Switch builtin strings to use string tables (#118734)
The Clang binary (and any binary linking Clang as a library), when built
using PIE, ends up with a pretty shocking number of dynamic relocations
to apply to the executable image: roughly 400k.
Each of these takes up binary space in the executable, and perhaps most
interestingly takes start-up time to apply the relocations.
The largest pattern I identified were the strings used to describe
target builtins. The addresses of these string literals were stored into
huge arrays, each one requiring a dynamic relocation. The way to avoid
this is to design the target builtins to use a single large table of
strings and offsets within the table for the individual strings. This
switches the builtin management to such a scheme.
This saves over 100k dynamic relocations by my measurement, an over 25%
reduction. Just looking at byte size improvements, using the `bloaty`
tool to compare a newly built `clang` binary to an old one:
```
FILE SIZE VM SIZE
-------------- --------------
+1.4% +653Ki +1.4% +653Ki .rodata
+0.0% +960 +0.0% +960 .text
+0.0% +197 +0.0% +197 .dynstr
+0.0% +184 +0.0% +184 .eh_frame
+0.0% +96 +0.0% +96 .dynsym
+0.0% +40 +0.0% +40 .eh_frame_hdr
+114% +32 [ = ] 0 [Unmapped]
+0.0% +20 +0.0% +20 .gnu.hash
+0.0% +8 +0.0% +8 .gnu.version
+0.9% +7 +0.9% +7 [LOAD #2 [R]]
[ = ] 0 -75.4% -3.00Ki .relro_padding
-16.1% -802Ki -16.1% -802Ki .data.rel.ro
-27.3% -2.52Mi -27.3% -2.52Mi .rela.dyn
-1.6% -2.66Mi -1.6% -2.66Mi TOTAL
```
We get a 16% reduction in the `.data.rel.ro` section, and nearly 30%
reduction in `.rela.dyn` where those reloctaions are stored.
This is also visible in my benchmarking of binary start-up overhead at
least:
```
Benchmark 1: ./old_clang --version
Time (mean ± σ): 17.6 ms ± 1.5 ms [User: 4.1 ms, System: 13.3 ms]
Range (min … max): 14.2 ms … 22.8 ms 162 runs
Benchmark 2: ./new_clang --version
Time (mean ± σ): 15.5 ms ± 1.4 ms [User: 3.6 ms, System: 11.8 ms]
Range (min … max): 12.4 ms … 20.3 ms 216 runs
Summary
'./new_clang --version' ran
1.13 ± 0.14 times faster than './old_clang --version'
```
We get about 2ms faster `--version` runs. While there is a lot of noise
in binary execution time, this delta is pretty consistent, and
represents over 10% improvement. This is particularly interesting to me
because for very short source files, repeatedly starting the `clang`
binary is actually the dominant cost. For example, `configure` scripts
running against the `clang` compiler are slow in large part because of
binary start up time, not the time to process the actual inputs to the
compiler.
----
This PR implements the string tables using `constexpr` code and the
existing macro system. I understand that the builtins are moving towards
a TableGen model, and if complete that would provide more options for
modeling this. Unfortunately, that migration isn't complete, and even
the parts that are migrated still rely on the ability to break out of
the TableGen model and directly expand an X-macro style `BUILTIN(...)`
textually. I looked at trying to complete the move to TableGen, but it
would both require the difficult migration of the remaining targets, and
solving some tricky problems with how to move away from any macro-based
expansion.
I was also able to find a reasonably clean and effective way of doing
this with the existing macros and some `constexpr` code that I think is
clean enough to be a pretty good intermediate state, and maybe give a
good target for the eventual TableGen solution. I was also able to
factor the macros into set of consistent patterns that avoids a
significant regression in overall boilerplate.
This commit is contained in:
@@ -55,6 +55,7 @@ struct HeaderDesc {
|
||||
#undef HEADER
|
||||
} ID;
|
||||
|
||||
constexpr HeaderDesc() : ID() {}
|
||||
constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
|
||||
|
||||
const char *getName() const;
|
||||
@@ -68,14 +69,140 @@ enum ID {
|
||||
FirstTSBuiltin
|
||||
};
|
||||
|
||||
// The info used to represent each builtin.
|
||||
struct Info {
|
||||
llvm::StringLiteral Name;
|
||||
const char *Type, *Attributes;
|
||||
const char *Features;
|
||||
// Rather than store pointers to the string literals describing these four
|
||||
// aspects of builtins, we store offsets into a common string table.
|
||||
struct StrOffsets {
|
||||
int Name;
|
||||
int Type;
|
||||
int Attributes;
|
||||
int Features;
|
||||
} Offsets;
|
||||
|
||||
HeaderDesc Header;
|
||||
LanguageID Langs;
|
||||
};
|
||||
|
||||
// The storage for `N` builtins. This contains a single pointer to the string
|
||||
// table used for these builtins and an array of metadata for each builtin.
|
||||
template <size_t N> struct Storage {
|
||||
const char *StringTable;
|
||||
|
||||
std::array<Info, N> Infos;
|
||||
|
||||
// A constexpr function to construct the storage for a a given string table in
|
||||
// the first argument and an array in the second argument. This is *only*
|
||||
// expected to be used at compile time, we should mark it `consteval` when
|
||||
// available.
|
||||
//
|
||||
// The `Infos` array is particularly special. This function expects an array
|
||||
// of `Info` structs, where the string offsets of each entry refer to the
|
||||
// *sizes* of those strings rather than their offsets, and for the target
|
||||
// string to be in the provided string table at an offset the sum of all
|
||||
// previous string sizes. This function walks the `Infos` array computing the
|
||||
// running sum and replacing the sizes with the actual offsets in the string
|
||||
// table that should be used. This arrangement is designed to make it easy to
|
||||
// expand `.def` and `.inc` files with X-macros to construct both the string
|
||||
// table and the `Info` structs in the arguments to this function.
|
||||
static constexpr Storage<N> Make(const char *Strings,
|
||||
std::array<Info, N> Infos) {
|
||||
// Translate lengths to offsets.
|
||||
int Offset = 0;
|
||||
for (auto &I : Infos) {
|
||||
Info::StrOffsets NewOffsets = {};
|
||||
NewOffsets.Name = Offset;
|
||||
Offset += I.Offsets.Name;
|
||||
NewOffsets.Type = Offset;
|
||||
Offset += I.Offsets.Type;
|
||||
NewOffsets.Attributes = Offset;
|
||||
Offset += I.Offsets.Attributes;
|
||||
NewOffsets.Features = Offset;
|
||||
Offset += I.Offsets.Features;
|
||||
I.Offsets = NewOffsets;
|
||||
}
|
||||
return {Strings, Infos};
|
||||
}
|
||||
};
|
||||
|
||||
// A detail macro used below to emit a string literal that, after string literal
|
||||
// concatenation, ends up triggering the `-Woverlength-strings` warning. While
|
||||
// the warning is useful in general to catch accidentally excessive strings,
|
||||
// here we are creating them intentionally.
|
||||
//
|
||||
// This relies on a subtle aspect of `_Pragma`: that the *diagnostic* ones don't
|
||||
// turn into actual tokens that would disrupt string literal concatenation.
|
||||
#ifdef __clang__
|
||||
#define CLANG_BUILTIN_DETAIL_STR_TABLE(S) \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Woverlength-strings\"") \
|
||||
S _Pragma("clang diagnostic pop")
|
||||
#else
|
||||
#define CLANG_BUILTIN_DETAIL_STR_TABLE(S) S
|
||||
#endif
|
||||
|
||||
// A macro that can be used with `Builtins.def` and similar files as an X-macro
|
||||
// to add the string arguments to a builtin string table. This is typically the
|
||||
// target for the `BUILTIN`, `LANGBUILTIN`, or `LIBBUILTIN` macros in those
|
||||
// files.
|
||||
#define CLANG_BUILTIN_STR_TABLE(ID, TYPE, ATTRS) \
|
||||
CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" /*FEATURE*/ "\0")
|
||||
|
||||
// A macro that can be used with target builtin `.def` and `.inc` files as an
|
||||
// X-macro to add the string arguments to a builtin string table. this is
|
||||
// typically the target for the `TARGET_BUILTIN` macro.
|
||||
#define CLANG_TARGET_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, FEATURE) \
|
||||
CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0")
|
||||
|
||||
// A macro that can be used with target builtin `.def` and `.inc` files as an
|
||||
// X-macro to add the string arguments to a builtin string table. this is
|
||||
// typically the target for the `TARGET_HEADER_BUILTIN` macro. We can't delegate
|
||||
// to `TARGET_BUILTIN` because the `FEATURE` string changes position.
|
||||
#define CLANG_TARGET_HEADER_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, HEADER, LANGS, \
|
||||
FEATURE) \
|
||||
CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0")
|
||||
|
||||
// A detail macro used internally to compute the desired string table
|
||||
// `StrOffsets` struct for arguments to `Storage::Make`.
|
||||
#define CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS) \
|
||||
Builtin::Info::StrOffsets { \
|
||||
sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("") \
|
||||
}
|
||||
|
||||
// A detail macro used internally to compute the desired string table
|
||||
// `StrOffsets` struct for arguments to `Storage::Make`.
|
||||
#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE) \
|
||||
Builtin::Info::StrOffsets { \
|
||||
sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE) \
|
||||
}
|
||||
|
||||
// A set of macros that can be used with builtin `.def' files as an X-macro to
|
||||
// create an `Info` struct for a particular builtin. It both computes the
|
||||
// `StrOffsets` value for the string table (the lengths here, translated to
|
||||
// offsets by the Storage::Make function), and the other metadata for each
|
||||
// builtin.
|
||||
//
|
||||
// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
|
||||
// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
|
||||
#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS) \
|
||||
Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \
|
||||
HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG) \
|
||||
Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \
|
||||
HeaderDesc::NO_HEADER, LANG},
|
||||
#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG) \
|
||||
Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \
|
||||
HeaderDesc::HEADER, LANG},
|
||||
#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE) \
|
||||
Builtin::Info{ \
|
||||
CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE), \
|
||||
HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG, \
|
||||
FEATURE) \
|
||||
Builtin::Info{ \
|
||||
CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE), \
|
||||
HeaderDesc::HEADER, LANG},
|
||||
|
||||
/// Holds information about both target-independent and
|
||||
/// target-specific builtins, allowing easy queries by clients.
|
||||
///
|
||||
@@ -83,8 +210,11 @@ struct Info {
|
||||
/// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
|
||||
/// be translated back with getAuxBuiltinID() before use.
|
||||
class Context {
|
||||
llvm::ArrayRef<Info> TSRecords;
|
||||
llvm::ArrayRef<Info> AuxTSRecords;
|
||||
const char *TSStrTable = nullptr;
|
||||
const char *AuxTSStrTable = nullptr;
|
||||
|
||||
llvm::ArrayRef<Info> TSInfos;
|
||||
llvm::ArrayRef<Info> AuxTSInfos;
|
||||
|
||||
public:
|
||||
Context() = default;
|
||||
@@ -100,12 +230,13 @@ public:
|
||||
|
||||
/// Return the identifier name for the specified builtin,
|
||||
/// e.g. "__builtin_abs".
|
||||
llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
|
||||
llvm::StringRef getName(unsigned ID) const;
|
||||
|
||||
/// Get the type descriptor string for the specified builtin.
|
||||
const char *getTypeString(unsigned ID) const {
|
||||
return getRecord(ID).Type;
|
||||
}
|
||||
const char *getTypeString(unsigned ID) const;
|
||||
|
||||
/// Get the attributes descriptor string for the specified builtin.
|
||||
const char *getAttributesString(unsigned ID) const;
|
||||
|
||||
/// Return true if this function is a target-specific builtin.
|
||||
bool isTSBuiltin(unsigned ID) const {
|
||||
@@ -114,40 +245,40 @@ public:
|
||||
|
||||
/// Return true if this function has no side effects.
|
||||
bool isPure(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'U') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'U') != nullptr;
|
||||
}
|
||||
|
||||
/// Return true if this function has no side effects and doesn't
|
||||
/// read memory.
|
||||
bool isConst(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'c') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'c') != nullptr;
|
||||
}
|
||||
|
||||
/// Return true if we know this builtin never throws an exception.
|
||||
bool isNoThrow(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'n') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'n') != nullptr;
|
||||
}
|
||||
|
||||
/// Return true if we know this builtin never returns.
|
||||
bool isNoReturn(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'r') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'r') != nullptr;
|
||||
}
|
||||
|
||||
/// Return true if we know this builtin can return twice.
|
||||
bool isReturnsTwice(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'j') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'j') != nullptr;
|
||||
}
|
||||
|
||||
/// Returns true if this builtin does not perform the side-effects
|
||||
/// of its arguments.
|
||||
bool isUnevaluated(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'u') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'u') != nullptr;
|
||||
}
|
||||
|
||||
/// Return true if this is a builtin for a libc/libm function,
|
||||
/// with a "__builtin_" prefix (e.g. __builtin_abs).
|
||||
bool isLibFunction(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'F') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'F') != nullptr;
|
||||
}
|
||||
|
||||
/// Determines whether this builtin is a predefined libc/libm
|
||||
@@ -158,21 +289,21 @@ public:
|
||||
/// they do not, but they are recognized as builtins once we see
|
||||
/// a declaration.
|
||||
bool isPredefinedLibFunction(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'f') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'f') != nullptr;
|
||||
}
|
||||
|
||||
/// Returns true if this builtin requires appropriate header in other
|
||||
/// compilers. In Clang it will work even without including it, but we can emit
|
||||
/// a warning about missing header.
|
||||
bool isHeaderDependentFunction(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'h') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'h') != nullptr;
|
||||
}
|
||||
|
||||
/// Determines whether this builtin is a predefined compiler-rt/libgcc
|
||||
/// function, such as "__clear_cache", where we know the signature a
|
||||
/// priori.
|
||||
bool isPredefinedRuntimeFunction(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'i') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'i') != nullptr;
|
||||
}
|
||||
|
||||
/// Determines whether this builtin is a C++ standard library function
|
||||
@@ -180,7 +311,7 @@ public:
|
||||
/// specialization, where the signature is determined by the standard library
|
||||
/// declaration.
|
||||
bool isInStdNamespace(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'z') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'z') != nullptr;
|
||||
}
|
||||
|
||||
/// Determines whether this builtin can have its address taken with no
|
||||
@@ -194,33 +325,33 @@ public:
|
||||
|
||||
/// Determines whether this builtin has custom typechecking.
|
||||
bool hasCustomTypechecking(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 't') != nullptr;
|
||||
return strchr(getAttributesString(ID), 't') != nullptr;
|
||||
}
|
||||
|
||||
/// Determines whether a declaration of this builtin should be recognized
|
||||
/// even if the type doesn't match the specified signature.
|
||||
bool allowTypeMismatch(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
|
||||
return strchr(getAttributesString(ID), 'T') != nullptr ||
|
||||
hasCustomTypechecking(ID);
|
||||
}
|
||||
|
||||
/// Determines whether this builtin has a result or any arguments which
|
||||
/// are pointer types.
|
||||
bool hasPtrArgsOrResult(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Type, '*') != nullptr;
|
||||
return strchr(getTypeString(ID), '*') != nullptr;
|
||||
}
|
||||
|
||||
/// Return true if this builtin has a result or any arguments which are
|
||||
/// reference types.
|
||||
bool hasReferenceArgsOrResult(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Type, '&') != nullptr ||
|
||||
strchr(getRecord(ID).Type, 'A') != nullptr;
|
||||
return strchr(getTypeString(ID), '&') != nullptr ||
|
||||
strchr(getTypeString(ID), 'A') != nullptr;
|
||||
}
|
||||
|
||||
/// If this is a library function that comes from a specific
|
||||
/// header, retrieve that header name.
|
||||
const char *getHeaderName(unsigned ID) const {
|
||||
return getRecord(ID).Header.getName();
|
||||
return getInfo(ID).Header.getName();
|
||||
}
|
||||
|
||||
/// Determine whether this builtin is like printf in its
|
||||
@@ -245,27 +376,25 @@ public:
|
||||
/// Such functions can be const when the MathErrno lang option and FP
|
||||
/// exceptions are disabled.
|
||||
bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'e') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'e') != nullptr;
|
||||
}
|
||||
|
||||
bool isConstWithoutExceptions(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'g') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'g') != nullptr;
|
||||
}
|
||||
|
||||
const char *getRequiredFeatures(unsigned ID) const {
|
||||
return getRecord(ID).Features;
|
||||
}
|
||||
const char *getRequiredFeatures(unsigned ID) const;
|
||||
|
||||
unsigned getRequiredVectorWidth(unsigned ID) const;
|
||||
|
||||
/// Return true if builtin ID belongs to AuxTarget.
|
||||
bool isAuxBuiltinID(unsigned ID) const {
|
||||
return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
|
||||
return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
|
||||
}
|
||||
|
||||
/// Return real builtin ID (i.e. ID it would have during compilation
|
||||
/// for AuxTarget).
|
||||
unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
|
||||
unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
|
||||
|
||||
/// Returns true if this is a libc/libm function without the '__builtin_'
|
||||
/// prefix.
|
||||
@@ -277,16 +406,20 @@ public:
|
||||
|
||||
/// Return true if this function can be constant evaluated by Clang frontend.
|
||||
bool isConstantEvaluated(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'E') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'E') != nullptr;
|
||||
}
|
||||
|
||||
/// Returns true if this is an immediate (consteval) function
|
||||
bool isImmediate(unsigned ID) const {
|
||||
return strchr(getRecord(ID).Attributes, 'G') != nullptr;
|
||||
return strchr(getAttributesString(ID), 'G') != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
const Info &getRecord(unsigned ID) const;
|
||||
std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
|
||||
|
||||
const Info &getInfo(unsigned ID) const {
|
||||
return getStrTableAndInfo(ID).second;
|
||||
}
|
||||
|
||||
/// Helper function for isPrintfLike and isScanfLike.
|
||||
bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
|
||||
|
||||
@@ -1138,5 +1138,6 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
|
||||
// FIXME: Obviously incomplete.
|
||||
|
||||
#undef BUILTIN
|
||||
#undef TARGET_BUILTIN
|
||||
#undef CUSTOM_BUILTIN
|
||||
#undef UNALIASED_CUSTOM_BUILTIN
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "clang/Basic/AddressSpaces.h"
|
||||
#include "clang/Basic/BitmaskEnum.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/CFProtectionOptions.h"
|
||||
#include "clang/Basic/CodeGenOptions.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
@@ -1009,11 +1010,11 @@ public:
|
||||
virtual void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const = 0;
|
||||
|
||||
|
||||
/// Return information about target-specific builtins for
|
||||
/// the current primary target, and info about which builtins are non-portable
|
||||
/// across the current set of primary and secondary targets.
|
||||
virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
|
||||
/// Return information about target-specific builtins for the current primary
|
||||
/// target, and info about which builtins are non-portable across the current
|
||||
/// set of primary and secondary targets.
|
||||
virtual std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const = 0;
|
||||
|
||||
/// Returns target-specific min and max values VScale_Range.
|
||||
virtual std::optional<std::pair<unsigned, unsigned>>
|
||||
|
||||
@@ -29,54 +29,93 @@ const char *HeaderDesc::getName() const {
|
||||
llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
|
||||
}
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
{"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
|
||||
ALL_LANGUAGES},
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
|
||||
static constexpr auto BuiltinStorage =
|
||||
Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
|
||||
CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/Builtins.inc"
|
||||
};
|
||||
,
|
||||
{CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#include "clang/Basic/Builtins.inc"
|
||||
});
|
||||
|
||||
const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
|
||||
std::pair<const char *, const Builtin::Info &>
|
||||
Builtin::Context::getStrTableAndInfo(unsigned ID) const {
|
||||
if (ID < Builtin::FirstTSBuiltin)
|
||||
return BuiltinInfo[ID];
|
||||
assert(((ID - Builtin::FirstTSBuiltin) <
|
||||
(TSRecords.size() + AuxTSRecords.size())) &&
|
||||
"Invalid builtin ID!");
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
|
||||
assert(
|
||||
((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
|
||||
"Invalid builtin ID!");
|
||||
if (isAuxBuiltinID(ID))
|
||||
return AuxTSRecords[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin];
|
||||
return TSRecords[ID - Builtin::FirstTSBuiltin];
|
||||
return {AuxTSStrTable,
|
||||
AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
|
||||
return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
|
||||
}
|
||||
|
||||
static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
|
||||
return &StrTable[Offset];
|
||||
}
|
||||
|
||||
/// Return the identifier name for the specified builtin,
|
||||
/// e.g. "__builtin_abs".
|
||||
llvm::StringRef Builtin::Context::getName(unsigned ID) const {
|
||||
const auto &[StrTable, I] = getStrTableAndInfo(ID);
|
||||
return getStrFromTable(StrTable, I.Offsets.Name);
|
||||
}
|
||||
|
||||
const char *Builtin::Context::getTypeString(unsigned ID) const {
|
||||
const auto &[StrTable, I] = getStrTableAndInfo(ID);
|
||||
return getStrFromTable(StrTable, I.Offsets.Type).data();
|
||||
}
|
||||
|
||||
const char *Builtin::Context::getAttributesString(unsigned ID) const {
|
||||
const auto &[StrTable, I] = getStrTableAndInfo(ID);
|
||||
return getStrFromTable(StrTable, I.Offsets.Attributes).data();
|
||||
}
|
||||
|
||||
const char *Builtin::Context::getRequiredFeatures(unsigned ID) const {
|
||||
const auto &[StrTable, I] = getStrTableAndInfo(ID);
|
||||
return getStrFromTable(StrTable, I.Offsets.Features).data();
|
||||
}
|
||||
|
||||
void Builtin::Context::InitializeTarget(const TargetInfo &Target,
|
||||
const TargetInfo *AuxTarget) {
|
||||
assert(TSRecords.empty() && "Already initialized target?");
|
||||
TSRecords = Target.getTargetBuiltins();
|
||||
if (AuxTarget)
|
||||
AuxTSRecords = AuxTarget->getTargetBuiltins();
|
||||
assert(TSStrTable == nullptr && "Already initialized target?");
|
||||
assert(TSInfos.empty() && "Already initialized target?");
|
||||
std::tie(TSStrTable, TSInfos) = Target.getTargetBuiltinStorage();
|
||||
if (AuxTarget) {
|
||||
std::tie(AuxTSStrTable, AuxTSInfos) = AuxTarget->getTargetBuiltinStorage();
|
||||
}
|
||||
}
|
||||
|
||||
bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) {
|
||||
bool InStdNamespace = FuncName.consume_front("std-");
|
||||
const char *StrTable = BuiltinStorage.StringTable;
|
||||
for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin;
|
||||
++i) {
|
||||
if (FuncName == BuiltinInfo[i].Name &&
|
||||
(bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace)
|
||||
return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr;
|
||||
const auto &I = BuiltinStorage.Infos[i];
|
||||
if (FuncName == getStrFromTable(StrTable, I.Offsets.Name) &&
|
||||
(bool)strchr(getStrFromTable(StrTable, I.Offsets.Attributes).data(),
|
||||
'z') == InStdNamespace)
|
||||
return strchr(getStrFromTable(StrTable, I.Offsets.Attributes).data(),
|
||||
'f') != nullptr;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Is this builtin supported according to the given language options?
|
||||
static bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
|
||||
static bool builtinIsSupported(const char *StrTable,
|
||||
const Builtin::Info &BuiltinInfo,
|
||||
const LangOptions &LangOpts) {
|
||||
auto AttributesStr =
|
||||
getStrFromTable(StrTable, BuiltinInfo.Offsets.Attributes);
|
||||
|
||||
/* Builtins Unsupported */
|
||||
if (LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr)
|
||||
if (LangOpts.NoBuiltin && strchr(AttributesStr.data(), 'f') != nullptr)
|
||||
return false;
|
||||
/* CorBuiltins Unsupported */
|
||||
if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG))
|
||||
@@ -123,7 +162,7 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
|
||||
if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
|
||||
return false;
|
||||
/* consteval Unsupported */
|
||||
if (!LangOpts.CPlusPlus20 && strchr(BuiltinInfo.Attributes, 'G') != nullptr)
|
||||
if (!LangOpts.CPlusPlus20 && strchr(AttributesStr.data(), 'G') != nullptr)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -134,20 +173,23 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
|
||||
void Builtin::Context::initializeBuiltins(IdentifierTable &Table,
|
||||
const LangOptions& LangOpts) {
|
||||
// Step #1: mark all target-independent builtins with their ID's.
|
||||
for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
|
||||
if (builtinIsSupported(BuiltinInfo[i], LangOpts)) {
|
||||
Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
|
||||
for (const auto &&[Index, I] :
|
||||
llvm::enumerate(llvm::ArrayRef(BuiltinStorage.Infos).drop_front()))
|
||||
if (builtinIsSupported(BuiltinStorage.StringTable, I, LangOpts)) {
|
||||
Table.get(getStrFromTable(BuiltinStorage.StringTable, I.Offsets.Name))
|
||||
.setBuiltinID(Index + 1);
|
||||
}
|
||||
|
||||
// Step #2: Register target-specific builtins.
|
||||
for (unsigned i = 0, e = TSRecords.size(); i != e; ++i)
|
||||
if (builtinIsSupported(TSRecords[i], LangOpts))
|
||||
Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin);
|
||||
for (const auto &&[Index, I] : llvm::enumerate(TSInfos))
|
||||
if (builtinIsSupported(TSStrTable, I, LangOpts))
|
||||
Table.get(getStrFromTable(TSStrTable, I.Offsets.Name))
|
||||
.setBuiltinID(Index + Builtin::FirstTSBuiltin);
|
||||
|
||||
// Step #3: Register target-specific builtins for AuxTarget.
|
||||
for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i)
|
||||
Table.get(AuxTSRecords[i].Name)
|
||||
.setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size());
|
||||
for (const auto &&[Index, I] : llvm::enumerate(AuxTSInfos))
|
||||
Table.get(getStrFromTable(AuxTSStrTable, I.Offsets.Name))
|
||||
.setBuiltinID(Index + Builtin::FirstTSBuiltin + TSInfos.size());
|
||||
|
||||
// Step #4: Unregister any builtins specified by -fno-builtin-foo.
|
||||
for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) {
|
||||
@@ -164,7 +206,7 @@ void Builtin::Context::initializeBuiltins(IdentifierTable &Table,
|
||||
}
|
||||
|
||||
unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const {
|
||||
const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V');
|
||||
const char *WidthPos = ::strchr(getAttributesString(ID), 'V');
|
||||
if (!WidthPos)
|
||||
return 0;
|
||||
|
||||
@@ -187,7 +229,7 @@ bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx,
|
||||
assert(::toupper(Fmt[0]) == Fmt[1] &&
|
||||
"Format string is not in the form \"xX\"");
|
||||
|
||||
const char *Like = ::strpbrk(getRecord(ID).Attributes, Fmt);
|
||||
const char *Like = ::strpbrk(getAttributesString(ID), Fmt);
|
||||
if (!Like)
|
||||
return false;
|
||||
|
||||
@@ -214,7 +256,7 @@ bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
|
||||
|
||||
bool Builtin::Context::performsCallback(unsigned ID,
|
||||
SmallVectorImpl<int> &Encoding) const {
|
||||
const char *CalleePos = ::strchr(getRecord(ID).Attributes, 'C');
|
||||
const char *CalleePos = ::strchr(getAttributesString(ID), 'C');
|
||||
if (!CalleePos)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -26,35 +26,39 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsNEON.def"
|
||||
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsSVE.def"
|
||||
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsSME.def"
|
||||
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsAArch64.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsNEON.def"
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsSVE.def"
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsSME.def"
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsAArch64.def"
|
||||
});
|
||||
|
||||
void AArch64TargetInfo::setArchFeatures() {
|
||||
if (*ArchInfo == llvm::AArch64::ARMV8R) {
|
||||
@@ -697,9 +701,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
}
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
|
||||
Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
AArch64TargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
std::optional<std::pair<unsigned, unsigned>>
|
||||
|
||||
@@ -180,7 +180,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
std::optional<std::pair<unsigned, unsigned>>
|
||||
getVScaleRange(const LangOptions &LangOpts) const override;
|
||||
|
||||
@@ -88,13 +88,18 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
|
||||
} // namespace targets
|
||||
} // namespace clang
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsAMDGPU.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsAMDGPU.def"
|
||||
});
|
||||
|
||||
const char *const AMDGPUTargetInfo::GCCRegNames[] = {
|
||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",
|
||||
@@ -266,9 +271,9 @@ void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
|
||||
!isAMDGCN(getTriple()));
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
AMDGPUTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
|
||||
@@ -257,7 +257,8 @@ public:
|
||||
StringRef CPU,
|
||||
const std::vector<std::string> &FeatureVec) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool useFP16ConversionIntrinsics() const override { return false; }
|
||||
|
||||
|
||||
@@ -40,7 +40,10 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return TargetInfo::VoidPtrBuiltinVaList;
|
||||
|
||||
@@ -1071,31 +1071,34 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsNEON.def"
|
||||
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsARM.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsNEON.def"
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsARM.def"
|
||||
});
|
||||
|
||||
ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
ARMTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
|
||||
|
||||
@@ -196,7 +196,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool isCLZForZeroUndef() const override;
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override;
|
||||
|
||||
@@ -63,7 +63,10 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
bool allowsLargerPreferedTypeAlignment() const override { return false; }
|
||||
|
||||
|
||||
@@ -19,11 +19,16 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsBPF.inc"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsBPF.inc"
|
||||
});
|
||||
|
||||
void BPFTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
@@ -81,9 +86,9 @@ void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
|
||||
Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> BPFTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
BPFTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
bool BPFTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
||||
|
||||
@@ -58,7 +58,8 @@ public:
|
||||
bool handleTargetFeatures(std::vector<std::string> &Features,
|
||||
DiagnosticsEngine &Diags) override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
std::string_view getClobbers() const override { return ""; }
|
||||
|
||||
|
||||
@@ -139,10 +139,6 @@ bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
||||
return true;
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
|
||||
return ArrayRef<Builtin::Info>();
|
||||
}
|
||||
|
||||
ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
|
||||
static const char *const GCCRegNames[] = {
|
||||
// Integer registers
|
||||
|
||||
@@ -73,7 +73,10 @@ public:
|
||||
|
||||
unsigned getMinGlobalAlign(uint64_t, bool HasNonWeakDef) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return VoidPtrBuiltinVaList;
|
||||
|
||||
@@ -72,7 +72,10 @@ public:
|
||||
return Feature == "directx";
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
std::string_view getClobbers() const override { return ""; }
|
||||
|
||||
|
||||
@@ -198,15 +198,19 @@ ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
|
||||
return llvm::ArrayRef(GCCRegAliases);
|
||||
}
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::Hexagon::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsHexagon.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsHexagon.def"
|
||||
});
|
||||
|
||||
bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
|
||||
std::string VS = "hvxv" + HVXVersion;
|
||||
@@ -264,7 +268,7 @@ void HexagonTargetInfo::fillValidCPUList(
|
||||
Values.push_back(Suffix.Name);
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
|
||||
Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
HexagonTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
@@ -66,7 +66,8 @@ public:
|
||||
BoolWidth = BoolAlign = 8;
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool validateAsmConstraint(const char *&Name,
|
||||
TargetInfo::ConstraintInfo &Info) const override {
|
||||
|
||||
@@ -78,7 +78,10 @@ public:
|
||||
return TargetInfo::VoidPtrBuiltinVaList;
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
bool validateAsmConstraint(const char *&Name,
|
||||
TargetInfo::ConstraintInfo &info) const override {
|
||||
|
||||
@@ -270,13 +270,18 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
|
||||
}
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::LoongArch::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsLoongArch.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsLoongArch.def"
|
||||
});
|
||||
|
||||
bool LoongArchTargetInfo::initFeatureMap(
|
||||
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
|
||||
@@ -303,9 +308,9 @@ bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
|
||||
Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
LoongArchTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
bool LoongArchTargetInfo::handleTargetFeatures(
|
||||
|
||||
@@ -70,7 +70,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return TargetInfo::VoidPtrBuiltinVaList;
|
||||
|
||||
@@ -115,9 +115,10 @@ void M68kTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
Builder.defineMacro("__HAVE_68881__");
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const {
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
M68kTargetInfo::getTargetBuiltinStorage() const {
|
||||
// FIXME: Implement.
|
||||
return {};
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
bool M68kTargetInfo::hasFeature(StringRef Feature) const {
|
||||
|
||||
@@ -44,7 +44,8 @@ public:
|
||||
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
bool hasFeature(StringRef Feature) const override;
|
||||
ArrayRef<const char *> getGCCRegNames() const override;
|
||||
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
||||
|
||||
@@ -50,9 +50,10 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
// FIXME: Implement.
|
||||
return {};
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
bool allowsLargerPreferedTypeAlignment() const override { return false; }
|
||||
|
||||
@@ -20,13 +20,17 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsMips.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsMips.def"
|
||||
});
|
||||
|
||||
bool MipsTargetInfo::processorSupportsGPR64() const {
|
||||
return llvm::StringSwitch<bool>(CPU)
|
||||
@@ -223,9 +227,9 @@ bool MipsTargetInfo::hasFeature(StringRef Feature) const {
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
MipsTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
unsigned MipsTargetInfo::getUnwindWordWidth() const {
|
||||
|
||||
@@ -197,7 +197,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool hasFeature(StringRef Feature) const override;
|
||||
|
||||
|
||||
@@ -20,15 +20,19 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsNVPTX.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsNVPTX.def"
|
||||
});
|
||||
|
||||
const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
|
||||
|
||||
@@ -295,7 +299,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
}
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
NVPTXTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
@@ -74,7 +74,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool useFP16ConversionIntrinsics() const override { return false; }
|
||||
|
||||
|
||||
@@ -52,7 +52,10 @@ public:
|
||||
return Feature == "pnacl";
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return TargetInfo::PNaClABIBuiltinVaList;
|
||||
|
||||
@@ -19,15 +19,19 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsPPC.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsPPC.def"
|
||||
});
|
||||
|
||||
/// handleTargetFeatures - Perform initialization based on the user
|
||||
/// configured set of features.
|
||||
@@ -927,9 +931,9 @@ void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
|
||||
MaxAtomicInlineWidth = 128;
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
PPCTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const {
|
||||
|
||||
@@ -187,7 +187,8 @@ public:
|
||||
|
||||
StringRef getABI() const override { return ABI; }
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool isCLZForZeroUndef() const override { return false; }
|
||||
|
||||
|
||||
@@ -240,22 +240,28 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#include "clang/Basic/BuiltinsRISCVVector.def"
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#include "clang/Basic/BuiltinsRISCV.inc"
|
||||
};
|
||||
static constexpr int NumBuiltins =
|
||||
clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsRISCVVector.def"
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsRISCV.inc"
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsRISCVVector.def"
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsRISCV.inc"
|
||||
});
|
||||
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
RISCVTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
bool RISCVTargetInfo::initFeatureMap(
|
||||
|
||||
@@ -62,7 +62,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return TargetInfo::VoidPtrBuiltinVaList;
|
||||
|
||||
@@ -81,8 +81,9 @@ SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const {
|
||||
return AMDGPUTI.convertConstraint(Constraint);
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const {
|
||||
return AMDGPUTI.getTargetBuiltins();
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
SPIRV64AMDGCNTargetInfo::getTargetBuiltinStorage() const {
|
||||
return AMDGPUTI.getTargetBuiltinStorage();
|
||||
}
|
||||
|
||||
void SPIRV64AMDGCNTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
|
||||
@@ -159,7 +159,10 @@ public:
|
||||
// memcpy as per section 3 of the SPIR spec.
|
||||
bool useFP16ConversionIntrinsics() const override { return false; }
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
std::string_view getClobbers() const override { return ""; }
|
||||
|
||||
@@ -408,7 +411,8 @@ public:
|
||||
|
||||
std::string convertConstraint(const char *&Constraint) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
@@ -48,9 +48,10 @@ public:
|
||||
|
||||
bool hasFeature(StringRef Feature) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
// FIXME: Implement!
|
||||
return {};
|
||||
return {nullptr, {}};
|
||||
}
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return TargetInfo::VoidPtrBuiltinVaList;
|
||||
|
||||
@@ -20,13 +20,18 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::SystemZ::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsSystemZ.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsSystemZ.def"
|
||||
});
|
||||
|
||||
const char *const SystemZTargetInfo::GCCRegNames[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
@@ -170,7 +175,7 @@ void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
Builder.defineMacro("__VEC__", "10304");
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> SystemZTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin -
|
||||
Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
SystemZTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
@@ -99,7 +99,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
ArrayRef<const char *> getGCCRegNames() const override;
|
||||
|
||||
|
||||
@@ -95,7 +95,10 @@ public:
|
||||
|
||||
bool hasFeature(StringRef Feature) const override { return Feature == "tce"; }
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override {
|
||||
return {nullptr, {}};
|
||||
}
|
||||
|
||||
std::string_view getClobbers() const override { return ""; }
|
||||
|
||||
|
||||
@@ -18,11 +18,16 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsVE.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsVE.def"
|
||||
});
|
||||
|
||||
void VETargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
@@ -39,7 +44,7 @@ void VETargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> VETargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
VETargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@ public:
|
||||
|
||||
bool hasSjLjLowering() const override { return true; }
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return TargetInfo::VoidPtrBuiltinVaList;
|
||||
|
||||
@@ -20,15 +20,19 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
clang::WebAssembly::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsWebAssembly.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsWebAssembly.def"
|
||||
});
|
||||
|
||||
static constexpr llvm::StringLiteral ValidCPUNames[] = {
|
||||
{"mvp"}, {"bleeding-edge"}, {"generic"}, {"lime"}};
|
||||
@@ -360,9 +364,9 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
|
||||
return true;
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
|
||||
Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
WebAssemblyTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags,
|
||||
|
||||
@@ -120,7 +120,8 @@ private:
|
||||
|
||||
bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const final;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const final;
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const final {
|
||||
return VoidPtrBuiltinVaList;
|
||||
|
||||
@@ -23,31 +23,45 @@
|
||||
namespace clang {
|
||||
namespace targets {
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfoX86[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
|
||||
// The x86-32 builtins are a subset and prefix of the x86-64 builtins.
|
||||
static constexpr int NumX86Builtins =
|
||||
X86::LastX86CommonBuiltin - Builtin::FirstTSBuiltin + 1;
|
||||
static constexpr int NumX86_64Builtins =
|
||||
X86::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
static_assert(NumX86Builtins < NumX86_64Builtins);
|
||||
|
||||
static constexpr auto BuiltinStorage =
|
||||
Builtin::Storage<NumX86_64Builtins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsX86.def"
|
||||
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsX86.inc"
|
||||
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
|
||||
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsX86_64.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsX86.def"
|
||||
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsX86.inc"
|
||||
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
|
||||
#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsX86_64.def"
|
||||
});
|
||||
|
||||
static const char *const GCCRegNames[] = {
|
||||
"ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
|
||||
@@ -1864,12 +1878,14 @@ ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
|
||||
return llvm::ArrayRef(AddlRegNames);
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
|
||||
Builtin::FirstTSBuiltin + 1);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
X86_32TargetInfo::getTargetBuiltinStorage() const {
|
||||
// Only use the relevant prefix of the infos, the string table base is common.
|
||||
return {BuiltinStorage.StringTable,
|
||||
llvm::ArrayRef(BuiltinStorage.Infos).take_front(NumX86Builtins)};
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfoX86,
|
||||
X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
X86_64TargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
@@ -508,7 +508,8 @@ public:
|
||||
MaxAtomicInlineWidth = 64;
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool hasBitIntType() const override { return true; }
|
||||
size_t getMaxBitIntWidth() const override {
|
||||
@@ -812,7 +813,8 @@ public:
|
||||
MaxAtomicInlineWidth = 128;
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
bool hasBitIntType() const override { return true; }
|
||||
size_t getMaxBitIntWidth() const override {
|
||||
|
||||
@@ -18,13 +18,17 @@
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfo[] = {
|
||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
|
||||
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
||||
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
|
||||
static constexpr int NumBuiltins =
|
||||
XCore::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
static constexpr auto BuiltinStorage = Builtin::Storage<NumBuiltins>::Make(
|
||||
#define BUILTIN CLANG_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsXCore.def"
|
||||
};
|
||||
, {
|
||||
#define BUILTIN CLANG_BUILTIN_ENTRY
|
||||
#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
|
||||
#include "clang/Basic/BuiltinsXCore.def"
|
||||
});
|
||||
|
||||
void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
@@ -32,7 +36,7 @@ void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
Builder.defineMacro("__XS1B__");
|
||||
}
|
||||
|
||||
ArrayRef<Builtin::Info> XCoreTargetInfo::getTargetBuiltins() const {
|
||||
return llvm::ArrayRef(BuiltinInfo,
|
||||
clang::XCore::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
XCoreTargetInfo::getTargetBuiltinStorage() const {
|
||||
return {BuiltinStorage.StringTable, BuiltinStorage.Infos};
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ public:
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
||||
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
||||
std::pair<const char *, ArrayRef<Builtin::Info>>
|
||||
getTargetBuiltinStorage() const override;
|
||||
|
||||
BuiltinVaListKind getBuiltinVaListKind() const override {
|
||||
return TargetInfo::VoidPtrBuiltinVaList;
|
||||
|
||||
Reference in New Issue
Block a user