[clang] Rework the printing of attributes (PR #87281)

Vassil Vassilev via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 2 07:51:01 PDT 2024


================
@@ -250,87 +241,43 @@ raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
   return Out;
 }
 
-// For CLANG_ATTR_LIST_CanPrintOnLeft macro.
-#include "clang/Basic/AttrLeftSideCanPrintList.inc"
-
-// For CLANG_ATTR_LIST_PrintOnLeft macro.
-#include "clang/Basic/AttrLeftSideMustPrintList.inc"
-
-static bool canPrintOnLeftSide(attr::Kind kind) {
-#ifdef CLANG_ATTR_LIST_CanPrintOnLeft
-  switch (kind) {
-  CLANG_ATTR_LIST_CanPrintOnLeft
-    return true;
-  default:
-    return false;
-  }
-#else
-  return false;
-#endif
-}
-
-static bool canPrintOnLeftSide(const Attr *A) {
-  if (A->isStandardAttributeSyntax())
-    return false;
+static DeclPrinter::AttrPosAsWritten getAttrPosAsWritten(const Attr *A,
+                                                         const Decl *D) {
+  SourceLocation ALoc = A->getLoc();
+  SourceLocation DLoc = D->getLocation();
+  const ASTContext &C = D->getASTContext();
+  if (ALoc.isInvalid() || DLoc.isInvalid())
+    return DeclPrinter::AttrPosAsWritten::Unknown;
 
-  return canPrintOnLeftSide(A->getKind());
-}
+  if (C.getSourceManager().isBeforeInTranslationUnit(ALoc, DLoc))
+    return DeclPrinter::AttrPosAsWritten::Left;
 
-static bool mustPrintOnLeftSide(attr::Kind kind) {
-#ifdef CLANG_ATTR_LIST_PrintOnLeft
-  switch (kind) {
-  CLANG_ATTR_LIST_PrintOnLeft
-    return true;
-  default:
-    return false;
-  }
-#else
-  return false;
-#endif
+  return DeclPrinter::AttrPosAsWritten::Right;
 }
 
-static bool mustPrintOnLeftSide(const Attr *A) {
-  if (A->isDeclspecAttribute())
-    return true;
-
-  return mustPrintOnLeftSide(A->getKind());
-}
-
-void DeclPrinter::prettyPrintAttributes(Decl *D, llvm::raw_ostream &Out,
-                                        AttrPrintLoc Loc) {
+void DeclPrinter::prettyPrintAttributes(const Decl *D,
+                                        AttrPosAsWritten P /*=Unknown*/) {
   if (Policy.PolishForDeclaration)
     return;
 
   if (D->hasAttrs()) {
-    AttrVec &Attrs = D->getAttrs();
+    const AttrVec &Attrs = D->getAttrs();
     for (auto *A : Attrs) {
       if (A->isInherited() || A->isImplicit())
         continue;
-
-      AttrPrintLoc AttrLoc = AttrPrintLoc::Right;
-      if (mustPrintOnLeftSide(A)) {
-        // If we must always print on left side (e.g. declspec), then mark as
-        // so.
-        AttrLoc = AttrPrintLoc::Left;
-      } else if (canPrintOnLeftSide(A)) {
-        // For functions with body defined we print the attributes on the left
-        // side so that GCC accept our dumps as well.
-        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-            FD && FD->isThisDeclarationADefinition())
-          // In case Decl is a function with a body, then attrs should be print
-          // on the left side.
-          AttrLoc = AttrPrintLoc::Left;
-
-          // In case it is a variable declaration with a ctor, then allow
-          // printing on the left side for readbility.
-        else if (const VarDecl *VD = dyn_cast<VarDecl>(D);
-                   VD && VD->getInit() &&
-                   VD->getInitStyle() == VarDecl::CallInit)
-          AttrLoc = AttrPrintLoc::Left;
+      switch (A->getKind()) {
+#define ATTR(X)
+#define PRAGMA_SPELLING_ATTR(X) case attr::X:
+#include "clang/Basic/AttrList.inc"
+        break;
+      default:
+        if (P == AttrPosAsWritten::Unknown || P == getAttrPosAsWritten(A, D)) {
----------------
vgvassilev wrote:

If the mode is "Unknown" that means we want the "regular/old" behavior where we don't have a left/right preference. I realize that's probably not the best terminology I use but let me know if you have better ideas.


https://github.com/llvm/llvm-project/pull/87281


More information about the cfe-commits mailing list