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