diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-08-21 03:04:33 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-08-21 03:04:33 +0000 |
| commit | b9fa99649bc99e2be9d06511d16f266225eae860 (patch) | |
| tree | c613a456b27dcd04d793d764d1b47310aff63d23 /clang/lib/Parse | |
| parent | 772527c57b4b949905e39ec03360f6f9d19d2729 (diff) | |
| download | bcm5719-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.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 37 |
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) { |

