blob: 9bc3efa095d33aa24b41aad8ad8f8c0a398a8392 [file] [log] [blame]
Ted Kremenek585b3182010-08-27 21:57:20 +00001//===- 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.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CIndexer.h"
15#include "CXCursor.h"
16#include "CXType.h"
17#include "clang/AST/DeclCXX.h"
Douglas Gregor49f6f542010-08-31 22:12:17 +000018#include "clang/AST/DeclTemplate.h"
Ted Kremenek585b3182010-08-27 21:57:20 +000019
20using namespace clang;
Douglas Gregore0329ac2010-09-02 00:07:54 +000021using namespace clang::cxcursor;
Ted Kremenek585b3182010-08-27 21:57:20 +000022
23extern "C" {
24
25unsigned clang_isVirtualBase(CXCursor C) {
26 if (C.kind != CXCursor_CXXBaseSpecifier)
27 return 0;
28
Douglas Gregore0329ac2010-09-02 00:07:54 +000029 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Ted Kremenek585b3182010-08-27 21:57:20 +000030 return B->isVirtual();
31}
32
33enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
Argyrios Kyrtzidis2dfdb942011-09-30 17:58:23 +000034 AccessSpecifier spec = AS_none;
35
36 if (C.kind == CXCursor_CXXAccessSpecifier)
37 spec = getCursorDecl(C)->getAccess();
38 else if (C.kind == CXCursor_CXXBaseSpecifier)
39 spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
40 else
Ted Kremenek585b3182010-08-27 21:57:20 +000041 return CX_CXXInvalidAccessSpecifier;
42
Argyrios Kyrtzidis2dfdb942011-09-30 17:58:23 +000043 switch (spec) {
Ted Kremenek585b3182010-08-27 21:57:20 +000044 case AS_public: return CX_CXXPublic;
45 case AS_protected: return CX_CXXProtected;
46 case AS_private: return CX_CXXPrivate;
47 case AS_none: return CX_CXXInvalidAccessSpecifier;
48 }
David Blaikie7530c032012-01-17 06:56:22 +000049
50 llvm_unreachable("Invalid AccessSpecifier!");
Ted Kremenek585b3182010-08-27 21:57:20 +000051}
52
Douglas Gregor49f6f542010-08-31 22:12:17 +000053enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
54 using namespace clang::cxcursor;
55
56 switch (C.kind) {
57 case CXCursor_ClassTemplate:
58 case CXCursor_FunctionTemplate:
59 if (TemplateDecl *Template
60 = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
61 return MakeCXCursor(Template->getTemplatedDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +000062 static_cast<CXTranslationUnit>(C.data[2])).kind;
Douglas Gregor49f6f542010-08-31 22:12:17 +000063 break;
64
65 case CXCursor_ClassTemplatePartialSpecialization:
66 if (ClassTemplateSpecializationDecl *PartialSpec
Joao Matos17d35c32012-08-31 22:18:20 +000067 = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
68 getCursorDecl(C))) {
69 switch (PartialSpec->getTagKind()) {
70 case TTK_Interface:
71 case TTK_Struct: return CXCursor_StructDecl;
72 case TTK_Class: return CXCursor_ClassDecl;
73 case TTK_Union: return CXCursor_UnionDecl;
74 case TTK_Enum: return CXCursor_NoDeclFound;
75 }
Douglas Gregor49f6f542010-08-31 22:12:17 +000076 }
77 break;
78
79 default:
80 break;
81 }
82
83 return CXCursor_NoDeclFound;
84}
85
Douglas Gregore0329ac2010-09-02 00:07:54 +000086CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
87 if (!clang_isDeclaration(C.kind))
88 return clang_getNullCursor();
89
90 Decl *D = getCursorDecl(C);
91 if (!D)
92 return clang_getNullCursor();
93
94 Decl *Template = 0;
95 if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
96 if (ClassTemplatePartialSpecializationDecl *PartialSpec
97 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
98 Template = PartialSpec->getSpecializedTemplate();
99 else if (ClassTemplateSpecializationDecl *ClassSpec
100 = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
101 llvm::PointerUnion<ClassTemplateDecl *,
102 ClassTemplatePartialSpecializationDecl *> Result
103 = ClassSpec->getSpecializedTemplateOrPartial();
104 if (Result.is<ClassTemplateDecl *>())
105 Template = Result.get<ClassTemplateDecl *>();
106 else
107 Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
108
109 } else
110 Template = CXXRecord->getInstantiatedFromMemberClass();
111 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
112 Template = Function->getPrimaryTemplate();
113 if (!Template)
114 Template = Function->getInstantiatedFromMemberFunction();
115 } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
116 if (Var->isStaticDataMember())
117 Template = Var->getInstantiatedFromStaticDataMember();
118 } else if (RedeclarableTemplateDecl *Tmpl
119 = dyn_cast<RedeclarableTemplateDecl>(D))
120 Template = Tmpl->getInstantiatedFromMemberTemplate();
121
122 if (!Template)
123 return clang_getNullCursor();
124
Ted Kremeneka60ed472010-11-16 08:15:36 +0000125 return MakeCXCursor(Template, static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregore0329ac2010-09-02 00:07:54 +0000126}
127
Ted Kremenek585b3182010-08-27 21:57:20 +0000128} // end extern "C"