diff options
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 158 |
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 |
