mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
[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:
@@ -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_
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 << " ";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user