blob: c3e5f485a2f1121e7b93a175a701ad350de07fa6 [file] [log] [blame]
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +00001//===- IndexingContext.h - Higher level API functions ------------------------===//
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#include "Index_Internal.h"
11#include "CXCursor.h"
12
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +000013#include "clang/AST/DeclObjC.h"
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000014#include "clang/AST/DeclGroup.h"
15#include "llvm/ADT/DenseMap.h"
16
17namespace clang {
18 class FileEntry;
19 class ObjCPropertyDecl;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000020 class ObjCClassDecl;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000021
22namespace cxindex {
23 class IndexingContext;
24
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000025struct DeclInfo : public CXIdxDeclInfo {
26 CXIdxEntityInfo CXEntInfo;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +000027 enum DInfoKind {
28 Info_Decl,
29
30 Info_ObjCContainer,
31 Info_ObjCInterface,
32 Info_ObjCProtocol,
33 Info_ObjCCategory
34 };
35
36 DInfoKind Kind;
37
38 DeclInfo(bool isRedeclaration, bool isDefinition, bool isContainer)
39 : Kind(Info_Decl) {
40 this->isRedeclaration = isRedeclaration;
41 this->isDefinition = isDefinition;
42 this->isContainer = isContainer;
43 }
44 DeclInfo(DInfoKind K,
45 bool isRedeclaration, bool isDefinition, bool isContainer)
46 : Kind(K) {
47 this->isRedeclaration = isRedeclaration;
48 this->isDefinition = isDefinition;
49 this->isContainer = isContainer;
50 }
51
52 static bool classof(const DeclInfo *) { return true; }
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000053};
54
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000055struct ObjCContainerDeclInfo : public DeclInfo {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +000056 CXIdxObjCContainerDeclInfo ObjCContDeclInfo;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +000057
58 ObjCContainerDeclInfo(bool isForwardRef,
59 bool isRedeclaration,
60 bool isImplementation)
61 : DeclInfo(Info_ObjCContainer, isRedeclaration,
62 /*isDefinition=*/!isForwardRef, /*isContainer=*/!isForwardRef) {
63 init(isForwardRef, isImplementation);
64 }
65 ObjCContainerDeclInfo(DInfoKind K,
66 bool isForwardRef,
67 bool isRedeclaration,
68 bool isImplementation)
69 : DeclInfo(K, isRedeclaration, /*isDefinition=*/!isForwardRef,
70 /*isContainer=*/!isForwardRef) {
71 init(isForwardRef, isImplementation);
72 }
73
74 static bool classof(const DeclInfo *D) {
75 return Info_ObjCContainer <= D->Kind && D->Kind <= Info_ObjCCategory;
76 }
77 static bool classof(const ObjCContainerDeclInfo *D) { return true; }
78
79private:
80 void init(bool isForwardRef, bool isImplementation) {
81 if (isForwardRef)
82 ObjCContDeclInfo.kind = CXIdxObjCContainer_ForwardRef;
83 else if (isImplementation)
84 ObjCContDeclInfo.kind = CXIdxObjCContainer_Implementation;
85 else
86 ObjCContDeclInfo.kind = CXIdxObjCContainer_Interface;
87 }
88};
89
90struct ObjCInterfaceDeclInfo : public ObjCContainerDeclInfo {
91 CXIdxObjCInterfaceDeclInfo ObjCInterDeclInfo;
92 CXIdxObjCProtocolRefListInfo ObjCProtoListInfo;
93
94 ObjCInterfaceDeclInfo(const ObjCInterfaceDecl *D)
95 : ObjCContainerDeclInfo(Info_ObjCInterface,
96 /*isForwardRef=*/false,
97 /*isRedeclaration=*/D->isInitiallyForwardDecl(),
98 /*isImplementation=*/false) { }
99
100 static bool classof(const DeclInfo *D) {
101 return D->Kind == Info_ObjCInterface;
102 }
103 static bool classof(const ObjCInterfaceDeclInfo *D) { return true; }
104};
105
106struct ObjCProtocolDeclInfo : public ObjCContainerDeclInfo {
107 CXIdxObjCProtocolRefListInfo ObjCProtoRefListInfo;
108
109 ObjCProtocolDeclInfo(const ObjCProtocolDecl *D)
110 : ObjCContainerDeclInfo(Info_ObjCProtocol,
111 /*isForwardRef=*/false,
112 /*isRedeclaration=*/D->isInitiallyForwardDecl(),
113 /*isImplementation=*/false) { }
114
115 static bool classof(const DeclInfo *D) {
116 return D->Kind == Info_ObjCProtocol;
117 }
118 static bool classof(const ObjCProtocolDeclInfo *D) { return true; }
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000119};
120
121struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000122 CXIdxObjCCategoryDeclInfo ObjCCatDeclInfo;
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000123
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000124 explicit ObjCCategoryDeclInfo(bool isImplementation)
125 : ObjCContainerDeclInfo(Info_ObjCCategory,
126 /*isForwardRef=*/false,
127 /*isRedeclaration=*/isImplementation,
128 /*isImplementation=*/isImplementation) { }
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000129
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000130 static bool classof(const DeclInfo *D) {
131 return D->Kind == Info_ObjCCategory;
132 }
133 static bool classof(const ObjCCategoryDeclInfo *D) { return true; }
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000134};
135
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000136class IndexingContext {
137 ASTContext *Ctx;
138 CXClientData ClientData;
139 IndexerCallbacks &CB;
140 unsigned IndexOptions;
141 CXTranslationUnit CXTU;
142
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000143 typedef llvm::DenseMap<const FileEntry *, CXIdxClientFile> FileMapTy;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000144 typedef llvm::DenseMap<const DeclContext *, CXIdxClientContainer> ContainerMapTy;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000145 FileMapTy FileMap;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000146 ContainerMapTy ContainerMap;
147
148 SmallVector<DeclGroupRef, 8> TUDeclsInObjCContainer;
149
150 llvm::SmallString<256> StrScratch;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000151 unsigned StrAdapterCount;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000152
153 class StrAdapter {
154 llvm::SmallString<256> &Scratch;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000155 IndexingContext &IdxCtx;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000156
157 public:
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000158 StrAdapter(IndexingContext &indexCtx)
159 : Scratch(indexCtx.StrScratch), IdxCtx(indexCtx) {
160 ++IdxCtx.StrAdapterCount;
161 }
162
163 ~StrAdapter() {
164 --IdxCtx.StrAdapterCount;
165 if (IdxCtx.StrAdapterCount == 0)
166 Scratch.clear();
167 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000168
169 const char *toCStr(StringRef Str);
170
171 unsigned getCurSize() const { return Scratch.size(); }
172
173 const char *getCStr(unsigned CharIndex) {
174 Scratch.push_back('\0');
175 return Scratch.data() + CharIndex;
176 }
177
178 SmallVectorImpl<char> &getBuffer() { return Scratch; }
179 };
180
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000181 struct ObjCProtocolListInfo {
182 SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
183 SmallVector<CXIdxEntityInfo, 4> ProtEntities;
184 SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
185
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000186 CXIdxObjCProtocolRefListInfo getListInfo() {
187 CXIdxObjCProtocolRefListInfo Info = { Prots.data(),
188 (unsigned)Prots.size() };
189 return Info;
190 }
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000191
192 ObjCProtocolListInfo(const ObjCProtocolList &ProtList,
193 IndexingContext &IdxCtx,
194 IndexingContext::StrAdapter &SA);
195 };
196
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000197public:
198 IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
199 unsigned indexOptions, CXTranslationUnit cxTU)
200 : Ctx(0), ClientData(clientData), CB(indexCallbacks),
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000201 IndexOptions(indexOptions), CXTU(cxTU), StrAdapterCount(0) { }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000202
203 ASTContext &getASTContext() const { return *Ctx; }
204
205 void setASTContext(ASTContext &ctx);
206
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000207 void enteredMainFile(const FileEntry *File);
208
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000209 void ppIncludedFile(SourceLocation hashLoc,
210 StringRef filename, const FileEntry *File,
211 bool isImport, bool isAngled);
212
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000213 void startedTranslationUnit();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000214
215 void indexDecl(const Decl *D);
216
217 void indexTagDecl(const TagDecl *D);
218
219 void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
220 const DeclContext *DC = 0);
221
222 void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
223 const DeclContext *DC);
224
225 void indexDeclContext(const DeclContext *DC);
226
227 void indexBody(const Stmt *S, const DeclContext *DC);
228
229 void handleDiagnostic(const StoredDiagnostic &StoredDiag);
230
231 void handleFunction(const FunctionDecl *FD);
232
233 void handleVar(const VarDecl *D);
234
235 void handleField(const FieldDecl *D);
236
237 void handleEnumerator(const EnumConstantDecl *D);
238
239 void handleTagDecl(const TagDecl *D);
240
241 void handleTypedef(const TypedefDecl *D);
242
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000243 void handleObjCClass(const ObjCClassDecl *D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000244 void handleObjCInterface(const ObjCInterfaceDecl *D);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000245 void handleObjCImplementation(const ObjCImplementationDecl *D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000246
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000247 void handleObjCForwardProtocol(const ObjCProtocolDecl *D,
248 SourceLocation Loc,
249 bool isRedeclaration);
250
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000251 void handleObjCProtocol(const ObjCProtocolDecl *D);
252
253 void handleObjCCategory(const ObjCCategoryDecl *D);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000254 void handleObjCCategoryImpl(const ObjCCategoryImplDecl *D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000255
256 void handleObjCMethod(const ObjCMethodDecl *D);
257
258 void handleObjCProperty(const ObjCPropertyDecl *D);
259
260 void handleReference(const NamedDecl *D, SourceLocation Loc,
261 const NamedDecl *Parent,
262 const DeclContext *DC,
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000263 const Expr *E = 0,
264 CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000265
266 bool isNotFromSourceFile(SourceLocation Loc) const;
267
268 void indexTUDeclsInObjCContainer();
269 void indexDeclGroupRef(DeclGroupRef DG);
270
271 void addTUDeclInObjCContainer(DeclGroupRef DG) {
272 TUDeclsInObjCContainer.push_back(DG);
273 }
274
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000275 void translateLoc(SourceLocation Loc, CXIdxClientFile *indexFile, CXFile *file,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000276 unsigned *line, unsigned *column, unsigned *offset);
277
278private:
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000279 void handleDecl(const NamedDecl *D,
280 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000281 DeclInfo &DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000282
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000283 void handleObjCContainer(const ObjCContainerDecl *D,
284 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000285 ObjCContainerDeclInfo &ContDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000286
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000287 void addContainerInMap(const DeclContext *DC, CXIdxClientContainer container);
288
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000289 const NamedDecl *getEntityDecl(const NamedDecl *D) const;
290
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000291 CXIdxClientContainer getIndexContainer(const NamedDecl *D) const {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000292 return getIndexContainerForDC(D->getDeclContext());
293 }
294
295 const DeclContext *getScopedContext(const DeclContext *DC) const;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000296 CXIdxClientContainer getIndexContainerForDC(const DeclContext *DC) const;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000297
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000298 CXIdxClientFile getIndexFile(const FileEntry *File);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000299
300 CXIdxLoc getIndexLoc(SourceLocation Loc) const;
301
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000302 void getEntityInfo(const NamedDecl *D,
303 CXIdxEntityInfo &EntityInfo,
304 StrAdapter &SA);
305
306 CXCursor getCursor(const NamedDecl *D) {
307 return cxcursor::MakeCXCursor(const_cast<NamedDecl*>(D), CXTU);
308 }
309
310 CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
311};
312
313}} // end clang::cxindex