r255744 - Print qualified display names when emitting CodeView

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 15 18:04:41 PST 2015


Author: rnk
Date: Tue Dec 15 20:04:40 2015
New Revision: 255744

URL: http://llvm.org/viewvc/llvm-project?rev=255744&view=rev
Log:
Print qualified display names when emitting CodeView

This is what debuggers expect.  Words towards fixing PR21528.

Added:
    cfe/trunk/test/CodeGenCXX/debug-info-codeview-display-name.cpp
Modified:
    cfe/trunk/include/clang/AST/PrettyPrinter.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/TemplateBase.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp

Modified: cfe/trunk/include/clang/AST/PrettyPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/PrettyPrinter.h?rev=255744&r1=255743&r2=255744&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/PrettyPrinter.h (original)
+++ cfe/trunk/include/clang/AST/PrettyPrinter.h Tue Dec 15 20:04:40 2015
@@ -42,7 +42,7 @@ struct PrintingPolicy {
       SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
       Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),
       Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
-      IncludeNewlines(true) { }
+      IncludeNewlines(true), MSVCFormatting(false) { }
 
   /// \brief What language we're printing.
   LangOptions LangOpts;
@@ -163,6 +163,11 @@ struct PrintingPolicy {
 
   /// \brief When true, include newlines after statements like "break", etc.
   unsigned IncludeNewlines : 1;
+
+  /// \brief Use whitespace and punctuation like MSVC does. In particular, this
+  /// prints anonymous namespaces as `anonymous namespace' and does not insert
+  /// spaces after template arguments.
+  bool MSVCFormatting : 1;
 };
 
 } // end namespace clang

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=255744&r1=255743&r2=255744&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Dec 15 20:04:40 2015
@@ -1434,8 +1434,10 @@ void NamedDecl::printQualifiedName(raw_o
       if (P.SuppressUnwrittenScope &&
           (ND->isAnonymousNamespace() || ND->isInline()))
         continue;
-      if (ND->isAnonymousNamespace())
-        OS << "(anonymous namespace)";
+      if (ND->isAnonymousNamespace()) {
+        OS << (P.MSVCFormatting ? "`anonymous namespace\'"
+                                : "(anonymous namespace)");
+      }
       else
         OS << *ND;
     } else if (const auto *RD = dyn_cast<RecordDecl>(*I)) {

Modified: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=255744&r1=255743&r2=255744&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Tue Dec 15 20:04:40 2015
@@ -53,7 +53,7 @@ static void printIntegral(const Template
     }
   }
 
-  if (T->isBooleanType()) {
+  if (T->isBooleanType() && !Policy.MSVCFormatting) {
     Out << (Val.getBoolValue() ? "true" : "false");
   } else if (T->isCharType()) {
     const char Ch = Val.getZExtValue();

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=255744&r1=255743&r2=255744&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Tue Dec 15 20:04:40 2015
@@ -925,12 +925,13 @@ void TypePrinter::printTag(TagDecl *D, r
   } else {
     // Make an unambiguous representation for anonymous types, e.g.
     //   (anonymous enum at /usr/include/string.h:120:9)
-    
+    OS << (Policy.MSVCFormatting ? '`' : '(');
+
     if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
-      OS << "(lambda";
+      OS << "lambda";
       HasKindDecoration = true;
     } else {
-      OS << "(anonymous";
+      OS << "anonymous";
     }
     
     if (Policy.AnonymousTagLocations) {
@@ -948,8 +949,8 @@ void TypePrinter::printTag(TagDecl *D, r
            << ':' << PLoc.getColumn();
       }
     }
-    
-    OS << ')';
+
+    OS << (Policy.MSVCFormatting ? '\'' : ')');
   }
 
   // If this is a class template specialization, print the template
@@ -1401,6 +1402,7 @@ TemplateSpecializationType::PrintTemplat
                                                 unsigned NumArgs,
                                                   const PrintingPolicy &Policy,
                                                       bool SkipBrackets) {
+  const char *Comma = Policy.MSVCFormatting ? "," : ", ";
   if (!SkipBrackets)
     OS << '<';
   
@@ -1411,14 +1413,14 @@ TemplateSpecializationType::PrintTemplat
     llvm::raw_svector_ostream ArgOS(Buf);
     if (Args[Arg].getKind() == TemplateArgument::Pack) {
       if (Args[Arg].pack_size() && Arg > 0)
-        OS << ", ";
+        OS << Comma;
       PrintTemplateArgumentList(ArgOS,
                                 Args[Arg].pack_begin(), 
                                 Args[Arg].pack_size(), 
                                 Policy, true);
     } else {
       if (Arg > 0)
-        OS << ", ";
+        OS << Comma;
       Args[Arg].print(Policy, ArgOS);
     }
     StringRef ArgString = ArgOS.str();
@@ -1450,11 +1452,12 @@ PrintTemplateArgumentList(raw_ostream &O
                           const TemplateArgumentLoc *Args, unsigned NumArgs,
                           const PrintingPolicy &Policy) {
   OS << '<';
+  const char *Comma = Policy.MSVCFormatting ? "," : ", ";
 
   bool needSpace = false;
   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
     if (Arg > 0)
-      OS << ", ";
+      OS << Comma;
     
     // Print the argument into a string.
     SmallString<128> Buf;

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=255744&r1=255743&r2=255744&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Dec 15 20:04:40 2015
@@ -183,22 +183,31 @@ StringRef CGDebugInfo::getFunctionName(c
   IdentifierInfo *FII = FD->getIdentifier();
   FunctionTemplateSpecializationInfo *Info =
       FD->getTemplateSpecializationInfo();
-  if (!Info && FII)
+
+  if (!Info && FII && !CGM.getCodeGenOpts().EmitCodeView)
     return FII->getName();
 
   // Otherwise construct human readable name for debug info.
   SmallString<128> NS;
   llvm::raw_svector_ostream OS(NS);
-  FD->printName(OS);
+  PrintingPolicy Policy(CGM.getLangOpts());
 
-  // Add any template specialization args.
-  if (Info) {
-    const TemplateArgumentList *TArgs = Info->TemplateArguments;
-    const TemplateArgument *Args = TArgs->data();
-    unsigned NumArgs = TArgs->size();
-    PrintingPolicy Policy(CGM.getLangOpts());
-    TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, NumArgs,
-                                                          Policy);
+  if (CGM.getCodeGenOpts().EmitCodeView) {
+    // Print a fully qualified name like MSVC would.
+    Policy.MSVCFormatting = true;
+    FD->printQualifiedName(OS, Policy);
+  } else {
+    // Print the unqualified name with some template arguments. This is what
+    // DWARF-based debuggers expect.
+    FD->printName(OS);
+    // Add any template specialization args.
+    if (Info) {
+      const TemplateArgumentList *TArgs = Info->TemplateArguments;
+      const TemplateArgument *Args = TArgs->data();
+      unsigned NumArgs = TArgs->size();
+      TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, NumArgs,
+                                                            Policy);
+    }
   }
 
   // Copy this name on the side and use its reference.

Added: cfe/trunk/test/CodeGenCXX/debug-info-codeview-display-name.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-codeview-display-name.cpp?rev=255744&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-codeview-display-name.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/debug-info-codeview-display-name.cpp Tue Dec 15 20:04:40 2015
@@ -0,0 +1,73 @@
+// 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
+
+void freefunc() { }
+// CHECK-DAG: "freefunc"
+
+namespace N {
+  int b() { return 0; }
+// CHECK-DAG: "N::b"
+  namespace { void func() { } }
+// CHECK-DAG: "N::`anonymous namespace'::func
+}
+
+void _c(void) {
+  N::func();
+}
+// CHECK-DAG: "_c"
+
+struct foo {
+  int operator+(int);
+  foo(){}
+// CHECK-DAG: "foo::foo"
+
+  ~foo(){}
+// CHECK-DAG: "foo::~foo"
+
+  foo(int i){}
+// CHECK-DAG: "foo::foo"
+
+  foo(char *q){}
+// CHECK-DAG: "foo::foo"
+
+  static foo* static_method() { return 0; }
+// CHECK-DAG: "foo::static_method"
+
+};
+
+void use_foo() {
+  foo f1, f2(1), f3((char*)0);
+  foo::static_method();
+}
+
+// CHECK-DAG: "foo::operator+"
+int foo::operator+(int a) { return a; }
+
+// PR17371
+struct OverloadedNewDelete {
+  // __cdecl
+  void *operator new(__SIZE_TYPE__);
+  void *operator new[](__SIZE_TYPE__);
+  void operator delete(void *);
+  void operator delete[](void *);
+  // __thiscall
+  int operator+(int);
+};
+
+void *OverloadedNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
+void *OverloadedNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
+void OverloadedNewDelete::operator delete(void *) { }
+void OverloadedNewDelete::operator delete[](void *) { }
+int OverloadedNewDelete::operator+(int x) { return x; };
+
+// CHECK-DAG: "OverloadedNewDelete::operator new"
+// CHECK-DAG: "OverloadedNewDelete::operator new[]"
+// CHECK-DAG: "OverloadedNewDelete::operator delete"
+// CHECK-DAG: "OverloadedNewDelete::operator delete[]"
+// CHECK-DAG: "OverloadedNewDelete::operator+"
+
+template <void (*)(void)>
+void fn_tmpl() {}
+
+template void fn_tmpl<freefunc>();
+// CHECK-DAG: "fn_tmpl"




More information about the cfe-commits mailing list