[DFAJumpThreading] Remove incoming StartBlock from all phis when unfolding select...
[llvm-project.git] / clang / tools / libclang / CIndexCXX.cpp
blobea6f97d39644e1825a5f91db104248e2b5dc82d1
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 TagTypeKind::Interface:
67 case TagTypeKind::Struct:
68 return CXCursor_StructDecl;
69 case TagTypeKind::Class:
70 return CXCursor_ClassDecl;
71 case TagTypeKind::Union:
72 return CXCursor_UnionDecl;
73 case TagTypeKind::Enum:
74 return CXCursor_NoDeclFound;
77 break;
79 default:
80 break;
83 return CXCursor_NoDeclFound;
86 CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
87 if (!clang_isDeclaration(C.kind))
88 return clang_getNullCursor();
90 const Decl *D = getCursorDecl(C);
91 if (!D)
92 return clang_getNullCursor();
94 Decl *Template = nullptr;
95 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
96 if (const ClassTemplatePartialSpecializationDecl *PartialSpec
97 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
98 Template = PartialSpec->getSpecializedTemplate();
99 else if (const 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 *>();
109 } else
110 Template = CXXRecord->getInstantiatedFromMemberClass();
111 } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
112 Template = Function->getPrimaryTemplate();
113 if (!Template)
114 Template = Function->getInstantiatedFromMemberFunction();
115 } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
116 if (Var->isStaticDataMember())
117 Template = Var->getInstantiatedFromStaticDataMember();
118 } else if (const RedeclarableTemplateDecl *Tmpl
119 = dyn_cast<RedeclarableTemplateDecl>(D))
120 Template = Tmpl->getInstantiatedFromMemberTemplate();
122 if (!Template)
123 return clang_getNullCursor();
125 return MakeCXCursor(Template, getCursorTU(C));