summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-08-21 03:04:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-08-21 03:04:33 +0000
commitb9fa99649bc99e2be9d06511d16f266225eae860 (patch)
treec613a456b27dcd04d793d764d1b47310aff63d23 /clang/lib/Parse
parent772527c57b4b949905e39ec03360f6f9d19d2729 (diff)
downloadbcm5719-llvm-b9fa99649bc99e2be9d06511d16f266225eae860.tar.gz
bcm5719-llvm-b9fa99649bc99e2be9d06511d16f266225eae860.zip
[modules] When we see a definition of a function for which we already have a
non-visible definition, skip the new definition to avoid ending up with a function with multiple definitions. llvm-svn: 245664
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r--clang/lib/Parse/ParseObjc.cpp1
-rw-r--r--clang/lib/Parse/Parser.cpp37
2 files changed, 34 insertions, 4 deletions
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index ed6090453da..ab097661f8b 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -2614,6 +2614,7 @@ void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
}
else if (Tok.is(tok::colon)) {
ConsumeToken();
+ // FIXME: This is wrong, due to C++11 braced initialization.
while (Tok.isNot(tok::l_brace)) {
ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 0acd828d7c1..35e853f64fc 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1067,10 +1067,17 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// Tell the actions module that we have entered a function definition with the
// specified Declarator for the function.
- Decl *Res = TemplateInfo.TemplateParams?
- Actions.ActOnStartOfFunctionTemplateDef(getCurScope(),
- *TemplateInfo.TemplateParams, D)
- : Actions.ActOnStartOfFunctionDef(getCurScope(), D);
+ Sema::SkipBodyInfo SkipBody;
+ Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
+ TemplateInfo.TemplateParams
+ ? *TemplateInfo.TemplateParams
+ : MultiTemplateParamsArg(),
+ &SkipBody);
+
+ if (SkipBody.ShouldSkip) {
+ SkipFunctionBody();
+ return Res;
+ }
// Break out of the ParsingDeclarator context before we parse the body.
D.complete(Res);
@@ -1137,6 +1144,28 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
return ParseFunctionStatementBody(Res, BodyScope);
}
+void Parser::SkipFunctionBody() {
+ if (Tok.is(tok::equal)) {
+ SkipUntil(tok::semi);
+ return;
+ }
+
+ bool IsFunctionTryBlock = Tok.is(tok::kw_try);
+ if (IsFunctionTryBlock)
+ ConsumeToken();
+
+ CachedTokens Skipped;
+ if (ConsumeAndStoreFunctionPrologue(Skipped))
+ SkipMalformedDecl();
+ else {
+ SkipUntil(tok::r_brace);
+ while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) {
+ SkipUntil(tok::l_brace);
+ SkipUntil(tok::r_brace);
+ }
+ }
+}
+
/// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
/// types for a function with a K&R-style identifier list for arguments.
void Parser::ParseKNRParamDeclarations(Declarator &D) {
OpenPOWER on IntegriCloud