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;
288 rotateTokens(SourceMgr, Fixes, Tok, LastSimpleTypeSpecifier,
290 return LastSimpleTypeSpecifier;
304 if (TypeToken->
is(tok::kw_typename))
309 if (TypeToken->
is(tok::coloncolon)) {
312 if (TypeToken && TypeToken->
is(tok::kw_template))
321 if (TypeToken->
isOneOf(tok::kw_struct, tok::kw_class))
324 if (TypeToken->
isOneOf(tok::kw_auto, tok::identifier)) {
337 (Next->is(TT_TemplateOpener) ||
338 Next->startsSequence(tok::coloncolon, tok::identifier) ||
339 Next->startsSequence(tok::coloncolon, tok::kw_template,
341 if (Next->is(TT_TemplateOpener)) {
342 assert(Next->MatchingParen &&
"Missing template closer");
343 TypeToken = Next->MatchingParen;
344 }
else if (Next->startsSequence(tok::coloncolon, tok::identifier)) {
345 TypeToken = Next->getNextNonComment();
347 TypeToken = Next->getNextNonComment()->getNextNonComment();
351 if (Next->is(tok::kw_auto))
375 if (Tok->
isNot(QualifierType))
394 ConfiguredQualifierTokens)) {
398 if (FirstQual != Tok)
414 const FormatToken *LastSimpleTypeSpecifier = TypeToken;
417 ConfiguredQualifierTokens,
LangOpts)) {
418 LastSimpleTypeSpecifier =
422 rotateTokens(SourceMgr, Fixes, LastSimpleTypeSpecifier, Tok,
427 if (TypeToken->
isOneOf(tok::kw_auto, tok::identifier, TT_TemplateCloser)) {
428 const auto IsStartOfType = [](
const FormatToken *
const Tok) ->
bool {
434 if (Tok->
is(TT_TemplateCloser))
443 if (Tok->
is(tok::identifier) &&
Previous->is(tok::coloncolon))
449 if (Tok->
is(tok::identifier) &&
Previous->is(tok::kw_template) &&
450 PrePrevious && PrePrevious->
is(tok::coloncolon)) {
460 while (!IsStartOfType(TypeToken)) {
462 if (TypeToken->
is(TT_TemplateCloser)) {
463 assert(TypeToken->
MatchingParen &&
"Missing template opener");
481 PreColonColon->
isOneOf(TT_TemplateCloser, tok::identifier)) {
482 TypeToken = PreColonColon;
484 TypeToken = ColonColon;
489 assert(TypeToken &&
"Should be auto or identifier");
513 const std::string &Qualifier) {
515 return llvm::StringSwitch<tok::TokenKind>(Qualifier)
516 .Case(
"type", tok::kw_typeof)
517 .Case(
"const", tok::kw_const)
518 .Case(
"volatile", tok::kw_volatile)
519 .Case(
"static", tok::kw_static)
520 .Case(
"inline", tok::kw_inline)
521 .Case(
"constexpr", tok::kw_constexpr)
522 .Case(
"restrict", tok::kw_restrict)
523 .Case(
"friend", tok::kw_friend)
524 .Default(tok::identifier);
529 const std::string &Qualifier,
530 const std::vector<tok::TokenKind> &QualifierTokens,
bool RightAlign)
532 ConfiguredQualifierTokens(QualifierTokens) {}
534std::pair<tooling::Replacements, unsigned>
551 assert(QualifierToken != tok::identifier &&
"Unrecognised Qualifier");
555 if (!
Line->Affected ||
Line->InPPDirective)
559 if (
First->Finalized)
564 for (
const auto *Tok =
First; Tok && Tok !=
Last && Tok->Next;
566 if (Tok->MustBreakBefore)
568 if (Tok->is(tok::comment))
571 Tok =
analyzeRight(SourceMgr, Keywords, Fixes, Tok, Qualifier,
574 Tok =
analyzeLeft(SourceMgr, Keywords, Fixes, Tok, Qualifier,
582 const std::vector<std::string> &Order, std::vector<std::string> &LeftOrder,
583 std::vector<std::string> &RightOrder,
590 assert(llvm::is_contained(Order,
"type") &&
591 "QualifierOrder must contain type");
595 for (
const auto &
s : Order) {
603 if (QualifierToken != tok::kw_typeof && QualifierToken != tok::identifier)
608 LeftOrder.insert(LeftOrder.begin(),
s);
610 RightOrder.push_back(
s);
616 return Tok && (Tok->
isTypeName(LangOpts) || Tok->
is(tok::kw_auto) ||
621 const std::vector<tok::TokenKind> &
Qualifiers,
623 return Tok && (Tok->
isTypeName(LangOpts) || Tok->
is(tok::kw_auto) ||
632 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)
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.