示例#1
0
文件: Main.cpp 项目: isanbard/flang
static bool ParseFile(const std::string &Filename,
                      const std::vector<std::string> &IncludeDirs) {
    llvm::OwningPtr<llvm::MemoryBuffer> MB;
    if (llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(Filename.c_str(),
                              MB)) {
        llvm::errs() << "Could not open input file '" << Filename << "': "
                     << ec.message() <<"\n";
        return true;
    }

    // Record the location of the include directory so that the lexer can find it
    // later.
    SourceMgr SrcMgr;
    SrcMgr.setIncludeDirs(IncludeDirs);

    // Tell SrcMgr about this buffer, which is what Parser will pick up.
    SrcMgr.AddNewSourceBuffer(MB.take(), SMLoc());

    LangOptions Opts;
    Opts.ReturnComments = ReturnComments;
    TextDiagnosticPrinter TDP(SrcMgr);
    Diagnostic Diag(&SrcMgr, &TDP, false);
#if 0
    PrintAction PA(Diag);
#endif
    ASTContext Context(SrcMgr);
    Sema SA(Context, Diag);
    Parser P(SrcMgr, Opts, Diag, SA);
    return P.ParseProgramUnits();
}
示例#2
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
  if (!TheTarget) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  std::unique_ptr<MemoryBuffer> BufferPtr;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) {
    Error = ec.message();
    Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
    return false;
  }
  MemoryBuffer *Buffer = BufferPtr.release();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  if (Opts.CompressDebugSections)
    MAI->setCompressDebugSections(true);

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
  if (!Out)
    return false;

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());

  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  // FIXME: Assembler behavior can change with -static.
  MOFI->InitMCObjectFileInfo(Opts.Triple,
                             Reloc::Default, CodeModel::Default, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);
  if (Opts.GenDwarfForAssembly)
    Ctx.setGenDwarfForAssembly(true);
  if (!Opts.DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
  if (!Opts.DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
  if (!Opts.DebugCompilationDir.empty())
    Ctx.setCompilationDir(Opts.DebugCompilationDir);
  if (!Opts.MainFileName.empty())
    Ctx.setMainFileName(StringRef(Opts.MainFileName));
  Ctx.setDwarfVersion(Opts.DwarfVersion);

  // Build up the feature string from the target feature list.
  std::string FS;
  if (!Opts.Features.empty()) {
    FS = Opts.Features[0];
    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
      FS += "," + Opts.Features[i];
  }

  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP =
      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
                                     *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (Opts.ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
    }
    Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB,
                                           Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
                                                      Opts.CPU);
    Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
                                                CE, *STI, Opts.RelaxAll,
                                                Opts.NoExecStack));
    Str.get()->InitSections();
  }

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  // FIXME: init MCTargetOptions from sanitizer flags here.
  MCTargetOptions Options;
  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
  if (!TAP) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  Parser->setTargetParser(*TAP.get());

  bool Success = !Parser->Run(Opts.NoInitialTextSection);

  // Close the output.
  delete Out;

  // Delete output on errors.
  if (!Success && Opts.OutputPath != "-")
    sys::fs::remove(Opts.OutputPath);

  return Success;
}
示例#3
0
文件: llvm-mc.cpp 项目: Wilfred/llvm
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal(argv[0]);
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets and assembly printers/parsers.
  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmParsers();
  llvm::InitializeAllDisassemblers();

  // Register the target printer for --version.
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
  TripleName = Triple::normalize(TripleName);
  setDwarfDebugFlags(argc, argv);

  setDwarfDebugProducer();

  const char *ProgName = argv[0];
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;
  // Now that GetTarget() has (potentially) replaced TripleName, it's safe to
  // construct the Triple object.
  Triple TheTriple(TripleName);

  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr =
      MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (std::error_code EC = BufferPtr.getError()) {
    errs() << InputFilename << ": " << EC.message() << '\n';
    return 1;
  }
  MemoryBuffer *Buffer = BufferPtr->get();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  assert(MAI && "Unable to create target asm info!");

  MAI->setRelaxELFRelocations(RelaxELFRel);

  if (CompressDebugSections != DebugCompressionType::DCT_None) {
    if (!zlib::isAvailable()) {
      errs() << ProgName
             << ": build tools with zlib to enable -compress-debug-sections";
      return 1;
    }
    MAI->setCompressDebugSections(CompressDebugSections);
  }

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  MCObjectFileInfo MOFI;
  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
  MOFI.InitMCObjectFileInfo(TheTriple, PIC, CMModel, Ctx);

  if (SaveTempLabels)
    Ctx.setAllowTemporaryLabels(false);

  Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
  // Default to 4 for dwarf version.
  unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4;
  if (DwarfVersion < 2 || DwarfVersion > 4) {
    errs() << ProgName << ": Dwarf version " << DwarfVersion
           << " is not supported." << '\n';
    return 1;
  }
  Ctx.setDwarfVersion(DwarfVersion);
  if (!DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
  if (!DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer));
  if (!DebugCompilationDir.empty())
    Ctx.setCompilationDir(DebugCompilationDir);
  else {
    // If no compilation dir is set, try to use the current directory.
    SmallString<128> CWD;
    if (!sys::fs::current_path(CWD))
      Ctx.setCompilationDir(CWD);
  }
  if (!MainFileName.empty())
    Ctx.setMainFileName(MainFileName);

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  std::unique_ptr<tool_output_file> Out = GetOutputStream();
  if (!Out)
    return 1;

  std::unique_ptr<buffer_ostream> BOS;
  raw_pwrite_stream *OS = &Out->os();
  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));

  MCInstPrinter *IP = nullptr;
  if (FileType == OFT_AssemblyFile) {
    IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant,
                                        *MAI, *MCII, *MRI);

    // Set the display preference for hex vs. decimal immediates.
    IP->setPrintImmHex(PrintImmHex);

    // Set up the AsmStreamer.
    MCCodeEmitter *CE = nullptr;
    MCAsmBackend *MAB = nullptr;
    if (ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    }
    auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS);
    Str.reset(TheTarget->createAsmStreamer(
        Ctx, std::move(FOut), /*asmverbose*/ true,
        /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst));

  } else if (FileType == OFT_Null) {
    Str.reset(TheTarget->createNullStreamer(Ctx));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");

    // Don't waste memory on names of temp labels.
    Ctx.setUseNamesOnTempLabels(false);

    if (!Out->os().supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(Out->os());
      OS = BOS.get();
    }

    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    Str.reset(TheTarget->createMCObjectStreamer(
        TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll,
        MCOptions.MCIncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ false));
    if (NoExecStack)
      Str->InitSections(true);
  }

  int Res = 1;
  bool disassemble = false;
  switch (Action) {
  case AC_AsLex:
    Res = AsLexInput(SrcMgr, *MAI, Out->os());
    break;
  case AC_Assemble:
    Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI,
                        *MCII, MCOptions);
    break;
  case AC_MDisassemble:
    assert(IP && "Expected assembly output");
    IP->setUseMarkup(1);
    disassemble = true;
    break;
  case AC_Disassemble:
    disassemble = true;
    break;
  }
  if (disassemble)
    Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
                                    *Buffer, SrcMgr, Out->os());

  // Keep output if no errors.
  if (Res == 0) Out->keep();
  return Res;
}
示例#4
0
static int AssembleInput(const char *ProgName) {
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;

  std::string Error;
  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error);
  if (Buffer == 0) {
    errs() << ProgName << ": ";
    if (Error.size())
      errs() << Error << "\n";
    else
      errs() << "input file didn't read correctly.\n";
    return 1;
  }
  
  SourceMgr SrcMgr;
  
  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
  
  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);
  
  MCContext Ctx;
  formatted_raw_ostream *Out = GetOutputStream();
  if (!Out)
    return 1;


  // FIXME: We shouldn't need to do this (and link in codegen).
  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, ""));

  if (!TM) {
    errs() << ProgName << ": error: could not create target for triple '"
           << TripleName << "'.\n";
    return 1;
  }

  OwningPtr<AsmPrinter> AP;
  OwningPtr<MCStreamer> Str;

  if (FileType == OFT_AssemblyFile) {
    const TargetAsmInfo *TAI = TheTarget->createAsmInfo(TripleName);
    assert(TAI && "Unable to create target asm info!");

    AP.reset(TheTarget->createAsmPrinter(*Out, *TM, TAI, true));
    Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get()));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");
    Str.reset(createMachOStreamer(Ctx, *Out));
  }

  // FIXME: Target hook & command line option for initial section.
  Str.get()->SwitchSection(MCSectionMachO::Create("__TEXT","__text",
                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
                                                  0, SectionKind::getText(),
                                                  Ctx));

  AsmParser Parser(SrcMgr, Ctx, *Str.get());
  OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(Parser));
  if (!TAP) {
    errs() << ProgName 
           << ": error: this target does not support assembly parsing.\n";
    return 1;
  }

  Parser.setTargetParser(*TAP.get());

  int Res = Parser.Run();
  if (Out != &fouts())
    delete Out;

  return Res;
}  
示例#5
0
static int AsLexInput(const char *ProgName) {
  std::string ErrorMessage;
  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
                                                      &ErrorMessage);
  if (Buffer == 0) {
    errs() << ProgName << ": ";
    if (ErrorMessage.size())
      errs() << ErrorMessage << "\n";
    else
      errs() << "input file didn't read correctly.\n";
    return 1;
  }

  SourceMgr SrcMgr;
  
  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
  
  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);

  AsmLexer Lexer(SrcMgr);
  
  bool Error = false;
  
  while (Lexer.Lex().isNot(AsmToken::Eof)) {
    switch (Lexer.getKind()) {
    default:
      Lexer.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
      Error = true;
      break;
    case AsmToken::Error:
      Error = true; // error already printed.
      break;
    case AsmToken::Identifier:
      outs() << "identifier: " << Lexer.getTok().getString() << '\n';
      break;
    case AsmToken::Register:
      outs() << "register: " << Lexer.getTok().getString() << '\n';
      break;
    case AsmToken::String:
      outs() << "string: " << Lexer.getTok().getString() << '\n';
      break;
    case AsmToken::Integer:
      outs() << "int: " << Lexer.getTok().getString() << '\n';
      break;

    case AsmToken::Amp:            outs() << "Amp\n"; break;
    case AsmToken::AmpAmp:         outs() << "AmpAmp\n"; break;
    case AsmToken::Caret:          outs() << "Caret\n"; break;
    case AsmToken::Colon:          outs() << "Colon\n"; break;
    case AsmToken::Comma:          outs() << "Comma\n"; break;
    case AsmToken::Dollar:         outs() << "Dollar\n"; break;
    case AsmToken::EndOfStatement: outs() << "EndOfStatement\n"; break;
    case AsmToken::Eof:            outs() << "Eof\n"; break;
    case AsmToken::Equal:          outs() << "Equal\n"; break;
    case AsmToken::EqualEqual:     outs() << "EqualEqual\n"; break;
    case AsmToken::Exclaim:        outs() << "Exclaim\n"; break;
    case AsmToken::ExclaimEqual:   outs() << "ExclaimEqual\n"; break;
    case AsmToken::Greater:        outs() << "Greater\n"; break;
    case AsmToken::GreaterEqual:   outs() << "GreaterEqual\n"; break;
    case AsmToken::GreaterGreater: outs() << "GreaterGreater\n"; break;
    case AsmToken::LParen:         outs() << "LParen\n"; break;
    case AsmToken::Less:           outs() << "Less\n"; break;
    case AsmToken::LessEqual:      outs() << "LessEqual\n"; break;
    case AsmToken::LessGreater:    outs() << "LessGreater\n"; break;
    case AsmToken::LessLess:       outs() << "LessLess\n"; break;
    case AsmToken::Minus:          outs() << "Minus\n"; break;
    case AsmToken::Percent:        outs() << "Percent\n"; break;
    case AsmToken::Pipe:           outs() << "Pipe\n"; break;
    case AsmToken::PipePipe:       outs() << "PipePipe\n"; break;
    case AsmToken::Plus:           outs() << "Plus\n"; break;
    case AsmToken::RParen:         outs() << "RParen\n"; break;
    case AsmToken::Slash:          outs() << "Slash\n"; break;
    case AsmToken::Star:           outs() << "Star\n"; break;
    case AsmToken::Tilde:          outs() << "Tilde\n"; break;
    }
  }
  
  return Error;
}
示例#6
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
  if (!TheTarget) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  OwningPtr<MemoryBuffer> BufferPtr;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) {
    Error = ec.message();
    Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
    return false;
  }
  MemoryBuffer *Buffer = BufferPtr.take();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
  if (!Out)
    return false;

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
  MCContext Ctx(*MAI, *MRI, MOFI.get());
  // FIXME: Assembler behavior can change with -static.
  MOFI->InitMCObjectFileInfo(Opts.Triple,
                             Reloc::Default, CodeModel::Default, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);

  OwningPtr<MCStreamer> Str;

  OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  OwningPtr<MCSubtargetInfo>
    STI(TheTarget->createMCSubtargetInfo(Opts.Triple, "", ""));

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP =
      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
                                     *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (Opts.ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
      MAB = TheTarget->createMCAsmBackend(Opts.Triple);
    }
    Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
                                           /*useLoc*/ true, /*useCFI*/ true,
                                           /*useDwarfDirectory*/ true, IP, CE,
                                           MAB, Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(Opts.Triple);
    Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
                                                CE, Opts.RelaxAll,
                                                Opts.NoExecStack));
    Str.get()->InitSections();
  }

  OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(),
                                                  *MAI));
  OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser));
  if (!TAP) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  Parser->setTargetParser(*TAP.get());

  bool Success = !Parser->Run(Opts.NoInitialTextSection);

  // Close the output.
  delete Out;

  // Delete output on errors.
  if (!Success && Opts.OutputPath != "-")
    sys::Path(Opts.OutputPath).eraseFromDisk();

  return Success;
}
示例#7
0
int AssembleOneInput(const uint8_t *Data, size_t Size) {
  const bool ShowInst = false;
  const bool AsmVerbose = false;
  const bool UseDwarfDirectory = true;

  Triple TheTriple(Triple::normalize(TripleName));

  SourceMgr SrcMgr;

  std::unique_ptr<MemoryBuffer> BufferPtr(new LLVMFuzzerInputBuffer(Data, Size));

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(BufferPtr), SMLoc());

  static const std::vector<std::string> NoIncludeDirs;
  SrcMgr.setIncludeDirs(NoIncludeDirs);

  static std::string ArchName;
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
      Error);
  if (!TheTarget) {
    errs() << "error: this target '" << TheTriple.normalize()
      << "/" << ArchName << "', was not found: '" << Error << "'\n";

    abort();
  }

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  if (!MRI) {
    errs() << "Unable to create target register info!";
    abort();
  }

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  if (!MAI) {
    errs() << "Unable to create target asm info!";
    abort();
  }


  MCObjectFileInfo MOFI;
  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);

  static const bool UsePIC = false;
  MOFI.InitMCObjectFileInfo(TheTriple, UsePIC, Ctx);

  const unsigned OutputAsmVariant = 0;
  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  MCInstPrinter *IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant,
      *MAI, *MCII, *MRI);
  if (!IP) {
    errs()
      << "error: unable to create instruction printer for target triple '"
      << TheTriple.normalize() << "' with assembly variant "
      << OutputAsmVariant << ".\n";

    abort();
  }

  const char *ProgName = "llvm-mc-fuzzer";
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
  MCCodeEmitter *CE = nullptr;
  MCAsmBackend *MAB = nullptr;

  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();

  std::string OutputString;
  raw_string_ostream Out(OutputString);
  auto FOut = llvm::make_unique<formatted_raw_ostream>(Out);

  std::unique_ptr<MCStreamer> Str;

  if (FileType == OFT_AssemblyFile) {
    Str.reset(TheTarget->createAsmStreamer(
        Ctx,  std::move(FOut), AsmVerbose,
        UseDwarfDirectory, IP, CE, MAB, ShowInst));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");

    std::error_code EC;
    const std::string OutputFilename = "-";
    auto Out =
        llvm::make_unique<ToolOutputFile>(OutputFilename, EC, sys::fs::F_None);
    if (EC) {
      errs() << EC.message() << '\n';
      abort();
    }

    // Don't waste memory on names of temp labels.
    Ctx.setUseNamesOnTempLabels(false);

    std::unique_ptr<buffer_ostream> BOS;
    raw_pwrite_stream *OS = &Out->os();
    if (!Out->os().supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(Out->os());
      OS = BOS.get();
    }

    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU,
                                                      MCOptions);
    Str.reset(TheTarget->createMCObjectStreamer(
        TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll,
        MCOptions.MCIncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ false));
  }
  const int Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI,
      *MCII, MCOptions);

  (void) Res;

  return 0;
}
示例#8
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
  if (!TheTarget)
    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);

  if (std::error_code EC = Buffer.getError()) {
    Error = EC.message();
    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
  }

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  MAI->setCompressDebugSections(Opts.CompressDebugSections);

  MAI->setRelaxELFRelocations(Opts.RelaxELFRelocations);

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  if (Opts.OutputPath.empty())
    Opts.OutputPath = "-";
  std::unique_ptr<raw_fd_ostream> FDOS =
      getOutputStream(Opts.OutputPath, Diags, IsBinary);
  if (!FDOS)
    return true;
  std::unique_ptr<raw_fd_ostream> DwoOS;
  if (!Opts.SplitDwarfFile.empty())
    DwoOS = getOutputStream(Opts.SplitDwarfFile, Diags, IsBinary);

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());

  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);

  bool PIC = false;
  if (Opts.RelocationModel == "static") {
    PIC = false;
  } else if (Opts.RelocationModel == "pic") {
    PIC = true;
  } else {
    assert(Opts.RelocationModel == "dynamic-no-pic" &&
           "Invalid PIC model!");
    PIC = false;
  }

  MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);
  if (Opts.GenDwarfForAssembly)
    Ctx.setGenDwarfForAssembly(true);
  if (!Opts.DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
  if (!Opts.DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
  if (!Opts.DebugCompilationDir.empty())
    Ctx.setCompilationDir(Opts.DebugCompilationDir);
  if (!Opts.DebugPrefixMap.empty())
    for (const auto &KV : Opts.DebugPrefixMap)
      Ctx.addDebugPrefixMapEntry(KV.first, KV.second);
  if (!Opts.MainFileName.empty())
    Ctx.setMainFileName(StringRef(Opts.MainFileName));
  Ctx.setDwarfVersion(Opts.DwarfVersion);

  // Build up the feature string from the target feature list.
  std::string FS;
  if (!Opts.Features.empty()) {
    FS = Opts.Features[0];
    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
      FS += "," + Opts.Features[i];
  }

  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

  raw_pwrite_stream *Out = FDOS.get();
  std::unique_ptr<buffer_ostream> BOS;

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP = TheTarget->createMCInstPrinter(
        llvm::Triple(Opts.Triple), Opts.OutputAsmVariant, *MAI, *MCII, *MRI);

    std::unique_ptr<MCCodeEmitter> CE;
    if (Opts.ShowEncoding)
      CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
    MCTargetOptions MCOptions;
    std::unique_ptr<MCAsmBackend> MAB(
        TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));

    auto FOut = llvm::make_unique<formatted_raw_ostream>(*Out);
    Str.reset(TheTarget->createAsmStreamer(
        Ctx, std::move(FOut), /*asmverbose*/ true,
        /*useDwarfDirectory*/ true, IP, std::move(CE), std::move(MAB),
        Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    if (!FDOS->supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(*FDOS);
      Out = BOS.get();
    }

    std::unique_ptr<MCCodeEmitter> CE(
        TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
    MCTargetOptions MCOptions;
    std::unique_ptr<MCAsmBackend> MAB(
        TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
    std::unique_ptr<MCObjectWriter> OW =
        DwoOS ? MAB->createDwoObjectWriter(*Out, *DwoOS)
              : MAB->createObjectWriter(*Out);

    Triple T(Opts.Triple);
    Str.reset(TheTarget->createMCObjectStreamer(
        T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI,
        Opts.RelaxAll, Opts.IncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ true));
    Str.get()->InitSections(Opts.NoExecStack);
  }

  // When -fembed-bitcode is passed to clang_as, a 1-byte marker
  // is emitted in __LLVM,__asm section if the object file is MachO format.
  if (Opts.EmbedBitcode && Ctx.getObjectFileInfo()->getObjectFileType() ==
                               MCObjectFileInfo::IsMachO) {
    MCSection *AsmLabel = Ctx.getMachOSection(
        "__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly());
    Str.get()->SwitchSection(AsmLabel);
    Str.get()->EmitZeros(1);
  }

  // Assembly to object compilation should leverage assembly info.
  Str->setUseAssemblerInfoForParsing(true);

  bool Failed = false;

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  // FIXME: init MCTargetOptions from sanitizer flags here.
  MCTargetOptions Options;
  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
  if (!TAP)
    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  // Set values for symbols, if any.
  for (auto &S : Opts.SymbolDefs) {
    auto Pair = StringRef(S).split('=');
    auto Sym = Pair.first;
    auto Val = Pair.second;
    int64_t Value;
    // We have already error checked this in the driver.
    Val.getAsInteger(0, Value);
    Ctx.setSymbolValue(Parser->getStreamer(), Sym, Value);
  }

  if (!Failed) {
    Parser->setTargetParser(*TAP.get());
    Failed = Parser->Run(Opts.NoInitialTextSection);
  }

  // Close Streamer first.
  // It might have a reference to the output stream.
  Str.reset();
  // Close the output stream early.
  BOS.reset();
  FDOS.reset();

  // Delete output file if there were errors.
  if (Failed) {
    if (Opts.OutputPath != "-")
      sys::fs::remove(Opts.OutputPath);
    if (!Opts.SplitDwarfFile.empty() && Opts.SplitDwarfFile != "-")
      sys::fs::remove(Opts.SplitDwarfFile);
  }

  return Failed;
}
示例#9
0
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets and assembly printers/parsers.
  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmParsers();
  llvm::InitializeAllDisassemblers();

  // Register the target printer for --version.
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
  TripleName = Triple::normalize(TripleName);
  setDwarfDebugFlags(argc, argv);

  setDwarfDebugProducer();

  const char *ProgName = argv[0];
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;

  std::unique_ptr<MemoryBuffer> BufferPtr;
  if (std::error_code ec =
          MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) {
    errs() << ProgName << ": " << ec.message() << '\n';
    return 1;
  }
  MemoryBuffer *Buffer = BufferPtr.release();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  assert(MAI && "Unable to create target asm info!");

  if (CompressDebugSections) {
    if (!zlib::isAvailable()) {
      errs() << ProgName << ": build tools with zlib to enable -compress-debug-sections";
      return 1;
    }
    MAI->setCompressDebugSections(true);
  }

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx);

  if (SaveTempLabels)
    Ctx.setAllowTemporaryLabels(false);

  Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
  if (DwarfVersion < 2 || DwarfVersion > 4) {
    errs() << ProgName << ": Dwarf version " << DwarfVersion
           << " is not supported." << '\n';
    return 1;
  }
  Ctx.setDwarfVersion(DwarfVersion);
  if (!DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
  if (!DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer));
  if (!DebugCompilationDir.empty())
    Ctx.setCompilationDir(DebugCompilationDir);
  if (!MainFileName.empty())
    Ctx.setMainFileName(MainFileName);

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  std::unique_ptr<tool_output_file> Out(GetOutputStream());
  if (!Out)
    return 1;

  formatted_raw_ostream FOS(Out->os());
  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));

  MCInstPrinter *IP = nullptr;
  if (FileType == OFT_AssemblyFile) {
    IP =
      TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);

    // Set the display preference for hex vs. decimal immediates.
    IP->setPrintImmHex(PrintImmHex);

    // Set up the AsmStreamer.
    MCCodeEmitter *CE = nullptr;
    MCAsmBackend *MAB = nullptr;
    if (ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    }
    Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/ true,
                                           /*useDwarfDirectory*/ true, IP, CE,
                                           MAB, ShowInst));

  } else if (FileType == OFT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
                                                FOS, CE, *STI, RelaxAll,
                                                NoExecStack));
  }

  int Res = 1;
  bool disassemble = false;
  switch (Action) {
  case AC_AsLex:
    Res = AsLexInput(SrcMgr, *MAI, Out.get());
    break;
  case AC_Assemble:
    Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII);
    break;
  case AC_MDisassemble:
    assert(IP && "Expected assembly output");
    IP->setUseMarkup(1);
    disassemble = true;
    break;
  case AC_Disassemble:
    disassemble = true;
    break;
  }
  if (disassemble)
    Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
                                    *Buffer, SrcMgr, Out->os());

  // Keep output if no errors.
  if (Res == 0) Out->keep();
  return Res;
}
示例#10
0
文件: TableGen.cpp 项目: Sciumo/llvm
int main(int argc, char **argv) {
  RecordKeeper Records;

  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv);


  try {
    // Parse the input file.
    OwningPtr<MemoryBuffer> File;
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
      errs() << "Could not open input file '" << InputFilename << "': "
             << ec.message() <<"\n";
      return 1;
    }
    MemoryBuffer *F = File.take();

    // Tell SrcMgr about this buffer, which is what TGParser will pick up.
    SrcMgr.AddNewSourceBuffer(F, SMLoc());

    // Record the location of the include directory so that the lexer can find
    // it later.
    SrcMgr.setIncludeDirs(IncludeDirs);

    TGParser Parser(SrcMgr, Records);

    if (Parser.ParseFile())
      return 1;

    std::string Error;
    tool_output_file Out(OutputFilename.c_str(), Error);
    if (!Error.empty()) {
      errs() << argv[0] << ": error opening " << OutputFilename
        << ":" << Error << "\n";
      return 1;
    }
    if (!DependFilename.empty()) {
      if (OutputFilename == "-") {
        errs() << argv[0] << ": the option -d must be used together with -o\n";
        return 1;
      }
      tool_output_file DepOut(DependFilename.c_str(), Error);
      if (!Error.empty()) {
        errs() << argv[0] << ": error opening " << DependFilename
          << ":" << Error << "\n";
        return 1;
      }
      DepOut.os() << DependFilename << ":";
      const std::vector<std::string> &Dependencies = Parser.getDependencies();
      for (std::vector<std::string>::const_iterator I = Dependencies.begin(),
                                                          E = Dependencies.end();
           I != E; ++I) {
        DepOut.os() << " " << (*I);
      }
      DepOut.os() << "\n";
      DepOut.keep();
    }

    switch (Action) {
    case PrintRecords:
      Out.os() << Records;           // No argument, dump all contents
      break;
    case GenEmitter:
      CodeEmitterGen(Records).run(Out.os());
      break;

    case GenRegisterEnums:
      RegisterInfoEmitter(Records).runEnums(Out.os());
      break;
    case GenRegister:
      RegisterInfoEmitter(Records).run(Out.os());
      break;
    case GenRegisterHeader:
      RegisterInfoEmitter(Records).runHeader(Out.os());
      break;
    case GenInstrEnums:
      InstrEnumEmitter(Records).run(Out.os());
      break;
    case GenInstrs:
      InstrInfoEmitter(Records).run(Out.os());
      break;
    case GenCallingConv:
      CallingConvEmitter(Records).run(Out.os());
      break;
    case GenAsmWriter:
      AsmWriterEmitter(Records).run(Out.os());
      break;
    case GenARMDecoder:
      ARMDecoderEmitter(Records).run(Out.os());
      break;
    case GenAsmMatcher:
      AsmMatcherEmitter(Records).run(Out.os());
      break;
    case GenClangAttrClasses:
      ClangAttrClassEmitter(Records).run(Out.os());
      break;
    case GenClangAttrImpl:
      ClangAttrImplEmitter(Records).run(Out.os());
      break;
    case GenClangAttrList:
      ClangAttrListEmitter(Records).run(Out.os());
      break;
    case GenClangAttrPCHRead:
      ClangAttrPCHReadEmitter(Records).run(Out.os());
      break;
    case GenClangAttrPCHWrite:
      ClangAttrPCHWriteEmitter(Records).run(Out.os());
      break;
    case GenClangAttrSpellingList:
      ClangAttrSpellingListEmitter(Records).run(Out.os());
      break;
    case GenClangDiagsDefs:
      ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os());
      break;
    case GenClangDiagGroups:
      ClangDiagGroupsEmitter(Records).run(Out.os());
      break;
    case GenClangDiagsIndexName:
      ClangDiagsIndexNameEmitter(Records).run(Out.os());
      break;
    case GenClangDeclNodes:
      ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os());
      ClangDeclContextEmitter(Records).run(Out.os());
      break;
    case GenClangStmtNodes:
      ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os());
      break;
    case GenClangSACheckers:
      ClangSACheckersEmitter(Records).run(Out.os());
      break;
    case GenDisassembler:
      DisassemblerEmitter(Records).run(Out.os());
      break;
    case GenOptParserDefs:
      OptParserEmitter(Records, true).run(Out.os());
      break;
    case GenOptParserImpl:
      OptParserEmitter(Records, false).run(Out.os());
      break;
    case GenDAGISel:
      DAGISelEmitter(Records).run(Out.os());
      break;
    case GenFastISel:
      FastISelEmitter(Records).run(Out.os());
      break;
    case GenSubtarget:
      SubtargetEmitter(Records).run(Out.os());
      break;
    case GenIntrinsic:
      IntrinsicEmitter(Records).run(Out.os());
      break;
    case GenTgtIntrinsic:
      IntrinsicEmitter(Records, true).run(Out.os());
      break;
    case GenLLVMCConf:
      LLVMCConfigurationEmitter(Records).run(Out.os());
      break;
    case GenEDInfo:
      EDEmitter(Records).run(Out.os());
      break;
    case GenArmNeon:
      NeonEmitter(Records).run(Out.os());
      break;
    case GenArmNeonSema:
      NeonEmitter(Records).runHeader(Out.os());
      break;
    case GenArmNeonTest:
      NeonEmitter(Records).runTests(Out.os());
      break;
    case PrintEnums:
    {
      std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
      for (unsigned i = 0, e = Recs.size(); i != e; ++i)
        Out.os() << Recs[i]->getName() << ", ";
      Out.os() << "\n";
      break;
    }
    case PrintSets:
    {
      SetTheory Sets;
      Sets.addFieldExpander("Set", "Elements");
      std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Set");
      for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
        Out.os() << Recs[i]->getName() << " = [";
        const std::vector<Record*> *Elts = Sets.expand(Recs[i]);
        assert(Elts && "Couldn't expand Set instance");
        for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei)
          Out.os() << ' ' << (*Elts)[ei]->getName();
        Out.os() << " ]\n";
      }
      break;
    }
    default:
      assert(1 && "Invalid Action");
      return 1;
    }

    // Declare success.
    Out.keep();
    return 0;

  } catch (const TGError &Error) {
    errs() << argv[0] << ": error:\n";
    PrintError(Error.getLoc(), Error.getMessage());

  } catch (const std::string &Error) {
    errs() << argv[0] << ": " << Error << "\n";
  } catch (const char *Error) {
    errs() << argv[0] << ": " << Error << "\n";
  } catch (...) {
    errs() << argv[0] << ": Unknown unexpected exception occurred.\n";
  }

  return 1;
}
示例#11
0
static bool ParseFile(const std::string &Filename,
                      const std::vector<std::string> &IncludeDirs,
                      SmallVectorImpl<std::string> &OutputFiles) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
      MemoryBuffer::getFileOrSTDIN(Filename);
  if (std::error_code EC = MBOrErr.getError()) {
    llvm::errs() << "Could not open input file '" << Filename << "': " 
                 << EC.message() <<"\n";
    return true;
  }
  std::unique_ptr<llvm::MemoryBuffer> MB = std::move(MBOrErr.get());

  // Record the location of the include directory so that the lexer can find it
  // later.
  SourceMgr SrcMgr;
  SrcMgr.setIncludeDirs(IncludeDirs);

  // Tell SrcMgr about this buffer, which is what Parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(MB), llvm::SMLoc());

  LangOptions Opts;
  Opts.DefaultReal8 = DefaultReal8;
  Opts.DefaultDouble8 = DefaultDouble8;
  Opts.DefaultInt8 = DefaultInt8;
  Opts.ReturnComments = ReturnComments;
  if(!FreeForm && !FixedForm) {
    llvm::StringRef Ext = llvm::sys::path::extension(Filename);
    if(Ext.equals_lower(".f")) {
      Opts.FixedForm = 1;
      Opts.FreeForm = 0;
    }
  } else if(FixedForm) {
    Opts.FixedForm = 1;
    Opts.FreeForm = 0;
  }

  TextDiagnosticPrinter TDP(SrcMgr);
  DiagnosticsEngine Diag(new DiagnosticIDs,&SrcMgr, &TDP, false);
  // Chain in -verify checker, if requested.
  if(RunVerifier)
    Diag.setClient(new VerifyDiagnosticConsumer(Diag));

  ASTContext Context(SrcMgr, Opts);
  Sema SA(Context, Diag);
  Parser P(SrcMgr, Opts, Diag, SA);
  Diag.getClient()->BeginSourceFile(Opts, &P.getLexer());
  P.ParseProgramUnits();
  Diag.getClient()->EndSourceFile();

  // Dump
  if(PrintAST || DumpAST) {
    auto Dumper = CreateASTDumper("");
    Dumper->HandleTranslationUnit(Context);
    delete Dumper;
  }

  // Emit
  if(!SyntaxOnly && !Diag.hadErrors()) {    
    flang::TargetOptions TargetOptions;
    TargetOptions.Triple = TargetTriple.empty()? llvm::sys::getDefaultTargetTriple() :
                                                 TargetTriple;
    TargetOptions.CPU = llvm::sys::getHostCPUName();

    auto CG = CreateLLVMCodeGen(Diag, Filename == ""? std::string("module") : Filename,
                                CodeGenOptions(), TargetOptions, llvm::getGlobalContext());
    CG->Initialize(Context);
    CG->HandleTranslationUnit(Context);

    BackendAction BA = Backend_EmitObj;
    if(EmitASM)   BA = Backend_EmitAssembly;
    if(EmitLLVM)  BA = Backend_EmitLL;

    const llvm::Target *TheTarget = 0;
    std::string Err;
    TheTarget = llvm::TargetRegistry::lookupTarget(TargetOptions.Triple, Err);

    CodeGenOpt::Level TMOptLevel = CodeGenOpt::Default;
    switch(OptLevel) {
    case 0:  TMOptLevel = CodeGenOpt::None; break;
    case 3:  TMOptLevel = CodeGenOpt::Aggressive; break;
    }

    llvm::TargetOptions Options;

    auto TM = TheTarget->createTargetMachine(TargetOptions.Triple, TargetOptions.CPU, "", Options,
                                             Reloc::Default, CodeModel::Default,
                                             TMOptLevel);

    if(!(EmitLLVM && OptLevel == 0)) {
      auto TheModule = CG->GetModule();
      auto PM = new llvm::legacy::PassManager();
      //llvm::legacy::FunctionPassManager *FPM = new llvm::legacy::FunctionPassManager(TheModule);
      //FPM->add(new DataLayoutPass());
      //PM->add(new llvm::DataLayoutPass());
      //TM->addAnalysisPasses(*PM);
      PM->add(createPromoteMemoryToRegisterPass());

      PassManagerBuilder PMBuilder;
      PMBuilder.OptLevel = OptLevel;
      PMBuilder.SizeLevel = 0;
      PMBuilder.LoopVectorize = true;
      PMBuilder.SLPVectorize = true;
      unsigned Threshold = 225;
      if (OptLevel > 2)
        Threshold = 275;
      PMBuilder.Inliner = createFunctionInliningPass(Threshold);


      PMBuilder.populateModulePassManager(*PM);
      //llvm::legacy::PassManager *MPM = new llvm::legacy::PassManager();
      //PMBuilder.populateModulePassManager(*MPM);

      PM->run(*TheModule);
      //MPM->run(*TheModule);
      delete PM;
      //delete MPM;
    }

    if(Interpret) {
      //const char *Env[] = { "", nullptr };
      //Execute(CG->ReleaseModule(), Env);
    } else if(OutputFile == "-"){
      // FIXME: outputting to stdout is broken 
      //EmitFile(llvm::outs(), CG->GetModule(), TM, BA);
      OutputFiles.push_back(GetOutputName("stdout",BA));
      EmitOutputFile(OutputFiles.back(), CG->GetModule(), TM, BA);
    }else {
      OutputFiles.push_back(GetOutputName(Filename, BA));
      EmitOutputFile(OutputFiles.back(), CG->GetModule(), TM, BA);
    }
    delete CG;
  }

  return Diag.hadErrors();
}
示例#12
0
static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
  if (!TheTarget) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, &Error);
  if (Buffer == 0) {
    Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
    return false;
  }

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  MCContext Ctx(*MAI);
  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
  if (!Out)
    return false;

  // FIXME: We shouldn't need to do this (and link in codegen).
  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(Opts.Triple, ""));
  if (!TM) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  OwningPtr<MCStreamer> Str;

  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP =
      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI);
    MCCodeEmitter *CE = 0;
    if (Opts.ShowEncoding)
      CE = TheTarget->createCodeEmitter(*TM, Ctx);
    Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(),
                                /*asmverbose*/true, IP, CE, Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
    TargetAsmBackend *TAB = TheTarget->createAsmBackend(Opts.Triple);
    Str.reset(TheTarget->createObjectStreamer(Opts.Triple, Ctx, *TAB, *Out,
                                              CE, Opts.RelaxAll));
  }

  OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
                                                  *Str.get(), *MAI));
  OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM));
  if (!TAP) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  Parser->setTargetParser(*TAP.get());

  bool Success = !Parser->Run(Opts.NoInitialTextSection);

  // Close the output.
  delete Out;

  // Delete output on errors.
  if (!Success && Opts.OutputPath != "-")
    sys::Path(Opts.OutputPath).eraseFromDisk();

  return Success;
}
示例#13
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
  if (!TheTarget)
    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);

  if (std::error_code EC = Buffer.getError()) {
    Error = EC.message();
    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
  }

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  if (Opts.CompressDebugSections)
    MAI->setCompressDebugSections(true);

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  std::unique_ptr<formatted_raw_ostream> Out(
      GetOutputStream(Opts, Diags, IsBinary));
  if (!Out)
    return true;

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());

  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  // FIXME: Assembler behavior can change with -static.
  MOFI->InitMCObjectFileInfo(Opts.Triple,
                             Reloc::Default, CodeModel::Default, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);
  if (Opts.GenDwarfForAssembly)
    Ctx.setGenDwarfForAssembly(true);
  if (!Opts.DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
  if (!Opts.DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
  if (!Opts.DebugCompilationDir.empty())
    Ctx.setCompilationDir(Opts.DebugCompilationDir);
  if (!Opts.MainFileName.empty())
    Ctx.setMainFileName(StringRef(Opts.MainFileName));
  Ctx.setDwarfVersion(Opts.DwarfVersion);

  // Build up the feature string from the target feature list.
  std::string FS;
  if (!Opts.Features.empty()) {
    FS = Opts.Features[0];
    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
      FS += "," + Opts.Features[i];
  }

  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP = TheTarget->createMCInstPrinter(
        llvm::Triple(Opts.Triple), Opts.OutputAsmVariant, *MAI, *MCII, *MRI);
    MCCodeEmitter *CE = nullptr;
    MCAsmBackend *MAB = nullptr;
    if (Opts.ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
    }
    Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB,
                                           Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
                                                      Opts.CPU);
    Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
                                                CE, *STI, Opts.RelaxAll));
    Str.get()->InitSections(Opts.NoExecStack);

    if (Opts.EmbedBitcode &&
        Ctx.getObjectFileInfo()->getObjectFileType() ==
                                 MCObjectFileInfo::IsMachO) {
      // When -fembed-bitcode is passed to clang_as, a 1-byte marker
      // is emitted in __LLVM,__asm section to tell the linker to add
      // the macho object into the bundle
      const MCSection *AsmLabel = Ctx.getMachOSection("__LLVM", "__asm",
                                      MachO::S_REGULAR, 4,
                                      SectionKind::getDataNoRel());
      Str.get()->SwitchSection(AsmLabel);
      Str.get()->EmitZeros(1);
    }
  }

  bool Failed = false;

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  // FIXME: init MCTargetOptions from sanitizer flags here.
  MCTargetOptions Options;
  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
  if (!TAP)
    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  if (!Failed) {
    Parser->setTargetParser(*TAP.get());
    Failed = Parser->Run(Opts.NoInitialTextSection);
  }

  // Close the output stream early.
  Out.reset();

  // Delete output file if there were errors.
  if (Failed && Opts.OutputPath != "-")
    sys::fs::remove(Opts.OutputPath);

  return Failed;
}
示例#14
0
static int AssembleInput(const char *ProgName) {
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;

  std::string Error;
  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error);
  if (Buffer == 0) {
    errs() << ProgName << ": ";
    if (Error.size())
      errs() << Error << "\n";
    else
      errs() << "input file didn't read correctly.\n";
    return 1;
  }
  
  SourceMgr SrcMgr;
  
  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
  
  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);
  
  
  llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName));
  assert(MAI && "Unable to create target asm info!");
  
  MCContext Ctx(*MAI);
  formatted_raw_ostream *Out = GetOutputStream();
  if (!Out)
    return 1;


  // FIXME: We shouldn't need to do this (and link in codegen).
  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, ""));

  if (!TM) {
    errs() << ProgName << ": error: could not create target for triple '"
           << TripleName << "'.\n";
    return 1;
  }

  OwningPtr<MCCodeEmitter> CE;
  OwningPtr<MCStreamer> Str;
  OwningPtr<TargetAsmBackend> TAB;

  if (FileType == OFT_AssemblyFile) {
    MCInstPrinter *IP =
      TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
    if (ShowEncoding)
      CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
    Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(),
                                /*asmverbose*/true, IP, CE.get(), ShowInst));
  } else if (FileType == OFT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");
    CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
    TAB.reset(TheTarget->createAsmBackend(TripleName));
    Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
                                              *Out, CE.get(), RelaxAll));
  }

  if (EnableLogging) {
    Str.reset(createLoggingStreamer(Str.take(), errs()));
  }

  OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
                                                   *Str.get(), *MAI));
  OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM));
  if (!TAP) {
    errs() << ProgName 
           << ": error: this target does not support assembly parsing.\n";
    return 1;
  }

  Parser->setTargetParser(*TAP.get());

  int Res = Parser->Run(NoInitialTextSection);
  delete Out;

  // Delete output on errors.
  if (Res && OutputFilename != "-")
    sys::Path(OutputFilename).eraseFromDisk();

  return Res;
}
示例#15
0
static int AsLexInput(const char *ProgName) {
    std::string ErrorMessage;
    MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
                           &ErrorMessage);
    if (Buffer == 0) {
        errs() << ProgName << ": ";
        if (ErrorMessage.size())
            errs() << ErrorMessage << "\n";
        else
            errs() << "input file didn't read correctly.\n";
        return 1;
    }

    SourceMgr SrcMgr;

    // Tell SrcMgr about this buffer, which is what TGParser will pick up.
    SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

    // Record the location of the include directories so that the lexer can find
    // it later.
    SrcMgr.setIncludeDirs(IncludeDirs);

    const Target *TheTarget = GetTarget(ProgName);
    if (!TheTarget)
        return 1;

    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName));
    assert(MAI && "Unable to create target asm info!");

    AsmLexer Lexer(*MAI);
    Lexer.setBuffer(SrcMgr.getMemoryBuffer(0));

    OwningPtr<tool_output_file> Out(GetOutputStream());
    if (!Out)
        return 1;

    bool Error = false;
    while (Lexer.Lex().isNot(AsmToken::Eof)) {
        switch (Lexer.getKind()) {
        default:
            SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
            Error = true;
            break;
        case AsmToken::Error:
            Error = true; // error already printed.
            break;
        case AsmToken::Identifier:
            Out->os() << "identifier: " << Lexer.getTok().getString() << '\n';
            break;
        case AsmToken::Integer:
            Out->os() << "int: " << Lexer.getTok().getString() << '\n';
            break;
        case AsmToken::Real:
            Out->os() << "real: " << Lexer.getTok().getString() << '\n';
            break;
        case AsmToken::Register:
            Out->os() << "register: " << Lexer.getTok().getRegVal() << '\n';
            break;
        case AsmToken::String:
            Out->os() << "string: " << Lexer.getTok().getString() << '\n';
            break;

        case AsmToken::Amp:
            Out->os() << "Amp\n";
            break;
        case AsmToken::AmpAmp:
            Out->os() << "AmpAmp\n";
            break;
        case AsmToken::At:
            Out->os() << "At\n";
            break;
        case AsmToken::Caret:
            Out->os() << "Caret\n";
            break;
        case AsmToken::Colon:
            Out->os() << "Colon\n";
            break;
        case AsmToken::Comma:
            Out->os() << "Comma\n";
            break;
        case AsmToken::Dollar:
            Out->os() << "Dollar\n";
            break;
        case AsmToken::Dot:
            Out->os() << "Dot\n";
            break;
        case AsmToken::EndOfStatement:
            Out->os() << "EndOfStatement\n";
            break;
        case AsmToken::Eof:
            Out->os() << "Eof\n";
            break;
        case AsmToken::Equal:
            Out->os() << "Equal\n";
            break;
        case AsmToken::EqualEqual:
            Out->os() << "EqualEqual\n";
            break;
        case AsmToken::Exclaim:
            Out->os() << "Exclaim\n";
            break;
        case AsmToken::ExclaimEqual:
            Out->os() << "ExclaimEqual\n";
            break;
        case AsmToken::Greater:
            Out->os() << "Greater\n";
            break;
        case AsmToken::GreaterEqual:
            Out->os() << "GreaterEqual\n";
            break;
        case AsmToken::GreaterGreater:
            Out->os() << "GreaterGreater\n";
            break;
        case AsmToken::Hash:
            Out->os() << "Hash\n";
            break;
        case AsmToken::LBrac:
            Out->os() << "LBrac\n";
            break;
        case AsmToken::LCurly:
            Out->os() << "LCurly\n";
            break;
        case AsmToken::LParen:
            Out->os() << "LParen\n";
            break;
        case AsmToken::Less:
            Out->os() << "Less\n";
            break;
        case AsmToken::LessEqual:
            Out->os() << "LessEqual\n";
            break;
        case AsmToken::LessGreater:
            Out->os() << "LessGreater\n";
            break;
        case AsmToken::LessLess:
            Out->os() << "LessLess\n";
            break;
        case AsmToken::Minus:
            Out->os() << "Minus\n";
            break;
        case AsmToken::Percent:
            Out->os() << "Percent\n";
            break;
        case AsmToken::Pipe:
            Out->os() << "Pipe\n";
            break;
        case AsmToken::PipePipe:
            Out->os() << "PipePipe\n";
            break;
        case AsmToken::Plus:
            Out->os() << "Plus\n";
            break;
        case AsmToken::RBrac:
            Out->os() << "RBrac\n";
            break;
        case AsmToken::RCurly:
            Out->os() << "RCurly\n";
            break;
        case AsmToken::RParen:
            Out->os() << "RParen\n";
            break;
        case AsmToken::Slash:
            Out->os() << "Slash\n";
            break;
        case AsmToken::Star:
            Out->os() << "Star\n";
            break;
        case AsmToken::Tilde:
            Out->os() << "Tilde\n";
            break;
        }
    }

    // Keep output if no errors.
    if (Error == 0) Out->keep();

    return Error;
}
示例#16
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
  if (!TheTarget)
    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);

  if (std::error_code EC = Buffer.getError()) {
    Error = EC.message();
    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
  }

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  if (Opts.CompressDebugSections)
    MAI->setCompressDebugSections(DebugCompressionType::DCT_ZlibGnu);

  MAI->setRelaxELFRelocations(Opts.RelaxELFRelocations);

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  std::unique_ptr<raw_fd_ostream> FDOS = getOutputStream(Opts, Diags, IsBinary);
  if (!FDOS)
    return true;

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());

  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);

  bool PIC = false;
  if (Opts.RelocationModel == "static") {
    PIC = false;
  } else if (Opts.RelocationModel == "pic") {
    PIC = true;
  } else {
    assert(Opts.RelocationModel == "dynamic-no-pic" &&
           "Invalid PIC model!");
    PIC = false;
  }

  MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, CodeModel::Default, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);
  if (Opts.GenDwarfForAssembly)
    Ctx.setGenDwarfForAssembly(true);
  if (!Opts.DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
  if (!Opts.DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
  if (!Opts.DebugCompilationDir.empty())
    Ctx.setCompilationDir(Opts.DebugCompilationDir);
  if (!Opts.MainFileName.empty())
    Ctx.setMainFileName(StringRef(Opts.MainFileName));
  Ctx.setDwarfVersion(Opts.DwarfVersion);

  // Build up the feature string from the target feature list.
  std::string FS;
  if (!Opts.Features.empty()) {
    FS = Opts.Features[0];
    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
      FS += "," + Opts.Features[i];
  }

  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

  raw_pwrite_stream *Out = FDOS.get();
  std::unique_ptr<buffer_ostream> BOS;

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP = TheTarget->createMCInstPrinter(
        llvm::Triple(Opts.Triple), Opts.OutputAsmVariant, *MAI, *MCII, *MRI);
    MCCodeEmitter *CE = nullptr;
    MCAsmBackend *MAB = nullptr;
    if (Opts.ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
      MCTargetOptions Options;
      MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU, Options);
    }
    auto FOut = llvm::make_unique<formatted_raw_ostream>(*Out);
    Str.reset(TheTarget->createAsmStreamer(
        Ctx, std::move(FOut), /*asmverbose*/ true,
        /*useDwarfDirectory*/ true, IP, CE, MAB, Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    if (!FDOS->supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(*FDOS);
      Out = BOS.get();
    }

    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
    MCTargetOptions Options;
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
                                                      Opts.CPU, Options);
    Triple T(Opts.Triple);
    Str.reset(TheTarget->createMCObjectStreamer(
        T, Ctx, *MAB, *Out, CE, *STI, Opts.RelaxAll,
        Opts.IncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ true));
    Str.get()->InitSections(Opts.NoExecStack);
  }

  bool Failed = false;

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  // FIXME: init MCTargetOptions from sanitizer flags here.
  MCTargetOptions Options;
  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
  if (!TAP)
    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  if (!Failed) {
    Parser->setTargetParser(*TAP.get());
    Failed = Parser->Run(Opts.NoInitialTextSection);
  }

  // Close Streamer first.
  // It might have a reference to the output stream.
  Str.reset();
  // Close the output stream early.
  BOS.reset();
  FDOS.reset();

  // Delete output file if there were errors.
  if (Failed && Opts.OutputPath != "-")
    sys::fs::remove(Opts.OutputPath);

  return Failed;
}