CGValue.h revision 226633
1234353Sdim//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10224145Sdim// These classes implement wrappers around llvm::Value in order to 11193323Sed// fully represent the range of values for C L- and R- values. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15249423Sdim#ifndef CLANG_CODEGEN_CGVALUE_H 16218893Sdim#define CLANG_CODEGEN_CGVALUE_H 17249423Sdim 18249423Sdim#include "clang/AST/ASTContext.h" 19249423Sdim#include "clang/AST/Type.h" 20249423Sdim 21243830Sdimnamespace llvm { 22249423Sdim class Constant; 23224145Sdim class Value; 24224145Sdim} 25224145Sdim 26224145Sdimnamespace clang { 27224145Sdim class ObjCPropertyRefExpr; 28193323Sed 29193323Sednamespace CodeGen { 30194710Sed class CGBitFieldInfo; 31194710Sed 32194710Sed/// RValue - This trivial value class is used to represent the result of an 33194710Sed/// expression that is evaluated. It can be one of three things: either a 34199989Srdivacky/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the 35263508Sdim/// address of an aggregate value in memory. 36199989Srdivackyclass RValue { 37218893Sdim enum Flavor { Scalar, Complex, Aggregate }; 38243830Sdim 39243830Sdim // Stores first value and flavor. 40243830Sdim llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1; 41263508Sdim // Stores second value and volatility. 42263508Sdim llvm::PointerIntPair<llvm::Value *, 1, bool> V2; 43263508Sdim 44263508Sdimpublic: 45263508Sdim bool isScalar() const { return V1.getInt() == Scalar; } 46218893Sdim bool isComplex() const { return V1.getInt() == Complex; } 47263508Sdim bool isAggregate() const { return V1.getInt() == Aggregate; } 48263508Sdim 49263508Sdim bool isVolatileQualified() const { return V2.getInt(); } 50263508Sdim 51263508Sdim /// getScalarVal() - Return the Value* of this scalar value. 52263508Sdim llvm::Value *getScalarVal() const { 53263508Sdim assert(isScalar() && "Not a scalar!"); 54263508Sdim return V1.getPointer(); 55263508Sdim } 56263508Sdim 57263508Sdim /// getComplexVal - Return the real/imag components of this complex value. 58263508Sdim /// 59263508Sdim std::pair<llvm::Value *, llvm::Value *> getComplexVal() const { 60263508Sdim return std::make_pair(V1.getPointer(), V2.getPointer()); 61263508Sdim } 62263508Sdim 63263508Sdim /// getAggregateAddr() - Return the Value* of the address of the aggregate. 64263508Sdim llvm::Value *getAggregateAddr() const { 65263508Sdim assert(isAggregate() && "Not an aggregate!"); 66263508Sdim return V1.getPointer(); 67263508Sdim } 68263508Sdim 69263508Sdim static RValue get(llvm::Value *V) { 70263508Sdim RValue ER; 71263508Sdim ER.V1.setPointer(V); 72263508Sdim ER.V1.setInt(Scalar); 73263508Sdim ER.V2.setInt(false); 74263508Sdim return ER; 75263508Sdim } 76263508Sdim static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { 77224145Sdim RValue ER; 78249423Sdim ER.V1.setPointer(V1); 79224145Sdim ER.V2.setPointer(V2); 80218893Sdim ER.V1.setInt(Complex); 81263508Sdim ER.V2.setInt(false); 82193323Sed return ER; 83224145Sdim } 84218893Sdim static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) { 85249423Sdim return getComplex(C.first, C.second); 86193323Sed } 87249423Sdim // FIXME: Aggregate rvalues need to retain information about whether they are 88249423Sdim // volatile or not. Remove default to find all places that probably get this 89249423Sdim // wrong. 90249423Sdim static RValue getAggregate(llvm::Value *V, bool Volatile = false) { 91249423Sdim RValue ER; 92249423Sdim ER.V1.setPointer(V); 93249423Sdim ER.V1.setInt(Aggregate); 94249423Sdim ER.V2.setInt(Volatile); 95249423Sdim return ER; 96263508Sdim } 97249423Sdim}; 98249423Sdim 99263508Sdim 100249423Sdim/// LValue - This represents an lvalue references. Because C/C++ allow 101249423Sdim/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a 102249423Sdim/// bitrange. 103263508Sdimclass LValue { 104249423Sdim enum { 105249423Sdim Simple, // This is a normal l-value, use getAddress(). 106249423Sdim VectorElt, // This is a vector element l-value (V[i]), use getVector* 107249423Sdim BitField, // This is a bitfield l-value, use getBitfield*. 108249423Sdim ExtVectorElt, // This is an extended vector subset, use getExtVectorComp 109249423Sdim PropertyRef // This is an Objective-C property reference, use 110249423Sdim // getPropertyRefExpr 111249423Sdim } LVType; 112249423Sdim 113249423Sdim llvm::Value *V; 114249423Sdim 115249423Sdim union { 116249423Sdim // Index into a vector subscript: V[i] 117249423Sdim llvm::Value *VectorIdx; 118249423Sdim 119249423Sdim // ExtVector element subset: V.xyx 120249423Sdim llvm::Constant *VectorElts; 121249423Sdim 122249423Sdim // BitField start bit and size 123249423Sdim const CGBitFieldInfo *BitFieldInfo; 124249423Sdim 125249423Sdim // Obj-C property reference expression 126249423Sdim const ObjCPropertyRefExpr *PropertyRefExpr; 127249423Sdim }; 128263508Sdim 129249423Sdim QualType Type; 130263508Sdim 131251662Sdim // 'const' is unused here 132263508Sdim Qualifiers Quals; 133263508Sdim 134249423Sdim /// The alignment to use when accessing this lvalue. 135249423Sdim unsigned short Alignment; 136249423Sdim 137249423Sdim // objective-c's ivar 138249423Sdim bool Ivar:1; 139249423Sdim 140249423Sdim // objective-c's ivar is an array 141249423Sdim bool ObjIsArray:1; 142249423Sdim 143249423Sdim // LValue is non-gc'able for any reason, including being a parameter or local 144249423Sdim // variable. 145249423Sdim bool NonGC: 1; 146249423Sdim 147249423Sdim // Lvalue is a global reference of an objective-c object 148249423Sdim bool GlobalObjCRef : 1; 149249423Sdim 150249423Sdim // Lvalue is a thread local reference 151249423Sdim bool ThreadLocalRef : 1; 152249423Sdim 153249423Sdim Expr *BaseIvarExp; 154249423Sdim 155249423Sdim /// TBAAInfo - TBAA information to attach to dereferences of this LValue. 156249423Sdim llvm::MDNode *TBAAInfo; 157263508Sdim 158263508Sdimprivate: 159263508Sdim void Initialize(QualType Type, Qualifiers Quals, unsigned Alignment = 0, 160263508Sdim llvm::MDNode *TBAAInfo = 0) { 161263508Sdim this->Type = Type; 162263508Sdim this->Quals = Quals; 163263508Sdim this->Alignment = Alignment; 164193323Sed assert(this->Alignment == Alignment && "Alignment exceeds allowed max!"); 165224145Sdim 166224145Sdim // Initialize Objective-C flags. 167224145Sdim this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; 168249423Sdim this->ThreadLocalRef = false; 169249423Sdim this->BaseIvarExp = 0; 170224145Sdim this->TBAAInfo = TBAAInfo; 171224145Sdim } 172249423Sdim 173224145Sdimpublic: 174224145Sdim bool isSimple() const { return LVType == Simple; } 175218893Sdim bool isVectorElt() const { return LVType == VectorElt; } 176224145Sdim bool isBitField() const { return LVType == BitField; } 177204961Srdivacky bool isExtVectorElt() const { return LVType == ExtVectorElt; } 178224145Sdim bool isPropertyRef() const { return LVType == PropertyRef; } 179224145Sdim 180224145Sdim bool isVolatileQualified() const { return Quals.hasVolatile(); } 181263508Sdim bool isRestrictQualified() const { return Quals.hasRestrict(); } 182193323Sed unsigned getVRQualifiers() const { 183239462Sdim return Quals.getCVRQualifiers() & ~Qualifiers::Const; 184239462Sdim } 185239462Sdim 186224145Sdim QualType getType() const { return Type; } 187224145Sdim 188193323Sed Qualifiers::ObjCLifetime getObjCLifetime() const { 189249423Sdim return Quals.getObjCLifetime(); 190249423Sdim } 191234353Sdim 192234353Sdim bool isObjCIvar() const { return Ivar; } 193224145Sdim void setObjCIvar(bool Value) { Ivar = Value; } 194198090Srdivacky 195193323Sed bool isObjCArray() const { return ObjIsArray; } 196193323Sed void setObjCArray(bool Value) { ObjIsArray = Value; } 197193323Sed 198263508Sdim bool isNonGC () const { return NonGC; } 199263508Sdim void setNonGC(bool Value) { NonGC = Value; } 200263508Sdim 201263508Sdim bool isGlobalObjCRef() const { return GlobalObjCRef; } 202263508Sdim void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; } 203224145Sdim 204234353Sdim bool isThreadLocalRef() const { return ThreadLocalRef; } 205218893Sdim void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;} 206198090Srdivacky 207198396Srdivacky bool isObjCWeak() const { 208198396Srdivacky return Quals.getObjCGCAttr() == Qualifiers::Weak; 209218893Sdim } 210263508Sdim bool isObjCStrong() const { 211263508Sdim return Quals.getObjCGCAttr() == Qualifiers::Strong; 212263508Sdim } 213263508Sdim 214263508Sdim bool isVolatile() const { 215263508Sdim return Quals.hasVolatile(); 216263508Sdim } 217263508Sdim 218263508Sdim Expr *getBaseIvarExp() const { return BaseIvarExp; } 219263508Sdim void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } 220263508Sdim 221263508Sdim llvm::MDNode *getTBAAInfo() const { return TBAAInfo; } 222263508Sdim void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; } 223263508Sdim 224263508Sdim const Qualifiers &getQuals() const { return Quals; } 225263508Sdim Qualifiers &getQuals() { return Quals; } 226263508Sdim 227263508Sdim unsigned getAddressSpace() const { return Quals.getAddressSpace(); } 228263508Sdim 229263508Sdim unsigned getAlignment() const { return Alignment; } 230263508Sdim 231263508Sdim // simple lvalue 232263508Sdim llvm::Value *getAddress() const { assert(isSimple()); return V; } 233263508Sdim void setAddress(llvm::Value *address) { 234263508Sdim assert(isSimple()); 235263508Sdim V = address; 236249423Sdim } 237263508Sdim 238263508Sdim // vector elt lvalue 239263508Sdim llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } 240263508Sdim llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } 241263508Sdim 242263508Sdim // extended vector elements. 243263508Sdim llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; } 244263508Sdim llvm::Constant *getExtVectorElts() const { 245263508Sdim assert(isExtVectorElt()); 246263508Sdim return VectorElts; 247263508Sdim } 248263508Sdim 249249423Sdim // bitfield lvalue 250249423Sdim llvm::Value *getBitFieldBaseAddr() const { 251249423Sdim assert(isBitField()); 252249423Sdim return V; 253249423Sdim } 254193323Sed const CGBitFieldInfo &getBitFieldInfo() const { 255198090Srdivacky assert(isBitField()); 256198090Srdivacky return *BitFieldInfo; 257198090Srdivacky } 258207618Srdivacky 259207618Srdivacky // property ref lvalue 260198090Srdivacky llvm::Value *getPropertyRefBaseAddr() const { 261198090Srdivacky assert(isPropertyRef()); 262198090Srdivacky return V; 263203954Srdivacky } 264203954Srdivacky const ObjCPropertyRefExpr *getPropertyRefExpr() const { 265219077Sdim assert(isPropertyRef()); 266219077Sdim return PropertyRefExpr; 267219077Sdim } 268198090Srdivacky 269198090Srdivacky static LValue MakeAddr(llvm::Value *address, QualType type, 270198090Srdivacky unsigned alignment, ASTContext &Context, 271198090Srdivacky llvm::MDNode *TBAAInfo = 0) { 272198090Srdivacky Qualifiers qs = type.getQualifiers(); 273198090Srdivacky qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); 274198090Srdivacky 275198090Srdivacky LValue R; 276198090Srdivacky R.LVType = Simple; 277198090Srdivacky R.V = address; 278198090Srdivacky R.Initialize(type, qs, alignment, TBAAInfo); 279198090Srdivacky return R; 280198090Srdivacky } 281198090Srdivacky 282198090Srdivacky static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx, 283198090Srdivacky QualType type) { 284198090Srdivacky LValue R; 285198090Srdivacky R.LVType = VectorElt; 286198090Srdivacky R.V = Vec; 287198090Srdivacky R.VectorIdx = Idx; 288198090Srdivacky R.Initialize(type, type.getQualifiers()); 289198090Srdivacky return R; 290198090Srdivacky } 291198090Srdivacky 292198090Srdivacky static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts, 293198090Srdivacky QualType type) { 294198090Srdivacky LValue R; 295198090Srdivacky R.LVType = ExtVectorElt; 296198090Srdivacky R.V = Vec; 297198090Srdivacky R.VectorElts = Elts; 298218893Sdim R.Initialize(type, type.getQualifiers()); 299198090Srdivacky return R; 300198090Srdivacky } 301198090Srdivacky 302198090Srdivacky /// \brief Create a new object to represent a bit-field access. 303198090Srdivacky /// 304198090Srdivacky /// \param BaseValue - The base address of the structure containing the 305198090Srdivacky /// bit-field. 306198090Srdivacky /// \param Info - The information describing how to perform the bit-field 307198090Srdivacky /// access. 308199481Srdivacky static LValue MakeBitfield(llvm::Value *BaseValue, 309218893Sdim const CGBitFieldInfo &Info, 310239462Sdim QualType type) { 311218893Sdim LValue R; 312218893Sdim R.LVType = BitField; 313263508Sdim R.V = BaseValue; 314263508Sdim R.BitFieldInfo = &Info; 315263508Sdim R.Initialize(type, type.getQualifiers()); 316263508Sdim return R; 317263508Sdim } 318199481Srdivacky 319199481Srdivacky // FIXME: It is probably bad that we aren't emitting the target when we build 320224145Sdim // the lvalue. However, this complicates the code a bit, and I haven't figured 321199481Srdivacky // out how to make it go wrong yet. 322263508Sdim static LValue MakePropertyRef(const ObjCPropertyRefExpr *E, 323199481Srdivacky llvm::Value *Base) { 324199481Srdivacky LValue R; 325 R.LVType = PropertyRef; 326 R.V = Base; 327 R.PropertyRefExpr = E; 328 R.Initialize(QualType(), Qualifiers()); 329 return R; 330 } 331}; 332 333/// An aggregate value slot. 334class AggValueSlot { 335 /// The address. 336 llvm::Value *Addr; 337 338 // Qualifiers 339 Qualifiers Quals; 340 341 /// DestructedFlag - This is set to true if some external code is 342 /// responsible for setting up a destructor for the slot. Otherwise 343 /// the code which constructs it should push the appropriate cleanup. 344 bool DestructedFlag : 1; 345 346 /// ObjCGCFlag - This is set to true if writing to the memory in the 347 /// slot might require calling an appropriate Objective-C GC 348 /// barrier. The exact interaction here is unnecessarily mysterious. 349 bool ObjCGCFlag : 1; 350 351 /// ZeroedFlag - This is set to true if the memory in the slot is 352 /// known to be zero before the assignment into it. This means that 353 /// zero fields don't need to be set. 354 bool ZeroedFlag : 1; 355 356 /// AliasedFlag - This is set to true if the slot might be aliased 357 /// and it's not undefined behavior to access it through such an 358 /// alias. Note that it's always undefined behavior to access a C++ 359 /// object that's under construction through an alias derived from 360 /// outside the construction process. 361 /// 362 /// This flag controls whether calls that produce the aggregate 363 /// value may be evaluated directly into the slot, or whether they 364 /// must be evaluated into an unaliased temporary and then memcpy'ed 365 /// over. Since it's invalid in general to memcpy a non-POD C++ 366 /// object, it's important that this flag never be set when 367 /// evaluating an expression which constructs such an object. 368 bool AliasedFlag : 1; 369 370public: 371 enum IsAliased_t { IsNotAliased, IsAliased }; 372 enum IsDestructed_t { IsNotDestructed, IsDestructed }; 373 enum IsZeroed_t { IsNotZeroed, IsZeroed }; 374 enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; 375 376 /// ignored - Returns an aggregate value slot indicating that the 377 /// aggregate value is being ignored. 378 static AggValueSlot ignored() { 379 AggValueSlot AV; 380 AV.Addr = 0; 381 AV.Quals = Qualifiers(); 382 AV.DestructedFlag = AV.ObjCGCFlag = AV.ZeroedFlag = AV.AliasedFlag = false; 383 return AV; 384 } 385 386 /// forAddr - Make a slot for an aggregate value. 387 /// 388 /// \param quals - The qualifiers that dictate how the slot should 389 /// be initialied. Only 'volatile' and the Objective-C lifetime 390 /// qualifiers matter. 391 /// 392 /// \param isDestructed - true if something else is responsible 393 /// for calling destructors on this object 394 /// \param needsGC - true if the slot is potentially located 395 /// somewhere that ObjC GC calls should be emitted for 396 static AggValueSlot forAddr(llvm::Value *addr, Qualifiers quals, 397 IsDestructed_t isDestructed, 398 NeedsGCBarriers_t needsGC, 399 IsAliased_t isAliased, 400 IsZeroed_t isZeroed = IsNotZeroed) { 401 AggValueSlot AV; 402 AV.Addr = addr; 403 AV.Quals = quals; 404 AV.DestructedFlag = isDestructed; 405 AV.ObjCGCFlag = needsGC; 406 AV.ZeroedFlag = isZeroed; 407 AV.AliasedFlag = isAliased; 408 return AV; 409 } 410 411 static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed, 412 NeedsGCBarriers_t needsGC, 413 IsAliased_t isAliased, 414 IsZeroed_t isZeroed = IsNotZeroed) { 415 return forAddr(LV.getAddress(), LV.getQuals(), 416 isDestructed, needsGC, isAliased, isZeroed); 417 } 418 419 IsDestructed_t isExternallyDestructed() const { 420 return IsDestructed_t(DestructedFlag); 421 } 422 void setExternallyDestructed(bool destructed = true) { 423 DestructedFlag = destructed; 424 } 425 426 Qualifiers getQualifiers() const { return Quals; } 427 428 bool isVolatile() const { 429 return Quals.hasVolatile(); 430 } 431 432 Qualifiers::ObjCLifetime getObjCLifetime() const { 433 return Quals.getObjCLifetime(); 434 } 435 436 NeedsGCBarriers_t requiresGCollection() const { 437 return NeedsGCBarriers_t(ObjCGCFlag); 438 } 439 440 llvm::Value *getAddr() const { 441 return Addr; 442 } 443 444 bool isIgnored() const { 445 return Addr == 0; 446 } 447 448 IsAliased_t isPotentiallyAliased() const { 449 return IsAliased_t(AliasedFlag); 450 } 451 452 RValue asRValue() const { 453 return RValue::getAggregate(getAddr(), isVolatile()); 454 } 455 456 void setZeroed(bool V = true) { ZeroedFlag = V; } 457 IsZeroed_t isZeroed() const { 458 return IsZeroed_t(ZeroedFlag); 459 } 460}; 461 462} // end namespace CodeGen 463} // end namespace clang 464 465#endif 466