anderslanglands created this revision. Herald added a project: All. anderslanglands requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Modifies clang_Cursor_getNumTemplateArguments() and friends to work on Struct, Class and ClassTemplatePartialSpecialization decls as well as functions Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D134416 Files: clang/docs/ReleaseNotes.rst clang/tools/libclang/CXCursor.cpp
Index: clang/tools/libclang/CXCursor.cpp =================================================================== --- clang/tools/libclang/CXCursor.cpp +++ clang/tools/libclang/CXCursor.cpp @@ -1353,34 +1353,42 @@ } int clang_Cursor_getNumTemplateArguments(CXCursor C) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C)); - if (!FD) { - return -1; - } - - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { + if (const FunctionDecl *FD = + llvm::dyn_cast_if_present<clang::FunctionDecl>(getCursorDecl(C))) { + const FunctionTemplateSpecializationInfo *SpecInfo = + FD->getTemplateSpecializationInfo(); + if (!SpecInfo) { + return -1; + } + return SpecInfo->TemplateArguments->size(); + } else if (const ClassTemplateSpecializationDecl *SD = + llvm::dyn_cast_if_present< + clang::ClassTemplateSpecializationDecl>( + getCursorDecl(C))) { + return SD->getTemplateArgs().size(); + } else { return -1; } - - return SpecInfo->TemplateArguments->size(); } enum CXGetTemplateArgumentStatus { /** The operation completed successfully */ CXGetTemplateArgumentStatus_Success = 0, - /** The specified cursor did not represent a FunctionDecl. */ - CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1, + /** The specified cursor did not represent a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_CursorNotCompatibleDecl = -1, - /** The specified cursor was not castable to a FunctionDecl. */ - CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2, + /** The specified cursor was not castable to a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_BadDeclCast = -2, /** A NULL FunctionTemplateSpecializationInfo was retrieved. */ CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3, @@ -1391,28 +1399,43 @@ static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I, TemplateArgument *TA) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { - return CXGetTemplateArgumentStatus_CursorNotFunctionDecl; + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { + return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C)); - if (!FD) { - return CXGetTemplateArgumentStatus_BadFunctionDeclCast; - } + if (const FunctionDecl *FD = + llvm::dyn_cast_if_present<clang::FunctionDecl>(getCursorDecl(C))) { - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { - return CXGetTemplateArgumentStatus_NullTemplSpecInfo; - } + const FunctionTemplateSpecializationInfo *SpecInfo = + FD->getTemplateSpecializationInfo(); + if (!SpecInfo) { + return CXGetTemplateArgumentStatus_NullTemplSpecInfo; + } - if (I >= SpecInfo->TemplateArguments->size()) { - return CXGetTemplateArgumentStatus_InvalidIndex; - } + if (I >= SpecInfo->TemplateArguments->size()) { + return CXGetTemplateArgumentStatus_InvalidIndex; + } - *TA = SpecInfo->TemplateArguments->get(I); - return 0; + *TA = SpecInfo->TemplateArguments->get(I); + return 0; + } else if (const ClassTemplateSpecializationDecl *SD = + llvm::dyn_cast_if_present< + clang::ClassTemplateSpecializationDecl>( + getCursorDecl(C))) { + if (I >= SD->getTemplateArgs().size()) { + printf("INVALID INDEX\n"); + return CXGetTemplateArgumentStatus_InvalidIndex; + } + + *TA = SD->getTemplateArgs()[I]; + return 0; + } else { + printf("CAST FAILED\n"); + return CXGetTemplateArgumentStatus_BadDeclCast; + } } enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -402,6 +402,10 @@ the behavior of ``QualType::getNonReferenceType`` for ``CXType``. - Introduced the new function ``clang_CXXMethod_isDeleted``, which queries whether the method is declared ``= delete``. +- ``clang_Cursor_getNumTemplateArguments``, ``clang_Cursor_getTemplateArgumentKind``, + ``clang_Cursor_getTemplateArgumentType``, ``clang_Cursor_getTemplateArgumentValue`` and + ``clang_Cursor_getTemplateArgumentUnsignedValue`` now work on struct, class and partial template specialization + cursors in addition to function cursors. Static Analyzer ---------------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits