1*7330f729Sjoerg //===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===// 2*7330f729Sjoerg // 3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*7330f729Sjoerg // 7*7330f729Sjoerg //===----------------------------------------------------------------------===// 8*7330f729Sjoerg // 9*7330f729Sjoerg // This file implements the libclang support for C++ cursors. 10*7330f729Sjoerg // 11*7330f729Sjoerg //===----------------------------------------------------------------------===// 12*7330f729Sjoerg 13*7330f729Sjoerg #include "CIndexer.h" 14*7330f729Sjoerg #include "CXCursor.h" 15*7330f729Sjoerg #include "CXType.h" 16*7330f729Sjoerg #include "clang/AST/DeclCXX.h" 17*7330f729Sjoerg #include "clang/AST/DeclTemplate.h" 18*7330f729Sjoerg 19*7330f729Sjoerg using namespace clang; 20*7330f729Sjoerg using namespace clang::cxcursor; 21*7330f729Sjoerg clang_isVirtualBase(CXCursor C)22*7330f729Sjoergunsigned clang_isVirtualBase(CXCursor C) { 23*7330f729Sjoerg if (C.kind != CXCursor_CXXBaseSpecifier) 24*7330f729Sjoerg return 0; 25*7330f729Sjoerg 26*7330f729Sjoerg const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); 27*7330f729Sjoerg return B->isVirtual(); 28*7330f729Sjoerg } 29*7330f729Sjoerg clang_getCXXAccessSpecifier(CXCursor C)30*7330f729Sjoergenum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { 31*7330f729Sjoerg AccessSpecifier spec = AS_none; 32*7330f729Sjoerg 33*7330f729Sjoerg if (C.kind == CXCursor_CXXAccessSpecifier || clang_isDeclaration(C.kind)) 34*7330f729Sjoerg spec = getCursorDecl(C)->getAccess(); 35*7330f729Sjoerg else if (C.kind == CXCursor_CXXBaseSpecifier) 36*7330f729Sjoerg spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier(); 37*7330f729Sjoerg else 38*7330f729Sjoerg return CX_CXXInvalidAccessSpecifier; 39*7330f729Sjoerg 40*7330f729Sjoerg switch (spec) { 41*7330f729Sjoerg case AS_public: return CX_CXXPublic; 42*7330f729Sjoerg case AS_protected: return CX_CXXProtected; 43*7330f729Sjoerg case AS_private: return CX_CXXPrivate; 44*7330f729Sjoerg case AS_none: return CX_CXXInvalidAccessSpecifier; 45*7330f729Sjoerg } 46*7330f729Sjoerg 47*7330f729Sjoerg llvm_unreachable("Invalid AccessSpecifier!"); 48*7330f729Sjoerg } 49*7330f729Sjoerg clang_getTemplateCursorKind(CXCursor C)50*7330f729Sjoergenum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { 51*7330f729Sjoerg using namespace clang::cxcursor; 52*7330f729Sjoerg 53*7330f729Sjoerg switch (C.kind) { 54*7330f729Sjoerg case CXCursor_ClassTemplate: 55*7330f729Sjoerg case CXCursor_FunctionTemplate: 56*7330f729Sjoerg if (const TemplateDecl *Template 57*7330f729Sjoerg = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C))) 58*7330f729Sjoerg return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind; 59*7330f729Sjoerg break; 60*7330f729Sjoerg 61*7330f729Sjoerg case CXCursor_ClassTemplatePartialSpecialization: 62*7330f729Sjoerg if (const ClassTemplateSpecializationDecl *PartialSpec 63*7330f729Sjoerg = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>( 64*7330f729Sjoerg getCursorDecl(C))) { 65*7330f729Sjoerg switch (PartialSpec->getTagKind()) { 66*7330f729Sjoerg case TTK_Interface: 67*7330f729Sjoerg case TTK_Struct: return CXCursor_StructDecl; 68*7330f729Sjoerg case TTK_Class: return CXCursor_ClassDecl; 69*7330f729Sjoerg case TTK_Union: return CXCursor_UnionDecl; 70*7330f729Sjoerg case TTK_Enum: return CXCursor_NoDeclFound; 71*7330f729Sjoerg } 72*7330f729Sjoerg } 73*7330f729Sjoerg break; 74*7330f729Sjoerg 75*7330f729Sjoerg default: 76*7330f729Sjoerg break; 77*7330f729Sjoerg } 78*7330f729Sjoerg 79*7330f729Sjoerg return CXCursor_NoDeclFound; 80*7330f729Sjoerg } 81*7330f729Sjoerg clang_getSpecializedCursorTemplate(CXCursor C)82*7330f729SjoergCXCursor clang_getSpecializedCursorTemplate(CXCursor C) { 83*7330f729Sjoerg if (!clang_isDeclaration(C.kind)) 84*7330f729Sjoerg return clang_getNullCursor(); 85*7330f729Sjoerg 86*7330f729Sjoerg const Decl *D = getCursorDecl(C); 87*7330f729Sjoerg if (!D) 88*7330f729Sjoerg return clang_getNullCursor(); 89*7330f729Sjoerg 90*7330f729Sjoerg Decl *Template = nullptr; 91*7330f729Sjoerg if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { 92*7330f729Sjoerg if (const ClassTemplatePartialSpecializationDecl *PartialSpec 93*7330f729Sjoerg = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) 94*7330f729Sjoerg Template = PartialSpec->getSpecializedTemplate(); 95*7330f729Sjoerg else if (const ClassTemplateSpecializationDecl *ClassSpec 96*7330f729Sjoerg = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) { 97*7330f729Sjoerg llvm::PointerUnion<ClassTemplateDecl *, 98*7330f729Sjoerg ClassTemplatePartialSpecializationDecl *> Result 99*7330f729Sjoerg = ClassSpec->getSpecializedTemplateOrPartial(); 100*7330f729Sjoerg if (Result.is<ClassTemplateDecl *>()) 101*7330f729Sjoerg Template = Result.get<ClassTemplateDecl *>(); 102*7330f729Sjoerg else 103*7330f729Sjoerg Template = Result.get<ClassTemplatePartialSpecializationDecl *>(); 104*7330f729Sjoerg 105*7330f729Sjoerg } else 106*7330f729Sjoerg Template = CXXRecord->getInstantiatedFromMemberClass(); 107*7330f729Sjoerg } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { 108*7330f729Sjoerg Template = Function->getPrimaryTemplate(); 109*7330f729Sjoerg if (!Template) 110*7330f729Sjoerg Template = Function->getInstantiatedFromMemberFunction(); 111*7330f729Sjoerg } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { 112*7330f729Sjoerg if (Var->isStaticDataMember()) 113*7330f729Sjoerg Template = Var->getInstantiatedFromStaticDataMember(); 114*7330f729Sjoerg } else if (const RedeclarableTemplateDecl *Tmpl 115*7330f729Sjoerg = dyn_cast<RedeclarableTemplateDecl>(D)) 116*7330f729Sjoerg Template = Tmpl->getInstantiatedFromMemberTemplate(); 117*7330f729Sjoerg 118*7330f729Sjoerg if (!Template) 119*7330f729Sjoerg return clang_getNullCursor(); 120*7330f729Sjoerg 121*7330f729Sjoerg return MakeCXCursor(Template, getCursorTU(C)); 122*7330f729Sjoerg } 123