FunctionTemplateSpecializationInfo *Info =
FD->getTemplateSpecializationInfo();
- if (!Info && FII)
+ // Emit the unqualified name in normal operation. LLVM and the debugger can
+ // compute the fully qualified name from the scope chain. If we're only
+ // emitting line table info, there won't be any scope chains, so emit the
+ // fully qualified name here so that stack traces are more accurate.
+ // FIXME: Do this when emitting DWARF as well as when emitting CodeView after
+ // evaluating the size impact.
+ bool UseQualifiedName = DebugKind == codegenoptions::DebugLineTablesOnly &&
+ CGM.getCodeGenOpts().EmitCodeView;
+
+ if (!Info && FII && !UseQualifiedName)
return FII->getName();
- // Otherwise construct human readable name for debug info.
SmallString<128> NS;
llvm::raw_svector_ostream OS(NS);
PrintingPolicy Policy(CGM.getLangOpts());
Policy.MSVCFormatting = CGM.getCodeGenOpts().EmitCodeView;
+ if (!UseQualifiedName)
+ FD->printName(OS);
+ else
+ FD->printQualifiedName(OS, Policy);
- // Print the unqualified name with some template arguments.
- FD->printName(OS);
// Add any template specialization args.
if (Info) {
const TemplateArgumentList *TArgs = Info->TemplateArguments;
-// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98 | \
-// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | FileCheck %s
+// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
+// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
+// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
+// RUN: %clang_cc1 -fblocks -debug-info-kind=line-tables-only -gcodeview -emit-llvm %s \
+// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
+// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=QUAL
void freefunc() { }
// CHECK-DAG: "freefunc"
namespace N {
int b() { return 0; }
-// CHECK-DAG: "b"
+// UNQUAL-DAG: "b"
+// QUAL-DAG: "N::b"
namespace { void func() { } }
-// CHECK-DAG: "func"
+// UNQUAL-DAG: "func"
+// QUAL-DAG: "N::`anonymous namespace'::func"
}
void _c(void) {
struct foo {
int operator+(int);
foo(){}
-// CHECK-DAG: "foo"
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
~foo(){}
-// CHECK-DAG: "~foo"
+// UNQUAL-DAG: "~foo"
+// QUAL-DAG: "foo::~foo"
foo(int i){}
-// CHECK-DAG: "foo"
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
foo(char *q){}
-// CHECK-DAG: "foo"
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
static foo* static_method() { return 0; }
-// CHECK-DAG: "static_method"
+// UNQUAL-DAG: "static_method"
+// QUAL-DAG: "foo::static_method"
};
foo::static_method();
}
-// CHECK-DAG: "operator+"
+// UNQUAL-DAG: "operator+"
+// QUAL-DAG: "foo::operator+"
int foo::operator+(int a) { return a; }
// PR17371
void OverloadedNewDelete::operator delete[](void *) { }
int OverloadedNewDelete::operator+(int x) { return x; };
-// CHECK-DAG: "operator new"
-// CHECK-DAG: "operator new[]"
-// CHECK-DAG: "operator delete"
-// CHECK-DAG: "operator delete[]"
-// CHECK-DAG: "operator+"
+// UNQUAL-DAG: "operator new"
+// UNQUAL-DAG: "operator new[]"
+// UNQUAL-DAG: "operator delete"
+// UNQUAL-DAG: "operator delete[]"
+// UNQUAL-DAG: "operator+"
+// QUAL-DAG: "OverloadedNewDelete::operator new"
+// QUAL-DAG: "OverloadedNewDelete::operator new[]"
+// QUAL-DAG: "OverloadedNewDelete::operator delete"
+// QUAL-DAG: "OverloadedNewDelete::operator delete[]"
+// QUAL-DAG: "OverloadedNewDelete::operator+"
+
template <typename T, void (*)(void)>
void fn_tmpl() {}