aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp158
1 files changed, 106 insertions, 52 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 1729c7ed3c31..a01638f0b67b 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -100,15 +100,24 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::ObjCTypeParam:
case Decl::Binding:
llvm_unreachable("Declaration should not be in declstmts!");
- case Decl::Function: // void X();
case Decl::Record: // struct/union/class X;
+ case Decl::CXXRecord: // struct/union/class X; [C++]
+ if (CGDebugInfo *DI = getDebugInfo())
+ if (cast<RecordDecl>(D).getDefinition())
+ DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(&D)));
+ return;
case Decl::Enum: // enum X;
+ if (CGDebugInfo *DI = getDebugInfo())
+ if (cast<EnumDecl>(D).getDefinition())
+ DI->EmitAndRetainType(getContext().getEnumType(cast<EnumDecl>(&D)));
+ return;
+ case Decl::Function: // void X();
case Decl::EnumConstant: // enum ? { X = ? }
- case Decl::CXXRecord: // struct/union/class X; [C++]
case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
case Decl::Label: // __label__ x;
case Decl::Import:
case Decl::MSGuid: // __declspec(uuid("..."))
+ case Decl::TemplateParamObject:
case Decl::OMPThreadPrivate:
case Decl::OMPAllocate:
case Decl::OMPCapturedExpr:
@@ -157,12 +166,11 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::Typedef: // typedef int X;
case Decl::TypeAlias: { // using X = int; [C++0x]
- const TypedefNameDecl &TD = cast<TypedefNameDecl>(D);
- QualType Ty = TD.getUnderlyingType();
-
+ QualType Ty = cast<TypedefNameDecl>(D).getUnderlyingType();
+ if (CGDebugInfo *DI = getDebugInfo())
+ DI->EmitAndRetainType(Ty);
if (Ty->isVariablyModifiedType())
EmitVariablyModifiedType(Ty);
-
return;
}
}
@@ -345,12 +353,11 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
if (GV->getValueType() != Init->getType()) {
llvm::GlobalVariable *OldGV = GV;
- GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
- OldGV->isConstant(),
- OldGV->getLinkage(), Init, "",
- /*InsertBefore*/ OldGV,
- OldGV->getThreadLocalMode(),
- CGM.getContext().getTargetAddressSpace(D.getType()));
+ GV = new llvm::GlobalVariable(
+ CGM.getModule(), Init->getType(), OldGV->isConstant(),
+ OldGV->getLinkage(), Init, "",
+ /*InsertBefore*/ OldGV, OldGV->getThreadLocalMode(),
+ OldGV->getType()->getPointerAddressSpace());
GV->setVisibility(OldGV->getVisibility());
GV->setDSOLocal(OldGV->isDSOLocal());
GV->setComdat(OldGV->getComdat());
@@ -903,14 +910,17 @@ static bool canEmitInitWithFewStoresAfterBZero(llvm::Constant *Init,
/// the scalar stores that would be required.
static void emitStoresForInitAfterBZero(CodeGenModule &CGM,
llvm::Constant *Init, Address Loc,
- bool isVolatile, CGBuilderTy &Builder) {
+ bool isVolatile, CGBuilderTy &Builder,
+ bool IsAutoInit) {
assert(!Init->isNullValue() && !isa<llvm::UndefValue>(Init) &&
"called emitStoresForInitAfterBZero for zero or undef value.");
if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) ||
isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) ||
isa<llvm::ConstantExpr>(Init)) {
- Builder.CreateStore(Init, Loc, isVolatile);
+ auto *I = Builder.CreateStore(Init, Loc, isVolatile);
+ if (IsAutoInit)
+ I->addAnnotationMetadata("auto-init");
return;
}
@@ -923,7 +933,7 @@ static void emitStoresForInitAfterBZero(CodeGenModule &CGM,
if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
emitStoresForInitAfterBZero(
CGM, Elt, Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,
- Builder);
+ Builder, IsAutoInit);
}
return;
}
@@ -938,7 +948,7 @@ static void emitStoresForInitAfterBZero(CodeGenModule &CGM,
if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
emitStoresForInitAfterBZero(CGM, Elt,
Builder.CreateConstInBoundsGEP2_32(Loc, 0, i),
- isVolatile, Builder);
+ isVolatile, Builder, IsAutoInit);
}
}
@@ -1146,7 +1156,7 @@ static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM,
static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
Address Loc, bool isVolatile,
CGBuilderTy &Builder,
- llvm::Constant *constant) {
+ llvm::Constant *constant, bool IsAutoInit) {
auto *Ty = constant->getType();
uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty);
if (!ConstantSize)
@@ -1155,7 +1165,9 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
bool canDoSingleStore = Ty->isIntOrIntVectorTy() ||
Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy();
if (canDoSingleStore) {
- Builder.CreateStore(constant, Loc, isVolatile);
+ auto *I = Builder.CreateStore(constant, Loc, isVolatile);
+ if (IsAutoInit)
+ I->addAnnotationMetadata("auto-init");
return;
}
@@ -1164,14 +1176,17 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
// If the initializer is all or mostly the same, codegen with bzero / memset
// then do a few stores afterward.
if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) {
- Builder.CreateMemSet(Loc, llvm::ConstantInt::get(CGM.Int8Ty, 0), SizeVal,
- isVolatile);
+ auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(CGM.Int8Ty, 0),
+ SizeVal, isVolatile);
+ if (IsAutoInit)
+ I->addAnnotationMetadata("auto-init");
bool valueAlreadyCorrect =
constant->isNullValue() || isa<llvm::UndefValue>(constant);
if (!valueAlreadyCorrect) {
Loc = Builder.CreateBitCast(Loc, Ty->getPointerTo(Loc.getAddressSpace()));
- emitStoresForInitAfterBZero(CGM, constant, Loc, isVolatile, Builder);
+ emitStoresForInitAfterBZero(CGM, constant, Loc, isVolatile, Builder,
+ IsAutoInit);
}
return;
}
@@ -1186,8 +1201,10 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
assert(AP.getBitWidth() <= 8);
Value = AP.getLimitedValue();
}
- Builder.CreateMemSet(Loc, llvm::ConstantInt::get(CGM.Int8Ty, Value), SizeVal,
- isVolatile);
+ auto *I = Builder.CreateMemSet(
+ Loc, llvm::ConstantInt::get(CGM.Int8Ty, Value), SizeVal, isVolatile);
+ if (IsAutoInit)
+ I->addAnnotationMetadata("auto-init");
return;
}
@@ -1200,7 +1217,8 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
Address EltPtr = Builder.CreateStructGEP(Loc, i);
emitStoresForConstant(
CGM, D, EltPtr, isVolatile, Builder,
- cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)));
+ cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)),
+ IsAutoInit);
}
return;
}
@@ -1211,7 +1229,8 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
Address EltPtr = Builder.CreateConstArrayGEP(Loc, i);
emitStoresForConstant(
CGM, D, EltPtr, isVolatile, Builder,
- cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)));
+ cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)),
+ IsAutoInit);
}
return;
}
@@ -1219,10 +1238,13 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
}
// Copy from a global.
- Builder.CreateMemCpy(Loc,
- createUnnamedGlobalForMemcpyFrom(
- CGM, D, Builder, constant, Loc.getAlignment()),
- SizeVal, isVolatile);
+ auto *I =
+ Builder.CreateMemCpy(Loc,
+ createUnnamedGlobalForMemcpyFrom(
+ CGM, D, Builder, constant, Loc.getAlignment()),
+ SizeVal, isVolatile);
+ if (IsAutoInit)
+ I->addAnnotationMetadata("auto-init");
}
static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
@@ -1231,7 +1253,8 @@ static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
llvm::Type *ElTy = Loc.getElementType();
llvm::Constant *constant =
constWithPadding(CGM, IsPattern::No, llvm::Constant::getNullValue(ElTy));
- emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
+ emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant,
+ /*IsAutoInit=*/true);
}
static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D,
@@ -1241,7 +1264,8 @@ static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D,
llvm::Constant *constant = constWithPadding(
CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy));
assert(!isa<llvm::UndefValue>(constant));
- emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
+ emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant,
+ /*IsAutoInit=*/true);
}
static bool containsUndef(llvm::Constant *constant) {
@@ -1710,14 +1734,16 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,
case LangOptions::TrivialAutoVarInitKind::Uninitialized:
llvm_unreachable("Uninitialized handled by caller");
- case LangOptions::TrivialAutoVarInitKind::Zero:
+ case LangOptions::TrivialAutoVarInitKind::Zero: {
if (CGM.stopAutoInit())
return;
if (!EltSize.isOne())
SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize));
- Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
- isVolatile);
+ auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0),
+ SizeVal, isVolatile);
+ I->addAnnotationMetadata("auto-init");
break;
+ }
case LangOptions::TrivialAutoVarInitKind::Pattern: {
if (CGM.stopAutoInit())
@@ -1746,10 +1772,12 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,
llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur");
Cur->addIncoming(Begin.getPointer(), OriginBB);
CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize);
- Builder.CreateMemCpy(Address(Cur, CurAlign),
- createUnnamedGlobalForMemcpyFrom(
- CGM, D, Builder, Constant, ConstantAlign),
- BaseSizeInChars, isVolatile);
+ auto *I =
+ Builder.CreateMemCpy(Address(Cur, CurAlign),
+ createUnnamedGlobalForMemcpyFrom(
+ CGM, D, Builder, Constant, ConstantAlign),
+ BaseSizeInChars, isVolatile);
+ I->addAnnotationMetadata("auto-init");
llvm::Value *Next =
Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next");
llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone");
@@ -1870,7 +1898,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
llvm::Type *BP = CGM.Int8Ty->getPointerTo(Loc.getAddressSpace());
emitStoresForConstant(
CGM, D, (Loc.getType() == BP) ? Loc : Builder.CreateBitCast(Loc, BP),
- type.isVolatileQualified(), Builder, constant);
+ type.isVolatileQualified(), Builder, constant, /*IsAutoInit=*/false);
}
/// Emit an expression as an initializer for an object (variable, field, etc.)
@@ -2088,21 +2116,47 @@ void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) {
EHStack.pushCleanup<CallStackRestore>(Kind, SPMem);
}
-void CodeGenFunction::pushLifetimeExtendedDestroy(
- CleanupKind cleanupKind, Address addr, QualType type,
- Destroyer *destroyer, bool useEHCleanupForArray) {
- // Push an EH-only cleanup for the object now.
- // FIXME: When popping normal cleanups, we need to keep this EH cleanup
- // around in case a temporary's destructor throws an exception.
- if (cleanupKind & EHCleanup)
- EHStack.pushCleanup<DestroyObject>(
- static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), addr, type,
+void CodeGenFunction::pushLifetimeExtendedDestroy(CleanupKind cleanupKind,
+ Address addr, QualType type,
+ Destroyer *destroyer,
+ bool useEHCleanupForArray) {
+ // If we're not in a conditional branch, we don't need to bother generating a
+ // conditional cleanup.
+ if (!isInConditionalBranch()) {
+ // Push an EH-only cleanup for the object now.
+ // FIXME: When popping normal cleanups, we need to keep this EH cleanup
+ // around in case a temporary's destructor throws an exception.
+ if (cleanupKind & EHCleanup)
+ EHStack.pushCleanup<DestroyObject>(
+ static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), addr, type,
+ destroyer, useEHCleanupForArray);
+
+ return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>(
+ cleanupKind, Address::invalid(), addr, type, destroyer, useEHCleanupForArray);
+ }
+
+ // Otherwise, we should only destroy the object if it's been initialized.
+ // Re-use the active flag and saved address across both the EH and end of
+ // scope cleanups.
+
+ using SavedType = typename DominatingValue<Address>::saved_type;
+ using ConditionalCleanupType =
+ EHScopeStack::ConditionalCleanup<DestroyObject, Address, QualType,
+ Destroyer *, bool>;
+
+ Address ActiveFlag = createCleanupActiveFlag();
+ SavedType SavedAddr = saveValueInCond(addr);
+
+ if (cleanupKind & EHCleanup) {
+ EHStack.pushCleanup<ConditionalCleanupType>(
+ static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), SavedAddr, type,
destroyer, useEHCleanupForArray);
+ initFullExprCleanupWithFlag(ActiveFlag);
+ }
- // Remember that we need to push a full cleanup for the object at the
- // end of the full-expression.
- pushCleanupAfterFullExpr<DestroyObject>(
- cleanupKind, addr, type, destroyer, useEHCleanupForArray);
+ pushCleanupAfterFullExprWithActiveFlag<ConditionalCleanupType>(
+ cleanupKind, ActiveFlag, SavedAddr, type, destroyer,
+ useEHCleanupForArray);
}
/// emitDestroy - Immediately perform the destruction of the given