diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-04-17 10:03:06 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-04-19 12:43:29 +0000 |
commit | 2408485cceff289e018df684683a22f301b04c71 (patch) | |
tree | 16fb21dc34baf454c10264661a533cd016f9f687 /tools | |
parent | ae67eb7103b782deb5dda308e19d6f8e68e31ae2 (diff) |
[backported/clang-7][libclang] Add PrintingPolicy for pretty printing declarations
-------------------------------------------------------------------------
* Improves pretty printing for Qt Creator's tooltips.
-------------------------------------------------------------------------
Summary:
Introduce clang_getCursorPrettyPrinted() for pretty printing
declarations. Expose also PrintingPolicy, so the user gets more
fine-grained control of the entities being printed.
The already existing clang_getCursorDisplayName() is pretty limited -
for example, it does not handle return types, parameter names or default
arguments for function declarations. Addressing these issues in
clang_getCursorDisplayName() would mean to duplicate existing code
(e.g. clang::DeclPrinter), so rather expose new API to access the
existing functionality.
Reviewed By: jbcoe
Subscribers: cfe-commits
Tags: #clang
Patch by nik (Nikolai Kosjar)
Differential Revision: https://reviews.llvm.org/D39903
Change-Id: I509a01bb5a1e4e1d899c2725f50ed78e482c075f
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/c-index-test/c-index-test.c | 104 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 191 | ||||
-rw-r--r-- | tools/libclang/libclang.exports | 5 |
3 files changed, 294 insertions, 6 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index c5e345ef6a..e9902efffb 100644 --- a/tools/c-index-test/c-index-test.c +++ b/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); @@ -1686,7 +1770,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; @@ -1754,8 +1843,11 @@ int perform_test_load_source(int argc, const char **argv, const char *InvocationPath; 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); InvocationPath = getenv("CINDEXTEST_INVOCATION_EMISSION_PATH"); if (InvocationPath) diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 429fca3474..bd2e4bc8d2 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -4706,6 +4706,197 @@ CXStringSet *clang_Cursor_getObjCManglings(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 5d1b0224ef..67e4b4334b 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -178,6 +178,8 @@ clang_getCursorAvailability clang_getCursorCompletionString clang_getCursorDefinition clang_getCursorDisplayName +clang_getCursorPrintingPolicy +clang_getCursorPrettyPrinted clang_getCursorExtent clang_getCursorExceptionSpecificationType clang_getCursorKind @@ -359,3 +361,6 @@ clang_EvalResult_isUnsignedInt clang_EvalResult_getAsDouble clang_EvalResult_getAsStr clang_EvalResult_dispose +clang_PrintingPolicy_getProperty +clang_PrintingPolicy_setProperty +clang_PrintingPolicy_dispose |