From: Douglas Gregor Date: Tue, 31 Aug 2010 22:12:17 +0000 (+0000) Subject: Add a new libclang function clang_getTemplateCursorKind(), which X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=49f6f5489483beaffc7ce48dfc000af4e65b9216;p=clang Add a new libclang function clang_getTemplateCursorKind(), which determines the kind of declaration that would be generated if the given template were instantiated. This allows a client to distinguish among class/struct/union templates and function/member function/static member function templates. Also, teach clang_CXXMethod_isStatic() about function templates. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112655 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index be02bcf8c3..404d7aa514 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1716,10 +1716,30 @@ CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor); */ /** - * \brief Determine if a C++ member function is declared 'static'. + * \brief Determine if a C++ member function or member function template is + * declared 'static'. */ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C); +/** + * \brief Given a cursor that represents a template, determine + * the cursor kind of the specializations would be generated by instantiating + * the template. + * + * This routine can be used to determine what flavor of function template, + * class template, or class template partial specialization is stored in the + * cursor. For example, it can describe whether a class template cursor is + * declared with "struct", "class" or "union". + * + * \param C The cursor to query. This cursor should represent a template + * declaration. + * + * \returns The cursor kind of the specializations that would be generated + * by instantiating the template \p C. If \p C is not a template, returns + * \c CXCursor_NoDeclFound. + */ +CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C); + /** * @} */ diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 1515ed3c2c..2a7e6e9b06 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -3322,8 +3322,14 @@ extern "C" { unsigned clang_CXXMethod_isStatic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; - CXXMethodDecl *D = dyn_cast(cxcursor::getCursorDecl(C)); - return (D && D->isStatic()) ? 1 : 0; + + CXXMethodDecl *Method = 0; + Decl *D = cxcursor::getCursorDecl(C); + if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null(D)) + Method = dyn_cast(FunTmpl->getTemplatedDecl()); + else + Method = dyn_cast_or_null(D); + return (Method && Method->isStatic()) ? 1 : 0; } } // end: extern "C" diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp index a168f16045..ee83f98722 100644 --- a/tools/libclang/CIndexCXX.cpp +++ b/tools/libclang/CIndexCXX.cpp @@ -15,6 +15,7 @@ #include "CXCursor.h" #include "CXType.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" using namespace clang; using namespace clang::cxstring; @@ -45,4 +46,36 @@ enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { return CX_CXXInvalidAccessSpecifier; } +enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { + using namespace clang::cxcursor; + + switch (C.kind) { + case CXCursor_ClassTemplate: + case CXCursor_FunctionTemplate: + if (TemplateDecl *Template + = dyn_cast_or_null(getCursorDecl(C))) + return MakeCXCursor(Template->getTemplatedDecl(), + getCursorASTUnit(C)).kind; + break; + + case CXCursor_ClassTemplatePartialSpecialization: + if (ClassTemplateSpecializationDecl *PartialSpec + = dyn_cast_or_null( + getCursorDecl(C))) { + switch (PartialSpec->getTagKind()) { + case TTK_Class: return CXCursor_ClassDecl; + case TTK_Struct: return CXCursor_StructDecl; + case TTK_Union: return CXCursor_UnionDecl; + case TTK_Enum: return CXCursor_NoDeclFound; + } + } + break; + + default: + break; + } + + return CXCursor_NoDeclFound; +} + } // end extern "C" diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports index 0d01dd9b28..289026510f 100644 --- a/tools/libclang/libclang.darwin.exports +++ b/tools/libclang/libclang.darwin.exports @@ -78,6 +78,7 @@ _clang_getRange _clang_getRangeEnd _clang_getRangeStart _clang_getResultType +_clang_getTemplateCursorKind _clang_getTokenExtent _clang_getTokenKind _clang_getTokenLocation diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 60d335299e..254ba98a73 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -78,6 +78,7 @@ clang_getRange clang_getRangeEnd clang_getRangeStart clang_getResultType +clang_getTemplateCursorKind clang_getTokenExtent clang_getTokenKind clang_getTokenLocation