clang  19.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 
13 #include "clang/Basic/Builtins.h"
14 #include "BuiltinTargetFeatures.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "llvm/ADT/StringRef.h"
19 using namespace clang;
20 
21 const 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 
32 static 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 
44 const 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 
63 bool 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  /* ObjC Unsupported */
94  if (!LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG)
95  return false;
96  /* OpenCLC Unsupported */
97  if (!LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCL_LANGUAGES))
98  return false;
99  /* OopenCL GAS Unsupported */
100  if (!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.Langs & OCL_GAS))
101  return false;
102  /* OpenCL Pipe Unsupported */
103  if (!LangOpts.OpenCLPipes && (BuiltinInfo.Langs & OCL_PIPE))
104  return false;
105 
106  // Device side enqueue is not supported until OpenCL 2.0. In 2.0 and higher
107  // support is indicated with language option for blocks.
108 
109  /* OpenCL DSE Unsupported */
110  if ((LangOpts.getOpenCLCompatibleVersion() < 200 || !LangOpts.Blocks) &&
112  return false;
113  /* OpenMP Unsupported */
114  if (!LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG)
115  return false;
116  /* CUDA Unsupported */
117  if (!LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG)
118  return false;
119  /* CPlusPlus Unsupported */
120  if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
121  return false;
122  return true;
123 }
124 
125 /// initializeBuiltins - Mark the identifiers for all the builtins with their
126 /// appropriate builtin ID # and mark any non-portable builtin identifiers as
127 /// such.
129  const LangOptions& LangOpts) {
130  // Step #1: mark all target-independent builtins with their ID's.
131  for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
132  if (builtinIsSupported(BuiltinInfo[i], LangOpts)) {
133  Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
134  }
135 
136  // Step #2: Register target-specific builtins.
137  for (unsigned i = 0, e = TSRecords.size(); i != e; ++i)
138  if (builtinIsSupported(TSRecords[i], LangOpts))
139  Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin);
140 
141  // Step #3: Register target-specific builtins for AuxTarget.
142  for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i)
143  Table.get(AuxTSRecords[i].Name)
144  .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size());
145 
146  // Step #4: Unregister any builtins specified by -fno-builtin-foo.
147  for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) {
148  bool InStdNamespace = Name.consume_front("std-");
149  auto NameIt = Table.find(Name);
150  if (NameIt != Table.end()) {
151  unsigned ID = NameIt->second->getBuiltinID();
152  if (ID != Builtin::NotBuiltin && isPredefinedLibFunction(ID) &&
153  isInStdNamespace(ID) == InStdNamespace) {
154  NameIt->second->clearBuiltinID();
155  }
156  }
157  }
158 }
159 
161  const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V');
162  if (!WidthPos)
163  return 0;
164 
165  ++WidthPos;
166  assert(*WidthPos == ':' &&
167  "Vector width specifier must be followed by a ':'");
168  ++WidthPos;
169 
170  char *EndPos;
171  unsigned Width = ::strtol(WidthPos, &EndPos, 10);
172  assert(*EndPos == ':' && "Vector width specific must end with a ':'");
173  return Width;
174 }
175 
176 bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx,
177  bool &HasVAListArg, const char *Fmt) const {
178  assert(Fmt && "Not passed a format string");
179  assert(::strlen(Fmt) == 2 &&
180  "Format string needs to be two characters long");
181  assert(::toupper(Fmt[0]) == Fmt[1] &&
182  "Format string is not in the form \"xX\"");
183 
184  const char *Like = ::strpbrk(getRecord(ID).Attributes, Fmt);
185  if (!Like)
186  return false;
187 
188  HasVAListArg = (*Like == Fmt[1]);
189 
190  ++Like;
191  assert(*Like == ':' && "Format specifier must be followed by a ':'");
192  ++Like;
193 
194  assert(::strchr(Like, ':') && "Format specifier must end with a ':'");
195  FormatIdx = ::strtol(Like, nullptr, 10);
196  return true;
197 }
198 
199 bool Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
200  bool &HasVAListArg) {
201  return isLike(ID, FormatIdx, HasVAListArg, "pP");
202 }
203 
204 bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
205  bool &HasVAListArg) {
206  return isLike(ID, FormatIdx, HasVAListArg, "sS");
207 }
208 
211  const char *CalleePos = ::strchr(getRecord(ID).Attributes, 'C');
212  if (!CalleePos)
213  return false;
214 
215  ++CalleePos;
216  assert(*CalleePos == '<' &&
217  "Callback callee specifier must be followed by a '<'");
218  ++CalleePos;
219 
220  char *EndPos;
221  int CalleeIdx = ::strtol(CalleePos, &EndPos, 10);
222  assert(CalleeIdx >= 0 && "Callee index is supposed to be positive!");
223  Encoding.push_back(CalleeIdx);
224 
225  while (*EndPos == ',') {
226  const char *PayloadPos = EndPos + 1;
227 
228  int PayloadIdx = ::strtol(PayloadPos, &EndPos, 10);
229  Encoding.push_back(PayloadIdx);
230  }
231 
232  assert(*EndPos == '>' && "Callback callee specifier must end with a '>'");
233  return true;
234 }
235 
236 bool Builtin::Context::canBeRedeclared(unsigned ID) const {
237  return ID == Builtin::NotBuiltin || ID == Builtin::BI__va_start ||
238  ID == Builtin::BI__builtin_assume_aligned ||
239  (!hasReferenceArgsOrResult(ID) && !hasCustomTypechecking(ID)) ||
240  isInStdNamespace(ID);
241 }
242 
244  StringRef RequiredFeatures, const llvm::StringMap<bool> &TargetFetureMap) {
245  // Return true if the builtin doesn't have any required features.
246  if (RequiredFeatures.empty())
247  return true;
248  assert(!RequiredFeatures.contains(' ') && "Space in feature list");
249 
250  TargetFeatures TF(TargetFetureMap);
251  return TF.hasRequiredFeatures(RequiredFeatures);
252 }
static char ID
Definition: Arena.cpp:183
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:50
bool performsCallback(unsigned ID, llvm::SmallVectorImpl< int > &Encoding) const
Determine whether this builtin has callback behavior (see llvm::AbstractCallSites for details).
Definition: Builtins.cpp:209
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
Definition: Builtins.h:262
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:160
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
Definition: Builtins.h:268
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:128
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:204
bool canBeRedeclared(unsigned ID) const
Returns true if this is a builtin that can be redeclared.
Definition: Builtins.cpp:236
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:199
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
iterator end() 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...
Definition: LangOptions.h:482
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
Definition: LangOptions.h:549
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:218
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
@ 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