Skip to content

Commit

Permalink
[libclang] Allow using PrintingPolicy with types (#122386)
Browse files Browse the repository at this point in the history
This allows controlling pretty-printing of types the same way it works
with cursors.
  • Loading branch information
efriedma-quic authored Jan 10, 2025
1 parent 129ec84 commit b302633
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 5 deletions.
5 changes: 5 additions & 0 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -2701,6 +2701,10 @@ def spelling(self):
"""Retrieve the spelling of this Type."""
return _CXString.from_result(conf.lib.clang_getTypeSpelling(self))

def pretty_printed(self, policy):
"""Pretty-prints this Type with the given PrintingPolicy"""
return _CXString.from_result(conf.lib.clang_getTypePrettyPrinted(self, policy))

def __eq__(self, other):
if type(other) != type(self):
return False
Expand Down Expand Up @@ -3955,6 +3959,7 @@ def set_property(self, property, value):
("clang_getTypedefDeclUnderlyingType", [Cursor], Type),
("clang_getTypedefName", [Type], _CXString),
("clang_getTypeKindSpelling", [c_uint], _CXString),
("clang_getTypePrettyPrinted", [Type, PrintingPolicy], _CXString),
("clang_getTypeSpelling", [Type], _CXString),
("clang_hashCursor", [Cursor], c_uint),
("clang_isAttribute", [CursorKind], bool),
Expand Down
19 changes: 18 additions & 1 deletion clang/bindings/python/tests/cindex/test_type.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import os

from clang.cindex import Config, CursorKind, RefQualifierKind, TranslationUnit, TypeKind
from clang.cindex import (
Config,
CursorKind,
PrintingPolicy,
PrintingPolicyProperty,
RefQualifierKind,
TranslationUnit,
TypeKind,
)

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])
Expand Down Expand Up @@ -517,3 +525,12 @@ class Template {
# Variable without a template argument.
cursor = get_cursor(tu, "bar")
self.assertEqual(cursor.get_num_template_arguments(), -1)

def test_pretty(self):
tu = get_tu("struct X {}; X x;", lang="cpp")
f = get_cursor(tu, "x")

pp = PrintingPolicy.create(f)
self.assertEqual(f.type.get_canonical().pretty_printed(pp), "X")
pp.set_property(PrintingPolicyProperty.SuppressTagKeyword, False)
self.assertEqual(f.type.get_canonical().pretty_printed(pp), "struct X")
13 changes: 9 additions & 4 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,8 @@ libclang
--------
- Add ``clang_isBeforeInTranslationUnit``. Given two source locations, it determines
whether the first one comes strictly before the second in the source code.
- Add ``clang_getTypePrettyPrinted``. It allows controlling the PrintingPolicy used
to pretty-print a type.

Static Analyzer
---------------
Expand Down Expand Up @@ -1322,10 +1324,13 @@ 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.
- Added ``Cursor.pretty_printed``, a binding for ``clang_getCursorPrettyPrinted``,
and related functions, which allow changing the formatting of pretty-printed code.
- Added ``Cursor.is_anonymous_record_decl``, a binding for
``clang_Cursor_isAnonymousRecordDecl``, which allows checking if a
declaration is an anonymous union or anonymous struct.
- Added ``Type.pretty_printed`, a binding for ``clang_getTypePrettyPrinted``,
which allows changing the formatting of pretty-printed types.

OpenMP Support
--------------
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang-c/Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -4182,6 +4182,14 @@ CINDEX_LINKAGE void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy);
CINDEX_LINKAGE CXString clang_getCursorPrettyPrinted(CXCursor Cursor,
CXPrintingPolicy Policy);

/**
* Pretty-print the underlying type using a custom printing policy.
*
* If the type is invalid, an empty string is returned.
*/
CINDEX_LINKAGE CXString clang_getTypePrettyPrinted(CXType CT,
CXPrintingPolicy cxPolicy);

/**
* Retrieve the display name for the entity referenced by this cursor.
*
Expand Down
14 changes: 14 additions & 0 deletions clang/tools/libclang/CXType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,20 @@ CXString clang_getTypeSpelling(CXType CT) {
return cxstring::createDup(OS.str());
}

CXString clang_getTypePrettyPrinted(CXType CT, CXPrintingPolicy cxPolicy) {
QualType T = GetQualType(CT);
if (T.isNull())
return cxstring::createEmpty();

SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);

T.print(OS, *UserPolicy);

return cxstring::createDup(OS.str());
}

CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
using namespace cxcursor;
CXTranslationUnit TU = cxcursor::getCursorTU(C);
Expand Down
1 change: 1 addition & 0 deletions clang/tools/libclang/libclang.map
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ LLVM_19 {

LLVM_20 {
global:
clang_getTypePrettyPrinted;
clang_isBeforeInTranslationUnit;
};

Expand Down

0 comments on commit b302633

Please sign in to comment.