[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};
}
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;

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> EUC_JPCharacterBytes(const char *);

View 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);
}

View 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();
}

View 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

View 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

View 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") {