diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index b6e0d71c1ae1b9..7caf0bbfd722af 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -1770,6 +1770,16 @@ def spelling(self): return self._spelling + def pretty_printed(self, policy): + """ + Pretty print declarations. + Parameters: + policy -- The policy to control the entities being printed. + """ + return _CXString.from_result( + conf.lib.clang_getCursorPrettyPrinted(self, policy) + ) + @property def displayname(self): """ @@ -3699,6 +3709,72 @@ def write_main_file_to_stdout(self): conf.lib.clang_CXRewriter_writeMainFileToStdOut(self) +class PrintingPolicyProperty(BaseEnumeration): + + """ + A PrintingPolicyProperty identifies a property of a PrintingPolicy. + """ + + Indentation = 0 + SuppressSpecifiers = 1 + SuppressTagKeyword = 2 + IncludeTagDefinition = 3 + SuppressScope = 4 + SuppressUnwrittenScope = 5 + SuppressInitializers = 6 + ConstantArraySizeAsWritten = 7 + AnonymousTagLocations = 8 + SuppressStrongLifetime = 9 + SuppressLifetimeQualifiers = 10 + SuppressTemplateArgsInCXXConstructors = 11 + Bool = 12 + Restrict = 13 + Alignof = 14 + UnderscoreAlignof = 15 + UseVoidForZeroParams = 16 + TerseOutput = 17 + PolishForDeclaration = 18 + Half = 19 + MSWChar = 20 + IncludeNewlines = 21 + MSVCFormatting = 22 + ConstantsAsWritten = 23 + SuppressImplicitBase = 24 + FullyQualifiedName = 25 + + +class PrintingPolicy(ClangObject): + """ + The PrintingPolicy is a wrapper class around clang::PrintingPolicy + + It allows specifying how declarations, expressions, and types should be + pretty-printed. + """ + + @staticmethod + def create(cursor): + """ + Creates a new PrintingPolicy + Parameters: + cursor -- Any cursor for a translation unit. + """ + return PrintingPolicy(conf.lib.clang_getCursorPrintingPolicy(cursor)) + + def __init__(self, ptr): + ClangObject.__init__(self, ptr) + + def __del__(self): + conf.lib.clang_PrintingPolicy_dispose(self) + + def get_property(self, property): + """Get a property value for the given printing policy.""" + return conf.lib.clang_PrintingPolicy_getProperty(self, property.value) + + def set_property(self, property, value): + """Set a property value for the given printing policy.""" + conf.lib.clang_PrintingPolicy_setProperty(self, property.value, value) + + # Now comes the plumbing to hook up the C library. # Register callback types @@ -3801,6 +3877,8 @@ def write_main_file_to_stdout(self): ("clang_getCursorExtent", [Cursor], SourceRange), ("clang_getCursorLexicalParent", [Cursor], Cursor), ("clang_getCursorLocation", [Cursor], SourceLocation), + ("clang_getCursorPrettyPrinted", [Cursor, PrintingPolicy], _CXString), + ("clang_getCursorPrintingPolicy", [Cursor], c_object_p), ("clang_getCursorReferenced", [Cursor], Cursor), ("clang_getCursorReferenceNameRange", [Cursor, c_uint, c_uint], SourceRange), ("clang_getCursorResultType", [Cursor], Type), @@ -3924,6 +4002,9 @@ def write_main_file_to_stdout(self): ("clang_Cursor_isAnonymousRecordDecl", [Cursor], bool), ("clang_Cursor_isBitField", [Cursor], bool), ("clang_Location_isInSystemHeader", [SourceLocation], bool), + ("clang_PrintingPolicy_dispose", [PrintingPolicy]), + ("clang_PrintingPolicy_getProperty", [PrintingPolicy, c_int], c_uint), + ("clang_PrintingPolicy_setProperty", [PrintingPolicy, c_int, c_uint]), ("clang_Type_getAlignOf", [Type], c_longlong), ("clang_Type_getClassType", [Type], Type), ("clang_Type_getNumTemplateArguments", [Type], c_int), @@ -4104,6 +4185,8 @@ def function_exists(self, name: str) -> bool: "FixIt", "Index", "LinkageKind", + "PrintingPolicy", + "PrintingPolicyProperty", "RefQualifierKind", "SourceLocation", "SourceRange", diff --git a/clang/bindings/python/tests/cindex/test_cursor.py b/clang/bindings/python/tests/cindex/test_cursor.py index 4d989a7421e790..c6aa65ce3c29f8 100644 --- a/clang/bindings/python/tests/cindex/test_cursor.py +++ b/clang/bindings/python/tests/cindex/test_cursor.py @@ -5,6 +5,8 @@ BinaryOperator, Config, CursorKind, + PrintingPolicy, + PrintingPolicyProperty, StorageClass, TemplateArgumentKind, TranslationUnit, @@ -981,3 +983,15 @@ def test_from_result_null(self): def test_from_cursor_result_null(self): tu = get_tu("") self.assertEqual(tu.cursor.semantic_parent, None) + + def test_pretty_print(self): + tu = get_tu("struct X { int x; }; void f(bool x) { }", lang="cpp") + f = get_cursor(tu, "f") + + self.assertEqual(f.displayname, "f(bool)") + pp = PrintingPolicy.create(f) + self.assertEqual(pp.get_property(PrintingPolicyProperty.Bool), True) + self.assertEqual(f.pretty_printed(pp), "void f(bool x) {\n}\n") + pp.set_property(PrintingPolicyProperty.Bool, False) + self.assertEqual(pp.get_property(PrintingPolicyProperty.Bool), False) + self.assertEqual(f.pretty_printed(pp), "void f(_Bool x) {\n}\n") diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5ac886856c539c..07a1a4195427d8 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1298,6 +1298,8 @@ Sanitizers Python Binding Changes ---------------------- - Fixed an issue that led to crashes when calling ``Type.get_exception_specification_kind``. +- Added bindings for ``clang_getCursorPrettyPrinted`` and related functions, + which allow changing the formatting of pretty-printed code. - Added binding for ``clang_Cursor_isAnonymousRecordDecl``, which allows checking if a declaration is an anonymous union or anonymous struct.