diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.h | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 15 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 4 |
5 files changed, 44 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index a53ca8f5243..dbe582cd150 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3835,7 +3835,8 @@ CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage, llvm::Optional<unsigned> ArgNo, - CGBuilderTy &Builder) { + CGBuilderTy &Builder, + const bool UsePointerValue) { assert(DebugKind >= codegenoptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); if (VD->hasAttr<NoDebugAttr>()) @@ -3940,6 +3941,16 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, } } + // Clang stores the sret pointer provided by the caller in a static alloca. + // Use DW_OP_deref to tell the debugger to load the pointer and treat it as + // the address of the variable. + if (UsePointerValue) { + assert(std::find(Expr.begin(), Expr.end(), llvm::dwarf::DW_OP_deref) == + Expr.end() && + "Debug info already contains DW_OP_deref."); + Expr.push_back(llvm::dwarf::DW_OP_deref); + } + // Create the descriptor for the variable. auto *D = ArgNo ? DBuilder.createParameterVariable( Scope, Name, *ArgNo, Unit, Line, Ty, @@ -3958,9 +3969,10 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::DILocalVariable * CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage, - CGBuilderTy &Builder) { + CGBuilderTy &Builder, + const bool UsePointerValue) { assert(DebugKind >= codegenoptions::LimitedDebugInfo); - return EmitDeclare(VD, Storage, llvm::None, Builder); + return EmitDeclare(VD, Storage, llvm::None, Builder, UsePointerValue); } void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 054df01d97c..f0c67cdecbb 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -422,9 +422,10 @@ public: /// declaration. /// Returns a pointer to the DILocalVariable associated with the /// llvm.dbg.declare, or nullptr otherwise. - llvm::DILocalVariable *EmitDeclareOfAutoVariable(const VarDecl *Decl, - llvm::Value *AI, - CGBuilderTy &Builder); + llvm::DILocalVariable * + EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, + CGBuilderTy &Builder, + const bool UsePointerValue = false); /// Emit call to \c llvm.dbg.label for an label. void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder); @@ -507,7 +508,8 @@ private: /// llvm.dbg.declare, or nullptr otherwise. llvm::DILocalVariable *EmitDeclare(const VarDecl *decl, llvm::Value *AI, llvm::Optional<unsigned> ArgNo, - CGBuilderTy &Builder); + CGBuilderTy &Builder, + const bool UsePointerValue = false); struct BlockByRefType { /// The wrapper struct used inside the __block_literal struct. diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 233212c76be..c4e0d89c83c 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1403,12 +1403,11 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { getLangOpts().OpenMP ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D) : Address::invalid(); + bool NRVO = getLangOpts().ElideConstructors && D.isNRVOVariable(); + if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) { address = OpenMPLocalAddr; } else if (Ty->isConstantSizeType()) { - bool NRVO = getLangOpts().ElideConstructors && - D.isNRVOVariable(); - // If this value is an array or struct with a statically determinable // constant initializer, there are optimizations we can do. // @@ -1561,8 +1560,16 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // Emit debug info for local var declaration. if (EmitDebugInfo && HaveInsertPoint()) { + Address DebugAddr = address; + bool UsePointerValue = NRVO && ReturnValuePointer.isValid(); DI->setLocation(D.getLocation()); - (void)DI->EmitDeclareOfAutoVariable(&D, address.getPointer(), Builder); + + // If NRVO, use a pointer to the return address. + if (UsePointerValue) + DebugAddr = ReturnValuePointer; + + (void)DI->EmitDeclareOfAutoVariable(&D, DebugAddr.getPointer(), Builder, + UsePointerValue); } if (D.hasAttr<AnnotateAttr>() && HaveInsertPoint()) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index b9573f71a3a..581bbe5efaf 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -895,6 +895,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, if (CurFnInfo->getReturnInfo().isSRetAfterThis()) ++AI; ReturnValue = Address(&*AI, CurFnInfo->getReturnInfo().getIndirectAlign()); + if (!CurFnInfo->getReturnInfo().getIndirectByVal()) { + ReturnValuePointer = + CreateDefaultAlignTempAlloca(Int8PtrTy, "result.ptr"); + Builder.CreateStore(Builder.CreatePointerBitCastOrAddrSpaceCast( + ReturnValue.getPointer(), Int8PtrTy), + ReturnValuePointer); + } } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca && !hasScalarEvaluationKind(CurFnInfo->getReturnType())) { // Load the sret pointer from the argument struct and return into that. @@ -902,6 +909,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, llvm::Function::arg_iterator EI = CurFn->arg_end(); --EI; llvm::Value *Addr = Builder.CreateStructGEP(nullptr, &*EI, Idx); + ReturnValuePointer = Address(Addr, getPointerAlign()); Addr = Builder.CreateAlignedLoad(Addr, getPointerAlign(), "agg.result"); ReturnValue = Address(Addr, getNaturalTypeAlignment(RetTy)); } else { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index b274f45867a..e95a07ce0e4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -327,6 +327,10 @@ public: /// value. This is invalid iff the function has no return value. Address ReturnValue = Address::invalid(); + /// ReturnValuePointer - The temporary alloca to hold a pointer to sret. + /// This is invalid if sret is not in use. + Address ReturnValuePointer = Address::invalid(); + /// Return true if a label was seen in the current scope. bool hasLabelBeenSeenInCurrentScope() const { if (CurLexicalScope) |