blob: 731d5e046681c759e3b665edd9b81d1ea27581b3 [file] [log] [blame]
Chris Lattner64c34f12008-11-16 07:46:48 +00001//===--- 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"
Ken Dycka7305832010-01-15 12:37:54 +000015#include "clang/AST/CharUnits.h"
Chris Lattner64c34f12008-11-16 07:46:48 +000016#include "llvm/Support/raw_ostream.h"
17using namespace clang;
18
Ken Dycka7305832010-01-15 12:37:54 +000019namespace {
20 struct LV {
21 Expr* Base;
22 CharUnits Offset;
23 };
24}
25
26APValue::APValue(Expr* B) : Kind(Uninitialized) {
27 MakeLValue(); setLValue(B, CharUnits::Zero());
28}
Chris Lattner64c34f12008-11-16 07:46:48 +000029
30const 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();
Nate Begeman3d309f92009-01-18 01:01:34 +000037 else if (RHS.isVector())
38 MakeVector();
Chris Lattner64c34f12008-11-16 07:46:48 +000039 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());
Nate Begeman3d309f92009-01-18 01:01:34 +000050 else if (isVector())
Dan Gohmancb421fa2010-04-19 16:39:44 +000051 setVector(((const Vec *)(const char *)RHS.Data)->Elts,
52 RHS.getVectorLength());
Chris Lattner64c34f12008-11-16 07:46:48 +000053 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
62void APValue::MakeUninit() {
63 if (Kind == Int)
Douglas Gregor98300462009-09-08 19:57:33 +000064 ((APSInt*)(char*)Data)->~APSInt();
Chris Lattner64c34f12008-11-16 07:46:48 +000065 else if (Kind == Float)
Douglas Gregor98300462009-09-08 19:57:33 +000066 ((APFloat*)(char*)Data)->~APFloat();
Nate Begeman3d309f92009-01-18 01:01:34 +000067 else if (Kind == Vector)
Douglas Gregor98300462009-09-08 19:57:33 +000068 ((Vec*)(char*)Data)->~Vec();
Chris Lattner64c34f12008-11-16 07:46:48 +000069 else if (Kind == ComplexInt)
Douglas Gregor98300462009-09-08 19:57:33 +000070 ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
Chris Lattner64c34f12008-11-16 07:46:48 +000071 else if (Kind == ComplexFloat)
Douglas Gregor98300462009-09-08 19:57:33 +000072 ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
Chris Lattner64c34f12008-11-16 07:46:48 +000073 else if (Kind == LValue) {
Douglas Gregor98300462009-09-08 19:57:33 +000074 ((LV*)(char*)Data)->~LV();
Chris Lattner64c34f12008-11-16 07:46:48 +000075 }
Nate Begeman3d309f92009-01-18 01:01:34 +000076 Kind = Uninitialized;
Chris Lattner64c34f12008-11-16 07:46:48 +000077}
78
79void APValue::dump() const {
80 print(llvm::errs());
81 llvm::errs() << '\n';
Chris Lattner64c34f12008-11-16 07:46:48 +000082}
83
84static 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
92void 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;
Nate Begeman3d309f92009-01-18 01:01:34 +0000104 case Vector:
Nate Begeman59b5da62009-01-18 03:20:47 +0000105 OS << "Vector: " << getVectorElt(0);
Mike Stump1eb44332009-09-09 15:08:12 +0000106 for (unsigned i = 1; i != getVectorLength(); ++i)
Nate Begeman59b5da62009-01-18 03:20:47 +0000107 OS << ", " << getVectorElt(i);
Nate Begeman3d309f92009-01-18 01:01:34 +0000108 return;
Chris Lattner64c34f12008-11-16 07:46:48 +0000109 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
Ken Dycka7305832010-01-15 12:37:54 +0000121Expr* APValue::getLValueBase() const {
122 assert(isLValue() && "Invalid accessor");
123 return ((const LV*)(const void*)Data)->Base;
124}
125
126CharUnits APValue::getLValueOffset() const {
127 assert(isLValue() && "Invalid accessor");
128 return ((const LV*)(const void*)Data)->Offset;
129}
130
131void APValue::setLValue(Expr *B, const CharUnits &O) {
132 assert(isLValue() && "Invalid accessor");
133 ((LV*)(char*)Data)->Base = B;
134 ((LV*)(char*)Data)->Offset = O;
135}
136
137void APValue::MakeLValue() {
138 assert(isUninit() && "Bad state change");
139 new ((void*)(char*)Data) LV();
140 Kind = LValue;
141}
142