ParseInit.cpp revision 210299
1193326Sed//===--- ParseInit.cpp - Initializer Parsing ------------------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements initializer parsing as specified by C99 6.7.8. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/Parse/Designator.h" 15193326Sed#include "clang/Parse/Parser.h" 16193326Sed#include "clang/Parse/ParseDiagnostic.h" 17207619Srdivacky#include "clang/Parse/Scope.h" 18193326Sed#include "llvm/ADT/SmallString.h" 19198398Srdivacky#include "llvm/Support/raw_ostream.h" 20193326Sedusing namespace clang; 21193326Sed 22193326Sed 23193326Sed/// MayBeDesignationStart - Return true if this token might be the start of a 24193326Sed/// designator. If we can tell it is impossible that it is a designator, return 25198092Srdivacky/// false. 26193326Sedstatic bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) { 27193326Sed switch (K) { 28193326Sed default: return false; 29193326Sed case tok::period: // designator: '.' identifier 30193326Sed case tok::l_square: // designator: array-designator 31193326Sed return true; 32193326Sed case tok::identifier: // designation: identifier ':' 33193326Sed return PP.LookAhead(0).is(tok::colon); 34193326Sed } 35193326Sed} 36193326Sed 37207619Srdivackystatic void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, 38207619Srdivacky Designation &Desig) { 39207619Srdivacky // If we have exactly one array designator, this used the GNU 40207619Srdivacky // 'designation: array-designator' extension, otherwise there should be no 41207619Srdivacky // designators at all! 42207619Srdivacky if (Desig.getNumDesignators() == 1 && 43207619Srdivacky (Desig.getDesignator(0).isArrayDesignator() || 44207619Srdivacky Desig.getDesignator(0).isArrayRangeDesignator())) 45207619Srdivacky P.Diag(Loc, diag::ext_gnu_missing_equal_designator); 46207619Srdivacky else if (Desig.getNumDesignators() > 0) 47207619Srdivacky P.Diag(Loc, diag::err_expected_equal_designator); 48207619Srdivacky} 49207619Srdivacky 50193326Sed/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production 51193326Sed/// checking to see if the token stream starts with a designator. 52193326Sed/// 53193326Sed/// designation: 54193326Sed/// designator-list '=' 55193326Sed/// [GNU] array-designator 56193326Sed/// [GNU] identifier ':' 57193326Sed/// 58193326Sed/// designator-list: 59193326Sed/// designator 60193326Sed/// designator-list designator 61193326Sed/// 62193326Sed/// designator: 63193326Sed/// array-designator 64193326Sed/// '.' identifier 65193326Sed/// 66193326Sed/// array-designator: 67193326Sed/// '[' constant-expression ']' 68193326Sed/// [GNU] '[' constant-expression '...' constant-expression ']' 69193326Sed/// 70193326Sed/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an 71193326Sed/// initializer (because it is an expression). We need to consider this case 72193326Sed/// when parsing array designators. 73193326Sed/// 74193326SedParser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { 75193326Sed 76193326Sed // If this is the old-style GNU extension: 77193326Sed // designation ::= identifier ':' 78193326Sed // Handle it as a field designator. Otherwise, this must be the start of a 79193326Sed // normal expression. 80193326Sed if (Tok.is(tok::identifier)) { 81193326Sed const IdentifierInfo *FieldName = Tok.getIdentifierInfo(); 82193326Sed 83198398Srdivacky llvm::SmallString<256> NewSyntax; 84198398Srdivacky llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName() 85198398Srdivacky << " = "; 86193326Sed 87193326Sed SourceLocation NameLoc = ConsumeToken(); // Eat the identifier. 88198092Srdivacky 89193326Sed assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!"); 90193326Sed SourceLocation ColonLoc = ConsumeToken(); 91193326Sed 92193326Sed Diag(Tok, diag::ext_gnu_old_style_field_designator) 93206084Srdivacky << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc), 94206084Srdivacky NewSyntax.str()); 95193326Sed 96193326Sed Designation D; 97193326Sed D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc)); 98198092Srdivacky return Actions.ActOnDesignatedInitializer(D, ColonLoc, true, 99193326Sed ParseInitializer()); 100193326Sed } 101198092Srdivacky 102193326Sed // Desig - This is initialized when we see our first designator. We may have 103193326Sed // an objc message send with no designator, so we don't want to create this 104193326Sed // eagerly. 105193326Sed Designation Desig; 106198092Srdivacky 107193326Sed // Parse each designator in the designator list until we find an initializer. 108193326Sed while (Tok.is(tok::period) || Tok.is(tok::l_square)) { 109193326Sed if (Tok.is(tok::period)) { 110193326Sed // designator: '.' identifier 111193326Sed SourceLocation DotLoc = ConsumeToken(); 112198092Srdivacky 113193326Sed if (Tok.isNot(tok::identifier)) { 114193326Sed Diag(Tok.getLocation(), diag::err_expected_field_designator); 115193326Sed return ExprError(); 116193326Sed } 117198092Srdivacky 118193326Sed Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc, 119193326Sed Tok.getLocation())); 120193326Sed ConsumeToken(); // Eat the identifier. 121193326Sed continue; 122193326Sed } 123198092Srdivacky 124193326Sed // We must have either an array designator now or an objc message send. 125193326Sed assert(Tok.is(tok::l_square) && "Unexpected token!"); 126198092Srdivacky 127193326Sed // Handle the two forms of array designator: 128193326Sed // array-designator: '[' constant-expression ']' 129193326Sed // array-designator: '[' constant-expression '...' constant-expression ']' 130193326Sed // 131193326Sed // Also, we have to handle the case where the expression after the 132193326Sed // designator an an objc message send: '[' objc-message-expr ']'. 133193326Sed // Interesting cases are: 134193326Sed // [foo bar] -> objc message send 135193326Sed // [foo] -> array designator 136193326Sed // [foo ... bar] -> array designator 137193326Sed // [4][foo bar] -> obsolete GNU designation with objc message send. 138193326Sed // 139193326Sed SourceLocation StartLoc = ConsumeBracket(); 140207619Srdivacky OwningExprResult Idx(Actions); 141198092Srdivacky 142207619Srdivacky // If Objective-C is enabled and this is a typename (class message 143207619Srdivacky // send) or send to 'super', parse this as a message send 144207619Srdivacky // expression. We handle C++ and C separately, since C++ requires 145207619Srdivacky // much more complicated parsing. 146207619Srdivacky if (getLang().ObjC1 && getLang().CPlusPlus) { 147207619Srdivacky // Send to 'super'. 148207619Srdivacky if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super && 149210299Sed NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope()) { 150207619Srdivacky CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 151207619Srdivacky return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 152207619Srdivacky ConsumeToken(), 0, 153207619Srdivacky ExprArg(Actions)); 154207619Srdivacky } 155193326Sed 156207619Srdivacky // Parse the receiver, which is either a type or an expression. 157207619Srdivacky bool IsExpr; 158207619Srdivacky void *TypeOrExpr; 159207619Srdivacky if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) { 160207619Srdivacky SkipUntil(tok::r_square); 161207619Srdivacky return ExprError(); 162207619Srdivacky } 163207619Srdivacky 164207619Srdivacky // If the receiver was a type, we have a class message; parse 165207619Srdivacky // the rest of it. 166207619Srdivacky if (!IsExpr) { 167207619Srdivacky CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 168207619Srdivacky return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 169207619Srdivacky SourceLocation(), 170207619Srdivacky TypeOrExpr, 171207619Srdivacky ExprArg(Actions)); 172207619Srdivacky } 173207619Srdivacky 174207619Srdivacky // If the receiver was an expression, we still don't know 175207619Srdivacky // whether we have a message send or an array designator; just 176207619Srdivacky // adopt the expression for further analysis below. 177207619Srdivacky // FIXME: potentially-potentially evaluated expression above? 178207619Srdivacky Idx = OwningExprResult(Actions, TypeOrExpr); 179207619Srdivacky } else if (getLang().ObjC1 && Tok.is(tok::identifier)) { 180207619Srdivacky IdentifierInfo *II = Tok.getIdentifierInfo(); 181207619Srdivacky SourceLocation IILoc = Tok.getLocation(); 182207619Srdivacky TypeTy *ReceiverType; 183207619Srdivacky // Three cases. This is a message send to a type: [type foo] 184207619Srdivacky // This is a message send to super: [super foo] 185207619Srdivacky // This is a message sent to an expr: [super.bar foo] 186207619Srdivacky switch (Action::ObjCMessageKind Kind 187210299Sed = Actions.getObjCMessageKind(getCurScope(), II, IILoc, 188207619Srdivacky II == Ident_super, 189207619Srdivacky NextToken().is(tok::period), 190207619Srdivacky ReceiverType)) { 191207619Srdivacky case Action::ObjCSuperMessage: 192207619Srdivacky case Action::ObjCClassMessage: 193207619Srdivacky CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 194207619Srdivacky if (Kind == Action::ObjCSuperMessage) 195207619Srdivacky return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 196207619Srdivacky ConsumeToken(), 197207619Srdivacky 0, 198207619Srdivacky ExprArg(Actions)); 199207619Srdivacky ConsumeToken(); // the identifier 200207619Srdivacky if (!ReceiverType) { 201207619Srdivacky SkipUntil(tok::r_square); 202207619Srdivacky return ExprError(); 203207619Srdivacky } 204207619Srdivacky 205207619Srdivacky return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 206207619Srdivacky SourceLocation(), 207207619Srdivacky ReceiverType, 208207619Srdivacky ExprArg(Actions)); 209207619Srdivacky 210207619Srdivacky case Action::ObjCInstanceMessage: 211207619Srdivacky // Fall through; we'll just parse the expression and 212207619Srdivacky // (possibly) treat this like an Objective-C message send 213207619Srdivacky // later. 214207619Srdivacky break; 215207619Srdivacky } 216193326Sed } 217193326Sed 218207619Srdivacky // Parse the index expression, if we haven't already gotten one 219207619Srdivacky // above (which can only happen in Objective-C++). 220193326Sed // Note that we parse this as an assignment expression, not a constant 221193326Sed // expression (allowing *=, =, etc) to handle the objc case. Sema needs 222193326Sed // to validate that the expression is a constant. 223207619Srdivacky // FIXME: We also need to tell Sema that we're in a 224207619Srdivacky // potentially-potentially evaluated context. 225207619Srdivacky if (!Idx.get()) { 226207619Srdivacky Idx = ParseAssignmentExpression(); 227207619Srdivacky if (Idx.isInvalid()) { 228207619Srdivacky SkipUntil(tok::r_square); 229207619Srdivacky return move(Idx); 230207619Srdivacky } 231193326Sed } 232198092Srdivacky 233193326Sed // Given an expression, we could either have a designator (if the next 234193326Sed // tokens are '...' or ']' or an objc message send. If this is an objc 235198092Srdivacky // message send, handle it now. An objc-message send is the start of 236193326Sed // an assignment-expression production. 237198092Srdivacky if (getLang().ObjC1 && Tok.isNot(tok::ellipsis) && 238193326Sed Tok.isNot(tok::r_square)) { 239207619Srdivacky CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig); 240193326Sed return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 241193326Sed SourceLocation(), 242193326Sed 0, move(Idx)); 243193326Sed } 244193326Sed 245193326Sed // If this is a normal array designator, remember it. 246193326Sed if (Tok.isNot(tok::ellipsis)) { 247193326Sed Desig.AddDesignator(Designator::getArray(Idx.release(), StartLoc)); 248193326Sed } else { 249193326Sed // Handle the gnu array range extension. 250193326Sed Diag(Tok, diag::ext_gnu_array_range); 251193326Sed SourceLocation EllipsisLoc = ConsumeToken(); 252193326Sed 253193326Sed OwningExprResult RHS(ParseConstantExpression()); 254193326Sed if (RHS.isInvalid()) { 255193326Sed SkipUntil(tok::r_square); 256193326Sed return move(RHS); 257193326Sed } 258193326Sed Desig.AddDesignator(Designator::getArrayRange(Idx.release(), 259193326Sed RHS.release(), 260193326Sed StartLoc, EllipsisLoc)); 261193326Sed } 262193326Sed 263193326Sed SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc); 264193326Sed Desig.getDesignator(Desig.getNumDesignators() - 1).setRBracketLoc(EndLoc); 265193326Sed } 266193326Sed 267193326Sed // Okay, we're done with the designator sequence. We know that there must be 268193326Sed // at least one designator, because the only case we can get into this method 269193326Sed // without a designator is when we have an objc message send. That case is 270193326Sed // handled and returned from above. 271193326Sed assert(!Desig.empty() && "Designator is empty?"); 272193326Sed 273193326Sed // Handle a normal designator sequence end, which is an equal. 274193326Sed if (Tok.is(tok::equal)) { 275193326Sed SourceLocation EqualLoc = ConsumeToken(); 276193326Sed return Actions.ActOnDesignatedInitializer(Desig, EqualLoc, false, 277193326Sed ParseInitializer()); 278193326Sed } 279193326Sed 280193326Sed // We read some number of designators and found something that isn't an = or 281193326Sed // an initializer. If we have exactly one array designator, this 282193326Sed // is the GNU 'designation: array-designator' extension. Otherwise, it is a 283193326Sed // parse error. 284198092Srdivacky if (Desig.getNumDesignators() == 1 && 285193326Sed (Desig.getDesignator(0).isArrayDesignator() || 286193326Sed Desig.getDesignator(0).isArrayRangeDesignator())) { 287193326Sed Diag(Tok, diag::ext_gnu_missing_equal_designator) 288206084Srdivacky << FixItHint::CreateInsertion(Tok.getLocation(), "= "); 289193326Sed return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(), 290193326Sed true, ParseInitializer()); 291193326Sed } 292193326Sed 293193326Sed Diag(Tok, diag::err_expected_equal_designator); 294193326Sed return ExprError(); 295193326Sed} 296193326Sed 297193326Sed 298193326Sed/// ParseBraceInitializer - Called when parsing an initializer that has a 299193326Sed/// leading open brace. 300193326Sed/// 301193326Sed/// initializer: [C99 6.7.8] 302193326Sed/// '{' initializer-list '}' 303193326Sed/// '{' initializer-list ',' '}' 304193326Sed/// [GNU] '{' '}' 305193326Sed/// 306193326Sed/// initializer-list: 307193326Sed/// designation[opt] initializer 308193326Sed/// initializer-list ',' designation[opt] initializer 309193326Sed/// 310193326SedParser::OwningExprResult Parser::ParseBraceInitializer() { 311193326Sed SourceLocation LBraceLoc = ConsumeBrace(); 312193326Sed 313193326Sed /// InitExprs - This is the actual list of expressions contained in the 314193326Sed /// initializer. 315193326Sed ExprVector InitExprs(Actions); 316193326Sed 317193326Sed if (Tok.is(tok::r_brace)) { 318193326Sed // Empty initializers are a C++ feature and a GNU extension to C. 319193326Sed if (!getLang().CPlusPlus) 320193326Sed Diag(LBraceLoc, diag::ext_gnu_empty_initializer); 321193326Sed // Match the '}'. 322193326Sed return Actions.ActOnInitList(LBraceLoc, Action::MultiExprArg(Actions), 323193326Sed ConsumeBrace()); 324193326Sed } 325193326Sed 326193326Sed bool InitExprsOk = true; 327193326Sed 328193326Sed while (1) { 329193326Sed // Parse: designation[opt] initializer 330193326Sed 331193326Sed // If we know that this cannot be a designation, just parse the nested 332193326Sed // initializer directly. 333193326Sed OwningExprResult SubElt(Actions); 334193326Sed if (MayBeDesignationStart(Tok.getKind(), PP)) 335193326Sed SubElt = ParseInitializerWithPotentialDesignator(); 336193326Sed else 337193326Sed SubElt = ParseInitializer(); 338198092Srdivacky 339193326Sed // If we couldn't parse the subelement, bail out. 340193326Sed if (!SubElt.isInvalid()) { 341193326Sed InitExprs.push_back(SubElt.release()); 342193326Sed } else { 343193326Sed InitExprsOk = false; 344198092Srdivacky 345193326Sed // We have two ways to try to recover from this error: if the code looks 346193326Sed // gramatically ok (i.e. we have a comma coming up) try to continue 347193326Sed // parsing the rest of the initializer. This allows us to emit 348193326Sed // diagnostics for later elements that we find. If we don't see a comma, 349193326Sed // assume there is a parse error, and just skip to recover. 350193326Sed // FIXME: This comment doesn't sound right. If there is a r_brace 351193326Sed // immediately, it can't be an error, since there is no other way of 352193326Sed // leaving this loop except through this if. 353193326Sed if (Tok.isNot(tok::comma)) { 354193326Sed SkipUntil(tok::r_brace, false, true); 355193326Sed break; 356193326Sed } 357193326Sed } 358193326Sed 359193326Sed // If we don't have a comma continued list, we're done. 360193326Sed if (Tok.isNot(tok::comma)) break; 361193326Sed 362193326Sed // TODO: save comma locations if some client cares. 363193326Sed ConsumeToken(); 364193326Sed 365193326Sed // Handle trailing comma. 366193326Sed if (Tok.is(tok::r_brace)) break; 367193326Sed } 368193326Sed if (InitExprsOk && Tok.is(tok::r_brace)) 369193326Sed return Actions.ActOnInitList(LBraceLoc, move_arg(InitExprs), 370193326Sed ConsumeBrace()); 371193326Sed 372193326Sed // Match the '}'. 373193326Sed MatchRHSPunctuation(tok::r_brace, LBraceLoc); 374193326Sed return ExprError(); // an error occurred. 375193326Sed} 376193326Sed 377