From: peter klausler Date: Mon, 9 Jul 2018 19:46:51 +0000 (-0700) Subject: [flang] Refine variable structure definitions, add references to Standard. X-Git-Tag: llvmorg-12-init~9537^2~2414 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=74b12f1a314f76781ebfa410c2bcd8b3ff91560e;p=platform%2Fupstream%2Fllvm.git [flang] Refine variable structure definitions, add references to Standard. Original-commit: flang-compiler/f18@dbc6d45e02ded14d01ac856857e3e45b4cc0aa1a Reviewed-on: https://github.com/flang-compiler/f18/pull/117 Tree-same-pre-rewrite: false --- diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 3c985c4..57f3e0e 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -92,6 +92,7 @@ template struct Expr { struct Power : public Bin { using Bin::Bin; }; + // TODO: R916 type-param-inquiry CLASS_BOILERPLATE(Expr) Expr(const Constant &x) : u{x} {} diff --git a/flang/lib/evaluate/type.h b/flang/lib/evaluate/type.h index 04fa0d5..f17b891 100644 --- a/flang/lib/evaluate/type.h +++ b/flang/lib/evaluate/type.h @@ -115,6 +115,8 @@ using DefaultComplex = typename DefaultReal::Complex; using DefaultLogical = Type; using DefaultCharacter = Type; +using SubscriptInteger = Type; + // These templates create instances of std::variant<> that can contain // applications of some class template to all of the supported kinds of // a category of intrinsic type. diff --git a/flang/lib/evaluate/variable.cc b/flang/lib/evaluate/variable.cc index b78ec79..6d67d4d 100644 --- a/flang/lib/evaluate/variable.cc +++ b/flang/lib/evaluate/variable.cc @@ -21,16 +21,17 @@ namespace Fortran::evaluate { -Triplet::Triplet(std::optional &&l, - std::optional &&u, std::optional &&s) { +Triplet::Triplet(std::optional &&l, + std::optional &&u, + std::optional &&s) { if (l.has_value()) { - lower = SubscriptExpr{std::move(*l)}; + lower = SubscriptIntegerExpr{std::move(*l)}; } if (u.has_value()) { - upper = SubscriptExpr{std::move(*u)}; + upper = SubscriptIntegerExpr{std::move(*u)}; } if (s.has_value()) { - stride = SubscriptExpr{std::move(*s)}; + stride = SubscriptIntegerExpr{std::move(*s)}; } } @@ -114,15 +115,29 @@ std::ostream &ArrayRef::Dump(std::ostream &o) const { } std::ostream &CoarrayRef::Dump(std::ostream &o) const { - Emit(o, u); - char separator{'['}; - for (const SubscriptExpr &css : cosubscript) { + for (const Symbol *sym : base) { + Emit(o, *sym); + } + char separator{'('}; + for (const SubscriptIntegerExpr &ss : subscript) { + Emit(o << separator, ss); + separator = ','; + } + if (separator == ',') { + o << ')'; + } + separator = '['; + for (const SubscriptIntegerExpr &css : cosubscript) { Emit(o << separator, css); separator = ','; } - Emit(o, stat, "STAT="); - Emit(o, team, "TEAM="); - Emit(o, teamNumber, "TEAM_NUMBER="); + if (stat.has_value()) { + Emit(o << separator, stat, "STAT="); + separator = ','; + } + if (team.has_value()) { + Emit(o << separator, team, teamIsTeamNumber ? "TEAM_NUMBER=" : "TEAM="); + } return o << ']'; } diff --git a/flang/lib/evaluate/variable.h b/flang/lib/evaluate/variable.h index cb3ac62..5df4741 100644 --- a/flang/lib/evaluate/variable.h +++ b/flang/lib/evaluate/variable.h @@ -15,6 +15,12 @@ #ifndef FORTRAN_EVALUATE_VARIABLE_H_ #define FORTRAN_EVALUATE_VARIABLE_H_ +// Defines data structures to represent data access and function calls +// for use in expressions and assignment statements. Both copy and move +// semantics are supported. The representation adheres closely to the +// Fortran 2018 language standard (q.v.) and uses strong typing to ensure +// that only admissable combinations can be constructed. + #include "common.h" #include "expression-forward.h" #include "../common/idioms.h" @@ -29,9 +35,21 @@ namespace Fortran::evaluate { using semantics::Symbol; -// TODO: Reference sections in the Standard - +// Forward declarations struct DataRef; +struct Variable; +struct ActualFunctionArg; + +// Subscript and cosubscript expressions are of a kind that matches the +// address size, at least at the top level. +using SubscriptIntegerExpr = + common::Indirection>; + +// R913 structure-component & C920: Defined to be a multi-part +// data-ref whose last part has no subscripts (or image-selector, although +// that isn't explicit in the document). Pointer and allocatable components +// are not explicitly indirected in this representation. +// Complex components (%RE, %IM) are isolated below in ComplexPart. struct Component { CLASS_BOILERPLATE(Component) Component(const DataRef &b, const Symbol &c) : base{b}, sym{&c} {} @@ -41,24 +59,30 @@ struct Component { const Symbol *sym; }; -using SubscriptExpr = common::Indirection; - +// R921 subscript-triplet struct Triplet { CLASS_BOILERPLATE(Triplet) - Triplet(std::optional &&, std::optional &&, - std::optional &&); - std::optional lower, upper, stride; + Triplet(std::optional &&, + std::optional &&, + std::optional &&); + std::optional lower, upper, stride; }; +// R919 subscript when rank 0, R923 vector-subscript when rank 1 struct Subscript { CLASS_BOILERPLATE(Subscript) - explicit Subscript(const SubscriptExpr &s) : u{s} {} - explicit Subscript(SubscriptExpr &&s) : u{std::move(s)} {} + explicit Subscript(const SubscriptIntegerExpr &s) : u{s} {} + explicit Subscript(SubscriptIntegerExpr &&s) : u{std::move(s)} {} explicit Subscript(const Triplet &t) : u{t} {} explicit Subscript(Triplet &&t) : u{std::move(t)} {} - std::variant u; + std::variant u; }; +// R917 array-element, R918 array-section; however, the case of an +// array-section that is a complex-part-designator is represented here +// as a ComplexPart instead. C919 & C925 require that at most one set of +// subscripts have rank greater than 0, but that is not explicit in +// these types. struct ArrayRef { CLASS_BOILERPLATE(ArrayRef) ArrayRef(const Symbol &n, std::vector &&ss) @@ -69,41 +93,59 @@ struct ArrayRef { std::vector subscript; }; -struct Variable; +// R914 coindexed-named-object +// R924 image-selector, R926 image-selector-spec. +// C824 severely limits the usage of derived types with coarray ultimate +// components: they can't be pointers, allocatables, arrays, coarrays, or +// function results. They can be components of other derived types. +// C930 precludes having both TEAM= and TEAM_NUMBER=. +// TODO C931 prohibits the use of a coindexed object as a stat-variable. struct CoarrayRef { CLASS_BOILERPLATE(CoarrayRef) - CoarrayRef(const Symbol &n, std::vector &&s) - : u{&n}, cosubscript(std::move(s)) {} - CoarrayRef(Component &&c, std::vector &&s) - : u{std::move(c)}, cosubscript(std::move(s)) {} - CoarrayRef(ArrayRef &&a, std::vector &&s) - : u{std::move(a)}, cosubscript(std::move(s)) {} - std::variant u; - std::vector cosubscript; - std::optional> stat, team, teamNumber; + CoarrayRef(std::vector &&c, + std::vector &&ss, + std::vector &&css) + : base(std::move(c)), subscript(std::move(ss)), + cosubscript(std::move(css)) {} + std::vector base; + std::vector subscript, cosubscript; + std::optional> stat, team; + bool teamIsTeamNumber{false}; // false: TEAM=, true: TEAM_NUMBER= }; +// R911 data-ref is defined syntactically as a series of part-refs, which +// is far too expressive if the constraints are ignored. Here, the possible +// outcomes are spelled out. Note that a data-ref cannot include a terminal +// substring range or complex component designator; use R901 designator +// for that. struct DataRef { CLASS_BOILERPLATE(DataRef) explicit DataRef(const Symbol &n) : u{&n} {} explicit DataRef(Component &&c) : u{std::move(c)} {} explicit DataRef(ArrayRef &&a) : u{std::move(a)} {} - explicit DataRef(CoarrayRef &&c) : u{std::move(c)} {} + explicit DataRef(CoarrayRef &&a) : u{std::move(a)} {} std::variant u; }; +// R908 substring, R909 parent-string, R910 substring-range. +// The base object of a substring can be a literal. +// In the F2018 standard, substrings of array sections are parsed as +// variants of sections instead. struct Substring { CLASS_BOILERPLATE(Substring) - Substring(DataRef &&d, std::optional &&f, - std::optional &&l) + Substring(DataRef &&d, std::optional &&f, + std::optional &&l) : u{std::move(d)}, first{std::move(f)}, last{std::move(l)} {} - Substring(std::string &&s, std::optional &&f, - std::optional &&l) + Substring(std::string &&s, std::optional &&f, + std::optional &&l) : u{std::move(s)}, first{std::move(f)}, last{std::move(l)} {} std::variant u; - std::optional first, last; + std::optional first, last; }; +// R915 complex-part-designator +// In the F2018 standard, complex parts of array sections are parsed as +// variants of sections instead. struct ComplexPart { ENUM_CLASS(Part, RE, IM) CLASS_BOILERPLATE(ComplexPart) @@ -112,6 +154,8 @@ struct ComplexPart { Part part; }; +// R901 designator is the most general data reference object, apart from +// calls to pointer-valued functions. struct Designator { CLASS_BOILERPLATE(Designator) explicit Designator(DataRef &&d) : u{std::move(d)} {} @@ -137,7 +181,6 @@ template struct ProcedureRef { std::vector argument; }; -struct ActualFunctionArg; using FunctionRef = ProcedureRef; struct Variable {