]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/AST/APValue.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / AST / APValue.cpp
1 //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements the APValue class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/APValue.h"
15 #include "clang/AST/CharUnits.h"
16 #include "llvm/Support/raw_ostream.h"
17 using namespace clang;
18
19 namespace {
20   struct LV {
21     const Expr* Base;
22     CharUnits Offset;
23   };
24 }
25
26 APValue::APValue(const Expr* B) : Kind(Uninitialized) {
27   MakeLValue(); setLValue(B, CharUnits::Zero());
28 }
29
30 const APValue &APValue::operator=(const APValue &RHS) {
31   if (Kind != RHS.Kind) {
32     MakeUninit();
33     if (RHS.isInt())
34       MakeInt();
35     else if (RHS.isFloat())
36       MakeFloat();
37     else if (RHS.isVector())
38       MakeVector();
39     else if (RHS.isComplexInt())
40       MakeComplexInt();
41     else if (RHS.isComplexFloat())
42       MakeComplexFloat();
43     else if (RHS.isLValue())
44       MakeLValue();
45   }
46   if (isInt())
47     setInt(RHS.getInt());
48   else if (isFloat())
49     setFloat(RHS.getFloat());
50   else if (isVector())
51     setVector(((const Vec *)(const char *)RHS.Data)->Elts,
52               RHS.getVectorLength());
53   else if (isComplexInt())
54     setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
55   else if (isComplexFloat())
56     setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
57   else if (isLValue())
58     setLValue(RHS.getLValueBase(), RHS.getLValueOffset());
59   return *this;
60 }
61
62 void APValue::MakeUninit() {
63   if (Kind == Int)
64     ((APSInt*)(char*)Data)->~APSInt();
65   else if (Kind == Float)
66     ((APFloat*)(char*)Data)->~APFloat();
67   else if (Kind == Vector)
68     ((Vec*)(char*)Data)->~Vec();
69   else if (Kind == ComplexInt)
70     ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
71   else if (Kind == ComplexFloat)
72     ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
73   else if (Kind == LValue) {
74     ((LV*)(char*)Data)->~LV();
75   }
76   Kind = Uninitialized;
77 }
78
79 void APValue::dump() const {
80   print(llvm::errs());
81   llvm::errs() << '\n';
82 }
83
84 static double GetApproxValue(const llvm::APFloat &F) {
85   llvm::APFloat V = F;
86   bool ignored;
87   V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
88             &ignored);
89   return V.convertToDouble();
90 }
91
92 void APValue::print(llvm::raw_ostream &OS) const {
93   switch (getKind()) {
94   default: assert(0 && "Unknown APValue kind!");
95   case Uninitialized:
96     OS << "Uninitialized";
97     return;
98   case Int:
99     OS << "Int: " << getInt();
100     return;
101   case Float:
102     OS << "Float: " << GetApproxValue(getFloat());
103     return;
104   case Vector:
105     OS << "Vector: " << getVectorElt(0);
106     for (unsigned i = 1; i != getVectorLength(); ++i)
107       OS << ", " << getVectorElt(i);
108     return;
109   case ComplexInt:
110     OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
111     return;
112   case ComplexFloat:
113     OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
114        << ", " << GetApproxValue(getComplexFloatImag());
115   case LValue:
116     OS << "LValue: <todo>";
117     return;
118   }
119 }
120
121 const Expr* APValue::getLValueBase() const {
122   assert(isLValue() && "Invalid accessor");
123   return ((const LV*)(const void*)Data)->Base;
124 }
125
126 CharUnits APValue::getLValueOffset() const {
127     assert(isLValue() && "Invalid accessor");
128     return ((const LV*)(const void*)Data)->Offset;
129 }
130
131 void APValue::setLValue(const Expr *B, const CharUnits &O) {
132   assert(isLValue() && "Invalid accessor");
133   ((LV*)(char*)Data)->Base = B;
134   ((LV*)(char*)Data)->Offset = O;
135 }
136
137 void APValue::MakeLValue() {
138   assert(isUninit() && "Bad state change");
139   new ((void*)(char*)Data) LV();
140   Kind = LValue;
141 }
142