1 //===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the libclang support for C++ cursors.
12 //===----------------------------------------------------------------------===//
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclTemplate.h"
20 using namespace clang;
21 using namespace clang::cxstring;
22 using namespace clang::cxcursor;
26 unsigned clang_isVirtualBase(CXCursor C) {
27 if (C.kind != CXCursor_CXXBaseSpecifier)
30 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
31 return B->isVirtual();
34 enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
35 if (C.kind != CXCursor_CXXBaseSpecifier)
36 return CX_CXXInvalidAccessSpecifier;
38 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
39 switch (B->getAccessSpecifier()) {
40 case AS_public: return CX_CXXPublic;
41 case AS_protected: return CX_CXXProtected;
42 case AS_private: return CX_CXXPrivate;
43 case AS_none: return CX_CXXInvalidAccessSpecifier;
46 // FIXME: Clang currently thinks this is reachable.
47 return CX_CXXInvalidAccessSpecifier;
50 enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
51 using namespace clang::cxcursor;
54 case CXCursor_ClassTemplate:
55 case CXCursor_FunctionTemplate:
56 if (TemplateDecl *Template
57 = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
58 return MakeCXCursor(Template->getTemplatedDecl(),
59 getCursorASTUnit(C)).kind;
62 case CXCursor_ClassTemplatePartialSpecialization:
63 if (ClassTemplateSpecializationDecl *PartialSpec
64 = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
66 switch (PartialSpec->getTagKind()) {
67 case TTK_Class: return CXCursor_ClassDecl;
68 case TTK_Struct: return CXCursor_StructDecl;
69 case TTK_Union: return CXCursor_UnionDecl;
70 case TTK_Enum: return CXCursor_NoDeclFound;
79 return CXCursor_NoDeclFound;
82 CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
83 if (!clang_isDeclaration(C.kind))
84 return clang_getNullCursor();
86 Decl *D = getCursorDecl(C);
88 return clang_getNullCursor();
91 if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
92 if (ClassTemplatePartialSpecializationDecl *PartialSpec
93 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
94 Template = PartialSpec->getSpecializedTemplate();
95 else if (ClassTemplateSpecializationDecl *ClassSpec
96 = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
97 llvm::PointerUnion<ClassTemplateDecl *,
98 ClassTemplatePartialSpecializationDecl *> Result
99 = ClassSpec->getSpecializedTemplateOrPartial();
100 if (Result.is<ClassTemplateDecl *>())
101 Template = Result.get<ClassTemplateDecl *>();
103 Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
106 Template = CXXRecord->getInstantiatedFromMemberClass();
107 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
108 Template = Function->getPrimaryTemplate();
110 Template = Function->getInstantiatedFromMemberFunction();
111 } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
112 if (Var->isStaticDataMember())
113 Template = Var->getInstantiatedFromStaticDataMember();
114 } else if (RedeclarableTemplateDecl *Tmpl
115 = dyn_cast<RedeclarableTemplateDecl>(D))
116 Template = Tmpl->getInstantiatedFromMemberTemplate();
119 return clang_getNullCursor();
121 return MakeCXCursor(Template, getCursorASTUnit(C));