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 @@ -345,6 +345,10 @@ /// target also needs the directory along with the basename. Default to true. bool HasBasenameOnlyForFileDirective = true; + /// Tue if the target represents string constant as mostly raw characters in + /// paired double quotation. Default 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; @@ -673,6 +677,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,12 @@ unsigned UseDwarfDirectory : 1; void EmitRegisterName(int64_t Register); + void PrintQuotedString(StringRef Data, raw_ostream &OS); + void printDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + Optional Checksum, + Optional Source, + bool UseDwarfDirectory, raw_svector_ostream &OS); void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; @@ -1040,33 +1046,53 @@ llvm_unreachable("Invalid AsmCharLiteralSyntax value!"); } -static void PrintQuotedString(StringRef Data, raw_ostream &OS) { +void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) { 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; + } } } @@ -1391,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) { 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"