<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">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">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>