17#include "llvm/Support/Debug.h"
18#include "llvm/Support/Regex.h"
23#define DEBUG_TYPE "format-qualifier-alignment-fixer"
30 std::vector<std::string> LeftOrder;
31 std::vector<std::string> RightOrder;
32 std::vector<tok::TokenKind> ConfiguredQualifierTokens;
34 Style.
QualifierOrder, LeftOrder, RightOrder, ConfiguredQualifierTokens);
37 for (
const auto &Qualifier : LeftOrder) {
39 [&, Qualifier, ConfiguredQualifierTokens](
const Environment &
Env) {
41 ConfiguredQualifierTokens,
46 for (
const auto &Qualifier : RightOrder) {
48 [&, Qualifier, ConfiguredQualifierTokens](
const Environment &
Env) {
50 ConfiguredQualifierTokens,
61 auto Err = Fixes.
add(Replacement);
64 llvm::errs() <<
"Error while rearranging Qualifier : "
65 << llvm::toString(std::move(Err)) <<
"\n";
73 First->Tok.getEndLoc());
80 const std::string &Qualifier) {
82 First->Tok.getEndLoc());
84 std::string NewText{};
85 NewText +=
First->TokenText;
86 NewText +=
" " + Qualifier;
93 const std::string &Qualifier) {
95 First->Tok.getEndLoc());
97 std::string NewText =
" " + Qualifier +
" ";
98 NewText +=
First->TokenText;
106 return isspace(
s.back());
112 return isspace(
s.front());
128 NewText +=
Last->TokenText;
138 NewText += Tok->TokenText;
146 NewText +=
First->TokenText;
150 Last->Tok.getEndLoc());
157 const std::vector<tok::TokenKind> &
Qualifiers) {
167 case tok::kw_volatile:
170 case tok::kw_constexpr:
171 case tok::kw_restrict:
184 if (Tok->
isNot(QualifierType))
197 const bool IsRightQualifier = PreviousCheck && [PreviousCheck]() {
204 if (PreviousCheck->
is(tok::r_paren))
210 if (PreviousCheck->
is(tok::r_brace))
231 if (PreviousCheck->
is(TT_TemplateCloser)) {
242 if (PreviousCheck->
isOneOf(TT_PointerOrReference, tok::identifier,
257 if (IsRightQualifier) {
279 if (TypeToken->
isOneOf(tok::kw_decltype, tok::kw_typeof, tok::kw__Atomic))
282 const FormatToken *LastSimpleTypeSpecifier = TypeToken;
286 rotateTokens(SourceMgr, Fixes, Tok, LastSimpleTypeSpecifier,
288 return LastSimpleTypeSpecifier;
302 if (TypeToken->
is(tok::kw_typename))
307 if (TypeToken->
is(tok::coloncolon)) {
310 if (TypeToken && TypeToken->
is(tok::kw_template))
319 if (TypeToken->
isOneOf(tok::kw_struct, tok::kw_class))
322 if (TypeToken->
isOneOf(tok::kw_auto, tok::identifier)) {
335 (Next->is(TT_TemplateOpener) ||
336 Next->startsSequence(tok::coloncolon, tok::identifier) ||
337 Next->startsSequence(tok::coloncolon, tok::kw_template,
339 if (Next->is(TT_TemplateOpener)) {
340 assert(Next->MatchingParen &&
"Missing template closer");
341 TypeToken = Next->MatchingParen;
342 }
else if (Next->startsSequence(tok::coloncolon, tok::identifier)) {
343 TypeToken = Next->getNextNonComment();
345 TypeToken = Next->getNextNonComment()->getNextNonComment();
370 if (Tok->
isNot(QualifierType))
383 if (!TypeToken || TypeToken->
isOneOf(tok::star, tok::amp, tok::ampamp) ||
389 ConfiguredQualifierTokens)) {
393 if (FirstQual != Tok)
409 const FormatToken *LastSimpleTypeSpecifier = TypeToken;
412 ConfiguredQualifierTokens)) {
413 LastSimpleTypeSpecifier =
417 rotateTokens(SourceMgr, Fixes, LastSimpleTypeSpecifier, Tok,
422 if (TypeToken->
isOneOf(tok::kw_auto, tok::identifier, TT_TemplateCloser)) {
423 const auto IsStartOfType = [](
const FormatToken *
const Tok) ->
bool {
429 if (Tok->
is(TT_TemplateCloser))
438 if (Tok->
is(tok::identifier) &&
Previous->is(tok::coloncolon))
444 if (Tok->
is(tok::identifier) &&
Previous->is(tok::kw_template) &&
445 PrePrevious && PrePrevious->
is(tok::coloncolon)) {
452 while (!IsStartOfType(TypeToken)) {
454 if (TypeToken->
is(TT_TemplateCloser)) {
455 assert(TypeToken->
MatchingParen &&
"Missing template opener");
473 PreColonColon->
isOneOf(TT_TemplateCloser, tok::identifier)) {
474 TypeToken = PreColonColon;
476 TypeToken = ColonColon;
481 assert(TypeToken &&
"Should be auto or identifier");
505 const std::string &Qualifier) {
507 return llvm::StringSwitch<tok::TokenKind>(Qualifier)
508 .Case(
"type", tok::kw_typeof)
509 .Case(
"const", tok::kw_const)
510 .Case(
"volatile", tok::kw_volatile)
511 .Case(
"static", tok::kw_static)
512 .Case(
"inline", tok::kw_inline)
513 .Case(
"constexpr", tok::kw_constexpr)
514 .Case(
"restrict", tok::kw_restrict)
515 .Case(
"friend", tok::kw_friend)
516 .Default(tok::identifier);
521 const std::string &Qualifier,
522 const std::vector<tok::TokenKind> &QualifierTokens,
bool RightAlign)
524 ConfiguredQualifierTokens(QualifierTokens) {}
526std::pair<tooling::Replacements, unsigned>
537 assert(QualifierToken != tok::identifier &&
"Unrecognised Qualifier");
540 if (!Line->Affected || Line->InPPDirective)
544 if (
First->Finalized)
547 const auto *
Last = Line->Last;
549 for (
const auto *Tok =
First; Tok && Tok !=
Last && Tok->Next;
551 if (Tok->is(tok::comment))
554 Tok =
analyzeRight(SourceMgr, Keywords, Fixes, Tok, Qualifier,
557 Tok =
analyzeLeft(SourceMgr, Keywords, Fixes, Tok, Qualifier,
566 const std::vector<std::string> &Order, std::vector<std::string> &LeftOrder,
567 std::vector<std::string> &RightOrder,
574 assert(llvm::is_contained(Order,
"type") &&
575 "QualifierOrder must contain type");
579 for (
const auto &
s : Order) {
587 if (QualifierToken != tok::kw_typeof && QualifierToken != tok::identifier)
592 LeftOrder.insert(LeftOrder.begin(),
s);
594 RightOrder.push_back(
s);
607 const std::vector<tok::TokenKind> &
Qualifiers) {
617 if (Tok->
isNot(tok::identifier))
This file declares QualifierAlignmentFixer, a TokenAnalyzer that enforces either east or west const d...
__device__ __2f16 float __ockl_bool s
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
The collection of all-type qualifiers we support.
This class handles loading and caching of source files into memory.
tok::TokenKind getKind() const
TokenKind
Provides a simple uniform namespace for tokens from all C languages.