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