clang 20.0.0git
Builtins.cpp
Go to the documentation of this file.
1//===--- Builtins.cpp - Builtin function implementation -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements various things for builtin functions.
10//
11//===----------------------------------------------------------------------===//
12
18#include "llvm/ADT/StringRef.h"
19using namespace clang;
20
21const char *HeaderDesc::getName() const {
22 switch (ID) {
23#define HEADER(ID, NAME) \
24 case ID: \
25 return NAME;
26#include "clang/Basic/BuiltinHeaders.def"
27#undef HEADER
28 };
29 llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
30}
31
32static constexpr Builtin::Info BuiltinInfo[] = {
33 {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
35#define BUILTIN(ID, TYPE, ATTRS) \
36 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
37#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \
38 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
39#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS) \
40 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
41#include "clang/Basic/Builtins.inc"
42};
43
44const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
46 return BuiltinInfo[ID];
47 assert(((ID - Builtin::FirstTSBuiltin) <
48 (TSRecords.size() + AuxTSRecords.size())) &&
49 "Invalid builtin ID!");
50 if (isAuxBuiltinID(ID))
51 return AuxTSRecords[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin];
52 return TSRecords[ID - Builtin::FirstTSBuiltin];
53}
54
56 const TargetInfo *AuxTarget) {
57 assert(TSRecords.empty() && "Already initialized target?");
58 TSRecords = Target.getTargetBuiltins();
59 if (AuxTarget)
60 AuxTSRecords = AuxTarget->getTargetBuiltins();
61}
62
63bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) {
64 bool InStdNamespace = FuncName.consume_front("std-");
65 for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin;
66 ++i) {
67 if (FuncName == BuiltinInfo[i].Name &&
68 (bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace)
69 return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr;
70 }
71
72 return false;
73}
74
75/// Is this builtin supported according to the given language options?
77 const LangOptions &LangOpts) {
78 /* Builtins Unsupported */
79 if (LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr)
80 return false;
81 /* CorBuiltins Unsupported */
82 if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG))
83 return false;
84 /* MathBuiltins Unsupported */
85 if (LangOpts.NoMathBuiltin && BuiltinInfo.Header.ID == HeaderDesc::MATH_H)
86 return false;
87 /* GnuMode Unsupported */
88 if (!LangOpts.GNUMode && (BuiltinInfo.Langs & GNU_LANG))
89 return false;
90 /* MSMode Unsupported */
91 if (!LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG))
92 return false;
93 /* HLSLMode Unsupported */
94 if (!LangOpts.HLSL && (BuiltinInfo.Langs & HLSL_LANG))
95 return false;
96 /* ObjC Unsupported */
97 if (!LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG)
98 return false;
99 /* OpenCLC Unsupported */
100 if (!LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCL_LANGUAGES))
101 return false;
102 /* OopenCL GAS Unsupported */
103 if (!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.Langs & OCL_GAS))
104 return false;
105 /* OpenCL Pipe Unsupported */
106 if (!LangOpts.OpenCLPipes && (BuiltinInfo.Langs & OCL_PIPE))
107 return false;
108
109 // Device side enqueue is not supported until OpenCL 2.0. In 2.0 and higher
110 // support is indicated with language option for blocks.
111
112 /* OpenCL DSE Unsupported */
113 if ((LangOpts.getOpenCLCompatibleVersion() < 200 || !LangOpts.Blocks) &&
115 return false;
116 /* OpenMP Unsupported */
117 if (!LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG)
118 return false;
119 /* CUDA Unsupported */
120 if (!LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG)
121 return false;
122 /* CPlusPlus Unsupported */
123 if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
124 return false;
125 /* consteval Unsupported */
126 if (!LangOpts.CPlusPlus20 && strchr(BuiltinInfo.Attributes, 'G') != nullptr)
127 return false;
128 return true;
129}
130
131/// initializeBuiltins - Mark the identifiers for all the builtins with their
132/// appropriate builtin ID # and mark any non-portable builtin identifiers as
133/// such.
135 const LangOptions& LangOpts) {
136 // Step #1: mark all target-independent builtins with their ID's.
137 for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; ++i)
138 if (builtinIsSupported(BuiltinInfo[i], LangOpts)) {
139 Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
140 }
141
142 // Step #2: Register target-specific builtins.
143 for (unsigned i = 0, e = TSRecords.size(); i != e; ++i)
144 if (builtinIsSupported(TSRecords[i], LangOpts))
145 Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin);
146
147 // Step #3: Register target-specific builtins for AuxTarget.
148 for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i)
149 Table.get(AuxTSRecords[i].Name)
150 .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size());
151
152 // Step #4: Unregister any builtins specified by -fno-builtin-foo.
153 for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) {
154 bool InStdNamespace = Name.consume_front("std-");
155 auto NameIt = Table.find(Name);
156 if (NameIt != Table.end()) {
157 unsigned ID = NameIt->second->getBuiltinID();
158 if (ID != Builtin::NotBuiltin && isPredefinedLibFunction(ID) &&
159 isInStdNamespace(ID) == InStdNamespace) {
160 NameIt->second->clearBuiltinID();
161 }
162 }
163 }
164}
165
166std::string Builtin::Context::getQuotedName(unsigned ID) const {
167 return (llvm::Twine("'") + getName(ID) + "'").str();
168}
169
171 const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V');
172 if (!WidthPos)
173 return 0;
174
175 ++WidthPos;
176 assert(*WidthPos == ':' &&
177 "Vector width specifier must be followed by a ':'");
178 ++WidthPos;
179
180 char *EndPos;
181 unsigned Width = ::strtol(WidthPos, &EndPos, 10);
182 assert(*EndPos == ':' && "Vector width specific must end with a ':'");
183 return Width;
184}
185
186bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx,
187 bool &HasVAListArg, const char *Fmt) const {
188 assert(Fmt && "Not passed a format string");
189 assert(::strlen(Fmt) == 2 &&
190 "Format string needs to be two characters long");
191 assert(::toupper(Fmt[0]) == Fmt[1] &&
192 "Format string is not in the form \"xX\"");
193
194 const char *Like = ::strpbrk(getRecord(ID).Attributes, Fmt);
195 if (!Like)
196 return false;
197
198 HasVAListArg = (*Like == Fmt[1]);
199
200 ++Like;
201 assert(*Like == ':' && "Format specifier must be followed by a ':'");
202 ++Like;
203
204 assert(::strchr(Like, ':') && "Format specifier must end with a ':'");
205 FormatIdx = ::strtol(Like, nullptr, 10);
206 return true;
207}
208
209bool Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
210 bool &HasVAListArg) {
211 return isLike(ID, FormatIdx, HasVAListArg, "pP");
212}
213
214bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
215 bool &HasVAListArg) {
216 return isLike(ID, FormatIdx, HasVAListArg, "sS");
217}
218
220 SmallVectorImpl<int> &Encoding) const {
221 const char *CalleePos = ::strchr(getRecord(ID).Attributes, 'C');
222 if (!CalleePos)
223 return false;
224
225 ++CalleePos;
226 assert(*CalleePos == '<' &&
227 "Callback callee specifier must be followed by a '<'");
228 ++CalleePos;
229
230 char *EndPos;
231 int CalleeIdx = ::strtol(CalleePos, &EndPos, 10);
232 assert(CalleeIdx >= 0 && "Callee index is supposed to be positive!");
233 Encoding.push_back(CalleeIdx);
234
235 while (*EndPos == ',') {
236 const char *PayloadPos = EndPos + 1;
237
238 int PayloadIdx = ::strtol(PayloadPos, &EndPos, 10);
239 Encoding.push_back(PayloadIdx);
240 }
241
242 assert(*EndPos == '>' && "Callback callee specifier must end with a '>'");
243 return true;
244}
245
247 return ID == Builtin::NotBuiltin || ID == Builtin::BI__va_start ||
248 ID == Builtin::BI__builtin_assume_aligned ||
249 (!hasReferenceArgsOrResult(ID) && !hasCustomTypechecking(ID)) ||
250 isInStdNamespace(ID);
251}
252
254 StringRef RequiredFeatures, const llvm::StringMap<bool> &TargetFetureMap) {
255 // Return true if the builtin doesn't have any required features.
256 if (RequiredFeatures.empty())
257 return true;
258 assert(!RequiredFeatures.contains(' ') && "Space in feature list");
259
260 TargetFeatures TF(TargetFetureMap);
261 return TF.hasRequiredFeatures(RequiredFeatures);
262}
static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, const LangOptions &LangOpts)
Is this builtin supported according to the given language options?
Definition: Builtins.cpp:76
static constexpr Builtin::Info BuiltinInfo[]
Definition: Builtins.cpp:32
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.
llvm::MachO::Target Target
Definition: MachO.h:51
static std::string getName(const CallEvent &Call)
std::string getQuotedName(unsigned ID) const
Return a quoted name for the specified builtin for use in diagnostics.
Definition: Builtins.cpp:166
bool performsCallback(unsigned ID, llvm::SmallVectorImpl< int > &Encoding) const
Determine whether this builtin has callback behavior (see llvm::AbstractCallSites for details).
Definition: Builtins.cpp:219
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
Definition: Builtins.h:263
static bool isBuiltinFunc(llvm::StringRef Name)
Returns true if this is a libc/libm function without the '__builtin_' prefix.
Definition: Builtins.cpp:63
unsigned getRequiredVectorWidth(unsigned ID) const
Definition: Builtins.cpp:170
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
Definition: Builtins.h:269
void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)
Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...
Definition: Builtins.cpp:134
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...
Definition: Builtins.cpp:214
bool canBeRedeclared(unsigned ID) const
Returns true if this is a builtin that can be redeclared.
Definition: Builtins.cpp:246
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...
Definition: Builtins.cpp:209
void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget)
Perform target-specific initialization.
Definition: Builtins.cpp:55
TargetFeatures - This class is used to check whether the builtin function has the required tagert 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.
iterator end() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
Definition: LangOptions.h:566
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Definition: LangOptions.cpp:63
Exposes information about the current target.
Definition: TargetInfo.h:220
virtual ArrayRef< Builtin::Info > 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.
The JSON file list parser is used to communicate input to InstallAPI.
@ ALL_LANGUAGES
Definition: Builtins.h:46
@ MS_LANG
Definition: Builtins.h:37
@ CUDA_LANG
Definition: Builtins.h:39
@ OMP_LANG
Definition: Builtins.h:38
@ CXX_LANG
Definition: Builtins.h:35
@ OBJC_LANG
Definition: Builtins.h:36
@ OCL_DSE
Definition: Builtins.h:43
@ ALL_OCL_LANGUAGES
Definition: Builtins.h:44
@ HLSL_LANG
Definition: Builtins.h:45
@ OCL_GAS
Definition: Builtins.h:41
@ GNU_LANG
Definition: Builtins.h:33
@ COR_LANG
Definition: Builtins.h:40
@ OCL_PIPE
Definition: Builtins.h:42
HeaderDesc Header
Definition: Builtins.h:75
LanguageID Langs
Definition: Builtins.h:76
const char * Attributes
Definition: Builtins.h:73
const char * getName() const
Definition: Builtins.cpp:21
enum clang::HeaderDesc::HeaderID ID