https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/88600
>From bcd04db735a78b4d7df93e88229ea4e2491fc09e Mon Sep 17 00:00:00 2001 From: Vassil Vassilev <v.g.vassi...@gmail.com> Date: Sat, 13 Apr 2024 06:39:34 +0000 Subject: [PATCH] Fix the double space and double attribute printing of the final keyword. Fixes #56517. --- clang/lib/AST/DeclPrinter.cpp | 31 ++++++++++++--------- clang/test/SemaCXX/cxx11-attr-print.cpp | 5 ++++ clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl | 4 +-- clang/unittests/AST/DeclPrinterTest.cpp | 8 ++++++ clang/utils/TableGen/ClangAttrEmitter.cpp | 2 +- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 6afdb6cfccb142..c82d18be7741e5 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -119,7 +119,7 @@ namespace { void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args, const TemplateParameterList *Params); enum class AttrPosAsWritten { Default = 0, Left, Right }; - void + bool prettyPrintAttributes(const Decl *D, AttrPosAsWritten Pos = AttrPosAsWritten::Default); void prettyPrintPragmas(Decl *D); @@ -252,10 +252,12 @@ static DeclPrinter::AttrPosAsWritten getPosAsWritten(const Attr *A, return DeclPrinter::AttrPosAsWritten::Right; } -void DeclPrinter::prettyPrintAttributes(const Decl *D, +// returns true if an attribute was printed. +bool DeclPrinter::prettyPrintAttributes(const Decl *D, AttrPosAsWritten Pos /*=Default*/) { + bool hasPrinted = false; if (Policy.PolishForDeclaration) - return; + return hasPrinted; if (D->hasAttrs()) { const AttrVec &Attrs = D->getAttrs(); @@ -275,6 +277,7 @@ void DeclPrinter::prettyPrintAttributes(const Decl *D, if (Pos != AttrPosAsWritten::Left) Out << ' '; A->printPretty(Out, Policy); + hasPrinted = true; if (Pos == AttrPosAsWritten::Left) Out << ' '; } @@ -282,6 +285,7 @@ void DeclPrinter::prettyPrintAttributes(const Decl *D, } } } + return hasPrinted; } void DeclPrinter::prettyPrintPragmas(Decl *D) { @@ -1060,12 +1064,15 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { // FIXME: add printing of pragma attributes if required. if (!Policy.SuppressSpecifiers && D->isModulePrivate()) Out << "__module_private__ "; - Out << D->getKindName(); - prettyPrintAttributes(D); + Out << D->getKindName() << ' '; - if (D->getIdentifier()) { + // FIXME: Move before printing the decl kind to match the behavior of the + // attribute printing for variables and function where they are printed first. + if (prettyPrintAttributes(D, AttrPosAsWritten::Left)) Out << ' '; + + if (D->getIdentifier()) { if (auto *NNS = D->getQualifier()) NNS->print(Out, Policy); Out << *D; @@ -1082,13 +1089,10 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { } } - if (D->hasDefinition()) { - if (D->hasAttr<FinalAttr>()) { - Out << " final"; - } - } + prettyPrintAttributes(D, AttrPosAsWritten::Right); if (D->isCompleteDefinition()) { + Out << ' '; // Print the base classes if (D->getNumBases()) { Out << " : "; @@ -1109,15 +1113,16 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { if (Base->isPackExpansion()) Out << "..."; + Out << ' '; } } // Print the class definition // FIXME: Doesn't print access specifiers, e.g., "public:" if (Policy.TerseOutput) { - Out << " {}"; + Out << "{}"; } else { - Out << " {\n"; + Out << "{\n"; VisitDeclContext(D); Indent() << "}"; } diff --git a/clang/test/SemaCXX/cxx11-attr-print.cpp b/clang/test/SemaCXX/cxx11-attr-print.cpp index a169d1b4409b4d..2b084018bc0662 100644 --- a/clang/test/SemaCXX/cxx11-attr-print.cpp +++ b/clang/test/SemaCXX/cxx11-attr-print.cpp @@ -87,3 +87,8 @@ template struct S<int>; // CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int; using Small2 [[gnu::mode(byte)]] = int; + +class FinalNonTemplate final {}; +// CHECK: class FinalNonTemplate final { +template <typename T> class FinalTemplate final {}; +// CHECK: template <typename T> class FinalTemplate final { diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl index 7e79ae3bf005fc..b1a15c43191829 100644 --- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl @@ -6,11 +6,11 @@ typedef vector<float, 3> float3; RWBuffer<float3> Buffer; // expected-error@+2 {{class template 'RWBuffer' requires template arguments}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}} +// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}} RWBuffer BufferErr1; // expected-error@+2 {{too few template arguments for class template 'RWBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}} +// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}} RWBuffer<> BufferErr2; [numthreads(1,1,1)] diff --git a/clang/unittests/AST/DeclPrinterTest.cpp b/clang/unittests/AST/DeclPrinterTest.cpp index f2b027a25621ce..39c9eece751e9d 100644 --- a/clang/unittests/AST/DeclPrinterTest.cpp +++ b/clang/unittests/AST/DeclPrinterTest.cpp @@ -1556,3 +1556,11 @@ TEST(DeclPrinter, VarDeclWithInitializer) { PrintedDeclCXX17Matches("void foo() {int arr[42]; for(int a : arr);}", namedDecl(hasName("a")).bind("id"), "int a")); } + +TEST(DeclPrinter, TestTemplateFinal) { + ASSERT_TRUE(PrintedDeclCXX11Matches( + "template<typename T>" + "class FinalTemplate final {};", + classTemplateDecl(hasName("FinalTemplate")).bind("id"), + "template <typename T> class FinalTemplate final {}")); +} diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 6c56f99f503df4..765cbbf3b04bcf 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -1608,7 +1608,7 @@ writePrettyPrintFunction(const Record &R, Prefix = "["; Suffix = "]"; } else if (Variety == "Keyword") { - Prefix = " "; + Prefix = ""; Suffix = ""; } else if (Variety == "Pragma") { Prefix = "#pragma "; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits