Exemplo n.º 1
0
    /**
     * Run the analysis on 2 files
     */
    void IterativeAnalyzer::RunAnalysis(ostream& report_file) {
    	// parse configuration
    	if (WideningStrategy.size() == 0) { // set the default widening strategy to be by-equivalence (guards are not supported so far)
    		WideningStrategy.addValue(AnalysisConfiguration::kWideningStrategyEquiv);
		}
    	AnalysisConfiguration::PrintConfigurationHeader();
    	APAbstractDomain::ValTy::mgr_ptr_ = AnalysisConfiguration::ParseManager(ManagerType);
    	APAbstractDomain::ValTy::partition_point_ = AnalysisConfiguration::ParsePartitionPoint(PartitionPoint);
    	APAbstractDomain::ValTy::partition_strategy_ = AnalysisConfiguration::ParsePartitionStrategy(PartitionStrategy);
    	APAbstractDomain::ValTy::widening_point_ = AnalysisConfiguration::ParseWideningPoint(WideningPoint);
    	APAbstractDomain::ValTy::widening_strategy_ = AnalysisConfiguration::ParseWideningStrategy(WideningStrategy);
    	APAbstractDomain::ValTy::widening_threshold_ = AnalysisConfiguration::ParseWideningThreshold(WideningThreshold);
    	int k = AnalysisConfiguration::ParseInterleavignLookaheadWindow(InterleavingLookaheadWindow);
    	int p = AnalysisConfiguration::ParseInterleavignLookaheadPartition(InterleavingLookaheadPartition);
    	AnalysisConfiguration::PrintConfigurationFooter();

    	// extract an AST from each of the files
    	CodeHandler code(InputFilename), code2(InputFilename2);
    	ASTContext * contex_ptr = code.getAST(),
    			   * contex2_ptr = code2.getAST();

    	// place functions in a map according to name (so they are easily matched)
		map<string,const FunctionDecl*> functions, functions2;
		Utils::CreateFunctionsMap(contex_ptr->getTranslationUnitDecl(),functions);
		Utils::CreateFunctionsMap(contex2_ptr->getTranslationUnitDecl(),functions2);

    	// the context manager is needed to produce a CFG
		AnalysisContextManager context_manager;
		// iterate over functions, match them, and perform the dual analysis
		for (map<string,const FunctionDecl*>::const_iterator iter = functions.begin(), end = functions.end(); iter != end; ++iter) {
			const FunctionDecl* fd = iter->second;
			if (!fd->isThisDeclarationADefinition())
				continue;
			const FunctionDecl* fd2 = functions2[iter->first];
			if (!fd2) // no matching for the function in the 2nd AST
				continue;
			CFG * cfg_ptr = context_manager.getContext(fd)->getCFG(), * cfg2_ptr = context_manager.getContext(fd2)->getCFG();
#if (DEBUG)
			cerr << "Found both cfgs for " << iter->first << ":\n";
			cfg_ptr->dump(LangOptions());
			cfg2_ptr->dump(LangOptions());
			getchar();
#endif
			// this codes sets up the observer to use the first cfg
			// an observer is what we used to report the results
			// this could be defined using the second cfg as well
			APAbstractDomain domain(*cfg_ptr);
			domain.InitializeValues(*cfg_ptr);
			APChecker Observer(*contex_ptr,code.getDiagnosticsEngine(), code.getPreprocessor());
			domain.getAnalysisData().Observer = &Observer;
			domain.getAnalysisData().setContext(*contex_ptr);
			IterativeSolver is(domain,k,p);
			is.AssumeInputEquivalence(fd,fd2);
			is.RunOnCFGs(cfg_ptr,cfg2_ptr);

		}
    }
Exemplo n.º 2
0
static Replacement replaceStmtWithStmt(SourceManager &Sources,
                                       const Stmt &From,
                                       const Stmt &To) {
  return replaceStmtWithText(Sources, From, Lexer::getSourceText(
      CharSourceRange::getTokenRange(To.getSourceRange()),
      Sources, LangOptions()));
}
void FindBadConstructsConsumer::CheckOverriddenMethod(
    const CXXMethodDecl* method) {
  if (!method->size_overridden_methods() || method->getAttr<OverrideAttr>())
    return;

  if (isa<CXXDestructorDecl>(method) || method->isPure())
    return;

  if (IsMethodInBannedOrTestingNamespace(method))
    return;

  SourceManager& manager = instance().getSourceManager();
  SourceRange type_info_range =
      method->getTypeSourceInfo()->getTypeLoc().getSourceRange();
  FullSourceLoc loc(type_info_range.getBegin(), manager);

  // Build the FixIt insertion point after the end of the method definition,
  // including any const-qualifiers and attributes, and before the opening
  // of the l-curly-brace (if inline) or the semi-color (if a declaration).
  SourceLocation spelling_end =
      manager.getSpellingLoc(type_info_range.getEnd());
  if (spelling_end.isValid()) {
    SourceLocation token_end =
        Lexer::getLocForEndOfToken(spelling_end, 0, manager, LangOptions());
    diagnostic().Report(token_end, diag_method_requires_override_)
        << FixItHint::CreateInsertion(token_end, " OVERRIDE");
  } else {
    diagnostic().Report(loc, diag_method_requires_override_);
  }
}
Exemplo n.º 4
0
std::string applyAllReplacements(StringRef Code, const Replacements &Replaces) {
  IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
      new vfs::InMemoryFileSystem);
  FileManager Files(FileSystemOptions(), InMemoryFileSystem);
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager SourceMgr(Diagnostics, Files);
  Rewriter Rewrite(SourceMgr, LangOptions());
  InMemoryFileSystem->addFile(
      "<stdin>", 0, llvm::MemoryBuffer::getMemBuffer(Code, "<stdin>"));
  FileID ID = SourceMgr.createFileID(Files.getFile("<stdin>"), SourceLocation(),
                                     clang::SrcMgr::C_User);
  for (Replacements::const_iterator I = Replaces.begin(), E = Replaces.end();
       I != E; ++I) {
    Replacement Replace("<stdin>", I->getOffset(), I->getLength(),
                        I->getReplacementText());
    if (!Replace.apply(Rewrite))
      return "";
  }
  std::string Result;
  llvm::raw_string_ostream OS(Result);
  Rewrite.getEditBuffer(ID).write(OS);
  OS.flush();
  return Result;
}
Exemplo n.º 5
0
std::string applyAllReplacements(StringRef Code, const Replacements &Replaces) {
    FileManager Files((FileSystemOptions()));
    DiagnosticsEngine Diagnostics(
        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
        new DiagnosticOptions);
    SourceManager SourceMgr(Diagnostics, Files);
    Rewriter Rewrite(SourceMgr, LangOptions());
    std::unique_ptr<llvm::MemoryBuffer> Buf =
        llvm::MemoryBuffer::getMemBuffer(Code, "<stdin>");
    const clang::FileEntry *Entry =
        Files.getVirtualFile("<stdin>", Buf->getBufferSize(), 0);
    SourceMgr.overrideFileContents(Entry, std::move(Buf));
    FileID ID =
        SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User);
    for (Replacements::const_iterator I = Replaces.begin(), E = Replaces.end();
            I != E; ++I) {
        Replacement Replace("<stdin>", I->getOffset(), I->getLength(),
                            I->getReplacementText());
        if (!Replace.apply(Rewrite))
            return "";
    }
    std::string Result;
    llvm::raw_string_ostream OS(Result);
    Rewrite.getEditBuffer(ID).write(OS);
    OS.flush();
    return Result;
}
void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
  SourceManager &SM = *Result.SourceManager;
  if (const auto *E =
          Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) {
    CharSourceRange Range = Lexer::makeFileCharRange(
        CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions());

    if (Range.isInvalid())
      return;

    auto Diag = diag(Range.getBegin(), "use std::move to transfer ownership")
                << FixItHint::CreateInsertion(Range.getBegin(), "std::move(")
                << FixItHint::CreateInsertion(Range.getEnd(), ")");

    auto Insertion =
        Inserter->CreateIncludeInsertion(SM.getMainFileID(), "utility",
                                         /*IsAngled=*/true);
    if (Insertion.hasValue())
      Diag << Insertion.getValue();

    return;
  }

  SourceLocation IdentifierLoc;
  if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
    IdentifierLoc = locateFromTypeLoc(TL, SM);
  } else if (const auto *D =
                 Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
    IdentifierLoc = locateFromUsingDecl(D, SM);
  } else {
    llvm_unreachable("Bad Callback. No node provided.");
  }

  if (IdentifierLoc.isMacroID())
    IdentifierLoc = SM.getSpellingLoc(IdentifierLoc);

  // Ensure that only the 'auto_ptr' token is replaced and not the template
  // aliases.
  if (!checkTokenIsAutoPtr(IdentifierLoc, SM, LangOptions()))
    return;

  SourceLocation EndLoc =
      IdentifierLoc.getLocWithOffset(strlen("auto_ptr") - 1);
  diag(IdentifierLoc, "auto_ptr is deprecated, use unique_ptr instead")
      << FixItHint::CreateReplacement(SourceRange(IdentifierLoc, EndLoc),
                                      "unique_ptr");
}
Exemplo n.º 7
0
// Returns true on error.
static bool format(std::string FileName) {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return true;
  }
  if (Code->getBufferSize() == 0)
    return true; // Empty files are formatted correctly.
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  std::vector<CharSourceRange> Ranges;
  if (fillRanges(Sources, ID, Code.get(), Ranges))
    return true;

  FormatStyle FormatStyle = getStyle(Style, FileName);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources,
            getFormattingLangOpts(FormatStyle.Standard));
  tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs()
        << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>"
                   << I->getReplacementText() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Replaces.size() == 0)
        return false; // Nothing changed, don't touch the file.

      std::string ErrorInfo;
      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                      llvm::sys::fs::F_Binary);
      if (!ErrorInfo.empty()) {
        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
        return true;
      }
      Rewrite.getEditBuffer(ID).write(FileStream);
      FileStream.flush();
    } else {
      if (Cursor.getNumOccurrences() != 0)
        outs() << "{ \"Cursor\": " << tooling::shiftedCodePosition(
                                          Replaces, Cursor) << " }\n";
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemplo n.º 8
0
// -----------initializer MacroFormatter--------------------
// The preprocessor is used to find the macro names in the source files. The macro is 
// more difficult to process. Both its name and definition are fetched using the lexer.
MacroFormatter::MacroFormatter(const Token MacroNameTok, const MacroDirective *md, 
    CompilerInstance &ci, Arguments &arg) : md(md), args(arg), ci(ci) {
  current_status = CToFTypeFormatter::OKAY;
  error_string = "";
  const MacroInfo *mi = md->getMacroInfo();
  SourceManager& SM = ci.getSourceManager();

  // define macro properties
  isObjectOrFunction = mi->isObjectLike();
 
  // This should be a fine way to deal with invalid locations because sloc is checked for validity
  // before it is used.
  if (mi->getDefinitionLoc().isValid()) {
    sloc = SM.getPresumedLoc(mi->getDefinitionLoc());
    isInSystemHeader = SM.isInSystemHeader(mi->getDefinitionLoc());
  } else {
    isInSystemHeader = false;  // If it isn't anywhere, it isn't in a system header
  }

  // The macros' source text is fetched using the Lexer
  macroName = Lexer::getSourceText(CharSourceRange::getTokenRange(MacroNameTok.getLocation(),
      MacroNameTok.getEndLoc()), SM, LangOptions(), 0);
  macroDef = Lexer::getSourceText(CharSourceRange::getTokenRange(mi->getDefinitionLoc(),
      mi->getDefinitionEndLoc()), SM, LangOptions(), 0);
  
  // strangely there might be a "(" follows the macroName for function macros,
  // remove it if there is
  if (macroName.back() == '(') {
    macroName.erase(macroName.size()-1);
  }

  // get the value (number or char or string) for an object macro
  // Note that this doesn't really work properly because of other forms
  // of whitespace and all helpers also look for whitespace in macros.
  bool frontSpace = true;
  for (size_t i = macroName.size(); i < macroDef.size(); i++) {
    if (macroDef[i] != ' ') {
      frontSpace = false;
      macroVal += macroDef[i];
    } else if (frontSpace == false) {
      macroVal += macroDef[i];
    }
  }
}
Exemplo n.º 9
0
// FIXME: This should go into the Lexer, but we need to figure out how
// to handle ranges for refactoring in general first - there is no obvious
// good way how to integrate this into the Lexer yet.
static int getRangeSize(SourceManager &Sources, const CharSourceRange &Range) {
  SourceLocation SpellingBegin = Sources.getSpellingLoc(Range.getBegin());
  SourceLocation SpellingEnd = Sources.getSpellingLoc(Range.getEnd());
  std::pair<FileID, unsigned> Start = Sources.getDecomposedLoc(SpellingBegin);
  std::pair<FileID, unsigned> End = Sources.getDecomposedLoc(SpellingEnd);
  if (Start.first != End.first) return -1;
  if (Range.isTokenRange())
    End.second += Lexer::MeasureTokenLength(SpellingEnd, Sources,
                                            LangOptions());
  return End.second - Start.second;
}
Exemplo n.º 10
0
void AnalysisConsumer::AnalyzeFunction(CFG& cfg, ASTContext &contex, unsigned &report_ctr) {
        // Compute the ranges information.
    	cfg.print(llvm::outs(),LangOptions());
        APAbstractDomain Dom(cfg);
        Dom.InitializeValues(cfg);
        APChecker Observer(contex,diagnostics_engine_, preprocessor_ptr_);
        Dom.getAnalysisData().Observer = &Observer;
        Dom.getAnalysisData().setContext(contex);
        Solver S(Dom);
        S.runOnCFG(cfg, true);
        Observer.ObserveFixedPoint(true, compute_diff_, report_ctr);
    }
Exemplo n.º 11
0
void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
  SourceManager &SM = *Result.SourceManager;
  if (const auto *E =
          Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) {
    CharSourceRange Range = Lexer::makeFileCharRange(
        CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions());

    if (Range.isInvalid())
      return;

    auto Diag = diag(Range.getBegin(), "use std::move to transfer ownership")
                << FixItHint::CreateInsertion(Range.getBegin(), "std::move(")
                << FixItHint::CreateInsertion(Range.getEnd(), ")");

    if (auto Fix =
            Inserter->CreateIncludeInsertion(SM.getMainFileID(), "utility",
                                             /*IsAngled=*/true))
      Diag << *Fix;

    return;
  }

  SourceLocation AutoPtrLoc;
  if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
    //   std::auto_ptr<int> i;
    //        ^
    if (auto Loc = TL->getAs<TemplateSpecializationTypeLoc>())
      AutoPtrLoc = Loc.getTemplateNameLoc();
  } else if (const auto *D =
                 Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
    // using std::auto_ptr;
    //            ^
    AutoPtrLoc = D->getNameInfo().getBeginLoc();
  } else {
    llvm_unreachable("Bad Callback. No node provided.");
  }

  if (AutoPtrLoc.isMacroID())
    AutoPtrLoc = SM.getSpellingLoc(AutoPtrLoc);

  // Ensure that only the 'auto_ptr' token is replaced and not the template
  // aliases.
  if (StringRef(SM.getCharacterData(AutoPtrLoc), strlen("auto_ptr")) !=
      "auto_ptr")
    return;

  SourceLocation EndLoc =
      AutoPtrLoc.getLocWithOffset(strlen("auto_ptr") - 1);
  diag(AutoPtrLoc, "auto_ptr is deprecated, use unique_ptr instead")
      << FixItHint::CreateReplacement(SourceRange(AutoPtrLoc, EndLoc),
                                      "unique_ptr");
}
Exemplo n.º 12
0
// Returns true on error.
static bool format(StringRef FileName) {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  std::unique_ptr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return true;
  }
  if (Code->getBufferSize() == 0)
    return false; // Empty files are formatted correctly.
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  std::vector<CharSourceRange> Ranges;
  if (fillRanges(Sources, ID, Code.get(), Ranges))
    return true;

  FormatStyle FormatStyle = getStyle(
      Style, (FileName == "-") ? AssumeFilename : FileName, FallbackStyle);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources,
            getFormattingLangOpts(FormatStyle.Standard));
  tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs()
        << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>";
      outputReplacementXML(I->getReplacementText());
      llvm::outs() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Rewrite.overwriteChangedFiles())
        return true;
    } else {
      if (Cursor.getNumOccurrences() != 0)
        outs() << "{ \"Cursor\": "
               << tooling::shiftedCodePosition(Replaces, Cursor) << " }\n";
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemplo n.º 13
0
void InheritanceBuilder::run(const MatchFinder::MatchResult &Result) {
  if (const auto *C = Result.Nodes.getNodeAs<CXXRecordDecl>("class"))
    for (const auto &base : C->bases()) {
      const auto qname = C->getQualifiedNameAsString();
      if (base.getAccessSpecifier() == AS_public) {
        PrintingPolicy prtpol((LangOptions()));
        prtpol.SuppressTagKeyword = true;
        prtpol.SuppressScope = false;
        if (const auto tag = base.getType()
                                 .getDesugaredType(*Result.Context)
                                 ->getAs<TagType>())
          inh[ClassDetails(*dyn_cast<CXXRecordDecl>(tag->getDecl()),
                           tparam_names)]
              .emplace_back(*C, tparam_names);
      }
    }
}
void RedundantSmartptrGet::check(const MatchFinder::MatchResult &Result) {
  if (!allReturnTypesMatch(Result)) return;

  bool IsPtrToPtr = Result.Nodes.getNodeAs<Decl>("ptr_to_ptr") != nullptr;
  bool IsMemberExpr = Result.Nodes.getNodeAs<Expr>("memberExpr") != nullptr;
  const Expr *GetCall = Result.Nodes.getNodeAs<Expr>("redundant_get");
  const Expr *Smartptr = Result.Nodes.getNodeAs<Expr>("smart_pointer");

  if (IsPtrToPtr && IsMemberExpr) {
    // Ignore this case (eg. Foo->get()->DoSomething());
    return;
  }

  StringRef SmartptrText = Lexer::getSourceText(
      CharSourceRange::getTokenRange(Smartptr->getSourceRange()),
      *Result.SourceManager, LangOptions());
  // Replace foo->get() with *foo, and foo.get() with foo.
  std::string Replacement = Twine(IsPtrToPtr ? "*" : "", SmartptrText).str();
  diag(GetCall->getLocStart(), "Redundant get() call on smart pointer.")
      << FixItHint::CreateReplacement(GetCall->getSourceRange(), Replacement);
}
Exemplo n.º 15
0
// Returns true on error.
static bool format(StringRef FileName) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
      MemoryBuffer::getFileOrSTDIN(FileName);
  if (std::error_code EC = CodeOrErr.getError()) {
    errs() << EC.message() << "\n";
    return true;
  }
  std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
  if (Code->getBufferSize() == 0)
    return false; // Empty files are formatted correctly.
  std::vector<tooling::Range> Ranges;
  if (fillRanges(Code.get(), Ranges))
    return true;
  StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName;
  FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle);
  if (SortIncludes.getNumOccurrences() != 0)
    FormatStyle.SortIncludes = SortIncludes;
  unsigned CursorPosition = Cursor;
  Replacements Replaces = sortIncludes(FormatStyle, Code->getBuffer(), Ranges,
                                       AssumedFileName, &CursorPosition);
  auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces);
  if (!ChangedCode) {
    llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n";
    return true;
  }
  for (const auto &R : Replaces)
    Ranges.push_back({R.getOffset(), R.getLength()});

  bool IncompleteFormat = false;
  Replacements FormatChanges = reformat(FormatStyle, *ChangedCode, Ranges,
                                        AssumedFileName, &IncompleteFormat);
  Replaces = tooling::mergeReplacements(Replaces, FormatChanges);
  if (OutputXML) {
    outs() << "<?xml version='1.0'?>\n<replacements "
              "xml:space='preserve' incomplete_format='"
           << (IncompleteFormat ? "true" : "false") << "'>\n";
    if (Cursor.getNumOccurrences() != 0)
      outs() << "<cursor>"
             << tooling::shiftedCodePosition(FormatChanges, CursorPosition)
             << "</cursor>\n";

    outputReplacementsXML(Replaces); 
    outs() << "</replacements>\n";
  } else {
    IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
        new vfs::InMemoryFileSystem);
    FileManager Files(FileSystemOptions(), InMemoryFileSystem);
    DiagnosticsEngine Diagnostics(
        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
        new DiagnosticOptions);
    SourceManager Sources(Diagnostics, Files);
    FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files,
                                   InMemoryFileSystem.get());
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (FileName == "-")
        errs() << "error: cannot use -i when reading from stdin.\n";
      else if (Rewrite.overwriteChangedFiles())
        return true;
    } else {
      if (Cursor.getNumOccurrences() != 0)
        outs() << "{ \"Cursor\": "
               << tooling::shiftedCodePosition(FormatChanges, CursorPosition)
               << ", \"IncompleteFormat\": "
               << (IncompleteFormat ? "true" : "false") << " }\n";
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemplo n.º 16
0
// Returns true on error.
static bool format(std::string FileName) {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return true;
  }
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
  if (Offsets.empty())
    Offsets.push_back(0);
  if (Offsets.size() != Lengths.size() &&
      !(Offsets.size() == 1 && Lengths.empty())) {
    llvm::errs()
        << "error: number of -offset and -length arguments must match.\n";
    return true;
  }
  std::vector<CharSourceRange> Ranges;
  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
    if (Offsets[i] >= Code->getBufferSize()) {
      llvm::errs() << "error: offset " << Offsets[i]
                   << " is outside the file\n";
      return true;
    }
    SourceLocation Start =
        Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
    SourceLocation End;
    if (i < Lengths.size()) {
      if (Offsets[i] + Lengths[i] > Code->getBufferSize()) {
        llvm::errs() << "error: invalid length " << Lengths[i]
                     << ", offset + length (" << Offsets[i] + Lengths[i]
                     << ") is outside the file.\n";
        return true;
      }
      End = Start.getLocWithOffset(Lengths[i]);
    } else {
      End = Sources.getLocForEndOfFile(ID);
    }
    Ranges.push_back(CharSourceRange::getCharRange(Start, End));
  }
  tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs()
        << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>"
                   << I->getReplacementText() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Replaces.size() == 0)
        return false; // Nothing changed, don't touch the file.

      std::string ErrorInfo;
      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                      llvm::raw_fd_ostream::F_Binary);
      if (!ErrorInfo.empty()) {
        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
        return true;
      }
      Rewrite.getEditBuffer(ID).write(FileStream);
      FileStream.flush();
    } else {
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemplo n.º 17
0
// Returns true on error.
static bool format(StringRef FileName) {
  if (!OutputXML && Inplace && FileName == "-") {
    errs() << "error: cannot use -i when reading from stdin.\n";
    return false;
  }
  // On Windows, overwriting a file with an open file mapping doesn't work,
  // so read the whole file into memory when formatting in-place.
  ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
      !OutputXML && Inplace ? MemoryBuffer::getFileAsStream(FileName) :
                              MemoryBuffer::getFileOrSTDIN(FileName);
  if (std::error_code EC = CodeOrErr.getError()) {
    errs() << EC.message() << "\n";
    return true;
  }
  std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
  if (Code->getBufferSize() == 0)
    return false; // Empty files are formatted correctly.
  std::vector<tooling::Range> Ranges;
  if (fillRanges(Code.get(), Ranges))
    return true;
  StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName;

  llvm::Expected<FormatStyle> FormatStyle =
      getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer());
  if (!FormatStyle) {
    llvm::errs() << llvm::toString(FormatStyle.takeError()) << "\n";
    return true;
  }

  if (SortIncludes.getNumOccurrences() != 0)
    FormatStyle->SortIncludes = SortIncludes;
  unsigned CursorPosition = Cursor;
  Replacements Replaces = sortIncludes(*FormatStyle, Code->getBuffer(), Ranges,
                                       AssumedFileName, &CursorPosition);
  auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces);
  if (!ChangedCode) {
    llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n";
    return true;
  }
  // Get new affected ranges after sorting `#includes`.
  Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
  FormattingAttemptStatus Status;
  Replacements FormatChanges = reformat(*FormatStyle, *ChangedCode, Ranges,
                                        AssumedFileName, &Status);
  Replaces = Replaces.merge(FormatChanges);
  if (OutputXML) {
    outs() << "<?xml version='1.0'?>\n<replacements "
              "xml:space='preserve' incomplete_format='"
           << (Status.FormatComplete ? "false" : "true") << "'";
    if (!Status.FormatComplete)
      outs() << " line='" << Status.Line << "'";
    outs() << ">\n";
    if (Cursor.getNumOccurrences() != 0)
      outs() << "<cursor>"
             << FormatChanges.getShiftedCodePosition(CursorPosition)
             << "</cursor>\n";

    outputReplacementsXML(Replaces);
    outs() << "</replacements>\n";
  } else {
    IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
        new vfs::InMemoryFileSystem);
    FileManager Files(FileSystemOptions(), InMemoryFileSystem);
    DiagnosticsEngine Diagnostics(
        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
        new DiagnosticOptions);
    SourceManager Sources(Diagnostics, Files);
    FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files,
                                   InMemoryFileSystem.get());
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Rewrite.overwriteChangedFiles())
        return true;
    } else {
      if (Cursor.getNumOccurrences() != 0) {
        outs() << "{ \"Cursor\": "
               << FormatChanges.getShiftedCodePosition(CursorPosition)
               << ", \"IncompleteFormat\": "
               << (Status.FormatComplete ? "false" : "true");
        if (!Status.FormatComplete)
          outs() << ", \"Line\": " << Status.Line;
        outs() << " }\n";
      }
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
///get the source code of stmt
StringRef FindPatternVisitor::expr2str(Stmt *s){
    
    if(!s)
        return "";

    FullSourceLoc begin = CI->getASTContext().getFullLoc(s->getLocStart());
    FullSourceLoc end = CI->getASTContext().getFullLoc(s->getLocEnd());
    
    if(begin.isInvalid() || end.isInvalid())
        return "";
    
    SourceRange sr(begin.getExpansionLoc(), end.getExpansionLoc());
    
    return Lexer::getSourceText(CharSourceRange::getTokenRange(sr), CI->getSourceManager(), LangOptions(), 0);
}
Exemplo n.º 19
0
 void Transaction::DelayCallInfo::dump() const {
   PrintingPolicy Policy((LangOptions()));
   print(llvm::errs(), Policy, /*Indent*/0, /*PrintInstantiation*/true);
 }