// maybe an [image-selector].
// If it's a substring, it ends with (substring-range).
TYPE_CONTEXT_PARSER("designator"_en_US,
- construct<Designator>(substring) || construct<Designator>(dataRef))
+ sourced(construct<Designator>(substring) || construct<Designator>(dataRef)))
constexpr auto percentOrDot{"%"_tok ||
// legacy VAX extension for RECORD field access
// TEAM_NUMBER = scalar-int-expr
TYPE_PARSER(construct<ImageSelectorSpec>(construct<ImageSelectorSpec::Stat>(
"STAT =" >> scalar(integer(indirect(variable))))) ||
- construct<ImageSelectorSpec>(
- construct<TeamValue>("TEAM =" >> teamValue)) ||
+ construct<ImageSelectorSpec>(construct<TeamValue>("TEAM =" >> teamValue)) ||
construct<ImageSelectorSpec>(construct<ImageSelectorSpec::Team_Number>(
"TEAM_NUMBER =" >> scalarIntExpr)))
// R1520 function-reference -> procedure-designator ( [actual-arg-spec-list] )
TYPE_CONTEXT_PARSER("function reference"_en_US,
- construct<FunctionReference>(construct<Call>(Parser<ProcedureDesignator>{},
- parenthesized(optionalList(actualArgSpec)))) /
+ construct<FunctionReference>(
+ sourced(construct<Call>(Parser<ProcedureDesignator>{},
+ parenthesized(optionalList(actualArgSpec))))) /
!"["_tok)
// R1521 call-stmt -> CALL procedure-designator [( [actual-arg-spec-list] )]
-TYPE_PARSER(
- construct<CallStmt>(construct<Call>("CALL" >> Parser<ProcedureDesignator>{},
- defaulted(parenthesized(optionalList(actualArgSpec))))))
+TYPE_PARSER(construct<CallStmt>(
+ sourced(construct<Call>("CALL" >> Parser<ProcedureDesignator>{},
+ defaulted(parenthesized(optionalList(actualArgSpec)))))))
// R1522 procedure-designator ->
// procedure-name | proc-component-ref | data-ref % binding-name
struct Designator {
UNION_CLASS_BOILERPLATE(Designator);
bool EndsInBareName() const;
+ CharBlock source;
std::variant<DataRef, Substring> u;
};
// R1520 function-reference -> procedure-designator ( [actual-arg-spec-list] )
struct Call {
TUPLE_CLASS_BOILERPLATE(Call);
+ CharBlock source;
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
};
using MaybeExpr =
std::optional<Fortran::evaluate::Expr<Fortran::evaluate::SomeType>>;
-namespace Fortran::parser {
-bool SourceLocationFindingVisitor::Pre(const Expr &x) {
- source = x.source;
- return false;
-}
-void SourceLocationFindingVisitor::Post(const CharBlock &at) { source = at; }
-}
-
// Much of the code that implements semantic analysis of expressions is
// tightly coupled with their typed representations in lib/evaluate,
// and appears here in namespace Fortran::evaluate for convenience.
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::Designator &d) {
+ auto save{GetContextualMessages().SetLocation(d.source)};
FixMisparsedSubstring(d);
// These checks have to be deferred to these "top level" data-refs where
// we can be sure that there are no following subscripts (yet).
// TODO: Actual arguments that are procedures and procedure pointers need to
// be detected and represented (they're not expressions).
// TODO: C1534: Don't allow a "restricted" specific intrinsic to be passed.
+ auto save{GetContextualMessages().SetLocation(funcRef.v.source)};
ActualArguments arguments;
for (const auto &arg :
std::get<std::list<parser::ActualArgSpec>>(funcRef.v.t)) {
struct SourceLocationFindingVisitor {
template<typename A> bool Pre(const A &) { return true; }
template<typename A> void Post(const A &) {}
- bool Pre(const Expr &);
- template<typename A> bool Pre(const Statement<A> &stmt) {
+ bool Pre(const Expr &x) {
+ source = x.source;
+ return false;
+ }
+ bool Pre(const Designator &x) {
+ source = x.source;
+ return false;
+ }
+ bool Pre(const Call &x) {
+ source = x.source;
+ return false;
+ }
+ bool Pre(const CompilerDirective &x) {
+ source = x.source;
+ return false;
+ }
+ bool Pre(const GenericSpec &x) {
+ source = x.source;
+ return false;
+ }
+ template<typename A> bool Pre(const UnlabeledStatement<A> &stmt) {
source = stmt.source;
return false;
}
- void Post(const CharBlock &);
+ void Post(const CharBlock &at) { source = at; }
CharBlock source;
};