zcov: / lib/CodeGen/CGValue.h


Files: 1 Branches Taken: 47.8% 11 / 23
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 23 / 23
Line Coverage: 100.0% 118 / 118


Programs: 19 Runs 55043


       1                 : //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- 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                 : // These classes implement wrappers around llvm::Value in order to
      11                 : // fully represent the range of values for C L- and R- values.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #ifndef CLANG_CODEGEN_CGVALUE_H
      16                 : #define CLANG_CODEGEN_CGVALUE_H
      17                 : 
      18                 : #include "clang/AST/Type.h"
      19                 : 
      20                 : namespace llvm {
      21                 :   class Constant;
      22                 :   class Value;
      23                 : }
      24                 : 
      25                 : namespace clang {
      26                 :   class ObjCPropertyRefExpr;
      27                 :   class ObjCImplicitSetterGetterRefExpr;
      28                 : 
      29                 : namespace CodeGen {
      30                 : 
      31                 : /// RValue - This trivial value class is used to represent the result of an
      32                 : /// expression that is evaluated.  It can be one of three things: either a
      33                 : /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
      34                 : /// address of an aggregate value in memory.
      35                 : class RValue {
      36                 :   llvm::Value *V1, *V2;
      37                 :   // TODO: Encode this into the low bit of pointer for more efficient
      38                 :   // return-by-value.
      39                 :   enum { Scalar, Complex, Aggregate } Flavor;
      40                 : 
      41                 :   bool Volatile:1;
      42                 : public:
      43                 : 
      44            17650:   bool isScalar() const { return Flavor == Scalar; }
      45               83:   bool isComplex() const { return Flavor == Complex; }
      46              524:   bool isAggregate() const { return Flavor == Aggregate; }
      47                 : 
      48              202:   bool isVolatileQualified() const { return Volatile; }
      49                 : 
      50                 :   /// getScalarVal() - Return the Value* of this scalar value.
      51            11681:   llvm::Value *getScalarVal() const {
                    11681: branch 1 taken
                        0: branch 2 not taken
      52            11681:     assert(isScalar() && "Not a scalar!");
      53            11681:     return V1;
      54                 :   }
      55                 : 
      56                 :   /// getComplexVal - Return the real/imag components of this complex value.
      57                 :   ///
      58               33:   std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
      59               33:     return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
      60                 :   }
      61                 : 
      62                 :   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
      63              270:   llvm::Value *getAggregateAddr() const {
                        0: branch 2 not taken
      64              270:     assert(isAggregate() && "Not an aggregate!");
      65              270:     return V1;
      66                 :   }
      67                 : 
      68            17637:   static RValue get(llvm::Value *V) {
      69                 :     RValue ER;
      70            17637:     ER.V1 = V;
      71            17637:     ER.Flavor = Scalar;
      72            17637:     ER.Volatile = false;
      73                 :     return ER;
      74                 :   }
      75                 :   static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
      76                 :     RValue ER;
      77                 :     ER.V1 = V1;
      78                 :     ER.V2 = V2;
      79                 :     ER.Flavor = Complex;
      80                 :     ER.Volatile = false;
      81                 :     return ER;
      82                 :   }
      83               79:   static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
      84                 :     RValue ER;
      85               79:     ER.V1 = C.first;
      86               79:     ER.V2 = C.second;
      87               79:     ER.Flavor = Complex;
      88               79:     ER.Volatile = false;
      89                 :     return ER;
      90                 :   }
      91                 :   // FIXME: Aggregate rvalues need to retain information about whether they are
      92                 :   // volatile or not.  Remove default to find all places that probably get this
      93                 :   // wrong.
      94              554:   static RValue getAggregate(llvm::Value *V, bool Vol = false) {
      95                 :     RValue ER;
      96              554:     ER.V1 = V;
      97              554:     ER.Flavor = Aggregate;
      98              554:     ER.Volatile = Vol;
      99                 :     return ER;
     100                 :   }
     101                 : };
     102                 : 
     103                 : 
     104                 : /// LValue - This represents an lvalue references.  Because C/C++ allow
     105                 : /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
     106                 : /// bitrange.
     107             8481: class LValue {
     108                 :   // FIXME: alignment?
     109                 : 
     110                 :   enum {
     111                 :     Simple,       // This is a normal l-value, use getAddress().
     112                 :     VectorElt,    // This is a vector element l-value (V[i]), use getVector*
     113                 :     BitField,     // This is a bitfield l-value, use getBitfield*.
     114                 :     ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
     115                 :     PropertyRef,  // This is an Objective-C property reference, use
     116                 :                   // getPropertyRefExpr
     117                 :     KVCRef        // This is an objective-c 'implicit' property ref,
     118                 :                   // use getKVCRefExpr
     119                 :   } LVType;
     120                 : 
     121                 :   llvm::Value *V;
     122                 : 
     123                 :   union {
     124                 :     // Index into a vector subscript: V[i]
     125                 :     llvm::Value *VectorIdx;
     126                 : 
     127                 :     // ExtVector element subset: V.xyx
     128                 :     llvm::Constant *VectorElts;
     129                 : 
     130                 :     // BitField start bit and size
     131                 :     struct {
     132                 :       unsigned short StartBit;
     133                 :       unsigned short Size;
     134                 :       bool IsSigned;
     135                 :     } BitfieldData;
     136                 : 
     137                 :     // Obj-C property reference expression
     138                 :     const ObjCPropertyRefExpr *PropertyRefExpr;
     139                 :     // ObjC 'implicit' property reference expression
     140                 :     const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;
     141                 :   };
     142                 : 
     143                 :   // 'const' is unused here
     144                 :   Qualifiers Quals;
     145                 : 
     146                 :   // objective-c's ivar
     147                 :   bool Ivar:1;
     148                 :   
     149                 :   // objective-c's ivar is an array
     150                 :   bool ObjIsArray:1;
     151                 : 
     152                 :   // LValue is non-gc'able for any reason, including being a parameter or local
     153                 :   // variable.
     154                 :   bool NonGC: 1;
     155                 : 
     156                 :   // Lvalue is a global reference of an objective-c object
     157                 :   bool GlobalObjCRef : 1;
     158                 : 
     159                 :   Expr *BaseIvarExp;
     160                 : private:
     161             8425:   void SetQualifiers(Qualifiers Quals) {
     162             8425:     this->Quals = Quals;
     163                 :     
     164                 :     // FIXME: Convenient place to set objc flags to 0. This should really be
     165                 :     // done in a user-defined constructor instead.
     166             8425:     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
     167             8425:     this->BaseIvarExp = 0;
     168             8425:   }
     169                 : 
     170                 : public:
     171            16221:   bool isSimple() const { return LVType == Simple; }
     172              194:   bool isVectorElt() const { return LVType == VectorElt; }
     173             2965:   bool isBitfield() const { return LVType == BitField; }
     174              310:   bool isExtVectorElt() const { return LVType == ExtVectorElt; }
     175              180:   bool isPropertyRef() const { return LVType == PropertyRef; }
     176               63:   bool isKVCRef() const { return LVType == KVCRef; }
     177                 : 
     178             5647:   bool isVolatileQualified() const { return Quals.hasVolatile(); }
     179                 :   bool isRestrictQualified() const { return Quals.hasRestrict(); }
     180               56:   unsigned getVRQualifiers() const {
     181               56:     return Quals.getCVRQualifiers() & ~Qualifiers::Const;
     182                 :   }
     183                 : 
     184              197:   bool isObjCIvar() const { return Ivar; }
     185               71:   bool isObjCArray() const { return ObjIsArray; }
     186              493:   bool isNonGC () const { return NonGC; }
     187              131:   bool isGlobalObjCRef() const { return GlobalObjCRef; }
     188             5048:   bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; }
     189             1440:   bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; }
     190                 :   
     191               72:   Expr *getBaseIvarExp() const { return BaseIvarExp; }
     192              135:   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
     193                 : 
     194                 :   unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
     195                 : 
     196              158:   static void SetObjCIvar(LValue& R, bool iValue) {
     197              158:     R.Ivar = iValue;
     198              158:   }
     199              585:   static void SetObjCArray(LValue& R, bool iValue) {
     200              585:     R.ObjIsArray = iValue;
     201              585:   }
     202              175:   static void SetGlobalObjCRef(LValue& R, bool iValue) {
     203              175:     R.GlobalObjCRef = iValue;
     204              175:   }
     205                 : 
     206             4490:   static void SetObjCNonGC(LValue& R, bool iValue) {
     207             4490:     R.NonGC = iValue;
     208             4490:   }
     209                 : 
     210                 :   // simple lvalue
                        0: branch 1 not taken
                     9560: branch 2 taken
     211             9560:   llvm::Value *getAddress() const { assert(isSimple()); return V; }
     212                 :   // vector elt lvalue
     213                7:   llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
                        0: branch 1 not taken
                        4: branch 2 taken
     214                4:   llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
     215                 :   // extended vector elements.
                        0: branch 1 not taken
                       64: branch 2 taken
     216               64:   llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
     217               56:   llvm::Constant *getExtVectorElts() const {
                        0: branch 1 not taken
                       56: branch 2 taken
     218               56:     assert(isExtVectorElt());
     219               56:     return VectorElts;
     220                 :   }
     221                 :   // bitfield lvalue
                        0: branch 1 not taken
                      130: branch 2 taken
     222              130:   llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
     223              130:   unsigned short getBitfieldStartBit() const {
                        0: branch 1 not taken
                      130: branch 2 taken
     224              130:     assert(isBitfield());
     225              130:     return BitfieldData.StartBit;
     226                 :   }
     227              130:   unsigned short getBitfieldSize() const {
                        0: branch 1 not taken
                      130: branch 2 taken
     228              130:     assert(isBitfield());
     229              130:     return BitfieldData.Size;
     230                 :   }
     231              119:   bool isBitfieldSigned() const {
                        0: branch 1 not taken
                      119: branch 2 taken
     232              119:     assert(isBitfield());
     233              119:     return BitfieldData.IsSigned;
     234                 :   }
     235                 :   // property ref lvalue
     236               65:   const ObjCPropertyRefExpr *getPropertyRefExpr() const {
                        0: branch 1 not taken
                       65: branch 2 taken
     237               65:     assert(isPropertyRef());
     238               65:     return PropertyRefExpr;
     239                 :   }
     240                 : 
     241                 :   // 'implicit' property ref lvalue
     242               15:   const ObjCImplicitSetterGetterRefExpr *getKVCRefExpr() const {
                        0: branch 1 not taken
                       15: branch 2 taken
     243               15:     assert(isKVCRef());
     244               15:     return KVCRefExpr;
     245                 :   }
     246                 : 
     247             8174:   static LValue MakeAddr(llvm::Value *V, Qualifiers Quals) {
     248             8174:     LValue R;
     249             8174:     R.LVType = Simple;
     250             8174:     R.V = V;
     251             8174:     R.SetQualifiers(Quals);
     252                 :     return R;
     253                 :   }
     254                 : 
     255                 :   static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
     256                4:                               unsigned CVR) {
     257                4:     LValue R;
     258                4:     R.LVType = VectorElt;
     259                4:     R.V = Vec;
     260                4:     R.VectorIdx = Idx;
     261                4:     R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     262                 :     return R;
     263                 :   }
     264                 : 
     265                 :   static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
     266               56:                                  unsigned CVR) {
     267               56:     LValue R;
     268               56:     R.LVType = ExtVectorElt;
     269               56:     R.V = Vec;
     270               56:     R.VectorElts = Elts;
     271               56:     R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     272                 :     return R;
     273                 :   }
     274                 : 
     275                 :   static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
     276                 :                              unsigned short Size, bool IsSigned,
     277              120:                              unsigned CVR) {
     278              120:     LValue R;
     279              120:     R.LVType = BitField;
     280              120:     R.V = V;
     281              120:     R.BitfieldData.StartBit = StartBit;
     282              120:     R.BitfieldData.Size = Size;
     283              120:     R.BitfieldData.IsSigned = IsSigned;
     284              120:     R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     285                 :     return R;
     286                 :   }
     287                 : 
     288                 :   // FIXME: It is probably bad that we aren't emitting the target when we build
     289                 :   // the lvalue. However, this complicates the code a bit, and I haven't figured
     290                 :   // out how to make it go wrong yet.
     291                 :   static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
     292               56:                                 unsigned CVR) {
     293               56:     LValue R;
     294               56:     R.LVType = PropertyRef;
     295               56:     R.PropertyRefExpr = E;
     296               56:     R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     297                 :     return R;
     298                 :   }
     299                 : 
     300                 :   static LValue MakeKVCRef(const ObjCImplicitSetterGetterRefExpr *E,
     301               15:                            unsigned CVR) {
     302               15:     LValue R;
     303               15:     R.LVType = KVCRef;
     304               15:     R.KVCRefExpr = E;
     305               15:     R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     306                 :     return R;
     307                 :   }
     308                 : };
     309                 : 
     310                 : }  // end namespace CodeGen
     311                 : }  // end namespace clang
     312                 : 
     313                 : #endif

Generated: 2010-02-10 01:31 by zcov