diff options
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 61 |
1 files changed, 33 insertions, 28 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 04f13c7..9df1220 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -113,12 +113,14 @@ void CodeGenFunction::EmitDecl(const Decl &D, bool EvaluateConditionDecl) { case Decl::CXXRecord: // struct/union/class X; [C++] if (CGDebugInfo *DI = getDebugInfo()) if (cast<RecordDecl>(D).getDefinition()) - DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(&D))); + DI->EmitAndRetainType( + getContext().getCanonicalTagType(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))); + DI->EmitAndRetainType( + getContext().getCanonicalTagType(cast<EnumDecl>(&D))); return; case Decl::Function: // void X(); case Decl::EnumConstant: // enum ? { X = ? } @@ -599,10 +601,11 @@ namespace { llvm::Constant *CleanupFn; const CGFunctionInfo &FnInfo; const VarDecl &Var; + const CleanupAttr *Attribute; CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info, - const VarDecl *Var) - : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {} + const VarDecl *Var, const CleanupAttr *Attr) + : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Attribute(Attr) {} void Emit(CodeGenFunction &CGF, Flags flags) override { DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false, @@ -624,8 +627,11 @@ namespace { CallArgList Args; Args.add(RValue::get(Arg), CGF.getContext().getPointerType(Var.getType())); - auto Callee = CGCallee::forDirect(CleanupFn); - CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args); + GlobalDecl GD = GlobalDecl(Attribute->getFunctionDecl()); + auto Callee = CGCallee::forDirect(CleanupFn, CGCalleeInfo(GD)); + CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args, + /*callOrInvoke*/ nullptr, /*IsMustTail*/ false, + Attribute->getLoc()); } }; } // end anonymous namespace @@ -1347,30 +1353,27 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) { } /// Emit a lifetime.begin marker if some criteria are satisfied. -/// \return a pointer to the temporary size Value if a marker was emitted, null -/// otherwise -llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size, - llvm::Value *Addr) { +/// \return whether the marker was emitted. +bool CodeGenFunction::EmitLifetimeStart(llvm::Value *Addr) { if (!ShouldEmitLifetimeMarkers) - return nullptr; + return false; assert(Addr->getType()->getPointerAddressSpace() == CGM.getDataLayout().getAllocaAddrSpace() && "Pointer should be in alloca address space"); - llvm::Value *SizeV = llvm::ConstantInt::get( - Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue()); - llvm::CallInst *C = - Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr}); + llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {Addr}); C->setDoesNotThrow(); - return SizeV; + return true; } -void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) { +void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Addr) { + if (!ShouldEmitLifetimeMarkers) + return; + assert(Addr->getType()->getPointerAddressSpace() == CGM.getDataLayout().getAllocaAddrSpace() && "Pointer should be in alloca address space"); - llvm::CallInst *C = - Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr}); + llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Addr}); C->setDoesNotThrow(); } @@ -1567,7 +1570,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { ; if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { - const auto *RD = RecordTy->getDecl(); + const auto *RD = RecordTy->getOriginalDecl()->getDefinitionOrSelf(); const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); if ((CXXRD && !CXXRD->hasTrivialDestructor()) || RD->isNonTrivialToPrimitiveDestroy()) { @@ -1628,9 +1631,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // is rare. if (!Bypasses.IsBypassed(&D) && !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) { - llvm::TypeSize Size = CGM.getDataLayout().getTypeAllocSize(allocaTy); - emission.SizeForLifetimeMarkers = - EmitLifetimeStart(Size, AllocaAddr.getPointer()); + emission.UseLifetimeMarkers = + EmitLifetimeStart(AllocaAddr.getPointer()); } } else { assert(!emission.useLifetimeMarkers()); @@ -1723,9 +1725,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // Make sure we call @llvm.lifetime.end. if (emission.useLifetimeMarkers()) - EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, - emission.getOriginalAllocatedAddress(), - emission.getSizeForLifetimeMarkers()); + EHStack.pushCleanup<CallLifetimeEnd>( + NormalEHLifetimeMarker, emission.getOriginalAllocatedAddress()); // Analogous to lifetime markers, we use a 'cleanup' to emit fake.use // calls for local variables. We are exempting volatile variables and @@ -2231,7 +2232,8 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { assert(F && "Could not find function!"); const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD); - EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D); + EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D, + CA); } // If this is a block variable, call _Block_object_destroy @@ -2727,7 +2729,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, // Don't push a cleanup in a thunk for a method that will also emit a // cleanup. if (Ty->isRecordType() && !CurFuncIsThunk && - Ty->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) { + Ty->castAs<RecordType>() + ->getOriginalDecl() + ->getDefinitionOrSelf() + ->isParamDestroyedInCallee()) { if (QualType::DestructionKind DtorKind = D.needsDestruction(getContext())) { assert((DtorKind == QualType::DK_cxx_destructor || |