IndexingContext.h revision c71d55469e7d5f7b376a30620617a175a9442da9
1//===- 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
13#include "clang/AST/DeclObjC.h"
14#include "clang/AST/DeclGroup.h"
15#include "llvm/ADT/DenseMap.h"
16
17namespace clang {
18  class FileEntry;
19  class ObjCPropertyDecl;
20  class ObjCClassDecl;
21
22namespace cxindex {
23  class IndexingContext;
24
25struct DeclInfo : public CXIdxDeclInfo {
26  CXIdxEntityInfo CXEntInfo;
27  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; }
53};
54
55struct ObjCContainerDeclInfo : public DeclInfo {
56  CXIdxObjCContainerDeclInfo ObjCContDeclInfo;
57
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; }
119};
120
121struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo {
122  CXIdxObjCCategoryDeclInfo ObjCCatDeclInfo;
123
124  explicit ObjCCategoryDeclInfo(bool isImplementation)
125    : ObjCContainerDeclInfo(Info_ObjCCategory,
126                            /*isForwardRef=*/false,
127                            /*isRedeclaration=*/isImplementation,
128                            /*isImplementation=*/isImplementation) { }
129
130  static bool classof(const DeclInfo *D) {
131    return D->Kind == Info_ObjCCategory;
132  }
133  static bool classof(const ObjCCategoryDeclInfo *D) { return true; }
134};
135
136class IndexingContext {
137  ASTContext *Ctx;
138  CXClientData ClientData;
139  IndexerCallbacks &CB;
140  unsigned IndexOptions;
141  CXTranslationUnit CXTU;
142
143  typedef llvm::DenseMap<const FileEntry *, CXIdxClientFile> FileMapTy;
144  typedef llvm::DenseMap<const DeclContext *, CXIdxClientContainer> ContainerMapTy;
145  FileMapTy FileMap;
146  ContainerMapTy ContainerMap;
147
148  SmallVector<DeclGroupRef, 8> TUDeclsInObjCContainer;
149
150  llvm::SmallString<256> StrScratch;
151  unsigned StrAdapterCount;
152
153  class StrAdapter {
154    llvm::SmallString<256> &Scratch;
155    IndexingContext &IdxCtx;
156
157  public:
158    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    }
168
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
181  struct ObjCProtocolListInfo {
182    SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
183    SmallVector<CXIdxEntityInfo, 4> ProtEntities;
184    SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
185
186    CXIdxObjCProtocolRefListInfo getListInfo() {
187      CXIdxObjCProtocolRefListInfo Info = { Prots.data(),
188                                            (unsigned)Prots.size() };
189      return Info;
190    }
191
192    ObjCProtocolListInfo(const ObjCProtocolList &ProtList,
193                         IndexingContext &IdxCtx,
194                         IndexingContext::StrAdapter &SA);
195  };
196
197public:
198  IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
199                  unsigned indexOptions, CXTranslationUnit cxTU)
200    : Ctx(0), ClientData(clientData), CB(indexCallbacks),
201      IndexOptions(indexOptions), CXTU(cxTU), StrAdapterCount(0) { }
202
203  ASTContext &getASTContext() const { return *Ctx; }
204
205  void setASTContext(ASTContext &ctx);
206
207  void enteredMainFile(const FileEntry *File);
208
209  void ppIncludedFile(SourceLocation hashLoc,
210                      StringRef filename, const FileEntry *File,
211                      bool isImport, bool isAngled);
212
213  void startedTranslationUnit();
214
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
243  void handleObjCClass(const ObjCClassDecl *D);
244  void handleObjCInterface(const ObjCInterfaceDecl *D);
245  void handleObjCImplementation(const ObjCImplementationDecl *D);
246
247  void handleObjCForwardProtocol(const ObjCProtocolDecl *D,
248                                 SourceLocation Loc,
249                                 bool isRedeclaration);
250
251  void handleObjCProtocol(const ObjCProtocolDecl *D);
252
253  void handleObjCCategory(const ObjCCategoryDecl *D);
254  void handleObjCCategoryImpl(const ObjCCategoryImplDecl *D);
255
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,
263                       const Expr *E = 0,
264                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
265
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
275  void translateLoc(SourceLocation Loc, CXIdxClientFile *indexFile, CXFile *file,
276                    unsigned *line, unsigned *column, unsigned *offset);
277
278private:
279  void handleDecl(const NamedDecl *D,
280                  SourceLocation Loc, CXCursor Cursor,
281                  DeclInfo &DInfo);
282
283  void handleObjCContainer(const ObjCContainerDecl *D,
284                           SourceLocation Loc, CXCursor Cursor,
285                           ObjCContainerDeclInfo &ContDInfo);
286
287  void addContainerInMap(const DeclContext *DC, CXIdxClientContainer container);
288
289  const NamedDecl *getEntityDecl(const NamedDecl *D) const;
290
291  CXIdxClientContainer getIndexContainer(const NamedDecl *D) const {
292    return getIndexContainerForDC(D->getDeclContext());
293  }
294
295  const DeclContext *getScopedContext(const DeclContext *DC) const;
296  CXIdxClientContainer getIndexContainerForDC(const DeclContext *DC) const;
297
298  CXIdxClientFile getIndexFile(const FileEntry *File);
299
300  CXIdxLoc getIndexLoc(SourceLocation Loc) const;
301
302  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
314