//===--- 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, 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(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();

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

  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) {
    // 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 && !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__");
  }
}

/// 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_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");
  }
  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().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);

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

  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;
    case 51:
      Builder.defineMacro("_OPENMP", "202011");
      break;
    case 52:
      Builder.defineMacro("_OPENMP", "202111");
      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) {
    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(Predefines.str());
}
