зеркало из https://github.com/microsoft/clang-1.git
Teach statement / declaration disambiguation about C++11-style generalized initializers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177480 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
f48b93cb20
Коммит
576f32c5e1
|
@ -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 ')'
|
||||
///
|
||||
/// initializer-clause:
|
||||
/// assignment-expression
|
||||
/// '{' initializer-list ','[opt] '}'
|
||||
/// '{' '}'
|
||||
/// brace-or-equal-initializer:
|
||||
/// '=' initializer-clause
|
||||
/// [C++11] braced-init-list
|
||||
///
|
||||
/// 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.
|
||||
|
|
|
@ -133,3 +133,19 @@ namespace ellipsis {
|
|||
void l(int(S<int>::*...)(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};
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче