21
21
#include " clang/AST/ExprCXX.h"
22
22
#include " clang/AST/PrettyPrinter.h"
23
23
#include " clang/Basic/Module.h"
24
+ #include " clang/Basic/SourceManager.h"
24
25
#include " llvm/Support/raw_ostream.h"
25
26
using namespace clang ;
26
27
@@ -49,18 +50,6 @@ namespace {
49
50
50
51
void PrintObjCTypeParams (ObjCTypeParamList *Params);
51
52
52
- enum class AttrPrintLoc {
53
- None = 0 ,
54
- Left = 1 ,
55
- Right = 2 ,
56
- Any = Left | Right,
57
-
58
- LLVM_MARK_AS_BITMASK_ENUM (/* DefaultValue=*/ Any)
59
- };
60
-
61
- void prettyPrintAttributes (Decl *D, raw_ostream &out,
62
- AttrPrintLoc loc = AttrPrintLoc::Any);
63
-
64
53
public:
65
54
DeclPrinter (raw_ostream &Out, const PrintingPolicy &Policy,
66
55
const ASTContext &Context, unsigned Indentation = 0 ,
@@ -129,11 +118,10 @@ namespace {
129
118
const TemplateParameterList *Params);
130
119
void printTemplateArguments (llvm::ArrayRef<TemplateArgumentLoc> Args,
131
120
const TemplateParameterList *Params);
132
-
133
- inline void prettyPrintAttributes (Decl *D) {
134
- prettyPrintAttributes (D, Out);
135
- }
136
-
121
+ enum class AttrPosAsWritten { Default = 0 , Left, Right };
122
+ void
123
+ prettyPrintAttributes (const Decl *D,
124
+ AttrPosAsWritten Pos = AttrPosAsWritten::Default);
137
125
void prettyPrintPragmas (Decl *D);
138
126
void printDeclType (QualType T, StringRef DeclName, bool Pack = false );
139
127
};
@@ -250,87 +238,48 @@ raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
250
238
return Out;
251
239
}
252
240
253
- // For CLANG_ATTR_LIST_CanPrintOnLeft macro.
254
- #include " clang/Basic/AttrLeftSideCanPrintList.inc"
241
+ static DeclPrinter::AttrPosAsWritten getPosAsWritten (const Attr *A,
242
+ const Decl *D) {
243
+ SourceLocation ALoc = A->getLoc ();
244
+ SourceLocation DLoc = D->getLocation ();
245
+ const ASTContext &C = D->getASTContext ();
246
+ if (ALoc.isInvalid () || DLoc.isInvalid ())
247
+ return DeclPrinter::AttrPosAsWritten::Left;
255
248
256
- // For CLANG_ATTR_LIST_PrintOnLeft macro.
257
- # include " clang/Basic/AttrLeftSideMustPrintList.inc "
249
+ if (C. getSourceManager (). isBeforeInTranslationUnit (ALoc, DLoc))
250
+ return DeclPrinter::AttrPosAsWritten::Left;
258
251
259
- static bool canPrintOnLeftSide (attr::Kind kind) {
260
- #ifdef CLANG_ATTR_LIST_CanPrintOnLeft
261
- switch (kind) {
262
- CLANG_ATTR_LIST_CanPrintOnLeft
263
- return true ;
264
- default :
265
- return false ;
266
- }
267
- #else
268
- return false ;
269
- #endif
270
- }
271
-
272
- static bool canPrintOnLeftSide (const Attr *A) {
273
- if (A->isStandardAttributeSyntax ())
274
- return false ;
275
-
276
- return canPrintOnLeftSide (A->getKind ());
252
+ return DeclPrinter::AttrPosAsWritten::Right;
277
253
}
278
254
279
- static bool mustPrintOnLeftSide (attr::Kind kind) {
280
- #ifdef CLANG_ATTR_LIST_PrintOnLeft
281
- switch (kind) {
282
- CLANG_ATTR_LIST_PrintOnLeft
283
- return true ;
284
- default :
285
- return false ;
286
- }
287
- #else
288
- return false ;
289
- #endif
290
- }
291
-
292
- static bool mustPrintOnLeftSide (const Attr *A) {
293
- if (A->isDeclspecAttribute ())
294
- return true ;
295
-
296
- return mustPrintOnLeftSide (A->getKind ());
297
- }
298
-
299
- void DeclPrinter::prettyPrintAttributes (Decl *D, llvm::raw_ostream &Out,
300
- AttrPrintLoc Loc) {
255
+ void DeclPrinter::prettyPrintAttributes (const Decl *D,
256
+ AttrPosAsWritten Pos /* =Default*/ ) {
301
257
if (Policy.PolishForDeclaration )
302
258
return ;
303
259
304
260
if (D->hasAttrs ()) {
305
- AttrVec &Attrs = D->getAttrs ();
261
+ const AttrVec &Attrs = D->getAttrs ();
306
262
for (auto *A : Attrs) {
307
263
if (A->isInherited () || A->isImplicit ())
308
264
continue ;
309
-
310
- AttrPrintLoc AttrLoc = AttrPrintLoc::Right;
311
- if (mustPrintOnLeftSide (A)) {
312
- // If we must always print on left side (e.g. declspec), then mark as
313
- // so.
314
- AttrLoc = AttrPrintLoc::Left;
315
- } else if (canPrintOnLeftSide (A)) {
316
- // For functions with body defined we print the attributes on the left
317
- // side so that GCC accept our dumps as well.
318
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
319
- FD && FD->isThisDeclarationADefinition ())
320
- // In case Decl is a function with a body, then attrs should be print
321
- // on the left side.
322
- AttrLoc = AttrPrintLoc::Left;
323
-
324
- // In case it is a variable declaration with a ctor, then allow
325
- // printing on the left side for readbility.
326
- else if (const VarDecl *VD = dyn_cast<VarDecl>(D);
327
- VD && VD->getInit () &&
328
- VD->getInitStyle () == VarDecl::CallInit)
329
- AttrLoc = AttrPrintLoc::Left;
265
+ switch (A->getKind ()) {
266
+ #define ATTR (X )
267
+ #define PRAGMA_SPELLING_ATTR (X ) case attr::X:
268
+ #include " clang/Basic/AttrList.inc"
269
+ break ;
270
+ default :
271
+ AttrPosAsWritten APos = getPosAsWritten (A, D);
272
+ assert (APos != AttrPosAsWritten::Default &&
273
+ " Default not a valid for an attribute location" );
274
+ if (Pos == AttrPosAsWritten::Default || Pos == APos) {
275
+ if (Pos != AttrPosAsWritten::Left)
276
+ Out << ' ' ;
277
+ A->printPretty (Out, Policy);
278
+ if (Pos == AttrPosAsWritten::Left)
279
+ Out << ' ' ;
280
+ }
281
+ break ;
330
282
}
331
- // Only print the side matches the user requested.
332
- if ((Loc & AttrLoc) != AttrPrintLoc::None)
333
- A->printPretty (Out, Policy);
334
283
}
335
284
}
336
285
}
@@ -691,8 +640,10 @@ static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy,
691
640
692
641
void DeclPrinter::VisitFunctionDecl (FunctionDecl *D) {
693
642
if (!D->getDescribedFunctionTemplate () &&
694
- !D->isFunctionTemplateSpecialization ())
643
+ !D->isFunctionTemplateSpecialization ()) {
695
644
prettyPrintPragmas (D);
645
+ prettyPrintAttributes (D, AttrPosAsWritten::Left);
646
+ }
696
647
697
648
if (D->isFunctionTemplateSpecialization ())
698
649
Out << " template<> " ;
@@ -702,22 +653,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
702
653
printTemplateParameters (D->getTemplateParameterList (I));
703
654
}
704
655
705
- std::string LeftsideAttrs;
706
- llvm::raw_string_ostream LSAS (LeftsideAttrs);
707
-
708
- prettyPrintAttributes (D, LSAS, AttrPrintLoc::Left);
709
-
710
- // prettyPrintAttributes print a space on left side of the attribute.
711
- if (LeftsideAttrs[0 ] == ' ' ) {
712
- // Skip the space prettyPrintAttributes generated.
713
- LeftsideAttrs.erase (0 , LeftsideAttrs.find_first_not_of (' ' ));
714
-
715
- // Add a single space between the attribute and the Decl name.
716
- LSAS << ' ' ;
717
- }
718
-
719
- Out << LeftsideAttrs;
720
-
721
656
CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
722
657
CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
723
658
CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
@@ -883,7 +818,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
883
818
Ty.print (Out, Policy, Proto);
884
819
}
885
820
886
- prettyPrintAttributes (D, Out, AttrPrintLoc ::Right);
821
+ prettyPrintAttributes (D, AttrPosAsWritten ::Right);
887
822
888
823
if (D->isPureVirtual ())
889
824
Out << " = 0" ;
@@ -976,27 +911,12 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
976
911
void DeclPrinter::VisitVarDecl (VarDecl *D) {
977
912
prettyPrintPragmas (D);
978
913
914
+ prettyPrintAttributes (D, AttrPosAsWritten::Left);
915
+
979
916
if (const auto *Param = dyn_cast<ParmVarDecl>(D);
980
917
Param && Param->isExplicitObjectParameter ())
981
918
Out << " this " ;
982
919
983
- std::string LeftSide;
984
- llvm::raw_string_ostream LeftSideStream (LeftSide);
985
-
986
- // Print attributes that should be placed on the left, such as __declspec.
987
- prettyPrintAttributes (D, LeftSideStream, AttrPrintLoc::Left);
988
-
989
- // prettyPrintAttributes print a space on left side of the attribute.
990
- if (LeftSide[0 ] == ' ' ) {
991
- // Skip the space prettyPrintAttributes generated.
992
- LeftSide.erase (0 , LeftSide.find_first_not_of (' ' ));
993
-
994
- // Add a single space between the attribute and the Decl name.
995
- LeftSideStream << ' ' ;
996
- }
997
-
998
- Out << LeftSide;
999
-
1000
920
QualType T = D->getTypeSourceInfo ()
1001
921
? D->getTypeSourceInfo ()->getType ()
1002
922
: D->getASTContext ().getUnqualifiedObjCPointerType (D->getType ());
@@ -1029,21 +949,16 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) {
1029
949
}
1030
950
}
1031
951
1032
- StringRef Name;
1033
-
1034
- Name = (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
1035
- D->getIdentifier ())
1036
- ? D->getIdentifier ()->deuglifiedName ()
1037
- : D->getName ();
1038
-
1039
952
if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
1040
953
!Policy.SuppressUnwrittenScope )
1041
954
MaybePrintTagKeywordIfSupressingScopes (Policy, T, Out);
1042
- printDeclType (T, Name);
1043
955
1044
- // Print the attributes that should be placed right before the end of the
1045
- // decl.
1046
- prettyPrintAttributes (D, Out, AttrPrintLoc::Right);
956
+ printDeclType (T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
957
+ D->getIdentifier ())
958
+ ? D->getIdentifier ()->deuglifiedName ()
959
+ : D->getName ());
960
+
961
+ prettyPrintAttributes (D, AttrPosAsWritten::Right);
1047
962
1048
963
Expr *Init = D->getInit ();
1049
964
if (!Policy.SuppressInitializers && Init) {
0 commit comments