Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Unified Diff: tools/clang/BindMigrate/BindMigrateConsumer.cpp

Issue 7886056: Clang plugin that rewrites PostTask(_, NewRunnableMethod(...)) to PostTask(_, base::Bind(...)); (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix lifetime issue where BindMigrateAction is deleted before the ASTConsumer is finished. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/clang/BindMigrate/BindMigrateConsumer.h ('k') | tools/clang/BindMigrate/BindMigrateOptions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/clang/BindMigrate/BindMigrateConsumer.cpp
diff --git a/tools/clang/BindMigrate/BindMigrateConsumer.cpp b/tools/clang/BindMigrate/BindMigrateConsumer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..873948913c32300510579b5f4e5f45701fcdc70c
--- /dev/null
+++ b/tools/clang/BindMigrate/BindMigrateConsumer.cpp
@@ -0,0 +1,155 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iostream>
+#include <string>
+
+#include "BindMigrateConsumer.h"
+
+#include "clang/AST/AST.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Index/DeclReferenceMap.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Rewrite/ASTConsumers.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+#include "BindMigrateOptions.h"
+#include "OldCallbackTransform.h"
+#include "PostTaskTransform.h"
+#include "Util.h"
+
+using namespace std;
+
+namespace clang {
+
+BindMigrateConsumer::BindMigrateConsumer(CompilerInstance* instance,
+ const BindMigrateOptions& options)
+ : instance_(instance),
+ error_emitter_(instance, "[bind-migrate] "),
+ options_(options) {
+}
+
+BindMigrateConsumer::~BindMigrateConsumer() {
+}
+
+void BindMigrateConsumer::Initialize(ASTContext &context) {
+ remapper_.initFromDisk(options_.out_dir,
+ instance_->getDiagnostics(),
+ /*ignoreIfFilesChanges=*/true);
+
+ rewriter_.setSourceMgr(context.getSourceManager(), context.getLangOptions());
+}
+
+void BindMigrateConsumer::HandleTranslationUnit(ASTContext &context) {
+ OldCallbackTransform old_callback_tf(&context, &rewriter_, &error_emitter_);
+ PostTaskTransform post_task_tf(&context, &rewriter_, &error_emitter_);
+
+ // Create actual TransformApplier with all the wanted transforms.
+ std::vector<Transform*> transforms;
+ transforms.push_back(&old_callback_tf);
+ transforms.push_back(&post_task_tf);
+ TransformApplier transform_applier(transforms);
+ TransformCandidatePrinter transform_candidate_printer(
+ transforms, &context.getSourceManager());
+
+ // modify calls
+ TranslationUnitDecl *translation_unit = context.getTranslationUnitDecl();
+ for (DeclContext::decl_iterator it = translation_unit->decls_begin(),
+ end = translation_unit->decls_end(); it != end; ++it) {
+
+ SourceManager& source_manager = context.getSourceManager();
+
+ // Only consider our files.
+ const FileEntry* file_entry =
+ GetValidFile(source_manager, (*it)->getLocation());
+ if (!file_entry) {
+ continue;
+ }
+
+ // Apply blacklist.
+ string file_name = file_entry->getName();
+ bool in_blacklist = false;
+ for (vector<string>::const_iterator path =
+ options_.ignore_path_prefix.begin();
+ path != options_.ignore_path_prefix.end();
+ ++path) {
+ llvm::SmallString<512> abs_path;
+ llvm::Twine(*path).toVector(abs_path);
+ llvm::sys::fs::make_absolute(abs_path);
+ if (file_name.find(abs_path.c_str()) != string::npos) {
+ in_blacklist = true;
+ break;
+ }
+ }
+ if (in_blacklist) continue;
+
+ // Apply whitelist.
+ bool in_whitelist = options_.only_path_prefix.empty();
+ for (vector<string>::const_iterator path =
+ options_.only_path_prefix.begin();
+ path != options_.only_path_prefix.end();
+ ++path) {
+ llvm::SmallString<512> abs_path;
+ llvm::Twine(*path).toVector(abs_path);
+ llvm::sys::fs::make_absolute(abs_path);
+ if (file_name.find(abs_path.c_str()) != string::npos) {
+ in_whitelist = true;
+ break;
+ }
+ }
+ if (!in_whitelist) continue;
+
+ if (options_.mode == "print") {
+ transform_candidate_printer.TraverseDecl(*it);
+ } else if (options_.mode == "transform") {
+ transform_applier.TraverseDecl(*it);
+ }
+ }
+
+ // Get the buffer corresponding to MainFileID.
+ for (Rewriter::buffer_iterator it = rewriter_.buffer_begin();
+ it != rewriter_.buffer_end();
+ ++it) {
+ const FileEntry *file =
+ context.getSourceManager().getFileEntryForID(it->first);
+ assert(file);
+
+ std::string new_filename = file->getName();
+ new_filename += "-trans";
+ llvm::SmallString<512> new_text;
+ llvm::raw_svector_ostream vecOS(new_text);
+ it->second.write(vecOS);
+ vecOS.flush();
+ llvm::MemoryBuffer *mem_buf = llvm::MemoryBuffer::getMemBufferCopy(
+ StringRef(new_text.data(), new_text.size()), new_filename);
+ llvm::SmallString<64> orig_filename(file->getName());
+ instance_->getFileManager().FixupRelativePath(orig_filename);
+ remapper_.remap(orig_filename.str(), mem_buf);
+ }
+
+ // TODO(ajwong): We should just hook into BeginInvocation() like ARCMigrate
+ // does. As is, it is hard to flush at the end of the compilation sequence
+ // because there's no such thing as EndInvocation().
+ remapper_.writeParallelTree(options_.out_dir, instance_->getDiagnostics());
+}
+
+} // namespace clang
« no previous file with comments | « tools/clang/BindMigrate/BindMigrateConsumer.h ('k') | tools/clang/BindMigrate/BindMigrateOptions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698