// 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 &);
// 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
}
bool ImplicitRules::isImplicitNoneExternal() const {
- if (isImplicitNoneExternal_.has_value()) {
- return isImplicitNoneExternal_.value();
+ if (isImplicitNoneExternal_) {
+ return true;
} else if (inheritFromParent_) {
return parent_->isImplicitNoneExternal();
} else {
}
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;
}
}
-// 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);
}
-! 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.
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