https://github.com/w-utter updated https://github.com/llvm/llvm-project/pull/212648
>From ded00301e58cb228a318e0c008bdcd33a4c836c7 Mon Sep 17 00:00:00 2001 From: will <[email protected]> Date: Wed, 29 Jul 2026 08:52:56 +1000 Subject: [PATCH 1/2] [libclang] Add clang_Type_getDependentSizeExpr --- clang/include/clang-c/Index.h | 8 ++++++++ clang/tools/libclang/CXType.cpp | 26 ++++++++++++++++++++++++++ clang/tools/libclang/libclang.map | 1 + 3 files changed, 35 insertions(+) diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 8427236e0b444..3c2ae30d9bbb9 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -3734,6 +3734,14 @@ CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T); */ CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); + +/** + * Gets the expression associated with this dependent sized array + * + * If a non-dependent type is passed in, an invalid cursor is returned. + */ +CINDEX_LINKAGE CXCursor clang_Type_getDependentSizeExpr(CXType CT); + /** * Return the offset of the field represented by the Cursor. * diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index 0063939dec423..52e813ea3c795 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -912,6 +912,32 @@ long long clang_getNumElements(CXType CT) { return result; } +CXCursor clang_Type_getDependentSizeExpr(CXType CT) { + QualType T = GetQualType(CT); + const Type *TP = T.getTypePtrOrNull(); + + if (!TP) + return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); + + const Expr* E = nullptr; + + switch (TP->getTypeClass()) { + case Type::DependentSizedArray: + E = cast<DependentSizedArrayType> (TP)->getSizeExpr(); + break; + case Type::DependentSizedExtVector: + E = cast<DependentSizedExtVectorType> (TP)->getSizeExpr(); + break; + default: + break; + } + + if (!E) + return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); + + return cxcursor::MakeCXCursor(E, nullptr, GetTU(CT)); +} + CXType clang_getArrayElementType(CXType CT) { QualType ET = QualType(); QualType T = GetQualType(CT); diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map index 57f281096929d..4864cb6da5929 100644 --- a/clang/tools/libclang/libclang.map +++ b/clang/tools/libclang/libclang.map @@ -461,6 +461,7 @@ LLVM_23 { global: clang_ModuleCache_prune; clang_ModuleCache_pruneWithCallback; + clang_Type_getDependentSizeExpr; }; # Example of how to add a new symbol version entry. If you do add a new symbol >From 34d1bffc3e0253c474cc774ce327c8ded059b5a6 Mon Sep 17 00:00:00 2001 From: will <[email protected]> Date: Thu, 30 Jul 2026 23:20:03 +1000 Subject: [PATCH 2/2] [libclang] support getting template argument kind & values from CXType --- clang/include/clang-c/Index.h | 31 +++++++++++ clang/tools/libclang/CMakeLists.txt | 1 + clang/tools/libclang/CXCursor.cpp | 52 +++--------------- clang/tools/libclang/CXTemplateArgument.h | 62 ++++++++++++++++++++++ clang/tools/libclang/CXType.cpp | 64 ++++++++++++++++------- clang/tools/libclang/libclang.map | 5 ++ 6 files changed, 150 insertions(+), 65 deletions(-) create mode 100644 clang/tools/libclang/CXTemplateArgument.h diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 3c2ae30d9bbb9..6c53d1f7e5233 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -3251,6 +3251,15 @@ CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C); CINDEX_LINKAGE enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, unsigned I); +/** + * Retrieve the kind of the I'th template argument of the CXType CT. + * + * If the argument CXType does not represent a template specialization, + * an invalid template argument kind is returned. + */ +CINDEX_LINKAGE enum CXTemplateArgumentKind +clang_Type_getTemplateArgumentKind(CXType CT, unsigned I); + /** * Retrieve a CXType representing the type of a TemplateArgument of a * function decl representing a template specialization. @@ -3293,6 +3302,17 @@ CINDEX_LINKAGE CXType clang_Cursor_getTemplateArgumentType(CXCursor C, CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I); +/** + * Retrieve the value of an Integral TemplateArgument (of a function + * decl representing a template specialization) as a signed long long. + * + * It is undefined to call this function on a CXType that does not represent a + * FunctionDecl, StructDecl, ClassDecl or ClassTemplatePartialSpecialization + * whose I'th template argument is not an integral value. + */ +CINDEX_LINKAGE long long clang_Type_getTemplateArgumentValue(CXType CT, + unsigned index); + /** * Retrieve the value of an Integral TemplateArgument (of a function * decl representing a template specialization) as an unsigned long long. @@ -3314,6 +3334,17 @@ CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C, CINDEX_LINKAGE unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C, unsigned I); +/** + * Retrieve the value of an Integral TemplateArgument (of a function + * decl representing a template specialization) as an unsigned long long. + * + * It is undefined to call this function on a CXType that does not represent a + * FunctionDecl, StructDecl, ClassDecl or ClassTemplatePartialSpecialization + * whose I'th template argument is not an integral value. + */ +CINDEX_LINKAGE unsigned long long +clang_Type_getTemplateArgumentUnsignedValue(CXType C, unsigned I); + /** * Determine whether two CXTypes represent the same type. * diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt index 38f577499dd22..a1e9ea43d2d8e 100644 --- a/clang/tools/libclang/CMakeLists.txt +++ b/clang/tools/libclang/CMakeLists.txt @@ -51,6 +51,7 @@ set(SOURCES CXLoadedDiagnostic.h CXSourceLocation.h CXString.h + CXTemplateArgument.h CXTranslationUnit.h CXType.h Index_Internal.h diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index fb0b3c1502574..6bf9fe24d2fb1 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -14,6 +14,7 @@ #include "CXCursor.h" #include "CXString.h" +#include "CXTemplateArgument.h" #include "CXTranslationUnit.h" #include "CXType.h" #include "clang-c/Index.h" @@ -1529,38 +1530,12 @@ static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I, return CXGetTemplateArgumentStatus_BadDeclCast; } -enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, - unsigned I) { +enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, unsigned I) { TemplateArgument TA; if (clang_Cursor_getTemplateArgument(C, I, &TA)) { return CXTemplateArgumentKind_Invalid; } - - switch (TA.getKind()) { - case TemplateArgument::Null: - return CXTemplateArgumentKind_Null; - case TemplateArgument::Type: - return CXTemplateArgumentKind_Type; - case TemplateArgument::Declaration: - return CXTemplateArgumentKind_Declaration; - case TemplateArgument::NullPtr: - return CXTemplateArgumentKind_NullPtr; - case TemplateArgument::Integral: - return CXTemplateArgumentKind_Integral; - case TemplateArgument::StructuralValue: - // FIXME: Expose these values. - return CXTemplateArgumentKind_Invalid; - case TemplateArgument::Template: - return CXTemplateArgumentKind_Template; - case TemplateArgument::TemplateExpansion: - return CXTemplateArgumentKind_TemplateExpansion; - case TemplateArgument::Expression: - return CXTemplateArgumentKind_Expression; - case TemplateArgument::Pack: - return CXTemplateArgumentKind_Pack; - } - - return CXTemplateArgumentKind_Invalid; + return GetTemplateArgumentKind(TA); } CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) { @@ -1569,12 +1544,7 @@ CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) { CXGetTemplateArgumentStatus_Success) { return cxtype::MakeCXType(QualType(), getCursorTU(C)); } - - if (TA.getKind() != TemplateArgument::Type) { - return cxtype::MakeCXType(QualType(), getCursorTU(C)); - } - - return cxtype::MakeCXType(TA.getAsType(), getCursorTU(C)); + return GetTemplateArgumentType(TA, getCursorTU(C)); } long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) { @@ -1585,12 +1555,7 @@ long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) { return 0; } - if (TA.getKind() != TemplateArgument::Integral) { - assert(0 && "Passed template argument is not Integral"); - return 0; - } - - return TA.getAsIntegral().getSExtValue(); + return GetTemplateArgumentValue(TA); } unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C, @@ -1602,12 +1567,7 @@ unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C, return 0; } - if (TA.getKind() != TemplateArgument::Integral) { - assert(0 && "Passed template argument is not Integral"); - return 0; - } - - return TA.getAsIntegral().getZExtValue(); + return GetTemplateArgumentUnsignedValue(TA); } //===----------------------------------------------------------------------===// diff --git a/clang/tools/libclang/CXTemplateArgument.h b/clang/tools/libclang/CXTemplateArgument.h new file mode 100644 index 0000000000000..a5e2eab785dd4 --- /dev/null +++ b/clang/tools/libclang/CXTemplateArgument.h @@ -0,0 +1,62 @@ +#include "clang-c/Index.h" +#include "clang/AST/TemplateBase.h" + +#include "CXCursor.h" +#include "CXTranslationUnit.h" +#include "CXType.h" + +using namespace clang; + +enum CXTemplateArgumentKind GetTemplateArgumentKind(TemplateArgument TA) { + switch (TA.getKind()) { + case TemplateArgument::Null: + return CXTemplateArgumentKind_Null; + case TemplateArgument::Type: + return CXTemplateArgumentKind_Type; + case TemplateArgument::Declaration: + return CXTemplateArgumentKind_Declaration; + case TemplateArgument::NullPtr: + return CXTemplateArgumentKind_NullPtr; + case TemplateArgument::Integral: + return CXTemplateArgumentKind_Integral; + case TemplateArgument::StructuralValue: + // FIXME: Expose these values. + return CXTemplateArgumentKind_Invalid; + case TemplateArgument::Template: + return CXTemplateArgumentKind_Template; + case TemplateArgument::TemplateExpansion: + return CXTemplateArgumentKind_TemplateExpansion; + case TemplateArgument::Expression: + return CXTemplateArgumentKind_Expression; + case TemplateArgument::Pack: + return CXTemplateArgumentKind_Pack; + } + + return CXTemplateArgumentKind_Invalid; +} + +CXType GetTemplateArgumentType(TemplateArgument TA, CXTranslationUnit TU) { + if (TA.getKind() != TemplateArgument::Type) { + return cxtype::MakeCXType(QualType(), TU); + } + + return cxtype::MakeCXType(TA.getAsType(), TU); +} + +long long GetTemplateArgumentValue(TemplateArgument TA) { + if (TA.getKind() != TemplateArgument::Integral) { + assert(0 && "Passed template argument is not Integral"); + return 0; + } + + return TA.getAsIntegral().getSExtValue(); +} + +unsigned long long GetTemplateArgumentUnsignedValue(TemplateArgument TA) { + if (TA.getKind() != TemplateArgument::Integral) { + assert(0 && "Passed template argument is not Integral"); + return 0; + } + + return TA.getAsIntegral().getZExtValue(); +} diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index 52e813ea3c795..dd49fe15564c9 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -14,7 +14,9 @@ #include "CIndexer.h" #include "CXCursor.h" #include "CXString.h" +#include "CXTemplateArgument.h" #include "CXTranslationUnit.h" +#include "clang-c/Index.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" @@ -201,25 +203,26 @@ GetTemplateArguments(QualType Type) { return std::nullopt; } -static std::optional<QualType> -TemplateArgumentToQualType(const TemplateArgument &A) { - if (A.getKind() == TemplateArgument::Type) - return A.getAsType(); - return std::nullopt; -} +std::optional<TemplateArgument> +FindTemplateArgumentAt(CXType CT, unsigned index) { + QualType T = GetQualType(CT); + if (T.isNull()) + return std::nullopt; + + auto TA = GetTemplateArguments(T); + if (!TA) + return std::nullopt; -static std::optional<QualType> -FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) { unsigned current = 0; - for (const auto &A : TA) { + for (const auto &A : *TA) { if (A.getKind() == TemplateArgument::Pack) { if (index < current + A.pack_size()) - return TemplateArgumentToQualType(A.getPackAsArray()[index - current]); + return A.getPackAsArray()[index - current]; current += A.pack_size(); continue; } if (current == index) - return TemplateArgumentToQualType(A); + return A; current++; } return std::nullopt; @@ -1273,17 +1276,40 @@ int clang_Type_getNumTemplateArguments(CXType CT) { return GetTemplateArgumentArraySize(*TA); } +enum CXTemplateArgumentKind clang_Type_getTemplateArgumentKind(CXType CT, unsigned index) { + const auto TA = FindTemplateArgumentAt(CT, index); + + if (!TA) { + return CXTemplateArgumentKind_Invalid; + } + return GetTemplateArgumentKind(*TA); +} + +long long clang_Type_getTemplateArgumentValue(CXType CT, unsigned index) { + const auto TA = FindTemplateArgumentAt(CT, index); + + if (!TA) { + return 0; + } + return GetTemplateArgumentValue(*TA); +} + +unsigned long long clang_Type_getTemplateArgumentUnsignedValue(CXType CT, unsigned index) { + const auto TA = FindTemplateArgumentAt(CT, index); + + if (!TA) { + return 0; + } + return GetTemplateArgumentValue(*TA); +} + CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) { - QualType T = GetQualType(CT); - if (T.isNull()) - return MakeCXType(QualType(), GetTU(CT)); + const auto TA = FindTemplateArgumentAt(CT, index); - auto TA = GetTemplateArguments(T); - if (!TA) + if (!TA) { return MakeCXType(QualType(), GetTU(CT)); - - std::optional<QualType> QT = FindTemplateArgumentTypeAt(*TA, index); - return MakeCXType(QT.value_or(QualType()), GetTU(CT)); + } + return GetTemplateArgumentType(*TA, GetTU(CT)); } CXType clang_Type_getObjCObjectBaseType(CXType CT) { diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map index 4864cb6da5929..7e51647d1f49c 100644 --- a/clang/tools/libclang/libclang.map +++ b/clang/tools/libclang/libclang.map @@ -462,8 +462,13 @@ LLVM_23 { clang_ModuleCache_prune; clang_ModuleCache_pruneWithCallback; clang_Type_getDependentSizeExpr; + clang_Type_getTemplateArgumentValue; + clang_Type_getTemplateArgumentUnsignedValue; + clang_Type_getTemplateArgumentKind; }; + + # 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 { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
