1*f4a2713aSLionel Sambuc //===--- ParseInit.cpp - Initializer Parsing ------------------------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This file implements initializer parsing as specified by C99 6.7.8. 11*f4a2713aSLionel Sambuc // 12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc #include "clang/Parse/Parser.h" 15*f4a2713aSLionel Sambuc #include "RAIIObjectsForParser.h" 16*f4a2713aSLionel Sambuc #include "clang/Parse/ParseDiagnostic.h" 17*f4a2713aSLionel Sambuc #include "clang/Sema/Designator.h" 18*f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h" 19*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h" 20*f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h" 21*f4a2713aSLionel Sambuc using namespace clang; 22*f4a2713aSLionel Sambuc 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambuc /// MayBeDesignationStart - Return true if the current token might be the start 25*f4a2713aSLionel Sambuc /// of a designator. If we can tell it is impossible that it is a designator, 26*f4a2713aSLionel Sambuc /// return false. 27*f4a2713aSLionel Sambuc bool Parser::MayBeDesignationStart() { 28*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 29*f4a2713aSLionel Sambuc default: 30*f4a2713aSLionel Sambuc return false; 31*f4a2713aSLionel Sambuc 32*f4a2713aSLionel Sambuc case tok::period: // designator: '.' identifier 33*f4a2713aSLionel Sambuc return true; 34*f4a2713aSLionel Sambuc 35*f4a2713aSLionel Sambuc case tok::l_square: { // designator: array-designator 36*f4a2713aSLionel Sambuc if (!PP.getLangOpts().CPlusPlus11) 37*f4a2713aSLionel Sambuc return true; 38*f4a2713aSLionel Sambuc 39*f4a2713aSLionel Sambuc // C++11 lambda expressions and C99 designators can be ambiguous all the 40*f4a2713aSLionel Sambuc // way through the closing ']' and to the next character. Handle the easy 41*f4a2713aSLionel Sambuc // cases here, and fall back to tentative parsing if those fail. 42*f4a2713aSLionel Sambuc switch (PP.LookAhead(0).getKind()) { 43*f4a2713aSLionel Sambuc case tok::equal: 44*f4a2713aSLionel Sambuc case tok::r_square: 45*f4a2713aSLionel Sambuc // Definitely starts a lambda expression. 46*f4a2713aSLionel Sambuc return false; 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc case tok::amp: 49*f4a2713aSLionel Sambuc case tok::kw_this: 50*f4a2713aSLionel Sambuc case tok::identifier: 51*f4a2713aSLionel Sambuc // We have to do additional analysis, because these could be the 52*f4a2713aSLionel Sambuc // start of a constant expression or a lambda capture list. 53*f4a2713aSLionel Sambuc break; 54*f4a2713aSLionel Sambuc 55*f4a2713aSLionel Sambuc default: 56*f4a2713aSLionel Sambuc // Anything not mentioned above cannot occur following a '[' in a 57*f4a2713aSLionel Sambuc // lambda expression. 58*f4a2713aSLionel Sambuc return true; 59*f4a2713aSLionel Sambuc } 60*f4a2713aSLionel Sambuc 61*f4a2713aSLionel Sambuc // Handle the complicated case below. 62*f4a2713aSLionel Sambuc break; 63*f4a2713aSLionel Sambuc } 64*f4a2713aSLionel Sambuc case tok::identifier: // designation: identifier ':' 65*f4a2713aSLionel Sambuc return PP.LookAhead(0).is(tok::colon); 66*f4a2713aSLionel Sambuc } 67*f4a2713aSLionel Sambuc 68*f4a2713aSLionel Sambuc // Parse up to (at most) the token after the closing ']' to determine 69*f4a2713aSLionel Sambuc // whether this is a C99 designator or a lambda. 70*f4a2713aSLionel Sambuc TentativeParsingAction Tentative(*this); 71*f4a2713aSLionel Sambuc ConsumeBracket(); 72*f4a2713aSLionel Sambuc while (true) { 73*f4a2713aSLionel Sambuc switch (Tok.getKind()) { 74*f4a2713aSLionel Sambuc case tok::equal: 75*f4a2713aSLionel Sambuc case tok::amp: 76*f4a2713aSLionel Sambuc case tok::identifier: 77*f4a2713aSLionel Sambuc case tok::kw_this: 78*f4a2713aSLionel Sambuc // These tokens can occur in a capture list or a constant-expression. 79*f4a2713aSLionel Sambuc // Keep looking. 80*f4a2713aSLionel Sambuc ConsumeToken(); 81*f4a2713aSLionel Sambuc continue; 82*f4a2713aSLionel Sambuc 83*f4a2713aSLionel Sambuc case tok::comma: 84*f4a2713aSLionel Sambuc // Since a comma cannot occur in a constant-expression, this must 85*f4a2713aSLionel Sambuc // be a lambda. 86*f4a2713aSLionel Sambuc Tentative.Revert(); 87*f4a2713aSLionel Sambuc return false; 88*f4a2713aSLionel Sambuc 89*f4a2713aSLionel Sambuc case tok::r_square: { 90*f4a2713aSLionel Sambuc // Once we hit the closing square bracket, we look at the next 91*f4a2713aSLionel Sambuc // token. If it's an '=', this is a designator. Otherwise, it's a 92*f4a2713aSLionel Sambuc // lambda expression. This decision favors lambdas over the older 93*f4a2713aSLionel Sambuc // GNU designator syntax, which allows one to omit the '=', but is 94*f4a2713aSLionel Sambuc // consistent with GCC. 95*f4a2713aSLionel Sambuc ConsumeBracket(); 96*f4a2713aSLionel Sambuc tok::TokenKind Kind = Tok.getKind(); 97*f4a2713aSLionel Sambuc Tentative.Revert(); 98*f4a2713aSLionel Sambuc return Kind == tok::equal; 99*f4a2713aSLionel Sambuc } 100*f4a2713aSLionel Sambuc 101*f4a2713aSLionel Sambuc default: 102*f4a2713aSLionel Sambuc // Anything else cannot occur in a lambda capture list, so it 103*f4a2713aSLionel Sambuc // must be a designator. 104*f4a2713aSLionel Sambuc Tentative.Revert(); 105*f4a2713aSLionel Sambuc return true; 106*f4a2713aSLionel Sambuc } 107*f4a2713aSLionel Sambuc } 108*f4a2713aSLionel Sambuc 109*f4a2713aSLionel Sambuc return true; 110*f4a2713aSLionel Sambuc } 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, 113*f4a2713aSLionel Sambuc Designation &Desig) { 114*f4a2713aSLionel Sambuc // If we have exactly one array designator, this used the GNU 115*f4a2713aSLionel Sambuc // 'designation: array-designator' extension, otherwise there should be no 116*f4a2713aSLionel Sambuc // designators at all! 117*f4a2713aSLionel Sambuc if (Desig.getNumDesignators() == 1 && 118*f4a2713aSLionel Sambuc (Desig.getDesignator(0).isArrayDesignator() || 119*f4a2713aSLionel Sambuc Desig.getDesignator(0).isArrayRangeDesignator())) 120*f4a2713aSLionel Sambuc P.Diag(Loc, diag::ext_gnu_missing_equal_designator); 121*f4a2713aSLionel Sambuc else if (Desig.getNumDesignators() > 0) 122*f4a2713aSLionel Sambuc P.Diag(Loc, diag::err_expected_equal_designator); 123*f4a2713aSLionel Sambuc } 124*f4a2713aSLionel Sambuc 125*f4a2713aSLionel Sambuc /// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production 126*f4a2713aSLionel Sambuc /// checking to see if the token stream starts with a designator. 127*f4a2713aSLionel Sambuc /// 128*f4a2713aSLionel Sambuc /// designation: 129*f4a2713aSLionel Sambuc /// designator-list '=' 130*f4a2713aSLionel Sambuc /// [GNU] array-designator 131*f4a2713aSLionel Sambuc /// [GNU] identifier ':' 132*f4a2713aSLionel Sambuc /// 133*f4a2713aSLionel Sambuc /// designator-list: 134*f4a2713aSLionel Sambuc /// designator 135*f4a2713aSLionel Sambuc /// designator-list designator 136*f4a2713aSLionel Sambuc /// 137*f4a2713aSLionel Sambuc /// designator: 138*f4a2713aSLionel Sambuc /// array-designator 139*f4a2713aSLionel Sambuc /// '.' identifier 140*f4a2713aSLionel Sambuc /// 141*f4a2713aSLionel Sambuc /// array-designator: 142*f4a2713aSLionel Sambuc /// '[' constant-expression ']' 143*f4a2713aSLionel Sambuc /// [GNU] '[' constant-expression '...' constant-expression ']' 144*f4a2713aSLionel Sambuc /// 145*f4a2713aSLionel Sambuc /// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an 146*f4a2713aSLionel Sambuc /// initializer (because it is an expression). We need to consider this case 147*f4a2713aSLionel Sambuc /// when parsing array designators. 148*f4a2713aSLionel Sambuc /// 149*f4a2713aSLionel Sambuc ExprResult Parser::ParseInitializerWithPotentialDesignator() { 150*f4a2713aSLionel Sambuc 151*f4a2713aSLionel Sambuc // If this is the old-style GNU extension: 152*f4a2713aSLionel Sambuc // designation ::= identifier ':' 153*f4a2713aSLionel Sambuc // Handle it as a field designator. Otherwise, this must be the start of a 154*f4a2713aSLionel Sambuc // normal expression. 155*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier)) { 156*f4a2713aSLionel Sambuc const IdentifierInfo *FieldName = Tok.getIdentifierInfo(); 157*f4a2713aSLionel Sambuc 158*f4a2713aSLionel Sambuc SmallString<256> NewSyntax; 159*f4a2713aSLionel Sambuc llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName() 160*f4a2713aSLionel Sambuc << " = "; 161*f4a2713aSLionel Sambuc 162*f4a2713aSLionel Sambuc SourceLocation NameLoc = ConsumeToken(); // Eat the identifier. 163*f4a2713aSLionel Sambuc 164*f4a2713aSLionel Sambuc assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!"); 165*f4a2713aSLionel Sambuc SourceLocation ColonLoc = ConsumeToken(); 166*f4a2713aSLionel Sambuc 167*f4a2713aSLionel Sambuc Diag(NameLoc, diag::ext_gnu_old_style_field_designator) 168*f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc), 169*f4a2713aSLionel Sambuc NewSyntax.str()); 170*f4a2713aSLionel Sambuc 171*f4a2713aSLionel Sambuc Designation D; 172*f4a2713aSLionel Sambuc D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc)); 173*f4a2713aSLionel Sambuc return Actions.ActOnDesignatedInitializer(D, ColonLoc, true, 174*f4a2713aSLionel Sambuc ParseInitializer()); 175*f4a2713aSLionel Sambuc } 176*f4a2713aSLionel Sambuc 177*f4a2713aSLionel Sambuc // Desig - This is initialized when we see our first designator. We may have 178*f4a2713aSLionel Sambuc // an objc message send with no designator, so we don't want to create this 179*f4a2713aSLionel Sambuc // eagerly. 180*f4a2713aSLionel Sambuc Designation Desig; 181*f4a2713aSLionel Sambuc 182*f4a2713aSLionel Sambuc // Parse each designator in the designator list until we find an initializer. 183*f4a2713aSLionel Sambuc while (Tok.is(tok::period) || Tok.is(tok::l_square)) { 184*f4a2713aSLionel Sambuc if (Tok.is(tok::period)) { 185*f4a2713aSLionel Sambuc // designator: '.' identifier 186*f4a2713aSLionel Sambuc SourceLocation DotLoc = ConsumeToken(); 187*f4a2713aSLionel Sambuc 188*f4a2713aSLionel Sambuc if (Tok.isNot(tok::identifier)) { 189*f4a2713aSLionel Sambuc Diag(Tok.getLocation(), diag::err_expected_field_designator); 190*f4a2713aSLionel Sambuc return ExprError(); 191*f4a2713aSLionel Sambuc } 192*f4a2713aSLionel Sambuc 193*f4a2713aSLionel Sambuc Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc, 194*f4a2713aSLionel Sambuc Tok.getLocation())); 195*f4a2713aSLionel Sambuc ConsumeToken(); // Eat the identifier. 196*f4a2713aSLionel Sambuc continue; 197*f4a2713aSLionel Sambuc } 198*f4a2713aSLionel Sambuc 199*f4a2713aSLionel Sambuc // We must have either an array designator now or an objc message send. 200*f4a2713aSLionel Sambuc assert(Tok.is(tok::l_square) && "Unexpected token!"); 201*f4a2713aSLionel Sambuc 202*f4a2713aSLionel Sambuc // Handle the two forms of array designator: 203*f4a2713aSLionel Sambuc // array-designator: '[' constant-expression ']' 204*f4a2713aSLionel Sambuc // array-designator: '[' constant-expression '...' constant-expression ']' 205*f4a2713aSLionel Sambuc // 206*f4a2713aSLionel Sambuc // Also, we have to handle the case where the expression after the 207*f4a2713aSLionel Sambuc // designator an an objc message send: '[' objc-message-expr ']'. 208*f4a2713aSLionel Sambuc // Interesting cases are: 209*f4a2713aSLionel Sambuc // [foo bar] -> objc message send 210*f4a2713aSLionel Sambuc // [foo] -> array designator 211*f4a2713aSLionel Sambuc // [foo ... bar] -> array designator 212*f4a2713aSLionel Sambuc // [4][foo bar] -> obsolete GNU designation with objc message send. 213*f4a2713aSLionel Sambuc // 214*f4a2713aSLionel Sambuc // We do not need to check for an expression starting with [[ here. If it 215*f4a2713aSLionel Sambuc // contains an Objective-C message send, then it is not an ill-formed 216*f4a2713aSLionel Sambuc // attribute. If it is a lambda-expression within an array-designator, then 217*f4a2713aSLionel Sambuc // it will be rejected because a constant-expression cannot begin with a 218*f4a2713aSLionel Sambuc // lambda-expression. 219*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, true); 220*f4a2713aSLionel Sambuc 221*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_square); 222*f4a2713aSLionel Sambuc T.consumeOpen(); 223*f4a2713aSLionel Sambuc SourceLocation StartLoc = T.getOpenLocation(); 224*f4a2713aSLionel Sambuc 225*f4a2713aSLionel Sambuc ExprResult Idx; 226*f4a2713aSLionel Sambuc 227*f4a2713aSLionel Sambuc // If Objective-C is enabled and this is a typename (class message 228*f4a2713aSLionel Sambuc // send) or send to 'super', parse this as a message send 229*f4a2713aSLionel Sambuc // expression. We handle C++ and C separately, since C++ requires 230*f4a2713aSLionel Sambuc // much more complicated parsing. 231*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus) { 232*f4a2713aSLionel Sambuc // Send to 'super'. 233*f4a2713aSLionel Sambuc if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super && 234*f4a2713aSLionel Sambuc NextToken().isNot(tok::period) && 235*f4a2713aSLionel Sambuc getCurScope()->isInObjcMethodScope()) { 236*f4a2713aSLionel Sambuc CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 237*f4a2713aSLionel Sambuc return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 238*f4a2713aSLionel Sambuc ConsumeToken(), 239*f4a2713aSLionel Sambuc ParsedType(), 240*f4a2713aSLionel Sambuc 0); 241*f4a2713aSLionel Sambuc } 242*f4a2713aSLionel Sambuc 243*f4a2713aSLionel Sambuc // Parse the receiver, which is either a type or an expression. 244*f4a2713aSLionel Sambuc bool IsExpr; 245*f4a2713aSLionel Sambuc void *TypeOrExpr; 246*f4a2713aSLionel Sambuc if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) { 247*f4a2713aSLionel Sambuc SkipUntil(tok::r_square, StopAtSemi); 248*f4a2713aSLionel Sambuc return ExprError(); 249*f4a2713aSLionel Sambuc } 250*f4a2713aSLionel Sambuc 251*f4a2713aSLionel Sambuc // If the receiver was a type, we have a class message; parse 252*f4a2713aSLionel Sambuc // the rest of it. 253*f4a2713aSLionel Sambuc if (!IsExpr) { 254*f4a2713aSLionel Sambuc CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 255*f4a2713aSLionel Sambuc return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 256*f4a2713aSLionel Sambuc SourceLocation(), 257*f4a2713aSLionel Sambuc ParsedType::getFromOpaquePtr(TypeOrExpr), 258*f4a2713aSLionel Sambuc 0); 259*f4a2713aSLionel Sambuc } 260*f4a2713aSLionel Sambuc 261*f4a2713aSLionel Sambuc // If the receiver was an expression, we still don't know 262*f4a2713aSLionel Sambuc // whether we have a message send or an array designator; just 263*f4a2713aSLionel Sambuc // adopt the expression for further analysis below. 264*f4a2713aSLionel Sambuc // FIXME: potentially-potentially evaluated expression above? 265*f4a2713aSLionel Sambuc Idx = ExprResult(static_cast<Expr*>(TypeOrExpr)); 266*f4a2713aSLionel Sambuc } else if (getLangOpts().ObjC1 && Tok.is(tok::identifier)) { 267*f4a2713aSLionel Sambuc IdentifierInfo *II = Tok.getIdentifierInfo(); 268*f4a2713aSLionel Sambuc SourceLocation IILoc = Tok.getLocation(); 269*f4a2713aSLionel Sambuc ParsedType ReceiverType; 270*f4a2713aSLionel Sambuc // Three cases. This is a message send to a type: [type foo] 271*f4a2713aSLionel Sambuc // This is a message send to super: [super foo] 272*f4a2713aSLionel Sambuc // This is a message sent to an expr: [super.bar foo] 273*f4a2713aSLionel Sambuc switch (Sema::ObjCMessageKind Kind 274*f4a2713aSLionel Sambuc = Actions.getObjCMessageKind(getCurScope(), II, IILoc, 275*f4a2713aSLionel Sambuc II == Ident_super, 276*f4a2713aSLionel Sambuc NextToken().is(tok::period), 277*f4a2713aSLionel Sambuc ReceiverType)) { 278*f4a2713aSLionel Sambuc case Sema::ObjCSuperMessage: 279*f4a2713aSLionel Sambuc case Sema::ObjCClassMessage: 280*f4a2713aSLionel Sambuc CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 281*f4a2713aSLionel Sambuc if (Kind == Sema::ObjCSuperMessage) 282*f4a2713aSLionel Sambuc return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 283*f4a2713aSLionel Sambuc ConsumeToken(), 284*f4a2713aSLionel Sambuc ParsedType(), 285*f4a2713aSLionel Sambuc 0); 286*f4a2713aSLionel Sambuc ConsumeToken(); // the identifier 287*f4a2713aSLionel Sambuc if (!ReceiverType) { 288*f4a2713aSLionel Sambuc SkipUntil(tok::r_square, StopAtSemi); 289*f4a2713aSLionel Sambuc return ExprError(); 290*f4a2713aSLionel Sambuc } 291*f4a2713aSLionel Sambuc 292*f4a2713aSLionel Sambuc return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 293*f4a2713aSLionel Sambuc SourceLocation(), 294*f4a2713aSLionel Sambuc ReceiverType, 295*f4a2713aSLionel Sambuc 0); 296*f4a2713aSLionel Sambuc 297*f4a2713aSLionel Sambuc case Sema::ObjCInstanceMessage: 298*f4a2713aSLionel Sambuc // Fall through; we'll just parse the expression and 299*f4a2713aSLionel Sambuc // (possibly) treat this like an Objective-C message send 300*f4a2713aSLionel Sambuc // later. 301*f4a2713aSLionel Sambuc break; 302*f4a2713aSLionel Sambuc } 303*f4a2713aSLionel Sambuc } 304*f4a2713aSLionel Sambuc 305*f4a2713aSLionel Sambuc // Parse the index expression, if we haven't already gotten one 306*f4a2713aSLionel Sambuc // above (which can only happen in Objective-C++). 307*f4a2713aSLionel Sambuc // Note that we parse this as an assignment expression, not a constant 308*f4a2713aSLionel Sambuc // expression (allowing *=, =, etc) to handle the objc case. Sema needs 309*f4a2713aSLionel Sambuc // to validate that the expression is a constant. 310*f4a2713aSLionel Sambuc // FIXME: We also need to tell Sema that we're in a 311*f4a2713aSLionel Sambuc // potentially-potentially evaluated context. 312*f4a2713aSLionel Sambuc if (!Idx.get()) { 313*f4a2713aSLionel Sambuc Idx = ParseAssignmentExpression(); 314*f4a2713aSLionel Sambuc if (Idx.isInvalid()) { 315*f4a2713aSLionel Sambuc SkipUntil(tok::r_square, StopAtSemi); 316*f4a2713aSLionel Sambuc return Idx; 317*f4a2713aSLionel Sambuc } 318*f4a2713aSLionel Sambuc } 319*f4a2713aSLionel Sambuc 320*f4a2713aSLionel Sambuc // Given an expression, we could either have a designator (if the next 321*f4a2713aSLionel Sambuc // tokens are '...' or ']' or an objc message send. If this is an objc 322*f4a2713aSLionel Sambuc // message send, handle it now. An objc-message send is the start of 323*f4a2713aSLionel Sambuc // an assignment-expression production. 324*f4a2713aSLionel Sambuc if (getLangOpts().ObjC1 && Tok.isNot(tok::ellipsis) && 325*f4a2713aSLionel Sambuc Tok.isNot(tok::r_square)) { 326*f4a2713aSLionel Sambuc CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig); 327*f4a2713aSLionel Sambuc return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 328*f4a2713aSLionel Sambuc SourceLocation(), 329*f4a2713aSLionel Sambuc ParsedType(), 330*f4a2713aSLionel Sambuc Idx.take()); 331*f4a2713aSLionel Sambuc } 332*f4a2713aSLionel Sambuc 333*f4a2713aSLionel Sambuc // If this is a normal array designator, remember it. 334*f4a2713aSLionel Sambuc if (Tok.isNot(tok::ellipsis)) { 335*f4a2713aSLionel Sambuc Desig.AddDesignator(Designator::getArray(Idx.release(), StartLoc)); 336*f4a2713aSLionel Sambuc } else { 337*f4a2713aSLionel Sambuc // Handle the gnu array range extension. 338*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_gnu_array_range); 339*f4a2713aSLionel Sambuc SourceLocation EllipsisLoc = ConsumeToken(); 340*f4a2713aSLionel Sambuc 341*f4a2713aSLionel Sambuc ExprResult RHS(ParseConstantExpression()); 342*f4a2713aSLionel Sambuc if (RHS.isInvalid()) { 343*f4a2713aSLionel Sambuc SkipUntil(tok::r_square, StopAtSemi); 344*f4a2713aSLionel Sambuc return RHS; 345*f4a2713aSLionel Sambuc } 346*f4a2713aSLionel Sambuc Desig.AddDesignator(Designator::getArrayRange(Idx.release(), 347*f4a2713aSLionel Sambuc RHS.release(), 348*f4a2713aSLionel Sambuc StartLoc, EllipsisLoc)); 349*f4a2713aSLionel Sambuc } 350*f4a2713aSLionel Sambuc 351*f4a2713aSLionel Sambuc T.consumeClose(); 352*f4a2713aSLionel Sambuc Desig.getDesignator(Desig.getNumDesignators() - 1).setRBracketLoc( 353*f4a2713aSLionel Sambuc T.getCloseLocation()); 354*f4a2713aSLionel Sambuc } 355*f4a2713aSLionel Sambuc 356*f4a2713aSLionel Sambuc // Okay, we're done with the designator sequence. We know that there must be 357*f4a2713aSLionel Sambuc // at least one designator, because the only case we can get into this method 358*f4a2713aSLionel Sambuc // without a designator is when we have an objc message send. That case is 359*f4a2713aSLionel Sambuc // handled and returned from above. 360*f4a2713aSLionel Sambuc assert(!Desig.empty() && "Designator is empty?"); 361*f4a2713aSLionel Sambuc 362*f4a2713aSLionel Sambuc // Handle a normal designator sequence end, which is an equal. 363*f4a2713aSLionel Sambuc if (Tok.is(tok::equal)) { 364*f4a2713aSLionel Sambuc SourceLocation EqualLoc = ConsumeToken(); 365*f4a2713aSLionel Sambuc return Actions.ActOnDesignatedInitializer(Desig, EqualLoc, false, 366*f4a2713aSLionel Sambuc ParseInitializer()); 367*f4a2713aSLionel Sambuc } 368*f4a2713aSLionel Sambuc 369*f4a2713aSLionel Sambuc // We read some number of designators and found something that isn't an = or 370*f4a2713aSLionel Sambuc // an initializer. If we have exactly one array designator, this 371*f4a2713aSLionel Sambuc // is the GNU 'designation: array-designator' extension. Otherwise, it is a 372*f4a2713aSLionel Sambuc // parse error. 373*f4a2713aSLionel Sambuc if (Desig.getNumDesignators() == 1 && 374*f4a2713aSLionel Sambuc (Desig.getDesignator(0).isArrayDesignator() || 375*f4a2713aSLionel Sambuc Desig.getDesignator(0).isArrayRangeDesignator())) { 376*f4a2713aSLionel Sambuc Diag(Tok, diag::ext_gnu_missing_equal_designator) 377*f4a2713aSLionel Sambuc << FixItHint::CreateInsertion(Tok.getLocation(), "= "); 378*f4a2713aSLionel Sambuc return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(), 379*f4a2713aSLionel Sambuc true, ParseInitializer()); 380*f4a2713aSLionel Sambuc } 381*f4a2713aSLionel Sambuc 382*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_equal_designator); 383*f4a2713aSLionel Sambuc return ExprError(); 384*f4a2713aSLionel Sambuc } 385*f4a2713aSLionel Sambuc 386*f4a2713aSLionel Sambuc 387*f4a2713aSLionel Sambuc /// ParseBraceInitializer - Called when parsing an initializer that has a 388*f4a2713aSLionel Sambuc /// leading open brace. 389*f4a2713aSLionel Sambuc /// 390*f4a2713aSLionel Sambuc /// initializer: [C99 6.7.8] 391*f4a2713aSLionel Sambuc /// '{' initializer-list '}' 392*f4a2713aSLionel Sambuc /// '{' initializer-list ',' '}' 393*f4a2713aSLionel Sambuc /// [GNU] '{' '}' 394*f4a2713aSLionel Sambuc /// 395*f4a2713aSLionel Sambuc /// initializer-list: 396*f4a2713aSLionel Sambuc /// designation[opt] initializer ...[opt] 397*f4a2713aSLionel Sambuc /// initializer-list ',' designation[opt] initializer ...[opt] 398*f4a2713aSLionel Sambuc /// 399*f4a2713aSLionel Sambuc ExprResult Parser::ParseBraceInitializer() { 400*f4a2713aSLionel Sambuc InMessageExpressionRAIIObject InMessage(*this, false); 401*f4a2713aSLionel Sambuc 402*f4a2713aSLionel Sambuc BalancedDelimiterTracker T(*this, tok::l_brace); 403*f4a2713aSLionel Sambuc T.consumeOpen(); 404*f4a2713aSLionel Sambuc SourceLocation LBraceLoc = T.getOpenLocation(); 405*f4a2713aSLionel Sambuc 406*f4a2713aSLionel Sambuc /// InitExprs - This is the actual list of expressions contained in the 407*f4a2713aSLionel Sambuc /// initializer. 408*f4a2713aSLionel Sambuc ExprVector InitExprs; 409*f4a2713aSLionel Sambuc 410*f4a2713aSLionel Sambuc if (Tok.is(tok::r_brace)) { 411*f4a2713aSLionel Sambuc // Empty initializers are a C++ feature and a GNU extension to C. 412*f4a2713aSLionel Sambuc if (!getLangOpts().CPlusPlus) 413*f4a2713aSLionel Sambuc Diag(LBraceLoc, diag::ext_gnu_empty_initializer); 414*f4a2713aSLionel Sambuc // Match the '}'. 415*f4a2713aSLionel Sambuc return Actions.ActOnInitList(LBraceLoc, None, ConsumeBrace()); 416*f4a2713aSLionel Sambuc } 417*f4a2713aSLionel Sambuc 418*f4a2713aSLionel Sambuc bool InitExprsOk = true; 419*f4a2713aSLionel Sambuc 420*f4a2713aSLionel Sambuc while (1) { 421*f4a2713aSLionel Sambuc // Handle Microsoft __if_exists/if_not_exists if necessary. 422*f4a2713aSLionel Sambuc if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 423*f4a2713aSLionel Sambuc Tok.is(tok::kw___if_not_exists))) { 424*f4a2713aSLionel Sambuc if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) { 425*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) break; 426*f4a2713aSLionel Sambuc ConsumeToken(); 427*f4a2713aSLionel Sambuc } 428*f4a2713aSLionel Sambuc if (Tok.is(tok::r_brace)) break; 429*f4a2713aSLionel Sambuc continue; 430*f4a2713aSLionel Sambuc } 431*f4a2713aSLionel Sambuc 432*f4a2713aSLionel Sambuc // Parse: designation[opt] initializer 433*f4a2713aSLionel Sambuc 434*f4a2713aSLionel Sambuc // If we know that this cannot be a designation, just parse the nested 435*f4a2713aSLionel Sambuc // initializer directly. 436*f4a2713aSLionel Sambuc ExprResult SubElt; 437*f4a2713aSLionel Sambuc if (MayBeDesignationStart()) 438*f4a2713aSLionel Sambuc SubElt = ParseInitializerWithPotentialDesignator(); 439*f4a2713aSLionel Sambuc else 440*f4a2713aSLionel Sambuc SubElt = ParseInitializer(); 441*f4a2713aSLionel Sambuc 442*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis)) 443*f4a2713aSLionel Sambuc SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken()); 444*f4a2713aSLionel Sambuc 445*f4a2713aSLionel Sambuc // If we couldn't parse the subelement, bail out. 446*f4a2713aSLionel Sambuc if (!SubElt.isInvalid()) { 447*f4a2713aSLionel Sambuc InitExprs.push_back(SubElt.release()); 448*f4a2713aSLionel Sambuc } else { 449*f4a2713aSLionel Sambuc InitExprsOk = false; 450*f4a2713aSLionel Sambuc 451*f4a2713aSLionel Sambuc // We have two ways to try to recover from this error: if the code looks 452*f4a2713aSLionel Sambuc // grammatically ok (i.e. we have a comma coming up) try to continue 453*f4a2713aSLionel Sambuc // parsing the rest of the initializer. This allows us to emit 454*f4a2713aSLionel Sambuc // diagnostics for later elements that we find. If we don't see a comma, 455*f4a2713aSLionel Sambuc // assume there is a parse error, and just skip to recover. 456*f4a2713aSLionel Sambuc // FIXME: This comment doesn't sound right. If there is a r_brace 457*f4a2713aSLionel Sambuc // immediately, it can't be an error, since there is no other way of 458*f4a2713aSLionel Sambuc // leaving this loop except through this if. 459*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) { 460*f4a2713aSLionel Sambuc SkipUntil(tok::r_brace, StopBeforeMatch); 461*f4a2713aSLionel Sambuc break; 462*f4a2713aSLionel Sambuc } 463*f4a2713aSLionel Sambuc } 464*f4a2713aSLionel Sambuc 465*f4a2713aSLionel Sambuc // If we don't have a comma continued list, we're done. 466*f4a2713aSLionel Sambuc if (Tok.isNot(tok::comma)) break; 467*f4a2713aSLionel Sambuc 468*f4a2713aSLionel Sambuc // TODO: save comma locations if some client cares. 469*f4a2713aSLionel Sambuc ConsumeToken(); 470*f4a2713aSLionel Sambuc 471*f4a2713aSLionel Sambuc // Handle trailing comma. 472*f4a2713aSLionel Sambuc if (Tok.is(tok::r_brace)) break; 473*f4a2713aSLionel Sambuc } 474*f4a2713aSLionel Sambuc 475*f4a2713aSLionel Sambuc bool closed = !T.consumeClose(); 476*f4a2713aSLionel Sambuc 477*f4a2713aSLionel Sambuc if (InitExprsOk && closed) 478*f4a2713aSLionel Sambuc return Actions.ActOnInitList(LBraceLoc, InitExprs, 479*f4a2713aSLionel Sambuc T.getCloseLocation()); 480*f4a2713aSLionel Sambuc 481*f4a2713aSLionel Sambuc return ExprError(); // an error occurred. 482*f4a2713aSLionel Sambuc } 483*f4a2713aSLionel Sambuc 484*f4a2713aSLionel Sambuc 485*f4a2713aSLionel Sambuc // Return true if a comma (or closing brace) is necessary after the 486*f4a2713aSLionel Sambuc // __if_exists/if_not_exists statement. 487*f4a2713aSLionel Sambuc bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs, 488*f4a2713aSLionel Sambuc bool &InitExprsOk) { 489*f4a2713aSLionel Sambuc bool trailingComma = false; 490*f4a2713aSLionel Sambuc IfExistsCondition Result; 491*f4a2713aSLionel Sambuc if (ParseMicrosoftIfExistsCondition(Result)) 492*f4a2713aSLionel Sambuc return false; 493*f4a2713aSLionel Sambuc 494*f4a2713aSLionel Sambuc BalancedDelimiterTracker Braces(*this, tok::l_brace); 495*f4a2713aSLionel Sambuc if (Braces.consumeOpen()) { 496*f4a2713aSLionel Sambuc Diag(Tok, diag::err_expected_lbrace); 497*f4a2713aSLionel Sambuc return false; 498*f4a2713aSLionel Sambuc } 499*f4a2713aSLionel Sambuc 500*f4a2713aSLionel Sambuc switch (Result.Behavior) { 501*f4a2713aSLionel Sambuc case IEB_Parse: 502*f4a2713aSLionel Sambuc // Parse the declarations below. 503*f4a2713aSLionel Sambuc break; 504*f4a2713aSLionel Sambuc 505*f4a2713aSLionel Sambuc case IEB_Dependent: 506*f4a2713aSLionel Sambuc Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists) 507*f4a2713aSLionel Sambuc << Result.IsIfExists; 508*f4a2713aSLionel Sambuc // Fall through to skip. 509*f4a2713aSLionel Sambuc 510*f4a2713aSLionel Sambuc case IEB_Skip: 511*f4a2713aSLionel Sambuc Braces.skipToEnd(); 512*f4a2713aSLionel Sambuc return false; 513*f4a2713aSLionel Sambuc } 514*f4a2713aSLionel Sambuc 515*f4a2713aSLionel Sambuc while (Tok.isNot(tok::eof)) { 516*f4a2713aSLionel Sambuc trailingComma = false; 517*f4a2713aSLionel Sambuc // If we know that this cannot be a designation, just parse the nested 518*f4a2713aSLionel Sambuc // initializer directly. 519*f4a2713aSLionel Sambuc ExprResult SubElt; 520*f4a2713aSLionel Sambuc if (MayBeDesignationStart()) 521*f4a2713aSLionel Sambuc SubElt = ParseInitializerWithPotentialDesignator(); 522*f4a2713aSLionel Sambuc else 523*f4a2713aSLionel Sambuc SubElt = ParseInitializer(); 524*f4a2713aSLionel Sambuc 525*f4a2713aSLionel Sambuc if (Tok.is(tok::ellipsis)) 526*f4a2713aSLionel Sambuc SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken()); 527*f4a2713aSLionel Sambuc 528*f4a2713aSLionel Sambuc // If we couldn't parse the subelement, bail out. 529*f4a2713aSLionel Sambuc if (!SubElt.isInvalid()) 530*f4a2713aSLionel Sambuc InitExprs.push_back(SubElt.release()); 531*f4a2713aSLionel Sambuc else 532*f4a2713aSLionel Sambuc InitExprsOk = false; 533*f4a2713aSLionel Sambuc 534*f4a2713aSLionel Sambuc if (Tok.is(tok::comma)) { 535*f4a2713aSLionel Sambuc ConsumeToken(); 536*f4a2713aSLionel Sambuc trailingComma = true; 537*f4a2713aSLionel Sambuc } 538*f4a2713aSLionel Sambuc 539*f4a2713aSLionel Sambuc if (Tok.is(tok::r_brace)) 540*f4a2713aSLionel Sambuc break; 541*f4a2713aSLionel Sambuc } 542*f4a2713aSLionel Sambuc 543*f4a2713aSLionel Sambuc Braces.consumeClose(); 544*f4a2713aSLionel Sambuc 545*f4a2713aSLionel Sambuc return !trailingComma; 546*f4a2713aSLionel Sambuc } 547