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