Home | History | Annotate | Download | only in AST
      1 //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
      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 defines the APValue class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_AST_APVALUE_H
     15 #define LLVM_CLANG_AST_APVALUE_H
     16 
     17 #include "clang/Basic/LLVM.h"
     18 #include "llvm/ADT/APFloat.h"
     19 #include "llvm/ADT/APSInt.h"
     20 #include "llvm/ADT/PointerIntPair.h"
     21 #include "llvm/ADT/PointerUnion.h"
     22 
     23 namespace clang {
     24   class AddrLabelExpr;
     25   class ASTContext;
     26   class CharUnits;
     27   class DiagnosticBuilder;
     28   class Expr;
     29   class FieldDecl;
     30   class Decl;
     31   class ValueDecl;
     32   class CXXRecordDecl;
     33   class QualType;
     34 
     35 /// APValue - This class implements a discriminated union of [uninitialized]
     36 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
     37 /// [Vector: N * APValue], [Array: N * APValue]
     38 class APValue {
     39   typedef llvm::APSInt APSInt;
     40   typedef llvm::APFloat APFloat;
     41 public:
     42   enum ValueKind {
     43     Uninitialized,
     44     Int,
     45     Float,
     46     ComplexInt,
     47     ComplexFloat,
     48     LValue,
     49     Vector,
     50     Array,
     51     Struct,
     52     Union,
     53     MemberPointer,
     54     AddrLabelDiff
     55   };
     56   typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
     57   typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
     58   union LValuePathEntry {
     59     /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
     60     /// in the path. An opaque value of type BaseOrMemberType.
     61     void *BaseOrMember;
     62     /// ArrayIndex - The array index of the next item in the path.
     63     uint64_t ArrayIndex;
     64   };
     65   struct NoLValuePath {};
     66   struct UninitArray {};
     67   struct UninitStruct {};
     68 private:
     69   ValueKind Kind;
     70 
     71   struct ComplexAPSInt {
     72     APSInt Real, Imag;
     73     ComplexAPSInt() : Real(1), Imag(1) {}
     74   };
     75   struct ComplexAPFloat {
     76     APFloat Real, Imag;
     77     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
     78   };
     79   struct LV;
     80   struct Vec {
     81     APValue *Elts;
     82     unsigned NumElts;
     83     Vec() : Elts(0), NumElts(0) {}
     84     ~Vec() { delete[] Elts; }
     85   };
     86   struct Arr {
     87     APValue *Elts;
     88     unsigned NumElts, ArrSize;
     89     Arr(unsigned NumElts, unsigned ArrSize);
     90     ~Arr();
     91   };
     92   struct StructData {
     93     APValue *Elts;
     94     unsigned NumBases;
     95     unsigned NumFields;
     96     StructData(unsigned NumBases, unsigned NumFields);
     97     ~StructData();
     98   };
     99   struct UnionData {
    100     const FieldDecl *Field;
    101     APValue *Value;
    102     UnionData();
    103     ~UnionData();
    104   };
    105   struct AddrLabelDiffData {
    106     const AddrLabelExpr* LHSExpr;
    107     const AddrLabelExpr* RHSExpr;
    108   };
    109   struct MemberPointerData;
    110 
    111   enum {
    112     MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
    113                sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
    114   };
    115 
    116   union {
    117     void *Aligner;
    118     char Data[MaxSize];
    119   };
    120 
    121 public:
    122   APValue() : Kind(Uninitialized) {}
    123   explicit APValue(const APSInt &I) : Kind(Uninitialized) {
    124     MakeInt(); setInt(I);
    125   }
    126   explicit APValue(const APFloat &F) : Kind(Uninitialized) {
    127     MakeFloat(); setFloat(F);
    128   }
    129   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
    130     MakeVector(); setVector(E, N);
    131   }
    132   APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
    133     MakeComplexInt(); setComplexInt(R, I);
    134   }
    135   APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
    136     MakeComplexFloat(); setComplexFloat(R, I);
    137   }
    138   APValue(const APValue &RHS);
    139   APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
    140       : Kind(Uninitialized) {
    141     MakeLValue(); setLValue(B, O, N, CallIndex);
    142   }
    143   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
    144           bool OnePastTheEnd, unsigned CallIndex)
    145       : Kind(Uninitialized) {
    146     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
    147   }
    148   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
    149     MakeArray(InitElts, Size);
    150   }
    151   APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
    152     MakeStruct(B, M);
    153   }
    154   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
    155       : Kind(Uninitialized) {
    156     MakeUnion(); setUnion(D, V);
    157   }
    158   APValue(const ValueDecl *Member, bool IsDerivedMember,
    159           ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
    160     MakeMemberPointer(Member, IsDerivedMember, Path);
    161   }
    162   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
    163       : Kind(Uninitialized) {
    164     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
    165   }
    166 
    167   ~APValue() {
    168     MakeUninit();
    169   }
    170 
    171   /// \brief Swaps the contents of this and the given APValue.
    172   void swap(APValue &RHS);
    173 
    174   ValueKind getKind() const { return Kind; }
    175   bool isUninit() const { return Kind == Uninitialized; }
    176   bool isInt() const { return Kind == Int; }
    177   bool isFloat() const { return Kind == Float; }
    178   bool isComplexInt() const { return Kind == ComplexInt; }
    179   bool isComplexFloat() const { return Kind == ComplexFloat; }
    180   bool isLValue() const { return Kind == LValue; }
    181   bool isVector() const { return Kind == Vector; }
    182   bool isArray() const { return Kind == Array; }
    183   bool isStruct() const { return Kind == Struct; }
    184   bool isUnion() const { return Kind == Union; }
    185   bool isMemberPointer() const { return Kind == MemberPointer; }
    186   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
    187 
    188   void dump() const;
    189   void dump(raw_ostream &OS) const;
    190 
    191   void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
    192   std::string getAsString(ASTContext &Ctx, QualType Ty) const;
    193 
    194   APSInt &getInt() {
    195     assert(isInt() && "Invalid accessor");
    196     return *(APSInt*)(char*)Data;
    197   }
    198   const APSInt &getInt() const {
    199     return const_cast<APValue*>(this)->getInt();
    200   }
    201 
    202   APFloat &getFloat() {
    203     assert(isFloat() && "Invalid accessor");
    204     return *(APFloat*)(char*)Data;
    205   }
    206   const APFloat &getFloat() const {
    207     return const_cast<APValue*>(this)->getFloat();
    208   }
    209 
    210   APSInt &getComplexIntReal() {
    211     assert(isComplexInt() && "Invalid accessor");
    212     return ((ComplexAPSInt*)(char*)Data)->Real;
    213   }
    214   const APSInt &getComplexIntReal() const {
    215     return const_cast<APValue*>(this)->getComplexIntReal();
    216   }
    217 
    218   APSInt &getComplexIntImag() {
    219     assert(isComplexInt() && "Invalid accessor");
    220     return ((ComplexAPSInt*)(char*)Data)->Imag;
    221   }
    222   const APSInt &getComplexIntImag() const {
    223     return const_cast<APValue*>(this)->getComplexIntImag();
    224   }
    225 
    226   APFloat &getComplexFloatReal() {
    227     assert(isComplexFloat() && "Invalid accessor");
    228     return ((ComplexAPFloat*)(char*)Data)->Real;
    229   }
    230   const APFloat &getComplexFloatReal() const {
    231     return const_cast<APValue*>(this)->getComplexFloatReal();
    232   }
    233 
    234   APFloat &getComplexFloatImag() {
    235     assert(isComplexFloat() && "Invalid accessor");
    236     return ((ComplexAPFloat*)(char*)Data)->Imag;
    237   }
    238   const APFloat &getComplexFloatImag() const {
    239     return const_cast<APValue*>(this)->getComplexFloatImag();
    240   }
    241 
    242   const LValueBase getLValueBase() const;
    243   CharUnits &getLValueOffset();
    244   const CharUnits &getLValueOffset() const {
    245     return const_cast<APValue*>(this)->getLValueOffset();
    246   }
    247   bool isLValueOnePastTheEnd() const;
    248   bool hasLValuePath() const;
    249   ArrayRef<LValuePathEntry> getLValuePath() const;
    250   unsigned getLValueCallIndex() const;
    251 
    252   APValue &getVectorElt(unsigned I) {
    253     assert(isVector() && "Invalid accessor");
    254     assert(I < getVectorLength() && "Index out of range");
    255     return ((Vec*)(char*)Data)->Elts[I];
    256   }
    257   const APValue &getVectorElt(unsigned I) const {
    258     return const_cast<APValue*>(this)->getVectorElt(I);
    259   }
    260   unsigned getVectorLength() const {
    261     assert(isVector() && "Invalid accessor");
    262     return ((const Vec*)(const void *)Data)->NumElts;
    263   }
    264 
    265   APValue &getArrayInitializedElt(unsigned I) {
    266     assert(isArray() && "Invalid accessor");
    267     assert(I < getArrayInitializedElts() && "Index out of range");
    268     return ((Arr*)(char*)Data)->Elts[I];
    269   }
    270   const APValue &getArrayInitializedElt(unsigned I) const {
    271     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
    272   }
    273   bool hasArrayFiller() const {
    274     return getArrayInitializedElts() != getArraySize();
    275   }
    276   APValue &getArrayFiller() {
    277     assert(isArray() && "Invalid accessor");
    278     assert(hasArrayFiller() && "No array filler");
    279     return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()];
    280   }
    281   const APValue &getArrayFiller() const {
    282     return const_cast<APValue*>(this)->getArrayFiller();
    283   }
    284   unsigned getArrayInitializedElts() const {
    285     assert(isArray() && "Invalid accessor");
    286     return ((const Arr*)(const void *)Data)->NumElts;
    287   }
    288   unsigned getArraySize() const {
    289     assert(isArray() && "Invalid accessor");
    290     return ((const Arr*)(const void *)Data)->ArrSize;
    291   }
    292 
    293   unsigned getStructNumBases() const {
    294     assert(isStruct() && "Invalid accessor");
    295     return ((const StructData*)(const char*)Data)->NumBases;
    296   }
    297   unsigned getStructNumFields() const {
    298     assert(isStruct() && "Invalid accessor");
    299     return ((const StructData*)(const char*)Data)->NumFields;
    300   }
    301   APValue &getStructBase(unsigned i) {
    302     assert(isStruct() && "Invalid accessor");
    303     return ((StructData*)(char*)Data)->Elts[i];
    304   }
    305   APValue &getStructField(unsigned i) {
    306     assert(isStruct() && "Invalid accessor");
    307     return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i];
    308   }
    309   const APValue &getStructBase(unsigned i) const {
    310     return const_cast<APValue*>(this)->getStructBase(i);
    311   }
    312   const APValue &getStructField(unsigned i) const {
    313     return const_cast<APValue*>(this)->getStructField(i);
    314   }
    315 
    316   const FieldDecl *getUnionField() const {
    317     assert(isUnion() && "Invalid accessor");
    318     return ((const UnionData*)(const char*)Data)->Field;
    319   }
    320   APValue &getUnionValue() {
    321     assert(isUnion() && "Invalid accessor");
    322     return *((UnionData*)(char*)Data)->Value;
    323   }
    324   const APValue &getUnionValue() const {
    325     return const_cast<APValue*>(this)->getUnionValue();
    326   }
    327 
    328   const ValueDecl *getMemberPointerDecl() const;
    329   bool isMemberPointerToDerivedMember() const;
    330   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
    331 
    332   const AddrLabelExpr* getAddrLabelDiffLHS() const {
    333     assert(isAddrLabelDiff() && "Invalid accessor");
    334     return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr;
    335   }
    336   const AddrLabelExpr* getAddrLabelDiffRHS() const {
    337     assert(isAddrLabelDiff() && "Invalid accessor");
    338     return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr;
    339   }
    340 
    341   void setInt(const APSInt &I) {
    342     assert(isInt() && "Invalid accessor");
    343     *(APSInt*)(char*)Data = I;
    344   }
    345   void setFloat(const APFloat &F) {
    346     assert(isFloat() && "Invalid accessor");
    347     *(APFloat*)(char*)Data = F;
    348   }
    349   void setVector(const APValue *E, unsigned N) {
    350     assert(isVector() && "Invalid accessor");
    351     ((Vec*)(char*)Data)->Elts = new APValue[N];
    352     ((Vec*)(char*)Data)->NumElts = N;
    353     for (unsigned i = 0; i != N; ++i)
    354       ((Vec*)(char*)Data)->Elts[i] = E[i];
    355   }
    356   void setComplexInt(const APSInt &R, const APSInt &I) {
    357     assert(R.getBitWidth() == I.getBitWidth() &&
    358            "Invalid complex int (type mismatch).");
    359     assert(isComplexInt() && "Invalid accessor");
    360     ((ComplexAPSInt*)(char*)Data)->Real = R;
    361     ((ComplexAPSInt*)(char*)Data)->Imag = I;
    362   }
    363   void setComplexFloat(const APFloat &R, const APFloat &I) {
    364     assert(&R.getSemantics() == &I.getSemantics() &&
    365            "Invalid complex float (type mismatch).");
    366     assert(isComplexFloat() && "Invalid accessor");
    367     ((ComplexAPFloat*)(char*)Data)->Real = R;
    368     ((ComplexAPFloat*)(char*)Data)->Imag = I;
    369   }
    370   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
    371                  unsigned CallIndex);
    372   void setLValue(LValueBase B, const CharUnits &O,
    373                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
    374                  unsigned CallIndex);
    375   void setUnion(const FieldDecl *Field, const APValue &Value) {
    376     assert(isUnion() && "Invalid accessor");
    377     ((UnionData*)(char*)Data)->Field = Field;
    378     *((UnionData*)(char*)Data)->Value = Value;
    379   }
    380   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
    381                         const AddrLabelExpr* RHSExpr) {
    382     ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr;
    383     ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
    384   }
    385 
    386   /// Assign by swapping from a copy of the RHS.
    387   APValue &operator=(APValue RHS) {
    388     swap(RHS);
    389     return *this;
    390   }
    391 
    392 private:
    393   void DestroyDataAndMakeUninit();
    394   void MakeUninit() {
    395     if (Kind != Uninitialized)
    396       DestroyDataAndMakeUninit();
    397   }
    398   void MakeInt() {
    399     assert(isUninit() && "Bad state change");
    400     new ((void*)Data) APSInt(1);
    401     Kind = Int;
    402   }
    403   void MakeFloat() {
    404     assert(isUninit() && "Bad state change");
    405     new ((void*)(char*)Data) APFloat(0.0);
    406     Kind = Float;
    407   }
    408   void MakeVector() {
    409     assert(isUninit() && "Bad state change");
    410     new ((void*)(char*)Data) Vec();
    411     Kind = Vector;
    412   }
    413   void MakeComplexInt() {
    414     assert(isUninit() && "Bad state change");
    415     new ((void*)(char*)Data) ComplexAPSInt();
    416     Kind = ComplexInt;
    417   }
    418   void MakeComplexFloat() {
    419     assert(isUninit() && "Bad state change");
    420     new ((void*)(char*)Data) ComplexAPFloat();
    421     Kind = ComplexFloat;
    422   }
    423   void MakeLValue();
    424   void MakeArray(unsigned InitElts, unsigned Size);
    425   void MakeStruct(unsigned B, unsigned M) {
    426     assert(isUninit() && "Bad state change");
    427     new ((void*)(char*)Data) StructData(B, M);
    428     Kind = Struct;
    429   }
    430   void MakeUnion() {
    431     assert(isUninit() && "Bad state change");
    432     new ((void*)(char*)Data) UnionData();
    433     Kind = Union;
    434   }
    435   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
    436                          ArrayRef<const CXXRecordDecl*> Path);
    437   void MakeAddrLabelDiff() {
    438     assert(isUninit() && "Bad state change");
    439     new ((void*)(char*)Data) AddrLabelDiffData();
    440     Kind = AddrLabelDiff;
    441   }
    442 };
    443 
    444 } // end namespace clang.
    445 
    446 #endif
    447