1 //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the APValue class.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/APValue.h"
15 #include "clang/AST/CharUnits.h"
16 #include "llvm/Support/raw_ostream.h"
17 using namespace clang;
26 APValue::APValue(const Expr* B) : Kind(Uninitialized) {
27 MakeLValue(); setLValue(B, CharUnits::Zero());
30 const APValue &APValue::operator=(const APValue &RHS) {
31 if (Kind != RHS.Kind) {
35 else if (RHS.isFloat())
37 else if (RHS.isVector())
39 else if (RHS.isComplexInt())
41 else if (RHS.isComplexFloat())
43 else if (RHS.isLValue())
49 setFloat(RHS.getFloat());
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());
58 setLValue(RHS.getLValueBase(), RHS.getLValueOffset());
62 void APValue::MakeUninit() {
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();
79 void APValue::dump() const {
84 static double GetApproxValue(const llvm::APFloat &F) {
87 V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
89 return V.convertToDouble();
92 void APValue::print(llvm::raw_ostream &OS) const {
94 default: assert(0 && "Unknown APValue kind!");
96 OS << "Uninitialized";
99 OS << "Int: " << getInt();
102 OS << "Float: " << GetApproxValue(getFloat());
105 OS << "Vector: " << getVectorElt(0);
106 for (unsigned i = 1; i != getVectorLength(); ++i)
107 OS << ", " << getVectorElt(i);
110 OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
113 OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
114 << ", " << GetApproxValue(getComplexFloatImag());
116 OS << "LValue: <todo>";
121 const Expr* APValue::getLValueBase() const {
122 assert(isLValue() && "Invalid accessor");
123 return ((const LV*)(const void*)Data)->Base;
126 CharUnits APValue::getLValueOffset() const {
127 assert(isLValue() && "Invalid accessor");
128 return ((const LV*)(const void*)Data)->Offset;
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;
137 void APValue::MakeLValue() {
138 assert(isUninit() && "Bad state change");
139 new ((void*)(char*)Data) LV();