From 10dd55c548e802f3d1769f7e4e13bb1565b824e5 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 24 Jun 2016 17:55:40 +0000 Subject: [codeview] Emit parameter variables in the right order Clang emits them in reverse order to conform to the ABI, which requires left-to-right destruction. As a result, the order doesn't fall out naturally, and we have to sort things out in the backend. Fixes PR28213 llvm-svn: 273696 --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 25 +++++++++++++++++++++---- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h | 4 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'llvm/lib/CodeGen/AsmPrinter') diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index ca2482a5646..e01ee0984ed 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -504,8 +504,7 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, OS.EmitLabel(InlineEnd); - for (const LocalVariable &Var : Site.InlinedLocals) - emitLocalVariable(Var); + emitLocalVariableList(Site.InlinedLocals); // Recurse on child inlined call sites before closing the scope. for (const DILocation *ChildSite : Site.ChildSites) { @@ -608,8 +607,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, emitNullTerminatedSymbolName(OS, FuncName); OS.EmitLabel(ProcRecordEnd); - for (const LocalVariable &Var : FI.Locals) - emitLocalVariable(Var); + emitLocalVariableList(FI.Locals); // Emit inlined call site information. Only emit functions inlined directly // into the parent function. We'll emit the other sites recursively as part @@ -1680,6 +1678,25 @@ void CodeViewDebug::emitDeferredCompleteTypes() { } } +void CodeViewDebug::emitLocalVariableList(ArrayRef Locals) { + // Get the sorted list of parameters and emit them first. + SmallVector Params; + for (const LocalVariable &L : Locals) + if (L.DIVar->isParameter()) + Params.push_back(&L); + std::sort(Params.begin(), Params.end(), + [](const LocalVariable *L, const LocalVariable *R) { + return L->DIVar->getArg() < R->DIVar->getArg(); + }); + for (const LocalVariable *L : Params) + emitLocalVariable(*L); + + // Next emit all non-parameters in the order that we found them. + for (const LocalVariable &L : Locals) + if (!L.DIVar->isParameter()) + emitLocalVariable(L); +} + void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) { // LocalSym record, see SymbolRecord.h for more info. MCSymbol *LocalBegin = MMI->getContext().createTempSymbol(), diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index 53493725c13..51dd5df1027 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -220,6 +220,10 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { /// particular, locals from inlined code live inside the inlining site. void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc); + /// Emits local variables in the appropriate order. + void emitLocalVariableList(ArrayRef Locals); + + /// Emits an S_LOCAL record and its associated defined ranges. void emitLocalVariable(const LocalVariable &Var); /// Translates the DIType to codeview if necessary and returns a type index -- cgit v1.2.3