handle labeldecls.
[clang.git] / tools / libclang / CIndexCXX.cpp
blob0f49f65c2b80979f07d687777237bea424fe2b3d
1 //===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the libclang support for C++ cursors.
12 //===----------------------------------------------------------------------===//
14 #include "CIndexer.h"
15 #include "CXCursor.h"
16 #include "CXType.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclTemplate.h"
20 using namespace clang;
21 using namespace clang::cxcursor;
23 extern "C" {
25 unsigned clang_isVirtualBase(CXCursor C) {
26 if (C.kind != CXCursor_CXXBaseSpecifier)
27 return 0;
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;
52 switch (C.kind) {
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;
59 break;
61 case CXCursor_ClassTemplatePartialSpecialization:
62 if (ClassTemplateSpecializationDecl *PartialSpec
63 = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
64 getCursorDecl(C))) {
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;
72 break;
74 default:
75 break;
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);
86 if (!D)
87 return clang_getNullCursor();
89 Decl *Template = 0;
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 *>();
101 else
102 Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
104 } else
105 Template = CXXRecord->getInstantiatedFromMemberClass();
106 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
107 Template = Function->getPrimaryTemplate();
108 if (!Template)
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();
117 if (!Template)
118 return clang_getNullCursor();
120 return MakeCXCursor(Template, static_cast<CXTranslationUnit>(C.data[2]));
123 } // end extern "C"