diff options
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCAsmInfo.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 98 | ||||
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCExpr.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/MC/MCSectionCOFF.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCSectionELF.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/MC/MCSymbol.cpp | 38 |
7 files changed, 127 insertions, 77 deletions
diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp index b5d1c2859e4..100dc7c3dc6 100644 --- a/llvm/lib/MC/MCAsmInfo.cpp +++ b/llvm/lib/MC/MCAsmInfo.cpp @@ -50,6 +50,7 @@ MCAsmInfo::MCAsmInfo() { Code64Directive = ".code64"; AssemblerDialect = 0; AllowAtInName = false; + SupportsQuotedNames = true; UseDataRegionDirectives = false; ZeroDirective = "\t.zero\t"; AsciiDirective = "\t.ascii\t"; @@ -137,3 +138,22 @@ MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym, const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context); return MCBinaryExpr::createSub(Res, PC, Context); } + +static bool isAcceptableChar(char C) { + return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') || + (C >= '0' && C <= '9') || C == '_' || C == '$' || C == '.' || C == '@'; +} + +bool MCAsmInfo::isValidUnquotedName(StringRef Name) const { + if (Name.empty()) + return false; + + // If any of the characters in the string is an unacceptable character, force + // quotes. + for (char C : Name) { + if (!isAcceptableChar(C)) + return false; + } + + return true; +} diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 92997d05258..0f405ad1193 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -308,7 +308,9 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); MCStreamer::EmitLabel(Symbol); - OS << *Symbol << MAI->getLabelSuffix(); + Symbol->print(OS, MAI); + OS << MAI->getLabelSuffix(); + EmitEOL(); } @@ -328,7 +330,7 @@ void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) { if (!IsFirst) OS << ", "; IsFirst = false; - OS << **It; + (*It)->print(OS, MAI); } EmitEOL(); } @@ -384,20 +386,28 @@ void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) { // MCSymbols when they have spaces in them. OS << "\t.thumb_func"; // Only Mach-O hasSubsectionsViaSymbols() - if (MAI->hasSubsectionsViaSymbols()) - OS << '\t' << *Func; + if (MAI->hasSubsectionsViaSymbols()) { + OS << '\t'; + Func->print(OS, MAI); + } EmitEOL(); } void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { - OS << *Symbol << " = " << *Value; + Symbol->print(OS, MAI); + OS << " = "; + Value->print(OS, MAI); + EmitEOL(); MCStreamer::EmitAssignment(Symbol, Value); } void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { - OS << ".weakref " << *Alias << ", " << *Symbol; + OS << ".weakref "; + Alias->print(OS, MAI); + OS << ", "; + Symbol->print(OS, MAI); EmitEOL(); } @@ -414,8 +424,9 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object if (!MAI->hasDotTypeDotSizeDirective()) return false; // Symbol attribute not supported - OS << "\t.type\t" << *Symbol << ',' - << ((MAI->getCommentString()[0] != '@') ? '@' : '%'); + OS << "\t.type\t"; + Symbol->print(OS, MAI); + OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%'); switch (Attribute) { default: return false; case MCSA_ELF_TypeFunction: OS << "function"; break; @@ -456,19 +467,23 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break; } - OS << *Symbol; + Symbol->print(OS, MAI); EmitEOL(); return true; } void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { - OS << ".desc" << ' ' << *Symbol << ',' << DescValue; + OS << ".desc" << ' '; + Symbol->print(OS, MAI); + OS << ',' << DescValue; EmitEOL(); } void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { - OS << "\t.def\t " << *Symbol << ';'; + OS << "\t.def\t "; + Symbol->print(OS, MAI); + OS << ';'; EmitEOL(); } @@ -493,18 +508,24 @@ void MCAsmStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { } void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { - OS << "\t.secidx\t" << *Symbol; + OS << "\t.secidx\t"; + Symbol->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { - OS << "\t.secrel32\t" << *Symbol; + OS << "\t.secrel32\t"; + Symbol->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) { assert(MAI->hasDotTypeDotSizeDirective()); - OS << "\t.size\t" << *Symbol << ", " << *Value << '\n'; + OS << "\t.size\t"; + Symbol->print(OS, MAI); + OS << ", "; + Value->print(OS, MAI); + OS << '\n'; } void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -512,7 +533,10 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, // Common symbols do not belong to any actual section. AssignSection(Symbol, nullptr); - OS << "\t.comm\t" << *Symbol << ',' << Size; + OS << "\t.comm\t"; + Symbol->print(OS, MAI); + OS << ',' << Size; + if (ByteAlignment != 0) { if (MAI->getCOMMDirectiveAlignmentIsInBytes()) OS << ',' << ByteAlignment; @@ -531,7 +555,10 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, // Common symbols do not belong to any actual section. AssignSection(Symbol, nullptr); - OS << "\t.lcomm\t" << *Symbol << ',' << Size; + OS << "\t.lcomm\t"; + Symbol->print(OS, MAI); + OS << ',' << Size; + if (ByteAlign > 1) { switch (MAI->getLCOMMDirectiveAlignmentType()) { case LCOMM::NoAlignment: @@ -561,7 +588,9 @@ void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, OS << MOSection->getSegmentName() << "," << MOSection->getSectionName(); if (Symbol) { - OS << ',' << *Symbol << ',' << Size; + OS << ','; + Symbol->print(OS, MAI); + OS << ',' << Size; if (ByteAlignment != 0) OS << ',' << Log2_32(ByteAlignment); } @@ -578,7 +607,9 @@ void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, assert(Symbol && "Symbol shouldn't be NULL!"); // Instead of using the Section we'll just use the shortcut. // This is a mach-o specific directive and section. - OS << ".tbss " << *Symbol << ", " << Size; + OS << ".tbss "; + Symbol->print(OS, MAI); + OS << ", " << Size; // Output align if we have it. We default to 1 so don't bother printing // that. @@ -703,7 +734,8 @@ void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, } assert(Directive && "Invalid size for machine code value!"); - OS << Directive << *Value; + OS << Directive; + Value->print(OS, MAI); EmitEOL(); } @@ -713,7 +745,8 @@ void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) { EmitULEB128IntValue(IntValue); return; } - OS << ".uleb128 " << *Value; + OS << ".uleb128 "; + Value->print(OS, MAI); EmitEOL(); } @@ -723,19 +756,22 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { EmitSLEB128IntValue(IntValue); return; } - OS << ".sleb128 " << *Value; + OS << ".sleb128 "; + Value->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) { assert(MAI->getGPRel64Directive() != nullptr); - OS << MAI->getGPRel64Directive() << *Value; + OS << MAI->getGPRel64Directive(); + Value->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { assert(MAI->getGPRel32Directive() != nullptr); - OS << MAI->getGPRel32Directive() << *Value; + OS << MAI->getGPRel32Directive(); + Value->print(OS, MAI); EmitEOL(); } @@ -822,7 +858,9 @@ void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment, bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { // FIXME: Verify that Offset is associated with the current section. - OS << ".org " << *Offset << ", " << (unsigned) Value; + OS << ".org "; + Offset->print(OS, MAI); + OS << ", " << (unsigned)Value; EmitEOL(); return false; } @@ -993,13 +1031,15 @@ void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) { MCStreamer::EmitCFIPersonality(Sym, Encoding); - OS << "\t.cfi_personality " << Encoding << ", " << *Sym; + OS << "\t.cfi_personality " << Encoding << ", "; + Sym->print(OS, MAI); EmitEOL(); } void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { MCStreamer::EmitCFILsda(Sym, Encoding); - OS << "\t.cfi_lsda " << Encoding << ", " << *Sym; + OS << "\t.cfi_lsda " << Encoding << ", "; + Sym->print(OS, MAI); EmitEOL(); } @@ -1063,7 +1103,8 @@ void MCAsmStreamer::EmitCFIWindowSave() { void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { MCStreamer::EmitWinCFIStartProc(Symbol); - OS << ".seh_proc " << *Symbol; + OS << ".seh_proc "; + Symbol->print(OS, MAI); EmitEOL(); } @@ -1092,7 +1133,8 @@ void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) { MCStreamer::EmitWinEHHandler(Sym, Unwind, Except); - OS << "\t.seh_handler " << *Sym; + OS << "\t.seh_handler "; + Sym->print(OS, MAI); if (Unwind) OS << ", @unwind"; if (Except) diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 51f05b703a0..55f50097744 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -1199,8 +1199,7 @@ void MCFragment::dump() { case MCFragment::FT_SafeSEH: { const MCSafeSEHFragment *F = cast<MCSafeSEHFragment>(this); OS << "\n "; - OS << " Sym:"; - F->getSymbol()->print(OS); + OS << " Sym:" << F->getSymbol(); break; } } diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index 9cb4c9f5788..b16245ac3f4 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -30,10 +30,10 @@ STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations"); } } -void MCExpr::print(raw_ostream &OS) const { +void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const { switch (getKind()) { case MCExpr::Target: - return cast<MCTargetExpr>(this)->printImpl(OS); + return cast<MCTargetExpr>(this)->printImpl(OS, MAI); case MCExpr::Constant: OS << cast<MCConstantExpr>(*this).getValue(); return; @@ -43,11 +43,13 @@ void MCExpr::print(raw_ostream &OS) const { const MCSymbol &Sym = SRE.getSymbol(); // Parenthesize names that start with $ so that they don't look like // absolute names. - bool UseParens = !Sym.getName().empty() && Sym.getName()[0] == '$'; - if (UseParens) - OS << '(' << Sym << ')'; - else - OS << Sym; + bool UseParens = Sym.getName()[0] == '$'; + if (UseParens) { + OS << '('; + Sym.print(OS, MAI); + OS << ')'; + } else + Sym.print(OS, MAI); if (SRE.getKind() != MCSymbolRefExpr::VK_None) SRE.printVariantKind(OS); @@ -63,7 +65,7 @@ void MCExpr::print(raw_ostream &OS) const { case MCUnaryExpr::Not: OS << '~'; break; case MCUnaryExpr::Plus: OS << '+'; break; } - OS << *UE.getSubExpr(); + UE.getSubExpr()->print(OS, MAI); return; } @@ -72,9 +74,11 @@ void MCExpr::print(raw_ostream &OS) const { // Only print parens around the LHS if it is non-trivial. if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) { - OS << *BE.getLHS(); + BE.getLHS()->print(OS, MAI); } else { - OS << '(' << *BE.getLHS() << ')'; + OS << '('; + BE.getLHS()->print(OS, MAI); + OS << ')'; } switch (BE.getOpcode()) { @@ -111,9 +115,11 @@ void MCExpr::print(raw_ostream &OS) const { // Only print parens around the LHS if it is non-trivial. if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) { - OS << *BE.getRHS(); + BE.getRHS()->print(OS, MAI); } else { - OS << '(' << *BE.getRHS() << ')'; + OS << '('; + BE.getRHS()->print(OS, MAI); + OS << ')'; } return; } diff --git a/llvm/lib/MC/MCSectionCOFF.cpp b/llvm/lib/MC/MCSectionCOFF.cpp index 4d6298c542e..ce0b4f5fb41 100644 --- a/llvm/lib/MC/MCSectionCOFF.cpp +++ b/llvm/lib/MC/MCSectionCOFF.cpp @@ -94,7 +94,7 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, break; } assert(COMDATSymbol); - OS << *COMDATSymbol; + COMDATSymbol->print(OS, &MAI); } OS << '\n'; } diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp index 3cd84538425..b4448d79a2d 100644 --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -64,8 +64,10 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, if (ShouldOmitSectionDirective(SectionName, MAI)) { OS << '\t' << getSectionName(); - if (Subsection) - OS << '\t' << *Subsection; + if (Subsection) { + OS << '\t'; + Subsection->print(OS, &MAI); + } OS << '\n'; return; } @@ -153,8 +155,11 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, OS << '\n'; - if (Subsection) - OS << "\t.subsection\t" << *Subsection << '\n'; + if (Subsection) { + OS << "\t.subsection\t"; + Subsection->print(OS, &MAI); + OS << '\n'; + } } bool MCSectionELF::UseCodeAlign() const { diff --git a/llvm/lib/MC/MCSymbol.cpp b/llvm/lib/MC/MCSymbol.cpp index bcab23b9fc3..8d07b7605ce 100644 --- a/llvm/lib/MC/MCSymbol.cpp +++ b/llvm/lib/MC/MCSymbol.cpp @@ -8,36 +8,16 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; // Sentinel value for the absolute pseudo section. MCSection *MCSymbol::AbsolutePseudoSection = reinterpret_cast<MCSection *>(1); -static bool isAcceptableChar(char C) { - if ((C < 'a' || C > 'z') && - (C < 'A' || C > 'Z') && - (C < '0' || C > '9') && - C != '_' && C != '$' && C != '.' && C != '@') - return false; - return true; -} - -/// NameNeedsQuoting - Return true if the identifier \p Str needs quotes to be -/// syntactically correct. -static bool NameNeedsQuoting(StringRef Str) { - assert(!Str.empty() && "Cannot create an empty MCSymbol"); - - // If any of the characters in the string is an unacceptable character, force - // quotes. - for (unsigned i = 0, e = Str.size(); i != e; ++i) - if (!isAcceptableChar(Str[i])) - return true; - return false; -} - void MCSymbol::setVariableValue(const MCExpr *Value) { assert(!IsUsed && "Cannot set a variable that has already been used."); assert(Value && "Invalid variable value!"); @@ -45,23 +25,21 @@ void MCSymbol::setVariableValue(const MCExpr *Value) { SectionOrFragment = nullptr; } -void MCSymbol::print(raw_ostream &OS) const { +void MCSymbol::print(raw_ostream &OS, const MCAsmInfo *MAI) const { // The name for this MCSymbol is required to be a valid target name. However, // some targets support quoting names with funny characters. If the name // contains a funny character, then print it quoted. StringRef Name = getName(); - if (Name.empty()) { - OS << "\"\""; - return; - } - if (!NameNeedsQuoting(Name)) { + if (!MAI || MAI->isValidUnquotedName(Name)) { OS << Name; return; } + if (MAI && !MAI->supportsNameQuoting()) + report_fatal_error("Symbol name with unsupported characters"); + OS << '"'; - for (unsigned I = 0, E = Name.size(); I != E; ++I) { - char C = Name[I]; + for (char C : Name) { if (C == '\n') OS << "\\n"; else if (C == '"') |