Index: clang/include/clang-c/Index.h =================================================================== --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -33,7 +33,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 59 +#define CINDEX_VERSION_MINOR 60 #define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1)) @@ -3342,7 +3342,8 @@ CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175, - CXType_ExtVector = 176 + CXType_ExtVector = 176, + CXType_Atomic = 177 }; /** @@ -3932,6 +3933,13 @@ */ CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T); +/** + * Gets the type contained by this atomic type. + * + * If a non-atomic type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); + /** * Return the offset of the field represented by the Cursor. * Index: clang/test/Index/print-type.c =================================================================== --- clang/test/Index/print-type.c +++ clang/test/Index/print-type.c @@ -22,13 +22,15 @@ struct { struct { - int x; + _Atomic int x; int y; }; } bar; void fun(struct { int x; int y; } *param); +_Atomic(unsigned long) aul; + // RUN: c-index-test -test-print-type %s | FileCheck %s // CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0] // CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int] @@ -70,4 +72,7 @@ // CHECK: StructDecl=:18:1 (Definition) [type=struct (anonymous at {{.*}}print-type.c:18:1)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0] // CHECK: StructDecl=:23:1 (Definition) [type=struct (anonymous at {{.*}}print-type.c:23:1)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] [isAnonRecDecl=0] // CHECK: StructDecl=:24:3 (Definition) [type=struct (anonymous at {{.*}}print-type.c:24:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=1] +// CHECK: FieldDecl=x:25:17 (Definition) [type=_Atomic(int)] [typekind=Atomic] [valuetype=int] [valuetypekind=Int] [isPOD=0] [isAnonRecDecl=0] +// CHECK: FieldDecl=y:26:9 (Definition) [type=int] [typekind=Int] [isPOD=1] [isAnonRecDecl=0] // CHECK: StructDecl=:30:10 (Definition) [type=struct (anonymous at {{.*}}print-type.c:30:10)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0] +// CHECK: VarDecl=aul:32:24 [type=_Atomic(unsigned long)] [typekind=Atomic] [valuetype=unsigned long] [valuetypekind=ULong] [isPOD=0] [isAnonRecDecl=0] Index: clang/tools/c-index-test/c-index-test.c =================================================================== --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -1579,6 +1579,12 @@ PrintTypeTemplateArgs(CT, " [canonicaltemplateargs/%d="); } } + /* Print the value type if it exists. */ + { + CXType VT = clang_Type_getValueType(T); + if (VT.kind != CXType_Invalid) + PrintTypeAndTypeKind(VT, " [valuetype=%s] [valuetypekind=%s]"); + } /* Print the modified type if it exists. */ { CXType MT = clang_Type_getModifiedType(T); Index: clang/tools/libclang/CXType.cpp =================================================================== --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -115,6 +115,7 @@ TKCASE(Elaborated); TKCASE(Pipe); TKCASE(Attributed); + TKCASE(Atomic); default: return CXType_Unexposed; } @@ -616,6 +617,7 @@ TKIND(OCLEvent); TKIND(OCLQueue); TKIND(OCLReserveID); + TKIND(Atomic); } #undef TKIND return cxstring::createRef(s); @@ -1318,3 +1320,13 @@ } return CXTypeNullability_Invalid; } + +CXType clang_Type_getValueType(CXType CT) { + QualType T = GetQualType(CT); + + if (T.isNull() || !T->isAtomicType()) + return MakeCXType(QualType(), GetTU(CT)); + + const auto *AT = T->castAs(); + return MakeCXType(AT->getValueType(), GetTU(CT)); +} Index: clang/tools/libclang/libclang.exports =================================================================== --- clang/tools/libclang/libclang.exports +++ clang/tools/libclang/libclang.exports @@ -109,6 +109,7 @@ clang_Type_getObjCTypeArg clang_Type_getModifiedType clang_Type_getNullability +clang_Type_getValueType clang_VerbatimBlockLineComment_getText clang_VerbatimLineComment_getText clang_HTMLTagComment_getAsString