Skip to content

Commit 53d9fe7

Browse files
committed
[clang][Builtins] Parse clang extended vectors types.
Clang extended vector types are mangled as follows: '_ExtVector<' <lanes> ',' <scalar type> '>' This is used to defetmine the builtins signature for builtins that use parameters defined as typedef <scalar type> ext_vector_type_<lanes>_<scalar type> __attribute__((ext_vector_type(<lanes>))) For example: typedef double ext_vector_type_4_double __attribute__((ext_vector_type(4)))
1 parent 00e4a41 commit 53d9fe7

File tree

2 files changed

+137
-3
lines changed

2 files changed

+137
-3
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// RUN: clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins | FileCheck %s
2+
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_LANES 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_LANES
3+
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_COMMA 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_COMMA
4+
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_TYPE 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_TYPE
5+
6+
include "clang/Basic/BuiltinsBase.td"
7+
8+
def : Builtin {
9+
// CHECK: BUILTIN(__builtin_01, "E8idE4b", "")
10+
let Prototype = "_ExtVector<8,int>(double, _ExtVector<4, bool>)";
11+
let Spellings = ["__builtin_01"];
12+
}
13+
14+
def : Builtin {
15+
// CHECK: BUILTIN(__builtin_02, "E8UiE4s", "")
16+
let Prototype = "_ExtVector<8,unsigned int>(_ExtVector<4, short>)";
17+
let Spellings = ["__builtin_02"];
18+
}
19+
20+
def : Builtin {
21+
// CHECK: BUILTIN(__builtin_03, "di", "")
22+
let Prototype = "double(int)";
23+
let Spellings = ["__builtin_03"];
24+
}
25+
26+
def : Builtin {
27+
// CHECK: BUILTIN(__builtin_04, "diIUi", "")
28+
let Prototype = "double(int, _Constant unsigned int)";
29+
let Spellings = ["__builtin_04"];
30+
}
31+
32+
def : Builtin {
33+
// CHECK: BUILTIN(__builtin_05, "v&v&", "")
34+
let Prototype = "void&(void&)";
35+
let Spellings = ["__builtin_05"];
36+
}
37+
38+
def : Builtin {
39+
// CHECK: BUILTIN(__builtin_06, "v*v*cC*.", "")
40+
let Prototype = "void*(void*, char const*, ...)";
41+
let Spellings = ["__builtin_06"];
42+
}
43+
44+
def : Builtin {
45+
// CHECK: BUILTIN(__builtin_07, "E8iE4dE4b.", "")
46+
let Prototype = "_ExtVector<8, int>(_ExtVector<4,double>, _ExtVector<4, bool>, ...)";
47+
let Spellings = ["__builtin_07"];
48+
}
49+
50+
def : Builtin {
51+
// CHECK: BUILTIN(__builtin_08, "di*R", "")
52+
let Prototype = "double(int * restrict)";
53+
let Spellings = ["__builtin_08"];
54+
}
55+
56+
#ifdef ERROR_EXPECTED_LANES
57+
def : Builtin {
58+
// ERROR_EXPECTED_LANES: :[[# @LINE + 1]]:7: error: Expected number of lanes after '_ExtVector<'
59+
let Prototype = "_ExtVector<int>(double)";
60+
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
61+
}
62+
#endif
63+
64+
#ifdef ERROR_EXPECTED_COMMA
65+
def : Builtin {
66+
// ERROR_EXPECTED_COMMA: :[[# @LINE + 1]]:7: error: Expected ',' after number of lanes in '_ExtVector<'
67+
let Prototype = "_ExtVector<8 int>(double)";
68+
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
69+
}
70+
#endif
71+
72+
#ifdef ERROR_EXPECTED_TYPE
73+
def : Builtin {
74+
// ERROR_EXPECTED_TYPE: :[[# @LINE + 1]]:7: error: Expected '>' after scalar type in '_ExtVector<N, type>'
75+
let Prototype = "_ExtVector<8, int (double)";
76+
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
77+
}
78+
#endif
79+

clang/utils/TableGen/ClangBuiltinsEmitter.cpp

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,47 @@ class PrototypeParser {
4747
if (!Prototype.ends_with(")"))
4848
PrintFatalError(Loc, "Expected closing brace at end of prototype");
4949
Prototype = Prototype.drop_back();
50-
for (auto T = Prototype.split(','); !T.first.empty();
51-
Prototype = T.second, T = Prototype.split(','))
52-
ParseType(T.first);
50+
51+
// Look through the input parameters.
52+
const size_t end = Prototype.size();
53+
for (size_t I = 0; I != end;) {
54+
const StringRef Current = Prototype.substr(I, end);
55+
// Skip any leading space or commas
56+
if (Current.starts_with(" ") || Current.starts_with(",")) {
57+
++I;
58+
continue;
59+
}
60+
61+
// Check if we are in _ExtVector. We do this first because
62+
// extended vectors are written in template form with the syntax
63+
// _ExtVector< ..., ...>, so we need to make sure we are not
64+
// detecting the comma of the template class as a separator for
65+
// the parameters of the prototype. Note: the assumption is that
66+
// we cannot have nested _ExtVector.
67+
if (Current.starts_with("_ExtVector<")) {
68+
const size_t EndTemplate = Current.find('>', 0);
69+
ParseType(Current.substr(0, EndTemplate + 1));
70+
// Move the prototype beyond _ExtVector<...>
71+
I += EndTemplate + 1;
72+
continue;
73+
}
74+
75+
// We know that we are past _ExtVector, therefore the first seen
76+
// comma is the boundary of a parameter in the prototype.
77+
if (size_t CommaPos = Current.find(',', 0)) {
78+
if (CommaPos != StringRef::npos) {
79+
StringRef T = Current.substr(0, CommaPos);
80+
ParseType(T);
81+
// Move the prototype beyond the comma.
82+
I += CommaPos + 1;
83+
continue;
84+
}
85+
}
86+
87+
// No more commas, parse final parameter.
88+
ParseType(Current);
89+
I = end;
90+
}
5391
}
5492

5593
void ParseType(StringRef T) {
@@ -85,6 +123,23 @@ class PrototypeParser {
85123
if (Substitution.empty())
86124
PrintFatalError(Loc, "Not a template");
87125
ParseType(Substitution);
126+
} else if (T.consume_front("_ExtVector")) {
127+
// Clang extended vector types are mangled as follows:
128+
//
129+
// '_ExtVector<' <lanes> ',' <scalar type> '>'
130+
if (!T.consume_front("<"))
131+
PrintFatalError(Loc, "Expected '<' after '_ExtVector'");
132+
unsigned long long Lanes;
133+
if (llvm::consumeUnsignedInteger(T, 10, Lanes))
134+
PrintFatalError(Loc, "Expected number of lanes after '_ExtVector<'");
135+
Type += "E" + std::to_string(Lanes);
136+
if (!T.consume_front(","))
137+
PrintFatalError(Loc,
138+
"Expected ',' after number of lanes in '_ExtVector<'");
139+
if (!T.consume_back(">"))
140+
PrintFatalError(
141+
Loc, "Expected '>' after scalar type in '_ExtVector<N, type>'");
142+
ParseType(T);
88143
} else {
89144
auto ReturnTypeVal = StringSwitch<std::string>(T)
90145
.Case("__builtin_va_list_ref", "A")

0 commit comments

Comments
 (0)