diff options
author | dim <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 |
commit | 36c49e3f258dced101949edabd72e9bc3f1dedc4 (patch) | |
tree | 0bbe07708f7571f8b5291f6d7b96c102b7c99dee /lib/CodeGen/CGDeclCXX.cpp | |
parent | fc84956ac8b7cd244ef30e7a4d4d38a58dec5904 (diff) | |
download | FreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.zip FreeBSD-src-36c49e3f258dced101949edabd72e9bc3f1dedc4.tar.gz |
Vendor import of clang r114020 (from the release_28 branch):
http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020
Approved by: rpaulo (mentor)
Diffstat (limited to 'lib/CodeGen/CGDeclCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGDeclCXX.cpp | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index ec3f386..e2f1975 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "CodeGenFunction.h" +#include "CGCXXABI.h" #include "clang/Frontend/CodeGenOptions.h" #include "llvm/Intrinsics.h" @@ -30,9 +31,10 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, QualType T = D.getType(); bool isVolatile = Context.getCanonicalType(T).isVolatileQualified(); + unsigned Alignment = Context.getDeclAlign(&D).getQuantity(); if (!CGF.hasAggregateLLVMType(T)) { llvm::Value *V = CGF.EmitScalarExpr(Init); - CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T); + CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, Alignment, T); } else if (T->isAnyComplexType()) { CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile); } else { @@ -45,19 +47,15 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, CodeGenModule &CGM = CGF.CGM; ASTContext &Context = CGF.getContext(); - const Expr *Init = D.getInit(); QualType T = D.getType(); - if (!CGF.hasAggregateLLVMType(T) || T->isAnyComplexType()) - return; - - // Avoid generating destructor(s) for initialized objects. - if (!isa<CXXConstructExpr>(Init)) - return; + // Drill down past array types. const ConstantArrayType *Array = Context.getAsConstantArrayType(T); if (Array) T = Context.getBaseElementType(Array); + /// If that's not a record, we're done. + /// FIXME: __attribute__((cleanup)) ? const RecordType *RT = T->getAs<RecordType>(); if (!RT) return; @@ -94,8 +92,9 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, return; } + unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); RValue RV = EmitReferenceBindingToExpr(Init, &D); - EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T); + EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); } void @@ -174,13 +173,26 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) { unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); + DelayedCXXInitPosition.erase(D); + } + else { + llvm::DenseMap<const Decl *, unsigned>::iterator I = + DelayedCXXInitPosition.find(D); + if (I == DelayedCXXInitPosition.end()) { + CXXGlobalInits.push_back(Fn); + } else { + assert(CXXGlobalInits[I->second] == 0); + CXXGlobalInits[I->second] = Fn; + DelayedCXXInitPosition.erase(I); + } } - else - CXXGlobalInits.push_back(Fn); } void CodeGenModule::EmitCXXGlobalInitFunc() { + while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) + CXXGlobalInits.pop_back(); + if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) return; @@ -200,8 +212,7 @@ CodeGenModule::EmitCXXGlobalInitFunc() { llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; LocalCXXGlobalInits.push_back(Fn); } - for (unsigned i = 0; i < CXXGlobalInits.size(); i++) - LocalCXXGlobalInits.push_back(CXXGlobalInits[i]); + LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, &LocalCXXGlobalInits[0], LocalCXXGlobalInits.size()); @@ -247,7 +258,8 @@ void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, SourceLocation()); for (unsigned i = 0; i != NumDecls; ++i) - Builder.CreateCall(Decls[i]); + if (Decls[i]) + Builder.CreateCall(Decls[i]); FinishFunction(); } @@ -316,6 +328,20 @@ static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) { return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort"); } +namespace { + struct CallGuardAbort : EHScopeStack::Cleanup { + llvm::GlobalVariable *Guard; + CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {} + + void Emit(CodeGenFunction &CGF, bool IsForEH) { + // It shouldn't be possible for this to throw, but if it can, + // this should allow for the possibility of an invoke. + CGF.Builder.CreateCall(getGuardAbortFn(CGF), Guard) + ->setDoesNotThrow(); + } + }; +} + void CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV) { @@ -325,10 +351,10 @@ CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics; llvm::SmallString<256> GuardVName; - CGM.getMangleContext().mangleGuardVariable(&D, GuardVName); + CGM.getCXXABI().getMangleContext().mangleGuardVariable(&D, GuardVName); // Create the guard variable. - llvm::GlobalValue *GuardVariable = + llvm::GlobalVariable *GuardVariable = new llvm::GlobalVariable(CGM.getModule(), Int64Ty, false, GV->getLinkage(), llvm::Constant::getNullValue(Int64Ty), @@ -360,23 +386,25 @@ CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, InitBlock, EndBlock); // Call __cxa_guard_abort along the exceptional edge. - if (Exceptions) { - CleanupBlock Cleanup(*this, EHCleanup); - Builder.CreateCall(getGuardAbortFn(*this), GuardVariable); - } + if (Exceptions) + EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable); EmitBlock(InitBlock); } if (D.getType()->isReferenceType()) { + unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); QualType T = D.getType(); RValue RV = EmitReferenceBindingToExpr(D.getInit(), &D); - EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T); - + EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, Alignment, T); } else EmitDeclInit(*this, D, GV); if (ThreadsafeStatics) { + // Pop the guard-abort cleanup if we pushed one. + if (Exceptions) + PopCleanupBlock(); + // Call __cxa_guard_release. This cannot throw. Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable); } else { |