It's not perfect, but putting #error in include/clang/AST/APValue.h might be one way to start tracking it.
On Wed, Oct 29, 2014 at 3:24 PM, Daniel Jasper <[email protected]> wrote: > Can I reproduce this somehow? > > On Wed, Oct 29, 2014 at 3:23 PM, Hans Wennborg <[email protected]> wrote: >> >> This seems to have broken the Windows build. For example, >> http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/11259 >> >> It seems that clang-format, is still dependent on AST via FrontendAction. >> >> On Wed, Oct 29, 2014 at 11:55 AM, Daniel Jasper <[email protected]> >> wrote: >> > Author: djasper >> > Date: Wed Oct 29 13:55:09 2014 >> > New Revision: 220867 >> > >> > URL: http://llvm.org/viewvc/llvm-project?rev=220867&view=rev >> > Log: >> > Refactor libTooling to reduce required dependencies. >> > >> > This moves classes for storing and applying replacements to separate >> > files. These classes specifically are used by clang-format which doesn't >> > have any other dependencies on clangAST. Thereby, the size of >> > clang-format's binary can be cut roughly in half and its build time sped >> > up. >> > >> > Added: >> > cfe/trunk/include/clang/Tooling/Core/ >> > cfe/trunk/include/clang/Tooling/Core/Replacement.h >> > - copied, changed from r220860, >> > cfe/trunk/include/clang/Tooling/Refactoring.h >> > cfe/trunk/lib/Tooling/Core/ >> > cfe/trunk/lib/Tooling/Core/CMakeLists.txt >> > cfe/trunk/lib/Tooling/Core/Makefile >> > - copied, changed from r220860, cfe/trunk/lib/Tooling/Makefile >> > cfe/trunk/lib/Tooling/Core/Replacement.cpp >> > - copied, changed from r220860, >> > cfe/trunk/lib/Tooling/Refactoring.cpp >> > Modified: >> > cfe/trunk/include/clang/Tooling/Refactoring.h >> > cfe/trunk/lib/Format/CMakeLists.txt >> > cfe/trunk/lib/Tooling/CMakeLists.txt >> > cfe/trunk/lib/Tooling/Makefile >> > cfe/trunk/lib/Tooling/Refactoring.cpp >> > cfe/trunk/tools/clang-format/CMakeLists.txt >> > cfe/trunk/tools/clang-format/Makefile >> > cfe/trunk/tools/libclang/Makefile >> > cfe/trunk/unittests/Format/CMakeLists.txt >> > cfe/trunk/unittests/Format/Makefile >> > cfe/trunk/unittests/Tooling/Makefile >> > >> > Copied: cfe/trunk/include/clang/Tooling/Core/Replacement.h (from >> > r220860, cfe/trunk/include/clang/Tooling/Refactoring.h) >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Core/Replacement.h?p2=cfe/trunk/include/clang/Tooling/Core/Replacement.h&p1=cfe/trunk/include/clang/Tooling/Refactoring.h&r1=220860&r2=220867&rev=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/include/clang/Tooling/Refactoring.h (original) >> > +++ cfe/trunk/include/clang/Tooling/Core/Replacement.h Wed Oct 29 >> > 13:55:09 2014 >> > @@ -1,4 +1,4 @@ >> > -//===--- Refactoring.h - Framework for clang refactoring tools --*- C++ >> > -*-===// >> > +//===--- Replacement.h - Framework for clang refactoring tools --*- C++ >> > -*-===// >> > // >> > // The LLVM Compiler Infrastructure >> > // >> > @@ -7,7 +7,7 @@ >> > // >> > >> > //===----------------------------------------------------------------------===// >> > // >> > -// Interfaces supporting refactorings that span multiple translation >> > units. >> > +// Classes supporting refactorings that span multiple translation >> > units. >> > // While single translation unit refactorings are supported via the >> > Rewriter, >> > // when refactoring multiple translation units changes must be stored >> > in a >> > // SourceManager independent form, duplicate changes need to be >> > removed, and >> > @@ -16,19 +16,18 @@ >> > // >> > >> > //===----------------------------------------------------------------------===// >> > >> > -#ifndef LLVM_CLANG_TOOLING_REFACTORING_H >> > -#define LLVM_CLANG_TOOLING_REFACTORING_H >> > +#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H >> > +#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H >> > >> > #include "clang/Basic/SourceLocation.h" >> > -#include "clang/Tooling/Tooling.h" >> > #include "llvm/ADT/StringRef.h" >> > #include <set> >> > #include <string> >> > +#include <vector> >> > >> > namespace clang { >> > >> > class Rewriter; >> > -class SourceLocation; >> > >> > namespace tooling { >> > >> > @@ -193,42 +192,28 @@ struct TranslationUnitReplacements { >> > std::vector<Replacement> Replacements; >> > }; >> > >> > -/// \brief A tool to run refactorings. >> > +/// \brief Apply all replacements in \p Replaces to the Rewriter \p >> > Rewrite. >> > /// >> > -/// This is a refactoring specific version of \see ClangTool. >> > FrontendActions >> > -/// passed to run() and runAndSave() should add replacements to >> > -/// getReplacements(). >> > -class RefactoringTool : public ClangTool { >> > -public: >> > - /// \see ClangTool::ClangTool. >> > - RefactoringTool(const CompilationDatabase &Compilations, >> > - ArrayRef<std::string> SourcePaths); >> > - >> > - /// \brief Returns the set of replacements to which replacements >> > should >> > - /// be added during the run of the tool. >> > - Replacements &getReplacements(); >> > - >> > - /// \brief Call run(), apply all generated replacements, and >> > immediately save >> > - /// the results to disk. >> > - /// >> > - /// \returns 0 upon success. Non-zero upon failure. >> > - int runAndSave(FrontendActionFactory *ActionFactory); >> > - >> > - /// \brief Apply all stored replacements to the given Rewriter. >> > - /// >> > - /// Replacement applications happen independently of the success of >> > other >> > - /// applications. >> > - /// >> > - /// \returns true if all replacements apply. false otherwise. >> > - bool applyAllReplacements(Rewriter &Rewrite); >> > +/// Replacement applications happen independently of the success of >> > +/// other applications. >> > +/// >> > +/// \returns true if all replacements apply. false otherwise. >> > +bool applyAllReplacements(const Replacements &Replaces, Rewriter >> > &Rewrite); >> > >> > -private: >> > - /// \brief Write all refactored files to disk. >> > - int saveRewrittenFiles(Rewriter &Rewrite); >> > +/// \brief Apply all replacements in \p Replaces to the Rewriter \p >> > Rewrite. >> > +/// >> > +/// Replacement applications happen independently of the success of >> > +/// other applications. >> > +/// >> > +/// \returns true if all replacements apply. false otherwise. >> > +bool applyAllReplacements(const std::vector<Replacement> &Replaces, >> > + Rewriter &Rewrite); >> > >> > -private: >> > - Replacements Replace; >> > -}; >> > +/// \brief Applies all replacements in \p Replaces to \p Code. >> > +/// >> > +/// This completely ignores the path stored in each replacement. If one >> > or more >> > +/// replacements cannot be applied, this returns an empty \c string. >> > +std::string applyAllReplacements(StringRef Code, const Replacements >> > &Replaces); >> > >> > template <typename Node> >> > Replacement::Replacement(const SourceManager &Sources, >> > @@ -241,4 +226,4 @@ Replacement::Replacement(const SourceMan >> > } // end namespace tooling >> > } // end namespace clang >> > >> > -#endif // LLVM_CLANG_TOOLING_REFACTORING_H >> > +#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H >> > >> > Modified: cfe/trunk/include/clang/Tooling/Refactoring.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring.h?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/include/clang/Tooling/Refactoring.h (original) >> > +++ cfe/trunk/include/clang/Tooling/Refactoring.h Wed Oct 29 13:55:09 >> > 2014 >> > @@ -19,180 +19,16 @@ >> > #ifndef LLVM_CLANG_TOOLING_REFACTORING_H >> > #define LLVM_CLANG_TOOLING_REFACTORING_H >> > >> > -#include "clang/Basic/SourceLocation.h" >> > +#include "clang/Tooling/Core/Replacement.h" >> > #include "clang/Tooling/Tooling.h" >> > -#include "llvm/ADT/StringRef.h" >> > -#include <set> >> > #include <string> >> > >> > namespace clang { >> > >> > class Rewriter; >> > -class SourceLocation; >> > >> > namespace tooling { >> > >> > -/// \brief A source range independent of the \c SourceManager. >> > -class Range { >> > -public: >> > - Range() : Offset(0), Length(0) {} >> > - Range(unsigned Offset, unsigned Length) : Offset(Offset), >> > Length(Length) {} >> > - >> > - /// \brief Accessors. >> > - /// @{ >> > - unsigned getOffset() const { return Offset; } >> > - unsigned getLength() const { return Length; } >> > - /// @} >> > - >> > - /// \name Range Predicates >> > - /// @{ >> > - /// \brief Whether this range overlaps with \p RHS or not. >> > - bool overlapsWith(Range RHS) const { >> > - return Offset + Length > RHS.Offset && Offset < RHS.Offset + >> > RHS.Length; >> > - } >> > - >> > - /// \brief Whether this range contains \p RHS or not. >> > - bool contains(Range RHS) const { >> > - return RHS.Offset >= Offset && >> > - (RHS.Offset + RHS.Length) <= (Offset + Length); >> > - } >> > - /// @} >> > - >> > -private: >> > - unsigned Offset; >> > - unsigned Length; >> > -}; >> > - >> > -/// \brief A text replacement. >> > -/// >> > -/// Represents a SourceManager independent replacement of a range of >> > text in a >> > -/// specific file. >> > -class Replacement { >> > -public: >> > - /// \brief Creates an invalid (not applicable) replacement. >> > - Replacement(); >> > - >> > - /// \brief Creates a replacement of the range [Offset, Offset+Length) >> > in >> > - /// FilePath with ReplacementText. >> > - /// >> > - /// \param FilePath A source file accessible via a SourceManager. >> > - /// \param Offset The byte offset of the start of the range in the >> > file. >> > - /// \param Length The length of the range in bytes. >> > - Replacement(StringRef FilePath, unsigned Offset, >> > - unsigned Length, StringRef ReplacementText); >> > - >> > - /// \brief Creates a Replacement of the range [Start, Start+Length) >> > with >> > - /// ReplacementText. >> > - Replacement(const SourceManager &Sources, SourceLocation Start, >> > unsigned Length, >> > - StringRef ReplacementText); >> > - >> > - /// \brief Creates a Replacement of the given range with >> > ReplacementText. >> > - Replacement(const SourceManager &Sources, const CharSourceRange >> > &Range, >> > - StringRef ReplacementText); >> > - >> > - /// \brief Creates a Replacement of the node with ReplacementText. >> > - template <typename Node> >> > - Replacement(const SourceManager &Sources, const Node &NodeToReplace, >> > - StringRef ReplacementText); >> > - >> > - /// \brief Returns whether this replacement can be applied to a file. >> > - /// >> > - /// Only replacements that are in a valid file can be applied. >> > - bool isApplicable() const; >> > - >> > - /// \brief Accessors. >> > - /// @{ >> > - StringRef getFilePath() const { return FilePath; } >> > - unsigned getOffset() const { return ReplacementRange.getOffset(); } >> > - unsigned getLength() const { return ReplacementRange.getLength(); } >> > - StringRef getReplacementText() const { return ReplacementText; } >> > - /// @} >> > - >> > - /// \brief Applies the replacement on the Rewriter. >> > - bool apply(Rewriter &Rewrite) const; >> > - >> > - /// \brief Returns a human readable string representation. >> > - std::string toString() const; >> > - >> > - private: >> > - void setFromSourceLocation(const SourceManager &Sources, >> > SourceLocation Start, >> > - unsigned Length, StringRef >> > ReplacementText); >> > - void setFromSourceRange(const SourceManager &Sources, >> > - const CharSourceRange &Range, >> > - StringRef ReplacementText); >> > - >> > - std::string FilePath; >> > - Range ReplacementRange; >> > - std::string ReplacementText; >> > -}; >> > - >> > -/// \brief Less-than operator between two Replacements. >> > -bool operator<(const Replacement &LHS, const Replacement &RHS); >> > - >> > -/// \brief Equal-to operator between two Replacements. >> > -bool operator==(const Replacement &LHS, const Replacement &RHS); >> > - >> > -/// \brief A set of Replacements. >> > -/// FIXME: Change to a vector and deduplicate in the RefactoringTool. >> > -typedef std::set<Replacement> Replacements; >> > - >> > -/// \brief Apply all replacements in \p Replaces to the Rewriter \p >> > Rewrite. >> > -/// >> > -/// Replacement applications happen independently of the success of >> > -/// other applications. >> > -/// >> > -/// \returns true if all replacements apply. false otherwise. >> > -bool applyAllReplacements(const Replacements &Replaces, Rewriter >> > &Rewrite); >> > - >> > -/// \brief Apply all replacements in \p Replaces to the Rewriter \p >> > Rewrite. >> > -/// >> > -/// Replacement applications happen independently of the success of >> > -/// other applications. >> > -/// >> > -/// \returns true if all replacements apply. false otherwise. >> > -bool applyAllReplacements(const std::vector<Replacement> &Replaces, >> > - Rewriter &Rewrite); >> > - >> > -/// \brief Applies all replacements in \p Replaces to \p Code. >> > -/// >> > -/// This completely ignores the path stored in each replacement. If one >> > or more >> > -/// replacements cannot be applied, this returns an empty \c string. >> > -std::string applyAllReplacements(StringRef Code, const Replacements >> > &Replaces); >> > - >> > -/// \brief Calculates how a code \p Position is shifted when \p >> > Replaces are >> > -/// applied. >> > -unsigned shiftedCodePosition(const Replacements& Replaces, unsigned >> > Position); >> > - >> > -/// \brief Calculates how a code \p Position is shifted when \p >> > Replaces are >> > -/// applied. >> > -/// >> > -/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset(). >> > -unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces, >> > - unsigned Position); >> > - >> > -/// \brief Removes duplicate Replacements and reports if Replacements >> > conflict >> > -/// with one another. All Replacements are assumed to be in the same >> > file. >> > -/// >> > -/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset(). >> > -/// >> > -/// This function sorts \p Replaces so that conflicts can be reported >> > simply by >> > -/// offset into \p Replaces and number of elements in the conflict. >> > -void deduplicate(std::vector<Replacement> &Replaces, >> > - std::vector<Range> &Conflicts); >> > - >> > -/// \brief Collection of Replacements generated from a single >> > translation unit. >> > -struct TranslationUnitReplacements { >> > - /// Name of the main source for the translation unit. >> > - std::string MainSourceFile; >> > - >> > - /// A freeform chunk of text to describe the context of the >> > replacements. >> > - /// Will be printed, for example, when detecting conflicts during >> > replacement >> > - /// deduplication. >> > - std::string Context; >> > - >> > - std::vector<Replacement> Replacements; >> > -}; >> > - >> > /// \brief A tool to run refactorings. >> > /// >> > /// This is a refactoring specific version of \see ClangTool. >> > FrontendActions >> > @@ -230,14 +66,6 @@ private: >> > Replacements Replace; >> > }; >> > >> > -template <typename Node> >> > -Replacement::Replacement(const SourceManager &Sources, >> > - const Node &NodeToReplace, StringRef >> > ReplacementText) { >> > - const CharSourceRange Range = >> > - CharSourceRange::getTokenRange(NodeToReplace->getSourceRange()); >> > - setFromSourceRange(Sources, Range, ReplacementText); >> > -} >> > - >> > } // end namespace tooling >> > } // end namespace clang >> > >> > >> > Modified: cfe/trunk/lib/Format/CMakeLists.txt >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/CMakeLists.txt?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/lib/Format/CMakeLists.txt (original) >> > +++ cfe/trunk/lib/Format/CMakeLists.txt Wed Oct 29 13:55:09 2014 >> > @@ -12,5 +12,5 @@ add_clang_library(clangFormat >> > LINK_LIBS >> > clangBasic >> > clangLex >> > - clangTooling >> > + clangToolingCore >> > ) >> > >> > Modified: cfe/trunk/lib/Tooling/CMakeLists.txt >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CMakeLists.txt?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/lib/Tooling/CMakeLists.txt (original) >> > +++ cfe/trunk/lib/Tooling/CMakeLists.txt Wed Oct 29 13:55:09 2014 >> > @@ -1,5 +1,7 @@ >> > set(LLVM_LINK_COMPONENTS support) >> > >> > +add_subdirectory(Core) >> > + >> > add_clang_library(clangTooling >> > ArgumentsAdjusters.cpp >> > CommonOptionsParser.cpp >> > @@ -18,4 +20,5 @@ add_clang_library(clangTooling >> > clangFrontend >> > clangLex >> > clangRewrite >> > + clangToolingCore >> > ) >> > >> > Added: cfe/trunk/lib/Tooling/Core/CMakeLists.txt >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Core/CMakeLists.txt?rev=220867&view=auto >> > >> > ============================================================================== >> > --- cfe/trunk/lib/Tooling/Core/CMakeLists.txt (added) >> > +++ cfe/trunk/lib/Tooling/Core/CMakeLists.txt Wed Oct 29 13:55:09 2014 >> > @@ -0,0 +1,10 @@ >> > +set(LLVM_LINK_COMPONENTS support) >> > + >> > +add_clang_library(clangToolingCore >> > + Replacement.cpp >> > + >> > + LINK_LIBS >> > + clangBasic >> > + clangDriver >> > + clangRewrite >> > + ) >> > >> > Copied: cfe/trunk/lib/Tooling/Core/Makefile (from r220860, >> > cfe/trunk/lib/Tooling/Makefile) >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Core/Makefile?p2=cfe/trunk/lib/Tooling/Core/Makefile&p1=cfe/trunk/lib/Tooling/Makefile&r1=220860&r2=220867&rev=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/lib/Tooling/Makefile (original) >> > +++ cfe/trunk/lib/Tooling/Core/Makefile Wed Oct 29 13:55:09 2014 >> > @@ -1,4 +1,4 @@ >> > -##===- clang/lib/Tooling/Makefile ---------------------------*- >> > Makefile -*-===## >> > +##===- clang/lib/Tooling/Core/Makefile ---------------------*- Makefile >> > -*-===## >> > # >> > # The LLVM Compiler Infrastructure >> > # >> > @@ -7,7 +7,7 @@ >> > # >> > >> > ##===----------------------------------------------------------------------===## >> > >> > -CLANG_LEVEL := ../.. >> > -LIBRARYNAME := clangTooling >> > +CLANG_LEVEL := ../../.. >> > +LIBRARYNAME := clangToolingCore >> > >> > include $(CLANG_LEVEL)/Makefile >> > >> > Copied: cfe/trunk/lib/Tooling/Core/Replacement.cpp (from r220860, >> > cfe/trunk/lib/Tooling/Refactoring.cpp) >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Core/Replacement.cpp?p2=cfe/trunk/lib/Tooling/Core/Replacement.cpp&p1=cfe/trunk/lib/Tooling/Refactoring.cpp&r1=220860&r2=220867&rev=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/lib/Tooling/Refactoring.cpp (original) >> > +++ cfe/trunk/lib/Tooling/Core/Replacement.cpp Wed Oct 29 13:55:09 2014 >> > @@ -1,4 +1,4 @@ >> > -//===--- Refactoring.cpp - Framework for clang refactoring tools >> > ----------===// >> > +//===--- Replacement.cpp - Framework for clang refactoring tools >> > ----------===// >> > // >> > // The LLVM Compiler Infrastructure >> > // >> > @@ -7,17 +7,18 @@ >> > // >> > >> > //===----------------------------------------------------------------------===// >> > // >> > -// Implements tools to support refactorings. >> > +// Implements classes to support/store refactorings. >> > // >> > >> > //===----------------------------------------------------------------------===// >> > >> > +#include "clang/Basic/Diagnostic.h" >> > +#include "clang/Basic/DiagnosticIDs.h" >> > #include "clang/Basic/DiagnosticOptions.h" >> > #include "clang/Basic/FileManager.h" >> > #include "clang/Basic/SourceManager.h" >> > -#include "clang/Frontend/TextDiagnosticPrinter.h" >> > #include "clang/Lex/Lexer.h" >> > #include "clang/Rewrite/Core/Rewriter.h" >> > -#include "clang/Tooling/Refactoring.h" >> > +#include "clang/Tooling/Core/Replacement.h" >> > #include "llvm/Support/FileSystem.h" >> > #include "llvm/Support/Path.h" >> > #include "llvm/Support/raw_os_ostream.h" >> > @@ -142,67 +143,6 @@ void Replacement::setFromSourceRange(con >> > getRangeSize(Sources, Range), ReplacementText); >> > } >> > >> > -bool applyAllReplacements(const Replacements &Replaces, Rewriter >> > &Rewrite) { >> > - bool Result = true; >> > - for (Replacements::const_iterator I = Replaces.begin(), >> > - E = Replaces.end(); >> > - I != E; ++I) { >> > - if (I->isApplicable()) { >> > - Result = I->apply(Rewrite) && Result; >> > - } else { >> > - Result = false; >> > - } >> > - } >> > - return Result; >> > -} >> > - >> > -// FIXME: Remove this function when Replacements is implemented as >> > std::vector >> > -// instead of std::set. >> > -bool applyAllReplacements(const std::vector<Replacement> &Replaces, >> > - Rewriter &Rewrite) { >> > - bool Result = true; >> > - for (std::vector<Replacement>::const_iterator I = Replaces.begin(), >> > - E = Replaces.end(); >> > - I != E; ++I) { >> > - if (I->isApplicable()) { >> > - Result = I->apply(Rewrite) && Result; >> > - } else { >> > - Result = false; >> > - } >> > - } >> > - return Result; >> > -} >> > - >> > -std::string applyAllReplacements(StringRef Code, const Replacements >> > &Replaces) { >> > - FileManager Files((FileSystemOptions())); >> > - DiagnosticsEngine Diagnostics( >> > - IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), >> > - new DiagnosticOptions); >> > - Diagnostics.setClient(new TextDiagnosticPrinter( >> > - llvm::outs(), &Diagnostics.getDiagnosticOptions())); >> > - 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; >> > -} >> > - >> > unsigned shiftedCodePosition(const Replacements &Replaces, unsigned >> > Position) { >> > unsigned NewPosition = Position; >> > for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); >> > I != E; >> > @@ -285,41 +225,65 @@ void deduplicate(std::vector<Replacement >> > Conflicts.push_back(Range(ConflictStart, ConflictLength)); >> > } >> > >> > - >> > -RefactoringTool::RefactoringTool(const CompilationDatabase >> > &Compilations, >> > - ArrayRef<std::string> SourcePaths) >> > - : ClangTool(Compilations, SourcePaths) {} >> > - >> > -Replacements &RefactoringTool::getReplacements() { return Replace; } >> > - >> > -int RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) { >> > - if (int Result = run(ActionFactory)) { >> > - return Result; >> > - } >> > - >> > - LangOptions DefaultLangOptions; >> > - IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new >> > DiagnosticOptions(); >> > - TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts); >> > - DiagnosticsEngine Diagnostics( >> > - IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), >> > - &*DiagOpts, &DiagnosticPrinter, false); >> > - SourceManager Sources(Diagnostics, getFiles()); >> > - Rewriter Rewrite(Sources, DefaultLangOptions); >> > - >> > - if (!applyAllReplacements(Rewrite)) { >> > - llvm::errs() << "Skipped some replacements.\n"; >> > +bool applyAllReplacements(const Replacements &Replaces, Rewriter >> > &Rewrite) { >> > + bool Result = true; >> > + for (Replacements::const_iterator I = Replaces.begin(), >> > + E = Replaces.end(); >> > + I != E; ++I) { >> > + if (I->isApplicable()) { >> > + Result = I->apply(Rewrite) && Result; >> > + } else { >> > + Result = false; >> > + } >> > } >> > - >> > - return saveRewrittenFiles(Rewrite); >> > + return Result; >> > } >> > >> > -bool RefactoringTool::applyAllReplacements(Rewriter &Rewrite) { >> > - return tooling::applyAllReplacements(Replace, Rewrite); >> > +// FIXME: Remove this function when Replacements is implemented as >> > std::vector >> > +// instead of std::set. >> > +bool applyAllReplacements(const std::vector<Replacement> &Replaces, >> > + Rewriter &Rewrite) { >> > + bool Result = true; >> > + for (std::vector<Replacement>::const_iterator I = Replaces.begin(), >> > + E = Replaces.end(); >> > + I != E; ++I) { >> > + if (I->isApplicable()) { >> > + Result = I->apply(Rewrite) && Result; >> > + } else { >> > + Result = false; >> > + } >> > + } >> > + return Result; >> > } >> > >> > -int RefactoringTool::saveRewrittenFiles(Rewriter &Rewrite) { >> > - return Rewrite.overwriteChangedFiles() ? 1 : 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; >> > } >> > >> > } // end namespace tooling >> > } // end namespace clang >> > + >> > >> > Modified: cfe/trunk/lib/Tooling/Makefile >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Makefile?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/lib/Tooling/Makefile (original) >> > +++ cfe/trunk/lib/Tooling/Makefile Wed Oct 29 13:55:09 2014 >> > @@ -9,5 +9,6 @@ >> > >> > CLANG_LEVEL := ../.. >> > LIBRARYNAME := clangTooling >> > +PARALLEL_DIRS := Core >> > >> > include $(CLANG_LEVEL)/Makefile >> > >> > Modified: cfe/trunk/lib/Tooling/Refactoring.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring.cpp?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/lib/Tooling/Refactoring.cpp (original) >> > +++ cfe/trunk/lib/Tooling/Refactoring.cpp Wed Oct 29 13:55:09 2014 >> > @@ -25,267 +25,6 @@ >> > namespace clang { >> > namespace tooling { >> > >> > -static const char * const InvalidLocation = ""; >> > - >> > -Replacement::Replacement() >> > - : FilePath(InvalidLocation) {} >> > - >> > -Replacement::Replacement(StringRef FilePath, unsigned Offset, unsigned >> > Length, >> > - StringRef ReplacementText) >> > - : FilePath(FilePath), ReplacementRange(Offset, Length), >> > - ReplacementText(ReplacementText) {} >> > - >> > -Replacement::Replacement(const SourceManager &Sources, SourceLocation >> > Start, >> > - unsigned Length, StringRef ReplacementText) { >> > - setFromSourceLocation(Sources, Start, Length, ReplacementText); >> > -} >> > - >> > -Replacement::Replacement(const SourceManager &Sources, >> > - const CharSourceRange &Range, >> > - StringRef ReplacementText) { >> > - setFromSourceRange(Sources, Range, ReplacementText); >> > -} >> > - >> > -bool Replacement::isApplicable() const { >> > - return FilePath != InvalidLocation; >> > -} >> > - >> > -bool Replacement::apply(Rewriter &Rewrite) const { >> > - SourceManager &SM = Rewrite.getSourceMgr(); >> > - const FileEntry *Entry = SM.getFileManager().getFile(FilePath); >> > - if (!Entry) >> > - 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(ReplacementRange.getOffset()); >> > - // 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, ReplacementRange.getLength(), ReplacementText); >> > - assert(RewriteSucceeded); >> > - return RewriteSucceeded; >> > -} >> > - >> > -std::string Replacement::toString() const { >> > - std::string result; >> > - llvm::raw_string_ostream stream(result); >> > - stream << FilePath << ": " << ReplacementRange.getOffset() << ":+" >> > - << ReplacementRange.getLength() << ":\"" << ReplacementText << >> > "\""; >> > - return result; >> > -} >> > - >> > -bool operator<(const Replacement &LHS, const Replacement &RHS) { >> > - if (LHS.getOffset() != RHS.getOffset()) >> > - return LHS.getOffset() < RHS.getOffset(); >> > - if (LHS.getLength() != RHS.getLength()) >> > - return LHS.getLength() < RHS.getLength(); >> > - if (LHS.getFilePath() != RHS.getFilePath()) >> > - return LHS.getFilePath() < RHS.getFilePath(); >> > - return LHS.getReplacementText() < RHS.getReplacementText(); >> > -} >> > - >> > -bool operator==(const Replacement &LHS, const Replacement &RHS) { >> > - return LHS.getOffset() == RHS.getOffset() && >> > - LHS.getLength() == RHS.getLength() && >> > - LHS.getFilePath() == RHS.getFilePath() && >> > - LHS.getReplacementText() == RHS.getReplacementText(); >> > -} >> > - >> > -void Replacement::setFromSourceLocation(const SourceManager &Sources, >> > - SourceLocation Start, unsigned >> > Length, >> > - StringRef ReplacementText) { >> > - const std::pair<FileID, unsigned> DecomposedLocation = >> > - Sources.getDecomposedLoc(Start); >> > - const FileEntry *Entry = >> > Sources.getFileEntryForID(DecomposedLocation.first); >> > - if (Entry) { >> > - // Make FilePath absolute so replacements can be applied correctly >> > when >> > - // relative paths for files are used. >> > - llvm::SmallString<256> FilePath(Entry->getName()); >> > - std::error_code EC = llvm::sys::fs::make_absolute(FilePath); >> > - this->FilePath = EC ? FilePath.c_str() : Entry->getName(); >> > - } else { >> > - this->FilePath = InvalidLocation; >> > - } >> > - this->ReplacementRange = Range(DecomposedLocation.second, Length); >> > - this->ReplacementText = ReplacementText; >> > -} >> > - >> > -// 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(const 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; >> > -} >> > - >> > -void Replacement::setFromSourceRange(const SourceManager &Sources, >> > - const CharSourceRange &Range, >> > - StringRef ReplacementText) { >> > - setFromSourceLocation(Sources, >> > Sources.getSpellingLoc(Range.getBegin()), >> > - getRangeSize(Sources, Range), ReplacementText); >> > -} >> > - >> > -bool applyAllReplacements(const Replacements &Replaces, Rewriter >> > &Rewrite) { >> > - bool Result = true; >> > - for (Replacements::const_iterator I = Replaces.begin(), >> > - E = Replaces.end(); >> > - I != E; ++I) { >> > - if (I->isApplicable()) { >> > - Result = I->apply(Rewrite) && Result; >> > - } else { >> > - Result = false; >> > - } >> > - } >> > - return Result; >> > -} >> > - >> > -// FIXME: Remove this function when Replacements is implemented as >> > std::vector >> > -// instead of std::set. >> > -bool applyAllReplacements(const std::vector<Replacement> &Replaces, >> > - Rewriter &Rewrite) { >> > - bool Result = true; >> > - for (std::vector<Replacement>::const_iterator I = Replaces.begin(), >> > - E = Replaces.end(); >> > - I != E; ++I) { >> > - if (I->isApplicable()) { >> > - Result = I->apply(Rewrite) && Result; >> > - } else { >> > - Result = false; >> > - } >> > - } >> > - return Result; >> > -} >> > - >> > -std::string applyAllReplacements(StringRef Code, const Replacements >> > &Replaces) { >> > - FileManager Files((FileSystemOptions())); >> > - DiagnosticsEngine Diagnostics( >> > - IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), >> > - new DiagnosticOptions); >> > - Diagnostics.setClient(new TextDiagnosticPrinter( >> > - llvm::outs(), &Diagnostics.getDiagnosticOptions())); >> > - 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; >> > -} >> > - >> > -unsigned shiftedCodePosition(const Replacements &Replaces, unsigned >> > Position) { >> > - unsigned NewPosition = Position; >> > - for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); >> > I != E; >> > - ++I) { >> > - if (I->getOffset() >= Position) >> > - break; >> > - if (I->getOffset() + I->getLength() > Position) >> > - NewPosition += I->getOffset() + I->getLength() - Position; >> > - NewPosition += I->getReplacementText().size() - I->getLength(); >> > - } >> > - return NewPosition; >> > -} >> > - >> > -// FIXME: Remove this function when Replacements is implemented as >> > std::vector >> > -// instead of std::set. >> > -unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces, >> > - unsigned Position) { >> > - unsigned NewPosition = Position; >> > - for (std::vector<Replacement>::const_iterator I = Replaces.begin(), >> > - E = Replaces.end(); >> > - I != E; ++I) { >> > - if (I->getOffset() >= Position) >> > - break; >> > - if (I->getOffset() + I->getLength() > Position) >> > - NewPosition += I->getOffset() + I->getLength() - Position; >> > - NewPosition += I->getReplacementText().size() - I->getLength(); >> > - } >> > - return NewPosition; >> > -} >> > - >> > -void deduplicate(std::vector<Replacement> &Replaces, >> > - std::vector<Range> &Conflicts) { >> > - if (Replaces.empty()) >> > - return; >> > - >> > - auto LessNoPath = [](const Replacement &LHS, const Replacement &RHS) >> > { >> > - if (LHS.getOffset() != RHS.getOffset()) >> > - return LHS.getOffset() < RHS.getOffset(); >> > - if (LHS.getLength() != RHS.getLength()) >> > - return LHS.getLength() < RHS.getLength(); >> > - return LHS.getReplacementText() < RHS.getReplacementText(); >> > - }; >> > - >> > - auto EqualNoPath = [](const Replacement &LHS, const Replacement &RHS) >> > { >> > - return LHS.getOffset() == RHS.getOffset() && >> > - LHS.getLength() == RHS.getLength() && >> > - LHS.getReplacementText() == RHS.getReplacementText(); >> > - }; >> > - >> > - // Deduplicate. We don't want to deduplicate based on the path as we >> > assume >> > - // that all replacements refer to the same file (or are symlinks). >> > - std::sort(Replaces.begin(), Replaces.end(), LessNoPath); >> > - Replaces.erase(std::unique(Replaces.begin(), Replaces.end(), >> > EqualNoPath), >> > - Replaces.end()); >> > - >> > - // Detect conflicts >> > - Range ConflictRange(Replaces.front().getOffset(), >> > - Replaces.front().getLength()); >> > - unsigned ConflictStart = 0; >> > - unsigned ConflictLength = 1; >> > - for (unsigned i = 1; i < Replaces.size(); ++i) { >> > - Range Current(Replaces[i].getOffset(), Replaces[i].getLength()); >> > - if (ConflictRange.overlapsWith(Current)) { >> > - // Extend conflicted range >> > - ConflictRange = Range(ConflictRange.getOffset(), >> > - std::max(ConflictRange.getLength(), >> > - Current.getOffset() + >> > Current.getLength() - >> > - ConflictRange.getOffset())); >> > - ++ConflictLength; >> > - } else { >> > - if (ConflictLength > 1) >> > - Conflicts.push_back(Range(ConflictStart, ConflictLength)); >> > - ConflictRange = Current; >> > - ConflictStart = i; >> > - ConflictLength = 1; >> > - } >> > - } >> > - >> > - if (ConflictLength > 1) >> > - Conflicts.push_back(Range(ConflictStart, ConflictLength)); >> > -} >> > - >> > - >> > RefactoringTool::RefactoringTool(const CompilationDatabase >> > &Compilations, >> > ArrayRef<std::string> SourcePaths) >> > : ClangTool(Compilations, SourcePaths) {} >> > >> > Modified: cfe/trunk/tools/clang-format/CMakeLists.txt >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/CMakeLists.txt?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/tools/clang-format/CMakeLists.txt (original) >> > +++ cfe/trunk/tools/clang-format/CMakeLists.txt Wed Oct 29 13:55:09 2014 >> > @@ -9,7 +9,6 @@ target_link_libraries(clang-format >> > clangFormat >> > clangLex >> > clangRewrite >> > - clangTooling >> > ) >> > >> > install(TARGETS clang-format RUNTIME DESTINATION bin) >> > >> > Modified: cfe/trunk/tools/clang-format/Makefile >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/Makefile?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/tools/clang-format/Makefile (original) >> > +++ cfe/trunk/tools/clang-format/Makefile Wed Oct 29 13:55:09 2014 >> > @@ -16,9 +16,7 @@ TOOL_NO_EXPORTS = 1 >> > >> > include $(CLANG_LEVEL)/../../Makefile.config >> > LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc >> > option >> > -USEDLIBS = clangFormat.a clangTooling.a clangFrontend.a >> > clangSerialization.a \ >> > - clangDriver.a clangParse.a clangSema.a clangAnalysis.a \ >> > - clangRewriteFrontend.a clangRewrite.a clangEdit.a clangAST.a >> > \ >> > +USEDLIBS = clangFormat.a clangToolingCore.a clangDriver.a >> > clangRewrite.a \ >> > clangLex.a clangBasic.a >> > >> > include $(CLANG_LEVEL)/Makefile >> > >> > Modified: cfe/trunk/tools/libclang/Makefile >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Makefile?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/tools/libclang/Makefile (original) >> > +++ cfe/trunk/tools/libclang/Makefile Wed Oct 29 13:55:09 2014 >> > @@ -20,7 +20,7 @@ LINK_COMPONENTS := AsmParser BitReader C >> > USEDLIBS = clangIndex.a clangARCMigrate.a \ >> > clangRewriteFrontend.a \ >> > clangFormat.a \ >> > - clangTooling.a \ >> > + clangTooling.a clangToolingCore.a \ >> > clangFrontend.a clangDriver.a \ >> > clangSerialization.a \ >> > clangParse.a clangSema.a \ >> > >> > Modified: cfe/trunk/unittests/Format/CMakeLists.txt >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/CMakeLists.txt?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/unittests/Format/CMakeLists.txt (original) >> > +++ cfe/trunk/unittests/Format/CMakeLists.txt Wed Oct 29 13:55:09 2014 >> > @@ -11,5 +11,5 @@ add_clang_unittest(FormatTests >> > >> > target_link_libraries(FormatTests >> > clangFormat >> > - clangTooling >> > + clangToolingCore >> > ) >> > >> > Modified: cfe/trunk/unittests/Format/Makefile >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/Makefile?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/unittests/Format/Makefile (original) >> > +++ cfe/trunk/unittests/Format/Makefile Wed Oct 29 13:55:09 2014 >> > @@ -11,8 +11,8 @@ CLANG_LEVEL = ../.. >> > TESTNAME = Format >> > include $(CLANG_LEVEL)/../../Makefile.config >> > LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc >> > option >> > -USEDLIBS = clangFormat.a clangTooling.a clangFrontend.a >> > clangSerialization.a \ >> > - clangDriver.a clangParse.a clangRewrite.a \ >> > +USEDLIBS = clangFormat.a clangTooling.a clangToolingCore.a >> > clangFrontend.a \ >> > + clangSerialization.a clangDriver.a clangParse.a >> > clangRewrite.a \ >> > clangRewriteFrontend.a clangSema.a clangAnalysis.a >> > clangEdit.a \ >> > clangAST.a clangASTMatchers.a clangLex.a clangBasic.a >> > >> > >> > Modified: cfe/trunk/unittests/Tooling/Makefile >> > URL: >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/Makefile?rev=220867&r1=220866&r2=220867&view=diff >> > >> > ============================================================================== >> > --- cfe/trunk/unittests/Tooling/Makefile (original) >> > +++ cfe/trunk/unittests/Tooling/Makefile Wed Oct 29 13:55:09 2014 >> > @@ -11,7 +11,8 @@ CLANG_LEVEL = ../.. >> > TESTNAME = Tooling >> > include $(CLANG_LEVEL)/../../Makefile.config >> > LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc >> > option >> > -USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a >> > clangDriver.a \ >> > +USEDLIBS = clangTooling.a clangToolingCore.a clangFrontend.a \ >> > + clangSerialization.a clangDriver.a \ >> > clangParse.a clangRewrite.a clangRewriteFrontend.a \ >> > clangSema.a clangAnalysis.a clangEdit.a \ >> > clangAST.a clangASTMatchers.a clangLex.a clangBasic.a >> > >> > >> > _______________________________________________ >> > cfe-commits mailing list >> > [email protected] >> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
