<div dir="ltr">Reverted and re-landed with a fix to this.<div>This should've been an NFC, but I missed one corner case. Sorry about that.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 25, 2019 at 4:22 PM Nico Weber <<a href="mailto:thakis@chromium.org">thakis@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Is it possible that this broke Tooling/clang-diff-ast.cpp <a href="http://lab.llvm.org:8011/builders/clang-cmake-x86_64-avx2-linux/builds/11395/steps/ninja%20check%201/logs/FAIL%3A%20Clang%3A%3Aclang-diff-ast.cpp" target="_blank">http://lab.llvm.org:8011/builders/clang-cmake-x86_64-avx2-linux/builds/11395/steps/ninja%20check%201/logs/FAIL%3A%20Clang%3A%3Aclang-diff-ast.cpp</a> ?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 25, 2019 at 9:07 AM Ilya Biryukov via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: ibiryukov<br>
Date: Wed Sep 25 06:09:10 2019<br>
New Revision: 372863<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=372863&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=372863&view=rev</a><br>
Log:<br>
[AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName<br>
<br>
Summary:<br>
To be used in clangd, e.g. in D66647.<br>
Currently the alternative to this function is doing string manipulation on results of `printQualifiedName`, which is<br>
hard-to-impossible to get right in presence of template arguments.<br>
<br>
Reviewers: kadircet, aaron.ballman<br>
<br>
Reviewed By: kadircet, aaron.ballman<br>
<br>
Subscribers: aaron.ballman, usaxena95, cfe-commits<br>
<br>
Tags: #clang<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D67825" rel="noreferrer" target="_blank">https://reviews.llvm.org/D67825</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/Decl.h<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/unittests/AST/NamedDeclPrinterTest.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/Decl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=372863&r1=372862&r2=372863&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=372863&r1=372862&r2=372863&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Decl.h (original)<br>
+++ cfe/trunk/include/clang/AST/Decl.h Wed Sep 25 06:09:10 2019<br>
@@ -310,6 +310,14 @@ public:<br>
   void printQualifiedName(raw_ostream &OS) const;<br>
   void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;<br>
<br>
+  /// Print only the nested name specifier part of a fully-qualified name,<br>
+  /// including the '::' at the end. E.g.<br>
+  ///    when `printQualifiedName(D)` prints "A::B::i",<br>
+  ///    this function prints "A::B::".<br>
+  void printNestedNameSpecifier(raw_ostream &OS) const;<br>
+  void printNestedNameSpecifier(raw_ostream &OS,<br>
+                                const PrintingPolicy &Policy) const;<br>
+<br>
   // FIXME: Remove string version.<br>
   std::string getQualifiedNameAsString() const;<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=372863&r1=372862&r2=372863&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=372863&r1=372862&r2=372863&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Wed Sep 25 06:09:10 2019<br>
@@ -1558,6 +1558,19 @@ void NamedDecl::printQualifiedName(raw_o<br>
<br>
 void NamedDecl::printQualifiedName(raw_ostream &OS,<br>
                                    const PrintingPolicy &P) const {<br>
+  printNestedNameSpecifier(OS, P);<br>
+  if (getDeclName() || isa<DecompositionDecl>(this))<br>
+    OS << *this;<br>
+  else<br>
+    OS << "(anonymous)";<br>
+}<br>
+<br>
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const {<br>
+  printNestedNameSpecifier(OS, getASTContext().getPrintingPolicy());<br>
+}<br>
+<br>
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,<br>
+                                         const PrintingPolicy &P) const {<br>
   const DeclContext *Ctx = getDeclContext();<br>
<br>
   // For ObjC methods and properties, look through categories and use the<br>
@@ -1571,10 +1584,8 @@ void NamedDecl::printQualifiedName(raw_o<br>
         Ctx = ID;<br>
   }<br>
<br>
-  if (Ctx->isFunctionOrMethod()) {<br>
-    printName(OS);<br>
+  if (Ctx->isFunctionOrMethod())<br>
     return;<br>
-  }<br>
<br>
   using ContextsTy = SmallVector<const DeclContext *, 8>;<br>
   ContextsTy Contexts;<br>
@@ -1644,11 +1655,6 @@ void NamedDecl::printQualifiedName(raw_o<br>
     }<br>
     OS << "::";<br>
   }<br>
-<br>
-  if (getDeclName() || isa<DecompositionDecl>(this))<br>
-    OS << *this;<br>
-  else<br>
-    OS << "(anonymous)";<br>
 }<br>
<br>
 void NamedDecl::getNameForDiagnostic(raw_ostream &OS,<br>
<br>
Modified: cfe/trunk/unittests/AST/NamedDeclPrinterTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/NamedDeclPrinterTest.cpp?rev=372863&r1=372862&r2=372863&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/NamedDeclPrinterTest.cpp?rev=372863&r1=372862&r2=372863&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/unittests/AST/NamedDeclPrinterTest.cpp (original)<br>
+++ cfe/trunk/unittests/AST/NamedDeclPrinterTest.cpp Wed Sep 25 06:09:10 2019<br>
@@ -16,9 +16,12 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "clang/AST/ASTContext.h"<br>
+#include "clang/AST/Decl.h"<br>
+#include "clang/AST/PrettyPrinter.h"<br>
 #include "clang/ASTMatchers/ASTMatchFinder.h"<br>
 #include "clang/Tooling/Tooling.h"<br>
 #include "llvm/ADT/SmallString.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
 #include "gtest/gtest.h"<br>
<br>
 using namespace clang;<br>
@@ -30,11 +33,12 @@ namespace {<br>
 class PrintMatch : public MatchFinder::MatchCallback {<br>
   SmallString<1024> Printed;<br>
   unsigned NumFoundDecls;<br>
-  bool SuppressUnwrittenScope;<br>
+  std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer;<br>
<br>
 public:<br>
-  explicit PrintMatch(bool suppressUnwrittenScope)<br>
-    : NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope) {}<br>
+  explicit PrintMatch(<br>
+      std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer)<br>
+      : NumFoundDecls(0), Printer(std::move(Printer)) {}<br>
<br>
   void run(const MatchFinder::MatchResult &Result) override {<br>
     const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id");<br>
@@ -45,9 +49,7 @@ public:<br>
       return;<br>
<br>
     llvm::raw_svector_ostream Out(Printed);<br>
-    PrintingPolicy Policy = Result.Context->getPrintingPolicy();<br>
-    Policy.SuppressUnwrittenScope = SuppressUnwrittenScope;<br>
-    ND->printQualifiedName(Out, Policy);<br>
+    Printer(Out, ND);<br>
   }<br>
<br>
   StringRef getPrinted() const {<br>
@@ -59,12 +61,12 @@ public:<br>
   }<br>
 };<br>
<br>
-::testing::AssertionResult<br>
-PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,<br>
-                        bool SuppressUnwrittenScope,<br>
-                        const DeclarationMatcher &NodeMatch,<br>
-                        StringRef ExpectedPrinted, StringRef FileName) {<br>
-  PrintMatch Printer(SuppressUnwrittenScope);<br>
+::testing::AssertionResult PrintedDeclMatches(<br>
+    StringRef Code, const std::vector<std::string> &Args,<br>
+    const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted,<br>
+    StringRef FileName,<br>
+    std::function<void(llvm::raw_ostream &, const NamedDecl *)> Print) {<br>
+  PrintMatch Printer(std::move(Print));<br>
   MatchFinder Finder;<br>
   Finder.addMatcher(NodeMatch, &Printer);<br>
   std::unique_ptr<FrontendActionFactory> Factory =<br>
@@ -92,6 +94,21 @@ PrintedNamedDeclMatches(StringRef Code,<br>
 }<br>
<br>
 ::testing::AssertionResult<br>
+PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,<br>
+                        bool SuppressUnwrittenScope,<br>
+                        const DeclarationMatcher &NodeMatch,<br>
+                        StringRef ExpectedPrinted, StringRef FileName) {<br>
+  return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, FileName,<br>
+                            [=](llvm::raw_ostream &Out, const NamedDecl *ND) {<br>
+                              auto Policy =<br>
+                                  ND->getASTContext().getPrintingPolicy();<br>
+                              Policy.SuppressUnwrittenScope =<br>
+                                  SuppressUnwrittenScope;<br>
+                              ND->printQualifiedName(Out, Policy);<br>
+                            });<br>
+}<br>
+<br>
+::testing::AssertionResult<br>
 PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,<br>
                              StringRef ExpectedPrinted) {<br>
   std::vector<std::string> Args(1, "-std=c++98");<br>
@@ -127,6 +144,17 @@ PrintedWrittenPropertyDeclObjCMatches(St<br>
                                  "input.m");<br>
 }<br>
<br>
+::testing::AssertionResult<br>
+PrintedNestedNameSpecifierMatches(StringRef Code, StringRef DeclName,<br>
+                                  StringRef ExpectedPrinted) {<br>
+  std::vector<std::string> Args{"-std=c++11"};<br>
+  return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"),<br>
+                            ExpectedPrinted, "input.cc",<br>
+                            [](llvm::raw_ostream &Out, const NamedDecl *D) {<br>
+                              D->printNestedNameSpecifier(Out);<br>
+                            });<br>
+}<br>
+<br>
 } // unnamed namespace<br>
<br>
 TEST(NamedDeclPrinter, TestNamespace1) {<br>
@@ -223,3 +251,21 @@ R"(<br>
     "property",<br>
     "Obj::property"));<br>
 }<br>
+<br>
+TEST(NamedDeclPrinter, NestedNameSpecifierSimple) {<br>
+  const char *Code =<br>
+      R"(<br>
+  namespace foo { namespace bar { void func(); }  }<br>
+)";<br>
+  ASSERT_TRUE(PrintedNestedNameSpecifierMatches(Code, "func", "foo::bar::"));<br>
+}<br>
+<br>
+TEST(NamedDeclPrinter, NestedNameSpecifierTemplateArgs) {<br>
+  const char *Code =<br>
+      R"(<br>
+        template <class T> struct vector;<br>
+        template <> struct vector<int> { int method(); };<br>
+)";<br>
+  ASSERT_TRUE(<br>
+      PrintedNestedNameSpecifierMatches(Code, "method", "vector<int>::"));<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Regards,</div><div>Ilya Biryukov</div></div></div></div></div>