/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/tools/libclang/CIndexCXX.cpp
Line | Count | Source (jump to first uncovered line) |
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. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "CIndexer.h" |
14 | | #include "CXCursor.h" |
15 | | #include "CXType.h" |
16 | | #include "clang/AST/DeclCXX.h" |
17 | | #include "clang/AST/DeclTemplate.h" |
18 | | |
19 | | using namespace clang; |
20 | | using namespace clang::cxcursor; |
21 | | |
22 | 116 | unsigned clang_isVirtualBase(CXCursor C) { |
23 | 116 | if (C.kind != CXCursor_CXXBaseSpecifier) |
24 | 0 | return 0; |
25 | | |
26 | 116 | const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); |
27 | 116 | return B->isVirtual(); |
28 | 116 | } |
29 | | |
30 | 3.38k | enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { |
31 | 3.38k | AccessSpecifier spec = AS_none; |
32 | | |
33 | 3.38k | if (C.kind == CXCursor_CXXAccessSpecifier || clang_isDeclaration(C.kind)3.35k ) |
34 | 3.27k | spec = getCursorDecl(C)->getAccess(); |
35 | 116 | else if (C.kind == CXCursor_CXXBaseSpecifier) |
36 | 116 | spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier(); |
37 | 0 | else |
38 | 0 | return CX_CXXInvalidAccessSpecifier; |
39 | | |
40 | 3.38k | switch (spec) { |
41 | 662 | case AS_public: return CX_CXXPublic; |
42 | 13 | case AS_protected: return CX_CXXProtected; |
43 | 187 | case AS_private: return CX_CXXPrivate; |
44 | 2.52k | case AS_none: return CX_CXXInvalidAccessSpecifier; |
45 | 3.38k | } |
46 | | |
47 | 0 | llvm_unreachable("Invalid AccessSpecifier!"); |
48 | 0 | } |
49 | | |
50 | 0 | enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { |
51 | 0 | using namespace clang::cxcursor; |
52 | | |
53 | 0 | switch (C.kind) { |
54 | 0 | case CXCursor_ClassTemplate: |
55 | 0 | case CXCursor_FunctionTemplate: |
56 | 0 | if (const TemplateDecl *Template |
57 | 0 | = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C))) |
58 | 0 | return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind; |
59 | 0 | break; |
60 | | |
61 | 0 | case CXCursor_ClassTemplatePartialSpecialization: |
62 | 0 | if (const ClassTemplateSpecializationDecl *PartialSpec |
63 | 0 | = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>( |
64 | 0 | getCursorDecl(C))) { |
65 | 0 | switch (PartialSpec->getTagKind()) { |
66 | 0 | case TTK_Interface: |
67 | 0 | case TTK_Struct: return CXCursor_StructDecl; |
68 | 0 | case TTK_Class: return CXCursor_ClassDecl; |
69 | 0 | case TTK_Union: return CXCursor_UnionDecl; |
70 | 0 | case TTK_Enum: return CXCursor_NoDeclFound; |
71 | 0 | } |
72 | 0 | } |
73 | 0 | break; |
74 | | |
75 | 0 | default: |
76 | 0 | break; |
77 | 0 | } |
78 | | |
79 | 0 | return CXCursor_NoDeclFound; |
80 | 0 | } |
81 | | |
82 | 89.3k | CXCursor clang_getSpecializedCursorTemplate(CXCursor C) { |
83 | 89.3k | if (!clang_isDeclaration(C.kind)) |
84 | 82.4k | return clang_getNullCursor(); |
85 | | |
86 | 6.86k | const Decl *D = getCursorDecl(C); |
87 | 6.86k | if (!D) |
88 | 0 | return clang_getNullCursor(); |
89 | | |
90 | 6.86k | Decl *Template = nullptr; |
91 | 6.86k | if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { |
92 | 552 | if (const ClassTemplatePartialSpecializationDecl *PartialSpec |
93 | 552 | = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) |
94 | 13 | Template = PartialSpec->getSpecializedTemplate(); |
95 | 539 | else if (const ClassTemplateSpecializationDecl *ClassSpec |
96 | 539 | = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) { |
97 | 29 | llvm::PointerUnion<ClassTemplateDecl *, |
98 | 29 | ClassTemplatePartialSpecializationDecl *> Result |
99 | 29 | = ClassSpec->getSpecializedTemplateOrPartial(); |
100 | 29 | if (Result.is<ClassTemplateDecl *>()) |
101 | 28 | Template = Result.get<ClassTemplateDecl *>(); |
102 | 1 | else |
103 | 1 | Template = Result.get<ClassTemplatePartialSpecializationDecl *>(); |
104 | | |
105 | 29 | } else |
106 | 510 | Template = CXXRecord->getInstantiatedFromMemberClass(); |
107 | 6.31k | } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { |
108 | 1.52k | Template = Function->getPrimaryTemplate(); |
109 | 1.52k | if (!Template) |
110 | 1.51k | Template = Function->getInstantiatedFromMemberFunction(); |
111 | 4.78k | } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { |
112 | 1.39k | if (Var->isStaticDataMember()) |
113 | 26 | Template = Var->getInstantiatedFromStaticDataMember(); |
114 | 3.39k | } else if (const RedeclarableTemplateDecl *Tmpl |
115 | 3.39k | = dyn_cast<RedeclarableTemplateDecl>(D)) |
116 | 317 | Template = Tmpl->getInstantiatedFromMemberTemplate(); |
117 | | |
118 | 6.86k | if (!Template) |
119 | 6.80k | return clang_getNullCursor(); |
120 | | |
121 | 61 | return MakeCXCursor(Template, getCursorTU(C)); |
122 | 6.86k | } |