diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index ef779d622a8a..9a56f332a0f5 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -1086,7 +1086,9 @@ enum CXTypeKind { CXType_Enum = 106, CXType_Typedef = 107, CXType_ObjCInterface = 108, - CXType_ObjCObjectPointer = 109 + CXType_ObjCObjectPointer = 109, + CXType_FunctionNoProto = 110, + CXType_FunctionProto = 111 }; /** @@ -1138,6 +1140,11 @@ CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T); */ CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K); +/** + * \brief Retrieve the result type associated with a function or method type. + */ +CINDEX_LINKAGE CXType clang_getResultType(CXType T); + /** * @} */ diff --git a/clang/test/Index/print-typekind.c b/clang/test/Index/print-typekind.c index 79a9965d4d85..13b41198f127 100644 --- a/clang/test/Index/print-typekind.c +++ b/clang/test/Index/print-typekind.c @@ -8,7 +8,7 @@ int *f(int *p, char *x, FooType z) { // RUN: c-index-test -test-print-typekind %s | FileCheck %s // CHECK: TypedefDecl=FooType:1:13 (Definition) typekind=Typedef [canonical=Int] // CHECK: VarDecl=p:2:6 typekind=Pointer -// CHECK: FunctionDecl=f:3:6 (Definition) typekind=Unexposed [canonical=Unexposed] +// CHECK: FunctionDecl=f:3:6 (Definition) typekind=FunctionProto [canonical=FunctionProto] [result=Pointer] // CHECK: ParmDecl=p:3:13 (Definition) typekind=Pointer // CHECK: ParmDecl=x:3:22 (Definition) typekind=Pointer // CHECK: ParmDecl=z:3:33 (Definition) typekind=Typedef [canonical=Int] diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index 4268cec1b231..27c51a0c596a 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -455,16 +455,29 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p, if (!clang_isInvalid(clang_getCursorKind(cursor))) { CXType T = clang_getCursorType(cursor); - CXType CT = clang_getCanonicalType(T); CXString S = clang_getTypeKindSpelling(T.kind); PrintCursor(cursor); printf(" typekind=%s", clang_getCString(S)); - if (!clang_equalTypes(T, CT)) { - CXString CS = clang_getTypeKindSpelling(CT.kind); - printf(" [canonical=%s]", clang_getCString(CS)); - clang_disposeString(CS); - } clang_disposeString(S); + // Print the canonical type if it is different. + { + CXType CT = clang_getCanonicalType(T); + if (!clang_equalTypes(T, CT)) { + CXString CS = clang_getTypeKindSpelling(CT.kind); + printf(" [canonical=%s]", clang_getCString(CS)); + clang_disposeString(CS); + } + } + // Print the return type if it exists. + { + CXType RT = clang_getResultType(T); + if (RT.kind != CXType_Invalid) { + CXString RS = clang_getTypeKindSpelling(RT.kind); + printf(" [result=%s]", clang_getCString(RS)); + clang_disposeString(RS); + } + } + printf("\n"); } return CXChildVisit_Recurse; diff --git a/clang/tools/libclang/CXTypes.cpp b/clang/tools/libclang/CXTypes.cpp index ae756c7a1eea..64e49fba2b54 100644 --- a/clang/tools/libclang/CXTypes.cpp +++ b/clang/tools/libclang/CXTypes.cpp @@ -77,6 +77,8 @@ static CXTypeKind GetTypeKind(QualType T) { TKCASE(Typedef); TKCASE(ObjCInterface); TKCASE(ObjCObjectPointer); + TKCASE(FunctionNoProto); + TKCASE(FunctionProto); default: return CXType_Unexposed; } @@ -118,7 +120,8 @@ CXType clang_getCursorType(CXCursor C) { return MakeCXType(VD->getType(), AU); if (ObjCPropertyDecl *PD = dyn_cast(D)) return MakeCXType(PD->getType(), AU); - + if (FunctionDecl *FD = dyn_cast(D)) + return MakeCXType(FD->getType(), AU); return MakeCXType(QualType(), AU); } @@ -246,6 +249,8 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) { TKIND(Typedef); TKIND(ObjCInterface); TKIND(ObjCObjectPointer); + TKIND(FunctionNoProto); + TKIND(FunctionProto); } #undef TKIND return cxstring::createCXString(s); @@ -255,4 +260,15 @@ unsigned clang_equalTypes(CXType A, CXType B) { return A.data[0] == B.data[0] && A.data[1] == B.data[1];; } +CXType clang_getResultType(CXType X) { + QualType T = GetQualType(X); + if (!T.getTypePtr()) + return MakeCXType(QualType(), GetASTU(X)); + + if (const FunctionType *FD = T->getAs()) + return MakeCXType(FD->getResultType(), GetASTU(X)); + + return MakeCXType(QualType(), GetASTU(X)); +} + } // end: extern "C" diff --git a/clang/tools/libclang/libclang.darwin.exports b/clang/tools/libclang/libclang.darwin.exports index 3ef3b748547b..6c7eddfec62d 100644 --- a/clang/tools/libclang/libclang.darwin.exports +++ b/clang/tools/libclang/libclang.darwin.exports @@ -67,6 +67,7 @@ _clang_getPointeeType _clang_getRange _clang_getRangeEnd _clang_getRangeStart +_clang_getResultType _clang_getTokenExtent _clang_getTokenKind _clang_getTokenLocation diff --git a/clang/tools/libclang/libclang.exports b/clang/tools/libclang/libclang.exports index c7831f777e97..138b9767b19f 100644 --- a/clang/tools/libclang/libclang.exports +++ b/clang/tools/libclang/libclang.exports @@ -67,6 +67,7 @@ clang_getPointeeType clang_getRange clang_getRangeEnd clang_getRangeStart +clang_getResultType clang_getTokenExtent clang_getTokenKind clang_getTokenLocation