@@ -34,6 +34,19 @@ static bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) {
34
34
}
35
35
}
36
36
37
+ static void CheckArrayDesignatorSyntax (Parser &P, SourceLocation Loc,
38
+ Designation &Desig) {
39
+ // If we have exactly one array designator, this used the GNU
40
+ // 'designation: array-designator' extension, otherwise there should be no
41
+ // designators at all!
42
+ if (Desig.getNumDesignators () == 1 &&
43
+ (Desig.getDesignator (0 ).isArrayDesignator () ||
44
+ Desig.getDesignator (0 ).isArrayRangeDesignator ()))
45
+ P.Diag (Loc, diag::ext_gnu_missing_equal_designator);
46
+ else if (Desig.getNumDesignators () > 0 )
47
+ P.Diag (Loc, diag::err_expected_equal_designator);
48
+ }
49
+
37
50
// / ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
38
51
// / checking to see if the token stream starts with a designator.
39
52
// /
@@ -124,10 +137,46 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
124
137
// [4][foo bar] -> obsolete GNU designation with objc message send.
125
138
//
126
139
SourceLocation StartLoc = ConsumeBracket ();
140
+ OwningExprResult Idx (Actions);
141
+
142
+ // If Objective-C is enabled and this is a typename (class message
143
+ // send) or send to 'super', parse this as a message send
144
+ // expression. We handle C++ and C separately, since C++ requires
145
+ // much more complicated parsing.
146
+ if (getLang ().ObjC1 && getLang ().CPlusPlus ) {
147
+ // Send to 'super'.
148
+ if (Tok.is (tok::identifier) && Tok.getIdentifierInfo () == Ident_super &&
149
+ NextToken ().isNot (tok::period) && CurScope->isInObjcMethodScope ()) {
150
+ CheckArrayDesignatorSyntax (*this , StartLoc, Desig);
151
+ return ParseAssignmentExprWithObjCMessageExprStart (StartLoc,
152
+ ConsumeToken (), 0 ,
153
+ ExprArg (Actions));
154
+ }
127
155
128
- // If Objective-C is enabled and this is a typename (class message send) or
129
- // send to 'super', parse this as a message send expression.
130
- if (getLang ().ObjC1 && Tok.is (tok::identifier)) {
156
+ // Parse the receiver, which is either a type or an expression.
157
+ bool IsExpr;
158
+ void *TypeOrExpr;
159
+ if (ParseObjCXXMessageReceiver (IsExpr, TypeOrExpr)) {
160
+ SkipUntil (tok::r_square);
161
+ return ExprError ();
162
+ }
163
+
164
+ // If the receiver was a type, we have a class message; parse
165
+ // the rest of it.
166
+ if (!IsExpr) {
167
+ CheckArrayDesignatorSyntax (*this , StartLoc, Desig);
168
+ return ParseAssignmentExprWithObjCMessageExprStart (StartLoc,
169
+ SourceLocation (),
170
+ TypeOrExpr,
171
+ ExprArg (Actions));
172
+ }
173
+
174
+ // If the receiver was an expression, we still don't know
175
+ // whether we have a message send or an array designator; just
176
+ // adopt the expression for further analysis below.
177
+ // FIXME: potentially-potentially evaluated expression above?
178
+ Idx = OwningExprResult (Actions, TypeOrExpr);
179
+ } else if (getLang ().ObjC1 && Tok.is (tok::identifier)) {
131
180
IdentifierInfo *II = Tok.getIdentifierInfo ();
132
181
SourceLocation IILoc = Tok.getLocation ();
133
182
TypeTy *ReceiverType;
@@ -141,16 +190,7 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
141
190
ReceiverType)) {
142
191
case Action::ObjCSuperMessage:
143
192
case Action::ObjCClassMessage:
144
- // If we have exactly one array designator, this used the GNU
145
- // 'designation: array-designator' extension, otherwise there should be no
146
- // designators at all!
147
- if (Desig.getNumDesignators () == 1 &&
148
- (Desig.getDesignator (0 ).isArrayDesignator () ||
149
- Desig.getDesignator (0 ).isArrayRangeDesignator ()))
150
- Diag (StartLoc, diag::ext_gnu_missing_equal_designator);
151
- else if (Desig.getNumDesignators () > 0 )
152
- Diag (Tok, diag::err_expected_equal_designator);
153
-
193
+ CheckArrayDesignatorSyntax (*this , StartLoc, Desig);
154
194
if (Kind == Action::ObjCSuperMessage)
155
195
return ParseAssignmentExprWithObjCMessageExprStart (StartLoc,
156
196
ConsumeToken (),
@@ -175,13 +215,19 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
175
215
}
176
216
}
177
217
218
+ // Parse the index expression, if we haven't already gotten one
219
+ // above (which can only happen in Objective-C++).
178
220
// Note that we parse this as an assignment expression, not a constant
179
221
// expression (allowing *=, =, etc) to handle the objc case. Sema needs
180
222
// to validate that the expression is a constant.
181
- OwningExprResult Idx (ParseAssignmentExpression ());
182
- if (Idx.isInvalid ()) {
183
- SkipUntil (tok::r_square);
184
- return move (Idx);
223
+ // FIXME: We also need to tell Sema that we're in a
224
+ // potentially-potentially evaluated context.
225
+ if (!Idx.get ()) {
226
+ Idx = ParseAssignmentExpression ();
227
+ if (Idx.isInvalid ()) {
228
+ SkipUntil (tok::r_square);
229
+ return move (Idx);
230
+ }
185
231
}
186
232
187
233
// Given an expression, we could either have a designator (if the next
@@ -190,17 +236,7 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
190
236
// an assignment-expression production.
191
237
if (getLang ().ObjC1 && Tok.isNot (tok::ellipsis) &&
192
238
Tok.isNot (tok::r_square)) {
193
-
194
- // If we have exactly one array designator, this used the GNU
195
- // 'designation: array-designator' extension, otherwise there should be no
196
- // designators at all!
197
- if (Desig.getNumDesignators () == 1 &&
198
- (Desig.getDesignator (0 ).isArrayDesignator () ||
199
- Desig.getDesignator (0 ).isArrayRangeDesignator ()))
200
- Diag (StartLoc, diag::ext_gnu_missing_equal_designator);
201
- else if (Desig.getNumDesignators () > 0 )
202
- Diag (Tok, diag::err_expected_equal_designator);
203
-
239
+ CheckArrayDesignatorSyntax (*this , Tok.getLocation (), Desig);
204
240
return ParseAssignmentExprWithObjCMessageExprStart (StartLoc,
205
241
SourceLocation (),
206
242
0 , move (Idx));
0 commit comments