From: Richard Smith Date: Wed, 20 Mar 2013 03:35:02 +0000 (+0000) Subject: Teach statement / declaration disambiguation about C++11-style generalized initializers. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=22c7c4131a6b032351e3f3bb02d8ab7a9dd758fd;p=platform%2Fupstream%2Fllvm.git Teach statement / declaration disambiguation about C++11-style generalized initializers. llvm-svn: 177480 --- diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index b3cf983..fe602f6 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -184,6 +184,9 @@ Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { return TPResult::Ambiguous(); } +/// Tentatively parse an init-declarator-list in order to disambiguate it from +/// an expression. +/// /// init-declarator-list: /// init-declarator /// init-declarator-list ',' init-declarator @@ -192,14 +195,21 @@ Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { /// declarator initializer[opt] /// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] /// -/// initializer: -/// '=' initializer-clause -/// '(' expression-list ')' +/// initializer: +/// brace-or-equal-initializer +/// '(' expression-list ')' +/// +/// brace-or-equal-initializer: +/// '=' initializer-clause +/// [C++11] braced-init-list /// -/// initializer-clause: -/// assignment-expression -/// '{' initializer-list ','[opt] '}' -/// '{' '}' +/// initializer-clause: +/// assignment-expression +/// braced-init-list +/// +/// braced-init-list: +/// '{' initializer-list ','[opt] '}' +/// '{' '}' /// Parser::TPResult Parser::TryParseInitDeclaratorList() { while (1) { @@ -218,6 +228,10 @@ Parser::TPResult Parser::TryParseInitDeclaratorList() { ConsumeParen(); if (!SkipUntil(tok::r_paren)) return TPResult::Error(); + } else if (Tok.is(tok::l_brace)) { + // A left-brace here is sufficient to disambiguate the parse; an + // expression can never be followed directly by a braced-init-list. + return TPResult::True(); } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { // MSVC and g++ won't examine the rest of declarators if '=' is // encountered; they just conclude that we have a declaration. diff --git a/clang/test/Parser/cxx0x-ambig.cpp b/clang/test/Parser/cxx0x-ambig.cpp index dac3c09..3b864f9 100644 --- a/clang/test/Parser/cxx0x-ambig.cpp +++ b/clang/test/Parser/cxx0x-ambig.cpp @@ -133,3 +133,19 @@ namespace ellipsis { void l(int(S::*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} }; } + +namespace braced_init_list { + struct X { + void foo() {} + }; + + void (*pf1)() {}; + void (X::*pmf1)() {&X::foo}; + void (X::*pmf2)() = {&X::foo}; + + void test() { + void (*pf2)() {}; + void (X::*pmf3)() {&X::foo}; + void (X::*pmf4)() = {&X::foo}; + } +}