1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "EnumerationValueNode.h"
8
9#include <new>
10
11#include "EnumerationValue.h"
12#include "Tracing.h"
13#include "Type.h"
14#include "ValueLoader.h"
15#include "ValueLocation.h"
16
17
18EnumerationValueNode::EnumerationValueNode(ValueNodeChild* nodeChild,
19	EnumerationType* type)
20	:
21	ChildlessValueNode(nodeChild),
22	fType(type)
23{
24	fType->AcquireReference();
25}
26
27
28EnumerationValueNode::~EnumerationValueNode()
29{
30	fType->ReleaseReference();
31}
32
33
34Type*
35EnumerationValueNode::GetType() const
36{
37	return fType;
38}
39
40
41status_t
42EnumerationValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
43	ValueLocation*& _location, Value*& _value)
44{
45	// get the location
46	ValueLocation* location = NodeChild()->Location();
47	if (location == NULL)
48		return B_BAD_VALUE;
49
50	TRACE_LOCALS("  TYPE_ENUMERATION\n");
51
52	// get the value type
53	type_code valueType = 0;
54
55	// If a base type is known, try that.
56	if (PrimitiveType* baseType = dynamic_cast<PrimitiveType*>(
57			fType->BaseType())) {
58		valueType = baseType->TypeConstant();
59		if (!BVariant::TypeIsInteger(valueType))
60			valueType = 0;
61	}
62
63	// If we don't have a value type yet, guess it from the type size.
64	if (valueType == 0) {
65		// TODO: This is C source language specific!
66		switch (fType->ByteSize()) {
67			case 1:
68				valueType = B_INT8_TYPE;
69				break;
70			case 2:
71				valueType = B_INT16_TYPE;
72				break;
73			case 4:
74			default:
75				valueType = B_INT32_TYPE;
76				break;
77			case 8:
78				valueType = B_INT64_TYPE;
79				break;
80		}
81	}
82
83	// load the value data
84	BVariant valueData;
85	status_t error = valueLoader->LoadValue(location, valueType, true,
86		valueData);
87	if (error != B_OK)
88		return error;
89
90	// create the type object
91	Value* value = new(std::nothrow) EnumerationValue(fType, valueData);
92	if (value == NULL)
93		return B_NO_MEMORY;
94
95	location->AcquireReference();
96	_location = location;
97	_value = value;
98	return B_OK;
99}
100