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/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