//===--- 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/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, unsigned InlineWidth) {
  // 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 ((TypeWidth & (TypeWidth - 1)) == 0 && TypeWidth <= InlineWidth)
    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 = (uint32_t)TI.getTriple().getEnvironment() -
                            (uint32_t)llvm::Triple::Pixel;

    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
    // FIXME: Use correct value for C++23.
    if (LangOpts.CPlusPlus2b)
      Builder.defineMacro("__cplusplus", "202101L");
    //      [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.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 (LangOpts.GPUDefaultStream ==
        LangOptions::GPUDefaultStreamKind::PerThread)
      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.CPlusPlus2b   ? "202110L"
                                           : 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.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");
    Builder.defineMacro("__cpp_concepts", "201907L");
    Builder.defineMacro("__cpp_conditional_explicit", "201806L");
    //Builder.defineMacro("__cpp_consteval", "201811L");
    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++2b features.
  if (LangOpts.CPlusPlus2b) {
    Builder.defineMacro("__cpp_implicit_move", "202011L");
    Builder.defineMacro("__cpp_size_t_suffix", "202011L");
    Builder.defineMacro("__cpp_if_consteval", "202106L");
    Builder.defineMacro("__cpp_multidimensional_subscript", "202110L");
  }
  if (LangOpts.Char8)
    Builder.defineMacro("__cpp_char8_t", "201811L");
  Builder.defineMacro("__cpp_impl_destroying_delete", "201806L");

  // TS features.
  if (LangOpts.Coroutines)
    Builder.defineMacro("__cpp_coroutines", "201703L");
}

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

  // 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(0) == 64 && TI.getLongWidth() == 64
      && TI.getIntWidth() == 32) {
    Builder.defineMacro("_LP64");
    Builder.defineMacro("__LP64__");
  }

  if (TI.getPointerWidth(0) == 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(0), 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(0), TI, Builder);
  DefineTypeSizeof("__SIZEOF_SHORT__", TI.getShortWidth(), TI, Builder);
  DefineTypeSizeof("__SIZEOF_PTRDIFF_T__",
                   TI.getTypeWidth(TI.getPtrDiffType(0)), 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(0), Builder);
  DefineFmt("__PTRDIFF", TI.getPtrDiffType(0), 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(0)));

  // 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.
    unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth();
#define DEFINE_LOCK_FREE_MACRO(TYPE, Type)                                     \
  Builder.defineMacro(Prefix + #TYPE "_LOCK_FREE",                             \
                      getLockFreeValue(TI.get##Type##Width(),                  \
                                       InlineWidthBits));
    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(0),
                                         InlineWidthBits));
#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 51:
      Builder.defineMacro("_OPENMP", "202011");
      break;
    case 52:
      Builder.defineMacro("_OPENMP", "202111");
      break;
    case 50:
    default:
      // Default version is OpenMP 5.0
      Builder.defineMacro("_OPENMP", "201811");
      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");
  }

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

/// InitializePreprocessor - Initialize the preprocessor getting it and the
/// environment ready to process a single file. This returns true on error.
///
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.  We don't do
  // this in asm preprocessor mode, because "# 4" is not a line marker directive
  // in this mode.
  if (!PP.getLangOpts().AsmPreprocessor)
    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.OpenMPIsDevice || 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.
  if (!PP.getLangOpts().AsmPreprocessor)
    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).
  if (!PP.getLangOpts().AsmPreprocessor)
    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));
}
