[ASTPrinter] Print nested name specifiers for out-of-line functions
authorAlex Lorenz <arphaman@gmail.com>
Tue, 11 Apr 2017 16:46:03 +0000 (16:46 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Tue, 11 Apr 2017 16:46:03 +0000 (16:46 +0000)
rdar://31501863

llvm-svn: 299962

clang/lib/AST/DeclPrinter.cpp
clang/lib/AST/DeclarationName.cpp
clang/test/Index/comment-cplus-decls.cpp
clang/test/Index/overriding-method-comments.mm
clang/test/Misc/ast-print-out-of-line-func.cpp [new file with mode: 0644]

index aedc35b..5d841a1 100644 (file)
@@ -504,7 +504,14 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
 
   PrintingPolicy SubPolicy(Policy);
   SubPolicy.SuppressSpecifiers = false;
-  std::string Proto = D->getNameInfo().getAsString();
+  std::string Proto;
+  if (!Policy.SuppressScope) {
+    if (const NestedNameSpecifier *NS = D->getQualifier()) {
+      llvm::raw_string_ostream OS(Proto);
+      NS->print(OS, Policy);
+    }
+  }
+  Proto += D->getNameInfo().getAsString();
   if (GuideDecl)
     Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
   if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
index 6053bd7..1f8e26d 100644 (file)
@@ -660,7 +660,9 @@ void DeclarationNameInfo::printName(raw_ostream &OS) const {
       LangOptions LO;
       LO.CPlusPlus = true;
       LO.Bool = true;
-      OS << TInfo->getType().getAsString(PrintingPolicy(LO));
+      PrintingPolicy PP(LO);
+      PP.SuppressScope = true;
+      OS << TInfo->getType().getAsString(PP);
     } else
       OS << Name;
     return;
index 463aa9e..6e32c60 100644 (file)
@@ -102,7 +102,7 @@ namespace test0 {
     friend void ns::f(int a);
   };
 }
-// CHECK: <Declaration>friend void f(int a)</Declaration>
+// CHECK: <Declaration>friend void ns::f(int a)</Declaration>
 
 namespace test1 {
   template <class T> struct Outer {
@@ -115,7 +115,7 @@ namespace test1 {
     };
   };
 }
-// CHECK: <Declaration>friend void foo(T)</Declaration>
+// CHECK: <Declaration>friend void Outer&lt;T&gt;::foo(T)</Declaration>
 
 namespace test2 {
   namespace foo {
@@ -129,7 +129,7 @@ namespace test2 {
     friend void ::test2::foo::Func(int x);
   };
 }
-// CHECK: <Declaration>friend void Func(int x)</Declaration>
+// CHECK: <Declaration>friend void ::test2::foo::Func(int x)</Declaration>
 
 namespace test3 {
   template<class T> class vector {
@@ -149,7 +149,7 @@ namespace test3 {
   };
 }
 // CHECK: <Declaration>void f(const T &amp;t = T())</Declaration>
-// CHECK: <Declaration>friend void f(const test3::A &amp;)</Declaration>
+// CHECK: <Declaration>friend void vector&lt;A&gt;::f(const test3::A &amp;)</Declaration>
 
 class MyClass
 {
index d995e0e..824d055 100644 (file)
@@ -78,7 +78,7 @@ struct Base {
 
 void Base::foo_outofline(int RRR) {}
 
-// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-2]]" column="12"><Name>foo_outofline</Name><USR>c:@S@Base@F@foo_outofline#I#</USR><Declaration>void foo_outofline(int RRR)</Declaration><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>RRR</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to undefined virtual.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-2]]" column="12"><Name>foo_outofline</Name><USR>c:@S@Base@F@foo_outofline#I#</USR><Declaration>void Base::foo_outofline(int RRR)</Declaration><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>RRR</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to undefined virtual.</Para></Discussion></Parameter></Parameters></Function>]
 
 struct Derived : public Base {
   virtual void foo_pure(int PPP);
diff --git a/clang/test/Misc/ast-print-out-of-line-func.cpp b/clang/test/Misc/ast-print-out-of-line-func.cpp
new file mode 100644 (file)
index 0000000..7c4f7ae
--- /dev/null
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -ast-print -std=c++14 %s | FileCheck %s
+
+namespace ns {
+
+struct Wrapper {
+class Inner {
+  Inner();
+  Inner(int);
+  ~Inner();
+
+  void operator += (int);
+
+  template<typename T>
+  void member();
+
+  static void staticMember();
+
+  operator int();
+
+  operator ns::Wrapper();
+  // CHECK: operator ns::Wrapper()
+};
+};
+
+Wrapper::Inner::Inner() { }
+// CHECK: Wrapper::Inner::Inner()
+
+void Wrapper::Inner::operator +=(int) { }
+// CHECK: void Wrapper::Inner::operator+=(int)
+
+}
+
+ns::Wrapper::Inner::Inner(int) { }
+// CHECK: ns::Wrapper::Inner::Inner(int)
+
+ns::Wrapper::Inner::~Inner() { }
+// CHECK: ns::Wrapper::Inner::~Inner()
+
+template<typename T>
+void ::ns::Wrapper::Inner::member() { }
+// CHECK: template <typename T> void ::ns::Wrapper::Inner::member()
+
+ns::Wrapper::Inner::operator int() { return 0; }
+// CHECK: ns::Wrapper::Inner::operator int()
+
+ns::Wrapper::Inner::operator ::ns::Wrapper() { return ns::Wrapper(); }
+// CHECK: ns::Wrapper::Inner::operator ::ns::Wrapper()
+
+namespace ns {
+
+void Wrapper::Inner::staticMember() { }
+// CHECK: void Wrapper::Inner::staticMember()
+
+}