diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-12-16 21:30:33 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-12-16 21:30:33 +0000 |
commit | 4d87df5853ab4730f617a21747037ebcdde70745 (patch) | |
tree | 2339628b6677d8e1ecf8b3cdced7d7f86c2b8811 /clang/lib/Parse/ParseDecl.cpp | |
parent | 56b55387fcf8cd2b094c306eaa4955d2915643ae (diff) | |
download | bcm5719-llvm-4d87df5853ab4730f617a21747037ebcdde70745.tar.gz bcm5719-llvm-4d87df5853ab4730f617a21747037ebcdde70745.zip |
Delay parsing of default arguments of member functions until the class
is completely defined (C++ [class.mem]p2).
Reverse the order in which we process the definitions of member
functions specified inline. This way, we'll get diagnostics in the
order in which the member functions were declared in the class.
llvm-svn: 61103
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index ed151402744..1a8e5d9f955 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1771,6 +1771,10 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Remember this parsed parameter in ParamInfo. IdentifierInfo *ParmII = ParmDecl.getIdentifier(); + // DefArgToks is used when the parsing of default arguments needs + // to be delayed. + CachedTokens *DefArgToks = 0; + // If no parameter was specified, verify that *something* was specified, // otherwise we have a missing type and identifier. if (DS.getParsedSpecifiers() == DeclSpec::PQ_None && @@ -1790,24 +1794,39 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // ActOnParamDefaultArgument will reject the default argument in // C. if (Tok.is(tok::equal)) { - SourceLocation EqualLoc = Tok.getLocation(); - - // Consume the '='. - ConsumeToken(); - // Parse the default argument - OwningExprResult DefArgResult(ParseAssignmentExpression()); - if (DefArgResult.isInvalid()) { - SkipUntil(tok::comma, tok::r_paren, true, true); + if (D.getContext() == Declarator::MemberContext) { + // If we're inside a class definition, cache the tokens + // corresponding to the default argument. We'll actually parse + // them when we see the end of the class definition. + // FIXME: Templates will require something similar. + // FIXME: Can we use a smart pointer for Toks? + DefArgToks = new CachedTokens; + + if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks, + tok::semi, false)) { + delete DefArgToks; + DefArgToks = 0; + } } else { - // Inform the actions module about the default argument - Actions.ActOnParamDefaultArgument(Param, EqualLoc, - DefArgResult.release()); + // Consume the '='. + SourceLocation EqualLoc = ConsumeToken(); + + OwningExprResult DefArgResult(ParseAssignmentExpression()); + if (DefArgResult.isInvalid()) { + Actions.ActOnParamDefaultArgumentError(Param); + SkipUntil(tok::comma, tok::r_paren, true, true); + } else { + // Inform the actions module about the default argument + Actions.ActOnParamDefaultArgument(Param, EqualLoc, + DefArgResult.release()); + } } } ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, - ParmDecl.getIdentifierLoc(), Param)); + ParmDecl.getIdentifierLoc(), Param, + DefArgToks)); } // If the next token is a comma, consume it and keep reading arguments. |