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/APFloat.h" 00019 #include "llvm/ADT/APSInt.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(nullptr), 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 // We ensure elsewhere that Data is big enough for LV and MemberPointerData. 00112 typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt, 00113 ComplexAPFloat, Vec, Arr, StructData, 00114 UnionData, AddrLabelDiffData> DataType; 00115 static const size_t DataSize = sizeof(DataType); 00116 00117 DataType Data; 00118 00119 public: 00120 APValue() : Kind(Uninitialized) {} 00121 explicit APValue(APSInt I) : Kind(Uninitialized) { 00122 MakeInt(); setInt(std::move(I)); 00123 } 00124 explicit APValue(APFloat F) : Kind(Uninitialized) { 00125 MakeFloat(); setFloat(std::move(F)); 00126 } 00127 explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { 00128 MakeVector(); setVector(E, N); 00129 } 00130 APValue(APSInt R, APSInt I) : Kind(Uninitialized) { 00131 MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); 00132 } 00133 APValue(APFloat R, APFloat I) : Kind(Uninitialized) { 00134 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); 00135 } 00136 APValue(const APValue &RHS); 00137 APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); } 00138 APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex) 00139 : Kind(Uninitialized) { 00140 MakeLValue(); setLValue(B, O, N, CallIndex); 00141 } 00142 APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, 00143 bool OnePastTheEnd, unsigned CallIndex) 00144 : Kind(Uninitialized) { 00145 MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex); 00146 } 00147 APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { 00148 MakeArray(InitElts, Size); 00149 } 00150 APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) { 00151 MakeStruct(B, M); 00152 } 00153 explicit APValue(const FieldDecl *D, const APValue &V = APValue()) 00154 : Kind(Uninitialized) { 00155 MakeUnion(); setUnion(D, V); 00156 } 00157 APValue(const ValueDecl *Member, bool IsDerivedMember, 00158 ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) { 00159 MakeMemberPointer(Member, IsDerivedMember, Path); 00160 } 00161 APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) 00162 : Kind(Uninitialized) { 00163 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); 00164 } 00165 00166 ~APValue() { 00167 MakeUninit(); 00168 } 00169 00170 /// \brief Returns whether the object performed allocations. 00171 /// 00172 /// If APValues are constructed via placement new, \c needsCleanup() 00173 /// indicates whether the destructor must be called in order to correctly 00174 /// free all allocated memory. 00175 bool needsCleanup() const; 00176 00177 /// \brief Swaps the contents of this and the given APValue. 00178 void swap(APValue &RHS); 00179 00180 ValueKind getKind() const { return Kind; } 00181 bool isUninit() const { return Kind == Uninitialized; } 00182 bool isInt() const { return Kind == Int; } 00183 bool isFloat() const { return Kind == Float; } 00184 bool isComplexInt() const { return Kind == ComplexInt; } 00185 bool isComplexFloat() const { return Kind == ComplexFloat; } 00186 bool isLValue() const { return Kind == LValue; } 00187 bool isVector() const { return Kind == Vector; } 00188 bool isArray() const { return Kind == Array; } 00189 bool isStruct() const { return Kind == Struct; } 00190 bool isUnion() const { return Kind == Union; } 00191 bool isMemberPointer() const { return Kind == MemberPointer; } 00192 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } 00193 00194 void dump() const; 00195 void dump(raw_ostream &OS) const; 00196 00197 void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const; 00198 std::string getAsString(ASTContext &Ctx, QualType Ty) const; 00199 00200 APSInt &getInt() { 00201 assert(isInt() && "Invalid accessor"); 00202 return *(APSInt*)(char*)Data.buffer; 00203 } 00204 const APSInt &getInt() const { 00205 return const_cast<APValue*>(this)->getInt(); 00206 } 00207 00208 APFloat &getFloat() { 00209 assert(isFloat() && "Invalid accessor"); 00210 return *(APFloat*)(char*)Data.buffer; 00211 } 00212 const APFloat &getFloat() const { 00213 return const_cast<APValue*>(this)->getFloat(); 00214 } 00215 00216 APSInt &getComplexIntReal() { 00217 assert(isComplexInt() && "Invalid accessor"); 00218 return ((ComplexAPSInt*)(char*)Data.buffer)->Real; 00219 } 00220 const APSInt &getComplexIntReal() const { 00221 return const_cast<APValue*>(this)->getComplexIntReal(); 00222 } 00223 00224 APSInt &getComplexIntImag() { 00225 assert(isComplexInt() && "Invalid accessor"); 00226 return ((ComplexAPSInt*)(char*)Data.buffer)->Imag; 00227 } 00228 const APSInt &getComplexIntImag() const { 00229 return const_cast<APValue*>(this)->getComplexIntImag(); 00230 } 00231 00232 APFloat &getComplexFloatReal() { 00233 assert(isComplexFloat() && "Invalid accessor"); 00234 return ((ComplexAPFloat*)(char*)Data.buffer)->Real; 00235 } 00236 const APFloat &getComplexFloatReal() const { 00237 return const_cast<APValue*>(this)->getComplexFloatReal(); 00238 } 00239 00240 APFloat &getComplexFloatImag() { 00241 assert(isComplexFloat() && "Invalid accessor"); 00242 return ((ComplexAPFloat*)(char*)Data.buffer)->Imag; 00243 } 00244 const APFloat &getComplexFloatImag() const { 00245 return const_cast<APValue*>(this)->getComplexFloatImag(); 00246 } 00247 00248 const LValueBase getLValueBase() const; 00249 CharUnits &getLValueOffset(); 00250 const CharUnits &getLValueOffset() const { 00251 return const_cast<APValue*>(this)->getLValueOffset(); 00252 } 00253 bool isLValueOnePastTheEnd() const; 00254 bool hasLValuePath() const; 00255 ArrayRef<LValuePathEntry> getLValuePath() const; 00256 unsigned getLValueCallIndex() const; 00257 00258 APValue &getVectorElt(unsigned I) { 00259 assert(isVector() && "Invalid accessor"); 00260 assert(I < getVectorLength() && "Index out of range"); 00261 return ((Vec*)(char*)Data.buffer)->Elts[I]; 00262 } 00263 const APValue &getVectorElt(unsigned I) const { 00264 return const_cast<APValue*>(this)->getVectorElt(I); 00265 } 00266 unsigned getVectorLength() const { 00267 assert(isVector() && "Invalid accessor"); 00268 return ((const Vec*)(const void *)Data.buffer)->NumElts; 00269 } 00270 00271 APValue &getArrayInitializedElt(unsigned I) { 00272 assert(isArray() && "Invalid accessor"); 00273 assert(I < getArrayInitializedElts() && "Index out of range"); 00274 return ((Arr*)(char*)Data.buffer)->Elts[I]; 00275 } 00276 const APValue &getArrayInitializedElt(unsigned I) const { 00277 return const_cast<APValue*>(this)->getArrayInitializedElt(I); 00278 } 00279 bool hasArrayFiller() const { 00280 return getArrayInitializedElts() != getArraySize(); 00281 } 00282 APValue &getArrayFiller() { 00283 assert(isArray() && "Invalid accessor"); 00284 assert(hasArrayFiller() && "No array filler"); 00285 return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()]; 00286 } 00287 const APValue &getArrayFiller() const { 00288 return const_cast<APValue*>(this)->getArrayFiller(); 00289 } 00290 unsigned getArrayInitializedElts() const { 00291 assert(isArray() && "Invalid accessor"); 00292 return ((const Arr*)(const void *)Data.buffer)->NumElts; 00293 } 00294 unsigned getArraySize() const { 00295 assert(isArray() && "Invalid accessor"); 00296 return ((const Arr*)(const void *)Data.buffer)->ArrSize; 00297 } 00298 00299 unsigned getStructNumBases() const { 00300 assert(isStruct() && "Invalid accessor"); 00301 return ((const StructData*)(const char*)Data.buffer)->NumBases; 00302 } 00303 unsigned getStructNumFields() const { 00304 assert(isStruct() && "Invalid accessor"); 00305 return ((const StructData*)(const char*)Data.buffer)->NumFields; 00306 } 00307 APValue &getStructBase(unsigned i) { 00308 assert(isStruct() && "Invalid accessor"); 00309 return ((StructData*)(char*)Data.buffer)->Elts[i]; 00310 } 00311 APValue &getStructField(unsigned i) { 00312 assert(isStruct() && "Invalid accessor"); 00313 return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i]; 00314 } 00315 const APValue &getStructBase(unsigned i) const { 00316 return const_cast<APValue*>(this)->getStructBase(i); 00317 } 00318 const APValue &getStructField(unsigned i) const { 00319 return const_cast<APValue*>(this)->getStructField(i); 00320 } 00321 00322 const FieldDecl *getUnionField() const { 00323 assert(isUnion() && "Invalid accessor"); 00324 return ((const UnionData*)(const char*)Data.buffer)->Field; 00325 } 00326 APValue &getUnionValue() { 00327 assert(isUnion() && "Invalid accessor"); 00328 return *((UnionData*)(char*)Data.buffer)->Value; 00329 } 00330 const APValue &getUnionValue() const { 00331 return const_cast<APValue*>(this)->getUnionValue(); 00332 } 00333 00334 const ValueDecl *getMemberPointerDecl() const; 00335 bool isMemberPointerToDerivedMember() const; 00336 ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const; 00337 00338 const AddrLabelExpr* getAddrLabelDiffLHS() const { 00339 assert(isAddrLabelDiff() && "Invalid accessor"); 00340 return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr; 00341 } 00342 const AddrLabelExpr* getAddrLabelDiffRHS() const { 00343 assert(isAddrLabelDiff() && "Invalid accessor"); 00344 return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr; 00345 } 00346 00347 void setInt(APSInt I) { 00348 assert(isInt() && "Invalid accessor"); 00349 *(APSInt *)(char *)Data.buffer = std::move(I); 00350 } 00351 void setFloat(APFloat F) { 00352 assert(isFloat() && "Invalid accessor"); 00353 *(APFloat *)(char *)Data.buffer = std::move(F); 00354 } 00355 void setVector(const APValue *E, unsigned N) { 00356 assert(isVector() && "Invalid accessor"); 00357 ((Vec*)(char*)Data.buffer)->Elts = new APValue[N]; 00358 ((Vec*)(char*)Data.buffer)->NumElts = N; 00359 for (unsigned i = 0; i != N; ++i) 00360 ((Vec*)(char*)Data.buffer)->Elts[i] = E[i]; 00361 } 00362 void setComplexInt(APSInt R, APSInt I) { 00363 assert(R.getBitWidth() == I.getBitWidth() && 00364 "Invalid complex int (type mismatch)."); 00365 assert(isComplexInt() && "Invalid accessor"); 00366 ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R); 00367 ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I); 00368 } 00369 void setComplexFloat(APFloat R, APFloat I) { 00370 assert(&R.getSemantics() == &I.getSemantics() && 00371 "Invalid complex float (type mismatch)."); 00372 assert(isComplexFloat() && "Invalid accessor"); 00373 ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R); 00374 ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I); 00375 } 00376 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 00377 unsigned CallIndex); 00378 void setLValue(LValueBase B, const CharUnits &O, 00379 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, 00380 unsigned CallIndex); 00381 void setUnion(const FieldDecl *Field, const APValue &Value) { 00382 assert(isUnion() && "Invalid accessor"); 00383 ((UnionData*)(char*)Data.buffer)->Field = Field; 00384 *((UnionData*)(char*)Data.buffer)->Value = Value; 00385 } 00386 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, 00387 const AddrLabelExpr* RHSExpr) { 00388 ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr; 00389 ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr; 00390 } 00391 00392 /// Assign by swapping from a copy of the RHS. 00393 APValue &operator=(APValue RHS) { 00394 swap(RHS); 00395 return *this; 00396 } 00397 00398 private: 00399 void DestroyDataAndMakeUninit(); 00400 void MakeUninit() { 00401 if (Kind != Uninitialized) 00402 DestroyDataAndMakeUninit(); 00403 } 00404 void MakeInt() { 00405 assert(isUninit() && "Bad state change"); 00406 new ((void*)Data.buffer) APSInt(1); 00407 Kind = Int; 00408 } 00409 void MakeFloat() { 00410 assert(isUninit() && "Bad state change"); 00411 new ((void*)(char*)Data.buffer) APFloat(0.0); 00412 Kind = Float; 00413 } 00414 void MakeVector() { 00415 assert(isUninit() && "Bad state change"); 00416 new ((void*)(char*)Data.buffer) Vec(); 00417 Kind = Vector; 00418 } 00419 void MakeComplexInt() { 00420 assert(isUninit() && "Bad state change"); 00421 new ((void*)(char*)Data.buffer) ComplexAPSInt(); 00422 Kind = ComplexInt; 00423 } 00424 void MakeComplexFloat() { 00425 assert(isUninit() && "Bad state change"); 00426 new ((void*)(char*)Data.buffer) ComplexAPFloat(); 00427 Kind = ComplexFloat; 00428 } 00429 void MakeLValue(); 00430 void MakeArray(unsigned InitElts, unsigned Size); 00431 void MakeStruct(unsigned B, unsigned M) { 00432 assert(isUninit() && "Bad state change"); 00433 new ((void*)(char*)Data.buffer) StructData(B, M); 00434 Kind = Struct; 00435 } 00436 void MakeUnion() { 00437 assert(isUninit() && "Bad state change"); 00438 new ((void*)(char*)Data.buffer) UnionData(); 00439 Kind = Union; 00440 } 00441 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 00442 ArrayRef<const CXXRecordDecl*> Path); 00443 void MakeAddrLabelDiff() { 00444 assert(isUninit() && "Bad state change"); 00445 new ((void*)(char*)Data.buffer) AddrLabelDiffData(); 00446 Kind = AddrLabelDiff; 00447 } 00448 }; 00449 00450 } // end namespace clang. 00451 00452 #endif