virtual void run(const MatchFinder::MatchResult &Result){//freeVar
        const DeclRefExpr* DRE = Result.Nodes.getNodeAs<DeclRefExpr>("freeVar");
        #ifdef DEBUG
        llvm::errs()<<"----DRE(freeVar) find----\n";
        #endif
        
        if(!DRE)   return ;

        const SourceManager *SM = Result.SourceManager;
        
        const NamedDecl *ND = DRE->getFoundDecl();
        checkPoint cp;
        cp.name = rewrite.ConvertToString((Stmt*)DRE);
        std::string str_decl = ND->getNameAsString();
        cp.declName = str_decl;
       
        SourceLocation declLocStart = ND->getLocStart();
        std::string str_declLocStart = declLocStart.printToString(*SM);
        loc_strToint(cp.declRow,cp.declCol,str_declLocStart.c_str());

        SourceLocation locStart = DRE->getLocStart();
        std::string str_locStart = locStart.printToString(*SM);
        loc_strToint(cp.row,cp.col,str_locStart.c_str());


        
        cpVecF.push_back(cp);
    #ifdef DEBUG
    llvm::errs()<<"----DRE(freeVar) end----\n";
    #endif
    }
 virtual void run(const MatchFinder::MatchResult &Result) {
     auto *d = Result.Nodes.getNodeAs<TypeLoc>("stuff");
     SourceLocation locstart = d->getLocStart();
     llvm::errs() << "*\n";
     llvm::errs() << " start: " << locstart.printToString(*Result.SourceManager) << "\n";
     SourceLocation locend = d->getLocEnd();
     llvm::errs() << " end: " << locend.printToString(*Result.SourceManager) << "\n";
 }
    virtual void run(const MatchFinder::MatchResult &Result){
        const DeclRefExpr* DRE = Result.Nodes.getNodeAs<DeclRefExpr>("mallocVar");
        #ifdef DEBUG
        llvm::errs()<<"----DRE(mallocVar) find----\n";
        #endif

        if(!DRE)   return ;

        const SourceManager *SM = Result.SourceManager;
        SourceLocation locStart = DRE->getLocStart();
        
        std::string str_locStart = locStart.printToString(*SM);
        
        checkPoint cp;
        loc_strToint(cp.row,cp.col,str_locStart.c_str());


        cp.name = rewrite.ConvertToString((Stmt*)DRE);

        //找到该变量原先的声明处 
        const NamedDecl *ND = DRE->getFoundDecl();
        std::string str_decl = ND->getNameAsString();
        cp.declName = ND->getNameAsString();
        
        SourceLocation declLocStart = ND->getLocStart();
        std::string str_declLocStart = declLocStart.printToString(*SM);
        loc_strToint(cp.declRow,cp.declCol,str_declLocStart.c_str());
        
        #ifdef DEBUG
        llvm::errs()<<"\ncp: "
        <<cp.row<<":"<<cp.col<<":"<<cp.declRow<<":"<<cp.declCol<<"\n";
        #endif

        
        cpVec.push_back(cp);
        
        #ifdef DEBUG
        llvm::errs() << cp.name << "|\n" <<  cp.declName <<"|\n"
        << cp.declRow << ":" << cp.declCol << "\n";
        llvm::errs() << "ND:\n";
        ND->dump();
        llvm::errs() << "DRE:\n";
        DRE->dump();

        llvm::errs()<<"----DRE(mallocVar) end----\n";
        #endif

    }
// Collect referenced headers from one module.
// Collects the headers referenced in the given module into
// HeaderFileNames.
bool ModularizeUtilities::collectModuleHeaders(const clang::Module &Mod) {

  // Ignore explicit modules because they often have dependencies
  // we can't know.
  if (Mod.IsExplicit)
    return true;

  // Treat headers in umbrella directory as dependencies.
  DependentsVector UmbrellaDependents;

  // Recursively do submodules.
  for (auto MI = Mod.submodule_begin(), MIEnd = Mod.submodule_end();
       MI != MIEnd; ++MI)
    collectModuleHeaders(**MI);

  if (const FileEntry *UmbrellaHeader = Mod.getUmbrellaHeader().Entry) {
    std::string HeaderPath = getCanonicalPath(UmbrellaHeader->getName());
    // Collect umbrella header.
    HeaderFileNames.push_back(HeaderPath);

    // FUTURE: When needed, umbrella header header collection goes here.
  }
  else if (const DirectoryEntry *UmbrellaDir = Mod.getUmbrellaDir().Entry) {
    // If there normal headers, assume these are umbrellas and skip collection.
    if (Mod.Headers->size() == 0) {
      // Collect headers in umbrella directory.
      if (!collectUmbrellaHeaders(UmbrellaDir->getName(), UmbrellaDependents))
        return false;
    }
  }

  // We ignore HK_Private, HK_Textual, HK_PrivateTextual, and HK_Excluded,
  // assuming they are marked as such either because of unsuitability for
  // modules or because they are meant to be included by another header,
  // and thus should be ignored by modularize.

  int NormalHeaderCount = Mod.Headers[clang::Module::HK_Normal].size();

  for (int Index = 0; Index < NormalHeaderCount; ++Index) {
    DependentsVector NormalDependents;
    // Collect normal header.
    const clang::Module::Header &Header(
      Mod.Headers[clang::Module::HK_Normal][Index]);
    std::string HeaderPath = getCanonicalPath(Header.Entry->getName());
    HeaderFileNames.push_back(HeaderPath);
  }

  int MissingCountThisModule = Mod.MissingHeaders.size();

  for (int Index = 0; Index < MissingCountThisModule; ++Index) {
    std::string MissingFile = Mod.MissingHeaders[Index].FileName;
    SourceLocation Loc = Mod.MissingHeaders[Index].FileNameLoc;
    errs() << Loc.printToString(*SourceMgr)
      << ": error : Header not found: " << MissingFile << "\n";
  }

  MissingHeaderCount += MissingCountThisModule;

  return true;
}
    virtual void run(const MatchFinder::MatchResult &Result) {
        auto *d = Result.Nodes.getNodeAs<CXXConstructorDecl>("stuff");
        if (d) {
            if (d->getNumCtorInitializers() > 0) {
                const CXXCtorInitializer *firstinit = *d->init_begin();
                if (!firstinit->isWritten()) {
                    llvm::errs() << "firstinit not written; skipping\n";
                    return;
                }
                if (firstinit->isBaseInitializer()) {
                    TypeLoc basetypeloc = firstinit->getBaseClassLoc();
                    llvm::errs() << "firstinit as base loc: "
                                 << basetypeloc.getBeginLoc().printToString(
                                     *Result.SourceManager) << "\n";
                }
                SourceLocation initloc = firstinit->getSourceLocation();
                llvm::errs() << "firstinit loc: "
                             << initloc.printToString(*Result.SourceManager) << "\n";
                SourceRange initrange = firstinit->getSourceRange();
                llvm::errs() << "firstinit range from "
                             << initrange.getBegin().printToString(
                                 *Result.SourceManager) << "\n";
                llvm::errs() << "firstinit range to "
                             << initrange.getEnd().printToString(
                                 *Result.SourceManager) << "\n";

                SourceLocation start = firstinit->getLParenLoc();
                llvm::errs() << "firstinit start: "
                             << start.printToString(*Result.SourceManager) << "\n";
                Token tok_id = GetTokenBeforeLocation(start, *Result.Context);
                llvm::errs() << "  tok_id: "
                             << tok_id.getLocation().printToString(
                                 *Result.SourceManager) << "\n";
                Token tok_colon =
                    GetTokenBeforeLocation(tok_id.getLocation(), *Result.Context);
                llvm::errs() << "  tok_colon: "
                             << tok_colon.getLocation().printToString(
                                 *Result.SourceManager) << "\n";

                const CXXCtorInitializer *lastinit = *d->init_rbegin();
                SourceLocation end = lastinit->getRParenLoc();
                llvm::errs() << "lastinit end: "
                             << end.printToString(*Result.SourceManager) << "\n";
                //init->getInit()->dump();
            }
        }
    }
///record call-log pair
void FindPatternVisitor::recordCallLog(CallExpr *callExpr, CallExpr *logExpr){
    
    if(!callExpr || !logExpr)
        return;
    
    if(callExpr == logExpr)
        return;
    
    if(!callExpr->getDirectCallee() || !logExpr->getDirectCallee())
        return;
    
    if(hasRecorded[logExpr] == 0)
        hasRecorded[logExpr] = 1;
    else
        return;
    
    SourceLocation callLocation = callExpr->getLocStart();
    SourceLocation logLocation = logExpr->getLocStart();
    
    if(callLocation.isValid() && logLocation.isValid()){
        
        if(0){
            llvm::outs()<<callExpr->getDirectCallee()->getQualifiedNameAsString()<<"@"<<callLocation.printToString(CI->getSourceManager());
            llvm::outs()<<"#";
            llvm::outs()<<logExpr->getDirectCallee()->getQualifiedNameAsString()<<"@"<<logLocation.printToString(CI->getSourceManager());
            llvm::outs()<<"\n";
        }
        
        fputs(callExpr->getDirectCallee()->getQualifiedNameAsString().c_str(), out);
        fputs("@", out);
        string callloc = callLocation.printToString(CI->getSourceManager());
        callloc = callloc.substr(0, callloc.find(" "));
        fputs(callloc.c_str(), out);
        fputs("#", out);
        fputs(logExpr->getDirectCallee()->getQualifiedNameAsString().c_str(), out);
        fputs("@", out);
        string logloc = logLocation.printToString(CI->getSourceManager());
        logloc = logloc.substr(0, logloc.find(" "));
        fputs(logloc.c_str(), out);
        fputs("\n", out);
        
        totalPatternSnippet++;
    }
}
	string FileName(SourceLocation const& l, SourceManager const& sm) {
		if(l.isValid()) {
			return l.printToString(sm);
			//	if (l.isMacroID()){
			//		PresumedLoc pl = sm.getPresumedLoc(l);
			//		if (pl.isValid()){
			//			return string(pl.getFilename());
			//		}
			//	}
			//	return string(l.getFilename());
		}
		return string("UNKNOWN FILE");
	}
    virtual void run(const MatchFinder::MatchResult &Result){//free
        const CallExpr* CE = Result.Nodes.getNodeAs<CallExpr>("free");
        #ifdef DEBUG
        llvm::errs()<<"----CallExpr(free) find----\n";
        #endif
        if(!CE)   return ;
        

        //得到free()里的第0个参数,进行类似的操作
		const SourceManager *SM = Result.SourceManager;
        const Expr * arg = CE->getArg(0);        
        checkPoint cp;
        cp.name = rewrite.ConvertToString((Stmt*)arg);
        
        SourceLocation locStart = CE->getLocStart();
        std::string str_locStart = locStart.printToString(*SM);
        loc_strToint(cp.row,cp.col,str_locStart.c_str());
        
        #ifdef DEBUG
        llvm::errs()<<"cp:"<<cp.row<<" "<<cp.col<<" " + str_locStart + "\n";
        #endif
        
        bool findFlag = false;
        for(unsigned i=0;i<cpVecF.size();++i){
            if(cp.name == cpVecF[i].name &&
             cp.row == cpVecF[i].row){
                findFlag = true;
                cp.col = cpVecF[i].col;
                cp.declName = cpVecF[i].declName;
                cp.declRow = cpVecF[i].declRow;
                cp.declCol = cpVecF[i].declCol;
                break;
            }
        }
        if(!findFlag){
            cp.declName = cp.name;
            cp.declRow = cp.row;
            cp.declCol = cp.col;
        }
                
        char buf[4][32];
        sprintf(buf[0],"%d",cp.row);
        sprintf(buf[1],"%d",cp.col);
        sprintf(buf[2],"%d",cp.declRow);
        sprintf(buf[3],"%d",cp.declCol);                        
		//之后可以进行开文件的优化
        std::string str_insert = 
        "\n{\n\tFILE *fp = fopen(\"" + checkDataFileName +"\",\"a\");\n"
        "\tif(fp == NULL){\n" +
        "\t\tprintf(\"fail to open file " + checkDataFileName + "!\\n\");\n" +
        "\t\texit(-1);\n" + 
        "\t}\n"  + 
        //"\tfprintf(fp,\"f " + cp.name + " " + buf[0] + " " + buf[1] + " " + cp.declName + " " + buf[2] + " " + buf[3] + " %x \\n\"," + cp.name + ");\n" +
        "\tfprintf(fp,\"f " + cp.name + " " + buf[0] + " " + buf[1] + " %x \\n\"," + cp.name + ");\n" +
        "\tfclose(fp);\n" +
        "\tint fd=open(FIFO_SERVER,O_WRONLY |O_NONBLOCK,0);\n" + 
        "\tif(fd==-1){perror(\"open\");exit(1);}\n" + 
        "\tchar w_buf[100];\n" + 
        "\tsprintf(w_buf,\"f "+ cp.name + " " + buf[0] + " " + buf[1] + " %x \\n\"," + cp.name + ");\n" + 
        "\tif(write(fd,w_buf,100)==-1){\n" + 
        "\t\tif(errno==EAGAIN)\n" + 
        "\t\t\tprintf(\"The FIFO has not been read yet.Please try later\\n\");\n" + 
        "\t}\n" + 
        "\telse\n" + 
        "\t\tprintf(\"write %s to the FIFO\\n\",w_buf);\n" +
        "\tsleep(1);\n" + 
        "\tclose(fd);\n" + 
        "}\n";
        

       // llvm::errs() << "-----\n"<<str_insert<<"\n----\n";
        SourceLocation SL_locWithOffset = locStart;
        rewrite.InsertText(SL_locWithOffset,str_insert.c_str(),true,true);   
        #ifdef DEBUG
        llvm::errs()<<"----CallExpr(free) end----\n";
        #endif

    }
    virtual void run(const MatchFinder::MatchResult &Result){
        const BinaryOperator* BO = Result.Nodes.getNodeAs<BinaryOperator>("malloc");
        #ifdef DEBUG
        llvm::errs()<<"----BinaryOperator(malloc) find----\n";
        #endif
        if(!BO)   return ;
        const SourceManager *SM = Result.SourceManager;
        SourceLocation locEnd = BO->getLocEnd();
        checkPoint cp;
      
	
		//得到插装位置,找到mallocVarMatcher之前对应匹配到的信息(其实可以不用MallocVarMatcher,MallocVarMatcher只能匹配到纯粹的指针(不带*的))
        std::string str_locEnd = locEnd.printToString(*SM);
        loc_strToint(cp.row,cp.col,str_locEnd.c_str());
        bool findFlag = false;
        int findI;
        
        #ifdef DEBUG
        llvm::errs() <<"binary loc:" <<"|"<<cp.row<<"|"<<cp.col<<"\n";
        #endif
        
        for(unsigned i=0;i<cpVec.size();++i){
            if(cpVec[i].row == cp.row){
                    findFlag = true;
                    findI = i;
                    break;
                }
        }
		//左子树得到的 = 的左边
        Expr * lhs = BO->getLHS();
        cp.name = rewrite.ConvertToString((Stmt*)lhs);
        
        QualType qt = lhs->getType();
        #ifdef DEBUG
        llvm::errs()<<"lhs cp.name :"<<cp.name<<"\n";
        llvm::errs()<<"lhs type :"<<qt.getAsString()<<"\n";
        lhs->dump();
        #endif
        
		//找到的话直接用
        if(findFlag){        
            const NamedDecl *ND = ((DeclRefExpr*)lhs)->getFoundDecl();
            std::string str_decl = ND->getNameAsString();
            cp.declName = str_decl;
            SourceLocation declLocStart = ND->getLocStart();
            std::string str_declLocStart = declLocStart.printToString(*SM);
            loc_strToint(cp.declRow,cp.declCol,str_declLocStart.c_str());
        
        }else{//没找到的话,添加进来
            cp.declName = cp.name;
            cp.declRow = cp.row;
            cp.declCol = cp.col;
        }
        
		//string + 不支持int类型,所以先换成char*
        char buf[4][32];
        sprintf(buf[0],"%d",cp.row);
        sprintf(buf[1],"%d",cp.col);
        sprintf(buf[2],"%d",cp.declRow);
        sprintf(buf[3],"%d",cp.declCol);  
                                     
        //将程序运行时的指针值存下来 %x                                     
        std::string str_insert = 
        "\n{\n\tFILE *fp = fopen(\"" + checkDataFileName +"\",\"a\");\n"
        "\tif(fp == NULL){\n" +
        "\t\tprintf(\"fail to open file " + checkDataFileName + "!\\n\");\n" +
        "\t\texit(-1);\n" + 
        "\t}\n" + 
        
        //"\tfprintf(fp,\"m " + cp.name + " " + buf[0] + " " + buf[1] + " " + cp.declName + " " + buf[2] + " " + buf[3] + " %x \\n\"," + cp.name + ");\n" +
        "\tfprintf(fp,\"m " + cp.name + " " + buf[0] + " " + buf[1] + " %x \\n\"," + cp.name + ");\n" +
        "\tfclose(fp);\n\n" +
        "\tint fd=open(FIFO_SERVER,O_WRONLY |O_NONBLOCK,0);\n" + 
        "\tif(fd==-1){perror(\"open\");exit(1);}\n" + 
        "\tchar w_buf[100];\n" + 
        "\tsprintf(w_buf,\"m "+ cp.name + " " + buf[0] + " " + buf[1] + " %x \\n\"," + cp.name + ");\n" + 
        "\tif(write(fd,w_buf,100)==-1){\n" + 
        "\t\tif(errno==EAGAIN)\n" + 
        "\t\t\tprintf(\"The FIFO has not been read yet.Please try later\\n\");\n" + 
        "\t}\n" + 
        "\telse\n" + 
        "\t\tprintf(\"write %s to the FIFO\\n\",w_buf);\n" +
        "\tsleep(1);\n" + 
        "\tclose(fd);\n" + 
        "}\n";
        
        
        
        //llvm::errs() << "-----\n"<<str_insert<<"\n----\n";
		//找位置插装
        int locOffset = 2;
        SourceLocation SL_locWithOffset = locEnd.getLocWithOffset(locOffset);
        rewrite.InsertText(SL_locWithOffset,str_insert.c_str(),true,true); 
        
		if(!findFlag){        
            cpVec.push_back(cp);
        }

        #ifdef DEBUG
        llvm::errs()<<"----BinaryOperator(malloc) end----\n";
        #endif
    }