mirror of https://github.com/microsoft/clang.git
[libclang] Visit attributes for function and class templates
Summary: Previously, `VisitAttributes` was not called for function and class templates and thus their attributes were not accessible using libclang. Reviewers: bkramer, arphaman, rsmith, jbcoe Reviewed By: jbcoe Subscribers: cfe-commits Tags: #clang Patch by jklaehn (Johann Klähn) Differential Revision: https://reviews.llvm.org/D36955 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315958 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
551dc900ed
commit
11e6fda273
|
@ -377,6 +377,26 @@ def test_annotation_attribute():
|
|||
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')
|
||||
|
|
|
@ -16,6 +16,12 @@ protected:
|
|||
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 @@ protected:
|
|||
// 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]
|
||||
|
|
|
@ -907,7 +907,8 @@ bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
|||
if (VisitTemplateParameters(D->getTemplateParameters()))
|
||||
return true;
|
||||
|
||||
return VisitFunctionDecl(D->getTemplatedDecl());
|
||||
auto* FD = D->getTemplatedDecl();
|
||||
return VisitAttributes(FD) || VisitFunctionDecl(FD);
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
||||
|
@ -916,7 +917,8 @@ bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
|||
if (VisitTemplateParameters(D->getTemplateParameters()))
|
||||
return true;
|
||||
|
||||
return VisitCXXRecordDecl(D->getTemplatedDecl());
|
||||
auto* CD = D->getTemplatedDecl();
|
||||
return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
|
||||
|
|
Loading…
Reference in New Issue