17#include "llvm/Support/Debug.h"
18#include "llvm/Support/Regex.h"
20#define DEBUG_TYPE "format-qualifier-alignment-fixer"
27 std::vector<std::string> LeftOrder;
28 std::vector<std::string> RightOrder;
29 std::vector<tok::TokenKind> ConfiguredQualifierTokens;
31 Style.
QualifierOrder, LeftOrder, RightOrder, ConfiguredQualifierTokens);
34 for (
const auto &Qualifier : LeftOrder) {
36 [&, Qualifier, ConfiguredQualifierTokens](
const Environment &
Env) {
38 ConfiguredQualifierTokens,
43 for (
const auto &Qualifier : RightOrder) {
45 [&, Qualifier, ConfiguredQualifierTokens](
const Environment &
Env) {
47 ConfiguredQualifierTokens,
58 auto Err = Fixes.
add(Replacement);
61 llvm::errs() <<
"Error while rearranging Qualifier : "
62 << llvm::toString(std::move(Err)) <<
"\n";
70 First->Tok.getEndLoc());
77 const std::string &Qualifier) {
79 First->Tok.getEndLoc());
81 std::string NewText{};
82 NewText +=
First->TokenText;
83 NewText +=
" " + Qualifier;
90 const std::string &Qualifier) {
92 First->Tok.getEndLoc());
94 std::string NewText =
" " + Qualifier +
" ";
95 NewText +=
First->TokenText;
103 return isspace(
s.back());
109 return isspace(
s.front());
125 NewText +=
Last->TokenText;
133 Tok->isNot(tok::coloncolon)) {
137 NewText += Tok->TokenText;
145 NewText +=
First->TokenText;
149 Last->Tok.getEndLoc());
156 const std::vector<tok::TokenKind> &
Qualifiers) {
166 case tok::kw_volatile:
169 case tok::kw_constexpr:
170 case tok::kw_restrict:
183 if (Tok->
isNot(QualifierType))
196 const bool IsRightQualifier = PreviousCheck && [PreviousCheck]() {
203 if (PreviousCheck->
is(tok::r_paren))
209 if (PreviousCheck->
is(tok::r_brace))
230 if (PreviousCheck->
is(TT_TemplateCloser)) {
241 if (PreviousCheck->
isOneOf(TT_PointerOrReference, tok::identifier,
256 if (IsRightQualifier) {
278 if (TypeToken->
isOneOf(tok::kw_decltype, tok::kw_typeof, tok::kw__Atomic))
281 const FormatToken *LastSimpleTypeSpecifier = TypeToken;
287 rotateTokens(SourceMgr, Fixes, Tok, LastSimpleTypeSpecifier,
289 return LastSimpleTypeSpecifier;
303 if (TypeToken->
is(tok::kw_typename))
308 if (TypeToken->
is(tok::coloncolon)) {
311 if (TypeToken && TypeToken->
is(tok::kw_template))
320 if (TypeToken->
isOneOf(tok::kw_struct, tok::kw_class))
323 if (TypeToken->
isOneOf(tok::kw_auto, tok::identifier)) {
336 (Next->is(TT_TemplateOpener) ||
337 Next->startsSequence(tok::coloncolon, tok::identifier) ||
338 Next->startsSequence(tok::coloncolon, tok::kw_template,
340 if (Next->is(TT_TemplateOpener)) {
341 assert(Next->MatchingParen &&
"Missing template closer");
342 TypeToken = Next->MatchingParen;
343 }
else if (Next->startsSequence(tok::coloncolon, tok::identifier)) {
344 TypeToken = Next->getNextNonComment();
346 TypeToken = Next->getNextNonComment()->getNextNonComment();
350 if (Next && Next->is(tok::kw_auto))
374 if (Tok->
isNot(QualifierType))
389 TypeToken->
is(tok::r_square)) {
394 ConfiguredQualifierTokens)) {
398 if (FirstQual != Tok)
414 for (
const auto *Prev = TypeToken->
Previous;
415 Prev && Prev->
is(tok::coloncolon); Prev = Prev->Previous) {
418 if (!(Prev && Prev->is(tok::identifier)))
422 const FormatToken *LastSimpleTypeSpecifier = TypeToken;
425 ConfiguredQualifierTokens,
LangOpts)) {
426 LastSimpleTypeSpecifier =
430 rotateTokens(SourceMgr, Fixes, LastSimpleTypeSpecifier, Tok,
435 if (TypeToken->
isOneOf(tok::kw_auto, tok::identifier, TT_TemplateCloser)) {
436 const auto IsStartOfType = [](
const FormatToken *
const Tok) ->
bool {
442 if (Tok->
is(TT_TemplateCloser))
451 if (Tok->
is(tok::identifier) &&
Previous->is(tok::coloncolon))
457 if (Tok->
is(tok::identifier) &&
Previous->is(tok::kw_template) &&
458 PrePrevious && PrePrevious->
is(tok::coloncolon)) {
468 while (!IsStartOfType(TypeToken)) {
470 if (TypeToken->
is(TT_TemplateCloser)) {
471 assert(TypeToken->
MatchingParen &&
"Missing template opener");
489 PreColonColon->
isOneOf(TT_TemplateCloser, tok::identifier)) {
490 TypeToken = PreColonColon;
492 TypeToken = ColonColon;
497 assert(TypeToken &&
"Should be auto or identifier");
521 const std::string &Qualifier) {
523 return llvm::StringSwitch<tok::TokenKind>(Qualifier)
524 .Case(
"type", tok::kw_typeof)
525 .Case(
"const", tok::kw_const)
526 .Case(
"volatile", tok::kw_volatile)
527 .Case(
"static", tok::kw_static)
528 .Case(
"inline", tok::kw_inline)
529 .Case(
"constexpr", tok::kw_constexpr)
530 .Case(
"restrict", tok::kw_restrict)
531 .Case(
"friend", tok::kw_friend)
532 .Default(tok::identifier);
537 const std::string &Qualifier,
538 const std::vector<tok::TokenKind> &QualifierTokens,
bool RightAlign)
540 ConfiguredQualifierTokens(QualifierTokens) {}
542std::pair<tooling::Replacements, unsigned>
559 assert(QualifierToken != tok::identifier &&
"Unrecognised Qualifier");
563 if (!
Line->Affected ||
Line->InPPDirective)
567 if (
First->Finalized)
572 for (
const auto *Tok =
First; Tok && Tok !=
Last && Tok->Next;
574 if (Tok->MustBreakBefore)
576 if (Tok->is(tok::comment))
579 Tok =
analyzeRight(SourceMgr, Keywords, Fixes, Tok, Qualifier,
582 Tok =
analyzeLeft(SourceMgr, Keywords, Fixes, Tok, Qualifier,
590 const std::vector<std::string> &Order, std::vector<std::string> &LeftOrder,
591 std::vector<std::string> &RightOrder,
598 assert(llvm::is_contained(Order,
"type") &&
599 "QualifierOrder must contain type");
603 for (
const auto &
s : Order) {
611 if (QualifierToken != tok::kw_typeof && QualifierToken != tok::identifier)
616 LeftOrder.insert(LeftOrder.begin(),
s);
618 RightOrder.push_back(
s);
624 return Tok && (Tok->
isTypeName(LangOpts) || Tok->
is(tok::kw_auto) ||
629 const std::vector<tok::TokenKind> &
Qualifiers,
631 return Tok && (Tok->
isTypeName(LangOpts) || Tok->
is(tok::kw_auto) ||
639 if (Tok->
isNot(tok::identifier))
643 assert(!
Text.empty());
646 if (
Text.size() == 1)
651 if (Prev && Prev->is(tok::coloncolon))
654 if (Next && Next->is(tok::coloncolon))
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)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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.
The JSON file list parser is used to communicate input to InstallAPI.