[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. // Get the implicit type for identifiers starting with ch. May be null.
const DeclTypeSpec *GetType(char ch) const; const DeclTypeSpec *GetType(char ch) const;
// Record the implicit type for this range of characters. // Record the implicit type for this range of characters.
void SetType(const DeclTypeSpec &type, parser::Location lo, parser::Location, void SetType(const DeclTypeSpec &type, parser::Location lo, parser::Location);
bool isDefault = false);
private: private:
static char Incr(char ch); static char Incr(char ch);
ImplicitRules *parent_; ImplicitRules *parent_;
SemanticsContext &context_; SemanticsContext &context_;
bool inheritFromParent_; // look in parent if not specified here bool inheritFromParent_{false}; // look in parent if not specified here
std::optional<bool> isImplicitNoneType_; bool isImplicitNoneType_{false};
std::optional<bool> isImplicitNoneExternal_; bool isImplicitNoneExternal_{false};
// map initial character of identifier to nullptr or its default type // 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_; std::map<char, const DeclTypeSpec *> map_;
friend std::ostream &operator<<(std::ostream &, const ImplicitRules &); friend std::ostream &operator<<(std::ostream &, const ImplicitRules &);
@ -1109,9 +1110,9 @@ private:
// ImplicitRules implementation // ImplicitRules implementation
bool ImplicitRules::isImplicitNoneType() const { bool ImplicitRules::isImplicitNoneType() const {
if (isImplicitNoneType_.has_value()) { if (isImplicitNoneType_) {
return isImplicitNoneType_.value(); return true;
} else if (inheritFromParent_) { } else if (map_.empty() && inheritFromParent_) {
return parent_->isImplicitNoneType(); return parent_->isImplicitNoneType();
} else { } else {
return false; // default if not specified return false; // default if not specified
@ -1119,8 +1120,8 @@ bool ImplicitRules::isImplicitNoneType() const {
} }
bool ImplicitRules::isImplicitNoneExternal() const { bool ImplicitRules::isImplicitNoneExternal() const {
if (isImplicitNoneExternal_.has_value()) { if (isImplicitNoneExternal_) {
return isImplicitNoneExternal_.value(); return true;
} else if (inheritFromParent_) { } else if (inheritFromParent_) {
return parent_->isImplicitNoneExternal(); return parent_->isImplicitNoneExternal();
} else { } else {
@ -1129,7 +1130,7 @@ bool ImplicitRules::isImplicitNoneExternal() const {
} }
const DeclTypeSpec *ImplicitRules::GetType(char ch) const { const DeclTypeSpec *ImplicitRules::GetType(char ch) const {
if (isImplicitNoneType()) { if (isImplicitNoneType_) {
return nullptr; return nullptr;
} else if (auto it{map_.find(ch)}; it != map_.end()) { } else if (auto it{map_.find(ch)}; it != map_.end()) {
return it->second; 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 void ImplicitRules::SetType(
// an error if the type is already set. const DeclTypeSpec &type, parser::Location lo, parser::Location hi) {
void ImplicitRules::SetType(const DeclTypeSpec &type, parser::Location lo,
parser::Location hi, bool isDefault) {
for (char ch = *lo; ch; ch = ImplicitRules::Incr(ch)) { for (char ch = *lo; ch; ch = ImplicitRules::Incr(ch)) {
auto res{map_.emplace(ch, &type)}; auto res{map_.emplace(ch, &type)};
if (!res.second && !isDefault) { if (!res.second) {
context_.Say(parser::CharBlock{lo}, context_.Say(parser::CharBlock{lo},
"More than one implicit type specified for '%c'"_err_en_US, ch); "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"); ! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License. ! you may not use this file except in compliance with the License.
@ -35,3 +35,36 @@ contains
j = 2 j = 2
end subroutine end subroutine
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