// FormatString.cpp - Common stuff for handling printf/scanf formats -*- 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
//
//===----------------------------------------------------------------------===//
//
// Shared details for processing format strings of printf and scanf
// (and friends).
//
//===----------------------------------------------------------------------===//

#include "FormatStringParsing.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/ConvertUTF.h"
#include <optional>

using clang::analyze_format_string::ArgType;
using clang::analyze_format_string::FormatStringHandler;
using clang::analyze_format_string::FormatSpecifier;
using clang::analyze_format_string::LengthModifier;
using clang::analyze_format_string::OptionalAmount;
using clang::analyze_format_string::ConversionSpecifier;
using namespace clang;

// Key function to FormatStringHandler.
FormatStringHandler::~FormatStringHandler() {}

//===----------------------------------------------------------------------===//
// Functions for parsing format strings components in both printf and
// scanf format strings.
//===----------------------------------------------------------------------===//

OptionalAmount
clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
  const char *I = Beg;
  UpdateOnReturn <const char*> UpdateBeg(Beg, I);

  unsigned accumulator = 0;
  bool hasDigits = false;

  for ( ; I != E; ++I) {
    char c = *I;
    if (c >= '0' && c <= '9') {
      hasDigits = true;
      accumulator = (accumulator * 10) + (c - '0');
      continue;
    }

    if (hasDigits)
      return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
          false);

    break;
  }

  return OptionalAmount();
}

OptionalAmount
clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
                                                     const char *E,
                                                     unsigned &argIndex) {
  if (*Beg == '*') {
    ++Beg;
    return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
  }

  return ParseAmount(Beg, E);
}

OptionalAmount
clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H,
                                                  const char *Start,
                                                  const char *&Beg,
                                                  const char *E,
                                                  PositionContext p) {
  if (*Beg == '*') {
    const char *I = Beg + 1;
    const OptionalAmount &Amt = ParseAmount(I, E);

    if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
      H.HandleInvalidPosition(Beg, I - Beg, p);
      return OptionalAmount(false);
    }

    if (I == E) {
      // No more characters left?
      H.HandleIncompleteSpecifier(Start, E - Start);
      return OptionalAmount(false);
    }

    assert(Amt.getHowSpecified() == OptionalAmount::Constant);

    if (*I == '$') {
      // Handle positional arguments

      // Special case: '*0$', since this is an easy mistake.
      if (Amt.getConstantAmount() == 0) {
        H.HandleZeroPosition(Beg, I - Beg + 1);
        return OptionalAmount(false);
      }

      const char *Tmp = Beg;
      Beg = ++I;

      return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
                            Tmp, 0, true);
    }

    H.HandleInvalidPosition(Beg, I - Beg, p);
    return OptionalAmount(false);
  }

  return ParseAmount(Beg, E);
}


bool
clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
                                              FormatSpecifier &CS,
                                              const char *Start,
                                              const char *&Beg, const char *E,
                                              unsigned *argIndex) {
  // FIXME: Support negative field widths.
  if (argIndex) {
    CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
  }
  else {
    const OptionalAmount Amt =
      ParsePositionAmount(H, Start, Beg, E,
                          analyze_format_string::FieldWidthPos);

    if (Amt.isInvalid())
      return true;
    CS.setFieldWidth(Amt);
  }
  return false;
}

bool
clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
                                               FormatSpecifier &FS,
                                               const char *Start,
                                               const char *&Beg,
                                               const char *E) {
  const char *I = Beg;

  const OptionalAmount &Amt = ParseAmount(I, E);

  if (I == E) {
    // No more characters left?
    H.HandleIncompleteSpecifier(Start, E - Start);
    return true;
  }

  if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
    // Warn that positional arguments are non-standard.
    H.HandlePosition(Start, I - Start);

    // Special case: '%0$', since this is an easy mistake.
    if (Amt.getConstantAmount() == 0) {
      H.HandleZeroPosition(Start, I - Start);
      return true;
    }

    FS.setArgIndex(Amt.getConstantAmount() - 1);
    FS.setUsesPositionalArg();
    // Update the caller's pointer if we decided to consume
    // these characters.
    Beg = I;
    return false;
  }

  return false;
}

bool
clang::analyze_format_string::ParseVectorModifier(FormatStringHandler &H,
                                                  FormatSpecifier &FS,
                                                  const char *&I,
                                                  const char *E,
                                                  const LangOptions &LO) {
  if (!LO.OpenCL)
    return false;

  const char *Start = I;
  if (*I == 'v') {
    ++I;

    if (I == E) {
      H.HandleIncompleteSpecifier(Start, E - Start);
      return true;
    }

    OptionalAmount NumElts = ParseAmount(I, E);
    if (NumElts.getHowSpecified() != OptionalAmount::Constant) {
      H.HandleIncompleteSpecifier(Start, E - Start);
      return true;
    }

    FS.setVectorNumElts(NumElts);
  }

  return false;
}

bool
clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
                                                  const char *&I,
                                                  const char *E,
                                                  const LangOptions &LO,
                                                  bool IsScanf) {
  LengthModifier::Kind lmKind = LengthModifier::None;
  const char *lmPosition = I;
  switch (*I) {
    default:
      return false;
    case 'h':
      ++I;
      if (I != E && *I == 'h') {
        ++I;
        lmKind = LengthModifier::AsChar;
      } else if (I != E && *I == 'l' && LO.OpenCL) {
        ++I;
        lmKind = LengthModifier::AsShortLong;
      } else {
        lmKind = LengthModifier::AsShort;
      }
      break;
    case 'l':
      ++I;
      if (I != E && *I == 'l') {
        ++I;
        lmKind = LengthModifier::AsLongLong;
      } else {
        lmKind = LengthModifier::AsLong;
      }
      break;
    case 'j': lmKind = LengthModifier::AsIntMax;     ++I; break;
    case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
    case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
    case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
    case 'q': lmKind = LengthModifier::AsQuad;       ++I; break;
    case 'a':
      if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
        // For scanf in C90, look at the next character to see if this should
        // be parsed as the GNU extension 'a' length modifier. If not, this
        // will be parsed as a conversion specifier.
        ++I;
        if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
          lmKind = LengthModifier::AsAllocate;
          break;
        }
        --I;
      }
      return false;
    case 'm':
      if (IsScanf) {
        lmKind = LengthModifier::AsMAllocate;
        ++I;
        break;
      }
      return false;
    // printf: AsInt64, AsInt32, AsInt3264
    // scanf:  AsInt64
    case 'I':
      if (I + 1 != E && I + 2 != E) {
        if (I[1] == '6' && I[2] == '4') {
          I += 3;
          lmKind = LengthModifier::AsInt64;
          break;
        }
        if (IsScanf)
          return false;

        if (I[1] == '3' && I[2] == '2') {
          I += 3;
          lmKind = LengthModifier::AsInt32;
          break;
        }
      }
      ++I;
      lmKind = LengthModifier::AsInt3264;
      break;
    case 'w':
      lmKind = LengthModifier::AsWide; ++I; break;
  }
  LengthModifier lm(lmPosition, lmKind);
  FS.setLengthModifier(lm);
  return true;
}

bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
    const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
  if (SpecifierBegin + 1 >= FmtStrEnd)
    return false;

  const llvm::UTF8 *SB =
      reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1);
  const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd);
  const char FirstByte = *SB;

  // If the invalid specifier is a multibyte UTF-8 string, return the
  // total length accordingly so that the conversion specifier can be
  // properly updated to reflect a complete UTF-8 specifier.
  unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte);
  if (NumBytes == 1)
    return false;
  if (SB + NumBytes > SE)
    return false;

  Len = NumBytes + 1;
  return true;
}

//===----------------------------------------------------------------------===//
// Methods on ArgType.
//===----------------------------------------------------------------------===//

static bool namedTypeToLengthModifierKind(ASTContext &Ctx, QualType QT,
                                          LengthModifier::Kind &K) {
  if (!Ctx.getLangOpts().C99 && !Ctx.getLangOpts().CPlusPlus)
    return false;
  for (/**/; const auto *TT = QT->getAs<TypedefType>(); QT = TT->desugar()) {
    const auto *TD = TT->getDecl();
    const auto *DC = TT->getDecl()->getDeclContext();
    if (DC->isTranslationUnit() || DC->isStdNamespace()) {
      StringRef Name = TD->getIdentifier()->getName();
      if (Name == "size_t") {
        K = LengthModifier::AsSizeT;
        return true;
      } else if (Name == "ssize_t" /*Not C99, but common in Unix.*/) {
        K = LengthModifier::AsSizeT;
        return true;
      } else if (Name == "ptrdiff_t") {
        K = LengthModifier::AsPtrDiff;
        return true;
      } else if (Name == "intmax_t") {
        K = LengthModifier::AsIntMax;
        return true;
      } else if (Name == "uintmax_t") {
        K = LengthModifier::AsIntMax;
        return true;
      }
    }
  }
  if (const auto *PST = QT->getAs<PredefinedSugarType>()) {
    using Kind = PredefinedSugarType::Kind;
    switch (PST->getKind()) {
    case Kind::SizeT:
    case Kind::SignedSizeT:
      K = LengthModifier::AsSizeT;
      return true;
    case Kind::PtrdiffT:
      K = LengthModifier::AsPtrDiff;
      return true;
    }
    llvm_unreachable("unexpected kind");
  }
  return false;
}

// Check whether T and E are compatible size_t/ptrdiff_t types. E must be
// consistent with LE.
// T is the type of the actual expression in the code to be checked, and E is
// the expected type parsed from the format string.
static clang::analyze_format_string::ArgType::MatchKind
matchesSizeTPtrdiffT(ASTContext &C, QualType T, QualType E) {
  using MatchKind = clang::analyze_format_string::ArgType::MatchKind;

  if (!T->isIntegerType())
    return MatchKind::NoMatch;

  if (C.hasSameType(T, E))
    return MatchKind::Match;

  if (C.getCorrespondingSignedType(T.getCanonicalType()) !=
      C.getCorrespondingSignedType(E.getCanonicalType()))
    return MatchKind::NoMatch;

  return MatchKind::NoMatchSignedness;
}

clang::analyze_format_string::ArgType::MatchKind
ArgType::matchesType(ASTContext &C, QualType argTy) const {
  // When using the format attribute in C++, you can receive a function or an
  // array that will necessarily decay to a pointer when passed to the final
  // format consumer. Apply decay before type comparison.
  if (argTy->canDecayToPointerType())
    argTy = C.getDecayedType(argTy);

  if (Ptr) {
    // It has to be a pointer.
    const PointerType *PT = argTy->getAs<PointerType>();
    if (!PT)
      return NoMatch;

    // We cannot write through a const qualified pointer.
    if (PT->getPointeeType().isConstQualified())
      return NoMatch;

    argTy = PT->getPointeeType();
  }

  switch (K) {
    case InvalidTy:
      llvm_unreachable("ArgType must be valid");

    case UnknownTy:
      return Match;

    case AnyCharTy: {
      if (const auto *ETy = argTy->getAs<EnumType>()) {
        // If the enum is incomplete we know nothing about the underlying type.
        // Assume that it's 'int'. Do not use the underlying type for a scoped
        // enumeration.
        const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
        if (!ED->isComplete())
          return NoMatch;
        if (ETy->isUnscopedEnumerationType())
          argTy = ED->getIntegerType();
      }

      if (const auto *BT = argTy->getAs<BuiltinType>()) {
        // The types are perfectly matched?
        switch (BT->getKind()) {
        default:
          break;
        case BuiltinType::Char_S:
        case BuiltinType::SChar:
        case BuiltinType::UChar:
        case BuiltinType::Char_U:
            return Match;
        case BuiltinType::Bool:
          if (!Ptr)
            return Match;
          break;
        }
        // "Partially matched" because of promotions?
        if (!Ptr) {
          switch (BT->getKind()) {
          default:
            break;
          case BuiltinType::Int:
          case BuiltinType::UInt:
            return MatchPromotion;
          case BuiltinType::Short:
          case BuiltinType::UShort:
          case BuiltinType::WChar_S:
          case BuiltinType::WChar_U:
            return NoMatchPromotionTypeConfusion;
          }
        }
      }
      return NoMatch;
    }

    case SpecificTy: {
      if (TK != TypeKind::DontCare) {
        return matchesSizeTPtrdiffT(C, argTy, T);
      }

      if (const EnumType *ETy = argTy->getAs<EnumType>()) {
        // If the enum is incomplete we know nothing about the underlying type.
        // Assume that it's 'int'. Do not use the underlying type for a scoped
        // enumeration as that needs an exact match.
        const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
        if (!ED->isComplete())
          argTy = C.IntTy;
        else if (ETy->isUnscopedEnumerationType())
          argTy = ED->getIntegerType();
      }

      if (argTy->isSaturatedFixedPointType())
        argTy = C.getCorrespondingUnsaturatedType(argTy);

      argTy = C.getCanonicalType(argTy).getUnqualifiedType();

      if (T == argTy)
        return Match;
      if (const auto *BT = argTy->getAs<BuiltinType>()) {
        // Check if the only difference between them is signed vs unsigned
        // if true, return match signedness.
        switch (BT->getKind()) {
          default:
            break;
          case BuiltinType::Bool:
            if (Ptr && (T == C.UnsignedCharTy || T == C.SignedCharTy))
              return NoMatch;
            [[fallthrough]];
          case BuiltinType::Char_S:
          case BuiltinType::SChar:
            if (T == C.UnsignedShortTy || T == C.ShortTy)
              return NoMatchTypeConfusion;
            if (T == C.UnsignedCharTy)
              return NoMatchSignedness;
            if (T == C.SignedCharTy)
              return Match;
            break;
          case BuiltinType::Char_U:
          case BuiltinType::UChar:
            if (T == C.UnsignedShortTy || T == C.ShortTy)
              return NoMatchTypeConfusion;
            if (T == C.UnsignedCharTy)
              return Match;
            if (T == C.SignedCharTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::Short:
            if (T == C.UnsignedShortTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::UShort:
            if (T == C.ShortTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::Int:
            if (T == C.UnsignedIntTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::UInt:
            if (T == C.IntTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::Long:
            if (T == C.UnsignedLongTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::ULong:
            if (T == C.LongTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::LongLong:
            if (T == C.UnsignedLongLongTy)
              return NoMatchSignedness;
            break;
          case BuiltinType::ULongLong:
            if (T == C.LongLongTy)
              return NoMatchSignedness;
            break;
          }
          // "Partially matched" because of promotions?
          if (!Ptr) {
            switch (BT->getKind()) {
            default:
              break;
            case BuiltinType::Bool:
              if (T == C.IntTy || T == C.UnsignedIntTy)
                return MatchPromotion;
              break;
            case BuiltinType::Int:
            case BuiltinType::UInt:
              if (T == C.SignedCharTy || T == C.UnsignedCharTy ||
                  T == C.ShortTy || T == C.UnsignedShortTy || T == C.WCharTy ||
                  T == C.WideCharTy)
                return MatchPromotion;
              break;
            case BuiltinType::Char_U:
              if (T == C.UnsignedIntTy)
                return MatchPromotion;
              if (T == C.UnsignedShortTy)
                return NoMatchPromotionTypeConfusion;
              break;
            case BuiltinType::Char_S:
              if (T == C.IntTy)
                return MatchPromotion;
              if (T == C.ShortTy)
                return NoMatchPromotionTypeConfusion;
              break;
            case BuiltinType::Half:
            case BuiltinType::Float:
              if (T == C.DoubleTy)
                return MatchPromotion;
              break;
            case BuiltinType::Short:
            case BuiltinType::UShort:
              if (T == C.SignedCharTy || T == C.UnsignedCharTy)
                return NoMatchPromotionTypeConfusion;
              break;
            case BuiltinType::WChar_U:
            case BuiltinType::WChar_S:
              if (T != C.WCharTy && T != C.WideCharTy)
                return NoMatchPromotionTypeConfusion;
            }
          }
      }
      return NoMatch;
    }

    case CStrTy:
      if (const auto *PT = argTy->getAs<PointerType>();
          PT && PT->getPointeeType()->isCharType())
        return Match;
      return NoMatch;

    case WCStrTy:
      if (const auto *PT = argTy->getAs<PointerType>();
          PT &&
          C.hasSameUnqualifiedType(PT->getPointeeType(), C.getWideCharType()))
        return Match;
      return NoMatch;

    case WIntTy: {
      QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();

      if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
        return Match;

      QualType PromoArg = C.isPromotableIntegerType(argTy)
                              ? C.getPromotedIntegerType(argTy)
                              : argTy;
      PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();

      // If the promoted argument is the corresponding signed type of the
      // wint_t type, then it should match.
      if (PromoArg->hasSignedIntegerRepresentation() &&
          C.getCorrespondingUnsignedType(PromoArg) == WInt)
        return Match;

      return WInt == PromoArg ? Match : NoMatch;
    }

    case CPointerTy:
      if (const auto *PT = argTy->getAs<PointerType>()) {
        QualType PointeeTy = PT->getPointeeType();
        if (PointeeTy->isVoidType() || (!Ptr && PointeeTy->isCharType()))
          return Match;
        return NoMatchPedantic;
      }

      // nullptr_t* is not a double pointer, so reject when something like
      // void** is expected.
      // In C++, nullptr is promoted to void*. In C23, va_arg(ap, void*) is not
      // undefined when the next argument is of type nullptr_t.
      if (!Ptr && argTy->isNullPtrType())
        return C.getLangOpts().CPlusPlus ? MatchPromotion : Match;

      if (argTy->isObjCObjectPointerType() || argTy->isBlockPointerType())
        return NoMatchPedantic;

      return NoMatch;

    case ObjCPointerTy: {
      if (argTy->getAs<ObjCObjectPointerType>() ||
          argTy->getAs<BlockPointerType>())
        return Match;

      // Handle implicit toll-free bridging.
      if (const PointerType *PT = argTy->getAs<PointerType>()) {
        // Things such as CFTypeRef are really just opaque pointers
        // to C structs representing CF types that can often be bridged
        // to Objective-C objects.  Since the compiler doesn't know which
        // structs can be toll-free bridged, we just accept them all.
        QualType pointee = PT->getPointeeType();
        if (pointee->getAsStructureType() || pointee->isVoidType())
          return Match;
      }
      return NoMatch;
    }
  }

  llvm_unreachable("Invalid ArgType Kind!");
}

static analyze_format_string::ArgType::MatchKind
integerTypeMatch(ASTContext &C, QualType A, QualType B, bool CheckSign) {
  using MK = analyze_format_string::ArgType::MatchKind;

  uint64_t IntSize = C.getTypeSize(C.IntTy);
  uint64_t ASize = C.getTypeSize(A);
  uint64_t BSize = C.getTypeSize(B);
  if (std::max(ASize, IntSize) != std::max(BSize, IntSize))
    return MK::NoMatch;
  if (CheckSign && A->isSignedIntegerType() != B->isSignedIntegerType())
    return MK::NoMatchSignedness;
  if (ASize != BSize)
    return MK::MatchPromotion;
  return MK::Match;
}

analyze_format_string::ArgType::MatchKind
ArgType::matchesArgType(ASTContext &C, const ArgType &Other) const {
  using AK = analyze_format_string::ArgType::Kind;

  // Per matchesType.
  if (K == AK::InvalidTy || Other.K == AK::InvalidTy)
    return NoMatch;
  if (K == AK::UnknownTy || Other.K == AK::UnknownTy)
    return Match;

  // Handle whether either (or both, or neither) sides has Ptr set,
  // in addition to whether either (or both, or neither) sides is a SpecificTy
  // that is a pointer.
  ArgType Left = *this;
  bool LeftWasPointer = false;
  ArgType Right = Other;
  bool RightWasPointer = false;
  if (Left.Ptr) {
    Left.Ptr = false;
    LeftWasPointer = true;
  } else if (Left.K == AK::SpecificTy && Left.T->isPointerType()) {
    Left.T = Left.T->getPointeeType();
    LeftWasPointer = true;
  }
  if (Right.Ptr) {
    Right.Ptr = false;
    RightWasPointer = true;
  } else if (Right.K == AK::SpecificTy && Right.T->isPointerType()) {
    Right.T = Right.T->getPointeeType();
    RightWasPointer = true;
  }

  if (LeftWasPointer != RightWasPointer)
    return NoMatch;

  // Ensure that if at least one side is a SpecificTy, then Left is a
  // SpecificTy.
  if (Right.K == AK::SpecificTy)
    std::swap(Left, Right);

  if (Left.K == AK::SpecificTy) {
    if (Right.K == AK::SpecificTy) {
      if (Left.TK != TypeKind::DontCare) {
        return matchesSizeTPtrdiffT(C, Right.T, Left.T);
      } else if (Right.TK != TypeKind::DontCare) {
        return matchesSizeTPtrdiffT(C, Left.T, Right.T);
      }

      auto Canon1 = C.getCanonicalType(Left.T);
      auto Canon2 = C.getCanonicalType(Right.T);
      if (Canon1 == Canon2)
        return Match;

      auto *BT1 = QualType(Canon1)->getAs<BuiltinType>();
      auto *BT2 = QualType(Canon2)->getAs<BuiltinType>();
      if (BT1 == nullptr || BT2 == nullptr)
        return NoMatch;
      if (BT1 == BT2)
        return Match;

      if (!LeftWasPointer && BT1->isInteger() && BT2->isInteger())
        return integerTypeMatch(C, Canon1, Canon2, true);
      return NoMatch;
    } else if (Right.K == AK::AnyCharTy) {
      if (!LeftWasPointer && Left.T->isIntegerType())
        return integerTypeMatch(C, Left.T, C.CharTy, false);
      return NoMatch;
    } else if (Right.K == AK::WIntTy) {
      if (!LeftWasPointer && Left.T->isIntegerType())
        return integerTypeMatch(C, Left.T, C.WIntTy, true);
      return NoMatch;
    }
    // It's hypothetically possible to create an AK::SpecificTy ArgType
    // that matches another kind of ArgType, but in practice Clang doesn't
    // do that, so ignore that case.
    return NoMatch;
  }

  return Left.K == Right.K ? Match : NoMatch;
}

ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
  // Check for valid vector element types.
  if (T.isNull())
    return ArgType::Invalid();

  QualType Vec = C.getExtVectorType(T, NumElts);
  return ArgType(Vec, Name);
}

QualType ArgType::getRepresentativeType(ASTContext &C) const {
  QualType Res;
  switch (K) {
    case InvalidTy:
      llvm_unreachable("No representative type for Invalid ArgType");
    case UnknownTy:
      llvm_unreachable("No representative type for Unknown ArgType");
    case AnyCharTy:
      Res = C.CharTy;
      break;
    case SpecificTy:
      if (TK == TypeKind::PtrdiffT || TK == TypeKind::SizeT)
        // Using Name as name, so no need to show the uglified name.
        Res = T->getCanonicalTypeInternal();
      else
        Res = T;
      break;
    case CStrTy:
      Res = C.getPointerType(C.CharTy);
      break;
    case WCStrTy:
      Res = C.getPointerType(C.getWideCharType());
      break;
    case ObjCPointerTy:
      Res = C.ObjCBuiltinIdTy;
      break;
    case CPointerTy:
      Res = C.VoidPtrTy;
      break;
    case WIntTy: {
      Res = C.getWIntType();
      break;
    }
  }

  if (Ptr)
    Res = C.getPointerType(Res);
  return Res;
}

std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
  std::string S = getRepresentativeType(C).getAsString(C.getPrintingPolicy());
  std::string Alias;
  if (Name) {
    // Use a specific name for this type, e.g. "size_t".
    Alias = Name;
    if (Ptr) {
      // If ArgType is actually a pointer to T, append an asterisk.
      Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
    }
    // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
    if (S == Alias)
      Alias.clear();
  }

  if (!Alias.empty())
    return std::string("'") + Alias + "' (aka '" + S + "')";
  return std::string("'") + S + "'";
}


//===----------------------------------------------------------------------===//
// Methods on OptionalAmount.
//===----------------------------------------------------------------------===//

ArgType
analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
  return Ctx.IntTy;
}

//===----------------------------------------------------------------------===//
// Methods on LengthModifier.
//===----------------------------------------------------------------------===//

const char *
analyze_format_string::LengthModifier::toString() const {
  switch (kind) {
  case AsChar:
    return "hh";
  case AsShort:
    return "h";
  case AsShortLong:
    return "hl";
  case AsLong: // or AsWideChar
    return "l";
  case AsLongLong:
    return "ll";
  case AsQuad:
    return "q";
  case AsIntMax:
    return "j";
  case AsSizeT:
    return "z";
  case AsPtrDiff:
    return "t";
  case AsInt32:
    return "I32";
  case AsInt3264:
    return "I";
  case AsInt64:
    return "I64";
  case AsLongDouble:
    return "L";
  case AsAllocate:
    return "a";
  case AsMAllocate:
    return "m";
  case AsWide:
    return "w";
  case None:
    return "";
  }
  return nullptr;
}

//===----------------------------------------------------------------------===//
// Methods on ConversionSpecifier.
//===----------------------------------------------------------------------===//

const char *ConversionSpecifier::toString() const {
  switch (kind) {
  case bArg: return "b";
  case BArg: return "B";
  case dArg: return "d";
  case DArg: return "D";
  case iArg: return "i";
  case oArg: return "o";
  case OArg: return "O";
  case uArg: return "u";
  case UArg: return "U";
  case xArg: return "x";
  case XArg: return "X";
  case fArg: return "f";
  case FArg: return "F";
  case eArg: return "e";
  case EArg: return "E";
  case gArg: return "g";
  case GArg: return "G";
  case aArg: return "a";
  case AArg: return "A";
  case cArg: return "c";
  case sArg: return "s";
  case pArg: return "p";
  case PArg:
    return "P";
  case nArg: return "n";
  case PercentArg:  return "%";
  case ScanListArg: return "[";
  case InvalidSpecifier: return nullptr;

  // POSIX unicode extensions.
  case CArg: return "C";
  case SArg: return "S";

  // Objective-C specific specifiers.
  case ObjCObjArg: return "@";

  // FreeBSD kernel specific specifiers.
  case FreeBSDbArg: return "b";
  case FreeBSDDArg: return "D";
  case FreeBSDrArg: return "r";
  case FreeBSDyArg: return "y";

  // GlibC specific specifiers.
  case PrintErrno: return "m";

  // MS specific specifiers.
  case ZArg: return "Z";

  // ISO/IEC TR 18037 (fixed-point) specific specifiers.
  case rArg:
    return "r";
  case RArg:
    return "R";
  case kArg:
    return "k";
  case KArg:
    return "K";
  }
  return nullptr;
}

std::optional<ConversionSpecifier>
ConversionSpecifier::getStandardSpecifier() const {
  ConversionSpecifier::Kind NewKind;

  switch (getKind()) {
  default:
    return std::nullopt;
  case DArg:
    NewKind = dArg;
    break;
  case UArg:
    NewKind = uArg;
    break;
  case OArg:
    NewKind = oArg;
    break;
  }

  ConversionSpecifier FixedCS(*this);
  FixedCS.setKind(NewKind);
  return FixedCS;
}

//===----------------------------------------------------------------------===//
// Methods on OptionalAmount.
//===----------------------------------------------------------------------===//

void OptionalAmount::toString(raw_ostream &os) const {
  switch (hs) {
  case Invalid:
  case NotSpecified:
    return;
  case Arg:
    if (UsesDotPrefix)
        os << ".";
    if (usesPositionalArg())
      os << "*" << getPositionalArgIndex() << "$";
    else
      os << "*";
    break;
  case Constant:
    if (UsesDotPrefix)
        os << ".";
    os << amt;
    break;
  }
}

bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
                                             const LangOptions &LO) const {
  switch (LM.getKind()) {
    case LengthModifier::None:
      return true;

    // Handle most integer flags
    case LengthModifier::AsShort:
      // Length modifier only applies to FP vectors.
      if (LO.OpenCL && CS.isDoubleArg())
        return !VectorNumElts.isInvalid();

      if (CS.isFixedPointArg())
        return true;

      if (Target.getTriple().isOSMSVCRT()) {
        switch (CS.getKind()) {
          case ConversionSpecifier::cArg:
          case ConversionSpecifier::CArg:
          case ConversionSpecifier::sArg:
          case ConversionSpecifier::SArg:
          case ConversionSpecifier::ZArg:
            return true;
          default:
            break;
        }
      }
      [[fallthrough]];
    case LengthModifier::AsChar:
    case LengthModifier::AsLongLong:
    case LengthModifier::AsQuad:
    case LengthModifier::AsIntMax:
    case LengthModifier::AsSizeT:
    case LengthModifier::AsPtrDiff:
      switch (CS.getKind()) {
        case ConversionSpecifier::bArg:
        case ConversionSpecifier::BArg:
        case ConversionSpecifier::dArg:
        case ConversionSpecifier::DArg:
        case ConversionSpecifier::iArg:
        case ConversionSpecifier::oArg:
        case ConversionSpecifier::OArg:
        case ConversionSpecifier::uArg:
        case ConversionSpecifier::UArg:
        case ConversionSpecifier::xArg:
        case ConversionSpecifier::XArg:
        case ConversionSpecifier::nArg:
          return true;
        case ConversionSpecifier::FreeBSDrArg:
        case ConversionSpecifier::FreeBSDyArg:
          return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS();
        default:
          return false;
      }

    case LengthModifier::AsShortLong:
      return LO.OpenCL && !VectorNumElts.isInvalid();

    // Handle 'l' flag
    case LengthModifier::AsLong: // or AsWideChar
      if (CS.isDoubleArg()) {
        // Invalid for OpenCL FP scalars.
        if (LO.OpenCL && VectorNumElts.isInvalid())
          return false;
        return true;
      }

      if (CS.isFixedPointArg())
        return true;

      switch (CS.getKind()) {
        case ConversionSpecifier::bArg:
        case ConversionSpecifier::BArg:
        case ConversionSpecifier::dArg:
        case ConversionSpecifier::DArg:
        case ConversionSpecifier::iArg:
        case ConversionSpecifier::oArg:
        case ConversionSpecifier::OArg:
        case ConversionSpecifier::uArg:
        case ConversionSpecifier::UArg:
        case ConversionSpecifier::xArg:
        case ConversionSpecifier::XArg:
        case ConversionSpecifier::nArg:
        case ConversionSpecifier::cArg:
        case ConversionSpecifier::sArg:
        case ConversionSpecifier::ScanListArg:
        case ConversionSpecifier::ZArg:
          return true;
        case ConversionSpecifier::FreeBSDrArg:
        case ConversionSpecifier::FreeBSDyArg:
          return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS();
        default:
          return false;
      }

    case LengthModifier::AsLongDouble:
      switch (CS.getKind()) {
        case ConversionSpecifier::aArg:
        case ConversionSpecifier::AArg:
        case ConversionSpecifier::fArg:
        case ConversionSpecifier::FArg:
        case ConversionSpecifier::eArg:
        case ConversionSpecifier::EArg:
        case ConversionSpecifier::gArg:
        case ConversionSpecifier::GArg:
          return true;
        // GNU libc extension.
        case ConversionSpecifier::dArg:
        case ConversionSpecifier::iArg:
        case ConversionSpecifier::oArg:
        case ConversionSpecifier::uArg:
        case ConversionSpecifier::xArg:
        case ConversionSpecifier::XArg:
          return !Target.getTriple().isOSDarwin() &&
                 !Target.getTriple().isOSWindows();
        default:
          return false;
      }

    case LengthModifier::AsAllocate:
      switch (CS.getKind()) {
        case ConversionSpecifier::sArg:
        case ConversionSpecifier::SArg:
        case ConversionSpecifier::ScanListArg:
          return true;
        default:
          return false;
      }

    case LengthModifier::AsMAllocate:
      switch (CS.getKind()) {
        case ConversionSpecifier::cArg:
        case ConversionSpecifier::CArg:
        case ConversionSpecifier::sArg:
        case ConversionSpecifier::SArg:
        case ConversionSpecifier::ScanListArg:
          return true;
        default:
          return false;
      }
    case LengthModifier::AsInt32:
    case LengthModifier::AsInt3264:
    case LengthModifier::AsInt64:
      switch (CS.getKind()) {
        case ConversionSpecifier::dArg:
        case ConversionSpecifier::iArg:
        case ConversionSpecifier::oArg:
        case ConversionSpecifier::uArg:
        case ConversionSpecifier::xArg:
        case ConversionSpecifier::XArg:
          return Target.getTriple().isOSMSVCRT();
        default:
          return false;
      }
    case LengthModifier::AsWide:
      switch (CS.getKind()) {
        case ConversionSpecifier::cArg:
        case ConversionSpecifier::CArg:
        case ConversionSpecifier::sArg:
        case ConversionSpecifier::SArg:
        case ConversionSpecifier::ZArg:
          return Target.getTriple().isOSMSVCRT();
        default:
          return false;
      }
  }
  llvm_unreachable("Invalid LengthModifier Kind!");
}

bool FormatSpecifier::hasStandardLengthModifier() const {
  switch (LM.getKind()) {
    case LengthModifier::None:
    case LengthModifier::AsChar:
    case LengthModifier::AsShort:
    case LengthModifier::AsLong:
    case LengthModifier::AsLongLong:
    case LengthModifier::AsIntMax:
    case LengthModifier::AsSizeT:
    case LengthModifier::AsPtrDiff:
    case LengthModifier::AsLongDouble:
      return true;
    case LengthModifier::AsAllocate:
    case LengthModifier::AsMAllocate:
    case LengthModifier::AsQuad:
    case LengthModifier::AsInt32:
    case LengthModifier::AsInt3264:
    case LengthModifier::AsInt64:
    case LengthModifier::AsWide:
    case LengthModifier::AsShortLong: // ???
      return false;
  }
  llvm_unreachable("Invalid LengthModifier Kind!");
}

bool FormatSpecifier::hasStandardConversionSpecifier(
    const LangOptions &LangOpt) const {
  switch (CS.getKind()) {
    case ConversionSpecifier::bArg:
    case ConversionSpecifier::BArg:
    case ConversionSpecifier::cArg:
    case ConversionSpecifier::dArg:
    case ConversionSpecifier::iArg:
    case ConversionSpecifier::oArg:
    case ConversionSpecifier::uArg:
    case ConversionSpecifier::xArg:
    case ConversionSpecifier::XArg:
    case ConversionSpecifier::fArg:
    case ConversionSpecifier::FArg:
    case ConversionSpecifier::eArg:
    case ConversionSpecifier::EArg:
    case ConversionSpecifier::gArg:
    case ConversionSpecifier::GArg:
    case ConversionSpecifier::aArg:
    case ConversionSpecifier::AArg:
    case ConversionSpecifier::sArg:
    case ConversionSpecifier::pArg:
    case ConversionSpecifier::nArg:
    case ConversionSpecifier::ObjCObjArg:
    case ConversionSpecifier::ScanListArg:
    case ConversionSpecifier::PercentArg:
    case ConversionSpecifier::PArg:
      return true;
    case ConversionSpecifier::CArg:
    case ConversionSpecifier::SArg:
      return LangOpt.ObjC;
    case ConversionSpecifier::InvalidSpecifier:
    case ConversionSpecifier::FreeBSDbArg:
    case ConversionSpecifier::FreeBSDDArg:
    case ConversionSpecifier::FreeBSDrArg:
    case ConversionSpecifier::FreeBSDyArg:
    case ConversionSpecifier::PrintErrno:
    case ConversionSpecifier::DArg:
    case ConversionSpecifier::OArg:
    case ConversionSpecifier::UArg:
    case ConversionSpecifier::ZArg:
      return false;
    case ConversionSpecifier::rArg:
    case ConversionSpecifier::RArg:
    case ConversionSpecifier::kArg:
    case ConversionSpecifier::KArg:
      return LangOpt.FixedPoint;
  }
  llvm_unreachable("Invalid ConversionSpecifier Kind!");
}

bool FormatSpecifier::hasStandardLengthConversionCombination() const {
  if (LM.getKind() == LengthModifier::AsLongDouble) {
    switch(CS.getKind()) {
        case ConversionSpecifier::dArg:
        case ConversionSpecifier::iArg:
        case ConversionSpecifier::oArg:
        case ConversionSpecifier::uArg:
        case ConversionSpecifier::xArg:
        case ConversionSpecifier::XArg:
          return false;
        default:
          return true;
    }
  }
  return true;
}

std::optional<LengthModifier>
FormatSpecifier::getCorrectedLengthModifier() const {
  if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
    if (LM.getKind() == LengthModifier::AsLongDouble ||
        LM.getKind() == LengthModifier::AsQuad) {
      LengthModifier FixedLM(LM);
      FixedLM.setKind(LengthModifier::AsLongLong);
      return FixedLM;
    }
  }

  return std::nullopt;
}

bool FormatSpecifier::namedTypeToLengthModifier(ASTContext &Ctx, QualType QT,
                                                LengthModifier &LM) {
  if (LengthModifier::Kind Out = LengthModifier::Kind::None;
      namedTypeToLengthModifierKind(Ctx, QT, Out)) {
    LM.setKind(Out);
    return true;
  }
  return false;
}
