Exemplo n.º 1
0
void html::EscapeText(Rewriter &R, FileID FID,
                      bool EscapeSpaces, bool ReplaceTabs) {

  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
  const char* C = Buf->getBufferStart();
  const char* FileEnd = Buf->getBufferEnd();

  assert (C <= FileEnd);

  RewriteBuffer &RB = R.getEditBuffer(FID);

  unsigned ColNo = 0;
  for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) {
    switch (*C) {
    default: ++ColNo; break;
    case '\n':
    case '\r':
      ColNo = 0;
      break;

    case ' ':
      if (EscapeSpaces)
        RB.ReplaceText(FilePos, 1, "&nbsp;");
      ++ColNo;
      break;
    case '\f':
      RB.ReplaceText(FilePos, 1, "<hr>");
      ColNo = 0;
      break;

    case '\t': {
      if (!ReplaceTabs)
        break;
      unsigned NumSpaces = 8-(ColNo&7);
      if (EscapeSpaces)
        RB.ReplaceText(FilePos, 1,
                       StringRef("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
                                       "&nbsp;&nbsp;&nbsp;", 6*NumSpaces));
      else
        RB.ReplaceText(FilePos, 1, StringRef("        ", NumSpaces));
      ColNo += NumSpaces;
      break;
    }
    case '<':
      RB.ReplaceText(FilePos, 1, "&lt;");
      ++ColNo;
      break;

    case '>':
      RB.ReplaceText(FilePos, 1, "&gt;");
      ++ColNo;
      break;

    case '&':
      RB.ReplaceText(FilePos, 1, "&amp;");
      ++ColNo;
      break;
    }
  }
}
Exemplo n.º 2
0
int main(int argc, const char **argv) {
    // parse the command-line args passed to your code
    static cl::OptionCategory MyToolCategory("My tool options");
    CommonOptionsParser op(argc, argv, MyToolCategory);        
    // create a new Clang Tool instance (a LibTooling environment)
    ClangTool Tool(op.getCompilations(), op.getSourcePathList());

    // run the Clang Tool, creating a new FrontendAction (explained below)
    int result = Tool.run(newFrontendActionFactory<ExampleFrontendAction>().get());

    errs() << "\nFound " << numFunctions << " functions.\n\n";
    // print out the rewritten source code ("rewriter" is a global var.)
    rewriter.getEditBuffer(rewriter.getSourceMgr().getMainFileID()).write(errs());
    return result;
}
Exemplo n.º 3
0
/// HighlightRange - Highlight a range in the source code with the specified
/// start/end tags.  B/E must be in the same file.  This ensures that
/// start/end tags are placed at the start/end of each line if the range is
/// multiline.
void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
                          const char *StartTag, const char *EndTag) {
  SourceManager &SM = R.getSourceMgr();
  B = SM.getInstantiationLoc(B);
  E = SM.getInstantiationLoc(E);
  FileID FID = SM.getFileID(B);
  assert(SM.getFileID(E) == FID && "B/E not in the same file!");

  unsigned BOffset = SM.getFileOffset(B);
  unsigned EOffset = SM.getFileOffset(E);
  
  // Include the whole end token in the range.
  EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr(), R.getLangOpts());
  
  HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
                 SM.getBufferData(FID).first, StartTag, EndTag);
}
Exemplo n.º 4
0
void html::AddLineNumbers(Rewriter& R, FileID FID) {

  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
  const char* FileBeg = Buf->getBufferStart();
  const char* FileEnd = Buf->getBufferEnd();
  const char* C = FileBeg;
  RewriteBuffer &RB = R.getEditBuffer(FID);
  
  assert (C <= FileEnd);
  
  unsigned LineNo = 0;
  unsigned FilePos = 0;
  
  while (C != FileEnd) {    
    
    ++LineNo;
    unsigned LineStartPos = FilePos;
    unsigned LineEndPos = FileEnd - FileBeg;
    
    assert (FilePos <= LineEndPos);
    assert (C < FileEnd);
    
    // Scan until the newline (or end-of-file).
    
    while (C != FileEnd) {
      char c = *C;
      ++C;
      
      if (c == '\n') {
        LineEndPos = FilePos++;
        break;
      }
      
      ++FilePos;
    }
    
    AddLineNumber(RB, LineNo, LineStartPos, LineEndPos);
  }
  
  // Add one big table tag that surrounds all of the code.
  RB.InsertTextBefore(0, "<table class=\"code\">\n",
                      strlen("<table class=\"code\">\n"));
  
  RB.InsertTextAfter(FileEnd - FileBeg, "</table>", strlen("</table>"));
}
Exemplo n.º 5
0
int main(int argc, const char **argv) {

    for(int i = 3; i+1< argc; i+=2){
        functionsMap[argv[i]]=argv[i+1];
    }

    CommonOptionsParser op(argc, argv, MyToolCategory);

    ClangTool Tool(op.getCompilations(), op.getSourcePathList());

    int result = Tool.run(newFrontendActionFactory<InserterFrontendAction>().get());

    std::vector<string> paths = op.getSourcePathList();
    StringRef path = (paths[0]).insert(paths[0].find('.'),"Secured");
    std::error_code EC;
    llvm::raw_fd_ostream fd(path, EC, sys::fs::F_RW);

    rewriter.getEditBuffer(rewriter.getSourceMgr().getMainFileID()).write(fd);

    return result;

}
Exemplo n.º 6
0
/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
/// information about keywords, macro expansions etc.  This uses the macro
/// table state from the end of the file, so it won't be perfectly perfect,
/// but it will be reasonably close.
void html::SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP) {
  RewriteBuffer &RB = R.getEditBuffer(FID);

  const SourceManager &SM = PP.getSourceManager();
  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
  Lexer L(FID, FromFile, SM, PP.getLangOpts());
  const char *BufferStart = L.getBuffer().data();

  // Inform the preprocessor that we want to retain comments as tokens, so we
  // can highlight them.
  L.SetCommentRetentionState(true);

  // Lex all the tokens in raw mode, to avoid entering #includes or expanding
  // macros.
  Token Tok;
  L.LexFromRawLexer(Tok);

  while (Tok.isNot(tok::eof)) {
    // Since we are lexing unexpanded tokens, all tokens are from the main
    // FileID.
    unsigned TokOffs = SM.getFileOffset(Tok.getLocation());
    unsigned TokLen = Tok.getLength();
    switch (Tok.getKind()) {
    default: break;
    case tok::identifier:
      llvm_unreachable("tok::identifier in raw lexing mode!");
    case tok::raw_identifier: {
      // Fill in Result.IdentifierInfo and update the token kind,
      // looking up the identifier in the identifier table.
      PP.LookUpIdentifierInfo(Tok);

      // If this is a pp-identifier, for a keyword, highlight it as such.
      if (Tok.isNot(tok::identifier))
        HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
                       "<span class='keyword'>", "</span>");
      break;
    }
    case tok::comment:
      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
                     "<span class='comment'>", "</span>");
      break;
    case tok::utf8_string_literal:
      // Chop off the u part of u8 prefix
      ++TokOffs;
      --TokLen;
      // FALL THROUGH to chop the 8
    case tok::wide_string_literal:
    case tok::utf16_string_literal:
    case tok::utf32_string_literal:
      // Chop off the L, u, U or 8 prefix
      ++TokOffs;
      --TokLen;
      // FALL THROUGH.
    case tok::string_literal:
      // FIXME: Exclude the optional ud-suffix from the highlighted range.
      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
                     "<span class='string_literal'>", "</span>");
      break;
    case tok::hash: {
      // If this is a preprocessor directive, all tokens to end of line are too.
      if (!Tok.isAtStartOfLine())
        break;

      // Eat all of the tokens until we get to the next one at the start of
      // line.
      unsigned TokEnd = TokOffs+TokLen;
      L.LexFromRawLexer(Tok);
      while (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) {
        TokEnd = SM.getFileOffset(Tok.getLocation())+Tok.getLength();
        L.LexFromRawLexer(Tok);
      }

      // Find end of line.  This is a hack.
      HighlightRange(RB, TokOffs, TokEnd, BufferStart,
                     "<span class='directive'>", "</span>");

      // Don't skip the next token.
      continue;
    }
    }

    L.LexFromRawLexer(Tok);
  }
}
Exemplo n.º 7
0
/// RewriteMacrosInInput - Implement -rewrite-macros mode.
void clang::RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS) {
  SourceManager &SM = PP.getSourceManager();

  Rewriter Rewrite;
  Rewrite.setSourceMgr(SM, PP.getLangOpts());
  RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID());

  std::vector<Token> RawTokens;
  LexRawTokensFromMainFile(PP, RawTokens);
  unsigned CurRawTok = 0;
  Token RawTok = GetNextRawTok(RawTokens, CurRawTok, false);


  // Get the first preprocessing token.
  PP.EnterMainSourceFile();
  Token PPTok;
  PP.Lex(PPTok);

  // Preprocess the input file in parallel with raw lexing the main file. Ignore
  // all tokens that are preprocessed from a file other than the main file (e.g.
  // a header).  If we see tokens that are in the preprocessed file but not the
  // lexed file, we have a macro expansion.  If we see tokens in the lexed file
  // that aren't in the preprocessed view, we have macros that expand to no
  // tokens, or macro arguments etc.
  while (RawTok.isNot(tok::eof) || PPTok.isNot(tok::eof)) {
    SourceLocation PPLoc = SM.getExpansionLoc(PPTok.getLocation());

    // If PPTok is from a different source file, ignore it.
    if (!SM.isFromMainFile(PPLoc)) {
      PP.Lex(PPTok);
      continue;
    }

    // If the raw file hits a preprocessor directive, they will be extra tokens
    // in the raw file that don't exist in the preprocsesed file.  However, we
    // choose to preserve them in the output file and otherwise handle them
    // specially.
    if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) {
      // If this is a #warning directive or #pragma mark (GNU extensions),
      // comment the line out.
      if (RawTokens[CurRawTok].is(tok::identifier)) {
        const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo();
        if (II->getName() == "warning") {
          // Comment out #warning.
          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
        } else if (II->getName() == "pragma" &&
                   RawTokens[CurRawTok+1].is(tok::identifier) &&
                   (RawTokens[CurRawTok+1].getIdentifierInfo()->getName() ==
                    "mark")) {
          // Comment out #pragma mark.
          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
        }
      }

      // Otherwise, if this is a #include or some other directive, just leave it
      // in the file by skipping over the line.
      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
      while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof))
        RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
      continue;
    }

    // Okay, both tokens are from the same file.  Get their offsets from the
    // start of the file.
    unsigned PPOffs = SM.getFileOffset(PPLoc);
    unsigned RawOffs = SM.getFileOffset(RawTok.getLocation());

    // If the offsets are the same and the token kind is the same, ignore them.
    if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) {
      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
      PP.Lex(PPTok);
      continue;
    }

    // If the PP token is farther along than the raw token, something was
    // deleted.  Comment out the raw token.
    if (RawOffs <= PPOffs) {
      // Comment out a whole run of tokens instead of bracketing each one with
      // comments.  Add a leading space if RawTok didn't have one.
      bool HasSpace = RawTok.hasLeadingSpace();
      RB.InsertTextAfter(RawOffs, &" /*"[HasSpace]);
      unsigned EndPos;

      do {
        EndPos = RawOffs+RawTok.getLength();

        RawTok = GetNextRawTok(RawTokens, CurRawTok, true);
        RawOffs = SM.getFileOffset(RawTok.getLocation());

        if (RawTok.is(tok::comment)) {
          // Skip past the comment.
          RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
          break;
        }

      } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() &&
               (PPOffs != RawOffs || !isSameToken(RawTok, PPTok)));

      RB.InsertTextBefore(EndPos, "*/");
      continue;
    }

    // Otherwise, there was a replacement an expansion.  Insert the new token
    // in the output buffer.  Insert the whole run of new tokens at once to get
    // them in the right order.
    unsigned InsertPos = PPOffs;
    std::string Expansion;
    while (PPOffs < RawOffs) {
      Expansion += ' ' + PP.getSpelling(PPTok);
      PP.Lex(PPTok);
      PPLoc = SM.getExpansionLoc(PPTok.getLocation());
      PPOffs = SM.getFileOffset(PPLoc);
    }
    Expansion += ' ';
    RB.InsertTextBefore(InsertPos, Expansion);
  }

  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
  // we are done.
  if (const RewriteBuffer *RewriteBuf =
      Rewrite.getRewriteBufferFor(SM.getMainFileID())) {
    //printf("Changed:\n");
    *OS << std::string(RewriteBuf->begin(), RewriteBuf->end());
  } else {
    fprintf(stderr, "No changes\n");
  }
  OS->flush();
}