[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
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index ca2482a..e01ee09 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -504,8 +504,7 @@
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 @@
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::emitLocalVariableList(ArrayRef<LocalVariable> Locals) {
+ // Get the sorted list of parameters and emit them first.
+ SmallVector<const LocalVariable *, 6> 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(),