jklaehn updated this revision to Diff 118330. jklaehn added a comment. Added `c-index-test`-based test.
https://reviews.llvm.org/D36955 Files: bindings/python/tests/cindex/test_cursor.py test/Index/annotate-attribute.cpp tools/libclang/CIndex.cpp Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -907,16 +907,18 @@ if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitFunctionDecl(D->getTemplatedDecl()); + auto* FD = D->getTemplatedDecl(); + return VisitAttributes(FD) || VisitFunctionDecl(FD); } bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { // FIXME: Visit the "outer" template parameter lists on the TagDecl // before visiting these template parameters. if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitCXXRecordDecl(D->getTemplatedDecl()); + auto* CD = D->getTemplatedDecl(); + return VisitAttributes(CD) || VisitCXXRecordDecl(CD); } bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { Index: test/Index/annotate-attribute.cpp =================================================================== --- test/Index/annotate-attribute.cpp +++ test/Index/annotate-attribute.cpp @@ -16,6 +16,12 @@ void methodWithoutAttribute(); }; +template <typename T> +class __attribute__((annotate("works"))) TemplateTest {}; + +template <typename T> +int templateFunction(T value) __attribute__((annotate("works"))); + // CHECK: ClassDecl=Test:3:7 (Definition) Extent=[3:1 - 17:2] // CHECK-NEXT: CXXAccessSpecifier=:4:1 (Definition) Extent=[4:1 - 4:8] // CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:3 - 5:60] @@ -31,3 +37,9 @@ // CHECK-NEXT: CompoundStmt= Extent=[12:23 - 12:25] // CHECK-NEXT: CXXAccessSpecifier=:14:1 (Definition) Extent=[14:1 - 14:11] // CHECK-NEXT: CXXMethod=methodWithoutAttribute:16:8 Extent=[16:3 - 16:32] +// CHECK: ClassTemplate=TemplateTest:20:42 (Definition) Extent=[19:1 - 20:57] +// CHECK-NEXT: TemplateTypeParameter=T:19:20 (Definition) Extent=[19:11 - 19:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[20:22 - 20:39] +// CHECK: FunctionTemplate=templateFunction:23:5 Extent=[22:1 - 23:65] +// CHECK-NEXT: TemplateTypeParameter=T:22:20 (Definition) Extent=[22:11 - 22:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[23:46 - 23:63] Index: bindings/python/tests/cindex/test_cursor.py =================================================================== --- bindings/python/tests/cindex/test_cursor.py +++ bindings/python/tests/cindex/test_cursor.py @@ -377,6 +377,26 @@ else: assert False, "Couldn't find annotation" +def test_annotation_template(): + annotation = '__attribute__ ((annotate("annotation")))' + for source, kind in [ + ('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), + ('class %s foo {};', CursorKind.CLASS_TEMPLATE), + ]: + source = 'template<typename T> ' + (source % annotation) + tu = get_tu(source, lang="cpp") + + foo = get_cursor(tu, 'foo') + assert foo is not None + assert foo.kind == kind + + for c in foo.get_children(): + if c.kind == CursorKind.ANNOTATE_ATTR: + assert c.displayname == "annotation" + break + else: + assert False, "Couldn't find annotation for {}".format(kind) + def test_result_type(): tu = get_tu('int foo();') foo = get_cursor(tu, 'foo')
Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -907,16 +907,18 @@ if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitFunctionDecl(D->getTemplatedDecl()); + auto* FD = D->getTemplatedDecl(); + return VisitAttributes(FD) || VisitFunctionDecl(FD); } bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { // FIXME: Visit the "outer" template parameter lists on the TagDecl // before visiting these template parameters. if (VisitTemplateParameters(D->getTemplateParameters())) return true; - return VisitCXXRecordDecl(D->getTemplatedDecl()); + auto* CD = D->getTemplatedDecl(); + return VisitAttributes(CD) || VisitCXXRecordDecl(CD); } bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { Index: test/Index/annotate-attribute.cpp =================================================================== --- test/Index/annotate-attribute.cpp +++ test/Index/annotate-attribute.cpp @@ -16,6 +16,12 @@ void methodWithoutAttribute(); }; +template <typename T> +class __attribute__((annotate("works"))) TemplateTest {}; + +template <typename T> +int templateFunction(T value) __attribute__((annotate("works"))); + // CHECK: ClassDecl=Test:3:7 (Definition) Extent=[3:1 - 17:2] // CHECK-NEXT: CXXAccessSpecifier=:4:1 (Definition) Extent=[4:1 - 4:8] // CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:3 - 5:60] @@ -31,3 +37,9 @@ // CHECK-NEXT: CompoundStmt= Extent=[12:23 - 12:25] // CHECK-NEXT: CXXAccessSpecifier=:14:1 (Definition) Extent=[14:1 - 14:11] // CHECK-NEXT: CXXMethod=methodWithoutAttribute:16:8 Extent=[16:3 - 16:32] +// CHECK: ClassTemplate=TemplateTest:20:42 (Definition) Extent=[19:1 - 20:57] +// CHECK-NEXT: TemplateTypeParameter=T:19:20 (Definition) Extent=[19:11 - 19:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[20:22 - 20:39] +// CHECK: FunctionTemplate=templateFunction:23:5 Extent=[22:1 - 23:65] +// CHECK-NEXT: TemplateTypeParameter=T:22:20 (Definition) Extent=[22:11 - 22:21] [access=public] +// CHECK-NEXT: attribute(annotate)=works Extent=[23:46 - 23:63] Index: bindings/python/tests/cindex/test_cursor.py =================================================================== --- bindings/python/tests/cindex/test_cursor.py +++ bindings/python/tests/cindex/test_cursor.py @@ -377,6 +377,26 @@ else: assert False, "Couldn't find annotation" +def test_annotation_template(): + annotation = '__attribute__ ((annotate("annotation")))' + for source, kind in [ + ('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), + ('class %s foo {};', CursorKind.CLASS_TEMPLATE), + ]: + source = 'template<typename T> ' + (source % annotation) + tu = get_tu(source, lang="cpp") + + foo = get_cursor(tu, 'foo') + assert foo is not None + assert foo.kind == kind + + for c in foo.get_children(): + if c.kind == CursorKind.ANNOTATE_ATTR: + assert c.displayname == "annotation" + break + else: + assert False, "Couldn't find annotation for {}".format(kind) + def test_result_type(): tu = get_tu('int foo();') foo = get_cursor(tu, 'foo')
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits