blob: 35545d281f9b70fcdb982012bece1f11b2259d80 [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"
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +000015#include "llvm/ADT/DenseSet.h"
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000016
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 Kyrtzidisc6b4a502011-11-16 02:34:59 +0000136struct RefFileOccurence {
137 const FileEntry *File;
138 const Decl *Dcl;
139
140 RefFileOccurence(const FileEntry *File, const Decl *Dcl)
141 : File(File), Dcl(Dcl) { }
142};
143
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000144class IndexingContext {
145 ASTContext *Ctx;
146 CXClientData ClientData;
147 IndexerCallbacks &CB;
148 unsigned IndexOptions;
149 CXTranslationUnit CXTU;
150
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000151 typedef llvm::DenseMap<const FileEntry *, CXIdxClientFile> FileMapTy;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000152 typedef llvm::DenseMap<const DeclContext *, CXIdxClientContainer> ContainerMapTy;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000153 FileMapTy FileMap;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000154 ContainerMapTy ContainerMap;
155
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000156 llvm::DenseSet<RefFileOccurence> RefFileOccurences;
157
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000158 SmallVector<DeclGroupRef, 8> TUDeclsInObjCContainer;
159
160 llvm::SmallString<256> StrScratch;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000161 unsigned StrAdapterCount;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000162
163 class StrAdapter {
164 llvm::SmallString<256> &Scratch;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000165 IndexingContext &IdxCtx;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000166
167 public:
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000168 StrAdapter(IndexingContext &indexCtx)
169 : Scratch(indexCtx.StrScratch), IdxCtx(indexCtx) {
170 ++IdxCtx.StrAdapterCount;
171 }
172
173 ~StrAdapter() {
174 --IdxCtx.StrAdapterCount;
175 if (IdxCtx.StrAdapterCount == 0)
176 Scratch.clear();
177 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000178
179 const char *toCStr(StringRef Str);
180
181 unsigned getCurSize() const { return Scratch.size(); }
182
183 const char *getCStr(unsigned CharIndex) {
184 Scratch.push_back('\0');
185 return Scratch.data() + CharIndex;
186 }
187
188 SmallVectorImpl<char> &getBuffer() { return Scratch; }
189 };
190
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000191 struct ObjCProtocolListInfo {
192 SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
193 SmallVector<CXIdxEntityInfo, 4> ProtEntities;
194 SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
195
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000196 CXIdxObjCProtocolRefListInfo getListInfo() {
197 CXIdxObjCProtocolRefListInfo Info = { Prots.data(),
198 (unsigned)Prots.size() };
199 return Info;
200 }
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000201
202 ObjCProtocolListInfo(const ObjCProtocolList &ProtList,
203 IndexingContext &IdxCtx,
204 IndexingContext::StrAdapter &SA);
205 };
206
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000207public:
208 IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
209 unsigned indexOptions, CXTranslationUnit cxTU)
210 : Ctx(0), ClientData(clientData), CB(indexCallbacks),
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000211 IndexOptions(indexOptions), CXTU(cxTU), StrAdapterCount(0) { }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000212
213 ASTContext &getASTContext() const { return *Ctx; }
214
215 void setASTContext(ASTContext &ctx);
216
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000217 bool onlyOneRefPerFile() const {
218 return IndexOptions & CXIndexOpt_OneRefPerFile;
219 }
220
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000221 void enteredMainFile(const FileEntry *File);
222
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000223 void ppIncludedFile(SourceLocation hashLoc,
224 StringRef filename, const FileEntry *File,
225 bool isImport, bool isAngled);
226
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000227 void startedTranslationUnit();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000228
229 void indexDecl(const Decl *D);
230
231 void indexTagDecl(const TagDecl *D);
232
233 void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
234 const DeclContext *DC = 0);
235
236 void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
237 const DeclContext *DC);
238
239 void indexDeclContext(const DeclContext *DC);
240
241 void indexBody(const Stmt *S, const DeclContext *DC);
242
243 void handleDiagnostic(const StoredDiagnostic &StoredDiag);
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000244 void handleDiagnostic(CXDiagnostic CXDiag);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000245
246 void handleFunction(const FunctionDecl *FD);
247
248 void handleVar(const VarDecl *D);
249
250 void handleField(const FieldDecl *D);
251
252 void handleEnumerator(const EnumConstantDecl *D);
253
254 void handleTagDecl(const TagDecl *D);
255
256 void handleTypedef(const TypedefDecl *D);
257
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000258 void handleObjCClass(const ObjCClassDecl *D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000259 void handleObjCInterface(const ObjCInterfaceDecl *D);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000260 void handleObjCImplementation(const ObjCImplementationDecl *D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000261
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000262 void handleObjCForwardProtocol(const ObjCProtocolDecl *D,
263 SourceLocation Loc,
264 bool isRedeclaration);
265
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000266 void handleObjCProtocol(const ObjCProtocolDecl *D);
267
268 void handleObjCCategory(const ObjCCategoryDecl *D);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000269 void handleObjCCategoryImpl(const ObjCCategoryImplDecl *D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000270
271 void handleObjCMethod(const ObjCMethodDecl *D);
272
273 void handleObjCProperty(const ObjCPropertyDecl *D);
274
275 void handleReference(const NamedDecl *D, SourceLocation Loc,
276 const NamedDecl *Parent,
277 const DeclContext *DC,
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000278 const Expr *E = 0,
279 CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000280
281 bool isNotFromSourceFile(SourceLocation Loc) const;
282
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000283 void indexTopLevelDecl(Decl *D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000284 void indexTUDeclsInObjCContainer();
285 void indexDeclGroupRef(DeclGroupRef DG);
286
287 void addTUDeclInObjCContainer(DeclGroupRef DG) {
288 TUDeclsInObjCContainer.push_back(DG);
289 }
290
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000291 void translateLoc(SourceLocation Loc, CXIdxClientFile *indexFile, CXFile *file,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000292 unsigned *line, unsigned *column, unsigned *offset);
293
294private:
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000295 void handleDecl(const NamedDecl *D,
296 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000297 DeclInfo &DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000298
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000299 void handleObjCContainer(const ObjCContainerDecl *D,
300 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000301 ObjCContainerDeclInfo &ContDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000302
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000303 void addContainerInMap(const DeclContext *DC, CXIdxClientContainer container);
304
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000305 const NamedDecl *getEntityDecl(const NamedDecl *D) const;
306
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000307 CXIdxClientContainer getIndexContainer(const NamedDecl *D) const {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000308 return getIndexContainerForDC(D->getDeclContext());
309 }
310
311 const DeclContext *getScopedContext(const DeclContext *DC) const;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000312 CXIdxClientContainer getIndexContainerForDC(const DeclContext *DC) const;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000313
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000314 CXIdxClientFile getIndexFile(const FileEntry *File);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000315
316 CXIdxLoc getIndexLoc(SourceLocation Loc) const;
317
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000318 void getEntityInfo(const NamedDecl *D,
319 CXIdxEntityInfo &EntityInfo,
320 StrAdapter &SA);
321
322 CXCursor getCursor(const NamedDecl *D) {
323 return cxcursor::MakeCXCursor(const_cast<NamedDecl*>(D), CXTU);
324 }
325
326 CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
327};
328
329}} // end clang::cxindex
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000330
331namespace llvm {
332 /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
333 /// DenseSets.
334 template <>
335 struct DenseMapInfo<clang::cxindex::RefFileOccurence> {
336 static inline clang::cxindex::RefFileOccurence getEmptyKey() {
337 return clang::cxindex::RefFileOccurence(0, 0);
338 }
339
340 static inline clang::cxindex::RefFileOccurence getTombstoneKey() {
341 return clang::cxindex::RefFileOccurence((const clang::FileEntry *)~0,
342 (const clang::Decl *)~0);
343 }
344
345 static unsigned getHashValue(clang::cxindex::RefFileOccurence S) {
346 llvm::FoldingSetNodeID ID;
347 ID.AddPointer(S.File);
348 ID.AddPointer(S.Dcl);
349 return ID.ComputeHash();
350 }
351
352 static bool isEqual(clang::cxindex::RefFileOccurence LHS,
353 clang::cxindex::RefFileOccurence RHS) {
354 return LHS.File == RHS.File && LHS.Dcl == RHS.Dcl;
355 }
356 };
357}