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