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 @@ -2795,7 +2795,9 @@ CXType_ExtVector = 176, CXType_Atomic = 177, - CXType_BTFTagAttributed = 178 + CXType_BTFTagAttributed = 178, + + CXType_Using = 179 }; /** diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -4062,6 +4062,7 @@ return CXCursor_TranslationUnit; case Decl::Using: + case Decl::UsingShadow: case Decl::UnresolvedUsingValue: case Decl::UnresolvedUsingTypename: return CXCursor_UsingDeclaration; 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 @@ -92,6 +92,14 @@ } inline namespace InlineNS {} + +namespace ToBeExported { + typedef int ToBeExportedType; +} + +using ToBeExported::ToBeExportedType; +void UseToBeExported(ToBeExportedType f); + // RUN: c-index-test -test-print-type %s -std=c++14 | FileCheck %s // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] @@ -207,3 +215,5 @@ // CHECK: EnumDecl=(unnamed enum at {{.*}}:87:3 (Definition) [type=X::(unnamed enum at {{.*}}print-type.cpp:87:3)] [typekind=Enum] [isPOD=1] [isAnon=1] // CHECK: Namespace=:90:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] [isAnon=1] // CHECK: Namespace=InlineNS:94:18 (Definition) [type=] [typekind=Invalid] [isPOD=0] [isAnonRecDecl=0] [isInlineNamespace=1] +// CHECK: UsingDeclaration=ToBeExportedType[97:9] [type=] [typekind=Invalid] [isPOD=0] [isAnonRecDecl=0] +// CHECK: ParmDecl=f:101:39 (Definition) [type=ToBeExportedType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] [isAnonRecDecl=0] diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -1276,6 +1276,10 @@ return MakeCursorTypeRef(Tag->getDecl(), Loc, TU); if (const TemplateTypeParmType *TemplP = Ty->getAs()) return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU); + if (const UsingType *Using = Ty->getAs()) + if (const UsingShadowDecl *Shadow = Using->getFoundDecl()) + if (const auto *TD = dyn_cast_or_null(Shadow->getTargetDecl())) + return MakeCursorTypeRef(TD, Loc, TU); return cursor; } 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 @@ -99,6 +99,7 @@ TKCASE(Record); TKCASE(Enum); TKCASE(Typedef); + TKCASE(Using); TKCASE(ObjCInterface); TKCASE(ObjCObject); TKCASE(ObjCObjectPointer); @@ -219,24 +220,9 @@ return std::nullopt; } -CXType clang_getCursorType(CXCursor C) { - using namespace cxcursor; - - CXTranslationUnit TU = cxcursor::getCursorTU(C); - if (!TU) - return MakeCXType(QualType(), TU); - - ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext(); - if (clang_isExpression(C.kind)) { - QualType T = cxcursor::getCursorExpr(C)->getType(); - return MakeCXType(T, TU); - } - - if (clang_isDeclaration(C.kind)) { - const Decl *D = cxcursor::getCursorDecl(C); +static CXType getDeclType(const Decl* D, CXTranslationUnit TU, ASTContext &Context) { if (!D) return MakeCXType(QualType(), TU); - if (const TypeDecl *TD = dyn_cast(D)) return MakeCXType(Context.getTypeDeclType(TD), TU); if (const ObjCInterfaceDecl *ID = dyn_cast(D)) @@ -249,9 +235,27 @@ return MakeCXType(PD->getType(), TU); if (const FunctionTemplateDecl *FTD = dyn_cast(D)) return MakeCXType(FTD->getTemplatedDecl()->getType(), TU); + if (const auto *UD = dyn_cast(D)) + return getDeclType(UD->getTargetDecl(), TU, Context); return MakeCXType(QualType(), TU); +} + +CXType clang_getCursorType(CXCursor C) { + using namespace cxcursor; + + CXTranslationUnit TU = cxcursor::getCursorTU(C); + if (!TU) + return MakeCXType(QualType(), TU); + + ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext(); + if (clang_isExpression(C.kind)) { + QualType T = cxcursor::getCursorExpr(C)->getType(); + return MakeCXType(T, TU); } + if (clang_isDeclaration(C.kind)) + return getDeclType(cxcursor::getCursorDecl(C), TU, Context); + if (clang_isReference(C.kind)) { switch (C.kind) { case CXCursor_ObjCSuperClassRef: { @@ -501,6 +505,9 @@ case Type::Typedef: D = cast(TP)->getDecl(); break; + case Type::Using: + D = cast(TP)->getFoundDecl(); + break; case Type::ObjCObject: D = cast(TP)->getInterface(); break; @@ -598,6 +605,7 @@ TKIND(Record); TKIND(Enum); TKIND(Typedef); + TKIND(Using); TKIND(ObjCInterface); TKIND(ObjCObject); TKIND(ObjCObjectPointer);