[flang] Transform implict none ternaries to bool in `ImplicitRules`

Original-commit: flang-compiler/f18@324567bd2d
Reviewed-on: https://github.com/flang-compiler/f18/pull/635
Tree-same-pre-rewrite: false
This commit is contained in:
Jean Perier 2019-08-08 08:38:01 -07:00
parent 069ea6ec75
commit 0818c53966
2 changed files with 50 additions and 18 deletions

View File

@ -74,18 +74,19 @@ public:
// Get the implicit type for identifiers starting with ch. May be null.
const DeclTypeSpec *GetType(char ch) const;
// Record the implicit type for this range of characters.
void SetType(const DeclTypeSpec &type, parser::Location lo, parser::Location,
bool isDefault = false);
void SetType(const DeclTypeSpec &type, parser::Location lo, parser::Location);
private:
static char Incr(char ch);
ImplicitRules *parent_;
SemanticsContext &context_;
bool inheritFromParent_; // look in parent if not specified here
std::optional<bool> isImplicitNoneType_;
std::optional<bool> isImplicitNoneExternal_;
// map initial character of identifier to nullptr or its default type
bool inheritFromParent_{false}; // look in parent if not specified here
bool isImplicitNoneType_{false};
bool isImplicitNoneExternal_{false};
// map_ contains the mapping between letters and types that were defined
// by the IMPLICIT statements of the related scope. It does not contain
// the default Fortran mappings nor the mapping defined in parents.
std::map<char, const DeclTypeSpec *> map_;
friend std::ostream &operator<<(std::ostream &, const ImplicitRules &);
@ -1109,9 +1110,9 @@ private:
// ImplicitRules implementation
bool ImplicitRules::isImplicitNoneType() const {
if (isImplicitNoneType_.has_value()) {
return isImplicitNoneType_.value();
} else if (inheritFromParent_) {
if (isImplicitNoneType_) {
return true;
} else if (map_.empty() && inheritFromParent_) {
return parent_->isImplicitNoneType();
} else {
return false; // default if not specified
@ -1119,8 +1120,8 @@ bool ImplicitRules::isImplicitNoneType() const {
}
bool ImplicitRules::isImplicitNoneExternal() const {
if (isImplicitNoneExternal_.has_value()) {
return isImplicitNoneExternal_.value();
if (isImplicitNoneExternal_) {
return true;
} else if (inheritFromParent_) {
return parent_->isImplicitNoneExternal();
} else {
@ -1129,7 +1130,7 @@ bool ImplicitRules::isImplicitNoneExternal() const {
}
const DeclTypeSpec *ImplicitRules::GetType(char ch) const {
if (isImplicitNoneType()) {
if (isImplicitNoneType_) {
return nullptr;
} else if (auto it{map_.find(ch)}; it != map_.end()) {
return it->second;
@ -1144,13 +1145,11 @@ const DeclTypeSpec *ImplicitRules::GetType(char ch) const {
}
}
// isDefault is set when we are applying the default rules, so it is not
// an error if the type is already set.
void ImplicitRules::SetType(const DeclTypeSpec &type, parser::Location lo,
parser::Location hi, bool isDefault) {
void ImplicitRules::SetType(
const DeclTypeSpec &type, parser::Location lo, parser::Location hi) {
for (char ch = *lo; ch; ch = ImplicitRules::Incr(ch)) {
auto res{map_.emplace(ch, &type)};
if (!res.second && !isDefault) {
if (!res.second) {
context_.Say(parser::CharBlock{lo},
"More than one implicit type specified for '%c'"_err_en_US, ch);
}

View File

@ -1,4 +1,4 @@
! Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
! Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
@ -35,3 +35,36 @@ contains
j = 2
end subroutine
end subroutine
module m1
implicit none
contains
subroutine s1
implicit real (a-h)
a1 = 1.
h1 = 1.
!ERROR: No explicit type declared for 'i1'
i1 = 1
!ERROR: No explicit type declared for 'z1'
z1 = 2.
contains
subroutine ss1
implicit integer(f-j) ! overlap with host scope import is OK
a2 = 1.
h2 = 1
i2 = 1
!ERROR: No explicit type declared for 'z2'
z2 = 2.
contains
subroutine sss1
implicit none
!ERROR: No explicit type declared for 'a3'
a3 = 1.
end subroutine
end subroutine
end subroutine
subroutine s2
!ERROR: No explicit type declared for 'b1'
b1 = 1.
end subroutine
end module