Exemplo n.º 1
0
// Checks that the given input gives a parse error. Makes sure that an error
// text is available and the parse fails.
static void ExpectParseError(StringRef Message, StringRef Input) {
  SourceMgr SM;
  yaml::Stream Stream(Input, SM);
  SM.setDiagHandler(SuppressDiagnosticsOutput);
  EXPECT_FALSE(Stream.validate()) << Message << ": " << Input;
  EXPECT_TRUE(Stream.failed()) << Message << ": " << Input;
}
Exemplo n.º 2
0
TEST(YAMLParser, DefaultDiagnosticFilename) {
  SourceMgr SM;

  SMDiagnostic GeneratedDiag;
  SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);

  // When we construct a YAML stream over an unnamed string,
  // the filename is hard-coded as "YAML".
  yaml::Stream UnnamedStream("[]", SM);
  UnnamedStream.printError(UnnamedStream.begin()->getRoot(), "Hello, World!");
  EXPECT_EQ("YAML", GeneratedDiag.getFilename());
}
Exemplo n.º 3
0
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, unsigned LocCookie) const {
  assert(!Str.empty() && "Can't emit empty inline asm block");
  
  // Remember if the buffer is nul terminated or not so we can avoid a copy.
  bool isNullTerminated = Str.back() == 0;
  if (isNullTerminated)
    Str = Str.substr(0, Str.size()-1);
  
  // If the output streamer is actually a .s file, just emit the blob textually.
  // This is useful in case the asm parser doesn't handle something but the
  // system assembler does.
  if (OutStreamer.hasRawTextSupport()) {
    OutStreamer.EmitRawText(Str);
    return;
  }
  
  SourceMgr SrcMgr;
  
  // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
  LLVMContext &LLVMCtx = MMI->getModule()->getContext();
  bool HasDiagHandler = false;
  if (void *DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler()) {
    SrcMgr.setDiagHandler((SourceMgr::DiagHandlerTy)(intptr_t)DiagHandler,
                          LLVMCtx.getInlineAsmDiagnosticContext(), LocCookie);
    HasDiagHandler = true;
  }
  
  MemoryBuffer *Buffer;
  if (isNullTerminated)
    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
  else
    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");

  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
  
  OwningPtr<MCAsmParser> Parser(createMCAsmParser(TM.getTarget(), SrcMgr,
                                                  OutContext, OutStreamer,
                                                  *MAI));
  OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(*Parser, TM));
  if (!TAP)
    report_fatal_error("Inline asm not supported by this streamer because"
                       " we don't have an asm parser for this target\n");
  Parser->setTargetParser(*TAP.get());

  // Don't implicitly switch to the text section before the asm.
  int Res = Parser->Run(/*NoInitialTextSection*/ true,
                        /*NoFinalize*/ true);
  if (Res && !HasDiagHandler)
    report_fatal_error("Error parsing inline asm\n");
}
Exemplo n.º 4
0
TEST(YAMLParser, DiagnosticFilenameFromBufferID) {
  SourceMgr SM;

  SMDiagnostic GeneratedDiag;
  SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);

  // When we construct a YAML stream over a named buffer,
  // we get its ID as filename in diagnostics.
  std::unique_ptr<MemoryBuffer> Buffer =
      MemoryBuffer::getMemBuffer("[]", "buffername.yaml");
  yaml::Stream Stream(Buffer->getMemBufferRef(), SM);
  Stream.printError(Stream.begin()->getRoot(), "Hello, World!");
  EXPECT_EQ("buffername.yaml", GeneratedDiag.getFilename());
}
VFSFromYAML *VFSFromYAML::create(MemoryBuffer *Buffer,
                                 SourceMgr::DiagHandlerTy DiagHandler,
                                 void *DiagContext,
                                 IntrusiveRefCntPtr<FileSystem> ExternalFS) {

  SourceMgr SM;
  yaml::Stream Stream(Buffer, SM);

  SM.setDiagHandler(DiagHandler, DiagContext);
  yaml::document_iterator DI = Stream.begin();
  yaml::Node *Root = DI->getRoot();
  if (DI == Stream.end() || !Root) {
    SM.PrintMessage(SMLoc(), SourceMgr::DK_Error, "expected root node");
    return NULL;
  }

  VFSFromYAMLParser P(Stream);

  std::unique_ptr<VFSFromYAML> FS(new VFSFromYAML(ExternalFS));
  if (!P.parse(Root, FS.get()))
    return NULL;

  return FS.release();
}
Exemplo n.º 6
0
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode) const {
#ifndef ANDROID_TARGET_BUILD
  assert(!Str.empty() && "Can't emit empty inline asm block");

  // Remember if the buffer is nul terminated or not so we can avoid a copy.
  bool isNullTerminated = Str.back() == 0;
  if (isNullTerminated)
    Str = Str.substr(0, Str.size()-1);

  // If the output streamer is actually a .s file, just emit the blob textually.
  // This is useful in case the asm parser doesn't handle something but the
  // system assembler does.
  if (OutStreamer.hasRawTextSupport()) {
    OutStreamer.EmitRawText(Str);
    return;
  }

  SourceMgr SrcMgr;
  SrcMgrDiagInfo DiagInfo;

  // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
  LLVMContext &LLVMCtx = MMI->getModule()->getContext();
  bool HasDiagHandler = false;
  if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) {
    // If the source manager has an issue, we arrange for SrcMgrDiagHandler
    // to be invoked, getting DiagInfo passed into it.
    DiagInfo.LocInfo = LocMDNode;
    DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
    DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
    SrcMgr.setDiagHandler(SrcMgrDiagHandler, &DiagInfo);
    HasDiagHandler = true;
  }

  MemoryBuffer *Buffer;
  if (isNullTerminated)
    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
  else
    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");

  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr,
                                                  OutContext, OutStreamer,
                                                  *MAI));

  // FIXME: It would be nice if we can avoid createing a new instance of
  // MCSubtargetInfo here given TargetSubtargetInfo is available. However,
  // we have to watch out for asm directives which can change subtarget
  // state. e.g. .code 16, .code 32.
  OwningPtr<MCSubtargetInfo>
    STI(TM.getTarget().createMCSubtargetInfo(TM.getTargetTriple(),
                                             TM.getTargetCPU(),
                                             TM.getTargetFeatureString()));
  OwningPtr<MCTargetAsmParser>
    TAP(TM.getTarget().createMCAsmParser(*STI, *Parser));
  if (!TAP)
    report_fatal_error("Inline asm not supported by this streamer because"
                       " we don't have an asm parser for this target\n");
  Parser->setTargetParser(*TAP.get());

  // Don't implicitly switch to the text section before the asm.
  int Res = Parser->Run(/*NoInitialTextSection*/ true,
                        /*NoFinalize*/ true);
  if (Res && !HasDiagHandler)
    report_fatal_error("Error parsing inline asm\n");
#endif // ANDROID_TARGET_BUILD
}
Exemplo n.º 7
0
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
                               InlineAsm::AsmDialect Dialect) const {
  assert(!Str.empty() && "Can't emit empty inline asm block");

  // Remember if the buffer is nul terminated or not so we can avoid a copy.
  bool isNullTerminated = Str.back() == 0;
  if (isNullTerminated)
    Str = Str.substr(0, Str.size()-1);

  // If the output streamer does not have mature MC support or the integrated
  // assembler has been disabled, just emit the blob textually.
  // Otherwise parse the asm and emit it via MC support.
  // This is useful in case the asm parser doesn't handle something but the
  // system assembler does.
  const MCAsmInfo *MCAI = TM.getMCAsmInfo();
  assert(MCAI && "No MCAsmInfo");
  if (!MCAI->useIntegratedAssembler() &&
      !OutStreamer.isIntegratedAssemblerRequired()) {
    emitInlineAsmStart(TM.getSubtarget<MCSubtargetInfo>());
    OutStreamer.EmitRawText(Str);
    emitInlineAsmEnd(TM.getSubtarget<MCSubtargetInfo>(), nullptr);
    return;
  }

  SourceMgr SrcMgr;
  SrcMgrDiagInfo DiagInfo;

  // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
  LLVMContext &LLVMCtx = MMI->getModule()->getContext();
  bool HasDiagHandler = false;
  if (LLVMCtx.getInlineAsmDiagnosticHandler() != nullptr) {
    // If the source manager has an issue, we arrange for srcMgrDiagHandler
    // to be invoked, getting DiagInfo passed into it.
    DiagInfo.LocInfo = LocMDNode;
    DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
    DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
    SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo);
    HasDiagHandler = true;
  }

  std::unique_ptr<MemoryBuffer> Buffer;
  if (isNullTerminated)
    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
  else
    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");

  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, OutContext, OutStreamer, *MAI));

  // Initialize the parser with a fresh subtarget info. It is better to use a
  // new STI here because the parser may modify it and we do not want those
  // modifications to persist after parsing the inlineasm. The modifications
  // made by the parser will be seen by the code emitters because it passes
  // the current STI down to the EncodeInstruction() method.
  std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
      TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString()));

  // Preserve a copy of the original STI because the parser may modify it.  For
  // example, when switching between arm and thumb mode. If the target needs to
  // emit code to return to the original state it can do so in
  // emitInlineAsmEnd().
  MCSubtargetInfo STIOrig = *STI;

  MCTargetOptions MCOptions;
  if (MF)
    MCOptions = MF->getTarget().Options.MCOptions;
  std::unique_ptr<MCTargetAsmParser> TAP(
      TM.getTarget().createMCAsmParser(*STI, *Parser, *MII, MCOptions));
  if (!TAP)
    report_fatal_error("Inline asm not supported by this streamer because"
                       " we don't have an asm parser for this target\n");
  Parser->setAssemblerDialect(Dialect);
  Parser->setTargetParser(*TAP.get());
  if (MF) {
    const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
    TAP->SetFrameRegister(TRI->getFrameRegister(*MF));
  }

  emitInlineAsmStart(STIOrig);
  // Don't implicitly switch to the text section before the asm.
  int Res = Parser->Run(/*NoInitialTextSection*/ true,
                        /*NoFinalize*/ true);
  emitInlineAsmEnd(STIOrig, STI.get());
  if (Res && !HasDiagHandler)
    report_fatal_error("Error parsing inline asm\n");
}
Exemplo n.º 8
0
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
                               const MCTargetOptions &MCOptions,
                               const MDNode *LocMDNode,
                               InlineAsm::AsmDialect Dialect) const {
  assert(!Str.empty() && "Can't emit empty inline asm block");

  // Remember if the buffer is nul terminated or not so we can avoid a copy.
  bool isNullTerminated = Str.back() == 0;
  if (isNullTerminated)
    Str = Str.substr(0, Str.size()-1);

  // If the output streamer does not have mature MC support or the integrated
  // assembler has been disabled, just emit the blob textually.
  // Otherwise parse the asm and emit it via MC support.
  // This is useful in case the asm parser doesn't handle something but the
  // system assembler does.
  const MCAsmInfo *MCAI = TM.getMCAsmInfo();
  assert(MCAI && "No MCAsmInfo");
  if (!MCAI->useIntegratedAssembler() &&
      !OutStreamer->isIntegratedAssemblerRequired()) {
    emitInlineAsmStart();
    OutStreamer->EmitRawText(Str);
    emitInlineAsmEnd(STI, nullptr);
    return;
  }

  SourceMgr SrcMgr;
  SrcMgrDiagInfo DiagInfo;

  // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
  LLVMContext &LLVMCtx = MMI->getModule()->getContext();
  bool HasDiagHandler = false;
  if (LLVMCtx.getInlineAsmDiagnosticHandler() != nullptr) {
    // If the source manager has an issue, we arrange for srcMgrDiagHandler
    // to be invoked, getting DiagInfo passed into it.
    DiagInfo.LocInfo = LocMDNode;
    DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
    DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
    SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo);
    HasDiagHandler = true;
  }

  std::unique_ptr<MemoryBuffer> Buffer;
  if (isNullTerminated)
    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
  else
    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");

  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI));

  // Create a temporary copy of the original STI because the parser may modify
  // it. For example, when switching between arm and thumb mode. If the target
  // needs to emit code to return to the original state it can do so in
  // emitInlineAsmEnd().
  MCSubtargetInfo TmpSTI = STI;

  // We create a new MCInstrInfo here since we might be at the module level
  // and not have a MachineFunction to initialize the TargetInstrInfo from and
  // we only need MCInstrInfo for asm parsing. We create one unconditionally
  // because it's not subtarget dependent.
  std::unique_ptr<MCInstrInfo> MII(TM.getTarget().createMCInstrInfo());
  std::unique_ptr<MCTargetAsmParser> TAP(TM.getTarget().createMCAsmParser(
      TmpSTI, *Parser, *MII, MCOptions));
  if (!TAP)
    report_fatal_error("Inline asm not supported by this streamer because"
                       " we don't have an asm parser for this target\n");
  Parser->setAssemblerDialect(Dialect);
  Parser->setTargetParser(*TAP.get());
  if (MF) {
    const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
    TAP->SetFrameRegister(TRI->getFrameRegister(*MF));
  }

  emitInlineAsmStart();
  // Don't implicitly switch to the text section before the asm.
  int Res = Parser->Run(/*NoInitialTextSection*/ true,
                        /*NoFinalize*/ true);
  emitInlineAsmEnd(STI, &TmpSTI);
  if (Res && !HasDiagHandler)
    report_fatal_error("Error parsing inline asm\n");
}
int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
                              SmallVectorImpl<AsmToken> &tokens,
                              const std::string &str) {
  int ret = 0;
  
  switch (Key.Arch) {
  default:
    return -1;
  case Triple::x86:
  case Triple::x86_64:
  case Triple::arm:
  case Triple::thumb:
    break;
  }
  
  const char *cStr = str.c_str();
  MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
  
  StringRef instName;
  SMLoc instLoc;
  
  SourceMgr sourceMgr;
  sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this));
  sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
  MCContext context(*AsmInfo, *MRI, NULL);
  OwningPtr<MCStreamer> streamer(createNullStreamer(context));
  OwningPtr<MCAsmParser> genericParser(createMCAsmParser(sourceMgr,
                                                         context, *streamer,
                                                         *AsmInfo));

  StringRef triple = tripleFromArch(Key.Arch);
  OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(triple, "", ""));
  OwningPtr<MCTargetAsmParser>
    TargetParser(Tgt->createMCAsmParser(*STI, *genericParser));
  
  AsmToken OpcodeToken = genericParser->Lex();
  AsmToken NextToken = genericParser->Lex();  // consume next token, because specificParser expects us to
    
  if (OpcodeToken.is(AsmToken::Identifier)) {
    instName = OpcodeToken.getString();
    instLoc = OpcodeToken.getLoc();
    
    if (NextToken.isNot(AsmToken::Eof) &&
        TargetParser->ParseInstruction(instName, instLoc, operands))
      ret = -1;
  } else {
    ret = -1;
  }
  
  ParserMutex.acquire();
  
  if (!ret) {
    GenericAsmLexer->setBuffer(buf);
  
    while (SpecificAsmLexer->Lex(),
           SpecificAsmLexer->isNot(AsmToken::Eof) &&
           SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) {
      if (SpecificAsmLexer->is(AsmToken::Error)) {
        ret = -1;
        break;
      }
      tokens.push_back(SpecificAsmLexer->getTok());
    }
  }

  ParserMutex.release();
  
  return ret;
}
Exemplo n.º 10
0
int LLVMTargetMachineAssembleToOutputStream(LLVMTargetMachineRef TM, LLVMMemoryBufferRef Mem, void *JOStream, LLVMBool RelaxAll, LLVMBool NoExecStack, char **ErrorMessage) {
  *ErrorMessage = NULL;

#if !defined(WIN32)
  locale_t loc = newlocale(LC_ALL_MASK, "C", 0);
  locale_t oldLoc = uselocale(loc);
#endif

  TargetMachine *TheTargetMachine = unwrap(TM);
  const Target *TheTarget = &(TheTargetMachine->getTarget());

  std::string TripleName = TheTargetMachine->getTargetTriple().str();
  std::string MCPU = TheTargetMachine->getTargetCPU().str();
  std::string FeaturesStr = TheTargetMachine->getTargetFeatureString().str();
  Reloc::Model RelocModel = TheTargetMachine->getRelocationModel();
  CodeModel::Model CMModel = TheTargetMachine->getCodeModel();

  std::unique_ptr<MemoryBuffer> Buffer(unwrap(Mem));

  std::string DiagStr;
  raw_string_ostream DiagStream(DiagStr);
  SourceMgr SrcMgr;
  SrcMgr.setDiagHandler(assembleDiagHandler, &DiagStream);

  // 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(IncludeDirs);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx);

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

  raw_java_ostream& Out = *((raw_java_ostream*) JOStream);

  std::unique_ptr<MCStreamer> Str;
  MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
  MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
  Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
                                              Out, CE, *STI, RelaxAll != 0));
  if (NoExecStack != 0)
    Str->InitSections(true);

  MCTargetOptions MCOptions;
  std::unique_ptr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, *Str, *MAI));
  std::unique_ptr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
  if (!TAP) {
    *ErrorMessage = strdup("this target does not support assembly parsing");
    goto done;
  }

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

  if (Parser->Run(false)) {
    *ErrorMessage = strdup(DiagStream.str().c_str());
    goto done;
  }
  Out.flush();

done:
#if !defined(WIN32)
  uselocale(oldLoc);
  freelocale(loc);
#endif
  return *ErrorMessage ? 1 : 0;
}