[cfe-commits] r150267 - in /cfe/trunk: include/clang/AST/ASTConsumer.h include/clang/Frontend/MultiplexConsumer.h lib/Frontend/MultiplexConsumer.cpp lib/Sema/SemaExpr.cpp tools/libclang/IndexDecl.cpp tools/libclang/IndexTypeSourceInfo.cpp tools/libclang/Indexing.cpp tools/libclang/IndexingContext.cpp tools/libclang/IndexingContext.h

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Feb 10 12:10:44 PST 2012


Author: akirtzidis
Date: Fri Feb 10 14:10:44 2012
New Revision: 150267

URL: http://llvm.org/viewvc/llvm-project?rev=150267&view=rev
Log:
[libclang] Indexing API: Fully index implict template instantiations.

Modified:
    cfe/trunk/include/clang/AST/ASTConsumer.h
    cfe/trunk/include/clang/Frontend/MultiplexConsumer.h
    cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/tools/libclang/IndexDecl.cpp
    cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp
    cfe/trunk/tools/libclang/Indexing.cpp
    cfe/trunk/tools/libclang/IndexingContext.cpp
    cfe/trunk/tools/libclang/IndexingContext.h

Modified: cfe/trunk/include/clang/AST/ASTConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTConsumer.h (original)
+++ cfe/trunk/include/clang/AST/ASTConsumer.h Fri Feb 10 14:10:44 2012
@@ -24,6 +24,7 @@
   class SemaConsumer; // layering violation required for safe SemaConsumer
   class TagDecl;
   class VarDecl;
+  class FunctionDecl;
 
 /// ASTConsumer - This is an abstract interface that should be implemented by
 /// clients that read ASTs.  This abstraction layer allows the client to be
@@ -67,6 +68,12 @@
   /// can be defined in declspecs).
   virtual void HandleTagDeclDefinition(TagDecl *D) {}
 
+  /// \brief Invoked when a function is implicitly instantiated.
+  /// Note that at this point point it does not have a body, its body is
+  /// instantiated at the end of the translation unit and passed to
+  /// HandleTopLevelDecl.
+  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
+
   /// \brief Handle the specified top-level declaration that occurred inside
   /// and ObjC container.
   /// The default implementation ignored them.

Modified: cfe/trunk/include/clang/Frontend/MultiplexConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/MultiplexConsumer.h?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/MultiplexConsumer.h (original)
+++ cfe/trunk/include/clang/Frontend/MultiplexConsumer.h Fri Feb 10 14:10:44 2012
@@ -39,6 +39,7 @@
   virtual void HandleInterestingDecl(DeclGroupRef D);
   virtual void HandleTranslationUnit(ASTContext &Ctx);
   virtual void HandleTagDeclDefinition(TagDecl *D);
+  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D);
   virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
   virtual void CompleteTentativeDefinition(VarDecl *D);
   virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired);

Modified: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Fri Feb 10 14:10:44 2012
@@ -224,6 +224,11 @@
     Consumers[i]->HandleTagDeclDefinition(D);
 }
 
+void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleCXXImplicitFunctionInstantiation(D);
+}
+
 void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
     Consumers[i]->HandleTopLevelDeclInObjCContainer(D);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb 10 14:10:44 2012
@@ -18,6 +18,7 @@
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/AnalysisBasedWarnings.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
@@ -9483,8 +9484,11 @@
         // expression evaluator needing to call back into Sema if it sees a
         // call to such a function.
         InstantiateFunctionDefinition(Loc, Func);
-      else
+      else {
         PendingInstantiations.push_back(std::make_pair(Func, Loc));
+        // Notify the consumer that a function was implicitly instantiated.
+        Consumer.HandleCXXImplicitFunctionInstantiation(Func);
+      }
     }
   } else {
     // Walk redefinitions, as some of them may be instantiable.

Modified: cfe/trunk/tools/libclang/IndexDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexDecl.cpp?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/IndexDecl.cpp (original)
+++ cfe/trunk/tools/libclang/IndexDecl.cpp Fri Feb 10 14:10:44 2012
@@ -220,6 +220,15 @@
     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();

Modified: cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp (original)
+++ cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp Fri Feb 10 14:10:44 2012
@@ -72,10 +72,14 @@
   }
 
   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;
   }
 };

Modified: cfe/trunk/tools/libclang/Indexing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/Indexing.cpp (original)
+++ cfe/trunk/tools/libclang/Indexing.cpp Fri Feb 10 14:10:44 2012
@@ -135,6 +135,15 @@
   /// 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 @@
     indexDiagnostics(CXTU, IndexCtx);
   }
 
-  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; }
+  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
   virtual bool hasCodeCompletionSupport() const { return false; }
 };
 

Modified: cfe/trunk/tools/libclang/IndexingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexingContext.cpp?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/IndexingContext.cpp (original)
+++ cfe/trunk/tools/libclang/IndexingContext.cpp Fri Feb 10 14:10:44 2012
@@ -282,9 +282,23 @@
   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 @@
     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;
+}

Modified: cfe/trunk/tools/libclang/IndexingContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexingContext.h?rev=150267&r1=150266&r2=150267&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/IndexingContext.h (original)
+++ cfe/trunk/tools/libclang/IndexingContext.h Fri Feb 10 14:10:44 2012
@@ -20,6 +20,7 @@
   class ClassTemplateDecl;
   class FunctionTemplateDecl;
   class TypeAliasTemplateDecl;
+  class ClassTemplateSpecializationDecl;
 
 namespace cxindex {
   class IndexingContext;
@@ -426,6 +427,8 @@
   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,





More information about the cfe-commits mailing list