summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-12-16 21:30:33 +0000
committerDouglas Gregor <dgregor@apple.com>2008-12-16 21:30:33 +0000
commit4d87df5853ab4730f617a21747037ebcdde70745 (patch)
tree2339628b6677d8e1ecf8b3cdced7d7f86c2b8811 /clang/lib/Parse/ParseDecl.cpp
parent56b55387fcf8cd2b094c306eaa4955d2915643ae (diff)
downloadbcm5719-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.cpp43
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.
OpenPOWER on IntegriCloud