[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / tools / libclang / CIndexCXX.cpp
bloba06fe7ba4af56c224445f0af420573059bcda045
1 //===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the libclang support for C++ cursors.
11 //===----------------------------------------------------------------------===//
13 #include "CIndexer.h"
14 #include "CXCursor.h"
15 #include "CXType.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclTemplate.h"
19 using namespace clang;
20 using namespace clang::cxcursor;
22 unsigned clang_isVirtualBase(CXCursor C) {
23 if (C.kind != CXCursor_CXXBaseSpecifier)
24 return 0;
26 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
27 return B->isVirtual();
30 enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
31 AccessSpecifier spec = AS_none;
33 if (C.kind == CXCursor_CXXAccessSpecifier || clang_isDeclaration(C.kind))
34 spec = getCursorDecl(C)->getAccess();
35 else if (C.kind == CXCursor_CXXBaseSpecifier)
36 spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
37 else
38 return CX_CXXInvalidAccessSpecifier;
40 switch (spec) {
41 case AS_public: return CX_CXXPublic;
42 case AS_protected: return CX_CXXProtected;
43 case AS_private: return CX_CXXPrivate;
44 case AS_none: return CX_CXXInvalidAccessSpecifier;
47 llvm_unreachable("Invalid AccessSpecifier!");
50 enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
51 using namespace clang::cxcursor;
53 switch (C.kind) {
54 case CXCursor_ClassTemplate:
55 case CXCursor_FunctionTemplate:
56 if (const TemplateDecl *Template
57 = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
58 return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind;
59 break;
61 case CXCursor_ClassTemplatePartialSpecialization:
62 if (const ClassTemplateSpecializationDecl *PartialSpec
63 = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
64 getCursorDecl(C))) {
65 switch (PartialSpec->getTagKind()) {
66 case TTK_Interface:
67 case TTK_Struct: return CXCursor_StructDecl;
68 case TTK_Class: return CXCursor_ClassDecl;
69 case TTK_Union: return CXCursor_UnionDecl;
70 case TTK_Enum: return CXCursor_NoDeclFound;
73 break;
75 default:
76 break;
79 return CXCursor_NoDeclFound;
82 CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
83 if (!clang_isDeclaration(C.kind))
84 return clang_getNullCursor();
86 const Decl *D = getCursorDecl(C);
87 if (!D)
88 return clang_getNullCursor();
90 Decl *Template = nullptr;
91 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
92 if (const ClassTemplatePartialSpecializationDecl *PartialSpec
93 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
94 Template = PartialSpec->getSpecializedTemplate();
95 else if (const ClassTemplateSpecializationDecl *ClassSpec
96 = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
97 llvm::PointerUnion<ClassTemplateDecl *,
98 ClassTemplatePartialSpecializationDecl *> Result
99 = ClassSpec->getSpecializedTemplateOrPartial();
100 if (Result.is<ClassTemplateDecl *>())
101 Template = Result.get<ClassTemplateDecl *>();
102 else
103 Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
105 } else
106 Template = CXXRecord->getInstantiatedFromMemberClass();
107 } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
108 Template = Function->getPrimaryTemplate();
109 if (!Template)
110 Template = Function->getInstantiatedFromMemberFunction();
111 } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
112 if (Var->isStaticDataMember())
113 Template = Var->getInstantiatedFromStaticDataMember();
114 } else if (const RedeclarableTemplateDecl *Tmpl
115 = dyn_cast<RedeclarableTemplateDecl>(D))
116 Template = Tmpl->getInstantiatedFromMemberTemplate();
118 if (!Template)
119 return clang_getNullCursor();
121 return MakeCXCursor(Template, getCursorTU(C));