clang API Documentation
00001 //===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the tentative parsing portions of the Parser 00011 // interfaces, for ambiguity resolution. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/Parse/Parser.h" 00016 #include "clang/Parse/ParseDiagnostic.h" 00017 #include "clang/Sema/ParsedTemplate.h" 00018 using namespace clang; 00019 00020 /// isCXXDeclarationStatement - C++-specialized function that disambiguates 00021 /// between a declaration or an expression statement, when parsing function 00022 /// bodies. Returns true for declaration, false for expression. 00023 /// 00024 /// declaration-statement: 00025 /// block-declaration 00026 /// 00027 /// block-declaration: 00028 /// simple-declaration 00029 /// asm-definition 00030 /// namespace-alias-definition 00031 /// using-declaration 00032 /// using-directive 00033 /// [C++0x] static_assert-declaration 00034 /// 00035 /// asm-definition: 00036 /// 'asm' '(' string-literal ')' ';' 00037 /// 00038 /// namespace-alias-definition: 00039 /// 'namespace' identifier = qualified-namespace-specifier ';' 00040 /// 00041 /// using-declaration: 00042 /// 'using' typename[opt] '::'[opt] nested-name-specifier 00043 /// unqualified-id ';' 00044 /// 'using' '::' unqualified-id ; 00045 /// 00046 /// using-directive: 00047 /// 'using' 'namespace' '::'[opt] nested-name-specifier[opt] 00048 /// namespace-name ';' 00049 /// 00050 bool Parser::isCXXDeclarationStatement() { 00051 switch (Tok.getKind()) { 00052 // asm-definition 00053 case tok::kw_asm: 00054 // namespace-alias-definition 00055 case tok::kw_namespace: 00056 // using-declaration 00057 // using-directive 00058 case tok::kw_using: 00059 // static_assert-declaration 00060 case tok::kw_static_assert: 00061 case tok::kw__Static_assert: 00062 return true; 00063 // simple-declaration 00064 default: 00065 return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false); 00066 } 00067 } 00068 00069 /// isCXXSimpleDeclaration - C++-specialized function that disambiguates 00070 /// between a simple-declaration or an expression-statement. 00071 /// If during the disambiguation process a parsing error is encountered, 00072 /// the function returns true to let the declaration parsing code handle it. 00073 /// Returns false if the statement is disambiguated as expression. 00074 /// 00075 /// simple-declaration: 00076 /// decl-specifier-seq init-declarator-list[opt] ';' 00077 /// 00078 /// (if AllowForRangeDecl specified) 00079 /// for ( for-range-declaration : for-range-initializer ) statement 00080 /// for-range-declaration: 00081 /// attribute-specifier-seqopt type-specifier-seq declarator 00082 bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) { 00083 // C++ 6.8p1: 00084 // There is an ambiguity in the grammar involving expression-statements and 00085 // declarations: An expression-statement with a function-style explicit type 00086 // conversion (5.2.3) as its leftmost subexpression can be indistinguishable 00087 // from a declaration where the first declarator starts with a '('. In those 00088 // cases the statement is a declaration. [Note: To disambiguate, the whole 00089 // statement might have to be examined to determine if it is an 00090 // expression-statement or a declaration]. 00091 00092 // C++ 6.8p3: 00093 // The disambiguation is purely syntactic; that is, the meaning of the names 00094 // occurring in such a statement, beyond whether they are type-names or not, 00095 // is not generally used in or changed by the disambiguation. Class 00096 // templates are instantiated as necessary to determine if a qualified name 00097 // is a type-name. Disambiguation precedes parsing, and a statement 00098 // disambiguated as a declaration may be an ill-formed declaration. 00099 00100 // We don't have to parse all of the decl-specifier-seq part. There's only 00101 // an ambiguity if the first decl-specifier is 00102 // simple-type-specifier/typename-specifier followed by a '(', which may 00103 // indicate a function-style cast expression. 00104 // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such 00105 // a case. 00106 00107 TPResult TPR = isCXXDeclarationSpecifier(); 00108 if (TPR != TPResult::Ambiguous()) 00109 return TPR != TPResult::False(); // Returns true for TPResult::True() or 00110 // TPResult::Error(). 00111 00112 // FIXME: Add statistics about the number of ambiguous statements encountered 00113 // and how they were resolved (number of declarations+number of expressions). 00114 00115 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 00116 // We need tentative parsing... 00117 00118 TentativeParsingAction PA(*this); 00119 TPR = TryParseSimpleDeclaration(AllowForRangeDecl); 00120 PA.Revert(); 00121 00122 // In case of an error, let the declaration parsing code handle it. 00123 if (TPR == TPResult::Error()) 00124 return true; 00125 00126 // Declarations take precedence over expressions. 00127 if (TPR == TPResult::Ambiguous()) 00128 TPR = TPResult::True(); 00129 00130 assert(TPR == TPResult::True() || TPR == TPResult::False()); 00131 return TPR == TPResult::True(); 00132 } 00133 00134 /// simple-declaration: 00135 /// decl-specifier-seq init-declarator-list[opt] ';' 00136 /// 00137 /// (if AllowForRangeDecl specified) 00138 /// for ( for-range-declaration : for-range-initializer ) statement 00139 /// for-range-declaration: 00140 /// attribute-specifier-seqopt type-specifier-seq declarator 00141 /// 00142 Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { 00143 // We know that we have a simple-type-specifier/typename-specifier followed 00144 // by a '('. 00145 assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous()); 00146 00147 if (Tok.is(tok::kw_typeof)) 00148 TryParseTypeofSpecifier(); 00149 else { 00150 ConsumeToken(); 00151 00152 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 00153 TryParseProtocolQualifiers(); 00154 } 00155 00156 assert(Tok.is(tok::l_paren) && "Expected '('"); 00157 00158 TPResult TPR = TryParseInitDeclaratorList(); 00159 if (TPR != TPResult::Ambiguous()) 00160 return TPR; 00161 00162 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon))) 00163 return TPResult::False(); 00164 00165 return TPResult::Ambiguous(); 00166 } 00167 00168 /// init-declarator-list: 00169 /// init-declarator 00170 /// init-declarator-list ',' init-declarator 00171 /// 00172 /// init-declarator: 00173 /// declarator initializer[opt] 00174 /// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] 00175 /// 00176 /// initializer: 00177 /// '=' initializer-clause 00178 /// '(' expression-list ')' 00179 /// 00180 /// initializer-clause: 00181 /// assignment-expression 00182 /// '{' initializer-list ','[opt] '}' 00183 /// '{' '}' 00184 /// 00185 Parser::TPResult Parser::TryParseInitDeclaratorList() { 00186 while (1) { 00187 // declarator 00188 TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); 00189 if (TPR != TPResult::Ambiguous()) 00190 return TPR; 00191 00192 // [GNU] simple-asm-expr[opt] attributes[opt] 00193 if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 00194 return TPResult::True(); 00195 00196 // initializer[opt] 00197 if (Tok.is(tok::l_paren)) { 00198 // Parse through the parens. 00199 ConsumeParen(); 00200 if (!SkipUntil(tok::r_paren)) 00201 return TPResult::Error(); 00202 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { 00203 // MSVC and g++ won't examine the rest of declarators if '=' is 00204 // encountered; they just conclude that we have a declaration. 00205 // EDG parses the initializer completely, which is the proper behavior 00206 // for this case. 00207 // 00208 // At present, Clang follows MSVC and g++, since the parser does not have 00209 // the ability to parse an expression fully without recording the 00210 // results of that parse. 00211 // Also allow 'in' after on objective-c declaration as in: 00212 // for (int (^b)(void) in array). Ideally this should be done in the 00213 // context of parsing for-init-statement of a foreach statement only. But, 00214 // in any other context 'in' is invalid after a declaration and parser 00215 // issues the error regardless of outcome of this decision. 00216 // FIXME. Change if above assumption does not hold. 00217 return TPResult::True(); 00218 } 00219 00220 if (Tok.isNot(tok::comma)) 00221 break; 00222 ConsumeToken(); // the comma. 00223 } 00224 00225 return TPResult::Ambiguous(); 00226 } 00227 00228 /// isCXXConditionDeclaration - Disambiguates between a declaration or an 00229 /// expression for a condition of a if/switch/while/for statement. 00230 /// If during the disambiguation process a parsing error is encountered, 00231 /// the function returns true to let the declaration parsing code handle it. 00232 /// 00233 /// condition: 00234 /// expression 00235 /// type-specifier-seq declarator '=' assignment-expression 00236 /// [C++11] type-specifier-seq declarator '=' initializer-clause 00237 /// [C++11] type-specifier-seq declarator braced-init-list 00238 /// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 00239 /// '=' assignment-expression 00240 /// 00241 bool Parser::isCXXConditionDeclaration() { 00242 TPResult TPR = isCXXDeclarationSpecifier(); 00243 if (TPR != TPResult::Ambiguous()) 00244 return TPR != TPResult::False(); // Returns true for TPResult::True() or 00245 // TPResult::Error(). 00246 00247 // FIXME: Add statistics about the number of ambiguous statements encountered 00248 // and how they were resolved (number of declarations+number of expressions). 00249 00250 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 00251 // We need tentative parsing... 00252 00253 TentativeParsingAction PA(*this); 00254 00255 // type-specifier-seq 00256 if (Tok.is(tok::kw_typeof)) 00257 TryParseTypeofSpecifier(); 00258 else { 00259 ConsumeToken(); 00260 00261 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 00262 TryParseProtocolQualifiers(); 00263 } 00264 assert(Tok.is(tok::l_paren) && "Expected '('"); 00265 00266 // declarator 00267 TPR = TryParseDeclarator(false/*mayBeAbstract*/); 00268 00269 // In case of an error, let the declaration parsing code handle it. 00270 if (TPR == TPResult::Error()) 00271 TPR = TPResult::True(); 00272 00273 if (TPR == TPResult::Ambiguous()) { 00274 // '=' 00275 // [GNU] simple-asm-expr[opt] attributes[opt] 00276 if (Tok.is(tok::equal) || 00277 Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute)) 00278 TPR = TPResult::True(); 00279 else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) 00280 TPR = TPResult::True(); 00281 else 00282 TPR = TPResult::False(); 00283 } 00284 00285 PA.Revert(); 00286 00287 assert(TPR == TPResult::True() || TPR == TPResult::False()); 00288 return TPR == TPResult::True(); 00289 } 00290 00291 /// \brief Determine whether the next set of tokens contains a type-id. 00292 /// 00293 /// The context parameter states what context we're parsing right 00294 /// now, which affects how this routine copes with the token 00295 /// following the type-id. If the context is TypeIdInParens, we have 00296 /// already parsed the '(' and we will cease lookahead when we hit 00297 /// the corresponding ')'. If the context is 00298 /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' 00299 /// before this template argument, and will cease lookahead when we 00300 /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id 00301 /// and false for an expression. If during the disambiguation 00302 /// process a parsing error is encountered, the function returns 00303 /// true to let the declaration parsing code handle it. 00304 /// 00305 /// type-id: 00306 /// type-specifier-seq abstract-declarator[opt] 00307 /// 00308 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { 00309 00310 isAmbiguous = false; 00311 00312 // C++ 8.2p2: 00313 // The ambiguity arising from the similarity between a function-style cast and 00314 // a type-id can occur in different contexts. The ambiguity appears as a 00315 // choice between a function-style cast expression and a declaration of a 00316 // type. The resolution is that any construct that could possibly be a type-id 00317 // in its syntactic context shall be considered a type-id. 00318 00319 TPResult TPR = isCXXDeclarationSpecifier(); 00320 if (TPR != TPResult::Ambiguous()) 00321 return TPR != TPResult::False(); // Returns true for TPResult::True() or 00322 // TPResult::Error(). 00323 00324 // FIXME: Add statistics about the number of ambiguous statements encountered 00325 // and how they were resolved (number of declarations+number of expressions). 00326 00327 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. 00328 // We need tentative parsing... 00329 00330 TentativeParsingAction PA(*this); 00331 00332 // type-specifier-seq 00333 if (Tok.is(tok::kw_typeof)) 00334 TryParseTypeofSpecifier(); 00335 else { 00336 ConsumeToken(); 00337 00338 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 00339 TryParseProtocolQualifiers(); 00340 } 00341 00342 assert(Tok.is(tok::l_paren) && "Expected '('"); 00343 00344 // declarator 00345 TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/); 00346 00347 // In case of an error, let the declaration parsing code handle it. 00348 if (TPR == TPResult::Error()) 00349 TPR = TPResult::True(); 00350 00351 if (TPR == TPResult::Ambiguous()) { 00352 // We are supposed to be inside parens, so if after the abstract declarator 00353 // we encounter a ')' this is a type-id, otherwise it's an expression. 00354 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) { 00355 TPR = TPResult::True(); 00356 isAmbiguous = true; 00357 00358 // We are supposed to be inside a template argument, so if after 00359 // the abstract declarator we encounter a '>', '>>' (in C++0x), or 00360 // ',', this is a type-id. Otherwise, it's an expression. 00361 } else if (Context == TypeIdAsTemplateArgument && 00362 (Tok.is(tok::greater) || Tok.is(tok::comma) || 00363 (getLangOpts().CPlusPlus0x && Tok.is(tok::greatergreater)))) { 00364 TPR = TPResult::True(); 00365 isAmbiguous = true; 00366 00367 } else 00368 TPR = TPResult::False(); 00369 } 00370 00371 PA.Revert(); 00372 00373 assert(TPR == TPResult::True() || TPR == TPResult::False()); 00374 return TPR == TPResult::True(); 00375 } 00376 00377 /// \brief Returns true if this is a C++11 attribute-specifier. Per 00378 /// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens 00379 /// always introduce an attribute. In Objective-C++11, this rule does not 00380 /// apply if either '[' begins a message-send. 00381 /// 00382 /// If Disambiguate is true, we try harder to determine whether a '[[' starts 00383 /// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not. 00384 /// 00385 /// If OuterMightBeMessageSend is true, we assume the outer '[' is either an 00386 /// Obj-C message send or the start of an attribute. Otherwise, we assume it 00387 /// is not an Obj-C message send. 00388 /// 00389 /// C++11 [dcl.attr.grammar]: 00390 /// 00391 /// attribute-specifier: 00392 /// '[' '[' attribute-list ']' ']' 00393 /// alignment-specifier 00394 /// 00395 /// attribute-list: 00396 /// attribute[opt] 00397 /// attribute-list ',' attribute[opt] 00398 /// attribute '...' 00399 /// attribute-list ',' attribute '...' 00400 /// 00401 /// attribute: 00402 /// attribute-token attribute-argument-clause[opt] 00403 /// 00404 /// attribute-token: 00405 /// identifier 00406 /// identifier '::' identifier 00407 /// 00408 /// attribute-argument-clause: 00409 /// '(' balanced-token-seq ')' 00410 Parser::CXX11AttributeKind 00411 Parser::isCXX11AttributeSpecifier(bool Disambiguate, 00412 bool OuterMightBeMessageSend) { 00413 if (Tok.is(tok::kw_alignas)) 00414 return CAK_AttributeSpecifier; 00415 00416 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) 00417 return CAK_NotAttributeSpecifier; 00418 00419 // No tentative parsing if we don't need to look for ']]' or a lambda. 00420 if (!Disambiguate && !getLangOpts().ObjC1) 00421 return CAK_AttributeSpecifier; 00422 00423 TentativeParsingAction PA(*this); 00424 00425 // Opening brackets were checked for above. 00426 ConsumeBracket(); 00427 00428 // Outside Obj-C++11, treat anything with a matching ']]' as an attribute. 00429 if (!getLangOpts().ObjC1) { 00430 ConsumeBracket(); 00431 00432 bool IsAttribute = SkipUntil(tok::r_square, false); 00433 IsAttribute &= Tok.is(tok::r_square); 00434 00435 PA.Revert(); 00436 00437 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier; 00438 } 00439 00440 // In Obj-C++11, we need to distinguish four situations: 00441 // 1a) int x[[attr]]; C++11 attribute. 00442 // 1b) [[attr]]; C++11 statement attribute. 00443 // 2) int x[[obj](){ return 1; }()]; Lambda in array size/index. 00444 // 3a) int x[[obj get]]; Message send in array size/index. 00445 // 3b) [[Class alloc] init]; Message send in message send. 00446 // 4) [[obj]{ return self; }() doStuff]; Lambda in message send. 00447 // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted. 00448 00449 // If we have a lambda-introducer, then this is definitely not a message send. 00450 // FIXME: If this disambiguation is too slow, fold the tentative lambda parse 00451 // into the tentative attribute parse below. 00452 LambdaIntroducer Intro; 00453 if (!TryParseLambdaIntroducer(Intro)) { 00454 // A lambda cannot end with ']]', and an attribute must. 00455 bool IsAttribute = Tok.is(tok::r_square); 00456 00457 PA.Revert(); 00458 00459 if (IsAttribute) 00460 // Case 1: C++11 attribute. 00461 return CAK_AttributeSpecifier; 00462 00463 if (OuterMightBeMessageSend) 00464 // Case 4: Lambda in message send. 00465 return CAK_NotAttributeSpecifier; 00466 00467 // Case 2: Lambda in array size / index. 00468 return CAK_InvalidAttributeSpecifier; 00469 } 00470 00471 ConsumeBracket(); 00472 00473 // If we don't have a lambda-introducer, then we have an attribute or a 00474 // message-send. 00475 bool IsAttribute = true; 00476 while (Tok.isNot(tok::r_square)) { 00477 if (Tok.is(tok::comma)) { 00478 // Case 1: Stray commas can only occur in attributes. 00479 PA.Revert(); 00480 return CAK_AttributeSpecifier; 00481 } 00482 00483 // Parse the attribute-token, if present. 00484 // C++11 [dcl.attr.grammar]: 00485 // If a keyword or an alternative token that satisfies the syntactic 00486 // requirements of an identifier is contained in an attribute-token, 00487 // it is considered an identifier. 00488 SourceLocation Loc; 00489 if (!TryParseCXX11AttributeIdentifier(Loc)) { 00490 IsAttribute = false; 00491 break; 00492 } 00493 if (Tok.is(tok::coloncolon)) { 00494 ConsumeToken(); 00495 if (!TryParseCXX11AttributeIdentifier(Loc)) { 00496 IsAttribute = false; 00497 break; 00498 } 00499 } 00500 00501 // Parse the attribute-argument-clause, if present. 00502 if (Tok.is(tok::l_paren)) { 00503 ConsumeParen(); 00504 if (!SkipUntil(tok::r_paren, false)) { 00505 IsAttribute = false; 00506 break; 00507 } 00508 } 00509 00510 if (Tok.is(tok::ellipsis)) 00511 ConsumeToken(); 00512 00513 if (Tok.isNot(tok::comma)) 00514 break; 00515 00516 ConsumeToken(); 00517 } 00518 00519 // An attribute must end ']]'. 00520 if (IsAttribute) { 00521 if (Tok.is(tok::r_square)) { 00522 ConsumeBracket(); 00523 IsAttribute = Tok.is(tok::r_square); 00524 } else { 00525 IsAttribute = false; 00526 } 00527 } 00528 00529 PA.Revert(); 00530 00531 if (IsAttribute) 00532 // Case 1: C++11 statement attribute. 00533 return CAK_AttributeSpecifier; 00534 00535 // Case 3: Message send. 00536 return CAK_NotAttributeSpecifier; 00537 } 00538 00539 /// declarator: 00540 /// direct-declarator 00541 /// ptr-operator declarator 00542 /// 00543 /// direct-declarator: 00544 /// declarator-id 00545 /// direct-declarator '(' parameter-declaration-clause ')' 00546 /// cv-qualifier-seq[opt] exception-specification[opt] 00547 /// direct-declarator '[' constant-expression[opt] ']' 00548 /// '(' declarator ')' 00549 /// [GNU] '(' attributes declarator ')' 00550 /// 00551 /// abstract-declarator: 00552 /// ptr-operator abstract-declarator[opt] 00553 /// direct-abstract-declarator 00554 /// ... 00555 /// 00556 /// direct-abstract-declarator: 00557 /// direct-abstract-declarator[opt] 00558 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 00559 /// exception-specification[opt] 00560 /// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 00561 /// '(' abstract-declarator ')' 00562 /// 00563 /// ptr-operator: 00564 /// '*' cv-qualifier-seq[opt] 00565 /// '&' 00566 /// [C++0x] '&&' [TODO] 00567 /// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] 00568 /// 00569 /// cv-qualifier-seq: 00570 /// cv-qualifier cv-qualifier-seq[opt] 00571 /// 00572 /// cv-qualifier: 00573 /// 'const' 00574 /// 'volatile' 00575 /// 00576 /// declarator-id: 00577 /// '...'[opt] id-expression 00578 /// 00579 /// id-expression: 00580 /// unqualified-id 00581 /// qualified-id [TODO] 00582 /// 00583 /// unqualified-id: 00584 /// identifier 00585 /// operator-function-id [TODO] 00586 /// conversion-function-id [TODO] 00587 /// '~' class-name [TODO] 00588 /// template-id [TODO] 00589 /// 00590 Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, 00591 bool mayHaveIdentifier) { 00592 // declarator: 00593 // direct-declarator 00594 // ptr-operator declarator 00595 00596 while (1) { 00597 if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) 00598 if (TryAnnotateCXXScopeToken(true)) 00599 return TPResult::Error(); 00600 00601 if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || 00602 Tok.is(tok::ampamp) || 00603 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { 00604 // ptr-operator 00605 ConsumeToken(); 00606 while (Tok.is(tok::kw_const) || 00607 Tok.is(tok::kw_volatile) || 00608 Tok.is(tok::kw_restrict)) 00609 ConsumeToken(); 00610 } else { 00611 break; 00612 } 00613 } 00614 00615 // direct-declarator: 00616 // direct-abstract-declarator: 00617 if (Tok.is(tok::ellipsis)) 00618 ConsumeToken(); 00619 00620 if ((Tok.is(tok::identifier) || 00621 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) && 00622 mayHaveIdentifier) { 00623 // declarator-id 00624 if (Tok.is(tok::annot_cxxscope)) 00625 ConsumeToken(); 00626 ConsumeToken(); 00627 } else if (Tok.is(tok::l_paren)) { 00628 ConsumeParen(); 00629 if (mayBeAbstract && 00630 (Tok.is(tok::r_paren) || // 'int()' is a function. 00631 // 'int(...)' is a function. 00632 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) || 00633 isDeclarationSpecifier())) { // 'int(int)' is a function. 00634 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 00635 // exception-specification[opt] 00636 TPResult TPR = TryParseFunctionDeclarator(); 00637 if (TPR != TPResult::Ambiguous()) 00638 return TPR; 00639 } else { 00640 // '(' declarator ')' 00641 // '(' attributes declarator ')' 00642 // '(' abstract-declarator ')' 00643 if (Tok.is(tok::kw___attribute) || 00644 Tok.is(tok::kw___declspec) || 00645 Tok.is(tok::kw___cdecl) || 00646 Tok.is(tok::kw___stdcall) || 00647 Tok.is(tok::kw___fastcall) || 00648 Tok.is(tok::kw___thiscall) || 00649 Tok.is(tok::kw___unaligned)) 00650 return TPResult::True(); // attributes indicate declaration 00651 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); 00652 if (TPR != TPResult::Ambiguous()) 00653 return TPR; 00654 if (Tok.isNot(tok::r_paren)) 00655 return TPResult::False(); 00656 ConsumeParen(); 00657 } 00658 } else if (!mayBeAbstract) { 00659 return TPResult::False(); 00660 } 00661 00662 while (1) { 00663 TPResult TPR(TPResult::Ambiguous()); 00664 00665 // abstract-declarator: ... 00666 if (Tok.is(tok::ellipsis)) 00667 ConsumeToken(); 00668 00669 if (Tok.is(tok::l_paren)) { 00670 // Check whether we have a function declarator or a possible ctor-style 00671 // initializer that follows the declarator. Note that ctor-style 00672 // initializers are not possible in contexts where abstract declarators 00673 // are allowed. 00674 if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/)) 00675 break; 00676 00677 // direct-declarator '(' parameter-declaration-clause ')' 00678 // cv-qualifier-seq[opt] exception-specification[opt] 00679 ConsumeParen(); 00680 TPR = TryParseFunctionDeclarator(); 00681 } else if (Tok.is(tok::l_square)) { 00682 // direct-declarator '[' constant-expression[opt] ']' 00683 // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' 00684 TPR = TryParseBracketDeclarator(); 00685 } else { 00686 break; 00687 } 00688 00689 if (TPR != TPResult::Ambiguous()) 00690 return TPR; 00691 } 00692 00693 return TPResult::Ambiguous(); 00694 } 00695 00696 Parser::TPResult 00697 Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { 00698 switch (Kind) { 00699 // Obviously starts an expression. 00700 case tok::numeric_constant: 00701 case tok::char_constant: 00702 case tok::wide_char_constant: 00703 case tok::utf16_char_constant: 00704 case tok::utf32_char_constant: 00705 case tok::string_literal: 00706 case tok::wide_string_literal: 00707 case tok::utf8_string_literal: 00708 case tok::utf16_string_literal: 00709 case tok::utf32_string_literal: 00710 case tok::l_square: 00711 case tok::l_paren: 00712 case tok::amp: 00713 case tok::ampamp: 00714 case tok::star: 00715 case tok::plus: 00716 case tok::plusplus: 00717 case tok::minus: 00718 case tok::minusminus: 00719 case tok::tilde: 00720 case tok::exclaim: 00721 case tok::kw_sizeof: 00722 case tok::kw___func__: 00723 case tok::kw_const_cast: 00724 case tok::kw_delete: 00725 case tok::kw_dynamic_cast: 00726 case tok::kw_false: 00727 case tok::kw_new: 00728 case tok::kw_operator: 00729 case tok::kw_reinterpret_cast: 00730 case tok::kw_static_cast: 00731 case tok::kw_this: 00732 case tok::kw_throw: 00733 case tok::kw_true: 00734 case tok::kw_typeid: 00735 case tok::kw_alignof: 00736 case tok::kw_noexcept: 00737 case tok::kw_nullptr: 00738 case tok::kw___null: 00739 case tok::kw___alignof: 00740 case tok::kw___builtin_choose_expr: 00741 case tok::kw___builtin_offsetof: 00742 case tok::kw___builtin_types_compatible_p: 00743 case tok::kw___builtin_va_arg: 00744 case tok::kw___imag: 00745 case tok::kw___real: 00746 case tok::kw___FUNCTION__: 00747 case tok::kw___PRETTY_FUNCTION__: 00748 case tok::kw___has_nothrow_assign: 00749 case tok::kw___has_nothrow_copy: 00750 case tok::kw___has_nothrow_constructor: 00751 case tok::kw___has_trivial_assign: 00752 case tok::kw___has_trivial_copy: 00753 case tok::kw___has_trivial_constructor: 00754 case tok::kw___has_trivial_destructor: 00755 case tok::kw___has_virtual_destructor: 00756 case tok::kw___is_abstract: 00757 case tok::kw___is_base_of: 00758 case tok::kw___is_class: 00759 case tok::kw___is_convertible_to: 00760 case tok::kw___is_empty: 00761 case tok::kw___is_enum: 00762 case tok::kw___is_final: 00763 case tok::kw___is_literal: 00764 case tok::kw___is_literal_type: 00765 case tok::kw___is_pod: 00766 case tok::kw___is_polymorphic: 00767 case tok::kw___is_trivial: 00768 case tok::kw___is_trivially_assignable: 00769 case tok::kw___is_trivially_constructible: 00770 case tok::kw___is_trivially_copyable: 00771 case tok::kw___is_union: 00772 case tok::kw___uuidof: 00773 return TPResult::True(); 00774 00775 // Obviously starts a type-specifier-seq: 00776 case tok::kw_char: 00777 case tok::kw_const: 00778 case tok::kw_double: 00779 case tok::kw_enum: 00780 case tok::kw_half: 00781 case tok::kw_float: 00782 case tok::kw_int: 00783 case tok::kw_long: 00784 case tok::kw___int64: 00785 case tok::kw___int128: 00786 case tok::kw_restrict: 00787 case tok::kw_short: 00788 case tok::kw_signed: 00789 case tok::kw_struct: 00790 case tok::kw_union: 00791 case tok::kw_unsigned: 00792 case tok::kw_void: 00793 case tok::kw_volatile: 00794 case tok::kw__Bool: 00795 case tok::kw__Complex: 00796 case tok::kw_class: 00797 case tok::kw_typename: 00798 case tok::kw_wchar_t: 00799 case tok::kw_char16_t: 00800 case tok::kw_char32_t: 00801 case tok::kw___underlying_type: 00802 case tok::kw_thread_local: 00803 case tok::kw__Decimal32: 00804 case tok::kw__Decimal64: 00805 case tok::kw__Decimal128: 00806 case tok::kw___thread: 00807 case tok::kw_typeof: 00808 case tok::kw___cdecl: 00809 case tok::kw___stdcall: 00810 case tok::kw___fastcall: 00811 case tok::kw___thiscall: 00812 case tok::kw___unaligned: 00813 case tok::kw___vector: 00814 case tok::kw___pixel: 00815 case tok::kw__Atomic: 00816 return TPResult::False(); 00817 00818 default: 00819 break; 00820 } 00821 00822 return TPResult::Ambiguous(); 00823 } 00824 00825 /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration 00826 /// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could 00827 /// be either a decl-specifier or a function-style cast, and TPResult::Error() 00828 /// if a parsing error was found and reported. 00829 /// 00830 /// If HasMissingTypename is provided, a name with a dependent scope specifier 00831 /// will be treated as ambiguous if the 'typename' keyword is missing. If this 00832 /// happens, *HasMissingTypename will be set to 'true'. 00833 /// 00834 /// decl-specifier: 00835 /// storage-class-specifier 00836 /// type-specifier 00837 /// function-specifier 00838 /// 'friend' 00839 /// 'typedef' 00840 /// [C++0x] 'constexpr' 00841 /// [GNU] attributes declaration-specifiers[opt] 00842 /// 00843 /// storage-class-specifier: 00844 /// 'register' 00845 /// 'static' 00846 /// 'extern' 00847 /// 'mutable' 00848 /// 'auto' 00849 /// [GNU] '__thread' 00850 /// 00851 /// function-specifier: 00852 /// 'inline' 00853 /// 'virtual' 00854 /// 'explicit' 00855 /// 00856 /// typedef-name: 00857 /// identifier 00858 /// 00859 /// type-specifier: 00860 /// simple-type-specifier 00861 /// class-specifier 00862 /// enum-specifier 00863 /// elaborated-type-specifier 00864 /// typename-specifier 00865 /// cv-qualifier 00866 /// 00867 /// simple-type-specifier: 00868 /// '::'[opt] nested-name-specifier[opt] type-name 00869 /// '::'[opt] nested-name-specifier 'template' 00870 /// simple-template-id [TODO] 00871 /// 'char' 00872 /// 'wchar_t' 00873 /// 'bool' 00874 /// 'short' 00875 /// 'int' 00876 /// 'long' 00877 /// 'signed' 00878 /// 'unsigned' 00879 /// 'float' 00880 /// 'double' 00881 /// 'void' 00882 /// [GNU] typeof-specifier 00883 /// [GNU] '_Complex' 00884 /// [C++0x] 'auto' [TODO] 00885 /// [C++0x] 'decltype' ( expression ) 00886 /// 00887 /// type-name: 00888 /// class-name 00889 /// enum-name 00890 /// typedef-name 00891 /// 00892 /// elaborated-type-specifier: 00893 /// class-key '::'[opt] nested-name-specifier[opt] identifier 00894 /// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] 00895 /// simple-template-id 00896 /// 'enum' '::'[opt] nested-name-specifier[opt] identifier 00897 /// 00898 /// enum-name: 00899 /// identifier 00900 /// 00901 /// enum-specifier: 00902 /// 'enum' identifier[opt] '{' enumerator-list[opt] '}' 00903 /// 'enum' identifier[opt] '{' enumerator-list ',' '}' 00904 /// 00905 /// class-specifier: 00906 /// class-head '{' member-specification[opt] '}' 00907 /// 00908 /// class-head: 00909 /// class-key identifier[opt] base-clause[opt] 00910 /// class-key nested-name-specifier identifier base-clause[opt] 00911 /// class-key nested-name-specifier[opt] simple-template-id 00912 /// base-clause[opt] 00913 /// 00914 /// class-key: 00915 /// 'class' 00916 /// 'struct' 00917 /// 'union' 00918 /// 00919 /// cv-qualifier: 00920 /// 'const' 00921 /// 'volatile' 00922 /// [GNU] restrict 00923 /// 00924 Parser::TPResult 00925 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, 00926 bool *HasMissingTypename) { 00927 switch (Tok.getKind()) { 00928 case tok::identifier: // foo::bar 00929 // Check for need to substitute AltiVec __vector keyword 00930 // for "vector" identifier. 00931 if (TryAltiVecVectorToken()) 00932 return TPResult::True(); 00933 // Fall through. 00934 case tok::kw_typename: // typename T::type 00935 // Annotate typenames and C++ scope specifiers. If we get one, just 00936 // recurse to handle whatever we get. 00937 if (TryAnnotateTypeOrScopeToken()) 00938 return TPResult::Error(); 00939 if (Tok.is(tok::identifier)) { 00940 const Token &Next = NextToken(); 00941 return (!getLangOpts().ObjC1 && Next.is(tok::identifier)) ? 00942 TPResult::True() : TPResult::False(); 00943 } 00944 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 00945 00946 case tok::coloncolon: { // ::foo::bar 00947 const Token &Next = NextToken(); 00948 if (Next.is(tok::kw_new) || // ::new 00949 Next.is(tok::kw_delete)) // ::delete 00950 return TPResult::False(); 00951 } 00952 // Fall through. 00953 case tok::kw_decltype: 00954 // Annotate typenames and C++ scope specifiers. If we get one, just 00955 // recurse to handle whatever we get. 00956 if (TryAnnotateTypeOrScopeToken()) 00957 return TPResult::Error(); 00958 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename); 00959 00960 // decl-specifier: 00961 // storage-class-specifier 00962 // type-specifier 00963 // function-specifier 00964 // 'friend' 00965 // 'typedef' 00966 // 'constexpr' 00967 case tok::kw_friend: 00968 case tok::kw_typedef: 00969 case tok::kw_constexpr: 00970 // storage-class-specifier 00971 case tok::kw_register: 00972 case tok::kw_static: 00973 case tok::kw_extern: 00974 case tok::kw_mutable: 00975 case tok::kw_auto: 00976 case tok::kw___thread: 00977 // function-specifier 00978 case tok::kw_inline: 00979 case tok::kw_virtual: 00980 case tok::kw_explicit: 00981 00982 // Modules 00983 case tok::kw___module_private__: 00984 00985 // type-specifier: 00986 // simple-type-specifier 00987 // class-specifier 00988 // enum-specifier 00989 // elaborated-type-specifier 00990 // typename-specifier 00991 // cv-qualifier 00992 00993 // class-specifier 00994 // elaborated-type-specifier 00995 case tok::kw_class: 00996 case tok::kw_struct: 00997 case tok::kw_union: 00998 // enum-specifier 00999 case tok::kw_enum: 01000 // cv-qualifier 01001 case tok::kw_const: 01002 case tok::kw_volatile: 01003 01004 // GNU 01005 case tok::kw_restrict: 01006 case tok::kw__Complex: 01007 case tok::kw___attribute: 01008 return TPResult::True(); 01009 01010 // Microsoft 01011 case tok::kw___declspec: 01012 case tok::kw___cdecl: 01013 case tok::kw___stdcall: 01014 case tok::kw___fastcall: 01015 case tok::kw___thiscall: 01016 case tok::kw___w64: 01017 case tok::kw___ptr64: 01018 case tok::kw___ptr32: 01019 case tok::kw___forceinline: 01020 case tok::kw___unaligned: 01021 return TPResult::True(); 01022 01023 // Borland 01024 case tok::kw___pascal: 01025 return TPResult::True(); 01026 01027 // AltiVec 01028 case tok::kw___vector: 01029 return TPResult::True(); 01030 01031 case tok::annot_template_id: { 01032 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 01033 if (TemplateId->Kind != TNK_Type_template) 01034 return TPResult::False(); 01035 CXXScopeSpec SS; 01036 AnnotateTemplateIdTokenAsType(); 01037 assert(Tok.is(tok::annot_typename)); 01038 goto case_typename; 01039 } 01040 01041 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed 01042 // We've already annotated a scope; try to annotate a type. 01043 if (TryAnnotateTypeOrScopeToken()) 01044 return TPResult::Error(); 01045 if (!Tok.is(tok::annot_typename)) { 01046 // If the next token is an identifier or a type qualifier, then this 01047 // can't possibly be a valid expression either. 01048 if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) { 01049 CXXScopeSpec SS; 01050 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 01051 Tok.getAnnotationRange(), 01052 SS); 01053 if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) { 01054 TentativeParsingAction PA(*this); 01055 ConsumeToken(); 01056 ConsumeToken(); 01057 bool isIdentifier = Tok.is(tok::identifier); 01058 TPResult TPR = TPResult::False(); 01059 if (!isIdentifier) 01060 TPR = isCXXDeclarationSpecifier(BracedCastResult, 01061 HasMissingTypename); 01062 PA.Revert(); 01063 01064 if (isIdentifier || 01065 TPR == TPResult::True() || TPR == TPResult::Error()) 01066 return TPResult::Error(); 01067 01068 if (HasMissingTypename) { 01069 // We can't tell whether this is a missing 'typename' or a valid 01070 // expression. 01071 *HasMissingTypename = true; 01072 return TPResult::Ambiguous(); 01073 } 01074 } 01075 } 01076 return TPResult::False(); 01077 } 01078 // If that succeeded, fallthrough into the generic simple-type-id case. 01079 01080 // The ambiguity resides in a simple-type-specifier/typename-specifier 01081 // followed by a '('. The '(' could either be the start of: 01082 // 01083 // direct-declarator: 01084 // '(' declarator ')' 01085 // 01086 // direct-abstract-declarator: 01087 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 01088 // exception-specification[opt] 01089 // '(' abstract-declarator ')' 01090 // 01091 // or part of a function-style cast expression: 01092 // 01093 // simple-type-specifier '(' expression-list[opt] ')' 01094 // 01095 01096 // simple-type-specifier: 01097 01098 case tok::annot_typename: 01099 case_typename: 01100 // In Objective-C, we might have a protocol-qualified type. 01101 if (getLangOpts().ObjC1 && NextToken().is(tok::less)) { 01102 // Tentatively parse the 01103 TentativeParsingAction PA(*this); 01104 ConsumeToken(); // The type token 01105 01106 TPResult TPR = TryParseProtocolQualifiers(); 01107 bool isFollowedByParen = Tok.is(tok::l_paren); 01108 bool isFollowedByBrace = Tok.is(tok::l_brace); 01109 01110 PA.Revert(); 01111 01112 if (TPR == TPResult::Error()) 01113 return TPResult::Error(); 01114 01115 if (isFollowedByParen) 01116 return TPResult::Ambiguous(); 01117 01118 if (getLangOpts().CPlusPlus0x && isFollowedByBrace) 01119 return BracedCastResult; 01120 01121 return TPResult::True(); 01122 } 01123 01124 case tok::kw_char: 01125 case tok::kw_wchar_t: 01126 case tok::kw_char16_t: 01127 case tok::kw_char32_t: 01128 case tok::kw_bool: 01129 case tok::kw_short: 01130 case tok::kw_int: 01131 case tok::kw_long: 01132 case tok::kw___int64: 01133 case tok::kw___int128: 01134 case tok::kw_signed: 01135 case tok::kw_unsigned: 01136 case tok::kw_half: 01137 case tok::kw_float: 01138 case tok::kw_double: 01139 case tok::kw_void: 01140 case tok::annot_decltype: 01141 if (NextToken().is(tok::l_paren)) 01142 return TPResult::Ambiguous(); 01143 01144 // This is a function-style cast in all cases we disambiguate other than 01145 // one: 01146 // struct S { 01147 // enum E : int { a = 4 }; // enum 01148 // enum E : int { 4 }; // bit-field 01149 // }; 01150 if (getLangOpts().CPlusPlus0x && NextToken().is(tok::l_brace)) 01151 return BracedCastResult; 01152 01153 if (isStartOfObjCClassMessageMissingOpenBracket()) 01154 return TPResult::False(); 01155 01156 return TPResult::True(); 01157 01158 // GNU typeof support. 01159 case tok::kw_typeof: { 01160 if (NextToken().isNot(tok::l_paren)) 01161 return TPResult::True(); 01162 01163 TentativeParsingAction PA(*this); 01164 01165 TPResult TPR = TryParseTypeofSpecifier(); 01166 bool isFollowedByParen = Tok.is(tok::l_paren); 01167 bool isFollowedByBrace = Tok.is(tok::l_brace); 01168 01169 PA.Revert(); 01170 01171 if (TPR == TPResult::Error()) 01172 return TPResult::Error(); 01173 01174 if (isFollowedByParen) 01175 return TPResult::Ambiguous(); 01176 01177 if (getLangOpts().CPlusPlus0x && isFollowedByBrace) 01178 return BracedCastResult; 01179 01180 return TPResult::True(); 01181 } 01182 01183 // C++0x type traits support 01184 case tok::kw___underlying_type: 01185 return TPResult::True(); 01186 01187 // C11 _Atomic 01188 case tok::kw__Atomic: 01189 return TPResult::True(); 01190 01191 default: 01192 return TPResult::False(); 01193 } 01194 } 01195 01196 /// [GNU] typeof-specifier: 01197 /// 'typeof' '(' expressions ')' 01198 /// 'typeof' '(' type-name ')' 01199 /// 01200 Parser::TPResult Parser::TryParseTypeofSpecifier() { 01201 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!"); 01202 ConsumeToken(); 01203 01204 assert(Tok.is(tok::l_paren) && "Expected '('"); 01205 // Parse through the parens after 'typeof'. 01206 ConsumeParen(); 01207 if (!SkipUntil(tok::r_paren)) 01208 return TPResult::Error(); 01209 01210 return TPResult::Ambiguous(); 01211 } 01212 01213 /// [ObjC] protocol-qualifiers: 01214 //// '<' identifier-list '>' 01215 Parser::TPResult Parser::TryParseProtocolQualifiers() { 01216 assert(Tok.is(tok::less) && "Expected '<' for qualifier list"); 01217 ConsumeToken(); 01218 do { 01219 if (Tok.isNot(tok::identifier)) 01220 return TPResult::Error(); 01221 ConsumeToken(); 01222 01223 if (Tok.is(tok::comma)) { 01224 ConsumeToken(); 01225 continue; 01226 } 01227 01228 if (Tok.is(tok::greater)) { 01229 ConsumeToken(); 01230 return TPResult::Ambiguous(); 01231 } 01232 } while (false); 01233 01234 return TPResult::Error(); 01235 } 01236 01237 Parser::TPResult 01238 Parser::TryParseDeclarationSpecifier(bool *HasMissingTypename) { 01239 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(), 01240 HasMissingTypename); 01241 if (TPR != TPResult::Ambiguous()) 01242 return TPR; 01243 01244 if (Tok.is(tok::kw_typeof)) 01245 TryParseTypeofSpecifier(); 01246 else { 01247 if (Tok.is(tok::annot_cxxscope)) 01248 ConsumeToken(); 01249 ConsumeToken(); 01250 01251 if (getLangOpts().ObjC1 && Tok.is(tok::less)) 01252 TryParseProtocolQualifiers(); 01253 } 01254 01255 return TPResult::Ambiguous(); 01256 } 01257 01258 /// isCXXFunctionDeclarator - Disambiguates between a function declarator or 01259 /// a constructor-style initializer, when parsing declaration statements. 01260 /// Returns true for function declarator and false for constructor-style 01261 /// initializer. 01262 /// If during the disambiguation process a parsing error is encountered, 01263 /// the function returns true to let the declaration parsing code handle it. 01264 /// 01265 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 01266 /// exception-specification[opt] 01267 /// 01268 bool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) { 01269 01270 // C++ 8.2p1: 01271 // The ambiguity arising from the similarity between a function-style cast and 01272 // a declaration mentioned in 6.8 can also occur in the context of a 01273 // declaration. In that context, the choice is between a function declaration 01274 // with a redundant set of parentheses around a parameter name and an object 01275 // declaration with a function-style cast as the initializer. Just as for the 01276 // ambiguities mentioned in 6.8, the resolution is to consider any construct 01277 // that could possibly be a declaration a declaration. 01278 01279 TentativeParsingAction PA(*this); 01280 01281 ConsumeParen(); 01282 bool InvalidAsDeclaration = false; 01283 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration); 01284 if (TPR == TPResult::Ambiguous()) { 01285 if (Tok.isNot(tok::r_paren)) 01286 TPR = TPResult::False(); 01287 else { 01288 const Token &Next = NextToken(); 01289 if (Next.is(tok::amp) || Next.is(tok::ampamp) || 01290 Next.is(tok::kw_const) || Next.is(tok::kw_volatile) || 01291 Next.is(tok::kw_throw) || Next.is(tok::kw_noexcept) || 01292 Next.is(tok::l_square) || isCXX0XVirtSpecifier(Next) || 01293 Next.is(tok::l_brace) || Next.is(tok::kw_try) || 01294 Next.is(tok::equal)) 01295 // The next token cannot appear after a constructor-style initializer, 01296 // and can appear next in a function definition. This must be a function 01297 // declarator. 01298 TPR = TPResult::True(); 01299 else if (InvalidAsDeclaration) 01300 // Use the absence of 'typename' as a tie-breaker. 01301 TPR = TPResult::False(); 01302 } 01303 } 01304 01305 SourceLocation TPLoc = Tok.getLocation(); 01306 PA.Revert(); 01307 01308 // In case of an error, let the declaration parsing code handle it. 01309 if (TPR == TPResult::Error()) 01310 return true; 01311 01312 if (TPR == TPResult::Ambiguous()) { 01313 // Function declarator has precedence over constructor-style initializer. 01314 // Emit a warning just in case the author intended a variable definition. 01315 if (warnIfAmbiguous) 01316 Diag(Tok, diag::warn_parens_disambiguated_as_function_decl) 01317 << SourceRange(Tok.getLocation(), TPLoc); 01318 return true; 01319 } 01320 01321 return TPR == TPResult::True(); 01322 } 01323 01324 /// parameter-declaration-clause: 01325 /// parameter-declaration-list[opt] '...'[opt] 01326 /// parameter-declaration-list ',' '...' 01327 /// 01328 /// parameter-declaration-list: 01329 /// parameter-declaration 01330 /// parameter-declaration-list ',' parameter-declaration 01331 /// 01332 /// parameter-declaration: 01333 /// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 01334 /// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] 01335 /// '=' assignment-expression 01336 /// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 01337 /// attributes[opt] 01338 /// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] 01339 /// attributes[opt] '=' assignment-expression 01340 /// 01341 Parser::TPResult 01342 Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration) { 01343 01344 if (Tok.is(tok::r_paren)) 01345 return TPResult::True(); 01346 01347 // parameter-declaration-list[opt] '...'[opt] 01348 // parameter-declaration-list ',' '...' 01349 // 01350 // parameter-declaration-list: 01351 // parameter-declaration 01352 // parameter-declaration-list ',' parameter-declaration 01353 // 01354 while (1) { 01355 // '...'[opt] 01356 if (Tok.is(tok::ellipsis)) { 01357 ConsumeToken(); 01358 if (Tok.is(tok::r_paren)) 01359 return TPResult::True(); // '...)' is a sign of a function declarator. 01360 else 01361 return TPResult::False(); 01362 } 01363 01364 // An attribute-specifier-seq here is a sign of a function declarator. 01365 if (isCXX11AttributeSpecifier(/*Disambiguate*/false, 01366 /*OuterMightBeMessageSend*/true)) 01367 return TPResult::True(); 01368 01369 ParsedAttributes attrs(AttrFactory); 01370 MaybeParseMicrosoftAttributes(attrs); 01371 01372 // decl-specifier-seq 01373 // A parameter-declaration's initializer must be preceded by an '=', so 01374 // decl-specifier-seq '{' is not a parameter in C++11. 01375 TPResult TPR = TryParseDeclarationSpecifier(InvalidAsDeclaration); 01376 if (TPR != TPResult::Ambiguous()) 01377 return TPR; 01378 01379 // declarator 01380 // abstract-declarator[opt] 01381 TPR = TryParseDeclarator(true/*mayBeAbstract*/); 01382 if (TPR != TPResult::Ambiguous()) 01383 return TPR; 01384 01385 // [GNU] attributes[opt] 01386 if (Tok.is(tok::kw___attribute)) 01387 return TPResult::True(); 01388 01389 if (Tok.is(tok::equal)) { 01390 // '=' assignment-expression 01391 // Parse through assignment-expression. 01392 if (!SkipUntil(tok::comma, tok::r_paren, true/*StopAtSemi*/, 01393 true/*DontConsume*/)) 01394 return TPResult::Error(); 01395 } 01396 01397 if (Tok.is(tok::ellipsis)) { 01398 ConsumeToken(); 01399 if (Tok.is(tok::r_paren)) 01400 return TPResult::True(); // '...)' is a sign of a function declarator. 01401 else 01402 return TPResult::False(); 01403 } 01404 01405 if (Tok.isNot(tok::comma)) 01406 break; 01407 ConsumeToken(); // the comma. 01408 } 01409 01410 return TPResult::Ambiguous(); 01411 } 01412 01413 /// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue 01414 /// parsing as a function declarator. 01415 /// If TryParseFunctionDeclarator fully parsed the function declarator, it will 01416 /// return TPResult::Ambiguous(), otherwise it will return either False() or 01417 /// Error(). 01418 /// 01419 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] 01420 /// exception-specification[opt] 01421 /// 01422 /// exception-specification: 01423 /// 'throw' '(' type-id-list[opt] ')' 01424 /// 01425 Parser::TPResult Parser::TryParseFunctionDeclarator() { 01426 01427 // The '(' is already parsed. 01428 01429 TPResult TPR = TryParseParameterDeclarationClause(); 01430 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren)) 01431 TPR = TPResult::False(); 01432 01433 if (TPR == TPResult::False() || TPR == TPResult::Error()) 01434 return TPR; 01435 01436 // Parse through the parens. 01437 if (!SkipUntil(tok::r_paren)) 01438 return TPResult::Error(); 01439 01440 // cv-qualifier-seq 01441 while (Tok.is(tok::kw_const) || 01442 Tok.is(tok::kw_volatile) || 01443 Tok.is(tok::kw_restrict) ) 01444 ConsumeToken(); 01445 01446 // ref-qualifier[opt] 01447 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) 01448 ConsumeToken(); 01449 01450 // exception-specification 01451 if (Tok.is(tok::kw_throw)) { 01452 ConsumeToken(); 01453 if (Tok.isNot(tok::l_paren)) 01454 return TPResult::Error(); 01455 01456 // Parse through the parens after 'throw'. 01457 ConsumeParen(); 01458 if (!SkipUntil(tok::r_paren)) 01459 return TPResult::Error(); 01460 } 01461 if (Tok.is(tok::kw_noexcept)) { 01462 ConsumeToken(); 01463 // Possibly an expression as well. 01464 if (Tok.is(tok::l_paren)) { 01465 // Find the matching rparen. 01466 ConsumeParen(); 01467 if (!SkipUntil(tok::r_paren)) 01468 return TPResult::Error(); 01469 } 01470 } 01471 01472 return TPResult::Ambiguous(); 01473 } 01474 01475 /// '[' constant-expression[opt] ']' 01476 /// 01477 Parser::TPResult Parser::TryParseBracketDeclarator() { 01478 ConsumeBracket(); 01479 if (!SkipUntil(tok::r_square)) 01480 return TPResult::Error(); 01481 01482 return TPResult::Ambiguous(); 01483 }