}
};
-void CanonicalizeDo(Program &program) {
+bool CanonicalizeDo(Program &program) {
CanonicalizationOfDoLoops canonicalizationOfDoLoops;
Walk(program, canonicalizationOfDoLoops);
+ return true;
}
+
}
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// logically nested) into the more structured DoConstruct (explicitly nested)
namespace Fortran::parser {
struct Program;
-void CanonicalizeDo(Program &program);
+bool CanonicalizeDo(Program &program);
}
#endif // FORTRAN_SEMANTICS_CANONICALIZE_DO_H_
static std::string GetHeader(const std::string &);
static std::size_t GetFileSize(const std::string &);
-void ModFileWriter::WriteAll() { WriteAll(context_.globalScope()); }
+bool ModFileWriter::WriteAll() {
+ WriteAll(context_.globalScope());
+ return !context_.AnyFatalError();
+}
void ModFileWriter::WriteAll(const Scope &scope) {
for (const auto &child : scope.children()) {
class ModFileWriter {
public:
ModFileWriter(SemanticsContext &context) : context_{context} {}
- void WriteAll();
+ bool WriteAll();
private:
SemanticsContext &context_;
CHECK(!GetDeclTypeSpec());
}
-void ResolveNames(SemanticsContext &context, const parser::Program &program) {
+bool ResolveNames(SemanticsContext &context, const parser::Program &program) {
ResolveNamesVisitor{context}.Walk(program);
+ return !context.AnyFatalError();
}
// Get the Name out of a GenericSpec, or nullptr if none.
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
class SemanticsContext;
-void ResolveNames(SemanticsContext &, const parser::Program &);
+bool ResolveNames(SemanticsContext &, const parser::Program &);
void DumpSymbols(std::ostream &);
+
}
#endif // FORTRAN_SEMANTICS_RESOLVE_NAMES_H_
return true;
}
-void RewriteParseTree(SemanticsContext &context, parser::Program &program) {
+bool RewriteParseTree(SemanticsContext &context, parser::Program &program) {
RewriteMutator mutator{context.messages()};
parser::Walk(program, mutator);
+ return !context.AnyFatalError();
}
+
}
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
}
namespace Fortran::semantics {
-void RewriteParseTree(SemanticsContext &, parser::Program &);
+bool RewriteParseTree(SemanticsContext &, parser::Program &);
}
#endif // FORTRAN_SEMANTICS_REWRITE_PARSE_TREE_H_
// children are visited, Leave is called after. No two checkers may have the
// same Enter or Leave function. Each checker must be constructible from
// SemanticsContext and have BaseChecker as a virtual base class.
-template<typename... C> struct SemanticsVisitor : public virtual C... {
+template<typename... C> class SemanticsVisitor : public virtual C... {
+public:
using C::Enter...;
using C::Leave...;
using BaseChecker::Enter;
using BaseChecker::Leave;
- SemanticsVisitor(SemanticsContext &context) : C{context}... {}
+ SemanticsVisitor(SemanticsContext &context)
+ : C{context}..., context_{context} {}
template<typename N> bool Pre(const N &node) {
Enter(node);
return true;
}
template<typename N> void Post(const N &node) { Leave(node); }
- void Walk(const parser::Program &program) { parser::Walk(program, *this); }
+ bool Walk(const parser::Program &program) {
+ parser::Walk(program, *this);
+ return !context_.AnyFatalError();
+ }
+
+private:
+ SemanticsContext &context_;
};
using StatementSemanticsPass1 = SemanticsVisitor<ExprChecker>;
}
bool Semantics::Perform() {
- ValidateLabels(context_.messages(), program_);
- if (AnyFatalError()) {
- return false;
- }
- parser::CanonicalizeDo(program_);
- ResolveNames(context_, program_);
- if (AnyFatalError()) {
- return false;
- }
- RewriteParseTree(context_, program_);
- if (AnyFatalError()) {
- return false;
- }
- StatementSemanticsPass1{context_}.Walk(program_);
- if (AnyFatalError()) {
- return false;
- }
- StatementSemanticsPass2{context_}.Walk(program_);
- if (AnyFatalError()) {
- return false;
- }
- ModFileWriter writer{context_};
- writer.WriteAll();
- return !AnyFatalError();
+ return ValidateLabels(context_.messages(), program_) &&
+ parser::CanonicalizeDo(program_) && // force line break
+ ResolveNames(context_, program_) &&
+ RewriteParseTree(context_, program_) &&
+ StatementSemanticsPass1{context_}.Walk(program_) &&
+ StatementSemanticsPass2{context_}.Walk(program_) &&
+ ModFileWriter{context_}.WriteAll();
}
void Semantics::EmitMessages(std::ostream &os) const {