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 { Unknown = 0 , Default, 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,53 @@ 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::Unknown;
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
+ assert (Pos != AttrPosAsWritten::Unknown && " Use Default" );
262
+ const AttrVec &Attrs = D->getAttrs ();
306
263
for (auto *A : Attrs) {
307
264
if (A->isInherited () || A->isImplicit ())
308
265
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 ;
266
+ switch (A-> getKind ()) {
267
+ # define ATTR ( X )
268
+ # define PRAGMA_SPELLING_ATTR ( X ) case attr::X:
269
+ # include " clang/Basic/AttrList.inc "
270
+ break ;
271
+ default :
272
+ AttrPosAsWritten APos = getPosAsWritten (A, D);
273
+ // Might trigger on programatically created attributes or declarations
274
+ // with no source locations .
275
+ assert (APos != AttrPosAsWritten::Unknown &&
276
+ " Invalid source location for attribute or decl. " );
277
+ assert (APos != AttrPosAsWritten::Default &&
278
+ " Default not a valid for an attribute location " );
279
+ if (Pos == AttrPosAsWritten::Default || Pos == APos) {
280
+ if (Pos != AttrPosAsWritten::Left)
281
+ Out << ' ' ;
282
+ A-> printPretty (Out, Policy);
283
+ if (Pos == AttrPosAsWritten::Left)
284
+ Out << ' ' ;
285
+ }
286
+ break ;
330
287
}
331
- // Only print the side matches the user requested.
332
- if ((Loc & AttrLoc) != AttrPrintLoc::None)
333
- A->printPretty (Out, Policy);
334
288
}
335
289
}
336
290
}
@@ -691,8 +645,10 @@ static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy,
691
645
692
646
void DeclPrinter::VisitFunctionDecl (FunctionDecl *D) {
693
647
if (!D->getDescribedFunctionTemplate () &&
694
- !D->isFunctionTemplateSpecialization ())
648
+ !D->isFunctionTemplateSpecialization ()) {
695
649
prettyPrintPragmas (D);
650
+ prettyPrintAttributes (D, AttrPosAsWritten::Left);
651
+ }
696
652
697
653
if (D->isFunctionTemplateSpecialization ())
698
654
Out << " template<> " ;
@@ -702,22 +658,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
702
658
printTemplateParameters (D->getTemplateParameterList (I));
703
659
}
704
660
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
661
CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
722
662
CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
723
663
CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
@@ -883,7 +823,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
883
823
Ty.print (Out, Policy, Proto);
884
824
}
885
825
886
- prettyPrintAttributes (D, Out, AttrPrintLoc ::Right);
826
+ prettyPrintAttributes (D, AttrPosAsWritten ::Right);
887
827
888
828
if (D->isPureVirtual ())
889
829
Out << " = 0" ;
@@ -976,27 +916,12 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
976
916
void DeclPrinter::VisitVarDecl (VarDecl *D) {
977
917
prettyPrintPragmas (D);
978
918
919
+ prettyPrintAttributes (D, AttrPosAsWritten::Left);
920
+
979
921
if (const auto *Param = dyn_cast<ParmVarDecl>(D);
980
922
Param && Param->isExplicitObjectParameter ())
981
923
Out << " this " ;
982
924
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
925
QualType T = D->getTypeSourceInfo ()
1001
926
? D->getTypeSourceInfo ()->getType ()
1002
927
: D->getASTContext ().getUnqualifiedObjCPointerType (D->getType ());
@@ -1029,21 +954,16 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) {
1029
954
}
1030
955
}
1031
956
1032
- StringRef Name;
1033
-
1034
- Name = (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
1035
- D->getIdentifier ())
1036
- ? D->getIdentifier ()->deuglifiedName ()
1037
- : D->getName ();
1038
-
1039
957
if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
1040
958
!Policy.SuppressUnwrittenScope )
1041
959
MaybePrintTagKeywordIfSupressingScopes (Policy, T, Out);
1042
- printDeclType (T, Name);
1043
960
1044
- // Print the attributes that should be placed right before the end of the
1045
- // decl.
1046
- prettyPrintAttributes (D, Out, AttrPrintLoc::Right);
961
+ printDeclType (T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
962
+ D->getIdentifier ())
963
+ ? D->getIdentifier ()->deuglifiedName ()
964
+ : D->getName ());
965
+
966
+ prettyPrintAttributes (D, AttrPosAsWritten::Right);
1047
967
1048
968
Expr *Init = D->getInit ();
1049
969
if (!Policy.SuppressInitializers && Init) {
0 commit comments