ParseInit.cpp revision 206084
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" 17193326Sed#include "llvm/ADT/SmallString.h" 18198398Srdivacky#include "llvm/Support/raw_ostream.h" 19193326Sedusing namespace clang; 20193326Sed 21193326Sed 22193326Sed/// MayBeDesignationStart - Return true if this token might be the start of a 23193326Sed/// designator. If we can tell it is impossible that it is a designator, return 24198092Srdivacky/// false. 25193326Sedstatic bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) { 26193326Sed switch (K) { 27193326Sed default: return false; 28193326Sed case tok::period: // designator: '.' identifier 29193326Sed case tok::l_square: // designator: array-designator 30193326Sed return true; 31193326Sed case tok::identifier: // designation: identifier ':' 32193326Sed return PP.LookAhead(0).is(tok::colon); 33193326Sed } 34193326Sed} 35193326Sed 36193326Sed/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production 37193326Sed/// checking to see if the token stream starts with a designator. 38193326Sed/// 39193326Sed/// designation: 40193326Sed/// designator-list '=' 41193326Sed/// [GNU] array-designator 42193326Sed/// [GNU] identifier ':' 43193326Sed/// 44193326Sed/// designator-list: 45193326Sed/// designator 46193326Sed/// designator-list designator 47193326Sed/// 48193326Sed/// designator: 49193326Sed/// array-designator 50193326Sed/// '.' identifier 51193326Sed/// 52193326Sed/// array-designator: 53193326Sed/// '[' constant-expression ']' 54193326Sed/// [GNU] '[' constant-expression '...' constant-expression ']' 55193326Sed/// 56193326Sed/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an 57193326Sed/// initializer (because it is an expression). We need to consider this case 58193326Sed/// when parsing array designators. 59193326Sed/// 60193326SedParser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { 61193326Sed 62193326Sed // If this is the old-style GNU extension: 63193326Sed // designation ::= identifier ':' 64193326Sed // Handle it as a field designator. Otherwise, this must be the start of a 65193326Sed // normal expression. 66193326Sed if (Tok.is(tok::identifier)) { 67193326Sed const IdentifierInfo *FieldName = Tok.getIdentifierInfo(); 68193326Sed 69198398Srdivacky llvm::SmallString<256> NewSyntax; 70198398Srdivacky llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName() 71198398Srdivacky << " = "; 72193326Sed 73193326Sed SourceLocation NameLoc = ConsumeToken(); // Eat the identifier. 74198092Srdivacky 75193326Sed assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!"); 76193326Sed SourceLocation ColonLoc = ConsumeToken(); 77193326Sed 78193326Sed Diag(Tok, diag::ext_gnu_old_style_field_designator) 79206084Srdivacky << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc), 80206084Srdivacky NewSyntax.str()); 81193326Sed 82193326Sed Designation D; 83193326Sed D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc)); 84198092Srdivacky return Actions.ActOnDesignatedInitializer(D, ColonLoc, true, 85193326Sed ParseInitializer()); 86193326Sed } 87198092Srdivacky 88193326Sed // Desig - This is initialized when we see our first designator. We may have 89193326Sed // an objc message send with no designator, so we don't want to create this 90193326Sed // eagerly. 91193326Sed Designation Desig; 92198092Srdivacky 93193326Sed // Parse each designator in the designator list until we find an initializer. 94193326Sed while (Tok.is(tok::period) || Tok.is(tok::l_square)) { 95193326Sed if (Tok.is(tok::period)) { 96193326Sed // designator: '.' identifier 97193326Sed SourceLocation DotLoc = ConsumeToken(); 98198092Srdivacky 99193326Sed if (Tok.isNot(tok::identifier)) { 100193326Sed Diag(Tok.getLocation(), diag::err_expected_field_designator); 101193326Sed return ExprError(); 102193326Sed } 103198092Srdivacky 104193326Sed Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc, 105193326Sed Tok.getLocation())); 106193326Sed ConsumeToken(); // Eat the identifier. 107193326Sed continue; 108193326Sed } 109198092Srdivacky 110193326Sed // We must have either an array designator now or an objc message send. 111193326Sed assert(Tok.is(tok::l_square) && "Unexpected token!"); 112198092Srdivacky 113193326Sed // Handle the two forms of array designator: 114193326Sed // array-designator: '[' constant-expression ']' 115193326Sed // array-designator: '[' constant-expression '...' constant-expression ']' 116193326Sed // 117193326Sed // Also, we have to handle the case where the expression after the 118193326Sed // designator an an objc message send: '[' objc-message-expr ']'. 119193326Sed // Interesting cases are: 120193326Sed // [foo bar] -> objc message send 121193326Sed // [foo] -> array designator 122193326Sed // [foo ... bar] -> array designator 123193326Sed // [4][foo bar] -> obsolete GNU designation with objc message send. 124193326Sed // 125193326Sed SourceLocation StartLoc = ConsumeBracket(); 126198092Srdivacky 127193326Sed // If Objective-C is enabled and this is a typename or other identifier 128193326Sed // receiver, parse this as a message send expression. 129193326Sed if (getLang().ObjC1 && isTokObjCMessageIdentifierReceiver()) { 130193326Sed // If we have exactly one array designator, this used the GNU 131193326Sed // 'designation: array-designator' extension, otherwise there should be no 132193326Sed // designators at all! 133198092Srdivacky if (Desig.getNumDesignators() == 1 && 134193326Sed (Desig.getDesignator(0).isArrayDesignator() || 135193326Sed Desig.getDesignator(0).isArrayRangeDesignator())) 136193326Sed Diag(StartLoc, diag::ext_gnu_missing_equal_designator); 137193326Sed else if (Desig.getNumDesignators() > 0) 138193326Sed Diag(Tok, diag::err_expected_equal_designator); 139193326Sed 140193326Sed IdentifierInfo *Name = Tok.getIdentifierInfo(); 141193326Sed SourceLocation NameLoc = ConsumeToken(); 142193326Sed return ParseAssignmentExprWithObjCMessageExprStart( 143193326Sed StartLoc, NameLoc, Name, ExprArg(Actions)); 144193326Sed } 145193326Sed 146193326Sed // Note that we parse this as an assignment expression, not a constant 147193326Sed // expression (allowing *=, =, etc) to handle the objc case. Sema needs 148193326Sed // to validate that the expression is a constant. 149193326Sed OwningExprResult Idx(ParseAssignmentExpression()); 150193326Sed if (Idx.isInvalid()) { 151193326Sed SkipUntil(tok::r_square); 152193326Sed return move(Idx); 153193326Sed } 154198092Srdivacky 155193326Sed // Given an expression, we could either have a designator (if the next 156193326Sed // tokens are '...' or ']' or an objc message send. If this is an objc 157198092Srdivacky // message send, handle it now. An objc-message send is the start of 158193326Sed // an assignment-expression production. 159198092Srdivacky if (getLang().ObjC1 && Tok.isNot(tok::ellipsis) && 160193326Sed Tok.isNot(tok::r_square)) { 161198092Srdivacky 162193326Sed // If we have exactly one array designator, this used the GNU 163193326Sed // 'designation: array-designator' extension, otherwise there should be no 164193326Sed // designators at all! 165198092Srdivacky if (Desig.getNumDesignators() == 1 && 166193326Sed (Desig.getDesignator(0).isArrayDesignator() || 167193326Sed Desig.getDesignator(0).isArrayRangeDesignator())) 168193326Sed Diag(StartLoc, diag::ext_gnu_missing_equal_designator); 169193326Sed else if (Desig.getNumDesignators() > 0) 170193326Sed Diag(Tok, diag::err_expected_equal_designator); 171193326Sed 172193326Sed return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 173193326Sed SourceLocation(), 174193326Sed 0, move(Idx)); 175193326Sed } 176193326Sed 177193326Sed // If this is a normal array designator, remember it. 178193326Sed if (Tok.isNot(tok::ellipsis)) { 179193326Sed Desig.AddDesignator(Designator::getArray(Idx.release(), StartLoc)); 180193326Sed } else { 181193326Sed // Handle the gnu array range extension. 182193326Sed Diag(Tok, diag::ext_gnu_array_range); 183193326Sed SourceLocation EllipsisLoc = ConsumeToken(); 184193326Sed 185193326Sed OwningExprResult RHS(ParseConstantExpression()); 186193326Sed if (RHS.isInvalid()) { 187193326Sed SkipUntil(tok::r_square); 188193326Sed return move(RHS); 189193326Sed } 190193326Sed Desig.AddDesignator(Designator::getArrayRange(Idx.release(), 191193326Sed RHS.release(), 192193326Sed StartLoc, EllipsisLoc)); 193193326Sed } 194193326Sed 195193326Sed SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc); 196193326Sed Desig.getDesignator(Desig.getNumDesignators() - 1).setRBracketLoc(EndLoc); 197193326Sed } 198193326Sed 199193326Sed // Okay, we're done with the designator sequence. We know that there must be 200193326Sed // at least one designator, because the only case we can get into this method 201193326Sed // without a designator is when we have an objc message send. That case is 202193326Sed // handled and returned from above. 203193326Sed assert(!Desig.empty() && "Designator is empty?"); 204193326Sed 205193326Sed // Handle a normal designator sequence end, which is an equal. 206193326Sed if (Tok.is(tok::equal)) { 207193326Sed SourceLocation EqualLoc = ConsumeToken(); 208193326Sed return Actions.ActOnDesignatedInitializer(Desig, EqualLoc, false, 209193326Sed ParseInitializer()); 210193326Sed } 211193326Sed 212193326Sed // We read some number of designators and found something that isn't an = or 213193326Sed // an initializer. If we have exactly one array designator, this 214193326Sed // is the GNU 'designation: array-designator' extension. Otherwise, it is a 215193326Sed // parse error. 216198092Srdivacky if (Desig.getNumDesignators() == 1 && 217193326Sed (Desig.getDesignator(0).isArrayDesignator() || 218193326Sed Desig.getDesignator(0).isArrayRangeDesignator())) { 219193326Sed Diag(Tok, diag::ext_gnu_missing_equal_designator) 220206084Srdivacky << FixItHint::CreateInsertion(Tok.getLocation(), "= "); 221193326Sed return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(), 222193326Sed true, ParseInitializer()); 223193326Sed } 224193326Sed 225193326Sed Diag(Tok, diag::err_expected_equal_designator); 226193326Sed return ExprError(); 227193326Sed} 228193326Sed 229193326Sed 230193326Sed/// ParseBraceInitializer - Called when parsing an initializer that has a 231193326Sed/// leading open brace. 232193326Sed/// 233193326Sed/// initializer: [C99 6.7.8] 234193326Sed/// '{' initializer-list '}' 235193326Sed/// '{' initializer-list ',' '}' 236193326Sed/// [GNU] '{' '}' 237193326Sed/// 238193326Sed/// initializer-list: 239193326Sed/// designation[opt] initializer 240193326Sed/// initializer-list ',' designation[opt] initializer 241193326Sed/// 242193326SedParser::OwningExprResult Parser::ParseBraceInitializer() { 243193326Sed SourceLocation LBraceLoc = ConsumeBrace(); 244193326Sed 245193326Sed /// InitExprs - This is the actual list of expressions contained in the 246193326Sed /// initializer. 247193326Sed ExprVector InitExprs(Actions); 248193326Sed 249193326Sed if (Tok.is(tok::r_brace)) { 250193326Sed // Empty initializers are a C++ feature and a GNU extension to C. 251193326Sed if (!getLang().CPlusPlus) 252193326Sed Diag(LBraceLoc, diag::ext_gnu_empty_initializer); 253193326Sed // Match the '}'. 254193326Sed return Actions.ActOnInitList(LBraceLoc, Action::MultiExprArg(Actions), 255193326Sed ConsumeBrace()); 256193326Sed } 257193326Sed 258193326Sed bool InitExprsOk = true; 259193326Sed 260193326Sed while (1) { 261193326Sed // Parse: designation[opt] initializer 262193326Sed 263193326Sed // If we know that this cannot be a designation, just parse the nested 264193326Sed // initializer directly. 265193326Sed OwningExprResult SubElt(Actions); 266193326Sed if (MayBeDesignationStart(Tok.getKind(), PP)) 267193326Sed SubElt = ParseInitializerWithPotentialDesignator(); 268193326Sed else 269193326Sed SubElt = ParseInitializer(); 270198092Srdivacky 271193326Sed // If we couldn't parse the subelement, bail out. 272193326Sed if (!SubElt.isInvalid()) { 273193326Sed InitExprs.push_back(SubElt.release()); 274193326Sed } else { 275193326Sed InitExprsOk = false; 276198092Srdivacky 277193326Sed // We have two ways to try to recover from this error: if the code looks 278193326Sed // gramatically ok (i.e. we have a comma coming up) try to continue 279193326Sed // parsing the rest of the initializer. This allows us to emit 280193326Sed // diagnostics for later elements that we find. If we don't see a comma, 281193326Sed // assume there is a parse error, and just skip to recover. 282193326Sed // FIXME: This comment doesn't sound right. If there is a r_brace 283193326Sed // immediately, it can't be an error, since there is no other way of 284193326Sed // leaving this loop except through this if. 285193326Sed if (Tok.isNot(tok::comma)) { 286193326Sed SkipUntil(tok::r_brace, false, true); 287193326Sed break; 288193326Sed } 289193326Sed } 290193326Sed 291193326Sed // If we don't have a comma continued list, we're done. 292193326Sed if (Tok.isNot(tok::comma)) break; 293193326Sed 294193326Sed // TODO: save comma locations if some client cares. 295193326Sed ConsumeToken(); 296193326Sed 297193326Sed // Handle trailing comma. 298193326Sed if (Tok.is(tok::r_brace)) break; 299193326Sed } 300193326Sed if (InitExprsOk && Tok.is(tok::r_brace)) 301193326Sed return Actions.ActOnInitList(LBraceLoc, move_arg(InitExprs), 302193326Sed ConsumeBrace()); 303193326Sed 304193326Sed // Match the '}'. 305193326Sed MatchRHSPunctuation(tok::r_brace, LBraceLoc); 306193326Sed return ExprError(); // an error occurred. 307193326Sed} 308193326Sed 309