18#include "llvm/ADT/SmallString.h"
19#include "llvm/ADT/StringRef.h"
24#define HEADER(ID, NAME) \
27#include "clang/Basic/BuiltinHeaders.def"
30 llvm_unreachable(
"Unknown HeaderDesc::HeaderID enum");
35#define GET_BUILTIN_STR_TABLE
36#include "clang/Basic/Builtins.inc"
37#undef GET_BUILTIN_STR_TABLE
41#define GET_BUILTIN_INFOS
42#include "clang/Basic/Builtins.inc"
43#undef GET_BUILTIN_INFOS
47std::pair<const Builtin::InfosShard &, const Builtin::Info &>
48Builtin::Context::getShardAndInfo(
unsigned ID)
const {
50 NumAuxTargetBuiltins)) &&
51 "Invalid builtin ID!");
53 ArrayRef<InfosShard> Shards = BuiltinShards;
55 Shards = AuxTargetShards;
58 Shards = TargetShards;
65 for (
const auto &Shard : Shards) {
66 if (
ID < Shard.Infos.size()) {
67 return {Shard, Shard.Infos[
ID]};
70 ID -= Shard.Infos.size();
72 llvm_unreachable(
"Invalid target builtin shard structure!");
83 Buf.append(Name.begin(), Name.end());
84 return StringRef(Buf.data(), Buf.size());
95 const auto &[Shard, I] = getShardAndInfo(
ID);
96 return I.getName(Shard);
100 const auto &[Shard, I] = getShardAndInfo(
ID);
102 Result += Shard.NamePrefix;
103 Result += (*Shard.Strings)[I.Offsets.Name];
109 const auto &[Shard, I] = getShardAndInfo(
ID);
110 return (*Shard.Strings)[I.Offsets.Type].data();
114 const auto &[Shard, I] = getShardAndInfo(
ID);
115 return (*Shard.Strings)[I.Offsets.Attributes].data();
119 const auto &[Shard, I] = getShardAndInfo(
ID);
120 return (*Shard.Strings)[I.Offsets.Features].data();
127 assert(TargetShards.empty() &&
"Already initialized target?");
128 assert(NumTargetBuiltins == 0 &&
"Already initialized target?");
129 TargetShards =
Target.getTargetBuiltins();
130 for (
const auto &Shard : TargetShards)
131 NumTargetBuiltins += Shard.Infos.size();
134 for (
const auto &Shard : AuxTargetShards)
135 NumAuxTargetBuiltins += Shard.Infos.size();
140 bool InStdNamespace = FuncName.consume_front(
"std-");
142 if (llvm::StringRef FuncNameSuffix = FuncName;
143 FuncNameSuffix.consume_front(Shard.NamePrefix))
144 for (
const auto &I : Shard.Infos)
145 if (FuncNameSuffix == (*Shard.Strings)[I.Offsets.Name] &&
146 (
bool)strchr((*Shard.Strings)[I.Offsets.Attributes].data(),
'z') ==
148 return strchr((*Shard.Strings)[I.Offsets.Attributes].data(),
'f') !=
161 if (LangOpts.NoBuiltin && strchr(AttributesStr.data(),
'f') !=
nullptr)
167 if (LangOpts.NoMathBuiltin && BuiltinInfo.
Header.
ID == HeaderDesc::MATH_H)
173 if (!LangOpts.MicrosoftExt && (BuiltinInfo.
Langs &
MS_LANG))
185 if (!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.
Langs &
OCL_GAS))
208 if (!LangOpts.CPlusPlus20 && strchr(AttributesStr.data(),
'G') !=
nullptr)
229 case Builtin::BI__builtin_fma:
230 case Builtin::BI__builtin_fmaf:
231 case Builtin::BI__builtin_fmal:
232 case Builtin::BI__builtin_fmaf16:
234 case Builtin::BIfmaf:
235 case Builtin::BIfmal: {
236 if (Trip.isGNUEnvironment() || Trip.isOSMSVCRT())
248 unsigned BuiltinID, llvm::Triple Trip, std::optional<bool> ErrnoOverwritten,
249 bool MathErrnoEnabled,
bool HasOptNoneAttr,
250 bool IsOptimizationEnabled)
const {
255 bool ErrnoOverridenToFalseWithOpt = ErrnoOverwritten.has_value() &&
256 !ErrnoOverwritten.value() &&
257 !HasOptNoneAttr && IsOptimizationEnabled;
269 bool ConstWithoutErrnoAndExceptions =
288 bool ConstWithoutErrnoOrExceptions =
289 ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
290 bool GenerateIntrinsics =
291 (ConstAlways && !HasOptNoneAttr) ||
292 (!MathErrnoEnabled &&
293 !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) &&
295 if (!GenerateIntrinsics) {
297 ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
298 if (!GenerateIntrinsics)
300 ConstWithoutErrnoOrExceptions &&
301 (!MathErrnoEnabled &&
302 !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) &&
304 if (!GenerateIntrinsics)
306 ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
309 return GenerateIntrinsics;
321 for (
const auto &Shard : BuiltinShards)
322 for (
const auto &I : Shard.Infos) {
331 for (
const auto &Shard : TargetShards)
332 for (
const auto &I : Shard.Infos) {
339 for (
const auto &Shard : AuxTargetShards)
340 for (
const auto &I : Shard.Infos) {
348 bool InStdNamespace = Name.consume_front(
"std-");
349 auto NameIt = Table.
find(Name);
350 if (NameIt != Table.
end()) {
351 unsigned ID = NameIt->second->getBuiltinID();
354 NameIt->second->clearBuiltinID();
366 assert(*WidthPos ==
':' &&
367 "Vector width specifier must be followed by a ':'");
371 unsigned Width = ::strtol(WidthPos, &EndPos, 10);
372 assert(*EndPos ==
':' &&
"Vector width specific must end with a ':'");
376bool Builtin::Context::isLike(
unsigned ID,
unsigned &FormatIdx,
377 bool &HasVAListArg,
const char *Fmt)
const {
378 assert(Fmt &&
"Not passed a format string");
379 assert(::strlen(Fmt) == 2 &&
380 "Format string needs to be two characters long");
381 assert(::toupper(Fmt[0]) == Fmt[1] &&
382 "Format string is not in the form \"xX\"");
384 const char *Like = ::strpbrk(getAttributesString(
ID), Fmt);
388 HasVAListArg = (*Like == Fmt[1]);
391 assert(*Like ==
':' &&
"Format specifier must be followed by a ':'");
394 assert(::strchr(Like,
':') &&
"Format specifier must end with a ':'");
395 FormatIdx = ::strtol(Like,
nullptr, 10);
400 bool &HasVAListArg) {
401 return isLike(
ID, FormatIdx, HasVAListArg,
"pP");
405 bool &HasVAListArg) {
406 return isLike(
ID, FormatIdx, HasVAListArg,
"sS");
411 assert(*CurrPos ==
'<' &&
"Expected '<' to start index list");
415 int PosIdx = ::strtol(CurrPos, &EndPos, 10);
416 assert(PosIdx >= 0 &&
"Index is supposed to be positive!");
417 Indxs.push_back(PosIdx);
419 while (*EndPos ==
',') {
420 const char *PayloadPos = EndPos + 1;
422 int PayloadIdx = ::strtol(PayloadPos, &EndPos, 10);
423 Indxs.push_back(PayloadIdx);
426 assert(*EndPos ==
'>' &&
"Index list must end with '>'");
437 assert(*AttrPos ==
':' &&
"Format specifier must be followed by a ':'");
441 else if (*AttrPos ==
'1')
444 llvm_unreachable(
"Unrecognized NonNull optimization mode");
446 assert(*AttrPos ==
':' &&
"Mode must be followed by a ':'");
457 size_t Pos = Attrs.find(
'R');
458 if (Pos == StringRef::npos)
461 StringRef Str = Attrs.drop_front(Pos + 1);
462 if (!Str.consume_front(
"<"))
463 llvm_unreachable(
"Expected '<' to start range list");
467 if (Str.consumeInteger(10, Range.Index) || !Str.consume_front(
":") ||
468 Str.consumeInteger(10, Range.Lower) || !Str.consume_front(
":") ||
469 Str.consumeInteger(10, Range.Upper))
470 llvm_unreachable(
"Malformed argument range");
471 Ranges.push_back(Range);
472 }
while (Str.consume_front(
","));
474 assert(Str.starts_with(
'>') &&
"Range list must end with '>'");
491 ID == Builtin::BI__builtin_assume_aligned ||
497 StringRef RequiredFeatures,
const llvm::StringMap<bool> &TargetFetureMap) {
499 if (RequiredFeatures.empty())
501 assert(!RequiredFeatures.contains(
' ') &&
"Space in feature list");
504 return TF.hasRequiredFeatures(RequiredFeatures);
static constexpr llvm::StringTable BuiltinStrings
static StringRef getBuiltinNameInto(const Builtin::InfosShard &Shard, const Builtin::Info &BuiltinInfo, SmallVectorImpl< char > &Buf)
Return a non-owning StringRef of the builtin's name, reconstructed into Buf.
static constexpr Builtin::Info BuiltinInfos[]
static bool builtinIsSupported(const llvm::StringTable &Strings, const Builtin::Info &BuiltinInfo, const LangOptions &LangOpts)
Is this builtin supported according to the given language options?
static constexpr unsigned NumBuiltins
static void parseCommaSeparatedIndices(const char *CurrPos, llvm::SmallVectorImpl< int > &Indxs)
static bool isBuiltinConstForTriple(unsigned BuiltinID, llvm::Triple Trip)
Defines enum values for all the target-independent builtin functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
bool shouldGenerateFPMathIntrinsic(unsigned BuiltinID, llvm::Triple Trip, std::optional< bool > ErrnoOverwritten, bool MathErrnoEnabled, bool HasOptNoneAttr, bool IsOptimizationEnabled) const
Determine whether we can generate LLVM intrinsics for the given builtin ID, based on whether it has s...
llvm::SmallString< 64 > getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
bool hasReferenceArgsOrResult(unsigned ID) const
Return true if this builtin has a result or any arguments which are reference types.
bool performsCallback(unsigned ID, llvm::SmallVectorImpl< int > &Encoding) const
Determine whether this builtin has callback behavior (see llvm::AbstractCallSites for details).
bool isAuxBuiltinID(unsigned ID) const
Return true if the builtin ID belongs exclusively to the AuxTarget, and false if it belongs to both p...
bool isNonNull(unsigned ID, llvm::SmallVectorImpl< int > &Indxs, Info::NonNullMode &Mode) const
Return true if this builtin has parameters that must be non-null.
bool isConstWithoutErrnoAndExceptions(unsigned ID) const
Return true if this function has no side effects and doesn't read memory, except for possibly errno o...
static bool isBuiltinFunc(llvm::StringRef Name)
Returns true if this is a libc/libm function without the '__builtin_' prefix.
unsigned getRequiredVectorWidth(unsigned ID) const
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
bool hasCustomTypechecking(unsigned ID) const
Determines whether this builtin has custom typechecking.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)
Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...
bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg)
Determine whether this builtin is like scanf in its formatting rules and, if so, set the index to the...
bool isInStdNamespace(unsigned ID) const
Determines whether this builtin is a C++ standard library function that lives in (possibly-versioned)...
bool canBeRedeclared(unsigned ID) const
Returns true if this is a builtin that can be redeclared.
const char * getAttributesString(unsigned ID) const
Get the attributes descriptor string for the specified builtin.
bool isPredefinedLibFunction(unsigned ID) const
Determines whether this builtin is a predefined libc/libm function, such as "malloc",...
bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg)
Determine whether this builtin is like printf in its formatting rules and, if so, set the index to th...
const char * getTypeString(unsigned ID) const
Get the type descriptor string for the specified builtin.
const char * getRequiredFeatures(unsigned ID) const
bool isConstWithoutExceptions(unsigned ID) const
void getArgRanges(unsigned ID, llvm::SmallVectorImpl< ArgRange > &Ranges) const
Append the constant argument ranges of this builtin into Ranges.
void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget)
Perform target-specific initialization.
bool isConst(unsigned ID) const
Return true if this function has no side effects and doesn't read memory.
TargetFeatures - This class is used to check whether the builtin function has the required target spe...
void setBuiltinID(unsigned ID)
Implements an efficient mapping from strings to IdentifierInfo nodes.
iterator find(StringRef Name) const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Exposes information about the current target.
virtual llvm::SmallVector< Builtin::InfosShard > getTargetBuiltins() const =0
Return information about target-specific builtins for the current primary target, and info about whic...
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
Top level wrappers for InstallAPI frontend operations.
@ Result
The result type of a method or function.
A constant argument that must be in the half-open range [Lower, Upper).
llvm::StringTable::Offset Name
llvm::StringTable::Offset Attributes
The info used to represent each builtin.
struct clang::Builtin::Info::StrOffsets Offsets
std::string getName(const InfosShard &Shard) const
Get the name for the builtin represented by this Info object.
A shard of a target's builtins string table and info.
const llvm::StringTable * Strings
llvm::StringLiteral NamePrefix