//===--- QualifierAlignmentFixer.cpp ----------------------------*- C++--*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements QualifierAlignmentFixer, a TokenAnalyzer that
/// enforces either left or right const depending on the style.
///
//===----------------------------------------------------------------------===//

#include "QualifierAlignmentFixer.h"
#include "FormatToken.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Regex.h"

#define DEBUG_TYPE "format-qualifier-alignment-fixer"

namespace clang {
namespace format {

void addQualifierAlignmentFixerPasses(const FormatStyle &Style,
                                      SmallVectorImpl<AnalyzerPass> &Passes) {
  std::vector<std::string> LeftOrder;
  std::vector<std::string> RightOrder;
  std::vector<tok::TokenKind> ConfiguredQualifierTokens;
  prepareLeftRightOrderingForQualifierAlignmentFixer(
      Style.QualifierOrder, LeftOrder, RightOrder, ConfiguredQualifierTokens);

  const auto AddPass = [&](const std::string &Qualifier, bool RightAlign) {
    Passes.emplace_back([&, Qualifier, ConfiguredQualifierTokens,
                         RightAlign](const Environment &Env) {
      return LeftRightQualifierAlignmentFixer(
                 Env, Style, Qualifier, ConfiguredQualifierTokens, RightAlign)
          .process();
    });
  };

  // Handle the left and right alignment separately.
  for (const auto &Qualifier : LeftOrder) {
    AddPass(Qualifier, /*RightAlign=*/false);
    // Unlike the other declaration specifiers, `long` can legally occur twice
    // in the same sequence. A pass moves one occurrence across the type, so a
    // second pass is needed for `long long` and is otherwise a no-op.
    if (Qualifier == "long")
      AddPass(Qualifier, /*RightAlign=*/false);
  }
  for (const auto &Qualifier : RightOrder) {
    AddPass(Qualifier, /*RightAlign=*/true);
    if (Qualifier == "long")
      AddPass(Qualifier, /*RightAlign=*/true);
  }
}

static void replaceToken(const SourceManager &SourceMgr,
                         tooling::Replacements &Fixes,
                         const CharSourceRange &Range, std::string NewText) {
  auto Replacement = tooling::Replacement(SourceMgr, Range, NewText);
  auto Err = Fixes.add(Replacement);

  if (Err) {
    llvm::errs() << "Error while rearranging Qualifier : "
                 << llvm::toString(std::move(Err)) << "\n";
  }
}

static void removeToken(const SourceManager &SourceMgr,
                        tooling::Replacements &Fixes,
                        const FormatToken *First) {
  auto Range = CharSourceRange::getCharRange(First->getStartOfNonWhitespace(),
                                             First->Tok.getEndLoc());
  replaceToken(SourceMgr, Fixes, Range, "");
}

static void insertQualifierAfter(const SourceManager &SourceMgr,
                                 tooling::Replacements &Fixes,
                                 const FormatToken *First,
                                 const std::string &Qualifier) {
  auto Range = CharSourceRange::getCharRange(First->Tok.getLocation(),
                                             First->Tok.getEndLoc());

  std::string NewText{};
  NewText += First->TokenText;
  NewText += " " + Qualifier;
  replaceToken(SourceMgr, Fixes, Range, NewText);
}

static void insertQualifierBefore(const SourceManager &SourceMgr,
                                  tooling::Replacements &Fixes,
                                  const FormatToken *First,
                                  const std::string &Qualifier) {
  auto Range = CharSourceRange::getCharRange(First->getStartOfNonWhitespace(),
                                             First->Tok.getEndLoc());

  std::string NewText = " " + Qualifier + " ";
  NewText += First->TokenText;

  replaceToken(SourceMgr, Fixes, Range, NewText);
}

static bool endsWithSpace(const std::string &s) {
  if (s.empty())
    return false;
  return isspace(s.back());
}

static bool startsWithSpace(const std::string &s) {
  if (s.empty())
    return false;
  return isspace(s.front());
}

static void rotateTokens(const SourceManager &SourceMgr,
                         tooling::Replacements &Fixes, const FormatToken *First,
                         const FormatToken *Last, bool Left) {
  auto *End = Last;
  auto *Begin = First;
  if (!Left) {
    End = Last->Next;
    Begin = First->Next;
  }

  std::string NewText;
  // If we are rotating to the left we move the Last token to the front.
  if (Left) {
    NewText += Last->TokenText;
    NewText += " ";
  }

  // Then move through the other tokens.
  auto *Tok = Begin;
  while (Tok != End) {
    if (!NewText.empty() && !endsWithSpace(NewText) &&
        Tok->isNot(tok::coloncolon)) {
      NewText += " ";
    }

    NewText += Tok->TokenText;
    Tok = Tok->Next;
  }

  // If we are rotating to the right we move the first token to the back.
  if (!Left) {
    if (!NewText.empty() && !startsWithSpace(NewText))
      NewText += " ";
    NewText += First->TokenText;
  }

  auto Range = CharSourceRange::getCharRange(First->getStartOfNonWhitespace(),
                                             Last->Tok.getEndLoc());

  replaceToken(SourceMgr, Fixes, Range, NewText);
}

static bool
isConfiguredQualifier(const FormatToken *const Tok,
                      const std::vector<tok::TokenKind> &Qualifiers) {
  return Tok && llvm::is_contained(Qualifiers, Tok->Tok.getKind());
}

static bool isQualifier(const FormatToken *const Tok) {
  if (!Tok)
    return false;

  switch (Tok->Tok.getKind()) {
  case tok::kw_const:
  case tok::kw_volatile:
  case tok::kw_static:
  case tok::kw_inline:
  case tok::kw_constexpr:
  case tok::kw_restrict:
  case tok::kw_friend:
  case tok::kw__Nonnull:
  case tok::kw__Nullable:
  case tok::kw__Null_unspecified:
  case tok::kw___ptr32:
  case tok::kw___ptr64:
  case tok::kw___funcref:
  case tok::kw_typedef:
  case tok::kw_consteval:
  case tok::kw_constinit:
  case tok::kw_thread_local:
  case tok::kw_extern:
  case tok::kw_mutable:
  case tok::kw_explicit:
    return true;
  default:
    return false;
  }
}

const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
    const SourceManager &SourceMgr, const AdditionalKeywords &Keywords,
    tooling::Replacements &Fixes, const FormatToken *const Tok,
    const std::string &Qualifier, tok::TokenKind QualifierType) {
  // We only need to think about streams that begin with a qualifier.
  if (Tok->isNot(QualifierType))
    return Tok;

  const auto *Next = Tok->getNextNonComment();

  // Don't concern yourself if nothing follows the qualifier.
  if (!Next)
    return Tok;

  // Skip qualifiers to the left to find what preceeds the qualifiers.
  // Use isQualifier rather than isConfiguredQualifier to cover all qualifiers.
  const FormatToken *PreviousCheck = Tok->getPreviousNonComment();
  while (isQualifier(PreviousCheck))
    PreviousCheck = PreviousCheck->getPreviousNonComment();

  // Examples given in order of ['type', 'const', 'volatile']
  const bool IsRightQualifier = PreviousCheck && [PreviousCheck]() {
    // The cases:
    // `Foo() const` -> `Foo() const`
    // `Foo() const final` -> `Foo() const final`
    // `Foo() const override` -> `Foo() const final`
    // `Foo() const volatile override` -> `Foo() const volatile override`
    // `Foo() volatile const final` -> `Foo() const volatile final`
    if (PreviousCheck->is(tok::r_paren))
      return true;

    // The cases:
    // `struct {} volatile const a;` -> `struct {} const volatile a;`
    // `class {} volatile const a;` -> `class {} const volatile a;`
    if (PreviousCheck->is(tok::r_brace))
      return true;

    // The case:
    // `template <class T> const Bar Foo()` ->
    // `template <class T> Bar const Foo()`
    // The cases:
    // `Foo<int> const foo` -> `Foo<int> const foo`
    // `Foo<int> volatile const` -> `Foo<int> const volatile`
    // The case:
    // ```
    // template <class T>
    //   requires Concept1<T> && requires Concept2<T>
    // const Foo f();
    // ```
    // ->
    // ```
    // template <class T>
    //   requires Concept1<T> && requires Concept2<T>
    // Foo const f();
    // ```
    if (PreviousCheck->is(TT_TemplateCloser)) {
      // If the token closes a template<> or requires clause, then it is a left
      // qualifier and should be moved to the right.
      return !(PreviousCheck->ClosesTemplateDeclaration ||
               PreviousCheck->ClosesRequiresClause);
    }

    // The case  `Foo* const` -> `Foo* const`
    // The case  `Foo* volatile const` -> `Foo* const volatile`
    // The case  `int32_t const` -> `int32_t const`
    // The case  `auto volatile const` -> `auto const volatile`
    if (PreviousCheck->isOneOf(TT_PointerOrReference, tok::identifier,
                               tok::kw_auto)) {
      return true;
    }

    return false;
  }();

  // Find the last qualifier to the right.
  const auto *LastQual = Tok;
  for (; isQualifier(Next); Next = Next->getNextNonComment())
    LastQual = Next;

  if (!LastQual || !Next ||
      (LastQual->isOneOf(tok::kw_const, tok::kw_volatile) &&
       Next->isOneOf(Keywords.kw_override, Keywords.kw_final))) {
    return Tok;
  }

  // If this qualifier is to the right of a type or pointer do a partial sort
  // and return.
  if (IsRightQualifier) {
    if (LastQual != Tok)
      rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false);
    return Tok;
  }

  const FormatToken *TypeToken = LastQual->getNextNonComment();
  if (!TypeToken)
    return Tok;

  // Stay safe and don't move past macros, also don't bother with sorting.
  if (TypeToken->isPossibleMacro())
    return Tok;

  // The case `const long long int volatile` -> `long long int const volatile`
  // The case `long const long int volatile` -> `long long int const volatile`
  // The case `long long volatile int const` -> `long long int const volatile`
  // The case `const long long volatile int` -> `long long int const volatile`
  if (TypeToken->isTypeName(LangOpts)) {
    // The case `const decltype(foo)` -> `const decltype(foo)`
    // The case `const typeof(foo)` -> `const typeof(foo)`
    // The case `const _Atomic(foo)` -> `const _Atomic(foo)`
    if (TypeToken->isOneOf(tok::kw_decltype, tok::kw_typeof, tok::kw__Atomic))
      return Tok;

    const FormatToken *LastSimpleTypeSpecifier = TypeToken;
    while (isQualifierOrType(LastSimpleTypeSpecifier->getNextNonComment(),
                             LangOpts)) {
      LastSimpleTypeSpecifier = LastSimpleTypeSpecifier->getNextNonComment();
    }

    rotateTokens(SourceMgr, Fixes, Tok, LastSimpleTypeSpecifier,
                 /*Left=*/false);
    return LastSimpleTypeSpecifier;
  }

  // The case  `unsigned short const` -> `unsigned short const`
  // The case:
  // `unsigned short volatile const` -> `unsigned short const volatile`
  if (PreviousCheck && PreviousCheck->isTypeName(LangOpts)) {
    if (LastQual != Tok)
      rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false);
    return Tok;
  }

  // Skip the typename keyword.
  // The case `const typename C::type` -> `typename C::type const`
  if (TypeToken->is(tok::kw_typename))
    TypeToken = TypeToken->getNextNonComment();

  // Skip the initial :: of a global-namespace type.
  // The case `const ::...` -> `::... const`
  if (TypeToken->is(tok::coloncolon)) {
    // The case `const ::template Foo...` -> `::template Foo... const`
    TypeToken = TypeToken->getNextNonComment();
    if (TypeToken && TypeToken->is(tok::kw_template))
      TypeToken = TypeToken->getNextNonComment();
  }

  // Don't change declarations such as
  // `foo(const struct Foo a);` -> `foo(const struct Foo a);`
  // as they would currently change code such as
  // `const struct my_struct_t {} my_struct;` -> `struct my_struct_t const {}
  // my_struct;`
  if (TypeToken->isOneOf(tok::kw_struct, tok::kw_class))
    return Tok;

  if (TypeToken->isOneOf(tok::kw_auto, tok::identifier)) {
    // The case  `const auto` -> `auto const`
    // The case  `const Foo` -> `Foo const`
    // The case  `const ::Foo` -> `::Foo const`
    // The case  `const Foo *` -> `Foo const *`
    // The case  `const Foo &` -> `Foo const &`
    // The case  `const Foo &&` -> `Foo const &&`
    // The case  `const std::Foo &&` -> `std::Foo const &&`
    // The case  `const std::Foo<T> &&` -> `std::Foo<T> const &&`
    // The case  `const ::template Foo` -> `::template Foo const`
    // The case  `const T::template Foo` -> `T::template Foo const`
    const FormatToken *Next = nullptr;
    while ((Next = TypeToken->getNextNonComment()) &&
           (Next->is(TT_TemplateOpener) ||
            Next->startsSequence(tok::coloncolon, tok::identifier) ||
            Next->startsSequence(tok::coloncolon, tok::kw_template,
                                 tok::identifier))) {
      if (Next->is(TT_TemplateOpener)) {
        assert(Next->MatchingParen && "Missing template closer");
        TypeToken = Next->MatchingParen;
      } else if (Next->startsSequence(tok::coloncolon, tok::identifier)) {
        TypeToken = Next->getNextNonComment();
      } else {
        TypeToken = Next->getNextNonComment()->getNextNonComment();
      }
    }

    if (Next && Next->is(tok::kw_auto))
      TypeToken = Next;

    // Place the Qualifier at the end of the list of qualifiers.
    while (isQualifier(TypeToken->getNextNonComment())) {
      // The case `volatile Foo::iter const` -> `Foo::iter const volatile`
      TypeToken = TypeToken->getNextNonComment();
    }

    insertQualifierAfter(SourceMgr, Fixes, TypeToken, Qualifier);
    // Remove token and following whitespace.
    auto Range = CharSourceRange::getCharRange(
        Tok->getStartOfNonWhitespace(), Tok->Next->getStartOfNonWhitespace());
    replaceToken(SourceMgr, Fixes, Range, "");
  }

  return Tok;
}

const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft(
    const SourceManager &SourceMgr, const AdditionalKeywords &Keywords,
    tooling::Replacements &Fixes, const FormatToken *const Tok,
    const std::string &Qualifier, tok::TokenKind QualifierType) {
  // We only need to think about streams that begin with a qualifier.
  if (Tok->isNot(QualifierType))
    return Tok;
  // Don't concern yourself if nothing preceeds the qualifier.
  if (!Tok->getPreviousNonComment())
    return Tok;

  // Skip qualifiers to the left to find what preceeds the qualifiers.
  const FormatToken *TypeToken = Tok->getPreviousNonComment();
  while (isQualifier(TypeToken))
    TypeToken = TypeToken->getPreviousNonComment();

  // For left qualifiers preceeded by nothing, a template declaration, or *,&,&&
  // we only perform sorting.
  if (!TypeToken || TypeToken->isPointerOrReference() ||
      TypeToken->ClosesRequiresClause || TypeToken->ClosesTemplateDeclaration ||
      TypeToken->is(tok::r_square)) {

    // Don't sort past a non-configured qualifier token.
    const FormatToken *FirstQual = Tok;
    while (isConfiguredQualifier(FirstQual->getPreviousNonComment(),
                                 ConfiguredQualifierTokens)) {
      FirstQual = FirstQual->getPreviousNonComment();
    }

    if (FirstQual != Tok)
      rotateTokens(SourceMgr, Fixes, FirstQual, Tok, /*Left=*/true);
    return Tok;
  }

  // Stay safe and don't move past macros, also don't bother with sorting.
  if (TypeToken->isPossibleMacro())
    return Tok;

  // Examples given in order of ['const', 'volatile', 'type']

  // The case `volatile long long int const` -> `const volatile long long int`
  // The case `volatile long long const int` -> `const volatile long long int`
  // The case `const long long volatile int` -> `const volatile long long int`
  // The case `long volatile long int const` -> `const volatile long long int`
  if (TypeToken->isTypeName(LangOpts)) {
    for (const auto *Prev = TypeToken->Previous;
         Prev && Prev->is(tok::coloncolon); Prev = Prev->Previous) {
      TypeToken = Prev;
      Prev = Prev->Previous;
      if (!(Prev && Prev->is(tok::identifier)))
        break;
      TypeToken = Prev;
    }
    const FormatToken *LastSimpleTypeSpecifier = TypeToken;
    while (isConfiguredQualifierOrType(
        LastSimpleTypeSpecifier->getPreviousNonComment(),
        ConfiguredQualifierTokens, LangOpts)) {
      LastSimpleTypeSpecifier =
          LastSimpleTypeSpecifier->getPreviousNonComment();
    }

    rotateTokens(SourceMgr, Fixes, LastSimpleTypeSpecifier, Tok,
                 /*Left=*/true);
    return Tok;
  }

  if (TypeToken->isOneOf(tok::kw_auto, tok::identifier, TT_TemplateCloser)) {
    const auto IsStartOfType = [](const FormatToken *const Tok) -> bool {
      if (!Tok)
        return true;

      // A template closer is not the start of a type.
      // The case `?<> const` -> `const ?<>`
      if (Tok->is(TT_TemplateCloser))
        return false;

      const FormatToken *const Previous = Tok->getPreviousNonComment();
      if (!Previous)
        return true;

      // An identifier preceeded by :: is not the start of a type.
      // The case `?::Foo const` -> `const ?::Foo`
      if (Tok->is(tok::identifier) && Previous->is(tok::coloncolon))
        return false;

      const FormatToken *const PrePrevious = Previous->getPreviousNonComment();
      // An identifier preceeded by ::template is not the start of a type.
      // The case `?::template Foo const` -> `const ?::template Foo`
      if (Tok->is(tok::identifier) && Previous->is(tok::kw_template) &&
          PrePrevious && PrePrevious->is(tok::coloncolon)) {
        return false;
      }

      if (Tok->endsSequence(tok::kw_auto, tok::identifier))
        return false;

      return true;
    };

    while (!IsStartOfType(TypeToken)) {
      // The case `?<>`
      if (TypeToken->is(TT_TemplateCloser)) {
        assert(TypeToken->MatchingParen && "Missing template opener");
        TypeToken = TypeToken->MatchingParen->getPreviousNonComment();
      } else {
        // The cases
        // `::Foo`
        // `?>::Foo`
        // `?Bar::Foo`
        // `::template Foo`
        // `?>::template Foo`
        // `?Bar::template Foo`
        if (TypeToken->getPreviousNonComment()->is(tok::kw_template))
          TypeToken = TypeToken->getPreviousNonComment();

        const FormatToken *const ColonColon =
            TypeToken->getPreviousNonComment();
        const FormatToken *const PreColonColon =
            ColonColon->getPreviousNonComment();
        if (PreColonColon &&
            PreColonColon->isOneOf(TT_TemplateCloser, tok::identifier)) {
          TypeToken = PreColonColon;
        } else {
          TypeToken = ColonColon;
        }
      }
    }

    assert(TypeToken && "Should be auto or identifier");

    // Place the Qualifier at the start of the list of qualifiers.
    const FormatToken *Previous = nullptr;
    while ((Previous = TypeToken->getPreviousNonComment()) &&
           (isConfiguredQualifier(Previous, ConfiguredQualifierTokens) ||
            Previous->is(tok::kw_typename))) {
      // The case `volatile Foo::iter const` -> `const volatile Foo::iter`
      // The case `typename C::type const` -> `const typename C::type`
      TypeToken = Previous;
    }

    // Don't change declarations such as
    // `foo(struct Foo const a);` -> `foo(struct Foo const a);`
    if (!Previous || Previous->isNoneOf(tok::kw_struct, tok::kw_class)) {
      insertQualifierBefore(SourceMgr, Fixes, TypeToken, Qualifier);
      removeToken(SourceMgr, Fixes, Tok);
    }
  }

  return Tok;
}

tok::TokenKind LeftRightQualifierAlignmentFixer::getTokenFromQualifier(
    const std::string &Qualifier) {
  // Don't let 'type' be an identifier, but steal typeof token.
  return llvm::StringSwitch<tok::TokenKind>(Qualifier)
      .Case("type", tok::kw_typeof)
      .Case("const", tok::kw_const)
      .Case("volatile", tok::kw_volatile)
      .Case("static", tok::kw_static)
      .Case("inline", tok::kw_inline)
      .Case("constexpr", tok::kw_constexpr)
      .Case("restrict", tok::kw_restrict)
      .Case("friend", tok::kw_friend)
      .Case("typedef", tok::kw_typedef)
      .Case("consteval", tok::kw_consteval)
      .Case("constinit", tok::kw_constinit)
      .Case("thread_local", tok::kw_thread_local)
      .Case("extern", tok::kw_extern)
      .Case("mutable", tok::kw_mutable)
      .Case("signed", tok::kw_signed)
      .Case("unsigned", tok::kw_unsigned)
      .Case("long", tok::kw_long)
      .Case("short", tok::kw_short)
      .Case("explicit", tok::kw_explicit)
      .Default(tok::identifier);
}

LeftRightQualifierAlignmentFixer::LeftRightQualifierAlignmentFixer(
    const Environment &Env, const FormatStyle &Style,
    const std::string &Qualifier,
    const std::vector<tok::TokenKind> &QualifierTokens, bool RightAlign)
    : TokenAnalyzer(Env, Style), Qualifier(Qualifier), RightAlign(RightAlign),
      ConfiguredQualifierTokens(QualifierTokens) {}

std::pair<tooling::Replacements, unsigned>
LeftRightQualifierAlignmentFixer::analyze(
    TokenAnnotator & /*Annotator*/,
    SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
    FormatTokenLexer &Tokens) {
  tooling::Replacements Fixes;
  AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
  fixQualifierAlignment(AnnotatedLines, Tokens, Fixes);
  return {Fixes, 0};
}

void LeftRightQualifierAlignmentFixer::fixQualifierAlignment(
    SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, FormatTokenLexer &Tokens,
    tooling::Replacements &Fixes) {
  const AdditionalKeywords &Keywords = Tokens.getKeywords();
  const SourceManager &SourceMgr = Env.getSourceManager();
  tok::TokenKind QualifierToken = getTokenFromQualifier(Qualifier);
  assert(QualifierToken != tok::identifier && "Unrecognised Qualifier");

  for (AnnotatedLine *Line : AnnotatedLines) {
    fixQualifierAlignment(Line->Children, Tokens, Fixes);
    if (!Line->Affected || Line->InPPDirective)
      continue;
    FormatToken *First = Line->First;
    assert(First);
    if (First->Finalized)
      continue;

    const auto *Last = Line->Last;

    for (const auto *Tok = First; Tok && Tok != Last && Tok->Next;
         Tok = Tok->Next) {
      if (Tok->MustBreakBefore && Tok != First)
        break;
      if (Tok->is(tok::comment))
        continue;
      if (RightAlign) {
        Tok = analyzeRight(SourceMgr, Keywords, Fixes, Tok, Qualifier,
                           QualifierToken);
      } else {
        Tok = analyzeLeft(SourceMgr, Keywords, Fixes, Tok, Qualifier,
                          QualifierToken);
      }
    }
  }
}

void prepareLeftRightOrderingForQualifierAlignmentFixer(
    const std::vector<std::string> &Order, std::vector<std::string> &LeftOrder,
    std::vector<std::string> &RightOrder,
    std::vector<tok::TokenKind> &Qualifiers) {

  // Depending on the position of type in the order you need
  // To iterate forward or backward through the order list as qualifier
  // can push through each other.
  // The Order list must define the position of "type" to signify
  assert(llvm::is_contained(Order, "type") &&
         "QualifierOrder must contain type");
  // Split the Order list by type and reverse the left side.

  bool left = true;
  for (const auto &s : Order) {
    if (s == "type") {
      left = false;
      continue;
    }

    tok::TokenKind QualifierToken =
        LeftRightQualifierAlignmentFixer::getTokenFromQualifier(s);
    if (QualifierToken != tok::kw_typeof && QualifierToken != tok::identifier) {
      Qualifiers.push_back(QualifierToken);

      // Ensure signed/unsigned and long/short qualifier pairs are positioned
      // together by default unless the user has explicitly specified both in
      // the QualifierOrder. This allows users to override the default pairing
      // by listing both qualifiers in the order.
      auto AddPairedQualifier = [&](tok::TokenKind PairedToken,
                                    const std::string &PairedName) {
        if (!llvm::is_contained(Order, PairedName)) {
          Qualifiers.push_back(PairedToken);
          if (left)
            LeftOrder.insert(LeftOrder.begin(), PairedName);
          else
            RightOrder.push_back(PairedName);
        }
      };

      if (QualifierToken == tok::kw_unsigned)
        AddPairedQualifier(tok::kw_signed, "signed");
      else if (QualifierToken == tok::kw_signed)
        AddPairedQualifier(tok::kw_unsigned, "unsigned");
      else if (QualifierToken == tok::kw_long)
        AddPairedQualifier(tok::kw_short, "short");
      else if (QualifierToken == tok::kw_short)
        AddPairedQualifier(tok::kw_long, "long");
    }

    if (left) {
      // Reverse the order for left aligned items.
      LeftOrder.insert(LeftOrder.begin(), s);
    } else {
      RightOrder.push_back(s);
    }
  }
}

bool isQualifierOrType(const FormatToken *Tok, const LangOptions &LangOpts) {
  return Tok && (Tok->isTypeName(LangOpts) || Tok->is(tok::kw_auto) ||
                 isQualifier(Tok));
}

bool isConfiguredQualifierOrType(const FormatToken *Tok,
                                 const std::vector<tok::TokenKind> &Qualifiers,
                                 const LangOptions &LangOpts) {
  return Tok && (Tok->isTypeName(LangOpts) || Tok->is(tok::kw_auto) ||
                 isConfiguredQualifier(Tok, Qualifiers));
}

} // namespace format
} // namespace clang
