diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -357,9 +357,15 @@ LCOMM::LCOMMType LCOMMDirectiveAlignmentType = LCOMM::NoAlignment; /// True if the target only has basename for .file directive. False if the - /// target also needs the directory along with the basename. Default to true. + /// target also needs the directory along with the basename. Defaults to true. bool HasBasenameOnlyForFileDirective = true; + /// True if the target represents string constants as mostly raw characters in + /// paired double quotation with paired double quotation marks as the escape + /// mechanism to represent a double quotation mark within the string. Defaults + /// to false. + bool HasPairedDoubleQuoteStringConstants = false; + // True if the target allows .align directives on functions. This is true for // most targets, so defaults to true. bool HasFunctionAlignment = true; @@ -697,6 +703,9 @@ bool hasBasenameOnlyForFileDirective() const { return HasBasenameOnlyForFileDirective; } + bool hasPairedDoubleQuoteStringConstants() const { + return HasPairedDoubleQuoteStringConstants; + } bool hasFunctionAlignment() const { return HasFunctionAlignment; } bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; } bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp --- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -20,6 +20,11 @@ IsLittleEndian = false; HasVisibilityOnlyWithLinkage = true; HasBasenameOnlyForFileDirective = false; + + // For XCOFF, string constant consists of any number of characters enclosed in + // "" (double quotation marks). + HasPairedDoubleQuoteStringConstants = true; + PrivateGlobalPrefix = "L.."; PrivateLabelPrefix = "L.."; SupportsQuotedNames = false; diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -60,6 +60,13 @@ unsigned UseDwarfDirectory : 1; void EmitRegisterName(int64_t Register); + void PrintQuotedString(StringRef Data, raw_ostream &OS) const; + void printDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + Optional Checksum, + Optional Source, + bool UseDwarfDirectory, + raw_svector_ostream &OS) const; void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; @@ -1039,33 +1046,53 @@ llvm_unreachable("Invalid AsmCharLiteralSyntax value!"); } -static void PrintQuotedString(StringRef Data, raw_ostream &OS) { +void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const { OS << '"'; - for (unsigned i = 0, e = Data.size(); i != e; ++i) { - unsigned char C = Data[i]; - if (C == '"' || C == '\\') { - OS << '\\' << (char)C; - continue; + if (MAI->hasPairedDoubleQuoteStringConstants()) { + for (unsigned i = 0, e = Data.size(); i != e; ++i) { + unsigned char C = Data[i]; + if (C == '"') + OS << "\"\""; + else + OS << (char)C; } + } else { + for (unsigned i = 0, e = Data.size(); i != e; ++i) { + unsigned char C = Data[i]; + if (C == '"' || C == '\\') { + OS << '\\' << (char)C; + continue; + } - if (isPrint((unsigned char)C)) { - OS << (char)C; - continue; - } + if (isPrint((unsigned char)C)) { + OS << (char)C; + continue; + } - switch (C) { - case '\b': OS << "\\b"; break; - case '\f': OS << "\\f"; break; - case '\n': OS << "\\n"; break; - case '\r': OS << "\\r"; break; - case '\t': OS << "\\t"; break; + switch (C) { + case '\b': + OS << "\\b"; + break; + case '\f': + OS << "\\f"; + break; + case '\n': + OS << "\\n"; + break; + case '\r': + OS << "\\r"; + break; + case '\t': + OS << "\\t"; + break; default: OS << '\\'; OS << toOctal(C >> 6); OS << toOctal(C >> 3); OS << toOctal(C >> 0); break; + } } } @@ -1390,12 +1417,10 @@ EmitEOL(); } -static void printDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, - Optional Checksum, - Optional Source, - bool UseDwarfDirectory, - raw_svector_ostream &OS) { +void MCAsmStreamer::printDwarfFileDirective( + unsigned FileNo, StringRef Directory, StringRef Filename, + Optional Checksum, Optional Source, + bool UseDwarfDirectory, raw_svector_ostream &OS) const { SmallString<128> FullPathName; if (!UseDwarfDirectory && !Directory.empty()) { diff --git a/llvm/test/CodeGen/PowerPC/aix-filename-special-character-double-quotation.ll b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-double-quotation.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-double-quotation.ll @@ -0,0 +1,8 @@ +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s \ +; RUN: | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff < %s \ +; RUN: | FileCheck %s + +; CHECK: .file "1""2.c" + +source_filename = "1\222.c" diff --git a/llvm/test/CodeGen/PowerPC/aix-filename-special-character-single-quotation.ll b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-single-quotation.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-single-quotation.ll @@ -0,0 +1,8 @@ +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s \ +; RUN: | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff < %s \ +; RUN: | FileCheck %s + +; CHECK: .file "1'2.c" + +source_filename = "1'2.c"