summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Brewer <ben.brewer@codethink.co.uk>2015-08-27 16:14:41 +0100
committerBen Brewer <ben.brewer@codethink.co.uk>2015-08-27 16:14:41 +0100
commit409a57128f3b4cacc5ddb63165072055cc508b9f (patch)
tree305907a8a70f532f66d3b031262296845f4d46e0
parentc14f33fee8b2544c23601c1961c5c8d702b445ba (diff)
downloadflang-409a57128f3b4cacc5ddb63165072055cc508b9f.tar.gz
Allow unbracketed logical constant in IF and WHILE statementsbenbrewer/if-logical-const
-rw-r--r--include/flang/Parse/Parser.h2
-rw-r--r--lib/Parse/ParseExec.cpp60
2 files changed, 37 insertions, 25 deletions
diff --git a/include/flang/Parse/Parser.h b/include/flang/Parse/Parser.h
index b498f6054d..eb6156808c 100644
--- a/include/flang/Parse/Parser.h
+++ b/include/flang/Parse/Parser.h
@@ -484,7 +484,7 @@ private:
StmtResult ParseElseIfStmt();
StmtResult ParseElseStmt();
StmtResult ParseEndIfStmt();
- ExprResult ParseExpectedConditionExpression(const char *DiagAfter);
+ ExprResult ParseExpectedConditionExpression(const char *DiagAfter, bool *Failed = NULL);
StmtResult ParseDoStmt();
StmtResult ParseDoWhileStmt(bool isDo);
diff --git a/lib/Parse/ParseExec.cpp b/lib/Parse/ParseExec.cpp
index 7ac3e1afdf..9d070f2814 100644
--- a/lib/Parse/ParseExec.cpp
+++ b/lib/Parse/ParseExec.cpp
@@ -336,29 +336,44 @@ Parser::StmtResult Parser::ParseGotoStmt() {
/// if-stmt :=
/// IF(scalar-logic-expr) action-stmt
-ExprResult Parser::ParseExpectedConditionExpression(const char *DiagAfter) {
- if (!ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
- DiagAfter))
- return ExprError();
- ExprResult Condition = ParseExpectedFollowupExpression("(");
- if(Condition.isInvalid()) return Condition;
- if (!ExpectAndConsume(tok::r_paren))
- return ExprError();
+ExprResult Parser::ParseExpectedConditionExpression(const char *DiagAfter, bool *Failed) {
+ ExprResult Condition;
+ if (IsPresent(tok::logical_literal_constant)) {
+ Condition = ParseExpectedFollowupExpression(DiagAfter);
+ } else {
+ if (!ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+ DiagAfter)) {
+ if (Failed)
+ *Failed = true;
+ return ExprError();
+ }
+
+ Condition = ParseExpectedFollowupExpression("(");
+ if(Condition.isInvalid() && !SkipUntil(tok::r_paren, true, true)) {
+ if (Failed)
+ *Failed = true;
+ return Condition;
+ }
+
+ if (!ExpectAndConsume(tok::r_paren)) {
+ if (Failed)
+ *Failed = true;
+ return ExprError();
+ }
+ }
+
+ if (Failed)
+ *Failed = false;
return Condition;
}
Parser::StmtResult Parser::ParseIfStmt() {
auto Loc = ConsumeToken();
- ExprResult Condition;
- if (!ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "IF"))
+ bool BadCondition = false;
+ ExprResult Condition = ParseExpectedConditionExpression("IF", &BadCondition);
+ if (BadCondition)
goto error;
- Condition = ParseExpectedFollowupExpression("(");
- if(Condition.isInvalid()) {
- if(!SkipUntil(tok::r_paren, true, true))
- goto error;
- }
- if (!ExpectAndConsume(tok::r_paren)) goto error;
if(Features.FixedForm && !Tok.isAtStartOfStatement())
ReLexAmbiguousIdentifier(FixedFormAmbiguities.getMatcherForKeywordsAfterIF());
@@ -387,15 +402,12 @@ error:
// FIXME: fixed-form THENconstructname
Parser::StmtResult Parser::ParseElseIfStmt() {
auto Loc = ConsumeToken();
- ExprResult Condition;
- if (!ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "ELSE IF"))
+
+ bool BadCondition = false;
+ ExprResult Condition = ParseExpectedConditionExpression("ELSE IF", &BadCondition);
+ if (BadCondition)
goto error;
- Condition = ParseExpectedFollowupExpression("(");
- if(Condition.isInvalid()) {
- if(!SkipUntil(tok::r_paren, true, true))
- goto error;
- }
- if (!ExpectAndConsume(tok::r_paren)) goto error;
+
if (!ExpectAndConsumeFixedFormAmbiguous(tok::kw_THEN, diag::err_expected_kw, "THEN"))
goto error;
ParseTrailingConstructName();