17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/Regex.h"
22 #define DEBUG_TYPE "format-qualifier-alignment-fixer"
30 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef FileName)
32 FirstStartColumn(FirstStartColumn), NextStartColumn(NextStartColumn),
33 LastStartColumn(LastStartColumn), FileName(FileName) {
34 std::vector<std::string> LeftOrder;
35 std::vector<std::string> RightOrder;
36 std::vector<tok::TokenKind> ConfiguredQualifierTokens;
38 ConfiguredQualifierTokens);
41 for (
const auto &Qualifier : LeftOrder) {
43 [&, Qualifier, ConfiguredQualifierTokens](
const Environment &
Env) {
45 ConfiguredQualifierTokens,
50 for (
const auto &Qualifier : RightOrder) {
52 [&, Qualifier, ConfiguredQualifierTokens](
const Environment &
Env) {
54 ConfiguredQualifierTokens,
66 NextStartColumn, LastStartColumn);
71 for (
size_t I = 0, E = Passes.size(); I < E; ++I) {
72 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
74 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
76 Fixes = Fixes.
merge(PassFixes.first);
78 CurrentCode = std::move(*NewCode);
80 *CurrentCode, FileName,
82 FirstStartColumn, NextStartColumn, LastStartColumn);
93 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());
95 if (!OriginalCode.equals(Fix.getReplacementText())) {
96 auto Err = NonNoOpFixes.
add(Fix);
98 llvm::errs() <<
"Error adding replacements : "
103 return {NonNoOpFixes, 0};
110 auto Err = Fixes.
add(Replacement);
113 llvm::errs() <<
"Error while rearranging Qualifier : "
122 First->Tok.getEndLoc());
134 Next->Tok.getEndLoc());
137 NewText += Next->TokenText;
146 First->Tok.getEndLoc());
149 NewText +=
First->TokenText;
157 return isspace(
s.back());
163 return isspace(
s.front());
179 NewText +=
Last->TokenText;
189 NewText += Tok->TokenText;
197 NewText +=
First->TokenText;
201 Last->Tok.getEndLoc());
211 if (!Tok->
is(QualifierType))
225 if (LastQual && Qual != LastQual) {
229 TT_TemplateCloser)) {
235 TT_TemplateOpener)) {
242 if (EndTemplate->
startsSequence(TT_TemplateCloser, tok::coloncolon,
244 EndTemplate = EndTemplate->
Next->
Next;
247 if (EndTemplate && EndTemplate->
Next &&
248 !EndTemplate->
Next->
isOneOf(tok::equal, tok::l_paren)) {
262 while (Next && Next->isOneOf(tok::identifier, tok::coloncolon))
264 if (Next && Next->is(TT_TemplateOpener)) {
265 Next = Next->MatchingParen;
268 if (Next && Next->startsSequence(TT_TemplateCloser, tok::coloncolon,
272 assert(Next &&
"Missing template opener");
275 if (Next && Next->isOneOf(tok::star, tok::amp, tok::ampamp) &&
276 !Tok->
Next->
isOneOf(Keywords.kw_override, Keywords.kw_final)) {
277 if (Next->Previous && !Next->Previous->is(QualifierType)) {
301 if (Qual && Qual->
is(QualifierType))
308 if (LastQual && Qual != LastQual && Qual->
is(QualifierType)) {
315 tok::amp, tok::ampamp)) {
323 TT_TemplateCloser)) {
329 if (Tok->
is(TT_TemplateOpener) && Tok->
Next &&
341 while (Next && Next->isOneOf(tok::identifier, tok::coloncolon))
343 if (Next && Next->Previous &&
344 Next->Previous->startsSequence(tok::identifier, TT_TemplateOpener)) {
347 if (Next->is(tok::comment) && Next->getNextNonComment())
348 Next = Next->getNextNonComment();
349 assert(Next->MatchingParen &&
"Missing template closer");
350 Next = Next->MatchingParen;
355 if (Next->ClosesRequiresClause)
356 return Next->MatchingParen;
361 if (Next && Next->startsSequence(tok::coloncolon, tok::identifier))
362 Next = Next->Next->Next;
363 if (Next && Next->is(QualifierType)) {
370 if (Next && Next->Next &&
371 Next->Next->isOneOf(tok::amp, tok::ampamp, tok::star)) {
372 if (Next->is(QualifierType)) {
386 return llvm::StringSwitch<tok::TokenKind>(Qualifier)
387 .Case(
"type", tok::kw_typeof)
388 .Case(
"const", tok::kw_const)
389 .Case(
"volatile", tok::kw_volatile)
390 .Case(
"static", tok::kw_static)
391 .Case(
"inline", tok::kw_inline)
392 .Case(
"constexpr", tok::kw_constexpr)
393 .Case(
"restrict", tok::kw_restrict)
394 .Default(tok::identifier);
400 const std::vector<tok::TokenKind> &QualifierTokens,
bool RightAlign)
401 :
TokenAnalyzer(Env, Style), Qualifier(Qualifier), RightAlign(RightAlign),
402 ConfiguredQualifierTokens(QualifierTokens) {}
404 std::pair<tooling::Replacements, unsigned>
415 assert(QualifierToken != tok::identifier &&
"Unrecognised Qualifier");
418 if (
Line->InPPDirective)
422 if (
First->Finalized)
427 for (
const auto *Tok =
First; Tok && Tok !=
Last && Tok->Next;
429 if (Tok->is(tok::comment))
432 Tok =
analyzeRight(SourceMgr, Keywords, Fixes, Tok, Qualifier,
435 Tok =
analyzeLeft(SourceMgr, Keywords, Fixes, Tok, Qualifier,
444 const std::vector<std::string> &Order, std::vector<std::string> &LeftOrder,
445 std::vector<std::string> &RightOrder,
452 assert(llvm::is_contained(Order,
"type") &&
453 "QualifierOrder must contain type");
457 for (
const auto &
s : Order) {
465 if (QualifierToken != tok::kw_typeof && QualifierToken != tok::identifier)
470 LeftOrder.insert(LeftOrder.begin(),
s);
472 RightOrder.push_back(
s);
478 const FormatToken *Tok,
const std::vector<tok::TokenKind> &specifiedTypes) {
480 llvm::is_contained(specifiedTypes, Tok->
Tok.
getKind()));
488 if (!Tok->
is(tok::identifier))