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