Example #1
0
 virtual bool VisitStmt(Stmt *st) {
     if (ReturnStmt *ret = dyn_cast<ReturnStmt>(st)) {
         rewriter.ReplaceText(ret->getRetValue()->getLocStart(), 6, "val");
         errs() << "** Rewrote ReturnStmt\n";
     }        
     if (CallExpr *call = dyn_cast<CallExpr>(st)) {
         rewriter.ReplaceText(call->getLocStart(), 7, "add5");
         errs() << "** Rewrote function call\n";
     }
     return true;
 }
Example #2
0
 virtual bool VisitFunctionDecl(FunctionDecl *func) {
     numFunctions++;
     string funcName = func->getNameInfo().getName().getAsString();
     if (funcName == "do_math") {
         rewriter.ReplaceText(func->getLocation(), funcName.length(), "add5");
         errs() << "** Rewrote function def: " << funcName << "\n";
     }    
     return true;
 }
Example #3
0
void SynthesizeRemovalConsumer::renameLocation(SourceLocation L,
  std::string& N) {
  if (L.isMacroID()) {        
    // TODO: emit error using diagnostics
    SourceManager &SM = astContext->getSourceManager();
    if (SM.isMacroArgExpansion(L) || SM.isInSystemMacro(L)) {
      // see if it's the macro expansion we can handle
      // e.g.
      //   #define call(x) x
      //   call(y());   // if we want to rename y()
      L = SM.getSpellingLoc(L);
      
      // this falls through to the rename routine below
    }
    else {
      // if the spelling location is from an actual file that we can
      // touch, then do the replacement, but show a warning          
      SourceManager &SM = astContext->getSourceManager();
      auto SL = SM.getSpellingLoc(L);
      FullSourceLoc FSL(SL, SM);
      const FileEntry *FE = SM.getFileEntryForID(FSL.getFileID());
      if (FE) {
        llvm::errs() << "Warning: Rename attempted as a result of macro "
                     << "expansion may break things, at: " << loc(L) << "\n";            
        L = SL;
        // this falls through to the rename routine below
      }
      else {
        // cannot handle this case
        llvm::errs() << "Error: Token is resulted from macro expansion"
          " and is therefore not renamed, at: " << loc(L) << "\n";
        return;
      }
    }
  }
    
  if (shouldIgnore(L)) {
    return;
  }
    
  auto LE = preprocessor->getLocForEndOfToken(L);
  if (LE.isValid()) {        
    // getLocWithOffset returns the location *past* the token, hence -1
    auto E = LE.getLocWithOffset(-1);
    rewriter.ReplaceText(SourceRange(L, E), N);
  }
}  
Example #4
0
bool Replacement::apply(Rewriter &Rewrite) const {
  SourceManager &SM = Rewrite.getSourceMgr();
  const FileEntry *Entry = SM.getFileManager().getFile(FilePath);
  if (Entry == NULL)
    return false;
  FileID ID;
  // FIXME: Use SM.translateFile directly.
  SourceLocation Location = SM.translateFileLineCol(Entry, 1, 1);
  ID = Location.isValid() ?
    SM.getFileID(Location) :
    SM.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
  // FIXME: We cannot check whether Offset + Length is in the file, as
  // the remapping API is not public in the RewriteBuffer.
  const SourceLocation Start =
    SM.getLocForStartOfFile(ID).
    getLocWithOffset(Offset);
  // ReplaceText returns false on success.
  // ReplaceText only fails if the source location is not a file location, in
  // which case we already returned false earlier.
  bool RewriteSucceeded = !Rewrite.ReplaceText(Start, Length, ReplacementText);
  assert(RewriteSucceeded);
  return RewriteSucceeded;
}
Example #5
0
void C2Builder::rewriterTest(SourceManager& SM, LangOptions& LangOpts) {
#if 0
    // FOR TESTING rename global test.aa -> bb
    const std::string modName = "test";
    const std::string oldName = "aa";
    const std::string newName = "bb";

    // Step 1a: find Module
    const Module* M = 0;
    const Module* mod = findModule(modName);
    assert(M && "unknown module");
    assert(!M->isExternal() && "cannot replace symbol in external module");

    // Step 1b: find Decl
    Decl* D = M->findSymbol(oldName);
    assert(D && "unknown decl");

    // Step 2a: replace Decl itself
    Rewriter rewriter;
    rewriter.setSourceMgr(SM, LangOpts);
    rewriter.ReplaceText(D->getLocation(), oldName.size(), newName);

    // Step 2b: replace all references
    // TODO only in mainComponent
    const ModuleList& mods = mainComponent->getModules();
    for (unsigned m=0; m<mods.size(); m++) {
        const AstList& files = mods[m]->getFiles();
        for (unsigned a=0; a<files.size(); a++) {
            AST* ast = files[a];

            RefFinder finder(*ast, D);
            unsigned count = finder.find();
            if (count) printf("replaced %d references in %s\n", count, files[i]->getFileName().c_str());
            for (unsigned i=0; i<count; i++) {
                std::string temp = finder.locs[i].printToString(SM);
                printf("loc %d -> %s\n", finder.locs[i].getRawEncoding(), temp.c_str());
                PresumedLoc loc = SM.getPresumedLoc(finder.locs[i]);
                assert(!loc.isInvalid() && "Invalid location");
                printf(" -> %s:%d:%d\n", loc.getFilename(), loc.getLine(), loc.getColumn());
                std::pair<FileID, unsigned> Off = SM.getDecomposedExpansionLoc(finder.locs[i]);
                printf("-> offset %d\n", Off.second);
                rewriter.ReplaceText(finder.locs[i], oldName.size(), newName);
            }
        }
    }

    // Step 3: reparse and check
    // TODO

    // print output
    for (unsigned m=0; m<mods.size(); m++) {
        const AstList& files = mods[m]->getFiles();
        for (unsigned a=0; a<files.size(); a++) {
            AST* ast = files[a];
            const RewriteBuffer *RewriteBuf =
                rewriter.getRewriteBufferFor(ast->fileID);
            if (RewriteBuf) {
                printf("====== %s ======\n", ast->getFileName().c_str());
                llvm::outs() << std::string(RewriteBuf->begin(), RewriteBuf->end());
            }
        }
    }
    // also works!
    //bool err = rewriter.overwriteChangedFiles();
    //printf("errors = %d\n", err);
#endif
}