@@ -55,7 +55,6 @@ struct HeaderDesc {
55
55
#undef HEADER
56
56
} ID;
57
57
58
- constexpr HeaderDesc () : ID() {}
59
58
constexpr HeaderDesc (HeaderID ID) : ID(ID) {}
60
59
61
60
const char *getName () const ;
@@ -69,152 +68,23 @@ enum ID {
69
68
FirstTSBuiltin
70
69
};
71
70
72
- // The info used to represent each builtin.
73
71
struct Info {
74
- // Rather than store pointers to the string literals describing these four
75
- // aspects of builtins, we store offsets into a common string table.
76
- struct StrOffsets {
77
- int Name;
78
- int Type;
79
- int Attributes;
80
- int Features;
81
- } Offsets;
82
-
72
+ llvm::StringLiteral Name;
73
+ const char *Type, *Attributes;
74
+ const char *Features;
83
75
HeaderDesc Header;
84
76
LanguageID Langs;
85
77
};
86
78
87
- // The storage for `N` builtins. This contains a single pointer to the string
88
- // table used for these builtins and an array of metadata for each builtin.
89
- template <size_t N> struct Storage {
90
- const char *StringTable;
91
-
92
- std::array<Info, N> Infos;
93
-
94
- // A constexpr function to construct the storage for a a given string table in
95
- // the first argument and an array in the second argument. This is *only*
96
- // expected to be used at compile time, we should mark it `consteval` when
97
- // available.
98
- //
99
- // The `Infos` array is particularly special. This function expects an array
100
- // of `Info` structs, where the string offsets of each entry refer to the
101
- // *sizes* of those strings rather than their offsets, and for the target
102
- // string to be in the provided string table at an offset the sum of all
103
- // previous string sizes. This function walks the `Infos` array computing the
104
- // running sum and replacing the sizes with the actual offsets in the string
105
- // table that should be used. This arrangement is designed to make it easy to
106
- // expand `.def` and `.inc` files with X-macros to construct both the string
107
- // table and the `Info` structs in the arguments to this function.
108
- static constexpr Storage<N> Make (const char *Strings,
109
- std::array<Info, N> Infos) {
110
- // Translate lengths to offsets.
111
- int Offset = 0 ;
112
- for (auto &I : Infos) {
113
- Info::StrOffsets NewOffsets = {};
114
- NewOffsets.Name = Offset;
115
- Offset += I.Offsets .Name ;
116
- NewOffsets.Type = Offset;
117
- Offset += I.Offsets .Type ;
118
- NewOffsets.Attributes = Offset;
119
- Offset += I.Offsets .Attributes ;
120
- NewOffsets.Features = Offset;
121
- Offset += I.Offsets .Features ;
122
- I.Offsets = NewOffsets;
123
- }
124
- return {Strings, Infos};
125
- }
126
- };
127
-
128
- // A detail macro used below to emit a string literal that, after string literal
129
- // concatenation, ends up triggering the `-Woverlength-strings` warning. While
130
- // the warning is useful in general to catch accidentally excessive strings,
131
- // here we are creating them intentionally.
132
- //
133
- // This relies on a subtle aspect of `_Pragma`: that the *diagnostic* ones don't
134
- // turn into actual tokens that would disrupt string literal concatenation.
135
- #ifdef __clang__
136
- #define CLANG_BUILTIN_DETAIL_STR_TABLE (S ) \
137
- _Pragma (" clang diagnostic push" ) \
138
- _Pragma(" clang diagnostic ignored \" -Woverlength-strings\" " ) \
139
- S _Pragma(" clang diagnostic pop" )
140
- #else
141
- #define CLANG_BUILTIN_DETAIL_STR_TABLE (S ) S
142
- #endif
143
-
144
- // A macro that can be used with `Builtins.def` and similar files as an X-macro
145
- // to add the string arguments to a builtin string table. This is typically the
146
- // target for the `BUILTIN`, `LANGBUILTIN`, or `LIBBUILTIN` macros in those
147
- // files.
148
- #define CLANG_BUILTIN_STR_TABLE (ID, TYPE, ATTRS ) \
149
- CLANG_BUILTIN_DETAIL_STR_TABLE (#ID " \0 " TYPE " \0 " ATTRS " \0 " /* FEATURE*/ " \0 " )
150
-
151
- // A macro that can be used with target builtin `.def` and `.inc` files as an
152
- // X-macro to add the string arguments to a builtin string table. this is
153
- // typically the target for the `TARGET_BUILTIN` macro.
154
- #define CLANG_TARGET_BUILTIN_STR_TABLE (ID, TYPE, ATTRS, FEATURE ) \
155
- CLANG_BUILTIN_DETAIL_STR_TABLE (#ID " \0 " TYPE " \0 " ATTRS " \0 " FEATURE " \0 " )
156
-
157
- // A macro that can be used with target builtin `.def` and `.inc` files as an
158
- // X-macro to add the string arguments to a builtin string table. this is
159
- // typically the target for the `TARGET_HEADER_BUILTIN` macro. We can't delegate
160
- // to `TARGET_BUILTIN` because the `FEATURE` string changes position.
161
- #define CLANG_TARGET_HEADER_BUILTIN_STR_TABLE (ID, TYPE, ATTRS, HEADER, LANGS, \
162
- FEATURE) \
163
- CLANG_BUILTIN_DETAIL_STR_TABLE (#ID " \0 " TYPE " \0 " ATTRS " \0 " FEATURE " \0 " )
164
-
165
- // A detail macro used internally to compute the desired string table
166
- // `StrOffsets` struct for arguments to `Storage::Make`.
167
- #define CLANG_BUILTIN_DETAIL_STR_OFFSETS (ID, TYPE, ATTRS ) \
168
- Builtin::Info::StrOffsets { \
169
- sizeof (#ID), sizeof (TYPE), sizeof (ATTRS), sizeof (" " ) \
170
- }
171
-
172
- // A detail macro used internally to compute the desired string table
173
- // `StrOffsets` struct for arguments to `Storage::Make`.
174
- #define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS (ID, TYPE, ATTRS, FEATURE ) \
175
- Builtin::Info::StrOffsets { \
176
- sizeof (#ID), sizeof (TYPE), sizeof (ATTRS), sizeof (FEATURE) \
177
- }
178
-
179
- // A set of macros that can be used with builtin `.def' files as an X-macro to
180
- // create an `Info` struct for a particular builtin. It both computes the
181
- // `StrOffsets` value for the string table (the lengths here, translated to
182
- // offsets by the Storage::Make function), and the other metadata for each
183
- // builtin.
184
- //
185
- // There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
186
- // `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
187
- #define CLANG_BUILTIN_ENTRY (ID, TYPE, ATTRS ) \
188
- Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS (ID, TYPE, ATTRS), \
189
- HeaderDesc::NO_HEADER, ALL_LANGUAGES},
190
- #define CLANG_LANGBUILTIN_ENTRY (ID, TYPE, ATTRS, LANG ) \
191
- Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS (ID, TYPE, ATTRS), \
192
- HeaderDesc::NO_HEADER, LANG},
193
- #define CLANG_LIBBUILTIN_ENTRY (ID, TYPE, ATTRS, HEADER, LANG ) \
194
- Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS (ID, TYPE, ATTRS), \
195
- HeaderDesc::HEADER, LANG},
196
- #define CLANG_TARGET_BUILTIN_ENTRY (ID, TYPE, ATTRS, FEATURE ) \
197
- Builtin::Info{ \
198
- CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS (ID, TYPE, ATTRS, FEATURE), \
199
- HeaderDesc::NO_HEADER, ALL_LANGUAGES},
200
- #define CLANG_TARGET_HEADER_BUILTIN_ENTRY (ID, TYPE, ATTRS, HEADER, LANG, \
201
- FEATURE) \
202
- Builtin::Info{ \
203
- CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS (ID, TYPE, ATTRS, FEATURE), \
204
- HeaderDesc::HEADER, LANG},
205
-
206
79
// / Holds information about both target-independent and
207
80
// / target-specific builtins, allowing easy queries by clients.
208
81
// /
209
82
// / Builtins from an optional auxiliary target are stored in
210
83
// / AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
211
84
// / be translated back with getAuxBuiltinID() before use.
212
85
class Context {
213
- const char *TSStrTable = nullptr ;
214
- const char *AuxTSStrTable = nullptr ;
215
-
216
- llvm::ArrayRef<Info> TSInfos;
217
- llvm::ArrayRef<Info> AuxTSInfos;
86
+ llvm::ArrayRef<Info> TSRecords;
87
+ llvm::ArrayRef<Info> AuxTSRecords;
218
88
219
89
public:
220
90
Context () = default ;
@@ -230,13 +100,12 @@ class Context {
230
100
231
101
// / Return the identifier name for the specified builtin,
232
102
// / e.g. "__builtin_abs".
233
- llvm::StringRef getName (unsigned ID) const ;
103
+ llvm::StringRef getName (unsigned ID) const { return getRecord (ID). Name ; }
234
104
235
105
// / Get the type descriptor string for the specified builtin.
236
- const char *getTypeString (unsigned ID) const ;
237
-
238
- // / Get the attributes descriptor string for the specified builtin.
239
- const char *getAttributesString (unsigned ID) const ;
106
+ const char *getTypeString (unsigned ID) const {
107
+ return getRecord (ID).Type ;
108
+ }
240
109
241
110
// / Return true if this function is a target-specific builtin.
242
111
bool isTSBuiltin (unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
245
114
246
115
// / Return true if this function has no side effects.
247
116
bool isPure (unsigned ID) const {
248
- return strchr (getAttributesString (ID), ' U' ) != nullptr ;
117
+ return strchr (getRecord (ID). Attributes , ' U' ) != nullptr ;
249
118
}
250
119
251
120
// / Return true if this function has no side effects and doesn't
252
121
// / read memory.
253
122
bool isConst (unsigned ID) const {
254
- return strchr (getAttributesString (ID), ' c' ) != nullptr ;
123
+ return strchr (getRecord (ID). Attributes , ' c' ) != nullptr ;
255
124
}
256
125
257
126
// / Return true if we know this builtin never throws an exception.
258
127
bool isNoThrow (unsigned ID) const {
259
- return strchr (getAttributesString (ID), ' n' ) != nullptr ;
128
+ return strchr (getRecord (ID). Attributes , ' n' ) != nullptr ;
260
129
}
261
130
262
131
// / Return true if we know this builtin never returns.
263
132
bool isNoReturn (unsigned ID) const {
264
- return strchr (getAttributesString (ID), ' r' ) != nullptr ;
133
+ return strchr (getRecord (ID). Attributes , ' r' ) != nullptr ;
265
134
}
266
135
267
136
// / Return true if we know this builtin can return twice.
268
137
bool isReturnsTwice (unsigned ID) const {
269
- return strchr (getAttributesString (ID), ' j' ) != nullptr ;
138
+ return strchr (getRecord (ID). Attributes , ' j' ) != nullptr ;
270
139
}
271
140
272
141
// / Returns true if this builtin does not perform the side-effects
273
142
// / of its arguments.
274
143
bool isUnevaluated (unsigned ID) const {
275
- return strchr (getAttributesString (ID), ' u' ) != nullptr ;
144
+ return strchr (getRecord (ID). Attributes , ' u' ) != nullptr ;
276
145
}
277
146
278
147
// / Return true if this is a builtin for a libc/libm function,
279
148
// / with a "__builtin_" prefix (e.g. __builtin_abs).
280
149
bool isLibFunction (unsigned ID) const {
281
- return strchr (getAttributesString (ID), ' F' ) != nullptr ;
150
+ return strchr (getRecord (ID). Attributes , ' F' ) != nullptr ;
282
151
}
283
152
284
153
// / Determines whether this builtin is a predefined libc/libm
@@ -289,29 +158,29 @@ class Context {
289
158
// / they do not, but they are recognized as builtins once we see
290
159
// / a declaration.
291
160
bool isPredefinedLibFunction (unsigned ID) const {
292
- return strchr (getAttributesString (ID), ' f' ) != nullptr ;
161
+ return strchr (getRecord (ID). Attributes , ' f' ) != nullptr ;
293
162
}
294
163
295
164
// / Returns true if this builtin requires appropriate header in other
296
165
// / compilers. In Clang it will work even without including it, but we can emit
297
166
// / a warning about missing header.
298
167
bool isHeaderDependentFunction (unsigned ID) const {
299
- return strchr (getAttributesString (ID), ' h' ) != nullptr ;
168
+ return strchr (getRecord (ID). Attributes , ' h' ) != nullptr ;
300
169
}
301
170
302
171
// / Determines whether this builtin is a predefined compiler-rt/libgcc
303
172
// / function, such as "__clear_cache", where we know the signature a
304
173
// / priori.
305
174
bool isPredefinedRuntimeFunction (unsigned ID) const {
306
- return strchr (getAttributesString (ID), ' i' ) != nullptr ;
175
+ return strchr (getRecord (ID). Attributes , ' i' ) != nullptr ;
307
176
}
308
177
309
178
// / Determines whether this builtin is a C++ standard library function
310
179
// / that lives in (possibly-versioned) namespace std, possibly a template
311
180
// / specialization, where the signature is determined by the standard library
312
181
// / declaration.
313
182
bool isInStdNamespace (unsigned ID) const {
314
- return strchr (getAttributesString (ID), ' z' ) != nullptr ;
183
+ return strchr (getRecord (ID). Attributes , ' z' ) != nullptr ;
315
184
}
316
185
317
186
// / Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
325
194
326
195
// / Determines whether this builtin has custom typechecking.
327
196
bool hasCustomTypechecking (unsigned ID) const {
328
- return strchr (getAttributesString (ID), ' t' ) != nullptr ;
197
+ return strchr (getRecord (ID). Attributes , ' t' ) != nullptr ;
329
198
}
330
199
331
200
// / Determines whether a declaration of this builtin should be recognized
332
201
// / even if the type doesn't match the specified signature.
333
202
bool allowTypeMismatch (unsigned ID) const {
334
- return strchr (getAttributesString (ID), ' T' ) != nullptr ||
203
+ return strchr (getRecord (ID). Attributes , ' T' ) != nullptr ||
335
204
hasCustomTypechecking (ID);
336
205
}
337
206
338
207
// / Determines whether this builtin has a result or any arguments which
339
208
// / are pointer types.
340
209
bool hasPtrArgsOrResult (unsigned ID) const {
341
- return strchr (getTypeString (ID), ' *' ) != nullptr ;
210
+ return strchr (getRecord (ID). Type , ' *' ) != nullptr ;
342
211
}
343
212
344
213
// / Return true if this builtin has a result or any arguments which are
345
214
// / reference types.
346
215
bool hasReferenceArgsOrResult (unsigned ID) const {
347
- return strchr (getTypeString (ID), ' &' ) != nullptr ||
348
- strchr (getTypeString (ID), ' A' ) != nullptr ;
216
+ return strchr (getRecord (ID). Type , ' &' ) != nullptr ||
217
+ strchr (getRecord (ID). Type , ' A' ) != nullptr ;
349
218
}
350
219
351
220
// / If this is a library function that comes from a specific
352
221
// / header, retrieve that header name.
353
222
const char *getHeaderName (unsigned ID) const {
354
- return getInfo (ID).Header .getName ();
223
+ return getRecord (ID).Header .getName ();
355
224
}
356
225
357
226
// / Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
376
245
// / Such functions can be const when the MathErrno lang option and FP
377
246
// / exceptions are disabled.
378
247
bool isConstWithoutErrnoAndExceptions (unsigned ID) const {
379
- return strchr (getAttributesString (ID), ' e' ) != nullptr ;
248
+ return strchr (getRecord (ID). Attributes , ' e' ) != nullptr ;
380
249
}
381
250
382
251
bool isConstWithoutExceptions (unsigned ID) const {
383
- return strchr (getAttributesString (ID), ' g' ) != nullptr ;
252
+ return strchr (getRecord (ID). Attributes , ' g' ) != nullptr ;
384
253
}
385
254
386
- const char *getRequiredFeatures (unsigned ID) const ;
255
+ const char *getRequiredFeatures (unsigned ID) const {
256
+ return getRecord (ID).Features ;
257
+ }
387
258
388
259
unsigned getRequiredVectorWidth (unsigned ID) const ;
389
260
390
261
// / Return true if builtin ID belongs to AuxTarget.
391
262
bool isAuxBuiltinID (unsigned ID) const {
392
- return ID >= (Builtin::FirstTSBuiltin + TSInfos .size ());
263
+ return ID >= (Builtin::FirstTSBuiltin + TSRecords .size ());
393
264
}
394
265
395
266
// / Return real builtin ID (i.e. ID it would have during compilation
396
267
// / for AuxTarget).
397
- unsigned getAuxBuiltinID (unsigned ID) const { return ID - TSInfos .size (); }
268
+ unsigned getAuxBuiltinID (unsigned ID) const { return ID - TSRecords .size (); }
398
269
399
270
// / Returns true if this is a libc/libm function without the '__builtin_'
400
271
// / prefix.
@@ -406,20 +277,16 @@ class Context {
406
277
407
278
// / Return true if this function can be constant evaluated by Clang frontend.
408
279
bool isConstantEvaluated (unsigned ID) const {
409
- return strchr (getAttributesString (ID), ' E' ) != nullptr ;
280
+ return strchr (getRecord (ID). Attributes , ' E' ) != nullptr ;
410
281
}
411
282
412
283
// / Returns true if this is an immediate (consteval) function
413
284
bool isImmediate (unsigned ID) const {
414
- return strchr (getAttributesString (ID), ' G' ) != nullptr ;
285
+ return strchr (getRecord (ID). Attributes , ' G' ) != nullptr ;
415
286
}
416
287
417
288
private:
418
- std::pair<const char *, const Info &> getStrTableAndInfo (unsigned ID) const ;
419
-
420
- const Info &getInfo (unsigned ID) const {
421
- return getStrTableAndInfo (ID).second ;
422
- }
289
+ const Info &getRecord (unsigned ID) const ;
423
290
424
291
// / Helper function for isPrintfLike and isScanfLike.
425
292
bool isLike (unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
0 commit comments