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 Returns whether the object performed allocations.
    172   ///
    173   /// If APValues are constructed via placement new, \c needsCleanup()
    174   /// indicates whether the destructor must be called in order to correctly
    175   /// free all allocated memory.
    176   bool needsCleanup() const;
    177 
    178   /// \brief Swaps the contents of this and the given APValue.
    179   void swap(APValue &RHS);
    180 
    181   ValueKind getKind() const { return Kind; }
    182   bool isUninit() const { return Kind == Uninitialized; }
    183   bool isInt() const { return Kind == Int; }
    184   bool isFloat() const { return Kind == Float; }
    185   bool isComplexInt() const { return Kind == ComplexInt; }
    186   bool isComplexFloat() const { return Kind == ComplexFloat; }
    187   bool isLValue() const { return Kind == LValue; }
    188   bool isVector() const { return Kind == Vector; }
    189   bool isArray() const { return Kind == Array; }
    190   bool isStruct() const { return Kind == Struct; }
    191   bool isUnion() const { return Kind == Union; }
    192   bool isMemberPointer() const { return Kind == MemberPointer; }
    193   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
    194 
    195   void dump() const;
    196   void dump(raw_ostream &OS) const;
    197 
    198   void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
    199   std::string getAsString(ASTContext &Ctx, QualType Ty) const;
    200 
    201   APSInt &getInt() {
    202     assert(isInt() && "Invalid accessor");
    203     return *(APSInt*)(char*)Data;
    204   }
    205   const APSInt &getInt() const {
    206     return const_cast<APValue*>(this)->getInt();
    207   }
    208 
    209   APFloat &getFloat() {
    210     assert(isFloat() && "Invalid accessor");
    211     return *(APFloat*)(char*)Data;
    212   }
    213   const APFloat &getFloat() const {
    214     return const_cast<APValue*>(this)->getFloat();
    215   }
    216 
    217   APSInt &getComplexIntReal() {
    218     assert(isComplexInt() && "Invalid accessor");
    219     return ((ComplexAPSInt*)(char*)Data)->Real;
    220   }
    221   const APSInt &getComplexIntReal() const {
    222     return const_cast<APValue*>(this)->getComplexIntReal();
    223   }
    224 
    225   APSInt &getComplexIntImag() {
    226     assert(isComplexInt() && "Invalid accessor");
    227     return ((ComplexAPSInt*)(char*)Data)->Imag;
    228   }
    229   const APSInt &getComplexIntImag() const {
    230     return const_cast<APValue*>(this)->getComplexIntImag();
    231   }
    232 
    233   APFloat &getComplexFloatReal() {
    234     assert(isComplexFloat() && "Invalid accessor");
    235     return ((ComplexAPFloat*)(char*)Data)->Real;
    236   }
    237   const APFloat &getComplexFloatReal() const {
    238     return const_cast<APValue*>(this)->getComplexFloatReal();
    239   }
    240 
    241   APFloat &getComplexFloatImag() {
    242     assert(isComplexFloat() && "Invalid accessor");
    243     return ((ComplexAPFloat*)(char*)Data)->Imag;
    244   }
    245   const APFloat &getComplexFloatImag() const {
    246     return const_cast<APValue*>(this)->getComplexFloatImag();
    247   }
    248 
    249   const LValueBase getLValueBase() const;
    250   CharUnits &getLValueOffset();
    251   const CharUnits &getLValueOffset() const {
    252     return const_cast<APValue*>(this)->getLValueOffset();
    253   }
    254   bool isLValueOnePastTheEnd() const;
    255   bool hasLValuePath() const;
    256   ArrayRef<LValuePathEntry> getLValuePath() const;
    257   unsigned getLValueCallIndex() const;
    258 
    259   APValue &getVectorElt(unsigned I) {
    260     assert(isVector() && "Invalid accessor");
    261     assert(I < getVectorLength() && "Index out of range");
    262     return ((Vec*)(char*)Data)->Elts[I];
    263   }
    264   const APValue &getVectorElt(unsigned I) const {
    265     return const_cast<APValue*>(this)->getVectorElt(I);
    266   }
    267   unsigned getVectorLength() const {
    268     assert(isVector() && "Invalid accessor");
    269     return ((const Vec*)(const void *)Data)->NumElts;
    270   }
    271 
    272   APValue &getArrayInitializedElt(unsigned I) {
    273     assert(isArray() && "Invalid accessor");
    274     assert(I < getArrayInitializedElts() && "Index out of range");
    275     return ((Arr*)(char*)Data)->Elts[I];
    276   }
    277   const APValue &getArrayInitializedElt(unsigned I) const {
    278     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
    279   }
    280   bool hasArrayFiller() const {
    281     return getArrayInitializedElts() != getArraySize();
    282   }
    283   APValue &getArrayFiller() {
    284     assert(isArray() && "Invalid accessor");
    285     assert(hasArrayFiller() && "No array filler");
    286     return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()];
    287   }
    288   const APValue &getArrayFiller() const {
    289     return const_cast<APValue*>(this)->getArrayFiller();
    290   }
    291   unsigned getArrayInitializedElts() const {
    292     assert(isArray() && "Invalid accessor");
    293     return ((const Arr*)(const void *)Data)->NumElts;
    294   }
    295   unsigned getArraySize() const {
    296     assert(isArray() && "Invalid accessor");
    297     return ((const Arr*)(const void *)Data)->ArrSize;
    298   }
    299 
    300   unsigned getStructNumBases() const {
    301     assert(isStruct() && "Invalid accessor");
    302     return ((const StructData*)(const char*)Data)->NumBases;
    303   }
    304   unsigned getStructNumFields() const {
    305     assert(isStruct() && "Invalid accessor");
    306     return ((const StructData*)(const char*)Data)->NumFields;
    307   }
    308   APValue &getStructBase(unsigned i) {
    309     assert(isStruct() && "Invalid accessor");
    310     return ((StructData*)(char*)Data)->Elts[i];
    311   }
    312   APValue &getStructField(unsigned i) {
    313     assert(isStruct() && "Invalid accessor");
    314     return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i];
    315   }
    316   const APValue &getStructBase(unsigned i) const {
    317     return const_cast<APValue*>(this)->getStructBase(i);
    318   }
    319   const APValue &getStructField(unsigned i) const {
    320     return const_cast<APValue*>(this)->getStructField(i);
    321   }
    322 
    323   const FieldDecl *getUnionField() const {
    324     assert(isUnion() && "Invalid accessor");
    325     return ((const UnionData*)(const char*)Data)->Field;
    326   }
    327   APValue &getUnionValue() {
    328     assert(isUnion() && "Invalid accessor");
    329     return *((UnionData*)(char*)Data)->Value;
    330   }
    331   const APValue &getUnionValue() const {
    332     return const_cast<APValue*>(this)->getUnionValue();
    333   }
    334 
    335   const ValueDecl *getMemberPointerDecl() const;
    336   bool isMemberPointerToDerivedMember() const;
    337   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
    338 
    339   const AddrLabelExpr* getAddrLabelDiffLHS() const {
    340     assert(isAddrLabelDiff() && "Invalid accessor");
    341     return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr;
    342   }
    343   const AddrLabelExpr* getAddrLabelDiffRHS() const {
    344     assert(isAddrLabelDiff() && "Invalid accessor");
    345     return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr;
    346   }
    347 
    348   void setInt(const APSInt &I) {
    349     assert(isInt() && "Invalid accessor");
    350     *(APSInt*)(char*)Data = I;
    351   }
    352   void setFloat(const APFloat &F) {
    353     assert(isFloat() && "Invalid accessor");
    354     *(APFloat*)(char*)Data = F;
    355   }
    356   void setVector(const APValue *E, unsigned N) {
    357     assert(isVector() && "Invalid accessor");
    358     ((Vec*)(char*)Data)->Elts = new APValue[N];
    359     ((Vec*)(char*)Data)->NumElts = N;
    360     for (unsigned i = 0; i != N; ++i)
    361       ((Vec*)(char*)Data)->Elts[i] = E[i];
    362   }
    363   void setComplexInt(const APSInt &R, const APSInt &I) {
    364     assert(R.getBitWidth() == I.getBitWidth() &&
    365            "Invalid complex int (type mismatch).");
    366     assert(isComplexInt() && "Invalid accessor");
    367     ((ComplexAPSInt*)(char*)Data)->Real = R;
    368     ((ComplexAPSInt*)(char*)Data)->Imag = I;
    369   }
    370   void setComplexFloat(const APFloat &R, const APFloat &I) {
    371     assert(&R.getSemantics() == &I.getSemantics() &&
    372            "Invalid complex float (type mismatch).");
    373     assert(isComplexFloat() && "Invalid accessor");
    374     ((ComplexAPFloat*)(char*)Data)->Real = R;
    375     ((ComplexAPFloat*)(char*)Data)->Imag = I;
    376   }
    377   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
    378                  unsigned CallIndex);
    379   void setLValue(LValueBase B, const CharUnits &O,
    380                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
    381                  unsigned CallIndex);
    382   void setUnion(const FieldDecl *Field, const APValue &Value) {
    383     assert(isUnion() && "Invalid accessor");
    384     ((UnionData*)(char*)Data)->Field = Field;
    385     *((UnionData*)(char*)Data)->Value = Value;
    386   }
    387   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
    388                         const AddrLabelExpr* RHSExpr) {
    389     ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr;
    390     ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
    391   }
    392 
    393   /// Assign by swapping from a copy of the RHS.
    394   APValue &operator=(APValue RHS) {
    395     swap(RHS);
    396     return *this;
    397   }
    398 
    399 private:
    400   void DestroyDataAndMakeUninit();
    401   void MakeUninit() {
    402     if (Kind != Uninitialized)
    403       DestroyDataAndMakeUninit();
    404   }
    405   void MakeInt() {
    406     assert(isUninit() && "Bad state change");
    407     new ((void*)Data) APSInt(1);
    408     Kind = Int;
    409   }
    410   void MakeFloat() {
    411     assert(isUninit() && "Bad state change");
    412     new ((void*)(char*)Data) APFloat(0.0);
    413     Kind = Float;
    414   }
    415   void MakeVector() {
    416     assert(isUninit() && "Bad state change");
    417     new ((void*)(char*)Data) Vec();
    418     Kind = Vector;
    419   }
    420   void MakeComplexInt() {
    421     assert(isUninit() && "Bad state change");
    422     new ((void*)(char*)Data) ComplexAPSInt();
    423     Kind = ComplexInt;
    424   }
    425   void MakeComplexFloat() {
    426     assert(isUninit() && "Bad state change");
    427     new ((void*)(char*)Data) ComplexAPFloat();
    428     Kind = ComplexFloat;
    429   }
    430   void MakeLValue();
    431   void MakeArray(unsigned InitElts, unsigned Size);
    432   void MakeStruct(unsigned B, unsigned M) {
    433     assert(isUninit() && "Bad state change");
    434     new ((void*)(char*)Data) StructData(B, M);
    435     Kind = Struct;
    436   }
    437   void MakeUnion() {
    438     assert(isUninit() && "Bad state change");
    439     new ((void*)(char*)Data) UnionData();
    440     Kind = Union;
    441   }
    442   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
    443                          ArrayRef<const CXXRecordDecl*> Path);
    444   void MakeAddrLabelDiff() {
    445     assert(isUninit() && "Bad state change");
    446     new ((void*)(char*)Data) AddrLabelDiffData();
    447     Kind = AddrLabelDiff;
    448   }
    449 };
    450 
    451 } // end namespace clang.
    452 
    453 #endif
    454