diff --git a/flang/lib/parser/features.h b/flang/lib/common/features.h similarity index 95% rename from flang/lib/parser/features.h rename to flang/lib/common/features.h index 5bdae673bb95..509c1c2f4229 100644 --- a/flang/lib/parser/features.h +++ b/flang/lib/common/features.h @@ -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_ diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index 6dfb5c9b8ba6..5e73f746efc6 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -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 diff --git a/flang/lib/parser/parse-state.h b/flang/lib/parser/parse-state.h index c85a179ea49f..4ca85d16fc24 100644 --- a/flang/lib/parser/parse-state.h +++ b/flang/lib/parser/parse-state.h @@ -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 #include @@ -36,6 +36,8 @@ namespace Fortran::parser { +using common::LanguageFeature; + class ParseState { public: // TODO: Add a constructor for parsing a normalized module file. diff --git a/flang/lib/parser/parsing.cc b/flang/lib/parser/parsing.cc index 06b7b85cf2b5..99777aa8beb6 100644 --- a/flang/lib/parser/parsing.cc +++ b/flang/lib/parser/parsing.cc @@ -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 p{parseState.GetNextChar()}) { diff --git a/flang/lib/parser/parsing.h b/flang/lib/parser/parsing.h index 33cb391db127..6dfb52638e5c 100644 --- a/flang/lib/parser/parsing.h +++ b/flang/lib/parser/parsing.h @@ -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 #include #include @@ -36,7 +36,7 @@ struct Options { bool isFixedForm{false}; int fixedFormColumns{72}; - LanguageFeatureControl features; + common::LanguageFeatureControl features; std::vector searchDirectories; std::vector predefinitions; bool instrumentedParse{false}; diff --git a/flang/lib/parser/prescan.cc b/flang/lib/parser/prescan.cc index c1bdf56c599c..735061c290ba 100644 --- a/flang/lib/parser/prescan.cc +++ b/flang/lib/parser/prescan.cc @@ -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()} {} diff --git a/flang/lib/parser/prescan.h b/flang/lib/parser/prescan.h index 95bd81165c2d..5cadeee72a95 100644 --- a/flang/lib/parser/prescan.h +++ b/flang/lib/parser/prescan.h @@ -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 #include #include @@ -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}; diff --git a/flang/lib/parser/user-state.h b/flang/lib/parser/user-state.h index 539fbbd19b71..c086e6320525 100644 --- a/flang/lib/parser/user-state.h +++ b/flang/lib/parser/user-state.h @@ -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 #include @@ -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 oldStructureComponents_; - LanguageFeatureControl features_; + common::LanguageFeatureControl features_; }; // Definitions of parser classes that manipulate the UserState. diff --git a/flang/lib/semantics/check-do.cc b/flang/lib/semantics/check-do.cc index 13a9bdcb4d1a..52a00759fc10 100644 --- a/flang/lib/semantics/check-do.cc +++ b/flang/lib/semantics/check-do.cc @@ -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) { diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc index bd3f415551c5..248466ec5a78 100644 --- a/flang/lib/semantics/expression.cc +++ b/flang/lib/semantics/expression.cc @@ -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, diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index 788014d202c7..f1c26e39fe66 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -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)}; diff --git a/flang/lib/semantics/resolve-labels.cc b/flang/lib/semantics/resolve-labels.cc index 8134f77208ff..b7c97eedc818 100644 --- a/flang/lib/semantics/resolve-labels.cc +++ b/flang/lib/semantics/resolve-labels.cc @@ -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{ diff --git a/flang/lib/semantics/resolve-names-utils.cc b/flang/lib/semantics/resolve-names-utils.cc index f220743beb3e..e3cefe49433a 100644 --- a/flang/lib/semantics/resolve-names-utils.cc +++ b/flang/lib/semantics/resolve-names-utils.cc @@ -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 #include @@ -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; } diff --git a/flang/lib/semantics/semantics.cc b/flang/lib/semantics/semantics.cc index d02f3977204a..a2d14d8539e3 100644 --- a/flang/lib/semantics/semantics.cc +++ b/flang/lib/semantics/semantics.cc @@ -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); } diff --git a/flang/lib/semantics/semantics.h b/flang/lib/semantics/semantics.h index 85e208cc7268..c730c5786f0c 100644 --- a/flang/lib/semantics/semantics.h +++ b/flang/lib/semantics/semantics.h @@ -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 #include @@ -60,7 +60,7 @@ using ConstructStack = std::vector; 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 &location() const { return location_; } const std::vector &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 location_; std::vector searchDirectories_; diff --git a/flang/tools/f18/f18-parse-demo.cc b/flang/tools/f18/f18-parse-demo.cc index 1edb23a53a06..12e9e88a4a74 100644 --- a/flang/tools/f18/f18-parse-demo.cc +++ b/flang/tools/f18/f18-parse-demo.cc @@ -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" } diff --git a/flang/tools/f18/f18.cc b/flang/tools/f18/f18.cc index edbea5dec9e4..23396278f2e9 100644 --- a/flang/tools/f18/f18.cc +++ b/flang/tools/f18/f18.cc @@ -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 }