[PATCH] D43763: libclang: Visit class template instantiations

2019-04-14 Thread Milian Wolff via Phabricator via cfe-commits
milianw added a comment.
Herald added a subscriber: arphaman.
Herald added a project: clang.

looks good, but this needs a test, could you add one please?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D43763/new/

https://reviews.llvm.org/D43763



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43763: libclang: Visit class template instantiations

2018-02-26 Thread Florian Jung via Phabricator via cfe-commits
Windfisch created this revision.
Windfisch added a project: clang-c.
Herald added a subscriber: cfe-commits.

Changes `clang_visitChildren()`'s behaviour to also **visit** all explicit and 
implicit **class template instantiations** upon visiting a `ClassTemplateDecl`. 
In analogy to clang++'s `-dump-ast` option, they are treated as children of the 
`ClassTemplateDecl` node.

This is done by

- adding the `CXCursor_ClassTemplateSpecialization` cursor kind,
- adding a `EnforceVisitBody` flag to 
`CursorVisitor::VisitClassTemplateSpecializationDecl`, which overrides the 
existing early exits in that method,
- and recursively descending into `theTemplateDecl->specializations()`.

This patch also adds a query function `clang_getTemplateSpecializationKind` and 
the associated enum type `CXTemplateSpecializationKind` to retrieve the 
specialisation kind. That way, users can distinguish between implicit 
instantiations (which they probably want to visit as child of the 
ClassTemplateDecl) and explicit instantiation (which they may want choose to 
ignore, because their node will reappear at the very location where the 
explicit instantiation takes place).


Repository:
  rC Clang

https://reviews.llvm.org/D43763

Files:
  include/clang-c/Index.h
  lib/Sema/SemaCodeComplete.cpp
  tools/libclang/CIndex.cpp
  tools/libclang/CIndexCXX.cpp
  tools/libclang/CursorVisitor.h
  tools/libclang/libclang.exports

Index: tools/libclang/libclang.exports
===
--- tools/libclang/libclang.exports
+++ tools/libclang/libclang.exports
@@ -259,6 +259,7 @@
 clang_getSpellingLocation
 clang_getTUResourceUsageName
 clang_getTemplateCursorKind
+clang_getTemplateSpecializationKind
 clang_getTokenExtent
 clang_getTokenKind
 clang_getTokenLocation
Index: tools/libclang/CIndexCXX.cpp
===
--- tools/libclang/CIndexCXX.cpp
+++ tools/libclang/CIndexCXX.cpp
@@ -80,6 +80,25 @@
   return CXCursor_NoDeclFound;
 }
 
+enum CXTemplateSpecializationKind clang_getTemplateSpecializationKind(CXCursor C) {
+  using namespace clang::cxcursor;
+  
+  if (C.kind == CXCursor_ClassTemplateSpecialization)
+  {
+switch (static_cast(getCursorDecl(C))->getSpecializationKind())
+{
+  #define TRANSL(val) case val: return CX##val;
+  TRANSL(TSK_Undeclared)
+  TRANSL(TSK_ImplicitInstantiation)
+  TRANSL(TSK_ExplicitSpecialization)
+  TRANSL(TSK_ExplicitInstantiationDeclaration)
+  TRANSL(TSK_ExplicitInstantiationDefinition)
+  #undef TRANSL
+}
+  }
+  return CXTSK_Undeclared;
+}
+
 CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
 return clang_getNullCursor();
Index: tools/libclang/CursorVisitor.h
===
--- tools/libclang/CursorVisitor.h
+++ tools/libclang/CursorVisitor.h
@@ -205,7 +205,7 @@
   bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
   bool VisitTypedefDecl(TypedefDecl *D);
   bool VisitTagDecl(TagDecl *D);
-  bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
+  bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D, bool EnforceVisitBody = false);
   bool VisitClassTemplatePartialSpecializationDecl(
  ClassTemplatePartialSpecializationDecl *D);
   bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -498,7 +498,13 @@
 if (!D)
   return false;
 
-return VisitAttributes(D) || Visit(D);
+if (VisitAttributes(D))
+  return true;
+
+if (Cursor.kind == CXCursor_ClassTemplateSpecialization)
+  return VisitClassTemplateSpecializationDecl(static_cast(D), /*EnforceVisitBody*/ true);
+else
+  return Visit(D);
   }
 
   if (clang_isStatement(Cursor.kind)) {
@@ -701,22 +707,23 @@
 }
 
 bool CursorVisitor::VisitClassTemplateSpecializationDecl(
-  ClassTemplateSpecializationDecl *D) {
-  bool ShouldVisitBody = false;
-  switch (D->getSpecializationKind()) {
-  case TSK_Undeclared:
-  case TSK_ImplicitInstantiation:
-// Nothing to visit
-return false;
-  
-  case TSK_ExplicitInstantiationDeclaration:
-  case TSK_ExplicitInstantiationDefinition:
-break;
-  
-  case TSK_ExplicitSpecialization:
-ShouldVisitBody = true;
-break;
-  }
+  ClassTemplateSpecializationDecl *D, bool EnforceVisitBody) {
+  bool ShouldVisitBody = EnforceVisitBody;
+  if (!EnforceVisitBody)
+switch (D->getSpecializationKind()) {
+case TSK_Undeclared:
+case TSK_ImplicitInstantiation:
+  // Nothing to visit
+  return false;
+
+case TSK_ExplicitInstantiationDeclaration:
+case TSK_ExplicitInstantiationDef