1585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek//===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===// 2585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// 3585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// The LLVM Compiler Infrastructure 4585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// 5585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// This file is distributed under the University of Illinois Open Source 6585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// License. See LICENSE.TXT for details. 7585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// 8585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek//===----------------------------------------------------------------------===// 9585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// 10585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// This file implements the libclang support for C++ cursors. 11585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek// 12585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek//===----------------------------------------------------------------------===// 13585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 14585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek#include "CIndexer.h" 15585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek#include "CXCursor.h" 16585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek#include "CXType.h" 17585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek#include "clang/AST/DeclCXX.h" 1849f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor#include "clang/AST/DeclTemplate.h" 19585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 20585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenekusing namespace clang; 21e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregorusing namespace clang::cxcursor; 22585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 23585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenekextern "C" { 24585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 25585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenekunsigned clang_isVirtualBase(CXCursor C) { 26585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek if (C.kind != CXCursor_CXXBaseSpecifier) 27585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek return 0; 28585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 2967812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); 30585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek return B->isVirtual(); 31585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek} 32585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 33585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenekenum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { 342dfdb948bef51a601e763191e4becfe59880d382Argyrios Kyrtzidis AccessSpecifier spec = AS_none; 352dfdb948bef51a601e763191e4becfe59880d382Argyrios Kyrtzidis 3604b6748ee90649069ee79464317ae6cd6aca317dArgyrios Kyrtzidis if (C.kind == CXCursor_CXXAccessSpecifier || clang_isDeclaration(C.kind)) 372dfdb948bef51a601e763191e4becfe59880d382Argyrios Kyrtzidis spec = getCursorDecl(C)->getAccess(); 382dfdb948bef51a601e763191e4becfe59880d382Argyrios Kyrtzidis else if (C.kind == CXCursor_CXXBaseSpecifier) 392dfdb948bef51a601e763191e4becfe59880d382Argyrios Kyrtzidis spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier(); 402dfdb948bef51a601e763191e4becfe59880d382Argyrios Kyrtzidis else 41585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek return CX_CXXInvalidAccessSpecifier; 42585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 432dfdb948bef51a601e763191e4becfe59880d382Argyrios Kyrtzidis switch (spec) { 44585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek case AS_public: return CX_CXXPublic; 45585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek case AS_protected: return CX_CXXProtected; 46585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek case AS_private: return CX_CXXPrivate; 47585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek case AS_none: return CX_CXXInvalidAccessSpecifier; 48585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek } 497530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie 507530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie llvm_unreachable("Invalid AccessSpecifier!"); 51585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek} 52585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek 5349f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregorenum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { 5449f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor using namespace clang::cxcursor; 5549f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 5649f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor switch (C.kind) { 5749f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor case CXCursor_ClassTemplate: 5849f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor case CXCursor_FunctionTemplate: 59e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko if (const TemplateDecl *Template 6049f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C))) 6146f92523918fd4ac4df5489265c7f85c1b28baeaDmitri Gribenko return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind; 6249f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor break; 6349f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 6449f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor case CXCursor_ClassTemplatePartialSpecialization: 65e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko if (const ClassTemplateSpecializationDecl *PartialSpec 6617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>( 6717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos getCursorDecl(C))) { 6817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos switch (PartialSpec->getTagKind()) { 6917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos case TTK_Interface: 7017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos case TTK_Struct: return CXCursor_StructDecl; 7117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos case TTK_Class: return CXCursor_ClassDecl; 7217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos case TTK_Union: return CXCursor_UnionDecl; 7317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos case TTK_Enum: return CXCursor_NoDeclFound; 7417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos } 7549f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor } 7649f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor break; 7749f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 7849f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor default: 7949f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor break; 8049f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor } 8149f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 8249f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor return CXCursor_NoDeclFound; 8349f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor} 8449f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 85e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas GregorCXCursor clang_getSpecializedCursorTemplate(CXCursor C) { 86e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor if (!clang_isDeclaration(C.kind)) 87e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor return clang_getNullCursor(); 88e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor 89e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko const Decl *D = getCursorDecl(C); 90e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor if (!D) 91e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor return clang_getNullCursor(); 92e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor 93e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Decl *Template = 0; 94e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { 95e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko if (const ClassTemplatePartialSpecializationDecl *PartialSpec 96e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) 97e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = PartialSpec->getSpecializedTemplate(); 98e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko else if (const ClassTemplateSpecializationDecl *ClassSpec 99e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) { 100e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor llvm::PointerUnion<ClassTemplateDecl *, 101e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor ClassTemplatePartialSpecializationDecl *> Result 102e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor = ClassSpec->getSpecializedTemplateOrPartial(); 103e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor if (Result.is<ClassTemplateDecl *>()) 104e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = Result.get<ClassTemplateDecl *>(); 105e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor else 106e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = Result.get<ClassTemplatePartialSpecializationDecl *>(); 107e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor 108e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor } else 109e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = CXXRecord->getInstantiatedFromMemberClass(); 110e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { 111e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = Function->getPrimaryTemplate(); 112e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor if (!Template) 113e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = Function->getInstantiatedFromMemberFunction(); 114e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { 115e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor if (Var->isStaticDataMember()) 116e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = Var->getInstantiatedFromStaticDataMember(); 117e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko } else if (const RedeclarableTemplateDecl *Tmpl 118e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor = dyn_cast<RedeclarableTemplateDecl>(D)) 119e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor Template = Tmpl->getInstantiatedFromMemberTemplate(); 120e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor 121e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor if (!Template) 122e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor return clang_getNullCursor(); 123e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor 12446f92523918fd4ac4df5489265c7f85c1b28baeaDmitri Gribenko return MakeCXCursor(Template, getCursorTU(C)); 125e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor} 126e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor 127585b318a7333b5dd1d900881db7b6610e2701fe8Ted Kremenek} // end extern "C" 128