llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Kim Gräsman (kimgr)
<details>
<summary>Changes</summary>
This was motivated by the decl printing for the alignas() keyword attribute:
class alignas(1) Foo;
would be printed as:
class alignas(1) Foo;
with two spaces before class name.
Rather than trying to help prettyPrintAttributes guess what the caller wants in
terms of leading and trailing spaces, split it into two:
* getPrintableAttributes: returns attrs that should be printed at Pos
* prettyPrintAttributes: writes pre-filtered attrs to Out
That way callers can compose and only print desired prefix/suffix if they know
there are attributes to print.
Add simple test cases for alignas.
---
Full diff: https://github.com/llvm/llvm-project/pull/174197.diff
2 Files Affected:
- (modified) clang/lib/AST/DeclPrinter.cpp (+103-50)
- (modified) clang/test/SemaCXX/cxx11-attr-print.cpp (+5)
``````````diff
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 47ae613b643b6..87a6dc96a0154 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -124,9 +125,11 @@ namespace {
void printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
const TemplateParameterList *Params);
enum class AttrPosAsWritten { Default = 0, Left, Right };
- bool
- prettyPrintAttributes(const Decl *D,
- AttrPosAsWritten Pos = AttrPosAsWritten::Default);
+ AttrVec
+ getPrintableAttributes(const Decl *D,
+ AttrPosAsWritten Pos = AttrPosAsWritten::Default);
+ void prettyPrintAttributes(const AttrVec &Attrs);
+
void prettyPrintPragmas(Decl *D);
void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
};
@@ -252,41 +255,41 @@ static DeclPrinter::AttrPosAsWritten
getPosAsWritten(const Attr *A,
return DeclPrinter::AttrPosAsWritten::Right;
}
-// returns true if an attribute was printed.
-bool DeclPrinter::prettyPrintAttributes(const Decl *D,
- AttrPosAsWritten Pos /*=Default*/) {
- bool hasPrinted = false;
-
- if (D->hasAttrs()) {
- const AttrVec &Attrs = D->getAttrs();
- for (auto *A : Attrs) {
- if (A->isInherited() || A->isImplicit())
- continue;
- // Print out the keyword attributes, they aren't regular attributes.
- if (Policy.PolishForDeclaration && !A->isKeywordAttribute())
- continue;
- switch (A->getKind()) {
+AttrVec DeclPrinter::getPrintableAttributes(const Decl *D,
+ AttrPosAsWritten Pos /*=Default*/)
{
+ AttrVec Printable;
+ if (!D->hasAttrs())
+ return Printable;
+ for (auto *A : D->getAttrs()) {
+ if (A->isInherited() || A->isImplicit())
+ continue;
+ // Print out the keyword attributes, they aren't regular attributes.
+ if (Policy.PolishForDeclaration && !A->isKeywordAttribute())
+ continue;
+ switch (A->getKind()) {
#define ATTR(X)
#define PRAGMA_SPELLING_ATTR(X) case attr::X:
#include "clang/Basic/AttrList.inc"
- break;
- default:
- AttrPosAsWritten APos = getPosAsWritten(A, D);
- assert(APos != AttrPosAsWritten::Default &&
- "Default not a valid for an attribute location");
- if (Pos == AttrPosAsWritten::Default || Pos == APos) {
- if (Pos != AttrPosAsWritten::Left)
- Out << ' ';
- A->printPretty(Out, Policy);
- hasPrinted = true;
- if (Pos == AttrPosAsWritten::Left)
- Out << ' ';
- }
- break;
+ break;
+ default:
+ AttrPosAsWritten APos = getPosAsWritten(A, D);
+ assert(APos != AttrPosAsWritten::Default &&
+ "Default not a valid for an attribute location");
+ if (Pos == AttrPosAsWritten::Default || Pos == APos) {
+ Printable.push_back(A);
}
+ break;
}
}
- return hasPrinted;
+ return Printable;
+}
+
+void DeclPrinter::prettyPrintAttributes(const AttrVec &Attrs) {
+ llvm::ListSeparator LS(" ");
+ for (const auto *A : Attrs) {
+ Out << LS;
+ A->printPretty(Out, Policy);
+ }
}
void DeclPrinter::PrintOpenACCRoutineOnLambda(Decl *D) {
@@ -584,12 +587,19 @@ void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
}
QualType Ty = D->getTypeSourceInfo()->getType();
Ty.print(Out, Policy, D->getName(), Indentation);
- prettyPrintAttributes(D);
+
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
}
void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) {
Out << "using " << *D;
- prettyPrintAttributes(D);
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
Out << " = " << D->getTypeSourceInfo()->getType().getAsString(Policy);
}
@@ -604,7 +614,10 @@ void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
Out << " struct";
}
- prettyPrintAttributes(D);
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
if (D->getDeclName())
Out << ' ' << D->getDeclName();
@@ -624,7 +637,10 @@ void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
Out << "__module_private__ ";
Out << D->getKindName();
- prettyPrintAttributes(D);
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
if (D->getIdentifier())
Out << ' ' << *D;
@@ -638,7 +654,10 @@ void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
Out << *D;
- prettyPrintAttributes(D);
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
if (Expr *Init = D->getInitExpr()) {
Out << " = ";
Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
@@ -664,7 +683,11 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (!D->getDescribedFunctionTemplate() &&
!D->isFunctionTemplateSpecialization()) {
prettyPrintPragmas(D);
- prettyPrintAttributes(D, AttrPosAsWritten::Left);
+ if (AttrVec Attrs = getPrintableAttributes(D, AttrPosAsWritten::Left);
+ !Attrs.empty()) {
+ prettyPrintAttributes(Attrs);
+ Out << " ";
+ }
}
if (D->isFunctionTemplateSpecialization())
@@ -836,7 +859,11 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Ty.print(Out, Policy, Proto);
}
- prettyPrintAttributes(D, AttrPosAsWritten::Right);
+ if (AttrVec Attrs = getPrintableAttributes(D, AttrPosAsWritten::Right);
+ !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
if (D->isPureVirtual())
Out << " = 0";
@@ -928,7 +955,10 @@ void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
Out << " = ";
Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
}
- prettyPrintAttributes(D);
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
}
void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
@@ -938,7 +968,11 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
void DeclPrinter::VisitVarDecl(VarDecl *D) {
prettyPrintPragmas(D);
- prettyPrintAttributes(D, AttrPosAsWritten::Left);
+ if (AttrVec Attrs = getPrintableAttributes(D, AttrPosAsWritten::Left);
+ !Attrs.empty()) {
+ prettyPrintAttributes(Attrs);
+ Out << " ";
+ }
if (const auto *Param = dyn_cast<ParmVarDecl>(D);
Param && Param->isExplicitObjectParameter())
@@ -981,7 +1015,11 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) {
? D->getIdentifier()->deuglifiedName()
: D->getName());
- prettyPrintAttributes(D, AttrPosAsWritten::Right);
+ if (AttrVec Attrs = getPrintableAttributes(D, AttrPosAsWritten::Right);
+ !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
Expr *Init = D->getInit();
if (!Policy.SuppressInitializers && Init) {
@@ -1073,7 +1111,9 @@ void
DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
}
void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
- prettyPrintAttributes(D);
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ prettyPrintAttributes(Attrs);
+ }
}
void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
@@ -1085,8 +1125,11 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
// 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 (AttrVec Attrs = getPrintableAttributes(D, AttrPosAsWritten::Left);
+ !Attrs.empty()) {
+ prettyPrintAttributes(Attrs);
+ Out << " ";
+ }
if (D->getIdentifier()) {
D->getQualifier().print(Out, Policy);
@@ -1104,7 +1147,11 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
}
}
- prettyPrintAttributes(D, AttrPosAsWritten::Right);
+ if (AttrVec Attrs = getPrintableAttributes(D, AttrPosAsWritten::Right);
+ !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
if (D->isCompleteDefinition()) {
Out << ' ';
@@ -1421,7 +1468,10 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl
*OMD) {
if (OMD->isVariadic())
Out << ", ...";
- prettyPrintAttributes(OMD);
+ if (AttrVec Attrs = getPrintableAttributes(OMD); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
if (OMD->getBody() && !Policy.TerseOutput) {
Out << ' ';
@@ -1477,8 +1527,8 @@ void
DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
return;
}
bool eolnOut = false;
- if (OID->hasAttrs()) {
- prettyPrintAttributes(OID);
+ if (AttrVec Attrs = getPrintableAttributes(OID); !Attrs.empty()) {
+ prettyPrintAttributes(Attrs);
Out << "\n";
}
@@ -1777,7 +1827,10 @@ void DeclPrinter::VisitHLSLBufferDecl(HLSLBufferDecl *D)
{
Out << *D;
- prettyPrintAttributes(D);
+ if (AttrVec Attrs = getPrintableAttributes(D); !Attrs.empty()) {
+ Out << " ";
+ prettyPrintAttributes(Attrs);
+ }
Out << " {\n";
VisitDeclContext(D);
diff --git a/clang/test/SemaCXX/cxx11-attr-print.cpp
b/clang/test/SemaCXX/cxx11-attr-print.cpp
index 2b084018bc066..70274bd5aa72a 100644
--- a/clang/test/SemaCXX/cxx11-attr-print.cpp
+++ b/clang/test/SemaCXX/cxx11-attr-print.cpp
@@ -92,3 +92,8 @@ class FinalNonTemplate final {};
// CHECK: class FinalNonTemplate final {
template <typename T> class FinalTemplate final {};
// CHECK: template <typename T> class FinalTemplate final {
+
+class alignas(8) AlignedClass {};
+// CHECK: class alignas(8) AlignedClass {
+template<typename T> class alignas(4) AlignedClassTemplate {};
+// CHECK: class alignas(4) AlignedClassTemplate {
``````````
</details>
https://github.com/llvm/llvm-project/pull/174197
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits