[flang] Look for declared STRUCTURE component names after a . rather than defined operator names.

Original-commit: flang-compiler/f18@cf64809551
Reviewed-on: https://github.com/flang-compiler/f18/pull/37
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2018-03-30 14:10:00 -07:00
parent 3a0351e43c
commit f8c7fde5c2
2 changed files with 33 additions and 33 deletions

View file

@ -1633,26 +1633,25 @@ TYPE_PARSER(space >> "."_ch >>
// R911 data-ref -> part-ref [% part-ref]... // R911 data-ref -> part-ref [% part-ref]...
// R914 coindexed-named-object -> data-ref // R914 coindexed-named-object -> data-ref
// R917 array-element -> data-ref // R917 array-element -> data-ref
constexpr struct DefinedOperatorName { constexpr struct StructureComponentName {
using resultType = Success; using resultType = Name;
static std::optional<Success> Parse(ParseState *state) { static std::optional<Name> Parse(ParseState *state) {
if (std::optional<DefinedOpName> n{definedOpName.Parse(state)}) { if (std::optional<Name> n{name.Parse(state)}) {
if (const auto *user = state->userState()) { if (const auto *user = state->userState()) {
if (user->IsDefinedOperator(n->v.source)) { if (user->IsStructureComponent(n->source)) {
return {Success{}}; return n;
} }
} }
} }
return {}; return {};
} }
} definedOperatorName; } structureComponentName;
constexpr auto percentOrDot = "%"_tok || constexpr auto percentOrDot = "%"_tok ||
// legacy VAX extension for RECORD field access // legacy VAX extension for RECORD field access
// TODO: this clashes with user-defined operators in modern Fortran! extension("."_tok / lookAhead(structureComponentName));
// This work-around is incomplete; it can't see into modules.
extension(!namedIntrinsicOperator >> !definedOperatorName >> "."_tok);
// TODO - why is this not a TYPE_PARSER?
template<> template<>
std::optional<DataReference> Parser<DataReference>::Parse(ParseState *state) { std::optional<DataReference> Parser<DataReference>::Parse(ParseState *state) {
static constexpr auto partRefs = static constexpr auto partRefs =
@ -3386,24 +3385,8 @@ TYPE_PARSER(construct<ProcedureStmt>{}("MODULE PROCEDURE"_sptok >>
// R1509 defined-io-generic-spec -> // R1509 defined-io-generic-spec ->
// READ ( FORMATTED ) | READ ( UNFORMATTED ) | // READ ( FORMATTED ) | READ ( UNFORMATTED ) |
// WRITE ( FORMATTED ) | WRITE ( UNFORMATTED ) // WRITE ( FORMATTED ) | WRITE ( UNFORMATTED )
constexpr struct NoteOperatorDefinition {
using resultType = DefinedOperator;
static std::optional<DefinedOperator> Parse(ParseState *state) {
static constexpr auto definedOperator = Parser<DefinedOperator>{};
std::optional<DefinedOperator> op{definedOperator.Parse(state)};
if (op.has_value()) {
if (auto ustate = state->userState()) {
if (const auto *name = std::get_if<DefinedOpName>(&op->u)) {
ustate->NoteDefinedOperator(name->v.source);
}
}
}
return op;
}
} noteOperatorDefinition;
TYPE_PARSER(construct<GenericSpec>{}( TYPE_PARSER(construct<GenericSpec>{}(
"OPERATOR" >> parenthesized(noteOperatorDefinition)) || "OPERATOR" >> parenthesized(definedOperator)) ||
construct<GenericSpec>{}( construct<GenericSpec>{}(
"ASSIGNMENT ( = )" >> construct<GenericSpec::Assignment>{}) || "ASSIGNMENT ( = )" >> construct<GenericSpec::Assignment>{}) ||
construct<GenericSpec>{}( construct<GenericSpec>{}(
@ -3664,8 +3647,24 @@ TYPE_PARSER(construct<StructureStmt>{}("STRUCTURE /" >> name / "/", pure(true),
construct<StructureStmt>{}( construct<StructureStmt>{}(
"STRUCTURE" >> name, pure(false), defaulted(cut >> many(entityDecl)))) "STRUCTURE" >> name, pure(false), defaulted(cut >> many(entityDecl))))
constexpr struct StructureComponents {
using resultType = DataComponentDefStmt;
static std::optional<DataComponentDefStmt> Parse(ParseState *state) {
static constexpr auto stmt = Parser<DataComponentDefStmt>{};
std::optional<DataComponentDefStmt> defs{stmt.Parse(state)};
if (defs.has_value()) {
if (auto ustate = state->userState()) {
for (const auto &decl : std::get<std::list<ComponentDecl>>(defs->t)) {
ustate->NoteStructureComponent(std::get<Name>(decl.t).source);
}
}
}
return defs;
}
} structureComponents;
TYPE_PARSER( TYPE_PARSER(
construct<StructureField>{}(statement(Parser<DataComponentDefStmt>{})) || construct<StructureField>{}(statement(structureComponents)) ||
construct<StructureField>{}(indirect(Parser<Union>{})) || construct<StructureField>{}(indirect(Parser<Union>{})) ||
construct<StructureField>{}(indirect(Parser<StructureDef>{}))) construct<StructureField>{}(indirect(Parser<StructureDef>{})))

View file

@ -27,6 +27,7 @@ public:
void NewSubprogram() { void NewSubprogram() {
doLabels_.clear(); doLabels_.clear();
nonlabelDoConstructNestingDepth_ = 0; nonlabelDoConstructNestingDepth_ = 0;
structureComponents_.clear();
} }
void EnterNonlabelDoConstruct() { ++nonlabelDoConstructNestingDepth_; } void EnterNonlabelDoConstruct() { ++nonlabelDoConstructNestingDepth_; }
void LeaveDoConstruct() { void LeaveDoConstruct() {
@ -35,18 +36,18 @@ public:
} }
} }
void NoteDefinedOperator(const CharBlock &opr) { void NoteStructureComponent(const CharBlock &name) {
definedOperators_.insert(opr); structureComponents_.insert(name);
} }
bool IsDefinedOperator(const CharBlock &opr) const { bool IsStructureComponent(const CharBlock &name) const {
return definedOperators_.find(opr) != definedOperators_.end(); return structureComponents_.find(name) != structureComponents_.end();
} }
private: private:
std::unordered_set<Label> doLabels_; std::unordered_set<Label> doLabels_;
int nonlabelDoConstructNestingDepth_{0}; int nonlabelDoConstructNestingDepth_{0};
std::set<CharBlock> definedOperators_; std::set<CharBlock> structureComponents_;
}; };
} // namespace parser } // namespace parser
} // namespace Fortran } // namespace Fortran