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::cxcursor
;
25 unsigned clang_isVirtualBase(CXCursor C
) {
26 if (C
.kind
!= CXCursor_CXXBaseSpecifier
)
29 CXXBaseSpecifier
*B
= getCursorCXXBaseSpecifier(C
);
30 return B
->isVirtual();
33 enum CX_CXXAccessSpecifier
clang_getCXXAccessSpecifier(CXCursor C
) {
34 if (C
.kind
!= CXCursor_CXXBaseSpecifier
)
35 return CX_CXXInvalidAccessSpecifier
;
37 CXXBaseSpecifier
*B
= getCursorCXXBaseSpecifier(C
);
38 switch (B
->getAccessSpecifier()) {
39 case AS_public
: return CX_CXXPublic
;
40 case AS_protected
: return CX_CXXProtected
;
41 case AS_private
: return CX_CXXPrivate
;
42 case AS_none
: return CX_CXXInvalidAccessSpecifier
;
45 // FIXME: Clang currently thinks this is reachable.
46 return CX_CXXInvalidAccessSpecifier
;
49 enum CXCursorKind
clang_getTemplateCursorKind(CXCursor C
) {
50 using namespace clang::cxcursor
;
53 case CXCursor_ClassTemplate
:
54 case CXCursor_FunctionTemplate
:
55 if (TemplateDecl
*Template
56 = dyn_cast_or_null
<TemplateDecl
>(getCursorDecl(C
)))
57 return MakeCXCursor(Template
->getTemplatedDecl(),
58 static_cast<CXTranslationUnit
>(C
.data
[2])).kind
;
61 case CXCursor_ClassTemplatePartialSpecialization
:
62 if (ClassTemplateSpecializationDecl
*PartialSpec
63 = dyn_cast_or_null
<ClassTemplatePartialSpecializationDecl
>(
65 switch (PartialSpec
->getTagKind()) {
66 case TTK_Class
: return CXCursor_ClassDecl
;
67 case TTK_Struct
: return CXCursor_StructDecl
;
68 case TTK_Union
: return CXCursor_UnionDecl
;
69 case TTK_Enum
: return CXCursor_NoDeclFound
;
78 return CXCursor_NoDeclFound
;
81 CXCursor
clang_getSpecializedCursorTemplate(CXCursor C
) {
82 if (!clang_isDeclaration(C
.kind
))
83 return clang_getNullCursor();
85 Decl
*D
= getCursorDecl(C
);
87 return clang_getNullCursor();
90 if (CXXRecordDecl
*CXXRecord
= dyn_cast
<CXXRecordDecl
>(D
)) {
91 if (ClassTemplatePartialSpecializationDecl
*PartialSpec
92 = dyn_cast
<ClassTemplatePartialSpecializationDecl
>(CXXRecord
))
93 Template
= PartialSpec
->getSpecializedTemplate();
94 else if (ClassTemplateSpecializationDecl
*ClassSpec
95 = dyn_cast
<ClassTemplateSpecializationDecl
>(CXXRecord
)) {
96 llvm::PointerUnion
<ClassTemplateDecl
*,
97 ClassTemplatePartialSpecializationDecl
*> Result
98 = ClassSpec
->getSpecializedTemplateOrPartial();
99 if (Result
.is
<ClassTemplateDecl
*>())
100 Template
= Result
.get
<ClassTemplateDecl
*>();
102 Template
= Result
.get
<ClassTemplatePartialSpecializationDecl
*>();
105 Template
= CXXRecord
->getInstantiatedFromMemberClass();
106 } else if (FunctionDecl
*Function
= dyn_cast
<FunctionDecl
>(D
)) {
107 Template
= Function
->getPrimaryTemplate();
109 Template
= Function
->getInstantiatedFromMemberFunction();
110 } else if (VarDecl
*Var
= dyn_cast
<VarDecl
>(D
)) {
111 if (Var
->isStaticDataMember())
112 Template
= Var
->getInstantiatedFromStaticDataMember();
113 } else if (RedeclarableTemplateDecl
*Tmpl
114 = dyn_cast
<RedeclarableTemplateDecl
>(D
))
115 Template
= Tmpl
->getInstantiatedFromMemberTemplate();
118 return clang_getNullCursor();
120 return MakeCXCursor(Template
, static_cast<CXTranslationUnit
>(C
.data
[2]));