summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-14 13:03:23 +0100
committerarphaman <arphaman@gmail.com>2013-09-14 13:03:23 +0100
commit8faf776a94e8145925f13c157801fd364ca648d6 (patch)
tree5731d90b5f6633c0fff6dc9d3b532ceab44382a4
parent145e670d60b8868b1c0b3653f0483c16ee69d6b8 (diff)
downloadflang-8faf776a94e8145925f13c157801fd364ca648d6.tar.gz
fixed parsing for programs which begin with type statements
-rw-r--r--lib/Parse/Parser.cpp20
-rw-r--r--test/Parser/minimalAmbiguous.f954
2 files changed, 18 insertions, 6 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 07c6e5dac8..f5c57866b5 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -600,7 +600,8 @@ bool Parser::ParseProgramUnit() {
case tok::kw_LOGICAL:
case tok::kw_DOUBLEPRECISION:
case tok::kw_DOUBLECOMPLEX:
- ParseTypedExternalSubprogram(FunctionDecl::NoAttributes);
+ if(ParseTypedExternalSubprogram(FunctionDecl::NoAttributes))
+ ParseMainProgram();
break;
case tok::kw_RECURSIVE:
ParseRecursiveExternalSubprogram();
@@ -809,12 +810,14 @@ bool Parser::ParseExternalSubprogram() {
}
bool Parser::ParseTypedExternalSubprogram(int Attr) {
+ auto ReparseLoc = LocFirstStmtToken;
DeclSpec ReturnType;
ParseDeclarationTypeSpec(ReturnType);
+ bool IsRecursive = (Attr & FunctionDecl::Recursive) != 0;
if(Tok.isAtStartOfStatement())
goto err;
- if(!(Attr & FunctionDecl::Recursive)) {
+ if(!IsRecursive) {
if(Features.FixedForm)
ReLexAmbiguousIdentifier(fixedForm::KeywordMatcher(fixedForm::KeywordFilter(tok::kw_RECURSIVE,
tok::kw_FUNCTION)));
@@ -828,11 +831,16 @@ bool Parser::ParseTypedExternalSubprogram(int Attr) {
goto err;
if(Features.FixedForm)
ReLexAmbiguousIdentifier(fixedForm::KeywordMatcher(fixedForm::KeywordFilter(tok::kw_FUNCTION)));
- if(Tok.is(tok::kw_FUNCTION))
- return ParseExternalSubprogram(ReturnType, Attr);
+ if(Tok.is(tok::kw_FUNCTION)) {
+ ParseExternalSubprogram(ReturnType, Attr);
+ return false;
+ }
err:
- Diag.Report(getExpectedLoc(), diag::err_expected_kw)
- << "function";
+ if(IsRecursive) {
+ Diag.Report(getExpectedLoc(), diag::err_expected_kw)
+ << "function";
+ SkipUntilNextStatement();
+ } else StartStatementReparse(ReparseLoc);
return true;
}
diff --git a/test/Parser/minimalAmbiguous.f95 b/test/Parser/minimalAmbiguous.f95
new file mode 100644
index 0000000000..2ed490f1ea
--- /dev/null
+++ b/test/Parser/minimalAmbiguous.f95
@@ -0,0 +1,4 @@
+! RUN: %flang -fsyntax-only < %s
+INTEGER I
+I = 0
+END