| 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
|
|
|