clang API Documentation

APValue.h
Go to the documentation of this file.
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