Skip to content

Commit e50a1dc

Browse files
committed
Remove the CustomEntry escape hatch from builtin TableGen
This was an especially challenging escape hatch because it directly forced the use of a specific X-macro structure and prevented any other form of TableGen emission. The problematic feature that motivated this is a case where a builtin's prototype can't be represented in the mini-language used by TableGen. Instead of adding a complete custom entry for this, this PR just teaches the prototype handling to do the same thing the X-macros did in this case: emit an empty string and let the Clang builtin handling respond appropriately. This should produce identical results while preserving all the rest of the structured representation in the builtin TableGen code.
1 parent dc3cd2e commit e50a1dc

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,10 +3347,12 @@ def VFork : LibBuiltin<"unistd.h"> {
33473347
}
33483348

33493349
// POSIX pthread.h
3350-
// FIXME: This should be a GNULibBuiltin, but it's currently missing the prototype.
33513350

3352-
def PthreadCreate : CustomEntry {
3353-
let Entry = "LIBBUILTIN(pthread_create, \"\", \"fC<2,3>\", PTHREAD_H, ALL_GNU_LANGUAGES)";
3351+
def PthreadCreate : GNULibBuiltin<"pthread.h"> {
3352+
let Spellings = ["pthread_create"];
3353+
let Attributes = [FunctionWithoutBuiltinPrefix, Callback<[2, 3]>];
3354+
// Note that we don't have an expressable prototype so we leave it empty.
3355+
let Prototype = "";
33543356
}
33553357

33563358
def SigSetJmp : LibBuiltin<"setjmp.h"> {

clang/include/clang/Basic/BuiltinsBase.td

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ class IndexedAttribute<string baseMangling, int I> : Attribute<baseMangling> {
1717
int Index = I;
1818
}
1919

20+
class MultiIndexAttribute<string baseMangling, list<int> Is>
21+
: Attribute<baseMangling> {
22+
list<int> Indices = Is;
23+
}
24+
2025
// Standard Attributes
2126
// -------------------
2227
def NoReturn : Attribute<"r">;
@@ -77,6 +82,10 @@ def Constexpr : Attribute<"E">;
7782
// Builtin is immediate and must be constant evaluated. Implies Constexpr, and will only be supported in C++20 mode.
7883
def Consteval : Attribute<"EG">;
7984

85+
// Callback behavior: the first index argument is called with the arguments
86+
// indicated by the remaining indices.
87+
class Callback<list<int> ArgIndices> : MultiIndexAttribute<"C", ArgIndices>;
88+
8089
// Builtin kinds
8190
// =============
8291

@@ -90,10 +99,6 @@ class Builtin {
9099
bit RequiresUndef = 0;
91100
}
92101

93-
class CustomEntry {
94-
string Entry;
95-
}
96-
97102
class AtomicBuiltin : Builtin;
98103
class TargetBuiltin : Builtin {
99104
string Features = "";

clang/utils/TableGen/ClangBuiltinsEmitter.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "TableGenBackends.h"
14+
#include "llvm/ADT/StringExtras.h"
1415
#include "llvm/ADT/StringSwitch.h"
1516
#include "llvm/TableGen/Error.h"
1617
#include "llvm/TableGen/Record.h"
@@ -37,6 +38,14 @@ class PrototypeParser {
3738
private:
3839
void ParsePrototype(StringRef Prototype) {
3940
Prototype = Prototype.trim();
41+
42+
// Some builtins don't have an expressible prototype, simply emit an empty
43+
// string for them.
44+
if (Prototype.empty()) {
45+
Type = "";
46+
return;
47+
}
48+
4049
ParseTypes(Prototype);
4150
}
4251

@@ -236,8 +245,15 @@ void PrintAttributes(const Record *Builtin, BuiltinType BT, raw_ostream &OS) {
236245

237246
for (const auto *Attr : Builtin->getValueAsListOfDefs("Attributes")) {
238247
OS << Attr->getValueAsString("Mangling");
239-
if (Attr->isSubClassOf("IndexedAttribute"))
248+
if (Attr->isSubClassOf("IndexedAttribute")) {
240249
OS << ':' << Attr->getValueAsInt("Index") << ':';
250+
} else if (Attr->isSubClassOf("MultiIndexAttribute")) {
251+
OS << '<';
252+
llvm::ListSeparator Sep(",");
253+
for (int64_t Index : Attr->getValueAsListOfInts("Indices"))
254+
OS << Sep << Index;
255+
OS << '>';
256+
}
241257
}
242258
OS << '\"';
243259
}
@@ -380,10 +396,6 @@ void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) {
380396
EmitBuiltin(OS, Builtin);
381397
}
382398

383-
for (const auto *Entry : Records.getAllDerivedDefinitions("CustomEntry")) {
384-
OS << Entry->getValueAsString("Entry") << '\n';
385-
}
386-
387399
OS << R"c++(
388400
#undef ATOMIC_BUILTIN
389401
#undef BUILTIN

0 commit comments

Comments
 (0)