// 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 *ED = argTy->getAsEnumDecl()) {
        // 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.
        if (!ED->isComplete())
          return NoMatch;
        if (!ED->isScoped())
          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 auto *ED = argTy->getAsEnumDecl()) {
        // 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.
        if (!ED->isComplete())
          argTy = C.IntTy;
        else if (!ED->isScoped())
          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->isStructureType() || 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;
}
