[flang] Really fix backslash escapes.
authorpeter klausler <pklausler@nvidia.com>
Thu, 19 Jul 2018 22:35:55 +0000 (15:35 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 19 Jul 2018 22:35:55 +0000 (15:35 -0700)
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
flang/lib/parser/characters.h
flang/lib/parser/features.h
flang/lib/parser/unparse.cc
flang/lib/parser/unparse.h
flang/lib/semantics/unparse-with-symbols.cc
flang/tools/f18/f18.cc

index bbb53be36cb6ad977066c46746d56cd7c2b80295..7885f2755fd3663c1562ef595c8ad9be67c4c2ae 100644 (file)
@@ -82,11 +82,12 @@ std::optional<std::size_t> 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;
index 736b4008b8339d1f8d84757c0db3ed42cef5863f..5559d509736102bda7d7f12f985d3eea3cb084e2 100644 (file)
@@ -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<int> UTF8CharacterBytes(const char *);
 std::optional<int> EUC_JPCharacterBytes(const char *);
index 794137d0f221bbb4b69958a6216330e962b3e919..bf5ed6ed425860be46dbde35886de6d5a12707c2 100644 (file)
@@ -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);
   }
index 73ca7407ca76f4e588d058a7ac65940ea44f0875..6bc5a64346b1cfecc8c0abb213881412bfd43a37 100644 (file)
@@ -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<std::string>(x.t)));
+    Put(QuoteCharacterLiteral(
+        std::get<std::string>(x.t), true, backslashEscapes_));
   }
   void Before(const HollerithLiteralConstant &x) {
     std::optional<std::size_t> 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<format::FormatItem> &y) {
                      Walk("(", y, ",", ")");
@@ -2205,6 +2208,7 @@ private:
   std::set<CharBlock> 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();
 }
index 847c493dc1996f27d1743069f917eaad29d38b34..11b2a0f6af7e3df21a7432ed680f719a55fa8ff2 100644 (file)
@@ -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
 
index 62f3d9c2ab861f82369f13966242017995b5684f..aeb07c57576f11f62bad1293629883332a8d0f8d 100644 (file)
@@ -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
index 2666dd306825ffbc57de1cbcfdb6576e3ed9f7b9..9cd2afc9ff06b5dd7d28d5bd44ece62ba914229f 100644 (file)
@@ -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") {