diff options
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 25 | ||||
-rw-r--r-- | clang/test/SemaObjC/objc-array-literal.m | 8 | ||||
-rw-r--r-- | clang/test/SemaObjC/objc-dictionary-literal.m | 7 |
3 files changed, 38 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 67abe5839bf..75ddfcb03ed 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -3416,6 +3416,7 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { ExprVector ElementExprs; // array elements. ConsumeBracket(); // consume the l_square. + bool HasInvalidEltExpr = false; while (Tok.isNot(tok::r_square)) { // Parse list of array element expressions (all must be id types). ExprResult Res(ParseAssignmentExpression()); @@ -3427,11 +3428,15 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { return Res; } + Res = Actions.CorrectDelayedTyposInExpr(Res.get()); + if (Res.isInvalid()) + HasInvalidEltExpr = true; + // Parse the ellipsis that indicates a pack expansion. if (Tok.is(tok::ellipsis)) Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken()); if (Res.isInvalid()) - return true; + HasInvalidEltExpr = true; ElementExprs.push_back(Res.get()); @@ -3442,6 +3447,10 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { << tok::comma); } SourceLocation EndLoc = ConsumeBracket(); // location of ']' + + if (HasInvalidEltExpr) + return ExprError(); + MultiExprArg Args(ElementExprs); return Actions.BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args); } @@ -3449,6 +3458,7 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { SmallVector<ObjCDictionaryElement, 4> Elements; // dictionary elements. ConsumeBrace(); // consume the l_square. + bool HasInvalidEltExpr = false; while (Tok.isNot(tok::r_brace)) { // Parse the comma separated key : value expressions. ExprResult KeyExpr; @@ -3478,7 +3488,15 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { return ValueExpr; } - // Parse the ellipsis that designates this as a pack expansion. + // Check the key and value for possible typos + KeyExpr = Actions.CorrectDelayedTyposInExpr(KeyExpr.get()); + ValueExpr = Actions.CorrectDelayedTyposInExpr(ValueExpr.get()); + if (KeyExpr.isInvalid() || ValueExpr.isInvalid()) + HasInvalidEltExpr = true; + + // Parse the ellipsis that designates this as a pack expansion. Do not + // ActOnPackExpansion here, leave it to template instantiation time where + // we can get better diagnostics. SourceLocation EllipsisLoc; if (getLangOpts().CPlusPlus) TryConsumeToken(tok::ellipsis, EllipsisLoc); @@ -3495,6 +3513,9 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { << tok::comma); } SourceLocation EndLoc = ConsumeBrace(); + + if (HasInvalidEltExpr) + return ExprError(); // Create the ObjCDictionaryLiteral. return Actions.BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc), diff --git a/clang/test/SemaObjC/objc-array-literal.m b/clang/test/SemaObjC/objc-array-literal.m index 281994a758b..c0a0c67d442 100644 --- a/clang/test/SemaObjC/objc-array-literal.m +++ b/clang/test/SemaObjC/objc-array-literal.m @@ -67,3 +67,11 @@ id radar15147688() { x = @[ @"stuff", @"hello" "world"]; // expected-warning {{concatenated NSString literal for an NSArray expression}} return x; } + +enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}} +void foo() { + NSArray *array = @[ + @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}} + @(XXXYYYZZZTypeSomethingSomething) // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}} + ]; +} diff --git a/clang/test/SemaObjC/objc-dictionary-literal.m b/clang/test/SemaObjC/objc-dictionary-literal.m index 1a2c29f74db..ce301a0c73a 100644 --- a/clang/test/SemaObjC/objc-dictionary-literal.m +++ b/clang/test/SemaObjC/objc-dictionary-literal.m @@ -63,3 +63,10 @@ int main() { return 0; } +enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}} +void foo() { + NSDictionary *d = @{ + @"A" : @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}} + @"F" : @(XXXYYYZZZTypeSomethingSomething), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}} + }; +} |