summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-03-12 08:56:40 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-03-12 08:56:40 +0000
commitbfdb108fc5e627e740d096ee96ea6e1b10891e66 (patch)
tree329e7209f4fb7ce3a9a3636934309c1794bf24a9 /clang/lib/Parse/ParseDeclCXX.cpp
parentc5b05520550a4becec926564bef032e60023cde2 (diff)
downloadbcm5719-llvm-bfdb108fc5e627e740d096ee96ea6e1b10891e66.tar.gz
bcm5719-llvm-bfdb108fc5e627e740d096ee96ea6e1b10891e66.zip
Fix parsing of trailing-return-type. Types are syntactically prohibited from
being defined here: [] () -> struct S {} does not define struct S. In passing, implement DR1318 (syntactic disambiguation of 'final'). llvm-svn: 152551
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp34
1 files changed, 17 insertions, 17 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 391db1987a1..979b4dd18fe 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1114,11 +1114,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
if (SuppressingAccessChecks)
Actions.ActOnStopSuppressingAccessChecks();
- // There are four options here. If we have 'struct foo;', then this
- // is either a forward declaration or a friend declaration, which
- // have to be treated differently. If we have 'struct foo {...',
- // 'struct foo :...' or 'struct foo final[opt]' then this is a
- // definition. Otherwise we have something like 'struct foo xyz', a reference.
+ // There are four options here.
+ // - If we are in a trailing return type, this is always just a reference,
+ // and we must not try to parse a definition. For instance,
+ // [] () -> struct S { };
+ // does not define a type.
+ // - If we have 'struct foo {...', 'struct foo :...',
+ // 'struct foo final :' or 'struct foo final {', then this is a definition.
+ // - If we have 'struct foo;', then this is either a forward declaration
+ // or a friend declaration, which have to be treated differently.
+ // - Otherwise we have something like 'struct foo xyz', a reference.
// However, in type-specifier-seq's, things look like declarations but are
// just references, e.g.
// new struct s;
@@ -1126,10 +1131,12 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// &T::operator struct s;
// For these, DSC is DSC_type_specifier.
Sema::TagUseKind TUK;
- if (Tok.is(tok::l_brace) ||
- (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
- // FIXME: 'final' must be followed by ':' or '{' to mark a definition.
- isCXX0XFinalKeyword()) {
+ if (DSC == DSC_trailing)
+ TUK = Sema::TUK_Reference;
+ else if (Tok.is(tok::l_brace) ||
+ (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
+ (isCXX0XFinalKeyword() &&
+ NextToken().is(tok::l_brace) || NextToken().is(tok::colon))) {
if (DS.isFriendSpecified()) {
// C++ [class.friend]p2:
// A class shall not be defined in a friend declaration.
@@ -2673,14 +2680,7 @@ TypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
ConsumeToken();
- // FIXME: Need to suppress declarations when parsing this typename.
- // Otherwise in this function definition:
- //
- // auto f() -> struct X {}
- //
- // struct X is parsed as class definition because of the trailing
- // brace.
- return ParseTypeName(&Range);
+ return ParseTypeName(&Range, Declarator::TrailingReturnContext);
}
/// \brief We have just started parsing the definition of a new class,
OpenPOWER on IntegriCloud