//===--- 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"
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, MaxVal.toString(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(StringRef 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()));
}

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

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

  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);
  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);
  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 TypeAlign,
                                    unsigned InlineWidth) {
  // Fully-aligned, power-of-2 sizes no larger than the inline
  // width will be inlined as lock-free operations.
  if (TypeWidth == TypeAlign && (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) {
  // 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) {
    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) {
      if (LangOpts.OpenCLCPlusPlusVersion == 100)
        Builder.defineMacro("__OPENCL_CPP_VERSION__", "100");
      else
        llvm_unreachable("Unsupported C++ version for OpenCL");
      Builder.defineMacro("__CL_CPP_VERSION_1_0__", "100");
    } 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");
  }

  // Not "standard" per se, but available even with the -undef flag.
  if (LangOpts.AsmPreprocessor)
    Builder.defineMacro("__ASSEMBLER__");
  if (LangOpts.CUDA && !LangOpts.HIP)
    Builder.defineMacro("__CUDA__");
  if (LangOpts.HIP) {
    Builder.defineMacro("__HIP__");
    Builder.defineMacro("__HIPCC__");
    if (LangOpts.CUDAIsDevice)
      Builder.defineMacro("__HIP_DEVICE_COMPILE__");
  }
}

/// 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.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_coroutines", "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_size_t_suffix", "202011L");
  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");
}

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().getValueOr(0))));
    }

    if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW) {
      VersionTuple tuple = LangOpts.ObjCRuntime.getVersion();

      unsigned minor = 0;
      if (tuple.getMinor().hasValue())
        minor = tuple.getMinor().getValue();

      unsigned subminor = 0;
      if (tuple.getSubminor().hasValue())
        subminor = tuple.getSubminor().getValue();

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

  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);
  DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Builder);
  DefineTypeSize("__WINT_MAX__", TI.getWIntType(), TI, Builder);
  DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder);
  DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder);

  DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder);
  DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder);
  DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder);
  DefineTypeSize("__UINTPTR_MAX__", 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()));
  DefineTypeWidth("__INTMAX_WIDTH__",  TI.getIntMaxType(), TI, Builder);
  DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Builder);
  DefineFmt("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder);
  DefineTypeWidth("__PTRDIFF_WIDTH__", TI.getPtrDiffType(0), TI, Builder);
  DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
  DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder);
  DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Builder);
  DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
  DefineFmt("__SIZE", TI.getSizeType(), TI, Builder);
  DefineTypeWidth("__SIZE_WIDTH__", TI.getSizeType(), TI, Builder);
  DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
  DefineTypeWidth("__WCHAR_WIDTH__", TI.getWCharType(), TI, Builder);
  DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
  DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder);
  DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder);
  DefineTypeSize("__SIG_ATOMIC_MAX__", TI.getSigAtomicType(), TI, Builder);
  DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
  DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);

  DefineTypeWidth("__UINTMAX_WIDTH__",  TI.getUIntMaxType(), TI, Builder);
  DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
  DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
  DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder);

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

  char UserLabelPrefix[2] = {TI.getDataLayout().getGlobalPrefix(), 0};
  Builder.defineMacro("__USER_LABEL_PREFIX__", UserLabelPrefix);

  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(),                  \
                                       TI.get##Type##Align(),                  \
                                       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),
                                         TI.getPointerAlign(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_EVAL_METHOD__", Twine(TI.getFloatEvalMethod()));
  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;
    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) {
    TI.getOpenCLFeatureDefines(LangOpts, Builder);

    if (TI.getTriple().isSPIR())
      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(Predefines.str());
}
