//===--- 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/FileManager.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/FrontendDiagnostic.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.empty() && MacroBody.back() == '\\';
}

// 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, *Epsilon, *Max, *Min;
  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 + "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 DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty,
                      const TargetInfo &TI, MacroBuilder &Builder) {
  bool IsSigned = TI.isTypeSigned(Ty);
  StringRef FmtModifier = TI.getTypeFormatModifier(Ty);
  for (const char *Fmt = IsSigned ? "di" : "ouxX"; *Fmt; ++Fmt) {
    Builder.defineMacro(Prefix + "_FMT" + Twine(*Fmt) + "__",
                        Twine("\"") + FmtModifier + Twine(*Fmt) + "\"");
  }
}

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(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(Prefix + Twine(TypeWidth), Ty, TI, Builder);

  StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
  Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
}

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(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(Prefix + Twine(TypeWidth), Ty, TI, Builder);
}

static void DefineFastIntType(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(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()));

    if (LangOpts.NativeHalfType)
      Builder.defineMacro("__HLSL_ENABLE_16_BIT",
                          Twine((unsigned)LangOpts.getHLSLVersion()));

    // 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.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) {
    // FIXME: Use correct value for C23.
    if (LangOpts.C2x)
      Builder.defineMacro("__STDC_VERSION__", "202000L");
    else if (LangOpts.C17)
      Builder.defineMacro("__STDC_VERSION__", "201710L");
    else if (LangOpts.C11)
      Builder.defineMacro("__STDC_VERSION__", "201112L");
    else if (LangOpts.C99)
      Builder.defineMacro("__STDC_VERSION__", "199901L");
    else if (!LangOpts.GNUMode && LangOpts.Digraphs)
      Builder.defineMacro("__STDC_VERSION__", "199409L");
  } else {
    //   -- __cplusplus
    if (LangOpts.CPlusPlus26)
      // FIXME: Use correct value for C++26.
      Builder.defineMacro("__cplusplus", "202400L");
    else if (LangOpts.CPlusPlus23)
      Builder.defineMacro("__cplusplus", "202302L");
    //      [C++20] The integer literal 202002L.
    else if (LangOpts.CPlusPlus20)
      Builder.defineMacro("__cplusplus", "202002L");
    //      [C++17] The integer literal 201703L.
    else if (LangOpts.CPlusPlus17)
      Builder.defineMacro("__cplusplus", "201703L");
    //      [C++14] The name __cplusplus is defined to the value 201402L when
    //      compiling a C++ translation unit.
    else if (LangOpts.CPlusPlus14)
      Builder.defineMacro("__cplusplus", "201402L");
    //      [C++11] The name __cplusplus is defined to the value 201103L when
    //      compiling a C++ translation unit.
    else if (LangOpts.CPlusPlus11)
      Builder.defineMacro("__cplusplus", "201103L");
    //      [C++03] The name __cplusplus is defined to the value 199711L when
    //      compiling a C++ translation unit.
    else
      Builder.defineMacro("__cplusplus", "199711L");

    //   -- __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");

  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;
      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");

    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", "202001");
  }

  // 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");
    if (LangOpts.CUDAIsDevice) {
      Builder.defineMacro("__HIP_DEVICE_COMPILE__");
      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");
    }
  }
}

/// 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) {
  // 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   ? "202306L"
                                           : LangOpts.CPlusPlus23 ? "202211L"
                                           : LangOpts.CPlusPlus20 ? "201907L"
                                           : LangOpts.CPlusPlus17 ? "201603L"
                                           : LangOpts.CPlusPlus14 ? "201304L"
                                                                  : "200704");
    Builder.defineMacro("__cpp_constexpr_in_decltype", "201711L");
    Builder.defineMacro("__cpp_range_based_for",
                        LangOpts.CPlusPlus17 ? "201603L" : "200907");
    Builder.defineMacro("__cpp_static_assert", LangOpts.CPlusPlus26 ? "202306L"
                                               : LangOpts.CPlusPlus17
                                                   ? "201411L"
                                                   : "200410");
    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", "201606L");
    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");
  if (LangOpts.RelaxedTemplateTemplateArgs)
    Builder.defineMacro("__cpp_template_template_args", "201611L");

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

    // P0848 is implemented, but we're still waiting for other concepts
    // issues to be addressed before bumping __cpp_concepts up to 202002L.
    // Refer to the discussion of this at https://reviews.llvm.org/D128619.
    Builder.defineMacro("__cpp_concepts", "201907L");
    Builder.defineMacro("__cpp_conditional_explicit", "201806L");
    Builder.defineMacro("__cpp_consteval", "202211L");
    Builder.defineMacro("__cpp_constexpr_dynamic_alloc", "201907L");
    Builder.defineMacro("__cpp_constinit", "201907L");
    Builder.defineMacro("__cpp_impl_coroutine", "201902L");
    Builder.defineMacro("__cpp_designated_initializers", "201707L");
    Builder.defineMacro("__cpp_impl_three_way_comparison", "201907L");
    //Builder.defineMacro("__cpp_modules", "201907L");
    Builder.defineMacro("__cpp_using_enum", "201907L");
  }
  // C++23 features.
  if (LangOpts.CPlusPlus23) {
    Builder.defineMacro("__cpp_implicit_move", "202011L");
    Builder.defineMacro("__cpp_size_t_suffix", "202011L");
    Builder.defineMacro("__cpp_if_consteval", "202106L");
    Builder.defineMacro("__cpp_multidimensional_subscript", "202211L");
  }

  // 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", "202207L");

  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");
}

static void InitializePredefinedMacros(const TargetInfo &TI,
                                       const LangOptions &LangOpts,
                                       const FrontendOptions &FEOpts,
                                       const PreprocessorOptions &PPOpts,
                                       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 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 (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();
      std::string versionString = "1";
      // 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);

  // 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 (LangOpts.hasSjLjExceptions())
    Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
  else if (LangOpts.hasSEHExceptions())
    Builder.defineMacro("__SEH__");
  else if (LangOpts.hasDWARFExceptions() &&
           (TI.getTriple().isThumb() || TI.getTriple().isARM()))
    Builder.defineMacro("__ARM_DWARF_EH__");

  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
  // FIXME: clang currently ignores -fexec-charset=. If this changes,
  // then this may need to be updated.
  Builder.defineMacro("__clang_literal_encoding__", "\"UTF-8\"");
  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 (LangOpts.Optimize)
    Builder.defineMacro("__OPTIMIZE__");
  if (LangOpts.OptimizeSize)
    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()));

  Builder.defineMacro("__BOOL_WIDTH__", Twine(TI.getBoolWidth()));
  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);
  DefineTypeSizeAndWidth("__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("__INTMAX", TI.getIntMaxType(), TI, Builder);
  Builder.defineMacro("__INTMAX_C_SUFFIX__",
                      TI.getTypeConstantSuffix(TI.getIntMaxType()));
  DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
  DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
  Builder.defineMacro("__UINTMAX_C_SUFFIX__",
                      TI.getTypeConstantSuffix(TI.getUIntMaxType()));
  DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder);
  DefineFmt("__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI, Builder);
  DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
  DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder);
  DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
  DefineFmt("__SIZE", TI.getSizeType(), TI, Builder);
  DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
  DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
  DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
  DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
  DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);

  DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
  DefineFmt("__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 (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(TargetInfo::SignedChar, TI, Builder);

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

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

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

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

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

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

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

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

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

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

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

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

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

  if (LangOpts.FastMath || LangOpts.FiniteMathOnly)
    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");
  }

  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);
    if (LangOpts.Char8)
      DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like 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 (LangOpts.NoInlineDefine)
    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 52:
      Builder.defineMacro("_OPENMP", "202111");
      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 header wrapper, which in turn
  // informs the proper CUDA headers of this choice.
  if (LangOpts.CUDADeviceApproxTranscendentals || LangOpts.FastMath) {
    Builder.defineMacro("__CLANG_CUDA_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__");

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

/// 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 LangOptions &LangOpts = PP.getLangOpts();
  std::string PredefineBuffer;
  PredefineBuffer.reserve(4080);
  llvm::raw_string_ostream Predefines(PredefineBuffer);
  MacroBuilder Builder(Predefines);

  // 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.OpenMPIsTargetDevice ||
         LangOpts.SYCLIsDevice) &&
        PP.getAuxTargetInfo())
      InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
                                 PP.getPreprocessorOpts(), Builder);

    InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts,
                               PP.getPreprocessorOpts(), 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);

  // 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));
}
