From 57ae857548bdf8928171aebb9508cb0d9e04ccfe Mon Sep 17 00:00:00 2001 From: Malcolm Parsons Date: Mon, 28 Nov 2016 11:11:34 +0000 Subject: [PATCH] [Sema] Set range end of constructors and destructors in template instantiations Summary: clang-tidy checks frequently use source ranges of functions. The source range of constructors and destructors in template instantiations is currently a single token. The factory method for constructors and destructors does not allow the end source location to be specified. Set end location manually after creating instantiation. Reviewers: aaron.ballman, rsmith, arphaman Subscribers: arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D26849 llvm-svn: 288025 --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 ++ clang/test/Misc/ast-dump-decl.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index ae5f5de..6b6abc7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1871,11 +1871,13 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Constructor->isExplicit(), Constructor->isInlineSpecified(), false, Constructor->isConstexpr()); + Method->setRangeEnd(Constructor->getLocEnd()); } else if (CXXDestructorDecl *Destructor = dyn_cast(D)) { Method = CXXDestructorDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, Destructor->isInlineSpecified(), false); + Method->setRangeEnd(Destructor->getLocEnd()); } else if (CXXConversionDecl *Conversion = dyn_cast(D)) { Method = CXXConversionDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, diff --git a/clang/test/Misc/ast-dump-decl.cpp b/clang/test/Misc/ast-dump-decl.cpp index 9e94a30..1cfcd50 100644 --- a/clang/test/Misc/ast-dump-decl.cpp +++ b/clang/test/Misc/ast-dump-decl.cpp @@ -223,6 +223,10 @@ namespace testClassTemplateDecl { class D { }; template class TestClassTemplate { + public: + TestClassTemplate(); + ~TestClassTemplate(); + int j(); int i; }; @@ -252,10 +256,18 @@ namespace testClassTemplateDecl { // CHECK-NEXT: TemplateTypeParmDecl // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} +// CHECK-NEXT: CXXDestructorDecl{{.*}} +// CHECK-NEXT: CXXMethodDecl{{.*}} // CHECK-NEXT: FieldDecl{{.*}} i // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate // CHECK-NEXT: TemplateArgument{{.*}}A // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} +// CHECK-NEXT: CXXDestructorDecl{{.*}} +// CHECK-NEXT: CXXMethodDecl{{.*}} // CHECK-NEXT: FieldDecl{{.*}} i // CHECK: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' // CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' @@ -269,11 +281,19 @@ namespace testClassTemplateDecl { // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate // CHECK-NEXT: TemplateArgument{{.*}}C // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} +// CHECK-NEXT: CXXDestructorDecl{{.*}} +// CHECK-NEXT: CXXMethodDecl{{.*}} // CHECK-NEXT: FieldDecl{{.*}} i // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate // CHECK-NEXT: TemplateArgument{{.*}}D // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} +// CHECK-NEXT: CXXDestructorDecl{{.*}} +// CHECK-NEXT: CXXMethodDecl{{.*}} // CHECK-NEXT: FieldDecl{{.*}} i // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial -- 2.7.4