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