Skip to content

Commit ca79ff0

Browse files
authored
Revert "Switch builtin strings to use string tables" (#119638)
Reverts #118734 There are currently some specific versions of MSVC that are miscompiling this code (we think). We don't know why as all the other build bots and at least some folks' local Windows builds work fine. This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, the expectation is to roll forward at some point with a workaround if at all possible.
1 parent 2291e5a commit ca79ff0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+306
-606
lines changed

clang/include/clang/Basic/Builtins.h

+34-169
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ struct HeaderDesc {
5555
#undef HEADER
5656
} ID;
5757

58-
constexpr HeaderDesc() : ID() {}
5958
constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
6059

6160
const char *getName() const;
@@ -69,152 +68,23 @@ enum ID {
6968
FirstTSBuiltin
7069
};
7170

72-
// The info used to represent each builtin.
7371
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;
8375
HeaderDesc Header;
8476
LanguageID Langs;
8577
};
8678

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-
20679
/// Holds information about both target-independent and
20780
/// target-specific builtins, allowing easy queries by clients.
20881
///
20982
/// Builtins from an optional auxiliary target are stored in
21083
/// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
21184
/// be translated back with getAuxBuiltinID() before use.
21285
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;
21888

21989
public:
22090
Context() = default;
@@ -230,13 +100,10 @@ class Context {
230100

231101
/// Return the identifier name for the specified builtin,
232102
/// e.g. "__builtin_abs".
233-
llvm::StringRef getName(unsigned ID) const;
103+
llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
234104

235105
/// 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 { return getRecord(ID).Type; }
240107

241108
/// Return true if this function is a target-specific builtin.
242109
bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +112,40 @@ class Context {
245112

246113
/// Return true if this function has no side effects.
247114
bool isPure(unsigned ID) const {
248-
return strchr(getAttributesString(ID), 'U') != nullptr;
115+
return strchr(getRecord(ID).Attributes, 'U') != nullptr;
249116
}
250117

251118
/// Return true if this function has no side effects and doesn't
252119
/// read memory.
253120
bool isConst(unsigned ID) const {
254-
return strchr(getAttributesString(ID), 'c') != nullptr;
121+
return strchr(getRecord(ID).Attributes, 'c') != nullptr;
255122
}
256123

257124
/// Return true if we know this builtin never throws an exception.
258125
bool isNoThrow(unsigned ID) const {
259-
return strchr(getAttributesString(ID), 'n') != nullptr;
126+
return strchr(getRecord(ID).Attributes, 'n') != nullptr;
260127
}
261128

262129
/// Return true if we know this builtin never returns.
263130
bool isNoReturn(unsigned ID) const {
264-
return strchr(getAttributesString(ID), 'r') != nullptr;
131+
return strchr(getRecord(ID).Attributes, 'r') != nullptr;
265132
}
266133

267134
/// Return true if we know this builtin can return twice.
268135
bool isReturnsTwice(unsigned ID) const {
269-
return strchr(getAttributesString(ID), 'j') != nullptr;
136+
return strchr(getRecord(ID).Attributes, 'j') != nullptr;
270137
}
271138

272139
/// Returns true if this builtin does not perform the side-effects
273140
/// of its arguments.
274141
bool isUnevaluated(unsigned ID) const {
275-
return strchr(getAttributesString(ID), 'u') != nullptr;
142+
return strchr(getRecord(ID).Attributes, 'u') != nullptr;
276143
}
277144

278145
/// Return true if this is a builtin for a libc/libm function,
279146
/// with a "__builtin_" prefix (e.g. __builtin_abs).
280147
bool isLibFunction(unsigned ID) const {
281-
return strchr(getAttributesString(ID), 'F') != nullptr;
148+
return strchr(getRecord(ID).Attributes, 'F') != nullptr;
282149
}
283150

284151
/// Determines whether this builtin is a predefined libc/libm
@@ -289,29 +156,29 @@ class Context {
289156
/// they do not, but they are recognized as builtins once we see
290157
/// a declaration.
291158
bool isPredefinedLibFunction(unsigned ID) const {
292-
return strchr(getAttributesString(ID), 'f') != nullptr;
159+
return strchr(getRecord(ID).Attributes, 'f') != nullptr;
293160
}
294161

295162
/// Returns true if this builtin requires appropriate header in other
296163
/// compilers. In Clang it will work even without including it, but we can emit
297164
/// a warning about missing header.
298165
bool isHeaderDependentFunction(unsigned ID) const {
299-
return strchr(getAttributesString(ID), 'h') != nullptr;
166+
return strchr(getRecord(ID).Attributes, 'h') != nullptr;
300167
}
301168

302169
/// Determines whether this builtin is a predefined compiler-rt/libgcc
303170
/// function, such as "__clear_cache", where we know the signature a
304171
/// priori.
305172
bool isPredefinedRuntimeFunction(unsigned ID) const {
306-
return strchr(getAttributesString(ID), 'i') != nullptr;
173+
return strchr(getRecord(ID).Attributes, 'i') != nullptr;
307174
}
308175

309176
/// Determines whether this builtin is a C++ standard library function
310177
/// that lives in (possibly-versioned) namespace std, possibly a template
311178
/// specialization, where the signature is determined by the standard library
312179
/// declaration.
313180
bool isInStdNamespace(unsigned ID) const {
314-
return strchr(getAttributesString(ID), 'z') != nullptr;
181+
return strchr(getRecord(ID).Attributes, 'z') != nullptr;
315182
}
316183

317184
/// Determines whether this builtin can have its address taken with no
@@ -325,33 +192,33 @@ class Context {
325192

326193
/// Determines whether this builtin has custom typechecking.
327194
bool hasCustomTypechecking(unsigned ID) const {
328-
return strchr(getAttributesString(ID), 't') != nullptr;
195+
return strchr(getRecord(ID).Attributes, 't') != nullptr;
329196
}
330197

331198
/// Determines whether a declaration of this builtin should be recognized
332199
/// even if the type doesn't match the specified signature.
333200
bool allowTypeMismatch(unsigned ID) const {
334-
return strchr(getAttributesString(ID), 'T') != nullptr ||
201+
return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
335202
hasCustomTypechecking(ID);
336203
}
337204

338205
/// Determines whether this builtin has a result or any arguments which
339206
/// are pointer types.
340207
bool hasPtrArgsOrResult(unsigned ID) const {
341-
return strchr(getTypeString(ID), '*') != nullptr;
208+
return strchr(getRecord(ID).Type, '*') != nullptr;
342209
}
343210

344211
/// Return true if this builtin has a result or any arguments which are
345212
/// reference types.
346213
bool hasReferenceArgsOrResult(unsigned ID) const {
347-
return strchr(getTypeString(ID), '&') != nullptr ||
348-
strchr(getTypeString(ID), 'A') != nullptr;
214+
return strchr(getRecord(ID).Type, '&') != nullptr ||
215+
strchr(getRecord(ID).Type, 'A') != nullptr;
349216
}
350217

351218
/// If this is a library function that comes from a specific
352219
/// header, retrieve that header name.
353220
const char *getHeaderName(unsigned ID) const {
354-
return getInfo(ID).Header.getName();
221+
return getRecord(ID).Header.getName();
355222
}
356223

357224
/// Determine whether this builtin is like printf in its
@@ -376,25 +243,27 @@ class Context {
376243
/// Such functions can be const when the MathErrno lang option and FP
377244
/// exceptions are disabled.
378245
bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
379-
return strchr(getAttributesString(ID), 'e') != nullptr;
246+
return strchr(getRecord(ID).Attributes, 'e') != nullptr;
380247
}
381248

382249
bool isConstWithoutExceptions(unsigned ID) const {
383-
return strchr(getAttributesString(ID), 'g') != nullptr;
250+
return strchr(getRecord(ID).Attributes, 'g') != nullptr;
384251
}
385252

386-
const char *getRequiredFeatures(unsigned ID) const;
253+
const char *getRequiredFeatures(unsigned ID) const {
254+
return getRecord(ID).Features;
255+
}
387256

388257
unsigned getRequiredVectorWidth(unsigned ID) const;
389258

390259
/// Return true if builtin ID belongs to AuxTarget.
391260
bool isAuxBuiltinID(unsigned ID) const {
392-
return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
261+
return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
393262
}
394263

395264
/// Return real builtin ID (i.e. ID it would have during compilation
396265
/// for AuxTarget).
397-
unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
266+
unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
398267

399268
/// Returns true if this is a libc/libm function without the '__builtin_'
400269
/// prefix.
@@ -406,20 +275,16 @@ class Context {
406275

407276
/// Return true if this function can be constant evaluated by Clang frontend.
408277
bool isConstantEvaluated(unsigned ID) const {
409-
return strchr(getAttributesString(ID), 'E') != nullptr;
278+
return strchr(getRecord(ID).Attributes, 'E') != nullptr;
410279
}
411280

412281
/// Returns true if this is an immediate (consteval) function
413282
bool isImmediate(unsigned ID) const {
414-
return strchr(getAttributesString(ID), 'G') != nullptr;
283+
return strchr(getRecord(ID).Attributes, 'G') != nullptr;
415284
}
416285

417286
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-
}
287+
const Info &getRecord(unsigned ID) const;
423288

424289
/// Helper function for isPrintfLike and isScanfLike.
425290
bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,

clang/include/clang/Basic/BuiltinsPPC.def

-1
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
11381138
// FIXME: Obviously incomplete.
11391139

11401140
#undef BUILTIN
1141-
#undef TARGET_BUILTIN
11421141
#undef CUSTOM_BUILTIN
11431142
#undef UNALIASED_CUSTOM_BUILTIN

clang/include/clang/Basic/TargetInfo.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include "clang/Basic/AddressSpaces.h"
1818
#include "clang/Basic/BitmaskEnum.h"
19-
#include "clang/Basic/Builtins.h"
2019
#include "clang/Basic/CFProtectionOptions.h"
2120
#include "clang/Basic/CodeGenOptions.h"
2221
#include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,10 @@ class TargetInfo : public TransferrableTargetInfo,
10101009
virtual void getTargetDefines(const LangOptions &Opts,
10111010
MacroBuilder &Builder) const = 0;
10121011

1013-
/// Return information about target-specific builtins for the current primary
1014-
/// target, and info about which builtins are non-portable across the current
1015-
/// set of primary and secondary targets.
1016-
virtual std::pair<const char *, ArrayRef<Builtin::Info>>
1017-
getTargetBuiltinStorage() const = 0;
1012+
/// Return information about target-specific builtins for
1013+
/// the current primary target, and info about which builtins are non-portable
1014+
/// across the current set of primary and secondary targets.
1015+
virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
10181016

10191017
/// Returns target-specific min and max values VScale_Range.
10201018
virtual std::optional<std::pair<unsigned, unsigned>>

0 commit comments

Comments
 (0)