[flang] Add common::ImportKind

Replace parser::ImportStmt::Kind and semantics::Scope::ImportKind with a
single enum class in common/fortran.h. This eliminates the need to map
between the parser enum and the semantics enum.

Original-commit: flang-compiler/f18@779a99314c
Reviewed-on: https://github.com/flang-compiler/f18/pull/167
This commit is contained in:
Tim Keith
2018-08-23 11:45:49 -07:00
parent 364aed2109
commit 37476ee32e
8 changed files with 31 additions and 36 deletions

View File

@@ -25,5 +25,8 @@ namespace Fortran::common {
// Fortran has five kinds of intrinsic data, and the derived types.
ENUM_CLASS(TypeCategory, Integer, Real, Complex, Character, Logical, Derived)
// Kinds of IMPORT statements. Default means IMPORT or IMPORT :: names.
ENUM_CLASS(ImportKind, Default, Only, None, All)
} // namespace Fortran::common
#endif // FORTRAN_COMMON_FORTRAN_H_

View File

@@ -1293,11 +1293,12 @@ TYPE_PARSER(space >> (construct<LetterSpec>(letter, maybe("-" >> letter)) ||
// IMPORT [[::] import-name-list] |
// IMPORT , ONLY : import-name-list | IMPORT , NONE | IMPORT , ALL
TYPE_CONTEXT_PARSER("IMPORT statement"_en_US,
construct<ImportStmt>("IMPORT , ONLY :" >> pure(ImportStmt::Kind::Only),
construct<ImportStmt>("IMPORT , ONLY :" >> pure(common::ImportKind::Only),
nonemptyList(name)) ||
construct<ImportStmt>(
"IMPORT , NONE" >> pure(ImportStmt::Kind::None)) ||
construct<ImportStmt>("IMPORT , ALL" >> pure(ImportStmt::Kind::All)) ||
"IMPORT , NONE" >> pure(common::ImportKind::None)) ||
construct<ImportStmt>(
"IMPORT , ALL" >> pure(common::ImportKind::All)) ||
construct<ImportStmt>(
"IMPORT" >> maybe("::"_tok) >> optionalList(name)))

View File

@@ -21,9 +21,10 @@
namespace Fortran::parser {
// R867
ImportStmt::ImportStmt(Kind &&k, std::list<Name> &&n)
ImportStmt::ImportStmt(common::ImportKind &&k, std::list<Name> &&n)
: kind{k}, names(std::move(n)) {
CHECK(kind == Kind::Default || kind == Kind::Only || names.empty());
CHECK(kind == common::ImportKind::Default ||
kind == common::ImportKind::Only || names.empty());
}
// R901 designator

View File

@@ -28,6 +28,7 @@
#include "format-specification.h"
#include "message.h"
#include "provenance.h"
#include "../common/fortran.h"
#include "../common/idioms.h"
#include "../common/indirection.h"
#include <cinttypes>
@@ -571,11 +572,10 @@ using ObjectName = Name;
// IMPORT , ONLY : import-name-list | IMPORT , NONE | IMPORT , ALL
struct ImportStmt {
BOILERPLATE(ImportStmt);
ENUM_CLASS(Kind, Default, Only, None, All)
ImportStmt(Kind &&k) : kind{k} {}
ImportStmt(common::ImportKind &&k) : kind{k} {}
ImportStmt(std::list<Name> &&n) : names(std::move(n)) {}
ImportStmt(Kind &&, std::list<Name> &&);
Kind kind{Kind::Default};
ImportStmt(common::ImportKind &&, std::list<Name> &&);
common::ImportKind kind{common::ImportKind::Default};
std::list<Name> names;
};

View File

@@ -19,6 +19,7 @@
#include "characters.h"
#include "parse-tree-visitor.h"
#include "parse-tree.h"
#include "../common/fortran.h"
#include "../common/idioms.h"
#include "../common/indirection.h"
#include <algorithm>
@@ -648,13 +649,13 @@ public:
void Unparse(const ImportStmt &x) { // R867
Word("IMPORT");
switch (x.kind) {
case ImportStmt::Kind::Default: Walk(" :: ", x.names, ", "); break;
case ImportStmt::Kind::Only:
case common::ImportKind::Default: Walk(" :: ", x.names, ", "); break;
case common::ImportKind::Only:
Put(", "), Word("ONLY: ");
Walk(x.names, ", ");
break;
case ImportStmt::Kind::None: Word(", NONE"); break;
case ImportStmt::Kind::All: Word(", ALL"); break;
case common::ImportKind::None: Word(", NONE"); break;
case common::ImportKind::All: Word(", ALL"); break;
default: CRASH_NO_CASE;
}
}

View File

@@ -36,7 +36,6 @@ using namespace parser::literals;
class MessageHandler;
static GenericSpec MapGenericSpec(const parser::GenericSpec &);
static Scope::ImportKind MapImportKind(parser::ImportStmt::Kind);
// ImplicitRules maps initial character of identifier to the DeclTypeSpec*
// representing the implicit type; nullptr if none.
@@ -2149,7 +2148,6 @@ void ResolveNamesVisitor::Post(const parser::CallStmt &) {
}
bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) {
auto kind{MapImportKind(x.kind)};
auto &scope{currScope()};
// Check C896 and C899: where IMPORT statements are allowed
switch (scope.kind()) {
@@ -2157,7 +2155,7 @@ bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) {
if (!scope.symbol()->get<ModuleDetails>().isSubmodule()) {
Say("IMPORT is not allowed in a module scoping unit"_err_en_US);
return false;
} else if (kind == Scope::ImportKind::None) {
} else if (x.kind == common::ImportKind::None) {
Say("IMPORT,NONE is not allowed in a submodule scoping unit"_err_en_US);
return false;
}
@@ -2173,7 +2171,7 @@ bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) {
break;
default:;
}
if (auto error{scope.SetImportKind(kind)}) {
if (auto error{scope.SetImportKind(x.kind)}) {
Say(std::move(*error));
}
for (auto &name : x.names) {
@@ -2431,9 +2429,9 @@ void ResolveNamesVisitor::Post(const parser::SpecificationPart &) {
void ResolveNamesVisitor::CheckImports() {
auto &scope{currScope()};
switch (scope.importKind()) {
case Scope::ImportKind::None: break;
case Scope::ImportKind::All:
switch (scope.GetImportKind()) {
case common::ImportKind::None: break;
case common::ImportKind::All:
// C8102: all entities in host must not be hidden
for (const auto &pair : scope.parent()) {
auto &name{pair.first};
@@ -2442,8 +2440,8 @@ void ResolveNamesVisitor::CheckImports() {
}
}
break;
case Scope::ImportKind::Default:
case Scope::ImportKind::Only:
case common::ImportKind::Default:
case common::ImportKind::Only:
// C8102: entities named in IMPORT must not be hidden
for (auto &name : scope.importNames()) {
CheckImport(name, name);
@@ -2651,16 +2649,6 @@ static GenericSpec MapGenericSpec(const parser::GenericSpec &genericSpec) {
genericSpec.u);
}
static Scope::ImportKind MapImportKind(parser::ImportStmt::Kind kind) {
switch (kind) {
case parser::ImportStmt::Kind::Default: return Scope::ImportKind::Default;
case parser::ImportStmt::Kind::Only: return Scope::ImportKind::Only;
case parser::ImportStmt::Kind::None: return Scope::ImportKind::None;
case parser::ImportStmt::Kind::All: return Scope::ImportKind::All;
default: CRASH_NO_CASE;
}
}
static void PutIndent(std::ostream &os, int indent) {
for (int i = 0; i < indent; ++i) {
os << " ";

View File

@@ -74,7 +74,7 @@ DerivedTypeSpec &Scope::MakeDerivedTypeSpec(const SourceName &name) {
return derivedTypeSpecs_.back();
}
Scope::ImportKind Scope::importKind() const {
Scope::ImportKind Scope::GetImportKind() const {
if (importKind_) {
return *importKind_;
}
@@ -122,7 +122,7 @@ bool Scope::CanImport(const SourceName &name) const {
if (kind_ == Kind::Global) {
return false;
}
switch (importKind()) {
switch (GetImportKind()) {
case ImportKind::None: return false;
case ImportKind::All:
case ImportKind::Default: return true;

View File

@@ -17,6 +17,7 @@
#include "attr.h"
#include "symbol.h"
#include "../common/fortran.h"
#include "../common/idioms.h"
#include "../parser/message.h"
#include <list>
@@ -37,7 +38,7 @@ public:
static Scope globalScope; // contains program-units
ENUM_CLASS(Kind, System, Global, Module, MainProgram, Subprogram, DerivedType)
ENUM_CLASS(ImportKind, Default, Only, None, All);
using ImportKind = common::ImportKind;
Scope(Scope &parent, Kind kind, Symbol *symbol)
: parent_{parent}, kind_{kind}, symbol_{symbol} {
@@ -125,7 +126,7 @@ public:
// that are referenced by SourceName objects.
void set_chars(std::string &&chars) { chars_ = std::move(chars); }
ImportKind importKind() const;
ImportKind GetImportKind() const;
// Names appearing in IMPORT statements in this scope
std::set<SourceName> importNames() const { return importNames_; }