EHPrivateExtern = 1 << 2 };
DenseMap<const MCSymbol*, unsigned> FlagMap;
- bool needsSet(const MCExpr *Value);
+ DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
void EmitRegisterName(int64_t Register);
void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
void ChangeSection(const MCSection *Section,
const MCExpr *Subsection) override;
+ void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
void EmitLabel(MCSymbol *Symbol) override;
void EmitDebugLabel(MCSymbol *Symbol) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitLinkerOptions(ArrayRef<std::string> Options) override;
void EmitDataRegion(MCDataRegionType Kind) override;
+ void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+ unsigned Update) override;
void EmitThumbFunc(MCSymbol *Func) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0) override;
void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
void EmitBytes(StringRef Data) override;
- void EmitValueImpl(const MCExpr *Value, unsigned Size) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc = SMLoc()) override;
void EmitIntValue(uint64_t Value, unsigned Size) override;
void EmitULEB128Value(const MCExpr *Value) override;
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
StringRef FileName) override;
+ MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
void EmitIdent(StringRef IdentString) override;
void EmitCFISections(bool EH, bool Debug) override;
void EmitRawTextImpl(StringRef String) override;
void FinishImpl() override;
+
+ virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override;
};
} // end anonymous namespace.
EmitEOL();
}
+void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
+ StringRef str = MCLOHIdToName(Kind);
+
+#ifndef NDEBUG
+ int NbArgs = MCLOHIdToNbArgs(Kind);
+ assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
+ assert(str != "" && "Invalid LOH name");
+#endif
+
+ OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
+ bool IsFirst = true;
+ for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
+ It != EndIt; ++It) {
+ if (!IsFirst)
+ OS << ", ";
+ IsFirst = false;
+ OS << **It;
+ }
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
MCStreamer::EmitDebugLabel(Symbol);
EmitEOL();
}
+void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
+ unsigned Minor, unsigned Update) {
+ switch (Kind) {
+ case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break;
+ case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break;
+ }
+ OS << " " << Major << ", " << Minor;
+ if (Update)
+ OS << ", " << Update;
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
// This needs to emit to a temporary string to get properly quoted
// MCSymbols when they have spaces in them.
OS << *Symbol << " = " << *Value;
EmitEOL();
- // FIXME: Lift context changes into super class.
- Symbol->setVariableValue(Value);
+ MCStreamer::EmitAssignment(Symbol, Value);
}
void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
// Common symbols do not belong to any actual section.
- AssignSection(Symbol, NULL);
+ AssignSection(Symbol, nullptr);
OS << "\t.comm\t" << *Symbol << ',' << Size;
if (ByteAlignment != 0) {
void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlign) {
// Common symbols do not belong to any actual section.
- AssignSection(Symbol, NULL);
+ AssignSection(Symbol, nullptr);
OS << "\t.lcomm\t" << *Symbol << ',' << Size;
if (ByteAlign > 1) {
const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
- if (Symbol != NULL) {
+ if (Symbol) {
OS << ',' << *Symbol << ',' << Size;
if (ByteAlignment != 0)
OS << ',' << Log2_32(ByteAlignment);
uint64_t Size, unsigned ByteAlignment) {
AssignSection(Symbol, Section);
- assert(Symbol != NULL && "Symbol shouldn't be NULL!");
+ 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;
EmitValue(MCConstantExpr::Create(Value, getContext()), Size);
}
-void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
+void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc) {
assert(Size <= 8 && "Invalid size");
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
- const char *Directive = 0;
+ const char *Directive = nullptr;
switch (Size) {
default: break;
case 1: Directive = MAI->getData8bitsDirective(); break;
}
void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
- assert(MAI->getGPRel64Directive() != 0);
+ assert(MAI->getGPRel64Directive() != nullptr);
OS << MAI->getGPRel64Directive() << *Value;
EmitEOL();
}
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
- assert(MAI->getGPRel32Directive() != 0);
+ assert(MAI->getGPRel32Directive() != nullptr);
OS << MAI->getGPRel32Directive() << *Value;
EmitEOL();
}
StringRef Directory,
StringRef Filename,
unsigned CUID) {
+ assert(CUID == 0);
+
+ MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
+ unsigned NumFiles = Table.getMCDwarfFiles().size();
+ FileNo = Table.getFile(Directory, Filename, FileNo);
+ if (FileNo == 0)
+ return 0;
+ if (NumFiles == Table.getMCDwarfFiles().size())
+ return FileNo;
+
+ SmallString<128> FullPathName;
+
if (!UseDwarfDirectory && !Directory.empty()) {
if (sys::path::is_absolute(Filename))
- return EmitDwarfFileDirective(FileNo, "", Filename, CUID);
-
- SmallString<128> FullPathName = Directory;
- sys::path::append(FullPathName, Filename);
- return EmitDwarfFileDirective(FileNo, "", FullPathName, CUID);
+ Directory = "";
+ else {
+ FullPathName = Directory;
+ sys::path::append(FullPathName, Filename);
+ Directory = "";
+ Filename = FullPathName;
+ }
}
OS << "\t.file\t" << FileNo << ' ';
}
PrintQuotedString(Filename, OS);
EmitEOL();
- // All .file will belong to a single CUID.
- CUID = 0;
- return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename,
- CUID);
+ return FileNo;
}
void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
EmitEOL();
}
+MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
+ // Always use the zeroth line table, since asm syntax only supports one line
+ // table for now.
+ return MCStreamer::getDwarfLineTableSymbol(0);
+}
+
void MCAsmStreamer::EmitIdent(StringRef IdentString) {
assert(MAI->hasIdentDirective() && ".ident directive not supported");
OS << "\t.ident\t";
void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
MCStreamer::EmitWin64EHPushReg(Register);
- OS << "\t.seh_pushreg " << Register;
+ OS << "\t.seh_pushreg ";
+ EmitRegisterName(Register);
EmitEOL();
}
void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
MCStreamer::EmitWin64EHSetFrame(Register, Offset);
- OS << "\t.seh_setframe " << Register << ", " << Offset;
+ OS << "\t.seh_setframe ";
+ EmitRegisterName(Register);
+ OS << ", " << Offset;
EmitEOL();
}
void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
MCStreamer::EmitWin64EHSaveReg(Register, Offset);
- OS << "\t.seh_savereg " << Register << ", " << Offset;
+ OS << "\t.seh_savereg ";
+ EmitRegisterName(Register);
+ OS << ", " << Offset;
EmitEOL();
}
void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
- OS << "\t.seh_savexmm " << Register << ", " << Offset;
+ OS << "\t.seh_savexmm ";
+ EmitRegisterName(Register);
+ OS << ", " << Offset;
EmitEOL();
}
void MCAsmStreamer::FinishImpl() {
// If we are generating dwarf for assembly source files dump out the sections.
if (getContext().getGenDwarfForAssembly())
- MCGenDwarfInfo::Emit(this, NULL);
+ MCGenDwarfInfo::Emit(this);
+
+ // Emit the label for the line table, if requested - since the rest of the
+ // line table will be defined by .loc/.file directives, and not emitted
+ // directly, the label is the only work required here.
+ auto &Tables = getContext().getMCDwarfLineTables();
+ if (!Tables.empty()) {
+ assert(Tables.size() == 1 && "asm output only supports one line table");
+ if (auto *Label = Tables.begin()->second.getLabel()) {
+ SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
+ EmitLabel(Label);
+ }
+ }
if (!UseCFI)
EmitFrames(AsmBackend.get(), false);
}
+MCSymbolData &MCAsmStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) {
+ MCSymbolData *&Entry = SymbolMap[Symbol];
+
+ if (!Entry)
+ Entry = new MCSymbolData(*Symbol, nullptr, 0, nullptr);
+
+ return *Entry;
+}
+
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
formatted_raw_ostream &OS,
bool isVerboseAsm, bool useCFI,