diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 57 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 10 |
3 files changed, 74 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index f5c8187c26f..ca331cc92be 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1003,6 +1003,15 @@ public: case Expr::CXXUuidofExprClass: { return CGM.GetAddrOfUuidDescriptor(cast<CXXUuidofExpr>(E)); } + case Expr::MaterializeTemporaryExprClass: { + MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(E); + assert(MTE->getStorageDuration() == SD_Static); + SmallVector<const Expr *, 2> CommaLHSs; + SmallVector<SubobjectAdjustment, 2> Adjustments; + const Expr *Inner = MTE->GetTemporaryExpr() + ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); + return CGM.GetAddrOfGlobalTemporary(MTE, Inner); + } } return 0; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 3675e849aa7..4d64624dbcb 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2735,6 +2735,63 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str, return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment); } +llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary( + const MaterializeTemporaryExpr *E, const Expr *Inner) { + assert((E->getStorageDuration() == SD_Static || + E->getStorageDuration() == SD_Thread) && "not a global temporary"); + const VarDecl *VD = cast<VarDecl>(E->getExtendingDecl()); + + // If we're not materializing a subobject of the temporary, keep the + // cv-qualifiers from the type of the MaterializeTemporaryExpr. + if (Inner == E->GetTemporaryExpr()) + Inner = E; + + llvm::Constant *&Slot = MaterializedGlobalTemporaryMap[E]; + if (Slot) + return Slot; + + // FIXME: If an externally-visible declaration extends multiple temporaries, + // we need to give each temporary the same name in every translation unit (and + // we also need to make the temporaries externally-visible). + SmallString<256> Name; + llvm::raw_svector_ostream Out(Name); + getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out); + Out.flush(); + + llvm::Constant *InitialValue = 0; + APValue *Value = 0; + if (E->getStorageDuration() == SD_Static) { + // We might have a constant initializer for this temporary. + Value = getContext().getMaterializedTemporaryValue(E, false); + if (Value && Value->isUninit()) + Value = 0; + } + + bool Constant; + if (Value) { + // The temporary has a constant initializer, use it. + InitialValue = EmitConstantValue(*Value, Inner->getType(), 0); + Constant = isTypeConstant(Inner->getType(), /*ExcludeCtor*/Value); + } else { + // No constant initializer, the initialization will be provided when we + // initialize the declaration which performed lifetime extension. + InitialValue = EmitNullConstant(Inner->getType()); + Constant = false; + } + + // Create a global variable for this lifetime-extended temporary. + llvm::GlobalVariable *GV = + new llvm::GlobalVariable(getModule(), InitialValue->getType(), Constant, + llvm::GlobalValue::PrivateLinkage, InitialValue, + Name.c_str()); + GV->setAlignment( + getContext().getTypeAlignInChars(Inner->getType()).getQuantity()); + if (VD->getTLSKind()) + setTLSMode(GV, *VD); + Slot = GV; + return GV; +} + /// EmitObjCPropertyImplementations - Emit information for synthesized /// properties for an implementation. void CodeGenModule::EmitObjCPropertyImplementations(const diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 2777f959228..aa48cce08b8 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -307,7 +307,8 @@ class CodeGenModule : public CodeGenTypeCache { llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap; llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap; llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap; - + llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap; + llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap; llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap; @@ -731,7 +732,12 @@ public: /// GetAddrOfConstantCompoundLiteral - Returns a pointer to a constant global /// variable for the given file-scope compound literal expression. llvm::Constant *GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); - + + /// \brief Returns a pointer to a global variable representing a temporary + /// with static or thread storage duration. + llvm::Constant *GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, + const Expr *Inner); + /// \brief Retrieve the record type that describes the state of an /// Objective-C fast enumeration loop (for..in). QualType getObjCFastEnumerationStateType(); |