[cindex] Add support for calling getFullyQualifiedName to the Python binding. (#135420)

We're coming from llvm 11. There was a change made back in 15f3cd6 that
changed how type spelling works. Previous we were given namespaces of
the types within the spelling, and this was necessary in our use-case.
There is a more appropriate function available but it was not being
exposed over the Python bindings. This PR is intended to make make this
already-existing functionality accessible.

---------

Co-authored-by: Jannick Kremer <jannick.kremer@mailbox.org>
This commit is contained in:
Brian Cody
2025-04-15 06:36:00 -04:00
committed by GitHub
parent 81499edb30
commit 03b0f55d9c
6 changed files with 71 additions and 0 deletions

View File

@@ -2593,6 +2593,19 @@ class Type(Structure):
"""
return Type.from_result(conf.lib.clang_getCanonicalType(self), (self,))
def get_fully_qualified_name(self, policy, with_global_ns_prefix=False):
"""
Get the fully qualified name for a type.
This includes full qualification of all template parameters.
policy - This PrintingPolicy can further refine the type formatting
with_global_ns_prefix - If true, prepend '::' to qualified names
"""
return _CXString.from_result(
conf.lib.clang_getFullyQualifiedName(self, policy, with_global_ns_prefix)
)
def is_const_qualified(self):
"""Determine whether a Type has the "const" qualifier set.
@@ -4022,6 +4035,7 @@ FUNCTION_LIST: list[LibFunc] = [
("clang_getTypeSpelling", [Type], _CXString),
("clang_hashCursor", [Cursor], c_uint),
("clang_isAttribute", [CursorKind], bool),
("clang_getFullyQualifiedName", [Type, PrintingPolicy, c_uint], _CXString),
("clang_isConstQualifiedType", [Type], bool),
("clang_isCursorDefinition", [Cursor], bool),
("clang_isDeclaration", [CursorKind], bool),

View File

@@ -535,6 +535,25 @@ class A
pp.set_property(PrintingPolicyProperty.SuppressTagKeyword, False)
self.assertEqual(f.type.get_canonical().pretty_printed(pp), "struct X")
def test_fully_qualified_name(self):
source = """
namespace home {
class Bar {
};
class Foo {
public:
void setIt(Bar*);
};
}
class A : public home::Foo {
};
"""
tu = get_tu(source, lang="cpp")
arg = next(get_cursor(tu, "setIt").get_arguments())
pp = PrintingPolicy.create(arg)
self.assertEqual(arg.type.get_fully_qualified_name(pp), "home::Bar *")
self.assertEqual(arg.type.get_fully_qualified_name(pp, True), "::home::Bar *")
def test_base_classes(self):
source = """
class A { int a; };

View File

@@ -607,6 +607,8 @@ libclang
--------
- Added ``clang_visitCXXMethods``, which allows visiting the methods
of a class.
- Added ``clang_getFullyQualifiedName``, which provides fully qualified type names as
instructed by a PrintingPolicy.
- Fixed a buffer overflow in ``CXString`` implementation. The fix may result in
increased memory allocation.
@@ -661,6 +663,8 @@ Python Binding Changes
the cursor is a specialization of.
- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
allows visiting the methods of a class.
- Added ``Type.get_fully_qualified_name``, which provides fully qualified type names as
instructed by a PrintingPolicy.
OpenMP Support
--------------

View File

@@ -4223,6 +4223,18 @@ CINDEX_LINKAGE CXString clang_getCursorPrettyPrinted(CXCursor Cursor,
CINDEX_LINKAGE CXString clang_getTypePrettyPrinted(CXType CT,
CXPrintingPolicy cxPolicy);
/**
* Get the fully qualified name for a type.
*
* This includes full qualification of all template parameters.
*
* Policy - Further refine the type formatting
* WithGlobalNsPrefix - If non-zero, function will prepend a '::' to qualified
* names
*/
CINDEX_LINKAGE CXString clang_getFullyQualifiedName(
CXType CT, CXPrintingPolicy Policy, unsigned WithGlobalNsPrefix);
/**
* Retrieve the display name for the entity referenced by this cursor.
*

View File

@@ -19,6 +19,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/QualTypeNames.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
@@ -328,6 +329,22 @@ CXString clang_getTypePrettyPrinted(CXType CT, CXPrintingPolicy cxPolicy) {
return cxstring::createDup(OS.str());
}
CXString clang_getFullyQualifiedName(CXType CT, CXPrintingPolicy cxPolicy,
unsigned int WithGlobalNsPrefix) {
const QualType T = GetQualType(CT);
if (T.isNull())
return cxstring::createEmpty();
const CXTranslationUnit TU = GetTU(CT);
const ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
const PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
const bool WithGlobalNs = (WithGlobalNsPrefix != 0);
const std::string Str =
TypeName::getFullyQualifiedName(T, Ctx, *UserPolicy, WithGlobalNs);
return cxstring::createDup(Str);
}
CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
using namespace cxcursor;
CXTranslationUnit TU = cxcursor::getCursorTU(C);

View File

@@ -438,6 +438,11 @@ LLVM_20 {
clang_visitCXXMethods;
};
LLVM_21 {
global:
clang_getFullyQualifiedName;
};
# Example of how to add a new symbol version entry. If you do add a new symbol
# version, please update the example to depend on the version you added.
# LLVM_X {