[PATCH] libclang: New functions clang_Type_getNumTemplateArguments, clang_Type_getTemplateArgument.

Matthieu Nottale mnottale at aldebaran-robotics.com
Mon Sep 16 05:18:26 PDT 2013


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 <mnottale at 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



More information about the cfe-commits mailing list