//===--- InitPreprocessor.cpp - PP initialization code. ---------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the clang::InitializePreprocessor function.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Basic/DiagnosticLex.h"
#include "clang/Basic/HLSLRuntime.h"
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SyncScope.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
using namespace clang;

static bool MacroBodyEndsInBackslash(StringRef MacroBody) {
  while (!MacroBody.empty() && isWhitespace(MacroBody.back()))
    MacroBody = MacroBody.drop_back();
  return MacroBody.ends_with('\\');
}

// Append a #define line to Buf for Macro.  Macro should be of the form XXX,
// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
// "#define XXX Y z W".  To get a #define with no value, use "XXX=".
static void DefineBuiltinMacro(MacroBuilder &Builder, StringRef Macro,
                               DiagnosticsEngine &Diags) {
  std::pair<StringRef, StringRef> MacroPair = Macro.split('=');
  StringRef MacroName = MacroPair.first;
  StringRef MacroBody = MacroPair.second;
  if (MacroName.size() != Macro.size()) {
    // Per GCC -D semantics, the macro ends at \n if it exists.
    StringRef::size_type End = MacroBody.find_first_of("\n\r");
    if (End != StringRef::npos)
      Diags.Report(diag::warn_fe_macro_contains_embedded_newline)
        << MacroName;
    MacroBody = MacroBody.substr(0, End);
    // We handle macro bodies which end in a backslash by appending an extra
    // backslash+newline.  This makes sure we don't accidentally treat the
    // backslash as a line continuation marker.
    if (MacroBodyEndsInBackslash(MacroBody))
      Builder.defineMacro(MacroName, Twine(MacroBody) + "\\\n");
    else
      Builder.defineMacro(MacroName, MacroBody);
  } else {
    // Push "macroname 1".
    Builder.defineMacro(Macro);
  }
}

/// AddImplicitInclude - Add an implicit \#include of the specified file to the
/// predefines buffer.
/// As these includes are generated by -include arguments the header search
/// logic is going to search relatively to the current working directory.
static void AddImplicitInclude(MacroBuilder &Builder, StringRef File) {
  Builder.append(Twine("#include \"") + File + "\"");
}

static void AddImplicitIncludeMacros(MacroBuilder &Builder, StringRef File) {
  Builder.append(Twine("#__include_macros \"") + File + "\"");
  // Marker token to stop the __include_macros fetch loop.
  Builder.append("##"); // ##?
}

/// Add an implicit \#include using the original file used to generate
/// a PCH file.
static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP,
                                  const PCHContainerReader &PCHContainerRdr,
                                  StringRef ImplicitIncludePCH) {
  std::string OriginalFile = ASTReader::getOriginalSourceFile(
      std::string(ImplicitIncludePCH), PP.getFileManager(), PCHContainerRdr,
      PP.getDiagnostics());
  if (OriginalFile.empty())
    return;

  AddImplicitInclude(Builder, OriginalFile);
}

/// PickFP - This is used to pick a value based on the FP semantics of the
/// specified FP model.
template <typename T>
static T PickFP(const llvm::fltSemantics *Sem, T IEEEHalfVal, T IEEESingleVal,
                T IEEEDoubleVal, T X87DoubleExtendedVal, T PPCDoubleDoubleVal,
                T IEEEQuadVal) {
  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEhalf())
    return IEEEHalfVal;
  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle())
    return IEEESingleVal;
  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEdouble())
    return IEEEDoubleVal;
  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::x87DoubleExtended())
    return X87DoubleExtendedVal;
  if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::PPCDoubleDouble())
    return PPCDoubleDoubleVal;
  assert(Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad());
  return IEEEQuadVal;
}

static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
                              const llvm::fltSemantics *Sem, StringRef Ext) {
  const char *DenormMin, *NormMax, *Epsilon, *Max, *Min;
  NormMax = PickFP(Sem, "6.5504e+4", "3.40282347e+38",
                   "1.7976931348623157e+308", "1.18973149535723176502e+4932",
                   "8.98846567431157953864652595394501e+307",
                   "1.18973149535723176508575932662800702e+4932");
  DenormMin = PickFP(Sem, "5.9604644775390625e-8", "1.40129846e-45",
                     "4.9406564584124654e-324", "3.64519953188247460253e-4951",
                     "4.94065645841246544176568792868221e-324",
                     "6.47517511943802511092443895822764655e-4966");
  int Digits = PickFP(Sem, 3, 6, 15, 18, 31, 33);
  int DecimalDigits = PickFP(Sem, 5, 9, 17, 21, 33, 36);
  Epsilon = PickFP(Sem, "9.765625e-4", "1.19209290e-7",
                   "2.2204460492503131e-16", "1.08420217248550443401e-19",
                   "4.94065645841246544176568792868221e-324",
                   "1.92592994438723585305597794258492732e-34");
  int MantissaDigits = PickFP(Sem, 11, 24, 53, 64, 106, 113);
  int Min10Exp = PickFP(Sem, -4, -37, -307, -4931, -291, -4931);
  int Max10Exp = PickFP(Sem, 4, 38, 308, 4932, 308, 4932);
  int MinExp = PickFP(Sem, -13, -125, -1021, -16381, -968, -16381);
  int MaxExp = PickFP(Sem, 16, 128, 1024, 16384, 1024, 16384);
  Min = PickFP(Sem, "6.103515625e-5", "1.17549435e-38", "2.2250738585072014e-308",
               "3.36210314311209350626e-4932",
               "2.00416836000897277799610805135016e-292",
               "3.36210314311209350626267781732175260e-4932");
  Max = PickFP(Sem, "6.5504e+4", "3.40282347e+38", "1.7976931348623157e+308",
               "1.18973149535723176502e+4932",
               "1.79769313486231580793728971405301e+308",
               "1.18973149535723176508575932662800702e+4932");

  SmallString<32> DefPrefix;
  DefPrefix = "__";
  DefPrefix += Prefix;
  DefPrefix += "_";

  Builder.defineMacro(DefPrefix + "DENORM_MIN__", Twine(DenormMin)+Ext);
  Builder.defineMacro(DefPrefix + "NORM_MAX__", Twine(NormMax)+Ext);
  Builder.defineMacro(DefPrefix + "HAS_DENORM__");
  Builder.defineMacro(DefPrefix + "DIG__", Twine(Digits));
  Builder.defineMacro(DefPrefix + "DECIMAL_DIG__", Twine(DecimalDigits));
  Builder.defineMacro(DefPrefix + "EPSILON__", Twine(Epsilon)+Ext);
  Builder.defineMacro(DefPrefix + "HAS_INFINITY__");
  Builder.defineMacro(DefPrefix + "HAS_QUIET_NAN__");
  Builder.defineMacro(DefPrefix + "MANT_DIG__", Twine(MantissaDigits));

  Builder.defineMacro(DefPrefix + "MAX_10_EXP__", Twine(Max10Exp));
  Builder.defineMacro(DefPrefix + "MAX_EXP__", Twine(MaxExp));
  Builder.defineMacro(DefPrefix + "MAX__", Twine(Max)+Ext);

  Builder.defineMacro(DefPrefix + "MIN_10_EXP__","("+Twine(Min10Exp)+")");
  Builder.defineMacro(DefPrefix + "MIN_EXP__", "("+Twine(MinExp)+")");
  Builder.defineMacro(DefPrefix + "MIN__", Twine(Min)+Ext);
}


/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro
/// named MacroName with the max value for a type with width 'TypeWidth' a
/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL).
static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth,
                           StringRef ValSuffix, bool isSigned,
                           MacroBuilder &Builder) {
  llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth)
                                : llvm::APInt::getMaxValue(TypeWidth);
  Builder.defineMacro(MacroName, toString(MaxVal, 10, isSigned) + ValSuffix);
}

/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine
/// the width, suffix, and signedness of the given type
static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty,
                           const TargetInfo &TI, MacroBuilder &Builder) {
  DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty),
                 TI.isTypeSigned(Ty), Builder);
}

static void DefineTypeMin(const Twine &Prefix, TargetInfo::IntType Ty,
                          const TargetInfo &TI, MacroBuilder &Builder) {
  Builder.defineMacro(Prefix + "_MIN__",
                      TI.isTypeSigned(Ty)
                          ? Twine("(-") + Prefix + "_MAX__ - 1)"
                          : Twine("0") + TI.getTypeConstantSuffix(Ty));
}

static void DefineFmt(const LangOptions &LangOpts, const Twine &Prefix,
                      TargetInfo::IntType Ty, const TargetInfo &TI,
                      MacroBuilder &Builder) {
  StringRef FmtModifier = TI.getTypeFormatModifier(Ty);
  auto Emitter = [&](char Fmt) {
    Builder.defineMacro(Prefix + "_FMT" + Twine(Fmt) + "__",
                        Twine("\"") + FmtModifier + Twine(Fmt) + "\"");
  };
  bool IsSigned = TI.isTypeSigned(Ty);
  llvm::for_each(StringRef(IsSigned ? "di" : "ouxX"), Emitter);

  // C23 added the b and B modifiers for printing binary output of unsigned
  // integers. Conditionally define those if compiling in C23 mode.
  if (LangOpts.C23 && !IsSigned)
    llvm::for_each(StringRef("bB"), Emitter);
}

static void DefineType(const Twine &MacroName, TargetInfo::IntType Ty,
                       MacroBuilder &Builder) {
  Builder.defineMacro(MacroName, TargetInfo::getTypeName(Ty));
}

static void DefineTypeWidth(const Twine &MacroName, TargetInfo::IntType Ty,
                            const TargetInfo &TI, MacroBuilder &Builder) {
  Builder.defineMacro(MacroName, Twine(TI.getTypeWidth(Ty)));
}

static void DefineTypeSizeof(StringRef MacroName, unsigned BitWidth,
                             const TargetInfo &TI, MacroBuilder &Builder) {
  Builder.defineMacro(MacroName,
                      Twine(BitWidth / TI.getCharWidth()));
}

// This will generate a macro based on the prefix with `_MAX__` as the suffix
// for the max value representable for the type, and a macro with a `_WIDTH__`
// suffix for the width of the type.
static void DefineTypeSizeAndWidth(const Twine &Prefix, TargetInfo::IntType Ty,
                                   const TargetInfo &TI,
                                   MacroBuilder &Builder) {
  DefineTypeSize(Prefix + "_MAX__", Ty, TI, Builder);
  DefineTypeWidth(Prefix + "_WIDTH__", Ty, TI, Builder);
}

static void DefineExactWidthIntType(const LangOptions &LangOpts,
                                    TargetInfo::IntType Ty,
                                    const TargetInfo &TI,
                                    MacroBuilder &Builder) {
  int TypeWidth = TI.getTypeWidth(Ty);
  bool IsSigned = TI.isTypeSigned(Ty);

  // Use the target specified int64 type, when appropriate, so that [u]int64_t
  // ends up being defined in terms of the correct type.
  if (TypeWidth == 64)
    Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type();

  // Use the target specified int16 type when appropriate. Some MCU targets
  // (such as AVR) have definition of [u]int16_t to [un]signed int.
  if (TypeWidth == 16)
    Ty = IsSigned ? TI.getInt16Type() : TI.getUInt16Type();

  const char *Prefix = IsSigned ? "__INT" : "__UINT";

  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
  DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);

  StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
  Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
  Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C(c)",
                      ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
}

static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
                                        const TargetInfo &TI,
                                        MacroBuilder &Builder) {
  int TypeWidth = TI.getTypeWidth(Ty);
  bool IsSigned = TI.isTypeSigned(Ty);

  // Use the target specified int64 type, when appropriate, so that [u]int64_t
  // ends up being defined in terms of the correct type.
  if (TypeWidth == 64)
    Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type();

  // We don't need to define a _WIDTH macro for the exact-width types because
  // we already know the width.
  const char *Prefix = IsSigned ? "__INT" : "__UINT";
  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
}

static void DefineLeastWidthIntType(const LangOptions &LangOpts,
                                    unsigned TypeWidth, bool IsSigned,
                                    const TargetInfo &TI,
                                    MacroBuilder &Builder) {
  TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
  if (Ty == TargetInfo::NoInt)
    return;

  const char *Prefix = IsSigned ? "__INT_LEAST" : "__UINT_LEAST";
  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
  // We only want the *_WIDTH macro for the signed types to avoid too many
  // predefined macros (the unsigned width and the signed width are identical.)
  if (IsSigned)
    DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
  else
    DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
  DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
}

static void DefineFastIntType(const LangOptions &LangOpts, unsigned TypeWidth,
                              bool IsSigned, const TargetInfo &TI,
                              MacroBuilder &Builder) {
  // stdint.h currently defines the fast int types as equivalent to the least
  // types.
  TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
  if (Ty == TargetInfo::NoInt)
    return;

  const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST";
  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
  // We only want the *_WIDTH macro for the signed types to avoid too many
  // predefined macros (the unsigned width and the signed width are identical.)
  if (IsSigned)
    DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
  else
    DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
  DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
}


/// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with
/// the specified properties.
static const char *getLockFreeValue(unsigned TypeWidth, const TargetInfo &TI) {
  // Fully-aligned, power-of-2 sizes no larger than the inline
  // width will be inlined as lock-free operations.
  // Note: we do not need to check alignment since _Atomic(T) is always
  // appropriately-aligned in clang.
  if (TI.hasBuiltinAtomic(TypeWidth, TypeWidth))
    return "2"; // "always lock free"
  // We cannot be certain what operations the lib calls might be
  // able to implement as lock-free on future processors.
  return "1"; // "sometimes lock free"
}

/// Add definitions required for a smooth interaction between
/// Objective-C++ automated reference counting and libstdc++ (4.2).
static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts,
                                         MacroBuilder &Builder) {
  Builder.defineMacro("_GLIBCXX_PREDEFINED_OBJC_ARC_IS_SCALAR");

  std::string Result;
  {
    // Provide specializations for the __is_scalar type trait so that
    // lifetime-qualified objects are not considered "scalar" types, which
    // libstdc++ uses as an indicator of the presence of trivial copy, assign,
    // default-construct, and destruct semantics (none of which hold for
    // lifetime-qualified objects in ARC).
    llvm::raw_string_ostream Out(Result);

    Out << "namespace std {\n"
        << "\n"
        << "struct __true_type;\n"
        << "struct __false_type;\n"
        << "\n";

    Out << "template<typename _Tp> struct __is_scalar;\n"
        << "\n";

    if (LangOpts.ObjCAutoRefCount) {
      Out << "template<typename _Tp>\n"
          << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n"
          << "  enum { __value = 0 };\n"
          << "  typedef __false_type __type;\n"
          << "};\n"
          << "\n";
    }

    if (LangOpts.ObjCWeak) {
      Out << "template<typename _Tp>\n"
          << "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n"
          << "  enum { __value = 0 };\n"
          << "  typedef __false_type __type;\n"
          << "};\n"
          << "\n";
    }

    if (LangOpts.ObjCAutoRefCount) {
      Out << "template<typename _Tp>\n"
          << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))"
          << " _Tp> {\n"
          << "  enum { __value = 0 };\n"
          << "  typedef __false_type __type;\n"
          << "};\n"
          << "\n";
    }

    Out << "}\n";
  }
  Builder.append(Result);
}

static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
                                               const LangOptions &LangOpts,
                                               const FrontendOptions &FEOpts,
                                               MacroBuilder &Builder) {
  if (LangOpts.HLSL) {
    Builder.defineMacro("__hlsl_clang");
    // HLSL Version
    Builder.defineMacro("__HLSL_VERSION",
                        Twine((unsigned)LangOpts.getHLSLVersion()));
    Builder.defineMacro("__HLSL_202x",
                        Twine((unsigned)LangOptions::HLSLLangStd::HLSL_202x));
    Builder.defineMacro("__HLSL_202y",
                        Twine((unsigned)LangOptions::HLSLLangStd::HLSL_202y));

    if (LangOpts.NativeHalfType && LangOpts.NativeInt16Type)
      Builder.defineMacro("__HLSL_ENABLE_16_BIT", "1");

    // Shader target information
    // "enums" for shader stages
    Builder.defineMacro("__SHADER_STAGE_VERTEX",
                        Twine((uint32_t)ShaderStage::Vertex));
    Builder.defineMacro("__SHADER_STAGE_PIXEL",
                        Twine((uint32_t)ShaderStage::Pixel));
    Builder.defineMacro("__SHADER_STAGE_GEOMETRY",
                        Twine((uint32_t)ShaderStage::Geometry));
    Builder.defineMacro("__SHADER_STAGE_HULL",
                        Twine((uint32_t)ShaderStage::Hull));
    Builder.defineMacro("__SHADER_STAGE_DOMAIN",
                        Twine((uint32_t)ShaderStage::Domain));
    Builder.defineMacro("__SHADER_STAGE_COMPUTE",
                        Twine((uint32_t)ShaderStage::Compute));
    Builder.defineMacro("__SHADER_STAGE_AMPLIFICATION",
                        Twine((uint32_t)ShaderStage::Amplification));
    Builder.defineMacro("__SHADER_STAGE_MESH",
                        Twine((uint32_t)ShaderStage::Mesh));
    Builder.defineMacro("__SHADER_STAGE_LIBRARY",
                        Twine((uint32_t)ShaderStage::Library));
    // The current shader stage itself
    uint32_t StageInteger = static_cast<uint32_t>(
        hlsl::getStageFromEnvironment(TI.getTriple().getEnvironment()));

    Builder.defineMacro("__SHADER_TARGET_STAGE", Twine(StageInteger));
    // Add target versions
    if (TI.getTriple().getOS() == llvm::Triple::ShaderModel) {
      VersionTuple Version = TI.getTriple().getOSVersion();
      Builder.defineMacro("__SHADER_TARGET_MAJOR", Twine(Version.getMajor()));
      unsigned Minor = Version.getMinor().value_or(0);
      Builder.defineMacro("__SHADER_TARGET_MINOR", Twine(Minor));
    }
    return;
  }
  // C++ [cpp.predefined]p1:
  //   The following macro names shall be defined by the implementation:

  //   -- __STDC__
  //      [C++] Whether __STDC__ is predefined and if so, what its value is,
  //      are implementation-defined.
  // (Removed in C++20.)
  if ((!LangOpts.MSVCCompat || LangOpts.MSVCEnableStdcMacro) &&
      !LangOpts.TraditionalCPP)
    Builder.defineMacro("__STDC__");
  //   -- __STDC_HOSTED__
  //      The integer literal 1 if the implementation is a hosted
  //      implementation or the integer literal 0 if it is not.
  if (LangOpts.Freestanding)
    Builder.defineMacro("__STDC_HOSTED__", "0");
  else
    Builder.defineMacro("__STDC_HOSTED__");

  //   -- __STDC_VERSION__
  //      [C++] Whether __STDC_VERSION__ is predefined and if so, what its
  //      value is, are implementation-defined.
  // (Removed in C++20.)
  if (!LangOpts.CPlusPlus) {
    if (std::optional<uint32_t> Lang = LangOpts.getCLangStd())
      Builder.defineMacro("__STDC_VERSION__", Twine(*Lang) + "L");
  } else {
    //   -- __cplusplus
    Builder.defineMacro("__cplusplus",
                        Twine(*LangOpts.getCPlusPlusLangStd()) + "L");

    //   -- __STDCPP_DEFAULT_NEW_ALIGNMENT__
    //      [C++17] An integer literal of type std::size_t whose value is the
    //      alignment guaranteed by a call to operator new(std::size_t)
    //
    // We provide this in all language modes, since it seems generally useful.
    Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__",
                        Twine(TI.getNewAlign() / TI.getCharWidth()) +
                            TI.getTypeConstantSuffix(TI.getSizeType()));

    //   -- __STDCPP_­THREADS__
    //      Defined, and has the value integer literal 1, if and only if a
    //      program can have more than one thread of execution.
    if (LangOpts.getThreadModel() == LangOptions::ThreadModelKind::POSIX)
      Builder.defineMacro("__STDCPP_THREADS__", "1");
  }

  // In C11 these are environment macros. In C++11 they are only defined
  // as part of <cuchar>. To prevent breakage when mixing C and C++
  // code, define these macros unconditionally. We can define them
  // unconditionally, as Clang always uses UTF-16 and UTF-32 for 16-bit
  // and 32-bit character literals.
  Builder.defineMacro("__STDC_UTF_16__", "1");
  Builder.defineMacro("__STDC_UTF_32__", "1");

  // __has_embed definitions
  Builder.defineMacro("__STDC_EMBED_NOT_FOUND__",
                      llvm::itostr(static_cast<int>(EmbedResult::NotFound)));
  Builder.defineMacro("__STDC_EMBED_FOUND__",
                      llvm::itostr(static_cast<int>(EmbedResult::Found)));
  Builder.defineMacro("__STDC_EMBED_EMPTY__",
                      llvm::itostr(static_cast<int>(EmbedResult::Empty)));

  // We define this to '1' here to indicate that we only support '_Defer'
  // as a keyword.
  if (LangOpts.DeferTS)
    Builder.defineMacro("__STDC_DEFER_TS25755__", "1");

  if (LangOpts.ObjC)
    Builder.defineMacro("__OBJC__");

  // OpenCL v1.0/1.1 s6.9, v1.2/2.0 s6.10: Preprocessor Directives and Macros.
  if (LangOpts.OpenCL) {
    if (LangOpts.CPlusPlus) {
      switch (LangOpts.OpenCLCPlusPlusVersion) {
      case 100:
        Builder.defineMacro("__OPENCL_CPP_VERSION__", "100");
        break;
      case 202100:
        Builder.defineMacro("__OPENCL_CPP_VERSION__", "202100");
        break;
      default:
        llvm_unreachable("Unsupported C++ version for OpenCL");
      }
      Builder.defineMacro("__CL_CPP_VERSION_1_0__", "100");
      Builder.defineMacro("__CL_CPP_VERSION_2021__", "202100");
    } else {
      // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the
      // language standard with which the program is compiled. __OPENCL_VERSION__
      // is for the OpenCL version supported by the OpenCL device, which is not
      // necessarily the language standard with which the program is compiled.
      // A shared OpenCL header file requires a macro to indicate the language
      // standard. As a workaround, __OPENCL_C_VERSION__ is defined for
      // OpenCL v1.0 and v1.1.
      switch (LangOpts.OpenCLVersion) {
      case 100:
        Builder.defineMacro("__OPENCL_C_VERSION__", "100");
        break;
      case 110:
        Builder.defineMacro("__OPENCL_C_VERSION__", "110");
        break;
      case 120:
        Builder.defineMacro("__OPENCL_C_VERSION__", "120");
        break;
      case 200:
        Builder.defineMacro("__OPENCL_C_VERSION__", "200");
        break;
      case 300:
        Builder.defineMacro("__OPENCL_C_VERSION__", "300");
        break;
      case 310:
        Builder.defineMacro("__OPENCL_C_VERSION__", "310");
        break;
      default:
        llvm_unreachable("Unsupported OpenCL version");
      }
    }
    Builder.defineMacro("CL_VERSION_1_0", "100");
    Builder.defineMacro("CL_VERSION_1_1", "110");
    Builder.defineMacro("CL_VERSION_1_2", "120");
    Builder.defineMacro("CL_VERSION_2_0", "200");
    Builder.defineMacro("CL_VERSION_3_0", "300");
    Builder.defineMacro("CL_VERSION_3_1", "310");

    if (TI.isLittleEndian())
      Builder.defineMacro("__ENDIAN_LITTLE__");

    if (LangOpts.FastRelaxedMath)
      Builder.defineMacro("__FAST_RELAXED_MATH__");
  }

  if (LangOpts.SYCLIsDevice || LangOpts.SYCLIsHost) {
    // SYCL Version is set to a value when building SYCL applications
    if (LangOpts.getSYCLVersion() == LangOptions::SYCL_2017)
      Builder.defineMacro("CL_SYCL_LANGUAGE_VERSION", "121");
    else if (LangOpts.getSYCLVersion() == LangOptions::SYCL_2020)
      Builder.defineMacro("SYCL_LANGUAGE_VERSION", "202012L");
  }

  // Not "standard" per se, but available even with the -undef flag.
  if (LangOpts.AsmPreprocessor)
    Builder.defineMacro("__ASSEMBLER__");
  if (LangOpts.CUDA) {
    if (LangOpts.GPURelocatableDeviceCode)
      Builder.defineMacro("__CLANG_RDC__");
    if (!LangOpts.HIP)
      Builder.defineMacro("__CUDA__");
    if (LangOpts.GPUDefaultStream ==
        LangOptions::GPUDefaultStreamKind::PerThread)
      Builder.defineMacro("CUDA_API_PER_THREAD_DEFAULT_STREAM");
  }
  if (LangOpts.HIP) {
    Builder.defineMacro("__HIP__");
    Builder.defineMacro("__HIPCC__");
    Builder.defineMacro("__HIP_MEMORY_SCOPE_SINGLETHREAD", "1");
    Builder.defineMacro("__HIP_MEMORY_SCOPE_WAVEFRONT", "2");
    Builder.defineMacro("__HIP_MEMORY_SCOPE_WORKGROUP", "3");
    Builder.defineMacro("__HIP_MEMORY_SCOPE_AGENT", "4");
    Builder.defineMacro("__HIP_MEMORY_SCOPE_SYSTEM", "5");
    Builder.defineMacro("__HIP_MEMORY_SCOPE_CLUSTER", "6");
    if (LangOpts.HIPStdPar) {
      Builder.defineMacro("__HIPSTDPAR__");
      if (LangOpts.HIPStdParInterposeAlloc) {
        Builder.defineMacro("__HIPSTDPAR_INTERPOSE_ALLOC__");
        Builder.defineMacro("__HIPSTDPAR_INTERPOSE_ALLOC_V1__");
      }
    }
    if (LangOpts.CUDAIsDevice) {
      Builder.defineMacro("__HIP_DEVICE_COMPILE__");
      if (TI.getTriple().getEnvironment() == llvm::Triple::LLVM)
        Builder.defineMacro("__HIP_LLVM__");
      if (!TI.hasHIPImageSupport()) {
        Builder.defineMacro("__HIP_NO_IMAGE_SUPPORT__", "1");
        // Deprecated.
        Builder.defineMacro("__HIP_NO_IMAGE_SUPPORT", "1");
      }
    }
    if (LangOpts.GPUDefaultStream ==
        LangOptions::GPUDefaultStreamKind::PerThread) {
      Builder.defineMacro("__HIP_API_PER_THREAD_DEFAULT_STREAM__");
      // Deprecated.
      Builder.defineMacro("HIP_API_PER_THREAD_DEFAULT_STREAM");
    }
  }

  if (LangOpts.OpenACC)
    Builder.defineMacro("_OPENACC", "202506");
}

/// Initialize the predefined C++ language feature test macros defined in
/// ISO/IEC JTC1/SC22/WG21 (C++) SD-6: "SG10 Feature Test Recommendations".
static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
                                                 MacroBuilder &Builder,
                                                 const TargetInfo &TI) {
  // C++98 features.
  if (LangOpts.RTTI)
    Builder.defineMacro("__cpp_rtti", "199711L");
  if (LangOpts.CXXExceptions)
    Builder.defineMacro("__cpp_exceptions", "199711L");

  // C++11 features.
  if (LangOpts.CPlusPlus11) {
    Builder.defineMacro("__cpp_unicode_characters", "200704L");
    Builder.defineMacro("__cpp_raw_strings", "200710L");
    Builder.defineMacro("__cpp_unicode_literals", "200710L");
    Builder.defineMacro("__cpp_user_defined_literals", "200809L");
    Builder.defineMacro("__cpp_lambdas", "200907L");
    Builder.defineMacro("__cpp_constexpr", LangOpts.CPlusPlus26   ? "202406L"
                                           : LangOpts.CPlusPlus23 ? "202211L"
                                           : LangOpts.CPlusPlus20 ? "202002L"
                                           : LangOpts.CPlusPlus17 ? "201603L"
                                           : LangOpts.CPlusPlus14 ? "201304L"
                                                                  : "200704");
    Builder.defineMacro("__cpp_constexpr_in_decltype", "201711L");
    Builder.defineMacro("__cpp_range_based_for",
                        LangOpts.CPlusPlus23   ? "202211L"
                        : LangOpts.CPlusPlus17 ? "201603L"
                                               : "200907");
    // C++17 / C++26 static_assert supported as an extension in earlier language
    // modes, so we use the C++26 value.
    Builder.defineMacro("__cpp_static_assert", "202306L");
    Builder.defineMacro("__cpp_decltype", "200707L");
    Builder.defineMacro("__cpp_attributes", "200809L");
    Builder.defineMacro("__cpp_rvalue_references", "200610L");
    Builder.defineMacro("__cpp_variadic_templates", "200704L");
    Builder.defineMacro("__cpp_initializer_lists", "200806L");
    Builder.defineMacro("__cpp_delegating_constructors", "200604L");
    Builder.defineMacro("__cpp_nsdmi", "200809L");
    Builder.defineMacro("__cpp_inheriting_constructors", "201511L");
    Builder.defineMacro("__cpp_ref_qualifiers", "200710L");
    Builder.defineMacro("__cpp_alias_templates", "200704L");
  }
  if (LangOpts.ThreadsafeStatics)
    Builder.defineMacro("__cpp_threadsafe_static_init", "200806L");

  // C++14 features.
  if (LangOpts.CPlusPlus14) {
    Builder.defineMacro("__cpp_binary_literals", "201304L");
    Builder.defineMacro("__cpp_digit_separators", "201309L");
    Builder.defineMacro("__cpp_init_captures",
                        LangOpts.CPlusPlus20 ? "201803L" : "201304L");
    Builder.defineMacro("__cpp_generic_lambdas",
                        LangOpts.CPlusPlus20 ? "201707L" : "201304L");
    Builder.defineMacro("__cpp_decltype_auto", "201304L");
    Builder.defineMacro("__cpp_return_type_deduction", "201304L");
    Builder.defineMacro("__cpp_aggregate_nsdmi", "201304L");
    Builder.defineMacro("__cpp_variable_templates", "201304L");
  }
  if (LangOpts.SizedDeallocation)
    Builder.defineMacro("__cpp_sized_deallocation", "201309L");

  // C++17 features.
  if (LangOpts.CPlusPlus17) {
    Builder.defineMacro("__cpp_hex_float", "201603L");
    Builder.defineMacro("__cpp_inline_variables", "201606L");
    Builder.defineMacro("__cpp_noexcept_function_type", "201510L");
    Builder.defineMacro("__cpp_capture_star_this", "201603L");
    Builder.defineMacro("__cpp_if_constexpr", "201606L");
    Builder.defineMacro("__cpp_deduction_guides", "201703L"); // (not latest)
    Builder.defineMacro("__cpp_template_auto", "201606L"); // (old name)
    Builder.defineMacro("__cpp_namespace_attributes", "201411L");
    Builder.defineMacro("__cpp_enumerator_attributes", "201411L");
    Builder.defineMacro("__cpp_nested_namespace_definitions", "201411L");
    Builder.defineMacro("__cpp_variadic_using", "201611L");
    Builder.defineMacro("__cpp_aggregate_bases", "201603L");
    Builder.defineMacro("__cpp_structured_bindings", "202411L");
    Builder.defineMacro("__cpp_nontype_template_args",
                        "201411L"); // (not latest)
    Builder.defineMacro("__cpp_fold_expressions", "201603L");
    Builder.defineMacro("__cpp_guaranteed_copy_elision", "201606L");
    Builder.defineMacro("__cpp_nontype_template_parameter_auto", "201606L");
  }
  if (LangOpts.AlignedAllocation && !LangOpts.AlignedAllocationUnavailable)
    Builder.defineMacro("__cpp_aligned_new", "201606L");

  Builder.defineMacro("__cpp_template_template_args", "201611L");

  // C++20 features.
  if (LangOpts.CPlusPlus20) {
    Builder.defineMacro("__cpp_aggregate_paren_init", "201902L");

    Builder.defineMacro("__cpp_concepts", "202002");
    Builder.defineMacro("__cpp_conditional_explicit", "201806L");
    Builder.defineMacro("__cpp_consteval", "202211L");
    Builder.defineMacro("__cpp_constexpr_dynamic_alloc", "201907L");
    Builder.defineMacro("__cpp_constinit", "201907L");

    // Support for coroutines on 32-bit x86 Microsoft platforms is
    // incomplete, do not advertise it.
    if (!(TI.getCXXABI().isMicrosoft() && TI.getTriple().isX86_32()))
      Builder.defineMacro("__cpp_impl_coroutine", "201902L");

    Builder.defineMacro("__cpp_designated_initializers", "201707L");
    Builder.defineMacro("__cpp_impl_three_way_comparison", "201907L");
    // Intentionally to set __cpp_modules to 1.
    // See https://github.com/llvm/llvm-project/issues/71364 for details.
    // Builder.defineMacro("__cpp_modules", "201907L");
    Builder.defineMacro("__cpp_modules", "1");
    Builder.defineMacro("__cpp_using_enum", "201907L");
  }
  // C++23 features.
  if (LangOpts.CPlusPlus23) {
    Builder.defineMacro("__cpp_implicit_move", "202207L");
    Builder.defineMacro("__cpp_size_t_suffix", "202011L");
    Builder.defineMacro("__cpp_if_consteval", "202106L");
    Builder.defineMacro("__cpp_multidimensional_subscript", "202211L");
    Builder.defineMacro("__cpp_auto_cast", "202110L");
    Builder.defineMacro("__cpp_explicit_this_parameter", "202110L");
  }

  // We provide those C++23 features as extensions in earlier language modes, so
  // we also define their feature test macros.
  if (LangOpts.CPlusPlus11)
    Builder.defineMacro("__cpp_static_call_operator", "202207L");
  Builder.defineMacro("__cpp_named_character_escapes", "202606L");
  Builder.defineMacro("__cpp_placeholder_variables", "202306L");

  // C++26 features supported in earlier language modes.
  Builder.defineMacro("__cpp_pack_indexing", "202311L");
  Builder.defineMacro("__cpp_deleted_function", "202403L");
  Builder.defineMacro("__cpp_variadic_friend", "202403L");
  Builder.defineMacro("__cpp_trivial_relocatability", "202502L");

  if (LangOpts.Char8)
    Builder.defineMacro("__cpp_char8_t", "202207L");
  Builder.defineMacro("__cpp_impl_destroying_delete", "201806L");
}

/// InitializeOpenCLFeatureTestMacros - Define OpenCL macros based on target
/// settings and language version
void InitializeOpenCLFeatureTestMacros(const TargetInfo &TI,
                                       const LangOptions &Opts,
                                       MacroBuilder &Builder) {
  const llvm::StringMap<bool> &OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
  // FIXME: OpenCL options which affect language semantics/syntax
  // should be moved into LangOptions.
  auto defineOpenCLExtMacro = [&](llvm::StringRef Name, auto... OptArgs) {
    // Check if extension is supported by target and is available in this
    // OpenCL version
    if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Name) &&
        OpenCLOptions::isOpenCLOptionAvailableIn(Opts, OptArgs...))
      Builder.defineMacro(Name);
  };
#define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
  defineOpenCLExtMacro(#Ext, __VA_ARGS__);
#include "clang/Basic/OpenCLExtensions.def"

  // Assume compiling for FULL profile
  Builder.defineMacro("__opencl_c_int64");
}

llvm::SmallString<32> ConstructFixedPointLiteral(llvm::APFixedPoint Val,
                                                 llvm::StringRef Suffix) {
  if (Val.isSigned() && Val == llvm::APFixedPoint::getMin(Val.getSemantics())) {
    // When representing the min value of a signed fixed point type in source
    // code, we cannot simply write `-<lowest value>`. For example, the min
    // value of a `short _Fract` cannot be written as `-1.0hr`. This is because
    // the parser will read this (and really any negative numerical literal) as
    // a UnaryOperator that owns a FixedPointLiteral with a positive value
    // rather than just a FixedPointLiteral with a negative value. Compiling
    // `-1.0hr` results in an overflow to the maximal value of that fixed point
    // type. The correct way to represent a signed min value is to instead split
    // it into two halves, like `(-0.5hr-0.5hr)` which is what the standard
    // defines SFRACT_MIN as.
    llvm::SmallString<32> Literal;
    Literal.push_back('(');
    llvm::SmallString<32> HalfStr =
        ConstructFixedPointLiteral(Val.shr(1), Suffix);
    Literal += HalfStr;
    Literal += HalfStr;
    Literal.push_back(')');
    return Literal;
  }

  llvm::SmallString<32> Str(Val.toString());
  Str += Suffix;
  return Str;
}

void DefineFixedPointMacros(const TargetInfo &TI, MacroBuilder &Builder,
                            llvm::StringRef TypeName, llvm::StringRef Suffix,
                            unsigned Width, unsigned Scale, bool Signed) {
  // Saturation doesn't affect the size or scale of a fixed point type, so we
  // don't need it here.
  llvm::FixedPointSemantics FXSema(
      Width, Scale, Signed, /*IsSaturated=*/false,
      !Signed && TI.doUnsignedFixedPointTypesHavePadding());
  llvm::SmallString<32> MacroPrefix("__");
  MacroPrefix += TypeName;
  Builder.defineMacro(MacroPrefix + "_EPSILON__",
                      ConstructFixedPointLiteral(
                          llvm::APFixedPoint::getEpsilon(FXSema), Suffix));
  Builder.defineMacro(MacroPrefix + "_FBIT__", Twine(Scale));
  Builder.defineMacro(
      MacroPrefix + "_MAX__",
      ConstructFixedPointLiteral(llvm::APFixedPoint::getMax(FXSema), Suffix));

  // ISO/IEC TR 18037:2008 doesn't specify MIN macros for unsigned types since
  // they're all just zero.
  if (Signed)
    Builder.defineMacro(
        MacroPrefix + "_MIN__",
        ConstructFixedPointLiteral(llvm::APFixedPoint::getMin(FXSema), Suffix));
}

static void InitializePredefinedMacros(const TargetInfo &TI,
                                       const LangOptions &LangOpts,
                                       const FrontendOptions &FEOpts,
                                       const PreprocessorOptions &PPOpts,
                                       const CodeGenOptions &CGOpts,
                                       MacroBuilder &Builder) {
  // Compiler version introspection macros.
  Builder.defineMacro("__llvm__");  // LLVM Backend
  Builder.defineMacro("__clang__"); // Clang Frontend
#define TOSTR2(X) #X
#define TOSTR(X) TOSTR2(X)
  Builder.defineMacro("__clang_major__", TOSTR(CLANG_VERSION_MAJOR));
  Builder.defineMacro("__clang_minor__", TOSTR(CLANG_VERSION_MINOR));
  Builder.defineMacro("__clang_patchlevel__", TOSTR(CLANG_VERSION_PATCHLEVEL));
#undef TOSTR
#undef TOSTR2
  Builder.defineMacro("__clang_version__",
                      "\"" CLANG_VERSION_STRING " "
                      + getClangFullRepositoryVersion() + "\"");

  if (LangOpts.GNUCVersion != 0) {
    // Major, minor, patch, are given two decimal places each, so 4.2.1 becomes
    // 40201.
    unsigned GNUCMajor = LangOpts.GNUCVersion / 100 / 100;
    unsigned GNUCMinor = LangOpts.GNUCVersion / 100 % 100;
    unsigned GNUCPatch = LangOpts.GNUCVersion % 100;
    Builder.defineMacro("__GNUC__", Twine(GNUCMajor));
    Builder.defineMacro("__GNUC_MINOR__", Twine(GNUCMinor));
    Builder.defineMacro("__GNUC_PATCHLEVEL__", Twine(GNUCPatch));
    Builder.defineMacro("__GXX_ABI_VERSION", "1002");

    if (LangOpts.CPlusPlus) {
      Builder.defineMacro("__GNUG__", Twine(GNUCMajor));
      Builder.defineMacro("__GXX_WEAK__");
    }
  }

  // Define macros for the C11 / C++11 memory orderings
  Builder.defineMacro("__ATOMIC_RELAXED", "0");
  Builder.defineMacro("__ATOMIC_CONSUME", "1");
  Builder.defineMacro("__ATOMIC_ACQUIRE", "2");
  Builder.defineMacro("__ATOMIC_RELEASE", "3");
  Builder.defineMacro("__ATOMIC_ACQ_REL", "4");
  Builder.defineMacro("__ATOMIC_SEQ_CST", "5");

  // Define macros for the clang atomic scopes.
  Builder.defineMacro("__MEMORY_SCOPE_SYSTEM", "0");
  Builder.defineMacro("__MEMORY_SCOPE_DEVICE", "1");
  Builder.defineMacro("__MEMORY_SCOPE_WRKGRP", "2");
  Builder.defineMacro("__MEMORY_SCOPE_WVFRNT", "3");
  Builder.defineMacro("__MEMORY_SCOPE_SINGLE", "4");
  Builder.defineMacro("__MEMORY_SCOPE_CLUSTR", "5");

  // Define macros for the OpenCL memory scope.
  // The values should match AtomicScopeOpenCLModel::ID enum.
  static_assert(
      static_cast<unsigned>(AtomicScopeOpenCLModel::WorkGroup) == 1 &&
          static_cast<unsigned>(AtomicScopeOpenCLModel::Device) == 2 &&
          static_cast<unsigned>(AtomicScopeOpenCLModel::AllSVMDevices) == 3 &&
          static_cast<unsigned>(AtomicScopeOpenCLModel::SubGroup) == 4,
      "Invalid OpenCL memory scope enum definition");
  Builder.defineMacro("__OPENCL_MEMORY_SCOPE_WORK_ITEM", "0");
  Builder.defineMacro("__OPENCL_MEMORY_SCOPE_WORK_GROUP", "1");
  Builder.defineMacro("__OPENCL_MEMORY_SCOPE_DEVICE", "2");
  Builder.defineMacro("__OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES", "3");
  Builder.defineMacro("__OPENCL_MEMORY_SCOPE_SUB_GROUP", "4");

  // Define macros for floating-point data classes, used in __builtin_isfpclass.
  Builder.defineMacro("__FPCLASS_SNAN", "0x0001");
  Builder.defineMacro("__FPCLASS_QNAN", "0x0002");
  Builder.defineMacro("__FPCLASS_NEGINF", "0x0004");
  Builder.defineMacro("__FPCLASS_NEGNORMAL", "0x0008");
  Builder.defineMacro("__FPCLASS_NEGSUBNORMAL", "0x0010");
  Builder.defineMacro("__FPCLASS_NEGZERO", "0x0020");
  Builder.defineMacro("__FPCLASS_POSZERO", "0x0040");
  Builder.defineMacro("__FPCLASS_POSSUBNORMAL", "0x0080");
  Builder.defineMacro("__FPCLASS_POSNORMAL", "0x0100");
  Builder.defineMacro("__FPCLASS_POSINF", "0x0200");

  // Support for #pragma redefine_extname (Sun compatibility)
  Builder.defineMacro("__PRAGMA_REDEFINE_EXTNAME", "1");

  // Previously this macro was set to a string aiming to achieve compatibility
  // with GCC 4.2.1. Now, just return the full Clang version
  Builder.defineMacro("__VERSION__", "\"" +
                      Twine(getClangFullCPPVersion()) + "\"");

  // Initialize language-specific preprocessor defines.

  // Standard conforming mode?
  if (!LangOpts.GNUMode && !LangOpts.MSVCCompat)
    Builder.defineMacro("__STRICT_ANSI__");

  if (LangOpts.GNUCVersion && LangOpts.CPlusPlus11)
    Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__");

  if (TI.getTriple().isOSCygMing()) {
    // Set ABI defining macros for libstdc++ for MinGW and Cygwin, where the
    // default in libstdc++ differs from the defaults for this target.
    Builder.defineMacro("__GXX_TYPEINFO_EQUALITY_INLINE", "0");
  }

  if (LangOpts.ObjC) {
    if (LangOpts.ObjCRuntime.isNonFragile()) {
      Builder.defineMacro("__OBJC2__");

      if (LangOpts.ObjCExceptions)
        Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS");
    }

    if (LangOpts.getGC() != LangOptions::NonGC)
      Builder.defineMacro("__OBJC_GC__");

    if (LangOpts.ObjCRuntime.isNeXTFamily())
      Builder.defineMacro("__NEXT_RUNTIME__");

    if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::GNUstep) {
      auto version = LangOpts.ObjCRuntime.getVersion();
      // Don't rely on the tuple argument, because we can be asked to target
      // later ABIs than we actually support, so clamp these values to those
      // currently supported
      if (version >= VersionTuple(2, 0))
        Builder.defineMacro("__OBJC_GNUSTEP_RUNTIME_ABI__", "20");
      else
        Builder.defineMacro(
            "__OBJC_GNUSTEP_RUNTIME_ABI__",
            "1" + Twine(std::min(8U, version.getMinor().value_or(0))));
    }

    if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW) {
      VersionTuple tuple = LangOpts.ObjCRuntime.getVersion();
      unsigned minor = tuple.getMinor().value_or(0);
      unsigned subminor = tuple.getSubminor().value_or(0);
      Builder.defineMacro("__OBJFW_RUNTIME_ABI__",
                          Twine(tuple.getMajor() * 10000 + minor * 100 +
                                subminor));
    }

    Builder.defineMacro("IBOutlet", "__attribute__((iboutlet))");
    Builder.defineMacro("IBOutletCollection(ClassName)",
                        "__attribute__((iboutletcollection(ClassName)))");
    Builder.defineMacro("IBAction", "void)__attribute__((ibaction)");
    Builder.defineMacro("IBInspectable", "");
    Builder.defineMacro("IB_DESIGNABLE", "");
  }

  // Define a macro that describes the Objective-C boolean type even for C
  // and C++ since BOOL can be used from non Objective-C code.
  Builder.defineMacro("__OBJC_BOOL_IS_BOOL",
                      Twine(TI.useSignedCharForObjCBool() ? "0" : "1"));

  if (LangOpts.CPlusPlus)
    InitializeCPlusPlusFeatureTestMacros(LangOpts, Builder, TI);

  // darwin_constant_cfstrings controls this. This is also dependent
  // on other things like the runtime I believe.  This is set even for C code.
  if (!LangOpts.NoConstantCFStrings)
      Builder.defineMacro("__CONSTANT_CFSTRINGS__");

  if (LangOpts.ObjC)
    Builder.defineMacro("OBJC_NEW_PROPERTIES");

  if (LangOpts.PascalStrings)
    Builder.defineMacro("__PASCAL_STRINGS__");

  if (LangOpts.Blocks) {
    Builder.defineMacro("__block", "__attribute__((__blocks__(byref)))");
    Builder.defineMacro("__BLOCKS__");
  }

  if (!LangOpts.MSVCCompat && LangOpts.Exceptions)
    Builder.defineMacro("__EXCEPTIONS");
  if (LangOpts.GNUCVersion && LangOpts.RTTI)
    Builder.defineMacro("__GXX_RTTI");

  if (CGOpts.hasSjLjExceptions())
    Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
  else if (CGOpts.hasSEHExceptions())
    Builder.defineMacro("__SEH__");
  else if (CGOpts.hasDWARFExceptions() &&
           (TI.getTriple().isThumb() || TI.getTriple().isARM()))
    Builder.defineMacro("__ARM_DWARF_EH__");
  else if (CGOpts.hasWasmExceptions() && TI.getTriple().isWasm())
    Builder.defineMacro("__WASM_EXCEPTIONS__");

  if (LangOpts.Deprecated)
    Builder.defineMacro("__DEPRECATED");

  if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus)
    Builder.defineMacro("__private_extern__", "extern");

  if (LangOpts.MicrosoftExt) {
    if (LangOpts.WChar) {
      // wchar_t supported as a keyword.
      Builder.defineMacro("_WCHAR_T_DEFINED");
      Builder.defineMacro("_NATIVE_WCHAR_T_DEFINED");
    }
  }

  // Macros to help identify the narrow and wide character sets. This is set
  // to fexec-charset. If fexec-charset is not specified, the default is the
  // system charset.
  Builder.defineMacro("__clang_literal_encoding__",
                      Twine("\"" +
                            (LangOpts.LiteralEncoding.empty()
                                 ? TI.getDefaultOrdinaryLiteralEncoding()
                                 : LangOpts.LiteralEncoding) +
                            "\""));

  if (TI.getTypeWidth(TI.getWCharType()) >= 32) {
    // FIXME: 32-bit wchar_t signals UTF-32. This may change
    // if -fwide-exec-charset= is ever supported.
    Builder.defineMacro("__clang_wide_literal_encoding__", "\"UTF-32\"");
  } else {
    // FIXME: Less-than 32-bit wchar_t generally means UTF-16
    // (e.g., Windows, 32-bit IBM). This may need to be
    // updated if -fwide-exec-charset= is ever supported.
    Builder.defineMacro("__clang_wide_literal_encoding__", "\"UTF-16\"");
  }

  if (CGOpts.OptimizationLevel != 0)
    Builder.defineMacro("__OPTIMIZE__");
  if (CGOpts.OptimizeSize != 0)
    Builder.defineMacro("__OPTIMIZE_SIZE__");

  if (LangOpts.FastMath)
    Builder.defineMacro("__FAST_MATH__");

  // Initialize target-specific preprocessor defines.

  // __BYTE_ORDER__ was added in GCC 4.6. It's analogous
  // to the macro __BYTE_ORDER (no trailing underscores)
  // from glibc's <endian.h> header.
  // We don't support the PDP-11 as a target, but include
  // the define so it can still be compared against.
  Builder.defineMacro("__ORDER_LITTLE_ENDIAN__", "1234");
  Builder.defineMacro("__ORDER_BIG_ENDIAN__",    "4321");
  Builder.defineMacro("__ORDER_PDP_ENDIAN__",    "3412");
  if (TI.isBigEndian()) {
    Builder.defineMacro("__BYTE_ORDER__", "__ORDER_BIG_ENDIAN__");
    Builder.defineMacro("__BIG_ENDIAN__");
  } else {
    Builder.defineMacro("__BYTE_ORDER__", "__ORDER_LITTLE_ENDIAN__");
    Builder.defineMacro("__LITTLE_ENDIAN__");
  }

  if (TI.getPointerWidth(LangAS::Default) == 64 && TI.getLongWidth() == 64 &&
      TI.getIntWidth() == 32) {
    Builder.defineMacro("_LP64");
    Builder.defineMacro("__LP64__");
  }

  if (TI.getPointerWidth(LangAS::Default) == 32 && TI.getLongWidth() == 32 &&
      TI.getIntWidth() == 32) {
    Builder.defineMacro("_ILP32");
    Builder.defineMacro("__ILP32__");
  }

  // Define type sizing macros based on the target properties.
  assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
  Builder.defineMacro("__CHAR_BIT__", Twine(TI.getCharWidth()));

  // The macro is specifying the number of bits in the width, not the number of
  // bits the object requires for its in-memory representation, which is what
  // getBoolWidth() will return. The bool/_Bool data type is only ever one bit
  // wide. See C23 6.2.6.2p2 for the rules in C. Note that
  // C++23 [basic.fundamental]p10 allows an implementation-defined value
  // representation for bool; when lowering to LLVM, Clang represents bool as an
  // i8 in memory but as an i1 when the value is needed, so '1' is also correct
  // for C++.
  Builder.defineMacro("__BOOL_WIDTH__", "1");
  Builder.defineMacro("__SHRT_WIDTH__", Twine(TI.getShortWidth()));
  Builder.defineMacro("__INT_WIDTH__", Twine(TI.getIntWidth()));
  Builder.defineMacro("__LONG_WIDTH__", Twine(TI.getLongWidth()));
  Builder.defineMacro("__LLONG_WIDTH__", Twine(TI.getLongLongWidth()));

  size_t BitIntMaxWidth = TI.getMaxBitIntWidth();
  assert(BitIntMaxWidth <= llvm::IntegerType::MAX_INT_BITS &&
         "Target defined a max bit width larger than LLVM can support!");
  assert(BitIntMaxWidth >= TI.getLongLongWidth() &&
         "Target defined a max bit width smaller than the C standard allows!");
  Builder.defineMacro("__BITINT_MAXWIDTH__", Twine(BitIntMaxWidth));

  DefineTypeSize("__SCHAR_MAX__", TargetInfo::SignedChar, TI, Builder);
  DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder);
  DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder);
  DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, TI, Builder);
  DefineTypeSize("__LONG_LONG_MAX__", TargetInfo::SignedLongLong, TI, Builder);
  DefineTypeSizeAndWidth("__WCHAR", TI.getWCharType(), TI, Builder);
  DefineTypeMin("__WCHAR", TI.getWCharType(), TI, Builder);
  DefineTypeSizeAndWidth("__WINT", TI.getWIntType(), TI, Builder);
  DefineTypeMin("__WINT", TI.getWIntType(), TI, Builder);
  DefineTypeSizeAndWidth("__INTMAX", TI.getIntMaxType(), TI, Builder);
  DefineTypeSizeAndWidth("__SIZE", TI.getSizeType(), TI, Builder);

  DefineTypeSizeAndWidth("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
  DefineTypeSizeAndWidth("__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
                         Builder);
  DefineTypeSizeAndWidth("__INTPTR", TI.getIntPtrType(), TI, Builder);
  DefineTypeSizeAndWidth("__UINTPTR", TI.getUIntPtrType(), TI, Builder);

  DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder);
  DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder);
  DefineTypeSizeof("__SIZEOF_INT__", TI.getIntWidth(), TI, Builder);
  DefineTypeSizeof("__SIZEOF_LONG__", TI.getLongWidth(), TI, Builder);
  DefineTypeSizeof("__SIZEOF_LONG_DOUBLE__",TI.getLongDoubleWidth(),TI,Builder);
  DefineTypeSizeof("__SIZEOF_LONG_LONG__", TI.getLongLongWidth(), TI, Builder);
  DefineTypeSizeof("__SIZEOF_POINTER__", TI.getPointerWidth(LangAS::Default),
                   TI, Builder);
  DefineTypeSizeof("__SIZEOF_SHORT__", TI.getShortWidth(), TI, Builder);
  DefineTypeSizeof("__SIZEOF_PTRDIFF_T__",
                   TI.getTypeWidth(TI.getPtrDiffType(LangAS::Default)), TI,
                   Builder);
  DefineTypeSizeof("__SIZEOF_SIZE_T__",
                   TI.getTypeWidth(TI.getSizeType()), TI, Builder);
  DefineTypeSizeof("__SIZEOF_WCHAR_T__",
                   TI.getTypeWidth(TI.getWCharType()), TI, Builder);
  DefineTypeSizeof("__SIZEOF_WINT_T__",
                   TI.getTypeWidth(TI.getWIntType()), TI, Builder);
  if (TI.hasInt128Type())
    DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder);

  DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
  DefineFmt(LangOpts, "__INTMAX", TI.getIntMaxType(), TI, Builder);
  StringRef ConstSuffix(TI.getTypeConstantSuffix(TI.getIntMaxType()));
  Builder.defineMacro("__INTMAX_C_SUFFIX__", ConstSuffix);
  Builder.defineMacro("__INTMAX_C(c)",
                      ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
  DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
  DefineFmt(LangOpts, "__UINTMAX", TI.getUIntMaxType(), TI, Builder);
  ConstSuffix = TI.getTypeConstantSuffix(TI.getUIntMaxType());
  Builder.defineMacro("__UINTMAX_C_SUFFIX__", ConstSuffix);
  Builder.defineMacro("__UINTMAX_C(c)",
                      ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
  DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder);
  DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
            Builder);
  DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
  DefineFmt(LangOpts, "__INTPTR", TI.getIntPtrType(), TI, Builder);
  DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
  DefineFmt(LangOpts, "__SIZE", TI.getSizeType(), TI, Builder);
  DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
  DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
  DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
  DefineTypeMin("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
  if (LangOpts.C23)
    DefineType("__CHAR8_TYPE__", TI.UnsignedChar, Builder);
  DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
  DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);

  DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
  DefineFmt(LangOpts, "__UINTPTR", TI.getUIntPtrType(), TI, Builder);

  // The C standard requires the width of uintptr_t and intptr_t to be the same,
  // per 7.20.2.4p1. Same for intmax_t and uintmax_t, per 7.20.2.5p1.
  assert(TI.getTypeWidth(TI.getUIntPtrType()) ==
             TI.getTypeWidth(TI.getIntPtrType()) &&
         "uintptr_t and intptr_t have different widths?");
  assert(TI.getTypeWidth(TI.getUIntMaxType()) ==
             TI.getTypeWidth(TI.getIntMaxType()) &&
         "uintmax_t and intmax_t have different widths?");

  if (LangOpts.FixedPoint) {
    // Each unsigned type has the same width as their signed type.
    DefineFixedPointMacros(TI, Builder, "SFRACT", "HR", TI.getShortFractWidth(),
                           TI.getShortFractScale(), /*Signed=*/true);
    DefineFixedPointMacros(TI, Builder, "USFRACT", "UHR",
                           TI.getShortFractWidth(),
                           TI.getUnsignedShortFractScale(), /*Signed=*/false);
    DefineFixedPointMacros(TI, Builder, "FRACT", "R", TI.getFractWidth(),
                           TI.getFractScale(), /*Signed=*/true);
    DefineFixedPointMacros(TI, Builder, "UFRACT", "UR", TI.getFractWidth(),
                           TI.getUnsignedFractScale(), /*Signed=*/false);
    DefineFixedPointMacros(TI, Builder, "LFRACT", "LR", TI.getLongFractWidth(),
                           TI.getLongFractScale(), /*Signed=*/true);
    DefineFixedPointMacros(TI, Builder, "ULFRACT", "ULR",
                           TI.getLongFractWidth(),
                           TI.getUnsignedLongFractScale(), /*Signed=*/false);
    DefineFixedPointMacros(TI, Builder, "SACCUM", "HK", TI.getShortAccumWidth(),
                           TI.getShortAccumScale(), /*Signed=*/true);
    DefineFixedPointMacros(TI, Builder, "USACCUM", "UHK",
                           TI.getShortAccumWidth(),
                           TI.getUnsignedShortAccumScale(), /*Signed=*/false);
    DefineFixedPointMacros(TI, Builder, "ACCUM", "K", TI.getAccumWidth(),
                           TI.getAccumScale(), /*Signed=*/true);
    DefineFixedPointMacros(TI, Builder, "UACCUM", "UK", TI.getAccumWidth(),
                           TI.getUnsignedAccumScale(), /*Signed=*/false);
    DefineFixedPointMacros(TI, Builder, "LACCUM", "LK", TI.getLongAccumWidth(),
                           TI.getLongAccumScale(), /*Signed=*/true);
    DefineFixedPointMacros(TI, Builder, "ULACCUM", "ULK",
                           TI.getLongAccumWidth(),
                           TI.getUnsignedLongAccumScale(), /*Signed=*/false);

    Builder.defineMacro("__SACCUM_IBIT__", Twine(TI.getShortAccumIBits()));
    Builder.defineMacro("__USACCUM_IBIT__",
                        Twine(TI.getUnsignedShortAccumIBits()));
    Builder.defineMacro("__ACCUM_IBIT__", Twine(TI.getAccumIBits()));
    Builder.defineMacro("__UACCUM_IBIT__", Twine(TI.getUnsignedAccumIBits()));
    Builder.defineMacro("__LACCUM_IBIT__", Twine(TI.getLongAccumIBits()));
    Builder.defineMacro("__ULACCUM_IBIT__",
                        Twine(TI.getUnsignedLongAccumIBits()));
  }

  if (TI.hasFloat16Type())
    DefineFloatMacros(Builder, "FLT16", &TI.getHalfFormat(), "F16");
  DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
  DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
  DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L");

  // Define a __POINTER_WIDTH__ macro for stdint.h.
  Builder.defineMacro("__POINTER_WIDTH__",
                      Twine((int)TI.getPointerWidth(LangAS::Default)));

  // Define __BIGGEST_ALIGNMENT__ to be compatible with gcc.
  Builder.defineMacro("__BIGGEST_ALIGNMENT__",
                      Twine(TI.getSuitableAlign() / TI.getCharWidth()) );

  if (!LangOpts.CharIsSigned)
    Builder.defineMacro("__CHAR_UNSIGNED__");

  if (!TargetInfo::isTypeSigned(TI.getWCharType()))
    Builder.defineMacro("__WCHAR_UNSIGNED__");

  if (!TargetInfo::isTypeSigned(TI.getWIntType()))
    Builder.defineMacro("__WINT_UNSIGNED__");

  // Define exact-width integer types for stdint.h
  DefineExactWidthIntType(LangOpts, TargetInfo::SignedChar, TI, Builder);

  if (TI.getShortWidth() > TI.getCharWidth())
    DefineExactWidthIntType(LangOpts, TargetInfo::SignedShort, TI, Builder);

  if (TI.getIntWidth() > TI.getShortWidth())
    DefineExactWidthIntType(LangOpts, TargetInfo::SignedInt, TI, Builder);

  if (TI.getLongWidth() > TI.getIntWidth())
    DefineExactWidthIntType(LangOpts, TargetInfo::SignedLong, TI, Builder);

  if (TI.getLongLongWidth() > TI.getLongWidth())
    DefineExactWidthIntType(LangOpts, TargetInfo::SignedLongLong, TI, Builder);

  DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedChar, TI, Builder);
  DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder);
  DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder);

  if (TI.getShortWidth() > TI.getCharWidth()) {
    DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedShort, TI, Builder);
    DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder);
    DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder);
  }

  if (TI.getIntWidth() > TI.getShortWidth()) {
    DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedInt, TI, Builder);
    DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder);
    DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder);
  }

  if (TI.getLongWidth() > TI.getIntWidth()) {
    DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLong, TI, Builder);
    DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder);
    DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder);
  }

  if (TI.getLongLongWidth() > TI.getLongWidth()) {
    DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLongLong, TI,
                            Builder);
    DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder);
    DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder);
  }

  DefineLeastWidthIntType(LangOpts, 8, true, TI, Builder);
  DefineLeastWidthIntType(LangOpts, 8, false, TI, Builder);
  DefineLeastWidthIntType(LangOpts, 16, true, TI, Builder);
  DefineLeastWidthIntType(LangOpts, 16, false, TI, Builder);
  DefineLeastWidthIntType(LangOpts, 32, true, TI, Builder);
  DefineLeastWidthIntType(LangOpts, 32, false, TI, Builder);
  DefineLeastWidthIntType(LangOpts, 64, true, TI, Builder);
  DefineLeastWidthIntType(LangOpts, 64, false, TI, Builder);

  DefineFastIntType(LangOpts, 8, true, TI, Builder);
  DefineFastIntType(LangOpts, 8, false, TI, Builder);
  DefineFastIntType(LangOpts, 16, true, TI, Builder);
  DefineFastIntType(LangOpts, 16, false, TI, Builder);
  DefineFastIntType(LangOpts, 32, true, TI, Builder);
  DefineFastIntType(LangOpts, 32, false, TI, Builder);
  DefineFastIntType(LangOpts, 64, true, TI, Builder);
  DefineFastIntType(LangOpts, 64, false, TI, Builder);

  Builder.defineMacro("__USER_LABEL_PREFIX__", TI.getUserLabelPrefix());

  if (!LangOpts.MathErrno)
    Builder.defineMacro("__NO_MATH_ERRNO__");

  if (LangOpts.FastMath || (LangOpts.NoHonorInfs && LangOpts.NoHonorNaNs))
    Builder.defineMacro("__FINITE_MATH_ONLY__", "1");
  else
    Builder.defineMacro("__FINITE_MATH_ONLY__", "0");

  if (LangOpts.GNUCVersion) {
    if (LangOpts.GNUInline || LangOpts.CPlusPlus)
      Builder.defineMacro("__GNUC_GNU_INLINE__");
    else
      Builder.defineMacro("__GNUC_STDC_INLINE__");

    // The value written by __atomic_test_and_set.
    // FIXME: This is target-dependent.
    Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1");
  }

  // GCC defines these macros in both C and C++ modes despite them being needed
  // mostly for STL implementations in C++.
  auto [Destructive, Constructive] = TI.hardwareInterferenceSizes();
  Builder.defineMacro("__GCC_DESTRUCTIVE_SIZE", Twine(Destructive));
  Builder.defineMacro("__GCC_CONSTRUCTIVE_SIZE", Twine(Constructive));
  // We need to use push_macro to allow users to redefine these macros from the
  // command line with -D and not issue a -Wmacro-redefined warning.
  Builder.append("#pragma push_macro(\"__GCC_DESTRUCTIVE_SIZE\")");
  Builder.append("#pragma push_macro(\"__GCC_CONSTRUCTIVE_SIZE\")");

  auto addLockFreeMacros = [&](const llvm::Twine &Prefix) {
    // Used by libc++ and libstdc++ to implement ATOMIC_<foo>_LOCK_FREE.
#define DEFINE_LOCK_FREE_MACRO(TYPE, Type)                                     \
  Builder.defineMacro(Prefix + #TYPE "_LOCK_FREE",                             \
                      getLockFreeValue(TI.get##Type##Width(), TI));
    DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
    DEFINE_LOCK_FREE_MACRO(CHAR, Char);
    // char8_t has the same representation / width as unsigned
    // char in C++ and is a typedef for unsigned char in C23
    if (LangOpts.Char8 || LangOpts.C23)
      DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
    DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
    DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
    DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
    DEFINE_LOCK_FREE_MACRO(SHORT, Short);
    DEFINE_LOCK_FREE_MACRO(INT, Int);
    DEFINE_LOCK_FREE_MACRO(LONG, Long);
    DEFINE_LOCK_FREE_MACRO(LLONG, LongLong);
    Builder.defineMacro(
        Prefix + "POINTER_LOCK_FREE",
        getLockFreeValue(TI.getPointerWidth(LangAS::Default), TI));
#undef DEFINE_LOCK_FREE_MACRO
  };
  addLockFreeMacros("__CLANG_ATOMIC_");
  if (LangOpts.GNUCVersion)
    addLockFreeMacros("__GCC_ATOMIC_");

  if (CGOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining)
    Builder.defineMacro("__NO_INLINE__");

  if (unsigned PICLevel = LangOpts.PICLevel) {
    Builder.defineMacro("__PIC__", Twine(PICLevel));
    Builder.defineMacro("__pic__", Twine(PICLevel));
    if (LangOpts.PIE) {
      Builder.defineMacro("__PIE__", Twine(PICLevel));
      Builder.defineMacro("__pie__", Twine(PICLevel));
    }
  }

  // Macros to control C99 numerics and <float.h>
  Builder.defineMacro("__FLT_RADIX__", "2");
  Builder.defineMacro("__DECIMAL_DIG__", "__LDBL_DECIMAL_DIG__");

  if (LangOpts.getStackProtector() == LangOptions::SSPOn)
    Builder.defineMacro("__SSP__");
  else if (LangOpts.getStackProtector() == LangOptions::SSPStrong)
    Builder.defineMacro("__SSP_STRONG__", "2");
  else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
    Builder.defineMacro("__SSP_ALL__", "3");

  if (PPOpts.SetUpStaticAnalyzer)
    Builder.defineMacro("__clang_analyzer__");

  if (LangOpts.FastRelaxedMath)
    Builder.defineMacro("__FAST_RELAXED_MATH__");

  if (FEOpts.ProgramAction == frontend::RewriteObjC ||
      LangOpts.getGC() != LangOptions::NonGC) {
    Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
    Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
    Builder.defineMacro("__autoreleasing", "");
    Builder.defineMacro("__unsafe_unretained", "");
  } else if (LangOpts.ObjC) {
    Builder.defineMacro("__weak", "__attribute__((objc_ownership(weak)))");
    Builder.defineMacro("__strong", "__attribute__((objc_ownership(strong)))");
    Builder.defineMacro("__autoreleasing",
                        "__attribute__((objc_ownership(autoreleasing)))");
    Builder.defineMacro("__unsafe_unretained",
                        "__attribute__((objc_ownership(none)))");
  }

  // On Darwin, there are __double_underscored variants of the type
  // nullability qualifiers.
  if (TI.getTriple().isOSDarwin()) {
    Builder.defineMacro("__nonnull", "_Nonnull");
    Builder.defineMacro("__null_unspecified", "_Null_unspecified");
    Builder.defineMacro("__nullable", "_Nullable");
  }

  // Add a macro to differentiate between regular iOS/tvOS/watchOS targets and
  // the corresponding simulator targets.
  if (TI.getTriple().isOSDarwin() && TI.getTriple().isSimulatorEnvironment())
    Builder.defineMacro("__APPLE_EMBEDDED_SIMULATOR__", "1");

  // OpenMP definition
  // OpenMP 2.2:
  //   In implementations that support a preprocessor, the _OPENMP
  //   macro name is defined to have the decimal value yyyymm where
  //   yyyy and mm are the year and the month designations of the
  //   version of the OpenMP API that the implementation support.
  if (!LangOpts.OpenMPSimd) {
    switch (LangOpts.OpenMP) {
    case 0:
      break;
    case 31:
      Builder.defineMacro("_OPENMP", "201107");
      break;
    case 40:
      Builder.defineMacro("_OPENMP", "201307");
      break;
    case 45:
      Builder.defineMacro("_OPENMP", "201511");
      break;
    case 50:
      Builder.defineMacro("_OPENMP", "201811");
      break;
    case 51:
      Builder.defineMacro("_OPENMP", "202011");
      break;
    case 52:
      Builder.defineMacro("_OPENMP", "202111");
      break;
    case 60:
      Builder.defineMacro("_OPENMP", "202411");
      break;
    default: // case 51:
      // Default version is OpenMP 5.1
      Builder.defineMacro("_OPENMP", "202011");
      break;
    }
  }

  // CUDA device path compilaton
  if (LangOpts.CUDAIsDevice && !LangOpts.HIP) {
    // The CUDA_ARCH value is set for the GPU target specified in the NVPTX
    // backend's target defines.
    Builder.defineMacro("__CUDA_ARCH__");
  }

  // We need to communicate this to our CUDA/HIP header wrapper, which in turn
  // informs the proper CUDA/HIP headers of this choice.
  if (LangOpts.GPUDeviceApproxTranscendentals)
    Builder.defineMacro("__CLANG_GPU_APPROX_TRANSCENDENTALS__");

  // Define a macro indicating that the source file is being compiled with a
  // SYCL device compiler which doesn't produce host binary.
  if (LangOpts.SYCLIsDevice) {
    Builder.defineMacro("__SYCL_DEVICE_ONLY__", "1");
  }

  // OpenCL definitions.
  if (LangOpts.OpenCL) {
    InitializeOpenCLFeatureTestMacros(TI, LangOpts, Builder);

    if (TI.getTriple().isSPIR() || TI.getTriple().isSPIRV())
      Builder.defineMacro("__IMAGE_SUPPORT__");
  }

  if (TI.hasInt128Type() && LangOpts.CPlusPlus && LangOpts.GNUMode) {
    // For each extended integer type, g++ defines a macro mapping the
    // index of the type (0 in this case) in some list of extended types
    // to the type.
    Builder.defineMacro("__GLIBCXX_TYPE_INT_N_0", "__int128");
    Builder.defineMacro("__GLIBCXX_BITSIZE_INT_N_0", "128");
  }

  // ELF targets define __ELF__
  if (TI.getTriple().isOSBinFormatELF())
    Builder.defineMacro("__ELF__");

  if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Address |
                                 SanitizerKind::KernelAddress))
    Builder.defineMacro("__SANITIZE_ADDRESS__");
  if (LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
                                 SanitizerKind::KernelHWAddress))
    Builder.defineMacro("__SANITIZE_HWADDRESS__");
  if (LangOpts.Sanitize.has(SanitizerKind::Thread))
    Builder.defineMacro("__SANITIZE_THREAD__");
  if (LangOpts.Sanitize.has(SanitizerKind::AllocToken))
    Builder.defineMacro("__SANITIZE_ALLOC_TOKEN__");

  if (LangOpts.PointerFieldProtectionABI)
    Builder.defineMacro("__POINTER_FIELD_PROTECTION_ABI__");
  if (LangOpts.PointerFieldProtectionTagged)
    Builder.defineMacro("__POINTER_FIELD_PROTECTION_TAGGED__");

  // Target OS macro definitions.
  if (PPOpts.DefineTargetOSMacros) {
    const llvm::Triple &Triple = TI.getTriple();
#define TARGET_OS(Name, Predicate)                                             \
  Builder.defineMacro(#Name, (Predicate) ? "1" : "0");
#include "clang/Basic/TargetOSMacros.def"
#undef TARGET_OS
  }

  if (LangOpts.PointerAuthIntrinsics)
    Builder.defineMacro("__PTRAUTH__");

  if (CGOpts.Dwarf2CFIAsm)
    Builder.defineMacro("__GCC_HAVE_DWARF2_CFI_ASM");

  // Get other target #defines.
  TI.getTargetDefines(LangOpts, Builder);
}

static void InitializePGOProfileMacros(const CodeGenOptions &CodeGenOpts,
                                       MacroBuilder &Builder) {
  if (CodeGenOpts.hasProfileInstr())
    Builder.defineMacro("__LLVM_INSTR_PROFILE_GENERATE");

  if (CodeGenOpts.hasProfileIRUse() || CodeGenOpts.hasProfileClangUse())
    Builder.defineMacro("__LLVM_INSTR_PROFILE_USE");
}

/// InitializePreprocessor - Initialize the preprocessor getting it and the
/// environment ready to process a single file.
void clang::InitializePreprocessor(Preprocessor &PP,
                                   const PreprocessorOptions &InitOpts,
                                   const PCHContainerReader &PCHContainerRdr,
                                   const FrontendOptions &FEOpts,
                                   const CodeGenOptions &CodeGenOpts) {
  const LangOptions &LangOpts = PP.getLangOpts();
  std::string PredefineBuffer;
  PredefineBuffer.reserve(4080);
  llvm::raw_string_ostream Predefines(PredefineBuffer);
  MacroBuilder Builder(Predefines);

  // Ensure that the initial value of __COUNTER__ is hooked up.
  PP.setCounterValue(InitOpts.InitialCounterValue);

  // Emit line markers for various builtin sections of the file. The 3 here
  // marks <built-in> as being a system header, which suppresses warnings when
  // the same macro is defined multiple times.
  Builder.append("# 1 \"<built-in>\" 3");

  // Install things like __POWERPC__, __GNUC__, etc into the macro table.
  if (InitOpts.UsePredefines) {
    // FIXME: This will create multiple definitions for most of the predefined
    // macros. This is not the right way to handle this.
    if ((LangOpts.CUDA || LangOpts.isTargetDevice()) && PP.getAuxTargetInfo())
      InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
                                 PP.getPreprocessorOpts(), CodeGenOpts,
                                 Builder);

    InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts,
                               PP.getPreprocessorOpts(), CodeGenOpts, Builder);

    // Install definitions to make Objective-C++ ARC work well with various
    // C++ Standard Library implementations.
    if (LangOpts.ObjC && LangOpts.CPlusPlus &&
        (LangOpts.ObjCAutoRefCount || LangOpts.ObjCWeak)) {
      switch (InitOpts.ObjCXXARCStandardLibrary) {
      case ARCXX_nolib:
      case ARCXX_libcxx:
        break;

      case ARCXX_libstdcxx:
        AddObjCXXARCLibstdcxxDefines(LangOpts, Builder);
        break;
      }
    }
  }

  // Even with predefines off, some macros are still predefined.
  // These should all be defined in the preprocessor according to the
  // current language configuration.
  InitializeStandardPredefinedMacros(PP.getTargetInfo(), PP.getLangOpts(),
                                     FEOpts, Builder);

  // The PGO instrumentation profile macros are driven by options
  // -fprofile[-instr]-generate/-fcs-profile-generate/-fprofile[-instr]-use,
  // hence they are not guarded by InitOpts.UsePredefines.
  InitializePGOProfileMacros(CodeGenOpts, Builder);

  // Add on the predefines from the driver.  Wrap in a #line directive to report
  // that they come from the command line.
  Builder.append("# 1 \"<command line>\" 1");

  // Process #define's and #undef's in the order they are given.
  for (unsigned i = 0, e = InitOpts.Macros.size(); i != e; ++i) {
    if (InitOpts.Macros[i].second)  // isUndef
      Builder.undefineMacro(InitOpts.Macros[i].first);
    else
      DefineBuiltinMacro(Builder, InitOpts.Macros[i].first,
                         PP.getDiagnostics());
  }

  // Exit the command line and go back to <built-in> (2 is LC_LEAVE).
  Builder.append("# 1 \"<built-in>\" 2");

  // If -imacros are specified, include them now.  These are processed before
  // any -include directives.
  for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i)
    AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i]);

  // Process -include-pch/-include-pth directives.
  if (!InitOpts.ImplicitPCHInclude.empty())
    AddImplicitIncludePCH(Builder, PP, PCHContainerRdr,
                          InitOpts.ImplicitPCHInclude);

  // Process -include directives.
  for (unsigned i = 0, e = InitOpts.Includes.size(); i != e; ++i) {
    const std::string &Path = InitOpts.Includes[i];
    AddImplicitInclude(Builder, Path);
  }

  // Instruct the preprocessor to skip the preamble.
  PP.setSkipMainFilePreamble(InitOpts.PrecompiledPreambleBytes.first,
                             InitOpts.PrecompiledPreambleBytes.second);

  // Copy PredefinedBuffer into the Preprocessor.
  PP.setPredefines(std::move(PredefineBuffer));

  // Match gcc behavior regarding gnu-line-directive diagnostics, assuming that
  // '-x <*>-cpp-output' is analogous to '-fpreprocessed'.
  if (FEOpts.DashX.isPreprocessed()) {
    PP.getDiagnostics().setSeverity(diag::ext_pp_gnu_line_directive,
                                    diag::Severity::Ignored, SourceLocation());

    // Compiling with -xc++-cpp-output should suppress module directive
    // recognition. __preprocessed_module can either get the directive treatment
    // or be accepted directly by phase 7 in a module declaration. In the latter
    // case, __preprocessed_module will work even if there are preprocessing
    // tokens on the same line that precede it.
    PP.markMainFileAsPreprocessedModuleFile();
  }
}
