Hi,

Here is a libclang patch to add missing access to template arguments of a template type instanciation in CXType API.


Cheers,


P.S.: (barely related) I first though about doing it at CXCursor-api level, but a CXCursor cannot be generated for a basic type, which actually causes weird things when visiting using the C API:

  class Class{};
  template<typename A, typename B> class Templ;

  Templ<Class, Class> a;
  Templ<int, Class> b;

Visiting the two Templ instanciations gives the following visited trees:

Decl
  Templ: class template
  Class
  Class
Decl
  Templ
  Class

ie the "int" is silently skipped (by VisitBuildtinTypeLoc). I have a workaround that creates a dummy CXCursor in VisitBuildtinTypeLoc but that seems dangerous as most operations on it apart from clang_getCursorType will likely fail.





From eefb258787222dd32856c188d310c5a1c2e87a6f Mon Sep 17 00:00:00 2001
From: Matthieu Nottale <mnott...@aldebaran-robotics.com>
Date: Mon, 26 Aug 2013 15:05:43 +0200
Subject: [PATCH] libclang: New functions clang_Type_getNumTemplateArguments,
 clang_Type_getTemplateArgument.

 include/clang-c/Index.h         |   14 ++++++++++++++
 tools/libclang/CXType.cpp       |   30 ++++++++++++++++++++++++++++++
 tools/libclang/libclang.exports |    2 ++
 3 files changed, 46 insertions(+)

diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index b294e41..c2f2bd5 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -2994,6 +2994,20 @@ CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T); CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);

 /**
+ * \brief Returns the number of template parameters for given class template + * specialization, or -1 if type T is not a class template specialization.
+ *
+ */
+CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
+
+/**
+* \brief Returns the template parameter of a template class specialization
+*    at given index.
+*/
+CINDEX_LINKAGE CXType clang_Type_getTemplateArgument(CXType T, unsigned i);
+
+
+/**
* \brief Returns non-zero if the cursor specifies a Record member that is a
  *   bitfield.
  */
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index dcf69b5..809e50a 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -832,4 +832,34 @@ CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
   return cxstring::createDup(encoding);
 }

+int clang_Type_getNumTemplateArguments(CXType X)
+{
+  QualType T = GetQualType(X);
+  const CXXRecordDecl* RecordDecl =  T->getAsCXXRecordDecl();
+  if (!RecordDecl)
+    return -1;
+ const ClassTemplateSpecializationDecl* TemplateDecl = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RecordDecl);
+  if (!TemplateDecl)
+    return -1;
+  return TemplateDecl->getTemplateArgs().size();
+}
+
+CXType clang_Type_getTemplateArgument(CXType CT, unsigned i)
+{
+  QualType T = GetQualType(CT);
+  const CXXRecordDecl* RecordDecl = T->getAsCXXRecordDecl();
+  if (!RecordDecl)
+    return MakeCXType(QualType(), GetTU(CT));
+ const ClassTemplateSpecializationDecl* TemplateDecl = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RecordDecl);
+  if (!TemplateDecl)
+    return MakeCXType(QualType(), GetTU(CT));
+  const TemplateArgumentList& TA =  TemplateDecl->getTemplateArgs();
+  if (TA.size() <= i)
+    return MakeCXType(QualType(), GetTU(CT));
+  const TemplateArgument& A = TA.get(i);
+  if (A.getKind() != TemplateArgument::Type)
+    return MakeCXType(QualType(), GetTU(CT));
+  return MakeCXType(A.getAsType(), GetTU(CT));
+}
+
 } // end: extern "C"
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 92b060a..9d9954a 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -63,6 +63,8 @@ clang_TParamCommandComment_getIndex
 clang_Type_getAlignOf
 clang_Type_getSizeOf
 clang_Type_getOffsetOf
+clang_Type_getNumTemplateArguments
+clang_Type_getTemplateArgument
 clang_VerbatimBlockLineComment_getText
 clang_VerbatimLineComment_getText
 clang_HTMLTagComment_getAsString
--
1.7.10.4
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to