+ const_iterator begin() {
+ return Symbols.begin();
+ }
+
+ const_iterator end() {
+ return Symbols.end();
+ }
+
+ RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
+
+ virtual void ChangeSection(const MCSection *Section) {}
+ virtual void InitSections() {}
+ virtual void EmitLabel(MCSymbol *Symbol) {
+ Symbol->setSection(*getCurrentSection());
+ markDefined(*Symbol);
+ }
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
+ virtual void EmitThumbFunc(MCSymbol *Func) {}
+ virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
+ // FIXME: should we handle aliases?
+ markDefined(*Symbol);
+ }
+ virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) {
+ if (Attribute == MCSA_Global)
+ markGlobal(*Symbol);
+ }
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
+ virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
+ unsigned Size , unsigned ByteAlignment) {
+ markDefined(*Symbol);
+ }
+ virtual void EmitCOFFSymbolType(int Type) {}
+ virtual void EndCOFFSymbolDef() {}
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {
+ markDefined(*Symbol);
+ }
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {}
+ virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment) {}
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {}
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) {}
+ virtual void EmitULEB128Value(const MCExpr *Value) {}
+ virtual void EmitSLEB128Value(const MCExpr *Value) {}
+ virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {}
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit) {}
+ virtual void EmitValueToOffset(const MCExpr *Offset,
+ unsigned char Value ) {}
+ virtual void EmitFileDirective(StringRef Filename) {}
+ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
+ const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize) {}
+
+ virtual void EmitInstruction(const MCInst &Inst) {
+ // Scan for values.
+ for (unsigned i = Inst.getNumOperands(); i--; )
+ if (Inst.getOperand(i).isExpr())
+ AddValueSymbols(Inst.getOperand(i).getExpr());
+ }
+ virtual void Finish() {}
+ };
+}
+
+bool LTOModule::addAsmGlobalSymbols(MCContext &Context) {
+ const std::string &inlineAsm = _module->getModuleInlineAsm();
+
+ OwningPtr<RecordStreamer> Streamer(new RecordStreamer(Context));
+ MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm);
+ SourceMgr SrcMgr;
+ SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+ OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr,
+ Context, *Streamer,
+ *_target->getMCAsmInfo()));
+ OwningPtr<MCSubtargetInfo> STI(_target->getTarget().
+ createMCSubtargetInfo(_target->getTargetTriple(),
+ _target->getTargetCPU(),
+ _target->getTargetFeatureString()));
+ OwningPtr<MCTargetAsmParser>
+ TAP(_target->getTarget().createMCAsmParser(*STI, *Parser.get()));
+ Parser->setTargetParser(*TAP);
+ int Res = Parser->Run(false);
+ if (Res)
+ return true;
+
+ for (RecordStreamer::const_iterator i = Streamer->begin(),
+ e = Streamer->end(); i != e; ++i) {
+ StringRef Key = i->first();
+ RecordStreamer::State Value = i->second;
+ if (Value == RecordStreamer::DefinedGlobal)
+ addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_DEFAULT);
+ else if (Value == RecordStreamer::Defined)
+ addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_INTERNAL);
+ else if (Value == RecordStreamer::Global ||
+ Value == RecordStreamer::Used)
+ addAsmGlobalSymbolUndef(Key.data());