1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef ATTRIBUTE_VALUE_H
6#define ATTRIBUTE_VALUE_H
7
8#include "AttributeClasses.h"
9#include "Types.h"
10
11
12class DebugInfoEntry;
13
14
15struct AttributeValue {
16	union {
17		target_addr_t		address;
18		struct {
19			const void*		data;
20			off_t			length;
21		}					block;
22		uint64				constant;
23		bool				flag;
24		off_t				pointer;
25		DebugInfoEntry*		reference;
26		const char*			string;
27	};
28
29	uint16				attributeForm;
30	uint8				attributeClass;
31	bool				isSigned;
32
33	AttributeValue()
34		:
35		attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
36	{
37	}
38
39	~AttributeValue()
40	{
41		Unset();
42	}
43
44	void SetToAddress(target_addr_t address)
45	{
46		Unset();
47		attributeClass = ATTRIBUTE_CLASS_ADDRESS;
48		this->address = address;
49	}
50
51	void SetToAddrPtr(off_t value)
52	{
53		Unset();
54		attributeClass = ATTRIBUTE_CLASS_ADDRPTR;
55		this->pointer = value;
56	}
57
58	void SetToBlock(const void* data, off_t length)
59	{
60		Unset();
61		attributeClass = ATTRIBUTE_CLASS_BLOCK;
62		block.data = data;
63		block.length = length;
64	}
65
66	void SetToConstant(uint64 value, bool isSigned)
67	{
68		Unset();
69		attributeClass = ATTRIBUTE_CLASS_CONSTANT;
70		this->constant = value;
71		this->isSigned = isSigned;
72	}
73
74	void SetToFlag(bool value)
75	{
76		Unset();
77		attributeClass = ATTRIBUTE_CLASS_FLAG;
78		this->flag = value;
79	}
80
81	void SetToLinePointer(off_t value)
82	{
83		Unset();
84		attributeClass = ATTRIBUTE_CLASS_LINEPTR;
85		this->pointer = value;
86	}
87
88	void SetToLocationList(off_t value)
89	{
90		Unset();
91		attributeClass = ATTRIBUTE_CLASS_LOCLIST;
92		this->pointer = value;
93	}
94
95	void SetToLocationListPointer(off_t value)
96	{
97		Unset();
98		attributeClass = ATTRIBUTE_CLASS_LOCLISTPTR;
99		this->pointer = value;
100	}
101
102	void SetToMacroPointer(off_t value)
103	{
104		Unset();
105		attributeClass = ATTRIBUTE_CLASS_MACPTR;
106		this->pointer = value;
107	}
108
109	void SetToRangeList(off_t value)
110	{
111		Unset();
112		attributeClass = ATTRIBUTE_CLASS_RANGELIST;
113		this->pointer = value;
114	}
115
116	void SetToRangeListPointer(off_t value)
117	{
118		Unset();
119		attributeClass = ATTRIBUTE_CLASS_RANGELISTPTR;
120		this->pointer = value;
121	}
122
123	void SetToReference(DebugInfoEntry* entry)
124	{
125		Unset();
126		attributeClass = ATTRIBUTE_CLASS_REFERENCE;
127		this->reference = entry;
128	}
129
130	void SetToString(const char* string)
131	{
132		Unset();
133		attributeClass = ATTRIBUTE_CLASS_STRING;
134		this->string = string;
135	}
136
137	void SetToStrOffsetsPtr(off_t value)
138	{
139		Unset();
140		attributeClass = ATTRIBUTE_CLASS_STROFFSETSPTR;
141		this->pointer = value;
142	}
143
144	void Unset()
145	{
146		attributeClass = ATTRIBUTE_CLASS_UNKNOWN;
147	}
148
149	const char* ToString(char* buffer, size_t size);
150};
151
152
153struct DynamicAttributeValue {
154	union {
155		uint64				constant;
156		DebugInfoEntry*		reference;
157		struct {
158			const void*		data;
159			off_t			length;
160		}					block;
161	};
162	uint8				attributeClass;
163
164	DynamicAttributeValue()
165		:
166		attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
167	{
168		this->constant = 0;
169	}
170
171	bool IsValid() const
172	{
173		return attributeClass != ATTRIBUTE_CLASS_UNKNOWN;
174	}
175
176	void SetTo(uint64 constant)
177	{
178		this->constant = constant;
179		attributeClass = ATTRIBUTE_CLASS_CONSTANT;
180	}
181
182	void SetTo(DebugInfoEntry* reference)
183	{
184		this->reference = reference;
185		attributeClass = ATTRIBUTE_CLASS_REFERENCE;
186	}
187
188	void SetTo(const void* data, off_t length)
189	{
190		block.data = data;
191		block.length = length;
192		attributeClass = ATTRIBUTE_CLASS_BLOCK;
193	}
194};
195
196
197struct ConstantAttributeValue {
198	union {
199		uint64				constant;
200		const char*			string;
201		struct {
202			const void*		data;
203			off_t			length;
204		}					block;
205	};
206	uint8				attributeClass;
207
208	ConstantAttributeValue()
209		:
210		attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
211	{
212	}
213
214	bool IsValid() const
215	{
216		return attributeClass != ATTRIBUTE_CLASS_UNKNOWN;
217	}
218
219	void SetTo(uint64 constant)
220	{
221		this->constant = constant;
222		attributeClass = ATTRIBUTE_CLASS_CONSTANT;
223	}
224
225	void SetTo(const char* string)
226	{
227		this->string = string;
228		attributeClass = ATTRIBUTE_CLASS_STRING;
229	}
230
231	void SetTo(const void* data, off_t length)
232	{
233		block.data = data;
234		block.length = length;
235		attributeClass = ATTRIBUTE_CLASS_BLOCK;
236	}
237};
238
239
240struct MemberLocation {
241	union {
242		uint64				constant;
243		off_t				listOffset;
244		struct {
245			const void*		data;
246			off_t			length;
247		}					expression;
248	};
249	uint8				attributeClass;
250
251	MemberLocation()
252		:
253		attributeClass(ATTRIBUTE_CLASS_UNKNOWN)
254	{
255	}
256
257	bool IsValid() const
258	{
259		return attributeClass != ATTRIBUTE_CLASS_UNKNOWN;
260	}
261
262	bool IsConstant() const
263	{
264		return attributeClass == ATTRIBUTE_CLASS_CONSTANT;
265	}
266
267	bool IsExpression() const
268	{
269		return attributeClass == ATTRIBUTE_CLASS_BLOCK
270			&& expression.data != NULL;
271	}
272
273	bool IsLocationList() const
274	{
275		return attributeClass == ATTRIBUTE_CLASS_LOCLIST;
276	}
277
278	void SetToConstant(uint64 constant)
279	{
280		this->constant = constant;
281		attributeClass = ATTRIBUTE_CLASS_CONSTANT;
282	}
283
284	void SetToExpression(const void* data, off_t length)
285	{
286		expression.data = data;
287		expression.length = length;
288		attributeClass = ATTRIBUTE_CLASS_BLOCK;
289	}
290
291	void SetToLocationList(off_t listOffset)
292	{
293		this->listOffset = listOffset;
294		attributeClass = ATTRIBUTE_CLASS_LOCLIST;
295	}
296};
297
298
299struct LocationDescription {
300	union {
301		off_t			listOffset;	// location list
302		struct {
303			const void*	data;
304			off_t		length;
305		}				expression;	// location expression
306	};
307	uint8				attributeClass;
308
309	LocationDescription()
310		:
311		attributeClass(ATTRIBUTE_CLASS_BLOCK)
312	{
313		expression.data = NULL;
314		expression.length = 0;
315	}
316
317	bool IsExpression() const
318	{
319		return attributeClass == ATTRIBUTE_CLASS_BLOCK
320			&& expression.data != NULL;
321	}
322
323	bool IsLocationList() const
324	{
325		return attributeClass == ATTRIBUTE_CLASS_LOCLIST;
326	}
327
328	bool IsValid() const
329	{
330		return IsExpression() || IsLocationList();
331	}
332
333	void SetToLocationList(off_t offset)
334	{
335		listOffset = offset;
336		attributeClass = ATTRIBUTE_CLASS_LOCLIST;
337	}
338
339	void SetToExpression(const void* data, off_t length)
340	{
341		expression.data = data;
342		expression.length = length;
343		attributeClass = ATTRIBUTE_CLASS_BLOCK;
344	}
345};
346
347
348struct DeclarationLocation {
349	uint32	file;
350	uint32	line;
351	uint32	column;
352
353	DeclarationLocation()
354		:
355		file(0xffffffff),
356		line(0xffffffff),
357		column(0xffffffff)
358	{
359	}
360
361	void SetFile(uint32 file)
362	{
363		this->file = file;
364	}
365
366	void SetLine(uint32 line)
367	{
368		this->line = line;
369	}
370
371	void SetColumn(uint32 column)
372	{
373		this->column = column;
374	}
375
376	bool IsFileSet() const
377	{
378		return file != 0xffffffff;
379	}
380
381	bool IsLineSet() const
382	{
383		return line != 0xffffffff;
384	}
385
386	bool IsColumnSet() const
387	{
388		return column != 0xffffffff;
389	}
390};
391
392#endif	// ATTRIBUTE_VALUE_H
393