diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-10 20:10:44 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-10 20:10:44 +0000 |
commit | 6d968363877388f0a0268711d59367907b465ae1 (patch) | |
tree | d9ccc4a529a9a2624f3d6764fce67a2aaf3db802 /tools | |
parent | 409e2456b70588eff1ef5477843fcd56454d8855 (diff) |
[libclang] Indexing API: Fully index implict template instantiations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150267 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libclang/IndexDecl.cpp | 9 | ||||
-rw-r--r-- | tools/libclang/IndexTypeSourceInfo.cpp | 6 | ||||
-rw-r--r-- | tools/libclang/Indexing.cpp | 11 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.cpp | 29 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.h | 3 |
5 files changed, 54 insertions, 4 deletions
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp index d2eb402ba2..3e9266995e 100644 --- a/tools/libclang/IndexDecl.cpp +++ b/tools/libclang/IndexDecl.cpp @@ -220,6 +220,15 @@ public: return true; } + bool VisitClassTemplateSpecializationDecl( + ClassTemplateSpecializationDecl *D) { + // FIXME: Notify subsequent callbacks that info comes from implicit + // instantiation. + if (D->isThisDeclarationADefinition()) + IndexCtx.indexTagDecl(D); + return true; + } + bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { IndexCtx.handleFunctionTemplate(D); FunctionDecl *FD = D->getTemplatedDecl(); diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp index e326404842..012e422ef5 100644 --- a/tools/libclang/IndexTypeSourceInfo.cpp +++ b/tools/libclang/IndexTypeSourceInfo.cpp @@ -72,10 +72,14 @@ public: } bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { - if (const TemplateSpecializationType *T = TL.getTypePtr()) + if (const TemplateSpecializationType *T = TL.getTypePtr()) { if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl()) IndexCtx.handleReference(D, TL.getTemplateNameLoc(), Parent, ParentDC); + if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + IndexCtx.handleReference(RD, TL.getTemplateNameLoc(), + Parent, ParentDC); + } return true; } }; diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp index c42ef2308a..a70a341543 100644 --- a/tools/libclang/Indexing.cpp +++ b/tools/libclang/Indexing.cpp @@ -135,6 +135,15 @@ public: /// The default implementation forwards to HandleTopLevelDecl but we don't /// care about them when indexing, so have an empty definition. virtual void HandleInterestingDecl(DeclGroupRef D) {} + + virtual void HandleTagDeclDefinition(TagDecl *D) { + if (IndexCtx.isTemplateImplicitInstantiation(D)) + IndexCtx.indexDecl(D); + } + + virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) { + IndexCtx.indexDecl(D); + } }; //===----------------------------------------------------------------------===// @@ -185,7 +194,7 @@ public: indexDiagnostics(CXTU, IndexCtx); } - virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; } + virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } virtual bool hasCodeCompletionSupport() const { return false; } }; diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp index 059d842515..47d7ff42a9 100644 --- a/tools/libclang/IndexingContext.cpp +++ b/tools/libclang/IndexingContext.cpp @@ -282,9 +282,23 @@ bool IndexingContext::handleDecl(const NamedDecl *D, DInfo.numAttributes = AttrList.getNumAttrs(); getContainerInfo(D->getDeclContext(), DInfo.SemanticContainer); - getContainerInfo(D->getLexicalDeclContext(), DInfo.LexicalContainer); DInfo.semanticContainer = &DInfo.SemanticContainer; - DInfo.lexicalContainer = &DInfo.LexicalContainer; + + if (D->getLexicalDeclContext() == D->getDeclContext()) { + DInfo.lexicalContainer = &DInfo.SemanticContainer; + } else if (isTemplateImplicitInstantiation(D)) { + // Implicit instantiations have the lexical context of where they were + // instantiated first. We choose instead the semantic context because: + // 1) at the time that we see the instantiation we have not seen the + // function where it occurred yet. + // 2) the lexical context of the first instantiation is not useful + // information anyway. + DInfo.lexicalContainer = &DInfo.SemanticContainer; + } else { + getContainerInfo(D->getLexicalDeclContext(), DInfo.LexicalContainer); + DInfo.lexicalContainer = &DInfo.LexicalContainer; + } + if (DInfo.isContainer) { getContainerInfo(getEntityContainer(D), DInfo.DeclAsContainer); DInfo.declAsContainer = &DInfo.DeclAsContainer; @@ -1036,3 +1050,14 @@ bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) { return false; return true; } + +bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) { + if (const ClassTemplateSpecializationDecl * + SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) { + return SD->getSpecializationKind() == TSK_ImplicitInstantiation; + } + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + return FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation; + } + return false; +} diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h index ef8e24e7c3..38f7563b57 100644 --- a/tools/libclang/IndexingContext.h +++ b/tools/libclang/IndexingContext.h @@ -20,6 +20,7 @@ namespace clang { class ClassTemplateDecl; class FunctionTemplateDecl; class TypeAliasTemplateDecl; + class ClassTemplateSpecializationDecl; namespace cxindex { class IndexingContext; @@ -426,6 +427,8 @@ public: CXIdxClientEntity getClientEntity(const Decl *D) const; void setClientEntity(const Decl *D, CXIdxClientEntity client); + static bool isTemplateImplicitInstantiation(const Decl *D); + private: bool handleDecl(const NamedDecl *D, SourceLocation Loc, CXCursor Cursor, |