diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-05 00:46:14 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-05 00:46:14 +0000 |
commit | e6c0144208a4352c7c50616508081278c2ee5f88 (patch) | |
tree | e0a9174e018e3f66e20d23282a1411af866c5f51 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 23399d765cea1b0f7e3ec8e63c1390a1f992a950 (diff) | |
download | bcm5719-llvm-e6c0144208a4352c7c50616508081278c2ee5f88.tar.gz bcm5719-llvm-e6c0144208a4352c7c50616508081278c2ee5f88.zip |
Model temporary lifetime-extension explicitly in the AST. Use this model to
handle temporaries which have been lifetime-extended to static storage duration
within constant expressions. This correctly handles nested lifetime extension
(through reference members of aggregates in aggregate initializers) but
non-constant-expression emission hasn't yet been updated to do the same.
llvm-svn: 183283
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
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 |