summaryrefslogtreecommitdiffstats
path: root/development/qt-creator-llvm/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch
diff options
context:
space:
mode:
Diffstat (limited to 'development/qt-creator-llvm/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch')
-rw-r--r--development/qt-creator-llvm/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch546
1 files changed, 546 insertions, 0 deletions
diff --git a/development/qt-creator-llvm/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch b/development/qt-creator-llvm/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch
new file mode 100644
index 0000000000..27b2e2a01e
--- /dev/null
+++ b/development/qt-creator-llvm/patches/180_D39903_libclang-Allow-pretty-printing-declarations.patch
@@ -0,0 +1,546 @@
+diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
+index 0f4ade266c..f188ec9d8c 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,90 @@ 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.
++ */
++CINDEX_LINKAGE unsigned
++clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
++ enum CXPrintingPolicyProperty Property);
++
++/**
++ * \brief Set a property value for the given printing policy.
++ */
++CINDEX_LINKAGE 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..342fbd5279 100644
+--- a/tools/clang/unittests/libclang/LibclangTest.cpp
++++ b/tools/clang/unittests/libclang/LibclangTest.cpp
+@@ -572,3 +572,35 @@ 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);
++ if (Property == CXPrintingPolicy_ConstantsAsWritten || Property == CXPrintingPolicy_SuppressImplicitBase)
++ continue; // These are not yet in clang 5.0.
++
++ clang_PrintingPolicy_setProperty(Policy, Property, Value);
++ EXPECT_EQ(Value, clang_PrintingPolicy_getProperty(Policy, Property));
++ }
++ }
++}