<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Aug 23, 2013 at 5:47 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Fri, Aug 23, 2013 at 2:35 PM, Sean Silva <<a href="mailto:silvas@purdue.edu">silvas@purdue.edu</a>> wrote:<br>

><br>
><br>
><br>
> On Thu, Aug 22, 2013 at 9:07 AM, Edwin Vane <<a href="mailto:edwin.vane@intel.com">edwin.vane@intel.com</a>> wrote:<br>
>><br>
>> Author: revane<br>
>> Date: Thu Aug 22 08:07:14 2013<br>
>> New Revision: 189008<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=189008&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=189008&view=rev</a><br>
>> Log:<br>
>> Introducing new tool clang-replace<br>
>><br>
>> Introducing new tool 'clang-replace' that finds files containing<br>
>> serialized Replacements and applies those changes after deduplication<br>
>> and detecting conflicts.<br>
>><br>
>> Currently the tool does not apply changes. It stops just after the<br>
>> deduplication and conflict report phase. Forthcoming patches will<br>
>> complete functionality.<br>
><br>
><br>
> I hate to bring this up post-commit (it just came to me now), but I really<br>
> feel `clang-replace` is not the right name for this tool. `clang-replace` is<br>
> not self-documenting and sounds more like a tool for renaming than a tool<br>
> that does what it does now (or will do soon), i.e. deduplicate/apply<br>
> replacements generated by refactoring tools. I feel like this tool should be<br>
> called `clang-apply-replacements` (or something like that).<br>
<br>
</div>If we're going to paint this bikeshed I'll mention my colour issues:<br>
<br>
This won't always apply 'replacements'. It might also/instead do, say,<br>
insertions (add 'override' everywhere, for example).<br></blockquote><div><br></div><div>Wouldn't that take the form of a clang::tooling::Replacement starting at the insertion point but with 0 length? If I understand correctly, this tool's only purpose is literally to slurp up serialized Replacement's then apply them (after a deduplication/conflict detection step). Hence my suggestion of `clang-apply-replacements`. What avenues of growth you are seeing that would change this?</div>
<div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
clang-apply-changes ? But I like the short tool names, not sure if<br>
clang-apply is too vague. (clang-change? clang-edit? clang-patch?)<br>
<div class="HOEnZb"><div class="h5"><br>
><br>
> -- Sean Silva<br>
><br>
><br>
>><br>
>><br>
>> Both build systems updated for new tool.<br>
>><br>
>> Includes a conflict test case.<br>
>><br>
>> clang-replace added to Doxygen build.<br>
>><br>
>> Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D1424" target="_blank">http://llvm-reviews.chandlerc.com/D1424</a><br>
>><br>
>><br>
>> Added:<br>
>>     clang-tools-extra/trunk/clang-replace/<br>
>>     clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp<br>
>>     clang-tools-extra/trunk/clang-replace/ApplyReplacements.h<br>
>>     clang-tools-extra/trunk/clang-replace/CMakeLists.txt<br>
>>     clang-tools-extra/trunk/clang-replace/Makefile<br>
>>     clang-tools-extra/trunk/clang-replace/tool/<br>
>>     clang-tools-extra/trunk/clang-replace/tool/CMakeLists.txt<br>
>>     clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp<br>
>>     clang-tools-extra/trunk/clang-replace/tool/Makefile<br>
>>     clang-tools-extra/trunk/test/clang-replace/<br>
>>     clang-tools-extra/trunk/test/clang-replace/conflict/<br>
>>     clang-tools-extra/trunk/test/clang-replace/conflict.cpp<br>
>>     clang-tools-extra/trunk/test/clang-replace/conflict/common.h<br>
>>     clang-tools-extra/trunk/test/clang-replace/conflict/expected.txt<br>
>>     clang-tools-extra/trunk/test/clang-replace/conflict/file1.yaml<br>
>>     clang-tools-extra/trunk/test/clang-replace/conflict/file2.yaml<br>
>>     clang-tools-extra/trunk/test/clang-replace/conflict/file3.yaml<br>
>> Modified:<br>
>>     clang-tools-extra/trunk/CMakeLists.txt<br>
>>     clang-tools-extra/trunk/Makefile<br>
>>     clang-tools-extra/trunk/docs/Doxyfile<br>
>>     clang-tools-extra/trunk/test/CMakeLists.txt<br>
>><br>
>> Modified: clang-tools-extra/trunk/CMakeLists.txt<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/CMakeLists.txt?rev=189008&r1=189007&r2=189008&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/CMakeLists.txt?rev=189008&r1=189007&r2=189008&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/CMakeLists.txt (original)<br>
>> +++ clang-tools-extra/trunk/CMakeLists.txt Thu Aug 22 08:07:14 2013<br>
>> @@ -1,6 +1,7 @@<br>
>>  add_subdirectory(remove-cstr-calls)<br>
>>  add_subdirectory(tool-template)<br>
>>  add_subdirectory(cpp11-migrate)<br>
>> +add_subdirectory(clang-replace)<br>
>>  add_subdirectory(modularize)<br>
>>  add_subdirectory(clang-tidy)<br>
>><br>
>><br>
>> Modified: clang-tools-extra/trunk/Makefile<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/Makefile?rev=189008&r1=189007&r2=189008&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/Makefile?rev=189008&r1=189007&r2=189008&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/Makefile (original)<br>
>> +++ clang-tools-extra/trunk/Makefile Thu Aug 22 08:07:14 2013<br>
>> @@ -12,7 +12,7 @@ CLANG_LEVEL := ../..<br>
>>  include $(CLANG_LEVEL)/../../Makefile.config<br>
>><br>
>>  PARALLEL_DIRS := remove-cstr-calls tool-template modularize<br>
>> -DIRS := cpp11-migrate clang-tidy unittests<br>
>> +DIRS := cpp11-migrate clang-tidy clang-replace unittests<br>
>><br>
>>  include $(CLANG_LEVEL)/Makefile<br>
>><br>
>><br>
>> Added: clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp (added)<br>
>> +++ clang-tools-extra/trunk/clang-replace/ApplyReplacements.cpp Thu Aug 22<br>
>> 08:07:14 2013<br>
>> @@ -0,0 +1,193 @@<br>
>> +//===-- Core/ApplyChangeDescriptions.cpp<br>
>> ----------------------------------===//<br>
>> +//<br>
>> +//                     The LLVM Compiler Infrastructure<br>
>> +//<br>
>> +// This file is distributed under the University of Illinois Open Source<br>
>> +// License. See LICENSE.TXT for details.<br>
>> +//<br>
>><br>
>> +//===----------------------------------------------------------------------===//<br>
>> +///<br>
>> +/// \file<br>
>> +/// \brief This file provides the implementation for finding and applying<br>
>> change<br>
>> +/// description files.<br>
>> +///<br>
>><br>
>> +//===----------------------------------------------------------------------===//<br>
>> +#include "ApplyReplacements.h"<br>
>> +#include "clang/Basic/LangOptions.h"<br>
>> +#include "clang/Basic/SourceManager.h"<br>
>> +#include "llvm/ADT/ArrayRef.h"<br>
>> +#include "llvm/Support/FileSystem.h"<br>
>> +#include "llvm/Support/MemoryBuffer.h"<br>
>> +#include "llvm/Support/Path.h"<br>
>> +#include "llvm/Support/raw_ostream.h"<br>
>> +<br>
>> +using namespace llvm;<br>
>> +using namespace clang;<br>
>> +<br>
>> +<br>
>> +static void eatDiagnostics(const SMDiagnostic &, void *) {}<br>
>> +<br>
>> +namespace clang {<br>
>> +namespace replace {<br>
>> +<br>
>> +llvm::error_code<br>
>> +collectReplacementsFromDirectory(const llvm::StringRef Directory,<br>
>> +                                 TUReplacements &TUs,<br>
>> +                                 clang::DiagnosticsEngine &Diagnostics) {<br>
>> +  using namespace llvm::sys::fs;<br>
>> +  using namespace llvm::sys::path;<br>
>> +<br>
>> +  error_code ErrorCode;<br>
>> +<br>
>> +  for (recursive_directory_iterator I(Directory, ErrorCode), E;<br>
>> +       I != E && !ErrorCode; I.increment(ErrorCode)) {<br>
>> +    if (filename(I->path())[0] == '.') {<br>
>> +      // Indicate not to descend into directories beginning with '.'<br>
>> +      I.no_push();<br>
>> +      continue;<br>
>> +    }<br>
>> +<br>
>> +    if (extension(I->path()) != ".yaml")<br>
>> +      continue;<br>
>> +<br>
>> +    OwningPtr<MemoryBuffer> Out;<br>
>> +    error_code BufferError = MemoryBuffer::getFile(I->path(), Out);<br>
>> +    if (BufferError) {<br>
>> +      errs() << "Error reading " << I->path() << ": " <<<br>
>> BufferError.message()<br>
>> +             << "\n";<br>
>> +      continue;<br>
>> +    }<br>
>> +<br>
>> +    yaml::Input YIn(Out->getBuffer());<br>
>> +    YIn.setDiagHandler(&eatDiagnostics);<br>
>> +    tooling::TranslationUnitReplacements TU;<br>
>> +    YIn >> TU;<br>
>> +    if (YIn.error()) {<br>
>> +      // File doesn't appear to be a header change description. Ignore<br>
>> it.<br>
>> +      continue;<br>
>> +    }<br>
>> +<br>
>> +    // Only keep files that properly parse.<br>
>> +    TUs.push_back(TU);<br>
>> +  }<br>
>> +<br>
>> +  return ErrorCode;<br>
>> +}<br>
>> +<br>
>> +/// \brief Dumps information for a sequence of conflicting Replacements.<br>
>> +///<br>
>> +/// \param[in] File FileEntry for the file the conflicting Replacements<br>
>> are<br>
>> +/// for.<br>
>> +/// \param[in] ConflictingReplacements List of conflicting Replacements.<br>
>> +/// \param[in] SM SourceManager used for reporting.<br>
>> +static void reportConflict(<br>
>> +    const FileEntry *File,<br>
>> +    const llvm::ArrayRef<clang::tooling::Replacement><br>
>> ConflictingReplacements,<br>
>> +    SourceManager &SM) {<br>
>> +  FileID FID = SM.translateFile(File);<br>
>> +  if (FID.isInvalid())<br>
>> +    FID = SM.createFileID(File, SourceLocation(), SrcMgr::C_User);<br>
>> +<br>
>> +  // FIXME: Output something a little more user-friendly (e.g. unified<br>
>> diff?)<br>
>> +  errs() << "The following changes conflict:\n";<br>
>> +  for (const tooling::Replacement *I = ConflictingReplacements.begin(),<br>
>> +                                  *E = ConflictingReplacements.end();<br>
>> +       I != E; ++I) {<br>
>> +    if (I->getLength() == 0) {<br>
>> +      errs() << "  Insert at " << SM.getLineNumber(FID, I->getOffset())<br>
>> << ":"<br>
>> +             << SM.getColumnNumber(FID, I->getOffset()) << " "<br>
>> +             << I->getReplacementText() << "\n";<br>
>> +    } else {<br>
>> +      if (I->getReplacementText().empty())<br>
>> +        errs() << "  Remove ";<br>
>> +      else<br>
>> +        errs() << "  Replace ";<br>
>> +<br>
>> +      errs() << SM.getLineNumber(FID, I->getOffset()) << ":"<br>
>> +             << SM.getColumnNumber(FID, I->getOffset()) << "-"<br>
>> +             << SM.getLineNumber(FID, I->getOffset() + I->getLength() -<br>
>> 1)<br>
>> +             << ":"<br>
>> +             << SM.getColumnNumber(FID, I->getOffset() + I->getLength() -<br>
>> 1);<br>
>> +<br>
>> +      if (I->getReplacementText().empty())<br>
>> +        errs() << "\n";<br>
>> +      else<br>
>> +        errs() << " with \"" << I->getReplacementText() << "\"\n";<br>
>> +    }<br>
>> +  }<br>
>> +}<br>
>> +<br>
>> +/// \brief Deduplicates and tests for conflicts among the replacements<br>
>> for each<br>
>> +/// file in \c Replacements. Any conflicts found are reported.<br>
>> +///<br>
>> +/// \param[in,out] Replacements Container of all replacements grouped by<br>
>> file<br>
>> +/// to be deduplicated and checked for conflicts.<br>
>> +/// \param[in] SM SourceManager required for conflict reporting<br>
>> +///<br>
>> +/// \returns \li true if conflicts were detected<br>
>> +///          \li false if no conflicts were detected<br>
>> +static bool deduplicateAndDetectConflicts(FileToReplacementsMap<br>
>> &Replacements,<br>
>> +                                          SourceManager &SM) {<br>
>> +  bool conflictsFound = false;<br>
>> +<br>
>> +  for (FileToReplacementsMap::iterator I = Replacements.begin(),<br>
>> +                                       E = Replacements.end();<br>
>> +       I != E; ++I) {<br>
>> +<br>
>> +    const FileEntry *Entry = SM.getFileManager().getFile(I->getKey());<br>
>> +    if (!Entry) {<br>
>> +      errs() << "Described file '" << I->getKey()<br>
>> +             << "' doesn't exist. Ignoring...\n";<br>
>> +      continue;<br>
>> +    }<br>
>> +<br>
>> +    std::vector<tooling::Range> Conflicts;<br>
>> +    tooling::deduplicate(I->getValue(), Conflicts);<br>
>> +<br>
>> +    if (Conflicts.empty())<br>
>> +      continue;<br>
>> +<br>
>> +    conflictsFound = true;<br>
>> +<br>
>> +    errs() << "There are conflicting changes to " << I->getKey() <<<br>
>> ":\n";<br>
>> +<br>
>> +    for (std::vector<tooling::Range>::const_iterator<br>
>> +             ConflictI = Conflicts.begin(),<br>
>> +             ConflictE = Conflicts.end();<br>
>> +         ConflictI != ConflictE; ++ConflictI) {<br>
>> +      ArrayRef<tooling::Replacement> ConflictingReplacements(<br>
>> +          &I->getValue()[ConflictI->getOffset()],<br>
>> ConflictI->getLength());<br>
>> +      reportConflict(Entry, ConflictingReplacements, SM);<br>
>> +    }<br>
>> +  }<br>
>> +<br>
>> +  return conflictsFound;<br>
>> +}<br>
>> +<br>
>> +bool mergeAndDeduplicate(const TUReplacements &TUs,<br>
>> +                         FileToReplacementsMap &GroupedReplacements,<br>
>> +                         clang::DiagnosticsEngine &Diagnostics) {<br>
>> +<br>
>> +  // FIXME: Use Diagnostics for output<br>
>> +<br>
>> +  // Group all replacements by target file.<br>
>> +  for (TUReplacements::const_iterator TUI = TUs.begin(), TUE = TUs.end();<br>
>> +       TUI != TUE; ++TUI)<br>
>> +    for (std::vector<tooling::Replacement>::const_iterator<br>
>> +             RI = TUI->Replacements.begin(),<br>
>> +             RE = TUI->Replacements.end();<br>
>> +         RI != RE; ++RI)<br>
>> +      GroupedReplacements[RI->getFilePath()].push_back(*RI);<br>
>> +<br>
>> +  FileManager Files((FileSystemOptions()));<br>
>> +  SourceManager SM(Diagnostics, Files);<br>
>> +<br>
>> +  // Ask clang to deduplicate and report conflicts.<br>
>> +  if (deduplicateAndDetectConflicts(GroupedReplacements, SM))<br>
>> +    return false;<br>
>> +<br>
>> +  return true;<br>
>> +}<br>
>> +<br>
>> +} // end namespace replace<br>
>> +} // end namespace clang<br>
>><br>
>> Added: clang-tools-extra/trunk/clang-replace/ApplyReplacements.h<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/ApplyReplacements.h?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/ApplyReplacements.h?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/clang-replace/ApplyReplacements.h (added)<br>
>> +++ clang-tools-extra/trunk/clang-replace/ApplyReplacements.h Thu Aug 22<br>
>> 08:07:14 2013<br>
>> @@ -0,0 +1,77 @@<br>
>> +//===-- Core/ApplyChangeDescriptions.h --------------------------*- C++<br>
>> -*-===//<br>
>> +//<br>
>> +//                     The LLVM Compiler Infrastructure<br>
>> +//<br>
>> +// This file is distributed under the University of Illinois Open Source<br>
>> +// License. See LICENSE.TXT for details.<br>
>> +//<br>
>><br>
>> +//===----------------------------------------------------------------------===//<br>
>> +///<br>
>> +/// \file<br>
>> +/// \brief This file provides the interface for finding and applying<br>
>> change<br>
>> +/// description files.<br>
>> +///<br>
>><br>
>> +//===----------------------------------------------------------------------===//<br>
>> +<br>
>> +#ifndef CPP11_MIGRATE_APPLYCHANGEDESCRIPTIONS_H<br>
>> +#define CPP11_MIGRATE_APPLYCHANGEDESCRIPTIONS_H<br>
>> +<br>
>> +#include "clang/Tooling/ReplacementsYaml.h"<br>
>> +#include "llvm/ADT/StringMap.h"<br>
>> +#include "llvm/ADT/StringRef.h"<br>
>> +#include "llvm/Support/system_error.h"<br>
>> +#include <vector><br>
>> +<br>
>> +namespace clang {<br>
>> +<br>
>> +class DiagnosticsEngine;<br>
>> +<br>
>> +namespace replace {<br>
>> +<br>
>> +/// \brief Collection of TranslationUnitReplacements.<br>
>> +typedef std::vector<clang::tooling::TranslationUnitReplacements><br>
>> +TUReplacements;<br>
>> +<br>
>> +/// \brief Map mapping file name to Replacements targeting that file.<br>
>> +typedef llvm::StringMap<std::vector<clang::tooling::Replacement> ><br>
>> +FileToReplacementsMap;<br>
>> +<br>
>> +/// \brief Recursively descends through a directory structure rooted at<br>
>> \p<br>
>> +/// Directory and attempts to deserialize *.yaml files as<br>
>> +/// TranslationUnitReplacements. All docs that successfully deserialize<br>
>> are<br>
>> +/// added to \p TUs.<br>
>> +///<br>
>> +/// Directories starting with '.' are ignored during traversal.<br>
>> +///<br>
>> +/// \param[in] Directory Directory to begin search for serialized<br>
>> +/// TranslationUnitReplacements.<br>
>> +/// \param[out] TUs Collection of all found and deserialized<br>
>> +/// TranslationUnitReplacements.<br>
>> +/// \param[in] Diagnostics DiagnosticsEngine used for error output.<br>
>> +///<br>
>> +/// \returns An error_code indicating success or failure in navigating<br>
>> the<br>
>> +/// directory structure.<br>
>> +llvm::error_code<br>
>> +collectReplacementsFromDirectory(const llvm::StringRef Directory,<br>
>> +                                 TUReplacements &TUs,<br>
>> +                                 clang::DiagnosticsEngine &Diagnostics);<br>
>> +<br>
>> +/// \brief Deduplicate, check for conflicts, and apply all Replacements<br>
>> stored<br>
>> +/// in \c TUs. If conflicts occur, no Replacements are applied.<br>
>> +///<br>
>> +/// \param[in] TUs Collection of TranslationUnitReplacements to merge,<br>
>> +/// deduplicate, and test for conflicts.<br>
>> +/// \param[out] GroupedReplacements Container grouping all Replacements<br>
>> by the<br>
>> +/// file they target.<br>
>> +/// \param[in] Diagnostics DiagnosticsEngine used for error/warning<br>
>> output.<br>
>> +///<br>
>> +/// \returns \li true If all changes were applied successfully.<br>
>> +///          \li false If there were conflicts.<br>
>> +bool mergeAndDeduplicate(const TUReplacements &TUs,<br>
>> +                         FileToReplacementsMap &GroupedReplacements,<br>
>> +                         clang::DiagnosticsEngine &Diagnostics);<br>
>> +<br>
>> +} // end namespace replace<br>
>> +} // end namespace clang<br>
>> +<br>
>> +#endif // CPP11_MIGRATE_APPLYCHANGEDESCRIPTIONS_H<br>
>><br>
>> Added: clang-tools-extra/trunk/clang-replace/CMakeLists.txt<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/CMakeLists.txt?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/CMakeLists.txt?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/clang-replace/CMakeLists.txt (added)<br>
>> +++ clang-tools-extra/trunk/clang-replace/CMakeLists.txt Thu Aug 22<br>
>> 08:07:14 2013<br>
>> @@ -0,0 +1,19 @@<br>
>> +set(LLVM_LINK_COMPONENTS<br>
>> +  ${LLVM_TARGETS_TO_BUILD}<br>
>> +  asmparser<br>
>> +  bitreader<br>
>> +  support<br>
>> +  mc<br>
>> +  )<br>
>> +<br>
>> +add_clang_library(clangReplace<br>
>> +  ApplyReplacements.cpp<br>
>> +  )<br>
>> +target_link_libraries(clangReplace<br>
>> +  clangTooling<br>
>> +  clangBasic<br>
>> +  clangRewriteFrontend<br>
>> +  )<br>
>> +<br>
>> +include_directories(${CMAKE_CURRENT_SOURCE_DIR})<br>
>> +add_subdirectory(tool)<br>
>><br>
>> Added: clang-tools-extra/trunk/clang-replace/Makefile<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/Makefile?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/Makefile?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/clang-replace/Makefile (added)<br>
>> +++ clang-tools-extra/trunk/clang-replace/Makefile Thu Aug 22 08:07:14<br>
>> 2013<br>
>> @@ -0,0 +1,16 @@<br>
>> +##===- clang-replace/Makefile ------------------------------*- Makefile<br>
>> -*-===##<br>
>> +#<br>
>> +#                     The LLVM Compiler Infrastructure<br>
>> +#<br>
>> +# This file is distributed under the University of Illinois Open Source<br>
>> +# License. See LICENSE.TXT for details.<br>
>> +#<br>
>><br>
>> +##===----------------------------------------------------------------------===##<br>
>> +<br>
>> +CLANG_LEVEL := ../../..<br>
>> +LIBRARYNAME := clangReplace<br>
>> +include $(CLANG_LEVEL)/../../Makefile.config<br>
>> +<br>
>> +DIRS = tool<br>
>> +<br>
>> +include $(CLANG_LEVEL)/Makefile<br>
>><br>
>> Added: clang-tools-extra/trunk/clang-replace/tool/CMakeLists.txt<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/tool/CMakeLists.txt?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/tool/CMakeLists.txt?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/clang-replace/tool/CMakeLists.txt (added)<br>
>> +++ clang-tools-extra/trunk/clang-replace/tool/CMakeLists.txt Thu Aug 22<br>
>> 08:07:14 2013<br>
>> @@ -0,0 +1,17 @@<br>
>> +set(LLVM_LINK_COMPONENTS<br>
>> +  ${LLVM_TARGETS_TO_BUILD}<br>
>> +  asmparser<br>
>> +  bitreader<br>
>> +  support<br>
>> +  mc<br>
>> +  )<br>
>> +<br>
>> +add_clang_executable(clang-replace<br>
>> +  ClangReplaceMain.cpp<br>
>> +  )<br>
>> +target_link_libraries(clang-replace<br>
>> +  clangReplace<br>
>> +  )<br>
>> +<br>
>> +install(TARGETS clang-replace<br>
>> +  RUNTIME DESTINATION bin)<br>
>><br>
>> Added: clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp<br>
>> (added)<br>
>> +++ clang-tools-extra/trunk/clang-replace/tool/ClangReplaceMain.cpp Thu<br>
>> Aug 22 08:07:14 2013<br>
>> @@ -0,0 +1,50 @@<br>
>> +//===-- ClangReplaceMain.cpp - Main file for clang-replace tool<br>
>> -----------===//<br>
>> +//<br>
>> +//                     The LLVM Compiler Infrastructure<br>
>> +//<br>
>> +// This file is distributed under the University of Illinois Open Source<br>
>> +// License. See LICENSE.TXT for details.<br>
>> +//<br>
>><br>
>> +//===----------------------------------------------------------------------===//<br>
>> +///<br>
>> +/// \file<br>
>> +/// \brief This file provides the main function for the clang-replace<br>
>> tool.<br>
>> +///<br>
>><br>
>> +//===----------------------------------------------------------------------===//<br>
>> +<br>
>> +#include "ApplyReplacements.h"<br>
>> +#include "clang/Basic/Diagnostic.h"<br>
>> +#include "clang/Basic/DiagnosticOptions.h"<br>
>> +#include "llvm/Support/CommandLine.h"<br>
>> +<br>
>> +using namespace llvm;<br>
>> +using namespace clang;<br>
>> +using namespace clang::replace;<br>
>> +<br>
>> +static cl::opt<std::string> Directory(cl::Positional, cl::Required,<br>
>> +                                      cl::desc("<Search Root<br>
>> Directory>"));<br>
>> +<br>
>> +int main(int argc, char **argv) {<br>
>> +  cl::ParseCommandLineOptions(argc, argv);<br>
>> +<br>
>> +  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new<br>
>> DiagnosticOptions());<br>
>> +  DiagnosticsEngine Diagnostics(<br>
>> +      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),<br>
>> +      DiagOpts.getPtr());<br>
>> +<br>
>> +  TUReplacements TUs;<br>
>> +<br>
>> +  error_code ErrorCode =<br>
>> +      collectReplacementsFromDirectory(Directory, TUs, Diagnostics);<br>
>> +<br>
>> +  if (ErrorCode) {<br>
>> +    errs() << "Trouble iterating over directory '" << Directory<br>
>> +           << "': " << ErrorCode.message() << "\n";<br>
>> +    return false;<br>
>> +  }<br>
>> +<br>
>> +  FileToReplacementsMap GroupedReplacements;<br>
>> +  if (mergeAndDeduplicate(TUs, GroupedReplacements, Diagnostics))<br>
>> +    return 0;<br>
>> +  return 1;<br>
>> +}<br>
>><br>
>> Added: clang-tools-extra/trunk/clang-replace/tool/Makefile<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/tool/Makefile?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-replace/tool/Makefile?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/clang-replace/tool/Makefile (added)<br>
>> +++ clang-tools-extra/trunk/clang-replace/tool/Makefile Thu Aug 22<br>
>> 08:07:14 2013<br>
>> @@ -0,0 +1,28 @@<br>
>> +##===- clang-replace/tool/Makefile -------------------------*- Makefile<br>
>> -*-===##<br>
>> +#<br>
>> +#                     The LLVM Compiler Infrastructure<br>
>> +#<br>
>> +# This file is distributed under the University of Illinois Open Source<br>
>> +# License. See LICENSE.TXT for details.<br>
>> +#<br>
>><br>
>> +##===----------------------------------------------------------------------===##<br>
>> +<br>
>> +CLANG_LEVEL := ../../../..<br>
>> +include $(CLANG_LEVEL)/../../Makefile.config<br>
>> +<br>
>> +TOOLNAME = clang-replace<br>
>> +<br>
>> +# No plugins, optimize startup time.<br>
>> +TOOL_NO_EXPORTS = 1<br>
>> +<br>
>> +SOURCES = ClangReplaceMain.cpp<br>
>> +<br>
>> +LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc<br>
>> mcparser option<br>
>> +USEDLIBS = clangReplace.a clangFormat.a clangTooling.a clangFrontend.a \<br>
>> +          clangSerialization.a clangDriver.a clangRewriteFrontend.a \<br>
>> +          clangRewriteCore.a clangParse.a clangSema.a clangAnalysis.a \<br>
>> +          clangAST.a clangASTMatchers.a clangEdit.a clangLex.a<br>
>> clangBasic.a<br>
>> +<br>
>> +include $(CLANG_LEVEL)/Makefile<br>
>> +<br>
>> +CPP.Flags += -I$(PROJ_SRC_DIR)/..<br>
>><br>
>> Modified: clang-tools-extra/trunk/docs/Doxyfile<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/Doxyfile?rev=189008&r1=189007&r2=189008&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/Doxyfile?rev=189008&r1=189007&r2=189008&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/docs/Doxyfile (original)<br>
>> +++ clang-tools-extra/trunk/docs/Doxyfile Thu Aug 22 08:07:14 2013<br>
>> @@ -648,7 +648,7 @@ WARN_LOGFILE           =<br>
>>  # directories like "/usr/src/myproject". Separate the files or<br>
>> directories<br>
>>  # with spaces.<br>
>><br>
>> -INPUT                  = ../cpp11-migrate<br>
>> +INPUT                  = ../cpp11-migrate ../clang-replace<br>
>><br>
>>  # This tag can be used to specify the character encoding of the source<br>
>> files<br>
>>  # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which<br>
>> is<br>
>><br>
>> Modified: clang-tools-extra/trunk/test/CMakeLists.txt<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/CMakeLists.txt?rev=189008&r1=189007&r2=189008&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/CMakeLists.txt?rev=189008&r1=189007&r2=189008&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/test/CMakeLists.txt (original)<br>
>> +++ clang-tools-extra/trunk/test/CMakeLists.txt Thu Aug 22 08:07:14 2013<br>
>> @@ -27,7 +27,7 @@ set(CLANG_TOOLS_TEST_DEPS<br>
>>    clang clang-headers FileCheck count not<br>
>><br>
>>    # Individual tools we test.<br>
>> -  remove-cstr-calls cpp11-migrate modularize clang-tidy<br>
>> +  remove-cstr-calls clang-replace cpp11-migrate modularize clang-tidy<br>
>><br>
>>    # Unit tests<br>
>>    ExtraToolsUnitTests<br>
>><br>
>> Added: clang-tools-extra/trunk/test/clang-replace/conflict.cpp<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict.cpp?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict.cpp?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/test/clang-replace/conflict.cpp (added)<br>
>> +++ clang-tools-extra/trunk/test/clang-replace/conflict.cpp Thu Aug 22<br>
>> 08:07:14 2013<br>
>> @@ -0,0 +1,7 @@<br>
>> +// RUN: mkdir -p %T/conflict<br>
>> +// RUN: sed "s#\$(path)#%/S/conflict#" %S/conflict/file1.yaml ><br>
>> %T/conflict/file1.yaml<br>
>> +// RUN: sed "s#\$(path)#%/S/conflict#" %S/conflict/file2.yaml ><br>
>> %T/conflict/file2.yaml<br>
>> +// RUN: sed "s#\$(path)#%/S/conflict#" %S/conflict/file3.yaml ><br>
>> %T/conflict/file3.yaml<br>
>> +// RUN: sed "s#\$(path)#%/S/conflict#" %S/conflict/expected.txt ><br>
>> %T/conflict/expected.txt<br>
>> +// RUN: not clang-replace %T/conflict > %T/conflict/output.txt 2>&1<br>
>> +// RUN: diff -b %T/conflict/output.txt %T/conflict/expected.txt<br>
>><br>
>> Added: clang-tools-extra/trunk/test/clang-replace/conflict/common.h<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/common.h?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/common.h?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/test/clang-replace/conflict/common.h (added)<br>
>> +++ clang-tools-extra/trunk/test/clang-replace/conflict/common.h Thu Aug<br>
>> 22 08:07:14 2013<br>
>> @@ -0,0 +1,17 @@<br>
>> +#ifndef COMMON_H<br>
>> +#define COMMON_H<br>
>> +<br>
>> +extern void ext(int (&)[5]);<br>
>> +<br>
>> +void func(int t) {<br>
>> +  int ints[5];<br>
>> +  for (unsigned i = 0; i < 5; ++i) {<br>
>> +    ints[i] = t;<br>
>> +  }<br>
>> +<br>
>> +  int *i = 0;<br>
>> +<br>
>> +  ext(ints);<br>
>> +}<br>
>> +<br>
>> +#endif // COMMON_H<br>
>><br>
>> Added: clang-tools-extra/trunk/test/clang-replace/conflict/expected.txt<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/expected.txt?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/expected.txt?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/test/clang-replace/conflict/expected.txt<br>
>> (added)<br>
>> +++ clang-tools-extra/trunk/test/clang-replace/conflict/expected.txt Thu<br>
>> Aug 22 08:07:14 2013<br>
>> @@ -0,0 +1,11 @@<br>
>> +There are conflicting changes to $(path)/common.h:<br>
>> +The following changes conflict:<br>
>> +  Replace 8:8-8:33 with "auto & i : ints"<br>
>> +  Replace 8:8-8:33 with "int & elem : ints"<br>
>> +The following changes conflict:<br>
>> +  Replace 9:5-9:11 with "elem"<br>
>> +  Replace 9:5-9:11 with "i"<br>
>> +The following changes conflict:<br>
>> +  Remove 12:3-12:14<br>
>> +  Insert at 12:12 (int*)<br>
>> +  Replace 12:12-12:12 with "nullptr"<br>
>><br>
>> Added: clang-tools-extra/trunk/test/clang-replace/conflict/file1.yaml<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/file1.yaml?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/file1.yaml?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/test/clang-replace/conflict/file1.yaml (added)<br>
>> +++ clang-tools-extra/trunk/test/clang-replace/conflict/file1.yaml Thu Aug<br>
>> 22 08:07:14 2013<br>
>> @@ -0,0 +1,16 @@<br>
>> +---<br>
>> +MainSourceFile: "source1.cpp"<br>
>> +Replacements:<br>
>> +  - FilePath:        "$(path)/common.h"<br>
>> +    Offset:          106<br>
>> +    Length:          26<br>
>> +    ReplacementText: "auto & i : ints"<br>
>> +  - FilePath:        "$(path)/common.h"<br>
>> +    Offset:          140<br>
>> +    Length:          7<br>
>> +    ReplacementText: "i"<br>
>> +  - FilePath:        "$(path)/common.h"<br>
>> +    Offset:          160<br>
>> +    Length:          12<br>
>> +    ReplacementText: ""<br>
>> +...<br>
>><br>
>> Added: clang-tools-extra/trunk/test/clang-replace/conflict/file2.yaml<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/file2.yaml?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/file2.yaml?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/test/clang-replace/conflict/file2.yaml (added)<br>
>> +++ clang-tools-extra/trunk/test/clang-replace/conflict/file2.yaml Thu Aug<br>
>> 22 08:07:14 2013<br>
>> @@ -0,0 +1,16 @@<br>
>> +---<br>
>> +MainSourceFile: "source2.cpp"<br>
>> +Replacements:<br>
>> +  - FilePath:        "$(path)/common.h"<br>
>> +    Offset:          106<br>
>> +    Length:          26<br>
>> +    ReplacementText: "int & elem : ints"<br>
>> +  - FilePath:        "$(path)/common.h"<br>
>> +    Offset:          140<br>
>> +    Length:          7<br>
>> +    ReplacementText: "elem"<br>
>> +  - FilePath:        "$(path)/common.h"<br>
>> +    Offset:          169<br>
>> +    Length:          1<br>
>> +    ReplacementText: "nullptr"<br>
>> +...<br>
>><br>
>> Added: clang-tools-extra/trunk/test/clang-replace/conflict/file3.yaml<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/file3.yaml?rev=189008&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-replace/conflict/file3.yaml?rev=189008&view=auto</a><br>

>><br>
>> ==============================================================================<br>
>> --- clang-tools-extra/trunk/test/clang-replace/conflict/file3.yaml (added)<br>
>> +++ clang-tools-extra/trunk/test/clang-replace/conflict/file3.yaml Thu Aug<br>
>> 22 08:07:14 2013<br>
>> @@ -0,0 +1,8 @@<br>
>> +---<br>
>> +MainSourceFile: "source1.cpp"<br>
>> +Replacements:<br>
>> +  - FilePath:        "$(path)/common.h"<br>
>> +    Offset:          169<br>
>> +    Length:          0<br>
>> +    ReplacementText: "(int*)"<br>
>> +...<br>
>><br>
>><br>
>> _______________________________________________<br>
>> cfe-commits mailing list<br>
>> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
><br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
><br>
</div></div></blockquote></div><br></div></div>