clang API Documentation
00001 //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the APValue class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_AST_APVALUE_H 00015 #define LLVM_CLANG_AST_APVALUE_H 00016 00017 #include "clang/Basic/LLVM.h" 00018 #include "llvm/ADT/APSInt.h" 00019 #include "llvm/ADT/APFloat.h" 00020 #include "llvm/ADT/PointerIntPair.h" 00021 #include "llvm/ADT/PointerUnion.h" 00022 00023 namespace clang { 00024 class AddrLabelExpr; 00025 class ASTContext; 00026 class CharUnits; 00027 class DiagnosticBuilder; 00028 class Expr; 00029 class FieldDecl; 00030 class Decl; 00031 class ValueDecl; 00032 class CXXRecordDecl; 00033 class QualType; 00034 00035 /// APValue - This class implements a discriminated union of [uninitialized] 00036 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], 00037 /// [Vector: N * APValue], [Array: N * APValue] 00038 class APValue { 00039 typedef llvm::APSInt APSInt; 00040 typedef llvm::APFloat APFloat; 00041 public: 00042 enum ValueKind { 00043 Uninitialized, 00044 Int, 00045 Float, 00046 ComplexInt, 00047 ComplexFloat, 00048 LValue, 00049 Vector, 00050 Array, 00051 Struct, 00052 Union, 00053 MemberPointer, 00054 AddrLabelDiff 00055 }; 00056 typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase; 00057 typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType; 00058 union LValuePathEntry { 00059 /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item 00060 /// in the path. An opaque value of type BaseOrMemberType. 00061 void *BaseOrMember; 00062 /// ArrayIndex - The array index of the next item in the path. 00063 uint64_t ArrayIndex; 00064 }; 00065 struct NoLValuePath {}; 00066 struct UninitArray {}; 00067 struct UninitStruct {}; 00068 private: 00069 ValueKind Kind; 00070 00071 struct ComplexAPSInt { 00072 APSInt Real, Imag; 00073 ComplexAPSInt() : Real(1), Imag(1) {} 00074 }; 00075 struct ComplexAPFloat { 00076 APFloat Real, Imag; 00077 ComplexAPFloat() : Real(0.0), Imag(0.0) {} 00078 }; 00079 struct LV; 00080 struct Vec { 00081 APValue *Elts; 00082 unsigned NumElts; 00083 Vec() : Elts(0), NumElts(0) {} 00084 ~Vec() { delete[] Elts; } 00085 }; 00086 struct Arr { 00087 APValue *Elts; 00088 unsigned NumElts, ArrSize; 00089 Arr(unsigned NumElts, unsigned ArrSize); 00090 ~Arr(); 00091 }; 00092 struct StructData { 00093 APValue *Elts; 00094 unsigned NumBases; 00095 unsigned NumFields; 00096 StructData(unsigned NumBases, unsigned NumFields); 00097 ~StructData(); 00098 }; 00099 struct UnionData { 00100 const FieldDecl *Field; 00101 APValue *Value; 00102 UnionData(); 00103 ~UnionData(); 00104 }; 00105 struct AddrLabelDiffData { 00106 const AddrLabelExpr* LHSExpr; 00107 const AddrLabelExpr* RHSExpr; 00108 }; 00109 struct MemberPointerData; 00110 00111 enum { 00112 MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ? 00113 sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat)) 00114 }; 00115 00116 union { 00117 void *Aligner; 00118 char Data[MaxSize]; 00119 }; 00120 00121 public: 00122 APValue() : Kind(Uninitialized) {} 00123 explicit APValue(const APSInt &I) : Kind(Uninitialized) { 00124 MakeInt(); setInt(I); 00125 } 00126 explicit APValue(const APFloat &F) : Kind(Uninitialized) { 00127 MakeFloat(); setFloat(F); 00128 } 00129 explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { 00130 MakeVector(); setVector(E, N); 00131 } 00132 APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) { 00133 MakeComplexInt(); setComplexInt(R, I); 00134 } 00135 APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) { 00136 MakeComplexFloat(); setComplexFloat(R, I); 00137 } 00138 APValue(const APValue &RHS); 00139 APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex) 00140 : Kind(Uninitialized) { 00141 MakeLValue(); setLValue(B, O, N, CallIndex); 00142 } 00143 APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, 00144 bool OnePastTheEnd, unsigned CallIndex) 00145 : Kind(Uninitialized) { 00146 MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex); 00147 } 00148 APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { 00149 MakeArray(InitElts, Size); 00150 } 00151 APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) { 00152 MakeStruct(B, M); 00153 } 00154 explicit APValue(const FieldDecl *D, const APValue &V = APValue()) 00155 : Kind(Uninitialized) { 00156 MakeUnion(); setUnion(D, V); 00157 } 00158 APValue(const ValueDecl *Member, bool IsDerivedMember, 00159 ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) { 00160 MakeMemberPointer(Member, IsDerivedMember, Path); 00161 } 00162 APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) 00163 : Kind(Uninitialized) { 00164 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); 00165 } 00166 00167 ~APValue() { 00168 MakeUninit(); 00169 } 00170 00171 /// \brief Swaps the contents of this and the given APValue. 00172 void swap(APValue &RHS); 00173 00174 ValueKind getKind() const { return Kind; } 00175 bool isUninit() const { return Kind == Uninitialized; } 00176 bool isInt() const { return Kind == Int; } 00177 bool isFloat() const { return Kind == Float; } 00178 bool isComplexInt() const { return Kind == ComplexInt; } 00179 bool isComplexFloat() const { return Kind == ComplexFloat; } 00180 bool isLValue() const { return Kind == LValue; } 00181 bool isVector() const { return Kind == Vector; } 00182 bool isArray() const { return Kind == Array; } 00183 bool isStruct() const { return Kind == Struct; } 00184 bool isUnion() const { return Kind == Union; } 00185 bool isMemberPointer() const { return Kind == MemberPointer; } 00186 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } 00187 00188 void dump() const; 00189 void dump(raw_ostream &OS) const; 00190 00191 void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const; 00192 std::string getAsString(ASTContext &Ctx, QualType Ty) const; 00193 00194 APSInt &getInt() { 00195 assert(isInt() && "Invalid accessor"); 00196 return *(APSInt*)(char*)Data; 00197 } 00198 const APSInt &getInt() const { 00199 return const_cast<APValue*>(this)->getInt(); 00200 } 00201 00202 APFloat &getFloat() { 00203 assert(isFloat() && "Invalid accessor"); 00204 return *(APFloat*)(char*)Data; 00205 } 00206 const APFloat &getFloat() const { 00207 return const_cast<APValue*>(this)->getFloat(); 00208 } 00209 00210 APSInt &getComplexIntReal() { 00211 assert(isComplexInt() && "Invalid accessor"); 00212 return ((ComplexAPSInt*)(char*)Data)->Real; 00213 } 00214 const APSInt &getComplexIntReal() const { 00215 return const_cast<APValue*>(this)->getComplexIntReal(); 00216 } 00217 00218 APSInt &getComplexIntImag() { 00219 assert(isComplexInt() && "Invalid accessor"); 00220 return ((ComplexAPSInt*)(char*)Data)->Imag; 00221 } 00222 const APSInt &getComplexIntImag() const { 00223 return const_cast<APValue*>(this)->getComplexIntImag(); 00224 } 00225 00226 APFloat &getComplexFloatReal() { 00227 assert(isComplexFloat() && "Invalid accessor"); 00228 return ((ComplexAPFloat*)(char*)Data)->Real; 00229 } 00230 const APFloat &getComplexFloatReal() const { 00231 return const_cast<APValue*>(this)->getComplexFloatReal(); 00232 } 00233 00234 APFloat &getComplexFloatImag() { 00235 assert(isComplexFloat() && "Invalid accessor"); 00236 return ((ComplexAPFloat*)(char*)Data)->Imag; 00237 } 00238 const APFloat &getComplexFloatImag() const { 00239 return const_cast<APValue*>(this)->getComplexFloatImag(); 00240 } 00241 00242 const LValueBase getLValueBase() const; 00243 CharUnits &getLValueOffset(); 00244 const CharUnits &getLValueOffset() const { 00245 return const_cast<APValue*>(this)->getLValueOffset(); 00246 } 00247 bool isLValueOnePastTheEnd() const; 00248 bool hasLValuePath() const; 00249 ArrayRef<LValuePathEntry> getLValuePath() const; 00250 unsigned getLValueCallIndex() const; 00251 00252 APValue &getVectorElt(unsigned I) { 00253 assert(isVector() && "Invalid accessor"); 00254 assert(I < getVectorLength() && "Index out of range"); 00255 return ((Vec*)(char*)Data)->Elts[I]; 00256 } 00257 const APValue &getVectorElt(unsigned I) const { 00258 return const_cast<APValue*>(this)->getVectorElt(I); 00259 } 00260 unsigned getVectorLength() const { 00261 assert(isVector() && "Invalid accessor"); 00262 return ((const Vec*)(const void *)Data)->NumElts; 00263 } 00264 00265 APValue &getArrayInitializedElt(unsigned I) { 00266 assert(isArray() && "Invalid accessor"); 00267 assert(I < getArrayInitializedElts() && "Index out of range"); 00268 return ((Arr*)(char*)Data)->Elts[I]; 00269 } 00270 const APValue &getArrayInitializedElt(unsigned I) const { 00271 return const_cast<APValue*>(this)->getArrayInitializedElt(I); 00272 } 00273 bool hasArrayFiller() const { 00274 return getArrayInitializedElts() != getArraySize(); 00275 } 00276 APValue &getArrayFiller() { 00277 assert(isArray() && "Invalid accessor"); 00278 assert(hasArrayFiller() && "No array filler"); 00279 return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()]; 00280 } 00281 const APValue &getArrayFiller() const { 00282 return const_cast<APValue*>(this)->getArrayFiller(); 00283 } 00284 unsigned getArrayInitializedElts() const { 00285 assert(isArray() && "Invalid accessor"); 00286 return ((const Arr*)(const void *)Data)->NumElts; 00287 } 00288 unsigned getArraySize() const { 00289 assert(isArray() && "Invalid accessor"); 00290 return ((const Arr*)(const void *)Data)->ArrSize; 00291 } 00292 00293 unsigned getStructNumBases() const { 00294 assert(isStruct() && "Invalid accessor"); 00295 return ((const StructData*)(const char*)Data)->NumBases; 00296 } 00297 unsigned getStructNumFields() const { 00298 assert(isStruct() && "Invalid accessor"); 00299 return ((const StructData*)(const char*)Data)->NumFields; 00300 } 00301 APValue &getStructBase(unsigned i) { 00302 assert(isStruct() && "Invalid accessor"); 00303 return ((StructData*)(char*)Data)->Elts[i]; 00304 } 00305 APValue &getStructField(unsigned i) { 00306 assert(isStruct() && "Invalid accessor"); 00307 return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i]; 00308 } 00309 const APValue &getStructBase(unsigned i) const { 00310 return const_cast<APValue*>(this)->getStructBase(i); 00311 } 00312 const APValue &getStructField(unsigned i) const { 00313 return const_cast<APValue*>(this)->getStructField(i); 00314 } 00315 00316 const FieldDecl *getUnionField() const { 00317 assert(isUnion() && "Invalid accessor"); 00318 return ((const UnionData*)(const char*)Data)->Field; 00319 } 00320 APValue &getUnionValue() { 00321 assert(isUnion() && "Invalid accessor"); 00322 return *((UnionData*)(char*)Data)->Value; 00323 } 00324 const APValue &getUnionValue() const { 00325 return const_cast<APValue*>(this)->getUnionValue(); 00326 } 00327 00328 const ValueDecl *getMemberPointerDecl() const; 00329 bool isMemberPointerToDerivedMember() const; 00330 ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const; 00331 00332 const AddrLabelExpr* getAddrLabelDiffLHS() const { 00333 assert(isAddrLabelDiff() && "Invalid accessor"); 00334 return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr; 00335 } 00336 const AddrLabelExpr* getAddrLabelDiffRHS() const { 00337 assert(isAddrLabelDiff() && "Invalid accessor"); 00338 return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr; 00339 } 00340 00341 void setInt(const APSInt &I) { 00342 assert(isInt() && "Invalid accessor"); 00343 *(APSInt*)(char*)Data = I; 00344 } 00345 void setFloat(const APFloat &F) { 00346 assert(isFloat() && "Invalid accessor"); 00347 *(APFloat*)(char*)Data = F; 00348 } 00349 void setVector(const APValue *E, unsigned N) { 00350 assert(isVector() && "Invalid accessor"); 00351 ((Vec*)(char*)Data)->Elts = new APValue[N]; 00352 ((Vec*)(char*)Data)->NumElts = N; 00353 for (unsigned i = 0; i != N; ++i) 00354 ((Vec*)(char*)Data)->Elts[i] = E[i]; 00355 } 00356 void setComplexInt(const APSInt &R, const APSInt &I) { 00357 assert(R.getBitWidth() == I.getBitWidth() && 00358 "Invalid complex int (type mismatch)."); 00359 assert(isComplexInt() && "Invalid accessor"); 00360 ((ComplexAPSInt*)(char*)Data)->Real = R; 00361 ((ComplexAPSInt*)(char*)Data)->Imag = I; 00362 } 00363 void setComplexFloat(const APFloat &R, const APFloat &I) { 00364 assert(&R.getSemantics() == &I.getSemantics() && 00365 "Invalid complex float (type mismatch)."); 00366 assert(isComplexFloat() && "Invalid accessor"); 00367 ((ComplexAPFloat*)(char*)Data)->Real = R; 00368 ((ComplexAPFloat*)(char*)Data)->Imag = I; 00369 } 00370 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 00371 unsigned CallIndex); 00372 void setLValue(LValueBase B, const CharUnits &O, 00373 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, 00374 unsigned CallIndex); 00375 void setUnion(const FieldDecl *Field, const APValue &Value) { 00376 assert(isUnion() && "Invalid accessor"); 00377 ((UnionData*)(char*)Data)->Field = Field; 00378 *((UnionData*)(char*)Data)->Value = Value; 00379 } 00380 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, 00381 const AddrLabelExpr* RHSExpr) { 00382 ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr; 00383 ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr; 00384 } 00385 00386 /// Assign by swapping from a copy of the RHS. 00387 APValue &operator=(APValue RHS) { 00388 swap(RHS); 00389 return *this; 00390 } 00391 00392 private: 00393 void DestroyDataAndMakeUninit(); 00394 void MakeUninit() { 00395 if (Kind != Uninitialized) 00396 DestroyDataAndMakeUninit(); 00397 } 00398 void MakeInt() { 00399 assert(isUninit() && "Bad state change"); 00400 new ((void*)Data) APSInt(1); 00401 Kind = Int; 00402 } 00403 void MakeFloat() { 00404 assert(isUninit() && "Bad state change"); 00405 new ((void*)(char*)Data) APFloat(0.0); 00406 Kind = Float; 00407 } 00408 void MakeVector() { 00409 assert(isUninit() && "Bad state change"); 00410 new ((void*)(char*)Data) Vec(); 00411 Kind = Vector; 00412 } 00413 void MakeComplexInt() { 00414 assert(isUninit() && "Bad state change"); 00415 new ((void*)(char*)Data) ComplexAPSInt(); 00416 Kind = ComplexInt; 00417 } 00418 void MakeComplexFloat() { 00419 assert(isUninit() && "Bad state change"); 00420 new ((void*)(char*)Data) ComplexAPFloat(); 00421 Kind = ComplexFloat; 00422 } 00423 void MakeLValue(); 00424 void MakeArray(unsigned InitElts, unsigned Size); 00425 void MakeStruct(unsigned B, unsigned M) { 00426 assert(isUninit() && "Bad state change"); 00427 new ((void*)(char*)Data) StructData(B, M); 00428 Kind = Struct; 00429 } 00430 void MakeUnion() { 00431 assert(isUninit() && "Bad state change"); 00432 new ((void*)(char*)Data) UnionData(); 00433 Kind = Union; 00434 } 00435 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 00436 ArrayRef<const CXXRecordDecl*> Path); 00437 void MakeAddrLabelDiff() { 00438 assert(isUninit() && "Bad state change"); 00439 new ((void*)(char*)Data) AddrLabelDiffData(); 00440 Kind = AddrLabelDiff; 00441 } 00442 }; 00443 00444 } // end namespace clang. 00445 00446 #endif