akhuang updated this revision to Diff 205385.
akhuang added a comment.
- add semicolon
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63361/new/
https://reviews.llvm.org/D63361
Files:
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDecl.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h
debuginfo-tests/nrvo-string.cpp
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1142,9 +1142,15 @@
// If the variable has an attached offset expression, extract it.
// FIXME: Try to handle DW_OP_deref as well.
int64_t ExprOffset = 0;
- if (VI.Expr)
- if (!VI.Expr->extractIfOffset(ExprOffset))
+ bool Deref = false;
+ if (VI.Expr) {
+ // If there is one DW_OP_deref element, use offset of 0 and keep going.
+ if (VI.Expr->getNumElements() == 1 &&
+ VI.Expr->getElement(0) == llvm::dwarf::DW_OP_deref)
+ Deref = true;
+ else if (!VI.Expr->extractIfOffset(ExprOffset))
continue;
+ }
// Get the frame register used and the offset.
unsigned FrameReg = 0;
@@ -1154,6 +1160,7 @@
// Calculate the label ranges.
LocalVarDefRange DefRange =
createDefRangeMem(CVReg, FrameOffset + ExprOffset);
+
for (const InsnRange &Range : Scope->getRanges()) {
const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
const MCSymbol *End = getLabelAfterInsn(Range.second);
@@ -1164,6 +1171,9 @@
LocalVariable Var;
Var.DIVar = VI.Var;
Var.DefRanges.emplace_back(std::move(DefRange));
+ if (Deref)
+ Var.UseReferenceType = true;
+
recordLocalVariable(std::move(Var), Scope);
}
}
Index: debuginfo-tests/nrvo-string.cpp
===================================================================
--- debuginfo-tests/nrvo-string.cpp
+++ debuginfo-tests/nrvo-string.cpp
@@ -17,11 +17,32 @@
string get_string() {
string unused;
string result = 3;
-// DEBUGGER: break 21
+ // DEBUGGER: break 21
return result;
}
-int main() { get_string(); }
+void some_function(int) {}
+struct string2 {
+ string2() = default;
+ string2(string2 &&other) { i = other.i; }
+ int i;
+};
+string2 get_string2() {
+ string2 result;
+ result.i = 5;
+ some_function(result.i);
+ // Test that the debugger can get the value of result after another
+ // function is called.
+ // DEBUGGER: break 35
+ return result;
+}
+int main() {
+ get_string();
+ get_string2();
+}
// DEBUGGER: r
// DEBUGGER: print result.i
// CHECK: = 3
+// DEBUGGER: c
+// DEBUGGER: print result.i
+// CHECK: = 5
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -327,6 +327,10 @@
/// 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)
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -895,6 +895,10 @@
if (CurFnInfo->getReturnInfo().isSRetAfterThis())
++AI;
ReturnValue = Address(&*AI, CurFnInfo->getReturnInfo().getIndirectAlign());
+ 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.
@@ -904,6 +908,10 @@
llvm::Value *Addr = Builder.CreateStructGEP(nullptr, &*EI, Idx);
Addr = Builder.CreateAlignedLoad(Addr, getPointerAlign(), "agg.result");
ReturnValue = Address(Addr, getNaturalTypeAlignment(RetTy));
+ ReturnValuePointer = CreateDefaultAlignTempAlloca(Int8PtrTy, "result.ptr");
+ Builder.CreateStore(Builder.CreatePointerBitCastOrAddrSpaceCast(
+ ReturnValue.getPointer(), Int8PtrTy),
+ ReturnValuePointer);
} else {
ReturnValue = CreateIRTemp(RetTy, "retval");
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -1403,12 +1403,11 @@
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,14 @@
// Emit debug info for local var declaration.
if (EmitDebugInfo && HaveInsertPoint()) {
+ Address DebugAddr = address;
DI->setLocation(D.getLocation());
- (void)DI->EmitDeclareOfAutoVariable(&D, address.getPointer(), Builder);
+
+ // If NRVO, use a pointer to the return address.
+ if (NRVO && ReturnValuePointer.isValid())
+ DebugAddr = ReturnValuePointer;
+
+ (void)DI->EmitDeclareOfAutoVariable(&D, DebugAddr.getPointer(), Builder);
}
if (D.hasAttr<AnnotateAttr>() && HaveInsertPoint())
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3940,6 +3940,12 @@
}
}
+ // 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 (VD->isNRVOVariable())
+ 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,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits