[flang] Move features.h from parser to common

Which features are enabled and disabled applies to more than just the
parser, so move that functionality to `common`.

Original-commit: flang-compiler/f18@98b3240efc
Reviewed-on: https://github.com/flang-compiler/f18/pull/815
Tree-same-pre-rewrite: false
This commit is contained in:
Tim Keith 2019-11-06 11:15:03 -08:00
parent e391c6f0d3
commit cae50f01ff
17 changed files with 69 additions and 64 deletions

View file

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FORTRAN_PARSER_FEATURES_H_
#define FORTRAN_PARSER_FEATURES_H_
#ifndef FORTRAN_COMMON_FEATURES_H_
#define FORTRAN_COMMON_FEATURES_H_
#include "../common/enum-set.h"
#include "../common/idioms.h"
namespace Fortran::parser {
namespace Fortran::common {
ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
FixedFormContinuationWithColumn1Ampersand, LogicalAbbreviations,
@ -64,4 +64,4 @@ private:
bool warnAll_{false};
};
}
#endif // FORTRAN_PARSER_FEATURES_H_
#endif // FORTRAN_COMMON_FEATURES_H_

View file

@ -29,11 +29,11 @@
// template functions. See parser-combinators.txt for documentation.
#include "char-block.h"
#include "features.h"
#include "message.h"
#include "parse-state.h"
#include "provenance.h"
#include "user-state.h"
#include "../common/features.h"
#include "../common/idioms.h"
#include "../common/indirection.h"
#include <cstring>

View file

@ -22,10 +22,10 @@
// and recovery during parsing!
#include "characters.h"
#include "features.h"
#include "message.h"
#include "provenance.h"
#include "user-state.h"
#include "../common/features.h"
#include "../common/idioms.h"
#include <cstddef>
#include <cstring>
@ -36,6 +36,8 @@
namespace Fortran::parser {
using common::LanguageFeature;
class ParseState {
public:
// TODO: Add a constructor for parsing a normalized module file.

View file

@ -93,7 +93,7 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
}
void Parsing::DumpCookedChars(std::ostream &out) const {
UserState userState{cooked_, LanguageFeatureControl{}};
UserState userState{cooked_, common::LanguageFeatureControl{}};
ParseState parseState{cooked_};
parseState.set_inFixedForm(options_.isFixedForm).set_userState(&userState);
while (std::optional<const char *> p{parseState.GetNextChar()}) {

View file

@ -16,11 +16,11 @@
#define FORTRAN_PARSER_PARSING_H_
#include "characters.h"
#include "features.h"
#include "instrumented-parser.h"
#include "message.h"
#include "parse-tree.h"
#include "provenance.h"
#include "../common/features.h"
#include <optional>
#include <ostream>
#include <string>
@ -36,7 +36,7 @@ struct Options {
bool isFixedForm{false};
int fixedFormColumns{72};
LanguageFeatureControl features;
common::LanguageFeatureControl features;
std::vector<std::string> searchDirectories;
std::vector<Predefinition> predefinitions;
bool instrumentedParse{false};

View file

@ -27,10 +27,12 @@
namespace Fortran::parser {
using common::LanguageFeature;
static constexpr int maxPrescannerNesting{100};
Prescanner::Prescanner(Messages &messages, CookedSource &cooked,
Preprocessor &preprocessor, LanguageFeatureControl lfc)
Preprocessor &preprocessor, common::LanguageFeatureControl lfc)
: messages_{messages}, cooked_{cooked}, preprocessor_{preprocessor},
features_{lfc}, encoding_{cooked.allSources().encoding()} {}

View file

@ -23,10 +23,10 @@
// inclusion, and driving the Fortran source preprocessor.
#include "characters.h"
#include "features.h"
#include "message.h"
#include "provenance.h"
#include "token-sequence.h"
#include "../common/features.h"
#include <bitset>
#include <optional>
#include <string>
@ -39,8 +39,8 @@ class Preprocessor;
class Prescanner {
public:
Prescanner(
Messages &, CookedSource &, Preprocessor &, LanguageFeatureControl);
Prescanner(Messages &, CookedSource &, Preprocessor &,
common::LanguageFeatureControl);
Prescanner(const Prescanner &);
Messages &messages() const { return messages_; }
@ -145,7 +145,8 @@ private:
return p[0] == '/' && p[1] == '*' &&
(inPreprocessorDirective_ ||
(!inCharLiteral_ &&
features_.IsEnabled(LanguageFeature::ClassicCComments)));
features_.IsEnabled(
common::LanguageFeature::ClassicCComments)));
}
void LabelField(TokenSequence &, int outCol = 1);
@ -184,7 +185,7 @@ private:
Messages &messages_;
CookedSource &cooked_;
Preprocessor &preprocessor_;
LanguageFeatureControl features_;
common::LanguageFeatureControl features_;
bool inFixedForm_{false};
int fixedFormColumnLimit_{72};
Encoding encoding_{Encoding::UTF_8};

View file

@ -1,4 +1,4 @@
// 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.
@ -21,8 +21,8 @@
// state in static data.
#include "char-block.h"
#include "features.h"
#include "parse-tree.h"
#include "../common/features.h"
#include "../common/idioms.h"
#include <cinttypes>
#include <optional>
@ -40,11 +40,11 @@ class Success {}; // for when one must return something that's present
class UserState {
public:
UserState(const CookedSource &cooked, LanguageFeatureControl features)
UserState(const CookedSource &cooked, common::LanguageFeatureControl features)
: cooked_{cooked}, features_{features} {}
const CookedSource &cooked() const { return cooked_; }
const LanguageFeatureControl &features() const { return features_; }
const common::LanguageFeatureControl &features() const { return features_; }
std::ostream *debugOutput() const { return debugOutput_; }
UserState &set_debugOutput(std::ostream *out) {
@ -107,7 +107,7 @@ private:
std::set<CharBlock> oldStructureComponents_;
LanguageFeatureControl features_;
common::LanguageFeatureControl features_;
};
// Definitions of parser classes that manipulate the UserState.

View file

@ -353,7 +353,7 @@ private:
void CheckDoControl(const parser::CharBlock &sourceLocation, bool isReal) {
const bool warn{context_.warnOnNonstandardUsage() ||
context_.ShouldWarn(parser::LanguageFeature::RealDoControls)};
context_.ShouldWarn(common::LanguageFeature::RealDoControls)};
if (isReal && !warn) {
// No messages for the default case
} else if (isReal && warn) {

View file

@ -383,10 +383,10 @@ struct IntTypeVisitor {
if (T::kind > kind) {
if (!isDefaultKind ||
!analyzer.context().IsEnabled(
parser::LanguageFeature::BigIntLiterals)) {
common::LanguageFeature::BigIntLiterals)) {
return std::nullopt;
} else if (analyzer.context().ShouldWarn(
parser::LanguageFeature::BigIntLiterals)) {
common::LanguageFeature::BigIntLiterals)) {
analyzer.Say(digits,
"Integer literal is too large for default INTEGER(KIND=%d); "
"assuming INTEGER(KIND=%d)"_en_US,
@ -1345,13 +1345,13 @@ MaybeExpr ExpressionAnalyzer::Analyze(
// T(1) or T(PT=PT(1)).
if (nextAnonymous == components.begin() && parentComponent != nullptr &&
valueType == DynamicType::From(*parentComponent) &&
context().IsEnabled(parser::LanguageFeature::AnonymousParents)) {
context().IsEnabled(common::LanguageFeature::AnonymousParents)) {
auto iter{
std::find(components.begin(), components.end(), *parentComponent)};
if (iter != components.end()) {
symbol = parentComponent;
nextAnonymous = ++iter;
if (context().ShouldWarn(parser::LanguageFeature::AnonymousParents)) {
if (context().ShouldWarn(common::LanguageFeature::AnonymousParents)) {
Say(source,
"Whole parent component '%s' in structure "
"constructor should not be anonymous"_en_US,

View file

@ -759,7 +759,7 @@ Scope *ModFileReader::Read(const SourceName &name, Scope *ancestor) {
parser::Parsing parsing{context_.allSources()};
parser::Options options;
options.isModuleFile = true;
options.features.Enable(parser::LanguageFeature::BackslashEscapes);
options.features.Enable(common::LanguageFeature::BackslashEscapes);
options.searchDirectories = context_.searchDirectories();
auto path{ModFileName(name, ancestorName, context_.moduleFileSuffix())};
const auto *sourceFile{parsing.Prescan(path, options)};

View file

@ -900,7 +900,7 @@ void CheckLabelDoConstraints(const SourceStmtList &dos,
ParentScope(scopes, doTarget.proxyForScope) == scope)) {
if (context.warnOnNonstandardUsage() ||
context.ShouldWarn(
parser::LanguageFeature::OldLabelDoEndStatements)) {
common::LanguageFeature::OldLabelDoEndStatements)) {
context
.Say(position,
parser::MessageFormattedText{

View file

@ -16,13 +16,13 @@
#include "expression.h"
#include "semantics.h"
#include "tools.h"
#include "../common/features.h"
#include "../common/idioms.h"
#include "../common/indirection.h"
#include "../evaluate/fold.h"
#include "../evaluate/tools.h"
#include "../evaluate/type.h"
#include "../parser/char-block.h"
#include "../parser/features.h"
#include "../parser/parse-tree.h"
#include <initializer_list>
#include <ostream>
@ -30,6 +30,7 @@
namespace Fortran::semantics {
using common::LanguageFeature;
using IntrinsicOperator = parser::DefinedOperator::IntrinsicOperator;
static GenericKind MapIntrinsicOperator(IntrinsicOperator);
@ -64,11 +65,10 @@ bool IsIntrinsicOperator(
if (intrinsics.count(str) > 0) {
return true;
}
if (context.IsEnabled(parser::LanguageFeature::XOROperator) &&
str == ".xor.") {
if (context.IsEnabled(LanguageFeature::XOROperator) && str == ".xor.") {
return true;
}
if (context.IsEnabled(parser::LanguageFeature::LogicalAbbreviations) &&
if (context.IsEnabled(LanguageFeature::LogicalAbbreviations) &&
(str == ".n." || str == ".a" || str == ".o." || str == ".x.")) {
return true;
}
@ -79,7 +79,7 @@ bool IsLogicalConstant(
const SemanticsContext &context, const SourceName &name) {
std::string str{name.ToString()};
return str == ".true." || str == ".false." ||
(context.IsEnabled(parser::LanguageFeature::LogicalAbbreviations) &&
(context.IsEnabled(LanguageFeature::LogicalAbbreviations) &&
(str == ".t" || str == ".f."));
}
@ -400,7 +400,7 @@ bool EquivalenceSets::CheckCanEquivalence(
} else if (isNum1) {
if (isChar2) {
if (context_.ShouldWarn(
parser::LanguageFeature::EquivalenceNumericWithCharacter)) {
LanguageFeature::EquivalenceNumericWithCharacter)) {
msg = "Equivalence set contains '%s' that is numeric sequence "
"type and '%s' that is character"_en_US;
}
@ -411,7 +411,7 @@ bool EquivalenceSets::CheckCanEquivalence(
} else if (isChar1) {
if (isNum2) {
if (context_.ShouldWarn(
parser::LanguageFeature::EquivalenceNumericWithCharacter)) {
LanguageFeature::EquivalenceNumericWithCharacter)) {
msg = "Equivalence set contains '%s' that is character sequence "
"type and '%s' that is numeric"_en_US;
}

View file

@ -130,7 +130,7 @@ static bool PerformStatementSemantics(
SemanticsContext::SemanticsContext(
const common::IntrinsicTypeDefaultKinds &defaultKinds,
const parser::LanguageFeatureControl &languageFeatures,
const common::LanguageFeatureControl &languageFeatures,
parser::AllSources &allSources)
: defaultKinds_{defaultKinds}, languageFeatures_{languageFeatures},
allSources_{allSources},
@ -144,11 +144,11 @@ int SemanticsContext::GetDefaultKind(TypeCategory category) const {
return defaultKinds_.GetDefaultKind(category);
}
bool SemanticsContext::IsEnabled(parser::LanguageFeature feature) const {
bool SemanticsContext::IsEnabled(common::LanguageFeature feature) const {
return languageFeatures_.IsEnabled(feature);
}
bool SemanticsContext::ShouldWarn(parser::LanguageFeature feature) const {
bool SemanticsContext::ShouldWarn(common::LanguageFeature feature) const {
return languageFeatures_.ShouldWarn(feature);
}

View file

@ -16,9 +16,9 @@
#define FORTRAN_SEMANTICS_SEMANTICS_H_
#include "scope.h"
#include "../common/features.h"
#include "../evaluate/common.h"
#include "../evaluate/intrinsics.h"
#include "../parser/features.h"
#include "../parser/message.h"
#include <iosfwd>
#include <string>
@ -60,7 +60,7 @@ using ConstructStack = std::vector<ConstructNode>;
class SemanticsContext {
public:
SemanticsContext(const common::IntrinsicTypeDefaultKinds &,
const parser::LanguageFeatureControl &, parser::AllSources &);
const common::LanguageFeatureControl &, parser::AllSources &);
~SemanticsContext();
const common::IntrinsicTypeDefaultKinds &defaultKinds() const {
@ -71,8 +71,8 @@ public:
return defaultKinds_.doublePrecisionKind();
}
int quadPrecisionKind() const { return defaultKinds_.quadPrecisionKind(); }
bool IsEnabled(parser::LanguageFeature) const;
bool ShouldWarn(parser::LanguageFeature) const;
bool IsEnabled(common::LanguageFeature) const;
bool ShouldWarn(common::LanguageFeature) const;
const std::optional<parser::CharBlock> &location() const { return location_; }
const std::vector<std::string> &searchDirectories() const {
return searchDirectories_;
@ -147,7 +147,7 @@ public:
private:
const common::IntrinsicTypeDefaultKinds &defaultKinds_;
const parser::LanguageFeatureControl languageFeatures_;
const common::LanguageFeatureControl languageFeatures_;
parser::AllSources &allSources_;
std::optional<parser::CharBlock> location_;
std::vector<std::string> searchDirectories_;

View file

@ -28,9 +28,9 @@
// F18 compiler under development.
#include "../../lib/common/default-kinds.h"
#include "../../lib/common/features.h"
#include "../../lib/parser/characters.h"
#include "../../lib/parser/dump-parse-tree.h"
#include "../../lib/parser/features.h"
#include "../../lib/parser/message.h"
#include "../../lib/parser/parse-tree-visitor.h"
#include "../../lib/parser/parse-tree.h"
@ -226,7 +226,7 @@ std::string CompileFortran(
if (driver.dumpUnparse) {
Unparse(std::cout, parseTree, driver.encoding, true /*capitalize*/,
options.features.IsEnabled(
Fortran::parser::LanguageFeature::BackslashEscapes));
Fortran::common::LanguageFeature::BackslashEscapes));
return {};
}
if (driver.parseOnly) {
@ -243,7 +243,7 @@ std::string CompileFortran(
tmpSource.open(tmpSourcePath);
Unparse(tmpSource, parseTree, driver.encoding, true /*capitalize*/,
options.features.IsEnabled(
Fortran::parser::LanguageFeature::BackslashEscapes));
Fortran::common::LanguageFeature::BackslashEscapes));
}
if (ParentProcess()) {
@ -308,7 +308,7 @@ int main(int argc, char *const argv[]) {
options.predefinitions.emplace_back("__F18_PATCHLEVEL__", "1");
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes, true);
Fortran::common::LanguageFeature::BackslashEscapes, true);
Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;
@ -356,27 +356,27 @@ int main(int argc, char *const argv[]) {
options.fixedFormColumns = 132;
} else if (arg == "-Mbackslash") {
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes, false);
Fortran::common::LanguageFeature::BackslashEscapes, false);
} else if (arg == "-Mnobackslash") {
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes);
Fortran::common::LanguageFeature::BackslashEscapes);
} else if (arg == "-Mstandard") {
driver.warnOnNonstandardUsage = true;
} else if (arg == "-fopenmp") {
options.features.Enable(Fortran::parser::LanguageFeature::OpenMP);
options.features.Enable(Fortran::common::LanguageFeature::OpenMP);
options.predefinitions.emplace_back("_OPENMP", "201511");
} else if (arg == "-Werror") {
driver.warningsAreErrors = true;
} else if (arg == "-ed") {
options.features.Enable(Fortran::parser::LanguageFeature::OldDebugLines);
options.features.Enable(Fortran::common::LanguageFeature::OldDebugLines);
} else if (arg == "-E" || arg == "-fpreprocess-only") {
driver.dumpCookedChars = true;
} else if (arg == "-fbackslash") {
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes);
Fortran::common::LanguageFeature::BackslashEscapes);
} else if (arg == "-fno-backslash") {
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes, false);
Fortran::common::LanguageFeature::BackslashEscapes, false);
} else if (arg == "-fdump-provenance") {
driver.dumpProvenance = true;
} else if (arg == "-fdump-parse-tree") {
@ -451,7 +451,7 @@ int main(int argc, char *const argv[]) {
options.features.WarnOnAllNonstandard();
}
if (!options.features.IsEnabled(
Fortran::parser::LanguageFeature::BackslashEscapes)) {
Fortran::common::LanguageFeature::BackslashEscapes)) {
driver.fcArgs.push_back("-fno-backslash"); // PGI "-Mbackslash"
}

View file

@ -15,10 +15,10 @@
// Temporary Fortran front end driver main program for development scaffolding.
#include "../../lib/common/default-kinds.h"
#include "../../lib/common/features.h"
#include "../../lib/evaluate/expression.h"
#include "../../lib/parser/characters.h"
#include "../../lib/parser/dump-parse-tree.h"
#include "../../lib/parser/features.h"
#include "../../lib/parser/message.h"
#include "../../lib/parser/parse-tree-visitor.h"
#include "../../lib/parser/parse-tree.h"
@ -301,7 +301,7 @@ std::string CompileFortran(std::string path, Fortran::parser::Options options,
if (driver.dumpUnparse) {
Unparse(std::cout, parseTree, driver.encoding, true /*capitalize*/,
options.features.IsEnabled(
Fortran::parser::LanguageFeature::BackslashEscapes),
Fortran::common::LanguageFeature::BackslashEscapes),
nullptr /* action before each statement */, &unparseExpression);
return {};
}
@ -320,7 +320,7 @@ std::string CompileFortran(std::string path, Fortran::parser::Options options,
Fortran::evaluate::formatForPGF90 = true;
Unparse(tmpSource, parseTree, driver.encoding, true /*capitalize*/,
options.features.IsEnabled(
Fortran::parser::LanguageFeature::BackslashEscapes),
Fortran::common::LanguageFeature::BackslashEscapes),
nullptr /* action before each statement */,
driver.unparseTypedExprsToPGF90 ? &unparseExpression : nullptr);
Fortran::evaluate::formatForPGF90 = false;
@ -437,27 +437,27 @@ int main(int argc, char *const argv[]) {
options.fixedFormColumns = 132;
} else if (arg == "-Mbackslash") {
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes, false);
Fortran::common::LanguageFeature::BackslashEscapes, false);
} else if (arg == "-Mnobackslash") {
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes, true);
Fortran::common::LanguageFeature::BackslashEscapes, true);
} else if (arg == "-Mstandard") {
driver.warnOnNonstandardUsage = true;
} else if (arg == "-fopenmp") {
options.features.Enable(Fortran::parser::LanguageFeature::OpenMP);
options.features.Enable(Fortran::common::LanguageFeature::OpenMP);
options.predefinitions.emplace_back("_OPENMP", "201511");
} else if (arg == "-Werror") {
driver.warningsAreErrors = true;
} else if (arg == "-ed") {
options.features.Enable(Fortran::parser::LanguageFeature::OldDebugLines);
options.features.Enable(Fortran::common::LanguageFeature::OldDebugLines);
} else if (arg == "-E") {
driver.dumpCookedChars = true;
} else if (arg == "-fbackslash" || arg == "-fno-backslash") {
options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes,
Fortran::common::LanguageFeature::BackslashEscapes,
arg == "-fbackslash");
} else if (arg == "-fxor-operator" || arg == "-fno-xor-operator") {
options.features.Enable(Fortran::parser::LanguageFeature::XOROperator,
options.features.Enable(Fortran::common::LanguageFeature::XOROperator,
arg == "-fxor-operator");
} else if (arg == "-fdebug-dump-provenance") {
driver.dumpProvenance = true;
@ -591,12 +591,12 @@ int main(int argc, char *const argv[]) {
if (driver.warnOnNonstandardUsage) {
options.features.WarnOnAllNonstandard();
}
if (options.features.IsEnabled(Fortran::parser::LanguageFeature::OpenMP)) {
if (options.features.IsEnabled(Fortran::common::LanguageFeature::OpenMP)) {
driver.pgf90Args.push_back("-mp");
}
if (isPGF90) {
if (!options.features.IsEnabled(
Fortran::parser::LanguageFeature::BackslashEscapes)) {
Fortran::common::LanguageFeature::BackslashEscapes)) {
driver.pgf90Args.push_back(
"-Mbackslash"); // yes, this *disables* them in pgf90
}