From 888786b3465f4daff9c281f463d5ee0dd9ef0366 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Thu, 19 Jul 2018 15:35:55 -0700 Subject: [PATCH] [flang] Really fix backslash escapes. Original-commit: flang-compiler/f18@a8c702c103fad51c9a1fb59d4088d9c037b778bd Reviewed-on: https://github.com/flang-compiler/f18/pull/133 Tree-same-pre-rewrite: false --- flang/lib/parser/characters.cc | 5 +++-- flang/lib/parser/characters.h | 3 ++- flang/lib/parser/features.h | 4 +++- flang/lib/parser/unparse.cc | 18 ++++++++++++------ flang/lib/parser/unparse.h | 2 +- flang/lib/semantics/unparse-with-symbols.cc | 2 +- flang/tools/f18/f18.cc | 10 ++++++++-- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/flang/lib/parser/characters.cc b/flang/lib/parser/characters.cc index bbb53be36cb6..7885f2755fd3 100644 --- a/flang/lib/parser/characters.cc +++ b/flang/lib/parser/characters.cc @@ -82,11 +82,12 @@ std::optional CountCharacters( return {chars}; } -std::string QuoteCharacterLiteral(const std::string &str) { +std::string QuoteCharacterLiteral( + const std::string &str, bool doubleDoubleQuotes, bool backslashEscapes) { std::string result{'"'}; const auto emit{[&](char ch) { result += ch; }}; for (char ch : str) { - EmitQuotedChar(ch, emit, emit); + EmitQuotedChar(ch, emit, emit, doubleDoubleQuotes, backslashEscapes); } result += '"'; return result; diff --git a/flang/lib/parser/characters.h b/flang/lib/parser/characters.h index 736b4008b833..5559d5097361 100644 --- a/flang/lib/parser/characters.h +++ b/flang/lib/parser/characters.h @@ -161,7 +161,8 @@ void EmitQuotedChar(char ch, const NORMAL &emit, const INSERTED &insert, } } -std::string QuoteCharacterLiteral(const std::string &); +std::string QuoteCharacterLiteral(const std::string &, + bool doubleDoubleQuotes = true, bool backslashEscapes = true); std::optional UTF8CharacterBytes(const char *); std::optional EUC_JPCharacterBytes(const char *); diff --git a/flang/lib/parser/features.h b/flang/lib/parser/features.h index 794137d0f221..bf5ed6ed4258 100644 --- a/flang/lib/parser/features.h +++ b/flang/lib/parser/features.h @@ -39,7 +39,9 @@ public: // These features must be explicitly enabled by command line options. disable_.set(LanguageFeature::OldDebugLines); disable_.set(LanguageFeature::OpenMP); - // These features, if enabled, conflict with valid standard usage. + // These features, if enabled, conflict with valid standard usage, + // so there are disabled here by default. + disable_.set(LanguageFeature::BackslashEscapes); disable_.set(LanguageFeature::LogicalAbbreviations); disable_.set(LanguageFeature::XOROperator); } diff --git a/flang/lib/parser/unparse.cc b/flang/lib/parser/unparse.cc index 73ca7407ca76..6bc5a64346b1 100644 --- a/flang/lib/parser/unparse.cc +++ b/flang/lib/parser/unparse.cc @@ -31,9 +31,10 @@ namespace Fortran::parser { class UnparseVisitor { public: UnparseVisitor(std::ostream &out, int indentationAmount, Encoding encoding, - bool capitalize, preStatementType *preStatement) + bool capitalize, bool backslashEscapes, preStatementType *preStatement) : out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding}, - capitalizeKeywords_{capitalize}, preStatement_{preStatement} {} + capitalizeKeywords_{capitalize}, backslashEscapes_{backslashEscapes}, + preStatement_{preStatement} {} // In nearly all cases, this code avoids defining Boolean-valued Pre() // callbacks for the parse tree walking framework in favor of two void @@ -181,7 +182,8 @@ public: Walk(*k), Put('_'); } } - Put(QuoteCharacterLiteral(std::get(x.t))); + Put(QuoteCharacterLiteral( + std::get(x.t), true, backslashEscapes_)); } void Before(const HollerithLiteralConstant &x) { std::optional chars{CountCharacters(x.v.data(), x.v.size(), @@ -1352,7 +1354,8 @@ public: Walk(*x.repeatCount); } std::visit(common::visitors{[&](const std::string &y) { - Put(QuoteCharacterLiteral(y)); + Put(QuoteCharacterLiteral( + y, true, backslashEscapes_)); }, [&](const std::list &y) { Walk("(", y, ",", ")"); @@ -2205,6 +2208,7 @@ private: std::set structureComponents_; Encoding encoding_{Encoding::UTF8}; bool capitalizeKeywords_{true}; + bool backslashEscapes_{false}; preStatementType *preStatement_{nullptr}; }; @@ -2259,8 +2263,10 @@ void UnparseVisitor::Word(const char *str) { void UnparseVisitor::Word(const std::string &str) { Word(str.c_str()); } void Unparse(std::ostream &out, const Program &program, Encoding encoding, - bool capitalizeKeywords, preStatementType *preStatement) { - UnparseVisitor visitor{out, 1, encoding, capitalizeKeywords, preStatement}; + bool capitalizeKeywords, bool backslashEscapes, + preStatementType *preStatement) { + UnparseVisitor visitor{ + out, 1, encoding, capitalizeKeywords, backslashEscapes, preStatement}; Walk(program, visitor); visitor.Done(); } diff --git a/flang/lib/parser/unparse.h b/flang/lib/parser/unparse.h index 847c493dc199..11b2a0f6af7e 100644 --- a/flang/lib/parser/unparse.h +++ b/flang/lib/parser/unparse.h @@ -31,7 +31,7 @@ using preStatementType = /// Convert parsed program to out as Fortran. void Unparse(std::ostream &out, const Program &program, Encoding encoding = Encoding::UTF8, bool capitalizeKeywords = true, - preStatementType *preStatement = nullptr); + bool backslashEscapes = true, preStatementType *preStatement = nullptr); } // namespace Fortran::parser diff --git a/flang/lib/semantics/unparse-with-symbols.cc b/flang/lib/semantics/unparse-with-symbols.cc index 62f3d9c2ab86..aeb07c57576f 100644 --- a/flang/lib/semantics/unparse-with-symbols.cc +++ b/flang/lib/semantics/unparse-with-symbols.cc @@ -148,7 +148,7 @@ void UnparseWithSymbols(std::ostream &out, const parser::Program &program, [&](const parser::CharBlock &location, std::ostream &out, int indent) { visitor.PrintSymbols(location, out, indent); }}; - parser::Unparse(out, program, encoding, false, &preStatement); + parser::Unparse(out, program, encoding, false, true, &preStatement); } } // namespace Fortran::semantics diff --git a/flang/tools/f18/f18.cc b/flang/tools/f18/f18.cc index 2666dd306825..9cd2afc9ff06 100644 --- a/flang/tools/f18/f18.cc +++ b/flang/tools/f18/f18.cc @@ -221,7 +221,9 @@ std::string CompileFortran( Fortran::semantics::DumpTree(std::cout, parseTree); } if (driver.dumpUnparse) { - Unparse(std::cout, parseTree, driver.encoding, true /*capitalize*/); + Unparse(std::cout, parseTree, driver.encoding, true /*capitalize*/, + options.features.IsEnabled( + Fortran::parser::LanguageFeature::BackslashEscapes)); return {}; } if (driver.parseOnly) { @@ -236,7 +238,9 @@ std::string CompileFortran( { std::ofstream tmpSource; tmpSource.open(tmpSourcePath); - Unparse(tmpSource, parseTree, driver.encoding); + Unparse(tmpSource, parseTree, driver.encoding, true /*capitalize*/, + options.features.IsEnabled( + Fortran::parser::LanguageFeature::BackslashEscapes)); } if (ParentProcess()) { @@ -345,6 +349,7 @@ int main(int argc, char *const argv[]) { } else if (arg == "-Mbackslash") { options.features.Enable( Fortran::parser::LanguageFeature::BackslashEscapes, false); + driver.pgf90Args.push_back(arg); } else if (arg == "-Mnobackslash") { options.features.Enable( Fortran::parser::LanguageFeature::BackslashEscapes); @@ -364,6 +369,7 @@ int main(int argc, char *const argv[]) { } else if (arg == "-fno-backslash") { options.features.Enable( Fortran::parser::LanguageFeature::BackslashEscapes, false); + driver.pgf90Args.push_back("-Mbackslash"); } else if (arg == "-fdebug-dump-provenance") { driver.dumpProvenance = true; } else if (arg == "-fdebug-dump-parse-tree") {