diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2789,7 +2789,9 @@ CXType_ExtVector = 176, CXType_Atomic = 177, - CXType_BTFTagAttributed = 178 + CXType_BTFTagAttributed = 178, + /* Represents a type that as been substituted for a template type parameter */ + CXType_SubstTemplateTypeParm = 179 }; /** @@ -3447,6 +3449,13 @@ */ CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); +/** + * Gets the replacement type for a SubstTemplateTypeParm type. + * + * If any other type kind is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getReplacementType(CXType CT); + /** * Return the offset of the field represented by the Cursor. * diff --git a/clang/test/Index/print-type.cpp b/clang/test/Index/print-type.cpp --- a/clang/test/Index/print-type.cpp +++ b/clang/test/Index/print-type.cpp @@ -171,7 +171,7 @@ // CHECK: VarDecl=autoI:54:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] // CHECK: VarDecl=autoTbar:55:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] -// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=Unexposed] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] +// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=SubstTemplateTypeParm] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] // CHECK: UnexposedExpr=tbar:36:3 [type=int (*)(int)] [typekind=Pointer] [canonicaltype=int (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=int (int)] [pointeekind=FunctionProto] // CHECK: DeclRefExpr=tbar:36:3 RefName=[55:17 - 55:21] RefName=[55:21 - 55:26] [type=int (int)] [typekind=FunctionProto] [canonicaltype=int (int)] [canonicaltypekind=FunctionProto] [isPOD=0] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -118,12 +118,17 @@ TKCASE(Attributed); TKCASE(BTFTagAttributed); TKCASE(Atomic); + TKCASE(SubstTemplateTypeParm); default: return CXType_Unexposed; } #undef TKCASE } +static CXTypeKind GetSubstTemplateTypeParmTypeKind(const SubstTemplateTypeParmType* TP) { + const QualType RT = TP->getReplacementType(); + return GetTypeKind(RT); +} CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { CXTypeKind TK = CXType_Invalid; @@ -635,6 +640,7 @@ TKIND(OCLQueue); TKIND(OCLReserveID); TKIND(Atomic); + TKIND(SubstTemplateTypeParm); } #undef TKIND return cxstring::createRef(s); @@ -1355,3 +1361,13 @@ const auto *AT = T->castAs(); return MakeCXType(AT->getValueType(), GetTU(CT)); } + +CXType clang_Type_getReplacementType(CXType CT) { + QualType T = GetQualType(CT); + + if (T.isNull() || T->getTypeClass() != Type::SubstTemplateTypeParm) + return MakeCXType(QualType(), GetTU(CT)); + + const auto *ST = T->castAs(); + return MakeCXType(ST->getReplacementType(), GetTU(CT)); +} \ No newline at end of file diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map --- a/clang/tools/libclang/libclang.map +++ b/clang/tools/libclang/libclang.map @@ -167,6 +167,7 @@ clang_Type_getSizeOf; clang_Type_getTemplateArgumentAsType; clang_Type_getValueType; + clang_Type_getReplacementType; clang_Type_isTransparentTagTypedef; clang_Type_visitFields; clang_VerbatimBlockLineComment_getText;