[flang] Really fix backslash escapes.

Original-commit: flang-compiler/f18@a8c702c103
Reviewed-on: https://github.com/flang-compiler/f18/pull/133
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2018-07-19 15:35:55 -07:00
parent d1bf9e1fe2
commit 888786b346
7 changed files with 30 additions and 14 deletions

View File

@ -82,11 +82,12 @@ std::optional<std::size_t> CountCharacters(
return {chars}; return {chars};
} }
std::string QuoteCharacterLiteral(const std::string &str) { std::string QuoteCharacterLiteral(
const std::string &str, bool doubleDoubleQuotes, bool backslashEscapes) {
std::string result{'"'}; std::string result{'"'};
const auto emit{[&](char ch) { result += ch; }}; const auto emit{[&](char ch) { result += ch; }};
for (char ch : str) { for (char ch : str) {
EmitQuotedChar(ch, emit, emit); EmitQuotedChar(ch, emit, emit, doubleDoubleQuotes, backslashEscapes);
} }
result += '"'; result += '"';
return result; return result;

View 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> UTF8CharacterBytes(const char *);
std::optional<int> EUC_JPCharacterBytes(const char *); std::optional<int> EUC_JPCharacterBytes(const char *);

View File

@ -39,7 +39,9 @@ public:
// These features must be explicitly enabled by command line options. // These features must be explicitly enabled by command line options.
disable_.set(LanguageFeature::OldDebugLines); disable_.set(LanguageFeature::OldDebugLines);
disable_.set(LanguageFeature::OpenMP); 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::LogicalAbbreviations);
disable_.set(LanguageFeature::XOROperator); disable_.set(LanguageFeature::XOROperator);
} }

View File

@ -31,9 +31,10 @@ namespace Fortran::parser {
class UnparseVisitor { class UnparseVisitor {
public: public:
UnparseVisitor(std::ostream &out, int indentationAmount, Encoding encoding, UnparseVisitor(std::ostream &out, int indentationAmount, Encoding encoding,
bool capitalize, preStatementType *preStatement) bool capitalize, bool backslashEscapes, preStatementType *preStatement)
: out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding}, : 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() // In nearly all cases, this code avoids defining Boolean-valued Pre()
// callbacks for the parse tree walking framework in favor of two void // callbacks for the parse tree walking framework in favor of two void
@ -181,7 +182,8 @@ public:
Walk(*k), Put('_'); 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) { void Before(const HollerithLiteralConstant &x) {
std::optional<std::size_t> chars{CountCharacters(x.v.data(), x.v.size(), std::optional<std::size_t> chars{CountCharacters(x.v.data(), x.v.size(),
@ -1352,7 +1354,8 @@ public:
Walk(*x.repeatCount); Walk(*x.repeatCount);
} }
std::visit(common::visitors{[&](const std::string &y) { std::visit(common::visitors{[&](const std::string &y) {
Put(QuoteCharacterLiteral(y)); Put(QuoteCharacterLiteral(
y, true, backslashEscapes_));
}, },
[&](const std::list<format::FormatItem> &y) { [&](const std::list<format::FormatItem> &y) {
Walk("(", y, ",", ")"); Walk("(", y, ",", ")");
@ -2205,6 +2208,7 @@ private:
std::set<CharBlock> structureComponents_; std::set<CharBlock> structureComponents_;
Encoding encoding_{Encoding::UTF8}; Encoding encoding_{Encoding::UTF8};
bool capitalizeKeywords_{true}; bool capitalizeKeywords_{true};
bool backslashEscapes_{false};
preStatementType *preStatement_{nullptr}; 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 UnparseVisitor::Word(const std::string &str) { Word(str.c_str()); }
void Unparse(std::ostream &out, const Program &program, Encoding encoding, void Unparse(std::ostream &out, const Program &program, Encoding encoding,
bool capitalizeKeywords, preStatementType *preStatement) { bool capitalizeKeywords, bool backslashEscapes,
UnparseVisitor visitor{out, 1, encoding, capitalizeKeywords, preStatement}; preStatementType *preStatement) {
UnparseVisitor visitor{
out, 1, encoding, capitalizeKeywords, backslashEscapes, preStatement};
Walk(program, visitor); Walk(program, visitor);
visitor.Done(); visitor.Done();
} }

View File

@ -31,7 +31,7 @@ using preStatementType =
/// Convert parsed program to out as Fortran. /// Convert parsed program to out as Fortran.
void Unparse(std::ostream &out, const Program &program, void Unparse(std::ostream &out, const Program &program,
Encoding encoding = Encoding::UTF8, bool capitalizeKeywords = true, Encoding encoding = Encoding::UTF8, bool capitalizeKeywords = true,
preStatementType *preStatement = nullptr); bool backslashEscapes = true, preStatementType *preStatement = nullptr);
} // namespace Fortran::parser } // namespace Fortran::parser

View File

@ -148,7 +148,7 @@ void UnparseWithSymbols(std::ostream &out, const parser::Program &program,
[&](const parser::CharBlock &location, std::ostream &out, int indent) { [&](const parser::CharBlock &location, std::ostream &out, int indent) {
visitor.PrintSymbols(location, out, indent); visitor.PrintSymbols(location, out, indent);
}}; }};
parser::Unparse(out, program, encoding, false, &preStatement); parser::Unparse(out, program, encoding, false, true, &preStatement);
} }
} // namespace Fortran::semantics } // namespace Fortran::semantics

View File

@ -221,7 +221,9 @@ std::string CompileFortran(
Fortran::semantics::DumpTree(std::cout, parseTree); Fortran::semantics::DumpTree(std::cout, parseTree);
} }
if (driver.dumpUnparse) { 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 {}; return {};
} }
if (driver.parseOnly) { if (driver.parseOnly) {
@ -236,7 +238,9 @@ std::string CompileFortran(
{ {
std::ofstream tmpSource; std::ofstream tmpSource;
tmpSource.open(tmpSourcePath); tmpSource.open(tmpSourcePath);
Unparse(tmpSource, parseTree, driver.encoding); Unparse(tmpSource, parseTree, driver.encoding, true /*capitalize*/,
options.features.IsEnabled(
Fortran::parser::LanguageFeature::BackslashEscapes));
} }
if (ParentProcess()) { if (ParentProcess()) {
@ -345,6 +349,7 @@ int main(int argc, char *const argv[]) {
} else if (arg == "-Mbackslash") { } else if (arg == "-Mbackslash") {
options.features.Enable( options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes, false); Fortran::parser::LanguageFeature::BackslashEscapes, false);
driver.pgf90Args.push_back(arg);
} else if (arg == "-Mnobackslash") { } else if (arg == "-Mnobackslash") {
options.features.Enable( options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes); Fortran::parser::LanguageFeature::BackslashEscapes);
@ -364,6 +369,7 @@ int main(int argc, char *const argv[]) {
} else if (arg == "-fno-backslash") { } else if (arg == "-fno-backslash") {
options.features.Enable( options.features.Enable(
Fortran::parser::LanguageFeature::BackslashEscapes, false); Fortran::parser::LanguageFeature::BackslashEscapes, false);
driver.pgf90Args.push_back("-Mbackslash");
} else if (arg == "-fdebug-dump-provenance") { } else if (arg == "-fdebug-dump-provenance") {
driver.dumpProvenance = true; driver.dumpProvenance = true;
} else if (arg == "-fdebug-dump-parse-tree") { } else if (arg == "-fdebug-dump-parse-tree") {