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