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/ASTContext.h" 19 #include "clang/AST/CharUnits.h" 20 #include "clang/AST/Type.h" 21 22 namespace llvm { 23 class Constant; 24 class Value; 25 } 26 27 namespace clang { 28 namespace CodeGen { 29 class AggValueSlot; 30 class CGBitFieldInfo; 31 32 /// RValue - This trivial value class is used to represent the result of an 33 /// expression that is evaluated. It can be one of three things: either a 34 /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the 35 /// address of an aggregate value in memory. 36 class RValue { 37 enum Flavor { Scalar, Complex, Aggregate }; 38 39 // Stores first value and flavor. 40 llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1; 41 // Stores second value and volatility. 42 llvm::PointerIntPair<llvm::Value *, 1, bool> V2; 43 44 public: isScalar()45 bool isScalar() const { return V1.getInt() == Scalar; } isComplex()46 bool isComplex() const { return V1.getInt() == Complex; } isAggregate()47 bool isAggregate() const { return V1.getInt() == Aggregate; } 48 isVolatileQualified()49 bool isVolatileQualified() const { return V2.getInt(); } 50 51 /// getScalarVal() - Return the Value* of this scalar value. getScalarVal()52 llvm::Value *getScalarVal() const { 53 assert(isScalar() && "Not a scalar!"); 54 return V1.getPointer(); 55 } 56 57 /// getComplexVal - Return the real/imag components of this complex value. 58 /// getComplexVal()59 std::pair<llvm::Value *, llvm::Value *> getComplexVal() const { 60 return std::make_pair(V1.getPointer(), V2.getPointer()); 61 } 62 63 /// getAggregateAddr() - Return the Value* of the address of the aggregate. getAggregateAddr()64 llvm::Value *getAggregateAddr() const { 65 assert(isAggregate() && "Not an aggregate!"); 66 return V1.getPointer(); 67 } 68 get(llvm::Value * V)69 static RValue get(llvm::Value *V) { 70 RValue ER; 71 ER.V1.setPointer(V); 72 ER.V1.setInt(Scalar); 73 ER.V2.setInt(false); 74 return ER; 75 } getComplex(llvm::Value * V1,llvm::Value * V2)76 static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { 77 RValue ER; 78 ER.V1.setPointer(V1); 79 ER.V2.setPointer(V2); 80 ER.V1.setInt(Complex); 81 ER.V2.setInt(false); 82 return ER; 83 } getComplex(const std::pair<llvm::Value *,llvm::Value * > & C)84 static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) { 85 return getComplex(C.first, C.second); 86 } 87 // FIXME: Aggregate rvalues need to retain information about whether they are 88 // volatile or not. Remove default to find all places that probably get this 89 // wrong. 90 static RValue getAggregate(llvm::Value *V, bool Volatile = false) { 91 RValue ER; 92 ER.V1.setPointer(V); 93 ER.V1.setInt(Aggregate); 94 ER.V2.setInt(Volatile); 95 return ER; 96 } 97 }; 98 99 100 /// LValue - This represents an lvalue references. Because C/C++ allow 101 /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a 102 /// bitrange. 103 class LValue { 104 enum { 105 Simple, // This is a normal l-value, use getAddress(). 106 VectorElt, // This is a vector element l-value (V[i]), use getVector* 107 BitField, // This is a bitfield l-value, use getBitfield*. 108 ExtVectorElt // This is an extended vector subset, use getExtVectorComp 109 } LVType; 110 111 llvm::Value *V; 112 113 union { 114 // Index into a vector subscript: V[i] 115 llvm::Value *VectorIdx; 116 117 // ExtVector element subset: V.xyx 118 llvm::Constant *VectorElts; 119 120 // BitField start bit and size 121 const CGBitFieldInfo *BitFieldInfo; 122 }; 123 124 QualType Type; 125 126 // 'const' is unused here 127 Qualifiers Quals; 128 129 // The alignment to use when accessing this lvalue. (For vector elements, 130 // this is the alignment of the whole vector.) 131 int64_t Alignment; 132 133 // objective-c's ivar 134 bool Ivar:1; 135 136 // objective-c's ivar is an array 137 bool ObjIsArray:1; 138 139 // LValue is non-gc'able for any reason, including being a parameter or local 140 // variable. 141 bool NonGC: 1; 142 143 // Lvalue is a global reference of an objective-c object 144 bool GlobalObjCRef : 1; 145 146 // Lvalue is a thread local reference 147 bool ThreadLocalRef : 1; 148 149 Expr *BaseIvarExp; 150 151 /// TBAAInfo - TBAA information to attach to dereferences of this LValue. 152 llvm::MDNode *TBAAInfo; 153 154 private: 155 void Initialize(QualType Type, Qualifiers Quals, 156 CharUnits Alignment, 157 llvm::MDNode *TBAAInfo = 0) { 158 this->Type = Type; 159 this->Quals = Quals; 160 this->Alignment = Alignment.getQuantity(); 161 assert(this->Alignment == Alignment.getQuantity() && 162 "Alignment exceeds allowed max!"); 163 164 // Initialize Objective-C flags. 165 this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; 166 this->ThreadLocalRef = false; 167 this->BaseIvarExp = 0; 168 this->TBAAInfo = TBAAInfo; 169 } 170 171 public: isSimple()172 bool isSimple() const { return LVType == Simple; } isVectorElt()173 bool isVectorElt() const { return LVType == VectorElt; } isBitField()174 bool isBitField() const { return LVType == BitField; } isExtVectorElt()175 bool isExtVectorElt() const { return LVType == ExtVectorElt; } 176 isVolatileQualified()177 bool isVolatileQualified() const { return Quals.hasVolatile(); } isRestrictQualified()178 bool isRestrictQualified() const { return Quals.hasRestrict(); } getVRQualifiers()179 unsigned getVRQualifiers() const { 180 return Quals.getCVRQualifiers() & ~Qualifiers::Const; 181 } 182 getType()183 QualType getType() const { return Type; } 184 getObjCLifetime()185 Qualifiers::ObjCLifetime getObjCLifetime() const { 186 return Quals.getObjCLifetime(); 187 } 188 isObjCIvar()189 bool isObjCIvar() const { return Ivar; } setObjCIvar(bool Value)190 void setObjCIvar(bool Value) { Ivar = Value; } 191 isObjCArray()192 bool isObjCArray() const { return ObjIsArray; } setObjCArray(bool Value)193 void setObjCArray(bool Value) { ObjIsArray = Value; } 194 isNonGC()195 bool isNonGC () const { return NonGC; } setNonGC(bool Value)196 void setNonGC(bool Value) { NonGC = Value; } 197 isGlobalObjCRef()198 bool isGlobalObjCRef() const { return GlobalObjCRef; } setGlobalObjCRef(bool Value)199 void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; } 200 isThreadLocalRef()201 bool isThreadLocalRef() const { return ThreadLocalRef; } setThreadLocalRef(bool Value)202 void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;} 203 isObjCWeak()204 bool isObjCWeak() const { 205 return Quals.getObjCGCAttr() == Qualifiers::Weak; 206 } isObjCStrong()207 bool isObjCStrong() const { 208 return Quals.getObjCGCAttr() == Qualifiers::Strong; 209 } 210 isVolatile()211 bool isVolatile() const { 212 return Quals.hasVolatile(); 213 } 214 getBaseIvarExp()215 Expr *getBaseIvarExp() const { return BaseIvarExp; } setBaseIvarExp(Expr * V)216 void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } 217 getTBAAInfo()218 llvm::MDNode *getTBAAInfo() const { return TBAAInfo; } setTBAAInfo(llvm::MDNode * N)219 void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; } 220 getQuals()221 const Qualifiers &getQuals() const { return Quals; } getQuals()222 Qualifiers &getQuals() { return Quals; } 223 getAddressSpace()224 unsigned getAddressSpace() const { return Quals.getAddressSpace(); } 225 getAlignment()226 CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); } setAlignment(CharUnits A)227 void setAlignment(CharUnits A) { Alignment = A.getQuantity(); } 228 229 // simple lvalue getAddress()230 llvm::Value *getAddress() const { assert(isSimple()); return V; } setAddress(llvm::Value * address)231 void setAddress(llvm::Value *address) { 232 assert(isSimple()); 233 V = address; 234 } 235 236 // vector elt lvalue getVectorAddr()237 llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } getVectorIdx()238 llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } 239 240 // extended vector elements. getExtVectorAddr()241 llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; } getExtVectorElts()242 llvm::Constant *getExtVectorElts() const { 243 assert(isExtVectorElt()); 244 return VectorElts; 245 } 246 247 // bitfield lvalue getBitFieldBaseAddr()248 llvm::Value *getBitFieldBaseAddr() const { 249 assert(isBitField()); 250 return V; 251 } getBitFieldInfo()252 const CGBitFieldInfo &getBitFieldInfo() const { 253 assert(isBitField()); 254 return *BitFieldInfo; 255 } 256 257 static LValue MakeAddr(llvm::Value *address, QualType type, 258 CharUnits alignment, ASTContext &Context, 259 llvm::MDNode *TBAAInfo = 0) { 260 Qualifiers qs = type.getQualifiers(); 261 qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); 262 263 LValue R; 264 R.LVType = Simple; 265 R.V = address; 266 R.Initialize(type, qs, alignment, TBAAInfo); 267 return R; 268 } 269 MakeVectorElt(llvm::Value * Vec,llvm::Value * Idx,QualType type,CharUnits Alignment)270 static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx, 271 QualType type, CharUnits Alignment) { 272 LValue R; 273 R.LVType = VectorElt; 274 R.V = Vec; 275 R.VectorIdx = Idx; 276 R.Initialize(type, type.getQualifiers(), Alignment); 277 return R; 278 } 279 MakeExtVectorElt(llvm::Value * Vec,llvm::Constant * Elts,QualType type,CharUnits Alignment)280 static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts, 281 QualType type, CharUnits Alignment) { 282 LValue R; 283 R.LVType = ExtVectorElt; 284 R.V = Vec; 285 R.VectorElts = Elts; 286 R.Initialize(type, type.getQualifiers(), Alignment); 287 return R; 288 } 289 290 /// \brief Create a new object to represent a bit-field access. 291 /// 292 /// \param BaseValue - The base address of the structure containing the 293 /// bit-field. 294 /// \param Info - The information describing how to perform the bit-field 295 /// access. MakeBitfield(llvm::Value * BaseValue,const CGBitFieldInfo & Info,QualType type,CharUnits Alignment)296 static LValue MakeBitfield(llvm::Value *BaseValue, 297 const CGBitFieldInfo &Info, 298 QualType type, CharUnits Alignment) { 299 LValue R; 300 R.LVType = BitField; 301 R.V = BaseValue; 302 R.BitFieldInfo = &Info; 303 R.Initialize(type, type.getQualifiers(), Alignment); 304 return R; 305 } 306 asAggregateRValue()307 RValue asAggregateRValue() const { 308 // FIMXE: Alignment 309 return RValue::getAggregate(getAddress(), isVolatileQualified()); 310 } 311 }; 312 313 /// An aggregate value slot. 314 class AggValueSlot { 315 /// The address. 316 llvm::Value *Addr; 317 318 // Qualifiers 319 Qualifiers Quals; 320 321 unsigned short Alignment; 322 323 /// DestructedFlag - This is set to true if some external code is 324 /// responsible for setting up a destructor for the slot. Otherwise 325 /// the code which constructs it should push the appropriate cleanup. 326 bool DestructedFlag : 1; 327 328 /// ObjCGCFlag - This is set to true if writing to the memory in the 329 /// slot might require calling an appropriate Objective-C GC 330 /// barrier. The exact interaction here is unnecessarily mysterious. 331 bool ObjCGCFlag : 1; 332 333 /// ZeroedFlag - This is set to true if the memory in the slot is 334 /// known to be zero before the assignment into it. This means that 335 /// zero fields don't need to be set. 336 bool ZeroedFlag : 1; 337 338 /// AliasedFlag - This is set to true if the slot might be aliased 339 /// and it's not undefined behavior to access it through such an 340 /// alias. Note that it's always undefined behavior to access a C++ 341 /// object that's under construction through an alias derived from 342 /// outside the construction process. 343 /// 344 /// This flag controls whether calls that produce the aggregate 345 /// value may be evaluated directly into the slot, or whether they 346 /// must be evaluated into an unaliased temporary and then memcpy'ed 347 /// over. Since it's invalid in general to memcpy a non-POD C++ 348 /// object, it's important that this flag never be set when 349 /// evaluating an expression which constructs such an object. 350 bool AliasedFlag : 1; 351 352 public: 353 enum IsAliased_t { IsNotAliased, IsAliased }; 354 enum IsDestructed_t { IsNotDestructed, IsDestructed }; 355 enum IsZeroed_t { IsNotZeroed, IsZeroed }; 356 enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; 357 358 /// ignored - Returns an aggregate value slot indicating that the 359 /// aggregate value is being ignored. ignored()360 static AggValueSlot ignored() { 361 return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed, 362 DoesNotNeedGCBarriers, IsNotAliased); 363 } 364 365 /// forAddr - Make a slot for an aggregate value. 366 /// 367 /// \param quals - The qualifiers that dictate how the slot should 368 /// be initialied. Only 'volatile' and the Objective-C lifetime 369 /// qualifiers matter. 370 /// 371 /// \param isDestructed - true if something else is responsible 372 /// for calling destructors on this object 373 /// \param needsGC - true if the slot is potentially located 374 /// somewhere that ObjC GC calls should be emitted for 375 static AggValueSlot forAddr(llvm::Value *addr, CharUnits align, 376 Qualifiers quals, 377 IsDestructed_t isDestructed, 378 NeedsGCBarriers_t needsGC, 379 IsAliased_t isAliased, 380 IsZeroed_t isZeroed = IsNotZeroed) { 381 AggValueSlot AV; 382 AV.Addr = addr; 383 AV.Alignment = align.getQuantity(); 384 AV.Quals = quals; 385 AV.DestructedFlag = isDestructed; 386 AV.ObjCGCFlag = needsGC; 387 AV.ZeroedFlag = isZeroed; 388 AV.AliasedFlag = isAliased; 389 return AV; 390 } 391 392 static AggValueSlot forLValue(const LValue &LV, 393 IsDestructed_t isDestructed, 394 NeedsGCBarriers_t needsGC, 395 IsAliased_t isAliased, 396 IsZeroed_t isZeroed = IsNotZeroed) { 397 return forAddr(LV.getAddress(), LV.getAlignment(), 398 LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed); 399 } 400 isExternallyDestructed()401 IsDestructed_t isExternallyDestructed() const { 402 return IsDestructed_t(DestructedFlag); 403 } 404 void setExternallyDestructed(bool destructed = true) { 405 DestructedFlag = destructed; 406 } 407 getQualifiers()408 Qualifiers getQualifiers() const { return Quals; } 409 isVolatile()410 bool isVolatile() const { 411 return Quals.hasVolatile(); 412 } 413 getObjCLifetime()414 Qualifiers::ObjCLifetime getObjCLifetime() const { 415 return Quals.getObjCLifetime(); 416 } 417 requiresGCollection()418 NeedsGCBarriers_t requiresGCollection() const { 419 return NeedsGCBarriers_t(ObjCGCFlag); 420 } 421 getAddr()422 llvm::Value *getAddr() const { 423 return Addr; 424 } 425 isIgnored()426 bool isIgnored() const { 427 return Addr == 0; 428 } 429 getAlignment()430 CharUnits getAlignment() const { 431 return CharUnits::fromQuantity(Alignment); 432 } 433 isPotentiallyAliased()434 IsAliased_t isPotentiallyAliased() const { 435 return IsAliased_t(AliasedFlag); 436 } 437 438 // FIXME: Alignment? asRValue()439 RValue asRValue() const { 440 return RValue::getAggregate(getAddr(), isVolatile()); 441 } 442 443 void setZeroed(bool V = true) { ZeroedFlag = V; } isZeroed()444 IsZeroed_t isZeroed() const { 445 return IsZeroed_t(ZeroedFlag); 446 } 447 }; 448 449 } // end namespace CodeGen 450 } // end namespace clang 451 452 #endif 453