示例#1
0
文件: disasm.cpp 项目: Carreau/julia
void jl_dump_function_asm(const char *Fptr, size_t Fsize,
#ifndef USE_MCJIT
                          std::vector<JITEvent_EmittedFunctionDetails::LineStart> lineinfo,
#else
                          const object::ObjectFile *objectfile,
#endif
                          formatted_raw_ostream &stream)
{
    // Initialize targets and assembly printers/parsers.
    // Avoids hard-coded targets - will generally be only host CPU anyway.
    llvm::InitializeNativeTargetAsmParser();
    llvm::InitializeNativeTargetDisassembler();

    // Get the host information
    std::string TripleName;
    if (TripleName.empty())
        TripleName = sys::getDefaultTargetTriple();
    Triple TheTriple(Triple::normalize(TripleName));

    std::string MCPU = sys::getHostCPUName();
    SubtargetFeatures Features;
    Features.getDefaultSubtargetFeatures(TheTriple);

    std::string err;
    const Target* TheTarget = TargetRegistry::lookupTarget(TripleName, err);

    // Set up required helpers and streamer
#ifdef LLVM35
    std::unique_ptr<MCStreamer> Streamer;
#else
    OwningPtr<MCStreamer> Streamer;
#endif
    SourceMgr SrcMgr;

#ifdef LLVM35
    std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName));
#elif defined(LLVM34)
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName));
#else
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName));
#endif
    assert(MAI && "Unable to create target asm info!");

#ifdef LLVM35
    std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
#else
    llvm::OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
#endif
    assert(MRI && "Unable to create target register info!");

#ifdef LLVM35
    std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
#else
    OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
#endif
#ifdef LLVM34
    MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
#else
    MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
#endif
    MOFI->InitMCObjectFileInfo(TripleName, Reloc::Default, CodeModel::Default, Ctx);

    // Set up Subtarget and Disassembler
#ifdef LLVM35
    std::unique_ptr<MCSubtargetInfo>
        STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
    std::unique_ptr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI, Ctx));
#else
    OwningPtr<MCSubtargetInfo>
        STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
    OwningPtr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
#endif
    if (!DisAsm) {
        JL_PRINTF(JL_STDERR, "error: no disassembler for target", TripleName.c_str(), "\n");
        return;
    }

    unsigned OutputAsmVariant = 1;
    bool ShowEncoding = false;
    bool ShowInst = false;

#ifdef LLVM35
    std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
    std::unique_ptr<MCInstrAnalysis>
        MCIA(TheTarget->createMCInstrAnalysis(MCII.get()));
#else
    OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
    OwningPtr<MCInstrAnalysis>
        MCIA(TheTarget->createMCInstrAnalysis(MCII.get()));
#endif
    MCInstPrinter* IP =
        TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (ShowEncoding) {
        CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
#ifdef LLVM34
        MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
#else
        MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
#endif
    }

    Streamer.reset(TheTarget->createAsmStreamer(Ctx, stream, /*asmverbose*/true,
#ifndef LLVM35
                                           /*useLoc*/ true,
                                           /*useCFI*/ true,
#endif
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB, ShowInst));
#ifdef LLVM36
    Streamer->InitSections(true);
#else
    Streamer->InitSections();
#endif

    // Make the MemoryObject wrapper
#ifdef LLVM36
    ArrayRef<uint8_t> memoryObject(const_cast<uint8_t*>((const uint8_t*)Fptr),Fsize);
#else
    FuncMCView memoryObject(Fptr, Fsize);
#endif
    SymbolTable DisInfo(Ctx, memoryObject);

#ifdef USE_MCJIT
    if (!objectfile) return;
#ifdef LLVM36
    DIContext *di_ctx = DIContext::getDWARFContext(*objectfile);
#else
    DIContext *di_ctx = DIContext::getDWARFContext(const_cast<object::ObjectFile*>(objectfile));
#endif
    if (di_ctx == NULL) return;
    DILineInfoTable lineinfo = di_ctx->getLineInfoForAddressRange((size_t)Fptr, Fsize);
#else
    typedef std::vector<JITEvent_EmittedFunctionDetails::LineStart> LInfoVec;
#endif

    // Take two passes: In the first pass we record all branch labels,
    // in the second we actually perform the output
    for (int pass = 0; pass < 2; ++ pass) {
        DisInfo.setPass(pass);
        if (pass != 0) {
            // Switch to symbolic disassembly. We cannot do this
            // before the first pass, because this changes branch
            // targets from immediate values (constants) to
            // expressions, which are not handled correctly by
            // MCIA->evaluateBranch. (It should be possible to rewrite
            // this routine to handle this case correctly as well.)
            // Could add OpInfoLookup here
#ifdef LLVM35
            DisAsm->setSymbolizer(std::unique_ptr<MCSymbolizer>(new MCExternalSymbolizer(
                        Ctx,
                        std::unique_ptr<MCRelocationInfo>(new MCRelocationInfo(Ctx)),
                        OpInfoLookup,
                        SymbolLookup,
                        &DisInfo)));
#else
            DisAsm->setupForSymbolicDisassembly(
                    OpInfoLookup, SymbolLookup, &DisInfo, &Ctx);
#endif
        }


        uint64_t nextLineAddr = -1;
#ifdef USE_MCJIT
        // Set up the line info
        DILineInfoTable::iterator lineIter = lineinfo.begin();
        DILineInfoTable::iterator lineEnd = lineinfo.end();

        if (lineIter != lineEnd) {
            nextLineAddr = lineIter->first;
            if (pass != 0) {
#ifdef LLVM35
                stream << "Filename: " << lineIter->second.FileName << "\n";
#else
                stream << "Filename: " << lineIter->second.getFileName() << "\n";
#endif
            }
        }
#else
        // Set up the line info
        LInfoVec::iterator lineIter = lineinfo.begin();
        LInfoVec::iterator lineEnd  = lineinfo.end();

        if (lineIter != lineEnd) {
            nextLineAddr = (*lineIter).Address;
            DISubprogram debugscope = DISubprogram((*lineIter).Loc.getScope(jl_LLVMContext));
            if (pass != 0) {
                stream << "Filename: " << debugscope.getFilename() << "\n";
                stream << "Source line: " << (*lineIter).Loc.getLine() << "\n";
            }
        }
#endif

        uint64_t Index = 0;
        uint64_t absAddr = 0;
        uint64_t insSize = 0;

        // Do the disassembly
        for (Index = 0, absAddr = (uint64_t)Fptr;
             Index < Fsize; Index += insSize, absAddr += insSize) {

            if (nextLineAddr != (uint64_t)-1 && absAddr == nextLineAddr) {
#ifdef USE_MCJIT
#ifdef LLVM35
                if (pass != 0)
                    stream << "Source line: " << lineIter->second.Line << "\n";
#else
                if (pass != 0)
                    stream << "Source line: " << lineIter->second.getLine() << "\n";
#endif
                nextLineAddr = (++lineIter)->first;
#else
                if (pass != 0)
                    stream << "Source line: " << (*lineIter).Loc.getLine() << "\n";
                nextLineAddr = (*++lineIter).Address;
#endif
            }
            if (pass != 0) {
                // Uncomment this to output addresses for all instructions
                // stream << Index << ": ";
                const char *symbolName = DisInfo.lookupSymbol(Index);
                if (symbolName)
                    stream << symbolName << ":";
            }

            MCInst Inst;
            MCDisassembler::DecodeStatus S;
            S = DisAsm->getInstruction(Inst, insSize, memoryObject, Index,
                                      /*REMOVE*/ nulls(), nulls());
            switch (S) {
            case MCDisassembler::Fail:
                if (pass != 0)
                    SrcMgr.PrintMessage(SMLoc::getFromPointer(Fptr + Index),
                                        SourceMgr::DK_Warning,
                                        "invalid instruction encoding");
                if (insSize == 0)
                    insSize = 1; // skip illegible bytes
                break;

            case MCDisassembler::SoftFail:
                if (pass != 0)
                    SrcMgr.PrintMessage(SMLoc::getFromPointer(Fptr + Index),
                                        SourceMgr::DK_Warning,
                                        "potentially undefined instruction encoding");
                // Fall through

            case MCDisassembler::Success:
                if (pass == 0) {
                    // Pass 0: Record all branch targets
                    if (MCIA->isBranch(Inst)) {
                        uint64_t addr;
#ifdef LLVM35
                        if (MCIA->evaluateBranch(Inst, Index, insSize, addr))
#else
                        if ((addr = MCIA->evaluateBranch(Inst, Index, insSize)) != (uint64_t)-1)
#endif
                            DisInfo.insertAddress(addr);
                    }
                }
                else {
                    // Pass 1: Output instruction
#ifdef LLVM35
                    Streamer->EmitInstruction(Inst, *STI);
#else
                    Streamer->EmitInstruction(Inst);
#endif
                }
                break;
            }
        }

        if (pass == 0)
            DisInfo.createSymbols();
    }
}
示例#2
0
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv);

  SourceMgr SM;

  // Read the expected strings from the check file.
  std::vector<CheckString> CheckStrings;
  if (ReadCheckFile(SM, CheckStrings))
    return 2;

  // Open the file to check and add it to SourceMgr.
  OwningPtr<MemoryBuffer> File;
  if (error_code ec =
        MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
    errs() << "Could not open input file '" << InputFilename << "': "
           << ec.message() << '\n';
    return 2;
  }
  MemoryBuffer *F = File.take();

  if (F->getBufferSize() == 0) {
    errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
    return 2;
  }
  
  // Remove duplicate spaces in the input file if requested.
  // Remove DOS style line endings.
  F = CanonicalizeInputFile(F, NoCanonicalizeWhiteSpace);

  SM.AddNewSourceBuffer(F, SMLoc());

  /// VariableTable - This holds all the current filecheck variables.
  StringMap<StringRef> VariableTable;

  // Check that we have all of the expected strings, in order, in the input
  // file.
  StringRef Buffer = F->getBuffer();

  const char *LastMatch = Buffer.data();

  for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
    const CheckString &CheckStr = CheckStrings[StrNo];

    StringRef SearchFrom = Buffer;

    // Find StrNo in the file.
    size_t MatchLen = 0;
    size_t MatchPos = CheckStr.Pat.Match(Buffer, MatchLen, VariableTable);
    Buffer = Buffer.substr(MatchPos);

    // If we didn't find a match, reject the input.
    if (MatchPos == StringRef::npos) {
      PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
      return 1;
    }

    StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);

    // If this check is a "CHECK-NEXT", verify that the previous match was on
    // the previous line (i.e. that there is one newline between them).
    if (CheckStr.IsCheckNext) {
      // Count the number of newlines between the previous match and this one.
      assert(LastMatch != F->getBufferStart() &&
             "CHECK-NEXT can't be the first check in a file");

      unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
      if (NumNewLines == 0) {
        SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
                    CheckPrefix+"-NEXT: is on the same line as previous match");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        SourceMgr::DK_Note, "'next' match was here");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
                        "previous match was here");
        return 1;
      }

      if (NumNewLines != 1) {
        SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error, CheckPrefix+
                        "-NEXT: is not on the line after the previous match");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        SourceMgr::DK_Note, "'next' match was here");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
                        "previous match was here");
        return 1;
      }
    }

    // If this match had "not strings", verify that they don't exist in the
    // skipped region.
    for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size();
         ChunkNo != e; ++ChunkNo) {
      size_t MatchLen = 0;
      size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion,
                                                             MatchLen,
                                                             VariableTable);
      if (Pos == StringRef::npos) continue;

      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), SourceMgr::DK_Error,
                      CheckPrefix+"-NOT: string occurred!");
      SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first, SourceMgr::DK_Note,
                      CheckPrefix+"-NOT: pattern specified here");
      return 1;
    }


    // Otherwise, everything is good.  Step over the matched text and remember
    // the position after the match as the end of the last match.
    Buffer = Buffer.substr(MatchLen);
    LastMatch = Buffer.data();
  }

  return 0;
}
示例#3
0
文件: TableGen.cpp 项目: Sciumo/llvm
void llvm::PrintError(SMLoc ErrorLoc, const Twine &Msg) {
  SrcMgr.PrintMessage(ErrorLoc, Msg, "error");
}
示例#4
0
void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
                               const StringMap<StringRef> &VariableTable) const{
  // If this was a regular expression using variables, print the current
  // variable values.
  if (!VariableUses.empty()) {
    for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
      SmallString<256> Msg;
      raw_svector_ostream OS(Msg);
      StringRef Var = VariableUses[i].first;
      if (Var[0] == '@') {
        std::string Value;
        if (EvaluateExpression(Var, Value)) {
          OS << "with expression \"";
          OS.write_escaped(Var) << "\" equal to \"";
          OS.write_escaped(Value) << "\"";
        } else {
          OS << "uses incorrect expression \"";
          OS.write_escaped(Var) << "\"";
        }
      } else {
        StringMap<StringRef>::const_iterator it = VariableTable.find(Var);

        // Check for undefined variable references.
        if (it == VariableTable.end()) {
          OS << "uses undefined variable \"";
          OS.write_escaped(Var) << "\"";
        } else {
          OS << "with variable \"";
          OS.write_escaped(Var) << "\" equal to \"";
          OS.write_escaped(it->second) << "\"";
        }
      }

      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
                      OS.str());
    }
  }

  // Attempt to find the closest/best fuzzy match.  Usually an error happens
  // because some string in the output didn't exactly match. In these cases, we
  // would like to show the user a best guess at what "should have" matched, to
  // save them having to actually check the input manually.
  size_t NumLinesForward = 0;
  size_t Best = StringRef::npos;
  double BestQuality = 0;

  // Use an arbitrary 4k limit on how far we will search.
  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
    if (Buffer[i] == '\n')
      ++NumLinesForward;

    // Patterns have leading whitespace stripped, so skip whitespace when
    // looking for something which looks like a pattern.
    if (Buffer[i] == ' ' || Buffer[i] == '\t')
      continue;

    // Compute the "quality" of this match as an arbitrary combination of the
    // match distance and the number of lines skipped to get to this match.
    unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
    double Quality = Distance + (NumLinesForward / 100.);

    if (Quality < BestQuality || Best == StringRef::npos) {
      Best = i;
      BestQuality = Quality;
    }
  }

  // Print the "possible intended match here" line if we found something
  // reasonable and not equal to what we showed in the "scanning from here"
  // line.
  if (Best && Best != StringRef::npos && BestQuality < 50) {
      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
                      SourceMgr::DK_Note, "possible intended match here");

    // FIXME: If we wanted to be really friendly we would show why the match
    // failed, as it can be hard to spot simple one character differences.
  }
}
示例#5
0
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
/// Returns true in case of an error, false otherwise.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  OwningPtr<MemoryBuffer> File;
  if (error_code ec =
        MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), File)) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ec.message() << '\n';
    return true;
  }
  MemoryBuffer *F = File.take();

  // If we want to canonicalize whitespace, strip excess whitespace from the
  // buffer containing the CHECK lines. Remove DOS style line endings.
  F = CanonicalizeInputFile(F, NoCanonicalizeWhiteSpace);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();
  std::vector<std::pair<SMLoc, Pattern> > NotMatches;

  // LineNumber keeps track of the line on which CheckPrefix instances are
  // found.
  unsigned LineNumber = 1;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    size_t PrefixLoc = Buffer.find(CheckPrefix);
    // If we didn't find a match, we're done.
    if (PrefixLoc == StringRef::npos)
      break;

    LineNumber += Buffer.substr(0, PrefixLoc).count('\n');

    Buffer = Buffer.substr(PrefixLoc);

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+5);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");

    // Remember the location of the start of the pattern, for diagnostics.
    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());

    // Parse the pattern.
    Pattern P;
    if (P.ParsePattern(Buffer.substr(0, EOL), SM, LineNumber))
      return true;

    Buffer = Buffer.substr(EOL);

    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      SourceMgr::DK_Error,
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line");
      return true;
    }

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          P));
      continue;
    }

    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(P,
                                       PatternLoc,
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  // Add an EOF pattern for any trailing CHECK-NOTs.
  if (!NotMatches.empty()) {
    CheckStrings.push_back(CheckString(Pattern(true),
                                       SMLoc::getFromPointer(Buffer.data()),
                                       false));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  return false;
}
示例#6
0
文件: disasm.cpp 项目: falcong/julia
void jl_dump_function_asm(void* Fptr, size_t Fsize,
                          std::vector<JITEvent_EmittedFunctionDetails::LineStart> lineinfo,
                          formatted_raw_ostream &stream) {

    // Initialize targets and assembly printers/parsers.
    // Avoids hard-coded targets - will generally be only host CPU anyway.
    llvm::InitializeNativeTargetAsmParser();
    llvm::InitializeNativeTargetDisassembler();
  
    // Get the host information
    std::string TripleName;
    if (TripleName.empty())
        TripleName = sys::getDefaultTargetTriple();
    Triple TheTriple(Triple::normalize(TripleName));

    std::string MCPU = sys::getHostCPUName();
    SubtargetFeatures Features;
    Features.getDefaultSubtargetFeatures(TheTriple);

    std::string err;
    const Target* TheTarget = TargetRegistry::lookupTarget(TripleName, err);

    // Set up required helpers and streamer 
    OwningPtr<MCStreamer> Streamer;
    SourceMgr SrcMgr;

#ifdef LLVM34
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName));
#else
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName));
#endif
    assert(MAI && "Unable to create target asm info!");

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

    OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
#ifdef LLVM34
    MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
#else
    MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
#endif    
    MOFI->InitMCObjectFileInfo(TripleName, Reloc::Default, CodeModel::Default, Ctx);

    // Set up Subtarget and Disassembler
    OwningPtr<MCSubtargetInfo>
        STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
#ifdef LLVM35
    OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI, Ctx));
#else
    OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
#endif
    if (!DisAsm) {
        JL_PRINTF(JL_STDERR, "error: no disassembler for target", TripleName.c_str(), "\n");
        return;
    }

    unsigned OutputAsmVariant = 1;
    bool ShowEncoding = false;
    bool ShowInst = false;

    OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
    MCInstPrinter* IP =
        TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (ShowEncoding) {
        CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
#ifdef LLVM34
        MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
#else
        MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
#endif
    }

    Streamer.reset(TheTarget->createAsmStreamer(Ctx, stream, /*asmverbose*/true,
#ifndef LLVM35
                                           /*useLoc*/ true,
                                           /*useCFI*/ true,
#endif
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB, ShowInst));
    Streamer->InitSections();
    // Make the MemoryObject wrapper
    FuncMCView memoryObject(Fptr, Fsize);
  
    uint64_t Size;
    uint64_t Index;
    uint64_t absAddr;

    // Set up the line info
    typedef std::vector<JITEvent_EmittedFunctionDetails::LineStart> LInfoVec;
    LInfoVec::iterator lineIter = lineinfo.begin();
    lineIter = lineinfo.begin();
    uint64_t nextLineAddr = -1;
    DISubprogram debugscope;

    if (lineIter != lineinfo.end()) {
        nextLineAddr = (*lineIter).Address;
        debugscope = DISubprogram((*lineIter).Loc.getScope(jl_LLVMContext));

        stream << "Filename: " << debugscope.getFilename().data() << "\n";
        stream << "Source line: " << (*lineIter).Loc.getLine() << "\n";
    }
    
    // Do the disassembly
    for (Index = 0, absAddr = (uint64_t)Fptr;
         Index < memoryObject.getExtent(); Index += Size, absAddr += Size) {
        
        if (nextLineAddr != (uint64_t)-1 && absAddr == nextLineAddr) {
            stream << "Source line: " << (*lineIter).Loc.getLine() << "\n";
            nextLineAddr = (*++lineIter).Address;
        }

        MCInst Inst;

        MCDisassembler::DecodeStatus S;
        S = DisAsm->getInstruction(Inst, Size, memoryObject, Index,
                                  /*REMOVE*/ nulls(), nulls());
        switch (S) {
        case MCDisassembler::Fail:
        SrcMgr.PrintMessage(SMLoc::getFromPointer(memoryObject[Index]),
                            SourceMgr::DK_Warning,
                            "invalid instruction encoding");
        if (Size == 0)
            Size = 1; // skip illegible bytes
        break;

        case MCDisassembler::SoftFail:
        SrcMgr.PrintMessage(SMLoc::getFromPointer(memoryObject[Index]),
                            SourceMgr::DK_Warning,
                            "potentially undefined instruction encoding");
        // Fall through

        case MCDisassembler::Success:
        #ifdef LLVM35
            Streamer->EmitInstruction(Inst, *STI);
        #else
            Streamer->EmitInstruction(Inst);
        #endif
        break;
        }
    }
}
示例#7
0
bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM,
                           unsigned LineNumber) {
  this->LineNumber = LineNumber;
  PatternLoc = SMLoc::getFromPointer(PatternStr.data());

  // Ignore trailing whitespace.
  while (!PatternStr.empty() &&
         (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
    PatternStr = PatternStr.substr(0, PatternStr.size()-1);

  // Check that there is something on the line.
  if (PatternStr.empty()) {
    SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
                    "found empty check string with prefix '" +
                    CheckPrefix+":'");
    return true;
  }

  // Check to see if this is a fixed string, or if it has regex pieces.
  if (PatternStr.size() < 2 ||
      (PatternStr.find("{{") == StringRef::npos &&
       PatternStr.find("[[") == StringRef::npos)) {
    FixedStr = PatternStr;
    return false;
  }

  // Paren value #0 is for the fully matched string.  Any new parenthesized
  // values add from there.
  unsigned CurParen = 1;

  // Otherwise, there is at least one regex piece.  Build up the regex pattern
  // by escaping scary characters in fixed strings, building up one big regex.
  while (!PatternStr.empty()) {
    // RegEx matches.
    if (PatternStr.startswith("{{")) {
      // This is the start of a regex match.  Scan for the }}.
      size_t End = PatternStr.find("}}");
      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        SourceMgr::DK_Error,
                        "found start of regex string with no end '}}'");
        return true;
      }

      // Enclose {{}} patterns in parens just like [[]] even though we're not
      // capturing the result for any purpose.  This is required in case the
      // expression contains an alternation like: CHECK:  abc{{x|z}}def.  We
      // want this to turn into: "abc(x|z)def" not "abcx|zdef".
      RegExStr += '(';
      ++CurParen;

      if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
        return true;
      RegExStr += ')';

      PatternStr = PatternStr.substr(End+2);
      continue;
    }

    // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
    // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
    // second form is [[foo]] which is a reference to foo.  The variable name
    // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
    // it.  This is to catch some common errors.
    if (PatternStr.startswith("[[")) {
      // Find the closing bracket pair ending the match.  End is going to be an
      // offset relative to the beginning of the match string.
      size_t End = FindRegexVarEnd(PatternStr.substr(2));

      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        SourceMgr::DK_Error,
                        "invalid named regex reference, no ]] found");
        return true;
      }

      StringRef MatchStr = PatternStr.substr(2, End);
      PatternStr = PatternStr.substr(End+4);

      // Get the regex name (e.g. "foo").
      size_t NameEnd = MatchStr.find(':');
      StringRef Name = MatchStr.substr(0, NameEnd);

      if (Name.empty()) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
                        "invalid name in named regex: empty name");
        return true;
      }

      // Verify that the name/expression is well formed. FileCheck currently
      // supports @LINE, @LINE+number, @LINE-number expressions. The check here
      // is relaxed, more strict check is performed in \c EvaluateExpression.
      bool IsExpression = false;
      for (unsigned i = 0, e = Name.size(); i != e; ++i) {
        if (i == 0 && Name[i] == '@') {
          if (NameEnd != StringRef::npos) {
            SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                            SourceMgr::DK_Error,
                            "invalid name in named regex definition");
            return true;
          }
          IsExpression = true;
          continue;
        }
        if (Name[i] != '_' && !isalnum(Name[i]) &&
            (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
          SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
                          SourceMgr::DK_Error, "invalid name in named regex");
          return true;
        }
      }

      // Name can't start with a digit.
      if (isdigit(static_cast<unsigned char>(Name[0]))) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
                        "invalid name in named regex");
        return true;
      }

      // Handle [[foo]].
      if (NameEnd == StringRef::npos) {
        // Handle variables that were defined earlier on the same line by
        // emitting a backreference.
        if (VariableDefs.find(Name) != VariableDefs.end()) {
          unsigned VarParenNum = VariableDefs[Name];
          if (VarParenNum < 1 || VarParenNum > 9) {
            SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                            SourceMgr::DK_Error,
                            "Can't back-reference more than 9 variables");
            return true;
          }
          AddBackrefToRegEx(VarParenNum);
        } else {
          VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
        }
        continue;
      }

      // Handle [[foo:.*]].
      VariableDefs[Name] = CurParen;
      RegExStr += '(';
      ++CurParen;

      if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
        return true;

      RegExStr += ')';
    }

    // Handle fixed string matches.
    // Find the end, which is the start of the next regex.
    size_t FixedMatchEnd = PatternStr.find("{{");
    FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
    AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr);
    PatternStr = PatternStr.substr(FixedMatchEnd);
  }

  return false;
}
示例#8
0
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  // Open the check file, and tell SourceMgr about it.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // If we want to canonicalize whitespace, strip excess whitespace from the
  // buffer containing the CHECK lines.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();

  std::vector<std::pair<SMLoc, Pattern> > NotMatches;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    Buffer = Buffer.substr(Buffer.find(CheckPrefix));

    // If we didn't find a match, we're done.
    if (Buffer.empty())
      break;

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+7);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");

    // Remember the location of the start of the pattern, for diagnostics.
    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());

    // Parse the pattern.
    Pattern P;
    if (P.ParsePattern(Buffer.substr(0, EOL), SM))
      return true;

    Buffer = Buffer.substr(EOL);


    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line", "error");
      return true;
    }

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          P));
      continue;
    }


    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(P,
                                       PatternLoc,
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  if (!NotMatches.empty()) {
    errs() << "error: '" << CheckPrefix
           << "-NOT:' not supported after last check line.\n";
    return true;
  }

  return false;
}
示例#9
0
文件: llvm-mc.cpp 项目: JaredCJR/llvm
static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI,
                      raw_ostream &OS) {

  AsmLexer Lexer(MAI);
  Lexer.setBuffer(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer());

  bool Error = false;
  while (Lexer.Lex().isNot(AsmToken::Eof)) {
    const AsmToken &Tok = Lexer.getTok();

    switch (Tok.getKind()) {
    default:
      SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning,
                          "unknown token");
      Error = true;
      break;
    case AsmToken::Error:
      Error = true; // error already printed.
      break;
    case AsmToken::Identifier:
      OS << "identifier: " << Lexer.getTok().getString();
      break;
    case AsmToken::Integer:
      OS << "int: " << Lexer.getTok().getString();
      break;
    case AsmToken::Real:
      OS << "real: " << Lexer.getTok().getString();
      break;
    case AsmToken::String:
      OS << "string: " << Lexer.getTok().getString();
      break;

    case AsmToken::Amp:            OS << "Amp"; break;
    case AsmToken::AmpAmp:         OS << "AmpAmp"; break;
    case AsmToken::At:             OS << "At"; break;
    case AsmToken::Caret:          OS << "Caret"; break;
    case AsmToken::Colon:          OS << "Colon"; break;
    case AsmToken::Comma:          OS << "Comma"; break;
    case AsmToken::Dollar:         OS << "Dollar"; break;
    case AsmToken::Dot:            OS << "Dot"; break;
    case AsmToken::EndOfStatement: OS << "EndOfStatement"; break;
    case AsmToken::Eof:            OS << "Eof"; break;
    case AsmToken::Equal:          OS << "Equal"; break;
    case AsmToken::EqualEqual:     OS << "EqualEqual"; break;
    case AsmToken::Exclaim:        OS << "Exclaim"; break;
    case AsmToken::ExclaimEqual:   OS << "ExclaimEqual"; break;
    case AsmToken::Greater:        OS << "Greater"; break;
    case AsmToken::GreaterEqual:   OS << "GreaterEqual"; break;
    case AsmToken::GreaterGreater: OS << "GreaterGreater"; break;
    case AsmToken::Hash:           OS << "Hash"; break;
    case AsmToken::LBrac:          OS << "LBrac"; break;
    case AsmToken::LCurly:         OS << "LCurly"; break;
    case AsmToken::LParen:         OS << "LParen"; break;
    case AsmToken::Less:           OS << "Less"; break;
    case AsmToken::LessEqual:      OS << "LessEqual"; break;
    case AsmToken::LessGreater:    OS << "LessGreater"; break;
    case AsmToken::LessLess:       OS << "LessLess"; break;
    case AsmToken::Minus:          OS << "Minus"; break;
    case AsmToken::Percent:        OS << "Percent"; break;
    case AsmToken::Pipe:           OS << "Pipe"; break;
    case AsmToken::PipePipe:       OS << "PipePipe"; break;
    case AsmToken::Plus:           OS << "Plus"; break;
    case AsmToken::RBrac:          OS << "RBrac"; break;
    case AsmToken::RCurly:         OS << "RCurly"; break;
    case AsmToken::RParen:         OS << "RParen"; break;
    case AsmToken::Slash:          OS << "Slash"; break;
    case AsmToken::Star:           OS << "Star"; break;
    case AsmToken::Tilde:          OS << "Tilde"; break;
    case AsmToken::PercentCall16:
      OS << "PercentCall16";
      break;
    case AsmToken::PercentCall_Hi:
      OS << "PercentCall_Hi";
      break;
    case AsmToken::PercentCall_Lo:
      OS << "PercentCall_Lo";
      break;
    case AsmToken::PercentDtprel_Hi:
      OS << "PercentDtprel_Hi";
      break;
    case AsmToken::PercentDtprel_Lo:
      OS << "PercentDtprel_Lo";
      break;
    case AsmToken::PercentGot:
      OS << "PercentGot";
      break;
    case AsmToken::PercentGot_Disp:
      OS << "PercentGot_Disp";
      break;
    case AsmToken::PercentGot_Hi:
      OS << "PercentGot_Hi";
      break;
    case AsmToken::PercentGot_Lo:
      OS << "PercentGot_Lo";
      break;
    case AsmToken::PercentGot_Ofst:
      OS << "PercentGot_Ofst";
      break;
    case AsmToken::PercentGot_Page:
      OS << "PercentGot_Page";
      break;
    case AsmToken::PercentGottprel:
      OS << "PercentGottprel";
      break;
    case AsmToken::PercentGp_Rel:
      OS << "PercentGp_Rel";
      break;
    case AsmToken::PercentHi:
      OS << "PercentHi";
      break;
    case AsmToken::PercentHigher:
      OS << "PercentHigher";
      break;
    case AsmToken::PercentHighest:
      OS << "PercentHighest";
      break;
    case AsmToken::PercentLo:
      OS << "PercentLo";
      break;
    case AsmToken::PercentNeg:
      OS << "PercentNeg";
      break;
    case AsmToken::PercentPcrel_Hi:
      OS << "PercentPcrel_Hi";
      break;
    case AsmToken::PercentPcrel_Lo:
      OS << "PercentPcrel_Lo";
      break;
    case AsmToken::PercentTlsgd:
      OS << "PercentTlsgd";
      break;
    case AsmToken::PercentTlsldm:
      OS << "PercentTlsldm";
      break;
    case AsmToken::PercentTprel_Hi:
      OS << "PercentTprel_Hi";
      break;
    case AsmToken::PercentTprel_Lo:
      OS << "PercentTprel_Lo";
      break;
    }

    // Print the token string.
    OS << " (\"";
    OS.write_escaped(Tok.getString());
    OS << "\")\n";
  }

  return Error;
}
示例#10
0
void PrintError(const char *Loc, const Twine &Msg) {
  SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
}
示例#11
0
bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
  PatternLoc = SMLoc::getFromPointer(PatternStr.data());

  // Ignore trailing whitespace.
  while (!PatternStr.empty() &&
         (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
    PatternStr = PatternStr.substr(0, PatternStr.size()-1);

  // Check that there is something on the line.
  if (PatternStr.empty()) {
    SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
                    CheckPrefix+":'", "error");
    return true;
  }

  // Check to see if this is a fixed string, or if it has regex pieces.
  if (PatternStr.size() < 2 ||
      (PatternStr.find("{{") == StringRef::npos &&
       PatternStr.find("[[") == StringRef::npos)) {
    FixedStr = PatternStr;
    return false;
  }

  // Paren value #0 is for the fully matched string.  Any new parenthesized
  // values add from their.
  unsigned CurParen = 1;

  // Otherwise, there is at least one regex piece.  Build up the regex pattern
  // by escaping scary characters in fixed strings, building up one big regex.
  while (!PatternStr.empty()) {
    // RegEx matches.
    if (PatternStr.size() >= 2 &&
        PatternStr[0] == '{' && PatternStr[1] == '{') {

      // Otherwise, this is the start of a regex match.  Scan for the }}.
      size_t End = PatternStr.find("}}");
      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        "found start of regex string with no end '}}'", "error");
        return true;
      }

      if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
        return true;
      PatternStr = PatternStr.substr(End+2);
      continue;
    }

    // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
    // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
    // second form is [[foo]] which is a reference to foo.  The variable name
    // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
    // it.  This is to catch some common errors.
    if (PatternStr.size() >= 2 &&
        PatternStr[0] == '[' && PatternStr[1] == '[') {
      // Verify that it is terminated properly.
      size_t End = PatternStr.find("]]");
      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        "invalid named regex reference, no ]] found", "error");
        return true;
      }

      StringRef MatchStr = PatternStr.substr(2, End-2);
      PatternStr = PatternStr.substr(End+2);

      // Get the regex name (e.g. "foo").
      size_t NameEnd = MatchStr.find(':');
      StringRef Name = MatchStr.substr(0, NameEnd);

      if (Name.empty()) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                        "invalid name in named regex: empty name", "error");
        return true;
      }

      // Verify that the name is well formed.
      for (unsigned i = 0, e = Name.size(); i != e; ++i)
        if (Name[i] != '_' &&
            (Name[i] < 'a' || Name[i] > 'z') &&
            (Name[i] < 'A' || Name[i] > 'Z') &&
            (Name[i] < '0' || Name[i] > '9')) {
          SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
                          "invalid name in named regex", "error");
          return true;
        }

      // Name can't start with a digit.
      if (isdigit(Name[0])) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                        "invalid name in named regex", "error");
        return true;
      }

      // Handle [[foo]].
      if (NameEnd == StringRef::npos) {
        VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
        continue;
      }

      // Handle [[foo:.*]].
      VariableDefs.push_back(std::make_pair(Name, CurParen));
      RegExStr += '(';
      ++CurParen;

      if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
        return true;

      RegExStr += ')';
    }

    // Handle fixed string matches.
    // Find the end, which is the start of the next regex.
    size_t FixedMatchEnd = PatternStr.find("{{");
    FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
    AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr);
    PatternStr = PatternStr.substr(FixedMatchEnd);
    continue;
  }

  return false;
}
示例#12
0
void PrintWarning(const char *Loc, const Twine &Msg) {
  SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg);
}
示例#13
0
static void parseMCMarkup(StringRef Filename) {
  OwningPtr<MemoryBuffer> BufferPtr;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, BufferPtr)) {
    errs() << ToolName << ": " << ec.message() << '\n';
    return;
  }
  MemoryBuffer *Buffer = BufferPtr.take();

  SourceMgr SrcMgr;

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

  StringRef InputSource = Buffer->getBuffer();
  MarkupLexer Lex(InputSource);
  MarkupParser Parser(Lex, SrcMgr);

  SmallVector<MarkupTag, 4> TagStack;

  for (int CurChar = Lex.getNextChar();
       CurChar != EOF;
       CurChar = Lex.getNextChar()) {
    switch (CurChar) {
    case '<': {
      // A "<<" is output as a literal '<' and does not start a markup tag.
      if (Lex.peekNextChar() == '<') {
        (void)Lex.getNextChar();
        break;
      }
      // Parse the markup entry.
      TagStack.push_back(Parser.parseTag());

      // Do any special handling for the start of a tag.
      processStartTag(TagStack.back());
      continue;
    }
    case '>': {
      SMLoc Loc = SMLoc::getFromPointer(Lex.getPosition() - 1);
      // A ">>" is output as a literal '>' and does not end a markup tag.
      if (Lex.peekNextChar() == '>') {
        (void)Lex.getNextChar();
        break;
      }
      // Close out the innermost tag.
      if (TagStack.empty())
        Parser.FatalError(Loc, "'>' without matching '<'");

      // Do any special handling for the end of a tag.
      processEndTag(TagStack.back());

      TagStack.pop_back();
      continue;
    }
    default:
      break;
    }
    // For anything else, just echo the character back out.
    if (!DumpTags && CurChar != EOF)
      outs() << (char)CurChar;
  }

  // If there are any unterminated markup tags, issue diagnostics for them.
  while (!TagStack.empty()) {
    MarkupTag &Tag = TagStack.back();
    SrcMgr.PrintMessage(Tag.getLoc(), SourceMgr::DK_Error,
                        "unterminated markup tag");
    TagStack.pop_back();
  }
}
示例#14
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));

  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:
      outs() << "identifier: " << 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;
}
示例#15
0
static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) {

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

  bool Error = false;
  while (Lexer.Lex().isNot(AsmToken::Eof)) {
    AsmToken Tok = Lexer.getTok();

    switch (Tok.getKind()) {
    default:
      SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning,
                          "unknown token");
      Error = true;
      break;
    case AsmToken::Error:
      Error = true; // error already printed.
      break;
    case AsmToken::Identifier:
      Out->os() << "identifier: " << Lexer.getTok().getString();
      break;
    case AsmToken::Integer:
      Out->os() << "int: " << Lexer.getTok().getString();
      break;
    case AsmToken::Real:
      Out->os() << "real: " << Lexer.getTok().getString();
      break;
    case AsmToken::String:
      Out->os() << "string: " << Lexer.getTok().getString();
      break;

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

    // Print the token string.
    Out->os() << " (\"";
    Out->os().write_escaped(Tok.getString());
    Out->os() << "\")\n";
  }

  return Error;
}
示例#16
0
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
/// Returns true in case of an error, false otherwise.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  std::unique_ptr<MemoryBuffer> File;
  if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(CheckFilename, File)) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ec.message() << '\n';
    return true;
  }

  // If we want to canonicalize whitespace, strip excess whitespace from the
  // buffer containing the CHECK lines. Remove DOS style line endings.
  MemoryBuffer *F =
    CanonicalizeInputFile(File.release(), NoCanonicalizeWhiteSpace);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();
  std::vector<Pattern> DagNotMatches;

  // LineNumber keeps track of the line on which CheckPrefix instances are
  // found.
  unsigned LineNumber = 1;

  while (1) {
    Check::CheckType CheckTy;
    size_t PrefixLoc;

    // See if a prefix occurs in the memory buffer.
    StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
                                                   LineNumber,
                                                   CheckTy,
                                                   PrefixLoc);
    if (UsedPrefix.empty())
      break;

    Buffer = Buffer.drop_front(PrefixLoc);

    // Location to use for error messages.
    const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);

    // PrefixLoc is to the start of the prefix. Skip to the end.
    Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));

    // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
    // leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");

    // Remember the location of the start of the pattern, for diagnostics.
    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());

    // Parse the pattern.
    Pattern P(CheckTy);
    if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
      return true;

    // Verify that CHECK-LABEL lines do not define or use variables
    if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
      SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
                      SourceMgr::DK_Error,
                      "found '" + UsedPrefix + "-LABEL:'"
                      " with variable definition or use");
      return true;
    }

    Buffer = Buffer.substr(EOL);

    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
                      SourceMgr::DK_Error,
                      "found '" + UsedPrefix + "-NEXT:' without previous '"
                      + UsedPrefix + ": line");
      return true;
    }

    // Handle CHECK-DAG/-NOT.
    if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
      DagNotMatches.push_back(P);
      continue;
    }

    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(P,
                                       UsedPrefix,
                                       PatternLoc,
                                       CheckTy));
    std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
  }

  // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
  // prefix as a filler for the error message.
  if (!DagNotMatches.empty()) {
    CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF),
                                       CheckPrefixes[0],
                                       SMLoc::getFromPointer(Buffer.data()),
                                       Check::CheckEOF));
    std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix"
           << (CheckPrefixes.size() > 1 ? "es " : " ");
    for (size_t I = 0, N = CheckPrefixes.size(); I != N; ++I) {
      StringRef Prefix(CheckPrefixes[I]);
      errs() << '\'' << Prefix << ":'";
      if (I != N - 1)
        errs() << ", ";
    }

    errs() << '\n';
    return true;
  }

  return false;
}
示例#17
0
size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
                             std::vector<const Pattern *> &NotStrings,
                             StringMap<StringRef> &VariableTable) const {
  if (DagNotStrings.empty())
    return 0;

  size_t LastPos = 0;
  size_t StartPos = LastPos;

  for (unsigned ChunkNo = 0, e = DagNotStrings.size();
       ChunkNo != e; ++ChunkNo) {
    const Pattern &Pat = DagNotStrings[ChunkNo];

    assert((Pat.getCheckTy() == Check::CheckDAG ||
            Pat.getCheckTy() == Check::CheckNot) &&
           "Invalid CHECK-DAG or CHECK-NOT!");

    if (Pat.getCheckTy() == Check::CheckNot) {
      NotStrings.push_back(&Pat);
      continue;
    }

    assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");

    size_t MatchLen = 0, MatchPos;

    // CHECK-DAG always matches from the start.
    StringRef MatchBuffer = Buffer.substr(StartPos);
    MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
    // With a group of CHECK-DAGs, a single mismatching means the match on
    // that group of CHECK-DAGs fails immediately.
    if (MatchPos == StringRef::npos) {
      PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
      return StringRef::npos;
    }
    // Re-calc it as the offset relative to the start of the original string.
    MatchPos += StartPos;

    if (!NotStrings.empty()) {
      if (MatchPos < LastPos) {
        // Reordered?
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
                        SourceMgr::DK_Error,
                        Prefix + "-DAG: found a match of CHECK-DAG"
                        " reordering across a CHECK-NOT");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
                        SourceMgr::DK_Note,
                        Prefix + "-DAG: the farthest match of CHECK-DAG"
                        " is found here");
        SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
                        Prefix + "-NOT: the crossed pattern specified"
                        " here");
        SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
                        Prefix + "-DAG: the reordered pattern specified"
                        " here");
        return StringRef::npos;
      }
      // All subsequent CHECK-DAGs should be matched from the farthest
      // position of all precedent CHECK-DAGs (including this one.)
      StartPos = LastPos;
      // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
      // CHECK-DAG, verify that there's no 'not' strings occurred in that
      // region.
      StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
      if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
        return StringRef::npos;
      // Clear "not strings".
      NotStrings.clear();
    }

    // Update the last position with CHECK-DAG matches.
    LastPos = std::max(MatchPos + MatchLen, LastPos);
  }

  return LastPos;
}
示例#18
0
int Disassembler::disassemble(const Target &T,
                              const std::string &Triple,
                              MCSubtargetInfo &STI,
                              MCStreamer &Streamer,
                              MemoryBuffer &Buffer,
                              SourceMgr &SM,
                              raw_ostream &Out) {

  std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
  if (!MRI) {
    errs() << "error: no register info for target " << Triple << "\n";
    return -1;
  }

  std::unique_ptr<const MCAsmInfo> MAI(T.createMCAsmInfo(*MRI, Triple));
  if (!MAI) {
    errs() << "error: no assembly info for target " << Triple << "\n";
    return -1;
  }

  // Set up the MCContext for creating symbols and MCExpr's.
  MCContext Ctx(MAI.get(), MRI.get(), nullptr);

  std::unique_ptr<const MCDisassembler> DisAsm(
    T.createMCDisassembler(STI, Ctx));
  if (!DisAsm) {
    errs() << "error: no disassembler for target " << Triple << "\n";
    return -1;
  }

  // Set up initial section manually here
  Streamer.InitSections(false);

  bool ErrorOccurred = false;

  // Convert the input to a vector for disassembly.
  ByteArrayTy ByteArray;
  StringRef Str = Buffer.getBuffer();
  bool InAtomicBlock = false;

  while (SkipToToken(Str)) {
    ByteArray.first.clear();
    ByteArray.second.clear();

    if (Str[0] == '[') {
      if (InAtomicBlock) {
        SM.PrintMessage(SMLoc::getFromPointer(Str.data()), SourceMgr::DK_Error,
                        "nested atomic blocks make no sense");
        ErrorOccurred = true;
      }
      InAtomicBlock = true;
      Str = Str.drop_front();
      continue;
    } else if (Str[0] == ']') {
      if (!InAtomicBlock) {
        SM.PrintMessage(SMLoc::getFromPointer(Str.data()), SourceMgr::DK_Error,
                        "attempt to close atomic block without opening");
        ErrorOccurred = true;
      }
      InAtomicBlock = false;
      Str = Str.drop_front();
      continue;
    }

    // It's a real token, get the bytes and emit them
    ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM);

    if (!ByteArray.first.empty())
      ErrorOccurred |= PrintInsts(*DisAsm, ByteArray, SM, Out, Streamer,
                                  InAtomicBlock, STI);
  }

  if (InAtomicBlock) {
    SM.PrintMessage(SMLoc::getFromPointer(Str.data()), SourceMgr::DK_Error,
                    "unclosed atomic block");
    ErrorOccurred = true;
  }

  return ErrorOccurred;
}