@@ -47,9 +47,47 @@ class PrototypeParser {
47
47
if (!Prototype.ends_with (" )" ))
48
48
PrintFatalError (Loc, " Expected closing brace at end of prototype" );
49
49
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
+ }
53
91
}
54
92
55
93
void ParseType (StringRef T) {
@@ -85,6 +123,23 @@ class PrototypeParser {
85
123
if (Substitution.empty ())
86
124
PrintFatalError (Loc, " Not a template" );
87
125
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);
88
143
} else {
89
144
auto ReturnTypeVal = StringSwitch<std::string>(T)
90
145
.Case (" __builtin_va_list_ref" , " A" )
0 commit comments