aboutsummaryrefslogtreecommitdiffstats
path: root/dist
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2018-01-16 09:07:46 +0100
committerNikolai Kosjar <nikolai.kosjar@qt.io>2018-01-16 10:10:20 +0000
commit1a706b410cf431d344e818248ef1f5f964a47176 (patch)
treeb495021c967222f133346b56c78bec68f9619fe9 /dist
parent3c745a9eaabcab8a6cc8bda578545cb67439e350 (diff)
Clang: Add patches improving pretty printing declarations
Change-Id: I36b57c12998b959a3c7c350628c29beab46457b5 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'dist')
-rw-r--r--dist/clang/patches/170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch144
-rw-r--r--dist/clang/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch543
-rw-r--r--dist/clang/patches/README.md11
3 files changed, 698 insertions, 0 deletions
diff --git a/dist/clang/patches/170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch b/dist/clang/patches/170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch
new file mode 100644
index 0000000000..304e80a2ff
--- /dev/null
+++ b/dist/clang/patches/170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch
@@ -0,0 +1,144 @@
+From 363747b90f66f097fd45a6cd665adbaf7612188a Mon Sep 17 00:00:00 2001
+From: Nikolai Kosjar <nikolai.kosjar@qt.io>
+Date: Mon, 15 Jan 2018 12:51:18 +0100
+Subject: [PATCH 2/3] Backport: [DeclPrinter] Allow printing fully qualified
+ name of function declaration
+
+https://reviews.llvm.org/D40013
+---
+ include/clang/AST/PrettyPrinter.h | 7 +++++-
+ lib/AST/DeclPrinter.cpp | 16 ++++++++----
+ unittests/AST/DeclPrinterTest.cpp | 51 ++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 64 insertions(+), 10 deletions(-)
+
+diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
+index 274df220e1..edcef0ae24 100644
+--- a/tools/clang/include/clang/AST/PrettyPrinter.h
++++ b/tools/clang/include/clang/AST/PrettyPrinter.h
+@@ -50,7 +50,8 @@ struct PrintingPolicy {
+ UseVoidForZeroParams(!LO.CPlusPlus),
+ TerseOutput(false), PolishForDeclaration(false),
+ Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
+- IncludeNewlines(true), MSVCFormatting(false) { }
++ IncludeNewlines(true), MSVCFormatting(false),
++ FullyQualifiedName(false) { }
+
+ /// \brief Adjust this printing policy for cases where it's known that
+ /// we're printing C++ code (for instance, if AST dumping reaches a
+@@ -200,6 +201,10 @@ struct PrintingPolicy {
+ /// prints anonymous namespaces as `anonymous namespace' and does not insert
+ /// spaces after template arguments.
+ bool MSVCFormatting : 1;
++
++ /// When true, print the fully qualified name of function declarations.
++ /// This is the opposite of SuppressScope and thus overrules it.
++ bool FullyQualifiedName : 1;
+ };
+
+ } // end namespace clang
+diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
+index 37f08a4985..ea37abe8f6 100644
+--- a/tools/clang/lib/AST/DeclPrinter.cpp
++++ b/tools/clang/lib/AST/DeclPrinter.cpp
+@@ -510,13 +510,19 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
+ PrintingPolicy SubPolicy(Policy);
+ SubPolicy.SuppressSpecifiers = false;
+ std::string Proto;
+- if (!Policy.SuppressScope) {
+- if (const NestedNameSpecifier *NS = D->getQualifier()) {
+- llvm::raw_string_ostream OS(Proto);
+- NS->print(OS, Policy);
++
++ if (Policy.FullyQualifiedName) {
++ Proto += D->getQualifiedNameAsString();
++ } else {
++ if (!Policy.SuppressScope) {
++ if (const NestedNameSpecifier *NS = D->getQualifier()) {
++ llvm::raw_string_ostream OS(Proto);
++ NS->print(OS, Policy);
++ }
+ }
++ Proto += D->getNameInfo().getAsString();
+ }
+- Proto += D->getNameInfo().getAsString();
++
+ if (GuideDecl)
+ Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
+ if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
+diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
+index dc1977d876..4cf8bce20e 100644
+--- a/tools/clang/unittests/AST/DeclPrinterTest.cpp
++++ b/tools/clang/unittests/AST/DeclPrinterTest.cpp
+@@ -104,15 +104,17 @@ PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
+ return ::testing::AssertionSuccess();
+ }
+
+-::testing::AssertionResult PrintedDeclCXX98Matches(StringRef Code,
+- StringRef DeclName,
+- StringRef ExpectedPrinted) {
++::testing::AssertionResult
++PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName,
++ StringRef ExpectedPrinted,
++ PrintingPolicyModifier PolicyModifier = nullptr) {
+ std::vector<std::string> Args(1, "-std=c++98");
+ return PrintedDeclMatches(Code,
+ Args,
+ namedDecl(hasName(DeclName)).bind("id"),
+ ExpectedPrinted,
+- "input.cc");
++ "input.cc",
++ PolicyModifier);
+ }
+
+ ::testing::AssertionResult
+@@ -350,6 +352,47 @@ TEST(DeclPrinter, TestFunctionDecl1) {
+ "void A()"));
+ }
+
++TEST(DeclPrinter, TestFreeFunctionDecl_FullyQualifiedName) {
++ ASSERT_TRUE(PrintedDeclCXX98Matches(
++ "void A();",
++ "A",
++ "void A()",
++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
++}
++
++TEST(DeclPrinter, TestFreeFunctionDeclInNamespace_FullyQualifiedName) {
++ ASSERT_TRUE(PrintedDeclCXX98Matches(
++ "namespace X { void A(); };",
++ "A",
++ "void X::A()",
++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
++}
++
++TEST(DeclPrinter, TestMemberFunction_FullyQualifiedName) {
++ ASSERT_TRUE(PrintedDeclCXX98Matches(
++ "struct X { void A(); };",
++ "A",
++ "void X::A()",
++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
++}
++
++TEST(DeclPrinter, TestMemberFunctionInNamespace_FullyQualifiedName) {
++ ASSERT_TRUE(PrintedDeclCXX98Matches(
++ "namespace Z { struct X { void A(); }; }",
++ "A",
++ "void Z::X::A()",
++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
++}
++
++TEST(DeclPrinter, TestMemberFunctionOutside_FullyQualifiedName) {
++ ASSERT_TRUE(PrintedDeclCXX98Matches(
++ "struct X { void A(); };"
++ "void X::A() {}",
++ functionDecl(hasName("A"), isDefinition()).bind("id"),
++ "void X::A()",
++ [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
++}
++
+ TEST(DeclPrinter, TestFunctionDecl2) {
+ ASSERT_TRUE(PrintedDeclCXX98Matches(
+ "void A() {}",
+--
+2.15.1
+
diff --git a/dist/clang/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch b/dist/clang/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch
new file mode 100644
index 0000000000..77e6da398f
--- /dev/null
+++ b/dist/clang/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch
@@ -0,0 +1,543 @@
+diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
+index 0f4ade266c..d6ad37ffaa 100644
+--- a/tools/clang/include/clang-c/Index.h
++++ b/tools/clang/include/clang-c/Index.h
+@@ -35,6 +35,7 @@
+ #define CINDEX_VERSION_MINOR 43
+ #define CINDEX_VERSION_HAS_ISINVALIDECL_BACKPORTED
+ #define CINDEX_VERSION_HAS_GETFILECONTENTS_BACKPORTED
++#define CINDEX_VERSION_HAS_PRETTYDECL_BACKPORTED
+
+ #define CINDEX_VERSION_ENCODE(major, minor) ( \
+ ((major) * 10000) \
+@@ -4066,6 +4067,89 @@ CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor,
+ unsigned pieceIndex,
+ unsigned options);
+
++/**
++ * \brief Opaque pointer representing a policy that controls pretty printing
++ * for \c clang_getCursorPrettyPrinted.
++ */
++typedef void *CXPrintingPolicy;
++
++/**
++ * \brief Properties for the printing policy.
++ *
++ * See \c clang::PrintingPolicy for more information.
++ */
++enum CXPrintingPolicyProperty {
++ CXPrintingPolicy_Indentation,
++ CXPrintingPolicy_SuppressSpecifiers,
++ CXPrintingPolicy_SuppressTagKeyword,
++ CXPrintingPolicy_IncludeTagDefinition,
++ CXPrintingPolicy_SuppressScope,
++ CXPrintingPolicy_SuppressUnwrittenScope,
++ CXPrintingPolicy_SuppressInitializers,
++ CXPrintingPolicy_ConstantArraySizeAsWritten,
++ CXPrintingPolicy_AnonymousTagLocations,
++ CXPrintingPolicy_SuppressStrongLifetime,
++ CXPrintingPolicy_SuppressLifetimeQualifiers,
++ CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors,
++ CXPrintingPolicy_Bool,
++ CXPrintingPolicy_Restrict,
++ CXPrintingPolicy_Alignof,
++ CXPrintingPolicy_UnderscoreAlignof,
++ CXPrintingPolicy_UseVoidForZeroParams,
++ CXPrintingPolicy_TerseOutput,
++ CXPrintingPolicy_PolishForDeclaration,
++ CXPrintingPolicy_Half,
++ CXPrintingPolicy_MSWChar,
++ CXPrintingPolicy_IncludeNewlines,
++ CXPrintingPolicy_MSVCFormatting,
++ CXPrintingPolicy_ConstantsAsWritten, /* Ops, not yet there in clang 5.0 and we do not need it. */
++ CXPrintingPolicy_SuppressImplicitBase, /* Ops, not yet there in clang 5.0 and we do not need it. */
++ CXPrintingPolicy_FullyQualifiedName,
++
++ CXPrintingPolicy_LastProperty = CXPrintingPolicy_FullyQualifiedName
++};
++
++/**
++ * \brief Get a property value for the given printing policy.
++ */
++unsigned
++clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
++ enum CXPrintingPolicyProperty Property);
++
++/**
++ * \brief Set a property value for the given printing policy.
++ */
++void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
++ enum CXPrintingPolicyProperty Property,
++ unsigned Value);
++
++/**
++ * \brief Retrieve the default policy for the cursor.
++ *
++ * The policy should be released after use with \c
++ * clang_PrintingPolicy_dispose.
++ */
++CINDEX_LINKAGE CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor);
++
++/**
++ * \brief Release a printing policy.
++ */
++CINDEX_LINKAGE void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy);
++
++/**
++ * \brief Pretty print declarations.
++ *
++ * \param Cursor The cursor representing a declaration.
++ *
++ * \param Policy The policy to control the entities being printed. If
++ * NULL, a default policy is used.
++ *
++ * \returns The pretty printed declaration or the empty string for
++ * other cursors.
++ */
++CINDEX_LINKAGE CXString clang_getCursorPrettyPrinted(CXCursor Cursor,
++ CXPrintingPolicy Policy);
++
+ /**
+ * \brief Retrieve the display name for the entity referenced by this cursor.
+ *
+diff --git a/test/Index/print-display-names.cpp b/test/Index/print-display-names.cpp
+index 94fe4665e6..5ba10e43bc 100644
+--- a/tools/clang/test/Index/print-display-names.cpp
++++ b/tools/clang/test/Index/print-display-names.cpp
+@@ -12,9 +12,20 @@ void g(ClassTmpl<T, T>);
+
+ template<> void g<int>(ClassTmpl<int, int>);
+
+-// RUN: c-index-test -test-load-source all-display %s | FileCheck %s
+-// CHECK: print-display-names.cpp:2:7: ClassTemplate=ClassTmpl<T, typename>:2:7
+-// CHECK: print-display-names.cpp:6:16: ClassDecl=ClassTmpl<Integer, Integer>:6:16 (Definition)
+-// CHECK: print-display-names.cpp:8:6: FunctionDecl=f(ClassTmpl<float, Integer>):8:6
+-// CHECK: print-display-names.cpp:11:6: FunctionTemplate=g(ClassTmpl<T, T>):11:6
+-// CHECK: print-display-names.cpp:13:17: FunctionDecl=g<>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6]
++// RUN: c-index-test -test-load-source all-display %s | FileCheck %s --check-prefix=DISPLAY_NAME
++// DISPLAY_NAME: print-display-names.cpp:2:7: ClassTemplate=ClassTmpl<T, typename>:2:7
++// DISPLAY_NAME: print-display-names.cpp:6:16: ClassDecl=ClassTmpl<Integer, Integer>:6:16 (Definition)
++// DISPLAY_NAME: print-display-names.cpp:8:6: FunctionDecl=f(ClassTmpl<float, Integer>):8:6
++// DISPLAY_NAME: print-display-names.cpp:11:6: FunctionTemplate=g(ClassTmpl<T, T>):11:6
++// DISPLAY_NAME: print-display-names.cpp:13:17: FunctionDecl=g<>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6]
++
++// RUN: env CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT=1 c-index-test -test-load-source all-pretty %s | FileCheck %s --check-prefix=PRETTY
++// PRETTY: print-display-names.cpp:2:7: ClassTemplate=template <typename T, typename > class ClassTmpl {}:2:7 (Definition) Extent=[1:1 - 2:20]
++// PRETTY: print-display-names.cpp:4:13: TypedefDecl=typedef int Integer:4:13 (Definition) Extent=[4:1 - 4:20]
++// PRETTY: print-display-names.cpp:6:16: ClassDecl=template<> class ClassTmpl<int, int> {}:6:16 (Definition) [Specialization of ClassTmpl:2:7] Extent=[6:1 - 6:43]
++// PRETTY: print-display-names.cpp:8:6: FunctionDecl=void f(ClassTmpl<float, Integer> p):8:6 Extent=[8:1 - 8:36]
++// PRETTY: print-display-names.cpp:8:34: ParmDecl=ClassTmpl<float, Integer> p:8:34 (Definition) Extent=[8:8 - 8:35]
++// PRETTY: print-display-names.cpp:11:6: FunctionTemplate=template <typename T> void g(ClassTmpl<T, T>):11:6 Extent=[10:1 - 11:24]
++// PRETTY: print-display-names.cpp:11:23: ParmDecl=ClassTmpl<T, T>:11:23 (Definition) Extent=[11:8 - 11:23]
++// PRETTY: print-display-names.cpp:13:17: FunctionDecl=template<> void g<int>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6] [Template arg 0: kind: 1, type: int] Extent=[13:1 - 13:44]
++// PRETTY: print-display-names.cpp:13:43: ParmDecl=ClassTmpl<int, int>:13:43 (Definition) Extent=[13:24 - 13:43]
+diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
+index 759ed449a4..ce2f549234 100644
+--- a/tools/clang/tools/c-index-test/c-index-test.c
++++ b/tools/clang/tools/c-index-test/c-index-test.c
+@@ -86,6 +86,69 @@ static unsigned getDefaultParsingOptions() {
+ return options;
+ }
+
++static void ModifyPrintingPolicyAccordingToEnv(CXPrintingPolicy Policy) {
++ struct Mapping {
++ const char *name;
++ enum CXPrintingPolicyProperty property;
++ };
++ struct Mapping mappings[] = {
++ {"CINDEXTEST_PRINTINGPOLICY_INDENTATION", CXPrintingPolicy_Indentation},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSPECIFIERS",
++ CXPrintingPolicy_SuppressSpecifiers},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSTAGKEYWORD",
++ CXPrintingPolicy_SuppressTagKeyword},
++ {"CINDEXTEST_PRINTINGPOLICY_INCLUDETAGDEFINITION",
++ CXPrintingPolicy_IncludeTagDefinition},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSCOPE",
++ CXPrintingPolicy_SuppressScope},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSUNWRITTENSCOPE",
++ CXPrintingPolicy_SuppressUnwrittenScope},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSINITIALIZERS",
++ CXPrintingPolicy_SuppressInitializers},
++ {"CINDEXTEST_PRINTINGPOLICY_CONSTANTARRAYSIZEASWRITTEN",
++ CXPrintingPolicy_ConstantArraySizeAsWritten},
++ {"CINDEXTEST_PRINTINGPOLICY_ANONYMOUSTAGLOCATIONS",
++ CXPrintingPolicy_AnonymousTagLocations},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSSTRONGLIFETIME",
++ CXPrintingPolicy_SuppressStrongLifetime},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSLIFETIMEQUALIFIERS",
++ CXPrintingPolicy_SuppressLifetimeQualifiers},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSTEMPLATEARGSINCXXCONSTRUCTORS",
++ CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors},
++ {"CINDEXTEST_PRINTINGPOLICY_BOOL", CXPrintingPolicy_Bool},
++ {"CINDEXTEST_PRINTINGPOLICY_RESTRICT", CXPrintingPolicy_Restrict},
++ {"CINDEXTEST_PRINTINGPOLICY_ALIGNOF", CXPrintingPolicy_Alignof},
++ {"CINDEXTEST_PRINTINGPOLICY_UNDERSCOREALIGNOF",
++ CXPrintingPolicy_UnderscoreAlignof},
++ {"CINDEXTEST_PRINTINGPOLICY_USEVOIDFORZEROPARAMS",
++ CXPrintingPolicy_UseVoidForZeroParams},
++ {"CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT", CXPrintingPolicy_TerseOutput},
++ {"CINDEXTEST_PRINTINGPOLICY_POLISHFORDECLARATION",
++ CXPrintingPolicy_PolishForDeclaration},
++ {"CINDEXTEST_PRINTINGPOLICY_HALF", CXPrintingPolicy_Half},
++ {"CINDEXTEST_PRINTINGPOLICY_MSWCHAR", CXPrintingPolicy_MSWChar},
++ {"CINDEXTEST_PRINTINGPOLICY_INCLUDENEWLINES",
++ CXPrintingPolicy_IncludeNewlines},
++ {"CINDEXTEST_PRINTINGPOLICY_MSVCFORMATTING",
++ CXPrintingPolicy_MSVCFormatting},
++ {"CINDEXTEST_PRINTINGPOLICY_CONSTANTSASWRITTEN",
++ CXPrintingPolicy_ConstantsAsWritten},
++ {"CINDEXTEST_PRINTINGPOLICY_SUPPRESSIMPLICITBASE",
++ CXPrintingPolicy_SuppressImplicitBase},
++ {"CINDEXTEST_PRINTINGPOLICY_FULLYQUALIFIEDNAME",
++ CXPrintingPolicy_FullyQualifiedName},
++ };
++
++ unsigned i;
++ for (i = 0; i < sizeof(mappings) / sizeof(struct Mapping); i++) {
++ char *value = getenv(mappings[i].name);
++ if (value) {
++ clang_PrintingPolicy_setProperty(Policy, mappings[i].property,
++ (unsigned)strtoul(value, 0L, 10));
++ }
++ }
++}
++
+ /** \brief Returns 0 in case of success, non-zero in case of a failure. */
+ static int checkForErrors(CXTranslationUnit TU);
+
+@@ -356,7 +419,11 @@ static void PrintRange(CXSourceRange R, const char *str) {
+ PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
+ }
+
+-int want_display_name = 0;
++static enum DisplayType {
++ DisplayType_Spelling,
++ DisplayType_DisplayName,
++ DisplayType_Pretty
++} wanted_display_type = DisplayType_Spelling;
+
+ static void printVersion(const char *Prefix, CXVersion Version) {
+ if (Version.Major < 0)
+@@ -656,6 +723,24 @@ static int lineCol_cmp(const void *p1, const void *p2) {
+ return (int)lhs->col - (int)rhs->col;
+ }
+
++static CXString CursorToText(CXCursor Cursor) {
++ switch (wanted_display_type) {
++ case DisplayType_Spelling:
++ return clang_getCursorSpelling(Cursor);
++ case DisplayType_DisplayName:
++ return clang_getCursorDisplayName(Cursor);
++ case DisplayType_Pretty:
++ default: {
++ CXString text;
++ CXPrintingPolicy Policy = clang_getCursorPrintingPolicy(Cursor);
++ ModifyPrintingPolicyAccordingToEnv(Policy);
++ text = clang_getCursorPrettyPrinted(Cursor, Policy);
++ clang_PrintingPolicy_dispose(Policy);
++ return text;
++ }
++ }
++}
++
+ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
+ CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
+ if (clang_isInvalid(Cursor.kind)) {
+@@ -682,8 +767,7 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
+ int I;
+
+ ks = clang_getCursorKindSpelling(Cursor.kind);
+- string = want_display_name? clang_getCursorDisplayName(Cursor)
+- : clang_getCursorSpelling(Cursor);
++ string = CursorToText(Cursor);
+ printf("%s=%s", clang_getCString(ks),
+ clang_getCString(string));
+ clang_disposeString(ks);
+@@ -1675,7 +1759,12 @@ static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
+ else if (!strcmp(filter, "all-display") ||
+ !strcmp(filter, "local-display")) {
+ ck = NULL;
+- want_display_name = 1;
++ wanted_display_type = DisplayType_DisplayName;
++ }
++ else if (!strcmp(filter, "all-pretty") ||
++ !strcmp(filter, "local-pretty")) {
++ ck = NULL;
++ wanted_display_type = DisplayType_Pretty;
+ }
+ else if (!strcmp(filter, "none")) K = (enum CXCursorKind) ~0;
+ else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl;
+@@ -1742,8 +1831,11 @@ int perform_test_load_source(int argc, const char **argv,
+ unsigned I;
+
+ Idx = clang_createIndex(/* excludeDeclsFromPCH */
+- (!strcmp(filter, "local") ||
+- !strcmp(filter, "local-display"))? 1 : 0,
++ (!strcmp(filter, "local") ||
++ !strcmp(filter, "local-display") ||
++ !strcmp(filter, "local-pretty"))
++ ? 1
++ : 0,
+ /* displayDiagnostics=*/1);
+
+ if ((CommentSchemaFile = parse_comments_schema(argc, argv))) {
+diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
+index 45ee9803f2..72b14fdb53 100644
+--- a/tools/clang/tools/libclang/CIndex.cpp
++++ b/tools/clang/tools/libclang/CIndex.cpp
+@@ -4652,6 +4652,197 @@ CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
+ return cxstring::createSet(Manglings);
+ }
+
++CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
++ if (clang_Cursor_isNull(C))
++ return 0;
++ return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
++}
++
++void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
++ if (Policy)
++ delete static_cast<PrintingPolicy *>(Policy);
++}
++
++unsigned
++clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
++ enum CXPrintingPolicyProperty Property) {
++ if (!Policy)
++ return 0;
++
++ PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
++ switch (Property) {
++ case CXPrintingPolicy_Indentation:
++ return P->Indentation;
++ case CXPrintingPolicy_SuppressSpecifiers:
++ return P->SuppressSpecifiers;
++ case CXPrintingPolicy_SuppressTagKeyword:
++ return P->SuppressTagKeyword;
++ case CXPrintingPolicy_IncludeTagDefinition:
++ return P->IncludeTagDefinition;
++ case CXPrintingPolicy_SuppressScope:
++ return P->SuppressScope;
++ case CXPrintingPolicy_SuppressUnwrittenScope:
++ return P->SuppressUnwrittenScope;
++ case CXPrintingPolicy_SuppressInitializers:
++ return P->SuppressInitializers;
++ case CXPrintingPolicy_ConstantArraySizeAsWritten:
++ return P->ConstantArraySizeAsWritten;
++ case CXPrintingPolicy_AnonymousTagLocations:
++ return P->AnonymousTagLocations;
++ case CXPrintingPolicy_SuppressStrongLifetime:
++ return P->SuppressStrongLifetime;
++ case CXPrintingPolicy_SuppressLifetimeQualifiers:
++ return P->SuppressLifetimeQualifiers;
++ case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
++ return P->SuppressTemplateArgsInCXXConstructors;
++ case CXPrintingPolicy_Bool:
++ return P->Bool;
++ case CXPrintingPolicy_Restrict:
++ return P->Restrict;
++ case CXPrintingPolicy_Alignof:
++ return P->Alignof;
++ case CXPrintingPolicy_UnderscoreAlignof:
++ return P->UnderscoreAlignof;
++ case CXPrintingPolicy_UseVoidForZeroParams:
++ return P->UseVoidForZeroParams;
++ case CXPrintingPolicy_TerseOutput:
++ return P->TerseOutput;
++ case CXPrintingPolicy_PolishForDeclaration:
++ return P->PolishForDeclaration;
++ case CXPrintingPolicy_Half:
++ return P->Half;
++ case CXPrintingPolicy_MSWChar:
++ return P->MSWChar;
++ case CXPrintingPolicy_IncludeNewlines:
++ return P->IncludeNewlines;
++ case CXPrintingPolicy_MSVCFormatting:
++ return P->MSVCFormatting;
++ case CXPrintingPolicy_ConstantsAsWritten:
++ // Ops, not yet there in clang 5.0 and we do not need it.
++ return 0;
++ case CXPrintingPolicy_SuppressImplicitBase:
++ // Ops, not yet there in clang 5.0 and we do not need it.
++ return 0;
++ case CXPrintingPolicy_FullyQualifiedName:
++ return P->FullyQualifiedName;
++ }
++
++ assert(false && "Invalid CXPrintingPolicyProperty");
++ return 0;
++}
++
++void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
++ enum CXPrintingPolicyProperty Property,
++ unsigned Value) {
++ if (!Policy)
++ return;
++
++ PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
++ switch (Property) {
++ case CXPrintingPolicy_Indentation:
++ P->Indentation = Value;
++ return;
++ case CXPrintingPolicy_SuppressSpecifiers:
++ P->SuppressSpecifiers = Value;
++ return;
++ case CXPrintingPolicy_SuppressTagKeyword:
++ P->SuppressTagKeyword = Value;
++ return;
++ case CXPrintingPolicy_IncludeTagDefinition:
++ P->IncludeTagDefinition = Value;
++ return;
++ case CXPrintingPolicy_SuppressScope:
++ P->SuppressScope = Value;
++ return;
++ case CXPrintingPolicy_SuppressUnwrittenScope:
++ P->SuppressUnwrittenScope = Value;
++ return;
++ case CXPrintingPolicy_SuppressInitializers:
++ P->SuppressInitializers = Value;
++ return;
++ case CXPrintingPolicy_ConstantArraySizeAsWritten:
++ P->ConstantArraySizeAsWritten = Value;
++ return;
++ case CXPrintingPolicy_AnonymousTagLocations:
++ P->AnonymousTagLocations = Value;
++ return;
++ case CXPrintingPolicy_SuppressStrongLifetime:
++ P->SuppressStrongLifetime = Value;
++ return;
++ case CXPrintingPolicy_SuppressLifetimeQualifiers:
++ P->SuppressLifetimeQualifiers = Value;
++ return;
++ case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
++ P->SuppressTemplateArgsInCXXConstructors = Value;
++ return;
++ case CXPrintingPolicy_Bool:
++ P->Bool = Value;
++ return;
++ case CXPrintingPolicy_Restrict:
++ P->Restrict = Value;
++ return;
++ case CXPrintingPolicy_Alignof:
++ P->Alignof = Value;
++ return;
++ case CXPrintingPolicy_UnderscoreAlignof:
++ P->UnderscoreAlignof = Value;
++ return;
++ case CXPrintingPolicy_UseVoidForZeroParams:
++ P->UseVoidForZeroParams = Value;
++ return;
++ case CXPrintingPolicy_TerseOutput:
++ P->TerseOutput = Value;
++ return;
++ case CXPrintingPolicy_PolishForDeclaration:
++ P->PolishForDeclaration = Value;
++ return;
++ case CXPrintingPolicy_Half:
++ P->Half = Value;
++ return;
++ case CXPrintingPolicy_MSWChar:
++ P->MSWChar = Value;
++ return;
++ case CXPrintingPolicy_IncludeNewlines:
++ P->IncludeNewlines = Value;
++ return;
++ case CXPrintingPolicy_MSVCFormatting:
++ P->MSVCFormatting = Value;
++ return;
++ case CXPrintingPolicy_ConstantsAsWritten:
++ // Ops, not yet there in clang 5.0 and we do not need it.
++ return;
++ case CXPrintingPolicy_SuppressImplicitBase:
++ // Ops, not yet there in clang 5.0 and we do not need it.
++ return;
++ case CXPrintingPolicy_FullyQualifiedName:
++ P->FullyQualifiedName = Value;
++ return;
++ }
++
++ assert(false && "Invalid CXPrintingPolicyProperty");
++}
++
++CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
++ if (clang_Cursor_isNull(C))
++ return cxstring::createEmpty();
++
++ if (clang_isDeclaration(C.kind)) {
++ const Decl *D = getCursorDecl(C);
++ if (!D)
++ return cxstring::createEmpty();
++
++ SmallString<128> Str;
++ llvm::raw_svector_ostream OS(Str);
++ PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
++ D->print(OS, UserPolicy ? *UserPolicy
++ : getCursorContext(C).getPrintingPolicy());
++
++ return cxstring::createDup(OS.str());
++ }
++
++ return cxstring::createEmpty();
++}
++
+ CXString clang_getCursorDisplayName(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return clang_getCursorSpelling(C);
+diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
+index c788abb881..ed4773b132 100644
+--- a/tools/clang/tools/libclang/libclang.exports
++++ b/tools/clang/tools/libclang/libclang.exports
+@@ -175,6 +175,8 @@ clang_getCursorAvailability
+ clang_getCursorCompletionString
+ clang_getCursorDefinition
+ clang_getCursorDisplayName
++clang_getCursorPrintingPolicy
++clang_getCursorPrettyPrinted
+ clang_getCursorExtent
+ clang_getCursorExceptionSpecificationType
+ clang_getCursorKind
+@@ -355,3 +357,6 @@ clang_EvalResult_isUnsignedInt
+ clang_EvalResult_getAsDouble
+ clang_EvalResult_getAsStr
+ clang_EvalResult_dispose
++clang_PrintingPolicy_getProperty
++clang_PrintingPolicy_setProperty
++clang_PrintingPolicy_dispose
+diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
+index f2a96d6be6..a9f5ee1da4 100644
+--- a/tools/clang/unittests/libclang/LibclangTest.cpp
++++ b/tools/clang/unittests/libclang/LibclangTest.cpp
+@@ -572,3 +572,33 @@ TEST_F(LibclangReparseTest, clang_parseTranslationUnit2FullArgv) {
+ EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
+ DisplayDiagnostics();
+ }
++
++class LibclangPrintingPolicyTest : public LibclangParseTest {
++public:
++ CXPrintingPolicy Policy = nullptr;
++
++ void SetUp() override {
++ LibclangParseTest::SetUp();
++ std::string File = "file.cpp";
++ WriteFile(File, "int i;\n");
++ ClangTU = clang_parseTranslationUnit(Index, File.c_str(), nullptr, 0,
++ nullptr, 0, TUFlags);
++ CXCursor TUCursor = clang_getTranslationUnitCursor(ClangTU);
++ Policy = clang_getCursorPrintingPolicy(TUCursor);
++ }
++ void TearDown() override {
++ clang_PrintingPolicy_dispose(Policy);
++ LibclangParseTest::TearDown();
++ }
++};
++
++TEST_F(LibclangPrintingPolicyTest, SetAndGetProperties) {
++ for (unsigned Value = 0; Value < 2; ++Value) {
++ for (int I = 0; I < CXPrintingPolicy_LastProperty; ++I) {
++ auto Property = static_cast<enum CXPrintingPolicyProperty>(I);
++
++ clang_PrintingPolicy_setProperty(Policy, Property, Value);
++ EXPECT_EQ(Value, clang_PrintingPolicy_getProperty(Policy, Property));
++ }
++ }
++}
diff --git a/dist/clang/patches/README.md b/dist/clang/patches/README.md
index e3d64bd2da..517df553b3 100644
--- a/dist/clang/patches/README.md
+++ b/dist/clang/patches/README.md
@@ -83,6 +83,17 @@ Together with https://codereview.qt-project.org/#/c/212972/ fixes highlighting
[libclang] Only mark CXCursors for explicit attributes with a type
Some classes have totally broken highlighting (like classes inside texteditor.cpp)
+##### 170_D40013_DeclPrinter-Allow-printing-fully-qualified-name.patch
+##### 180_D39903_libclang-Allow-pretty-printing-declarations.patch
+
+* <https://reviews.llvm.org/D40013>
+* <https://reviews.llvm.org/D39903>
+
+[DeclPrinter] Allow printing fully qualified name of function declaration
+[libclang] Allow pretty printing declarations
+
+Improves pretty printing for tooltips.
+
Additional changes
------------------