IndexingContext.h revision 6ec43adc39006a7fce94188956d0239bd54c0363
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};
28
29struct ObjCContainerDeclInfo : public DeclInfo {
30  CXIdxObjCContainerDeclInfo ObjCContDeclInfo;
31};
32
33struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo {
34  CXIdxObjCCategoryDeclInfo ObjCCatDeclInfo;
35};
36
37struct ObjCInterfaceDeclInfo : public ObjCCategoryDeclInfo {
38  CXIdxObjCInterfaceDeclInfo ObjCInterDeclInfo;
39};
40
41struct ObjCProtocolDeclInfo : public ObjCCategoryDeclInfo {
42  CXIdxObjCProtocolDeclInfo ObjCProtoDeclInfo;
43};
44
45class IndexingContext {
46  ASTContext *Ctx;
47  CXClientData ClientData;
48  IndexerCallbacks &CB;
49  unsigned IndexOptions;
50  CXTranslationUnit CXTU;
51
52  typedef llvm::DenseMap<const FileEntry *, CXIdxClientFile> FileMapTy;
53  typedef llvm::DenseMap<const DeclContext *, CXIdxClientContainer> ContainerMapTy;
54  FileMapTy FileMap;
55  ContainerMapTy ContainerMap;
56
57  SmallVector<DeclGroupRef, 8> TUDeclsInObjCContainer;
58
59  llvm::SmallString<256> StrScratch;
60  unsigned StrAdapterCount;
61
62  class StrAdapter {
63    llvm::SmallString<256> &Scratch;
64    IndexingContext &IdxCtx;
65
66  public:
67    StrAdapter(IndexingContext &indexCtx)
68      : Scratch(indexCtx.StrScratch), IdxCtx(indexCtx) {
69      ++IdxCtx.StrAdapterCount;
70    }
71
72    ~StrAdapter() {
73      --IdxCtx.StrAdapterCount;
74      if (IdxCtx.StrAdapterCount == 0)
75        Scratch.clear();
76    }
77
78    const char *toCStr(StringRef Str);
79
80    unsigned getCurSize() const { return Scratch.size(); }
81
82    const char *getCStr(unsigned CharIndex) {
83      Scratch.push_back('\0');
84      return Scratch.data() + CharIndex;
85    }
86
87    SmallVectorImpl<char> &getBuffer() { return Scratch; }
88  };
89
90  struct ObjCProtocolListInfo {
91    SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
92    SmallVector<CXIdxEntityInfo, 4> ProtEntities;
93    SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
94
95    CXIdxObjCProtocolRefInfo **getProtocolRefs() { return Prots.data(); }
96    unsigned getNumProtocols() { return (unsigned)Prots.size(); }
97
98    ObjCProtocolListInfo(const ObjCProtocolList &ProtList,
99                         IndexingContext &IdxCtx,
100                         IndexingContext::StrAdapter &SA);
101  };
102
103public:
104  IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
105                  unsigned indexOptions, CXTranslationUnit cxTU)
106    : Ctx(0), ClientData(clientData), CB(indexCallbacks),
107      IndexOptions(indexOptions), CXTU(cxTU), StrAdapterCount(0) { }
108
109  ASTContext &getASTContext() const { return *Ctx; }
110
111  void setASTContext(ASTContext &ctx);
112
113  void enteredMainFile(const FileEntry *File);
114
115  void ppIncludedFile(SourceLocation hashLoc,
116                      StringRef filename, const FileEntry *File,
117                      bool isImport, bool isAngled);
118
119  void startedTranslationUnit();
120
121  void indexDecl(const Decl *D);
122
123  void indexTagDecl(const TagDecl *D);
124
125  void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
126                           const DeclContext *DC = 0);
127
128  void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
129                           const DeclContext *DC);
130
131  void indexDeclContext(const DeclContext *DC);
132
133  void indexBody(const Stmt *S, const DeclContext *DC);
134
135  void handleDiagnostic(const StoredDiagnostic &StoredDiag);
136
137  void handleFunction(const FunctionDecl *FD);
138
139  void handleVar(const VarDecl *D);
140
141  void handleField(const FieldDecl *D);
142
143  void handleEnumerator(const EnumConstantDecl *D);
144
145  void handleTagDecl(const TagDecl *D);
146
147  void handleTypedef(const TypedefDecl *D);
148
149  void handleObjCClass(const ObjCClassDecl *D);
150  void handleObjCInterface(const ObjCInterfaceDecl *D);
151  void handleObjCImplementation(const ObjCImplementationDecl *D);
152
153  void handleObjCForwardProtocol(const ObjCProtocolDecl *D,
154                                 SourceLocation Loc,
155                                 bool isRedeclaration);
156
157  void handleObjCProtocol(const ObjCProtocolDecl *D);
158
159  void handleObjCCategory(const ObjCCategoryDecl *D);
160  void handleObjCCategoryImpl(const ObjCCategoryImplDecl *D);
161
162  void handleObjCMethod(const ObjCMethodDecl *D);
163
164  void handleObjCProperty(const ObjCPropertyDecl *D);
165
166  void handleReference(const NamedDecl *D, SourceLocation Loc,
167                       const NamedDecl *Parent,
168                       const DeclContext *DC,
169                       const Expr *E = 0,
170                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
171
172  bool isNotFromSourceFile(SourceLocation Loc) const;
173
174  void indexTUDeclsInObjCContainer();
175  void indexDeclGroupRef(DeclGroupRef DG);
176
177  void addTUDeclInObjCContainer(DeclGroupRef DG) {
178    TUDeclsInObjCContainer.push_back(DG);
179  }
180
181  void translateLoc(SourceLocation Loc, CXIdxClientFile *indexFile, CXFile *file,
182                    unsigned *line, unsigned *column, unsigned *offset);
183
184private:
185  void handleDecl(const NamedDecl *D,
186                  SourceLocation Loc, CXCursor Cursor,
187                  bool isRedeclaration, bool isDefinition, bool isContainer,
188                  DeclInfo &DInfo);
189
190  void handleObjCContainer(const ObjCContainerDecl *D,
191                           SourceLocation Loc, CXCursor Cursor,
192                           bool isForwardRef,
193                           bool isRedeclaration,
194                           bool isImplementation,
195                           ObjCContainerDeclInfo &ContDInfo);
196
197  void addContainerInMap(const DeclContext *DC, CXIdxClientContainer container);
198
199  const NamedDecl *getEntityDecl(const NamedDecl *D) const;
200
201  CXIdxClientContainer getIndexContainer(const NamedDecl *D) const {
202    return getIndexContainerForDC(D->getDeclContext());
203  }
204
205  const DeclContext *getScopedContext(const DeclContext *DC) const;
206  CXIdxClientContainer getIndexContainerForDC(const DeclContext *DC) const;
207
208  CXIdxClientFile getIndexFile(const FileEntry *File);
209
210  CXIdxLoc getIndexLoc(SourceLocation Loc) const;
211
212  void getEntityInfo(const NamedDecl *D,
213                     CXIdxEntityInfo &EntityInfo,
214                     StrAdapter &SA);
215
216  CXCursor getCursor(const NamedDecl *D) {
217    return cxcursor::MakeCXCursor(const_cast<NamedDecl*>(D), CXTU);
218  }
219
220  CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
221};
222
223}} // end clang::cxindex
224