]> granicus.if.org Git - clang/commitdiff
Raise the ARCMT functionality in Clang into proper FrontendActions.
authorChandler Carruth <chandlerc@gmail.com>
Thu, 16 Jun 2011 16:17:05 +0000 (16:17 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Thu, 16 Jun 2011 16:17:05 +0000 (16:17 +0000)
These are somewhat special in that they wrap any other FrontendAction,
running various ARC transformations or checks prior to the standard
action's run. To implement them easily, this extends FrontendAction to
have a WrapperFrontendAction utility class which forwards all calls by
default to an inner action setup at construction time. This is then
subclassed to override the specific behavior needed by the different
ARCMT tools.

Finally, FrontendTool is taught how to create these wrapper actions from
the existing flags and options structures.

The result is that clangFrontend no longer depends on clangARCMigrate.
This is very important, as clangARCMigrate *heavily* depends on
clangFrontend. Fundamentally ARCMigrate is at the same layer as
a library like Rewrite, sitting firmly on top of the Frontend, but tied
together with the FrontendTool when building the clang binary itself.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133161 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/ARCMigrate/ARCMTActions.h [new file with mode: 0644]
include/clang/Frontend/FrontendAction.h
lib/ARCMigrate/ARCMTActions.cpp [new file with mode: 0644]
lib/ARCMigrate/CMakeLists.txt
lib/Frontend/CMakeLists.txt
lib/Frontend/CompilerInstance.cpp
lib/Frontend/FrontendAction.cpp
lib/FrontendTool/CMakeLists.txt
lib/FrontendTool/ExecuteCompilerInvocation.cpp

diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
new file mode 100644 (file)
index 0000000..d2d9410
--- /dev/null
@@ -0,0 +1,46 @@
+//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
+#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+namespace arcmt {
+
+class CheckAction : public WrapperFrontendAction {
+protected:
+  virtual void ExecuteAction();
+
+public:
+  CheckAction(FrontendAction *WrappedAction);
+};
+
+class TransformationAction : public WrapperFrontendAction {
+protected:
+  virtual void ExecuteAction();
+
+public:
+  TransformationAction(FrontendAction *WrappedAction);
+};
+
+class InMemoryTransformationAction : public WrapperFrontendAction {
+protected:
+  virtual void ExecuteAction();
+
+public:
+  InMemoryTransformationAction(FrontendAction *WrappedAction);
+};
+
+}
+}
+
+#endif
index ee0863a4776fc172b01cf5f34907f0e3c12f2095..2538f55aaff9c72a1134bf2855ab15f3ae2457f6 100644 (file)
@@ -51,6 +51,7 @@ class FrontendAction {
   llvm::OwningPtr<ASTUnit> CurrentASTUnit;
   CompilerInstance *Instance;
   friend class ASTMergeAction;
+  friend class WrapperFrontendAction;
 
 private:
   ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
@@ -253,6 +254,35 @@ public:
   virtual bool usesPreprocessorOnly() const { return true; }
 };
 
+/// WrapperFrontendAction - A frontend action which simply wraps some other
+/// runtime specified frontend action. Deriving from this class allows an
+/// action to inject custom logic around some existing action's behavior. It
+/// implements every virtual method in the FrontendAction interface by
+/// forwarding to the wrapped action.
+class WrapperFrontendAction : public FrontendAction {
+  llvm::OwningPtr<FrontendAction> WrappedAction;
+
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+  virtual bool BeginSourceFileAction(CompilerInstance &CI,
+                                     llvm::StringRef Filename);
+  virtual void ExecuteAction();
+  virtual void EndSourceFileAction();
+
+public:
+  /// Construct a WrapperFrontendAction from an existing action, taking
+  /// ownership of it.
+  WrapperFrontendAction(FrontendAction *WrappedAction);
+
+  virtual bool usesPreprocessorOnly() const;
+  virtual bool usesCompleteTranslationUnit();
+  virtual bool hasPCHSupport() const;
+  virtual bool hasASTFileSupport() const;
+  virtual bool hasIRSupport() const;
+  virtual bool hasCodeCompletionSupport() const;
+};
+
 }  // end namespace clang
 
 #endif
diff --git a/lib/ARCMigrate/ARCMTActions.cpp b/lib/ARCMigrate/ARCMTActions.cpp
new file mode 100644 (file)
index 0000000..a30c278
--- /dev/null
@@ -0,0 +1,58 @@
+//===--- ARCMTActions.cpp - ARC Migrate Tool Frontend Actions ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ARCMigrate/ARCMTActions.h"
+#include "clang/ARCMigrate/ARCMT.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+using namespace clang;
+using namespace arcmt;
+
+void CheckAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  if (arcmt::checkForManualIssues(CI.getInvocation(), getCurrentFile(),
+                                  getCurrentFileKind(),
+                                  CI.getDiagnostics().getClient()))
+    return;
+
+  // We only want to see warnings reported from arcmt::checkForManualIssues.
+  CI.getDiagnostics().setIgnoreAllWarnings(true);
+  WrapperFrontendAction::ExecuteAction();
+}
+
+CheckAction::CheckAction(FrontendAction *WrappedAction)
+  : WrapperFrontendAction(WrappedAction) {}
+
+void TransformationAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  if (arcmt::applyTransformations(CI.getInvocation(), getCurrentFile(),
+                                  getCurrentFileKind(),
+                                  CI.getDiagnostics().getClient()))
+    return;
+
+  WrapperFrontendAction::ExecuteAction();
+}
+
+TransformationAction::TransformationAction(FrontendAction *WrappedAction)
+  : WrapperFrontendAction(WrappedAction) {}
+
+void InMemoryTransformationAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  if (arcmt::applyTransformationsInMemory(CI.getInvocation(), getCurrentFile(),
+                                          getCurrentFileKind(),
+                                          CI.getDiagnostics().getClient()))
+    return;
+
+  WrapperFrontendAction::ExecuteAction();
+}
+
+InMemoryTransformationAction::InMemoryTransformationAction(
+    FrontendAction *WrappedAction)
+  : WrapperFrontendAction(WrappedAction) {}
+
index 3645a22356639224a17b13062031b1fc6df7b78c..0049d2ff37cc2aad95fb720d2cd3532cdfbebf3f 100644 (file)
@@ -2,6 +2,7 @@ set(LLVM_USED_LIBS clangBasic clangAST clangParse clangFrontend clangRewrite)
 
 add_clang_library(clangARCMigrate
   ARCMT.cpp
+  ARCMTActions.cpp
   FileRemapper.cpp
   TransformActions.cpp
   Transforms.cpp
index 5565b7b4a852efc7b46d1bca6366d7c8350d1ddb..7dcbebff39b8a11f73733cc5277d4237e379ce5d 100644 (file)
@@ -1,5 +1,4 @@
 set( LLVM_USED_LIBS
-  clangARCMigrate
   clangAST
   clangBasic
   clangDriver
index b05c24a9851e07396f73a96b37c027778e421803..38fcfe3c4711fe16f1ffa22c72edec60469f4027 100644 (file)
@@ -26,7 +26,6 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/VerifyDiagnosticsClient.h"
 #include "clang/Frontend/Utils.h"
-#include "clang/ARCMigrate/ARCMT.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/Support/FileSystem.h"
@@ -597,34 +596,6 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
     if (hasSourceManager())
       getSourceManager().clearIDTables();
 
-    switch (getFrontendOpts().ARCMTAction) {
-    default:
-      break;
-
-    case FrontendOptions::ARCMT_Check:
-      if (arcmt::checkForManualIssues(getInvocation(), InFile,
-                                      getFrontendOpts().Inputs[i].first,
-                                      getDiagnostics().getClient()))
-        continue;
-      // We only want to see warnings reported from arcmt::checkForManualIssues.
-      getDiagnostics().setIgnoreAllWarnings(true);
-      break;
-
-    case FrontendOptions::ARCMT_Modify:
-      if (arcmt::applyTransformations(getInvocation(), InFile,
-                                      getFrontendOpts().Inputs[i].first,
-                                      getDiagnostics().getClient()))
-        continue;
-      break;
-
-    case FrontendOptions::ARCMT_ModifyInMemory:
-      if (arcmt::applyTransformationsInMemory(getInvocation(), InFile,
-                                              getFrontendOpts().Inputs[i].first,
-                                              getDiagnostics().getClient()))
-        continue;
-      break;
-    }
-
     if (Act.BeginSourceFile(*this, InFile, getFrontendOpts().Inputs[i].first)) {
       Act.Execute();
       Act.EndSourceFile();
index 42da44c2c720fb83d6f115a0b641fe2a39cb0fc9..0024818ad85d90008d0ad3f70db22e2236fdc5fd 100644 (file)
@@ -381,3 +381,41 @@ PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
                                               llvm::StringRef InFile) {
   llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
 }
+
+ASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
+                                                      llvm::StringRef InFile) {
+  return WrappedAction->CreateASTConsumer(CI, InFile);
+}
+bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI,
+                                                  llvm::StringRef Filename) {
+  return WrappedAction->BeginSourceFileAction(CI, Filename);
+}
+void WrapperFrontendAction::ExecuteAction() {
+  WrappedAction->ExecuteAction();
+}
+void WrapperFrontendAction::EndSourceFileAction() {
+  WrappedAction->EndSourceFileAction();
+}
+
+bool WrapperFrontendAction::usesPreprocessorOnly() const {
+  return WrappedAction->usesPreprocessorOnly();
+}
+bool WrapperFrontendAction::usesCompleteTranslationUnit() {
+  return WrappedAction->usesCompleteTranslationUnit();
+}
+bool WrapperFrontendAction::hasPCHSupport() const {
+  return WrappedAction->hasPCHSupport();
+}
+bool WrapperFrontendAction::hasASTFileSupport() const {
+  return WrappedAction->hasASTFileSupport();
+}
+bool WrapperFrontendAction::hasIRSupport() const {
+  return WrappedAction->hasIRSupport();
+}
+bool WrapperFrontendAction::hasCodeCompletionSupport() const {
+  return WrappedAction->hasCodeCompletionSupport();
+}
+
+WrapperFrontendAction::WrapperFrontendAction(FrontendAction *WrappedAction)
+  : WrappedAction(WrappedAction) {}
+
index 720ce2adf123c44d726780cc85d78df2d1ce71b6..b8e4329c07f90f6c3d322497521c77cab7a4fd55 100644 (file)
@@ -1,5 +1,6 @@
 set(LLVM_USED_LIBS clangDriver clangFrontend clangRewrite clangCodeGen 
-    clangStaticAnalyzerFrontend clangStaticAnalyzerCheckers clangStaticAnalyzerCore)
+    clangStaticAnalyzerFrontend clangStaticAnalyzerCheckers clangStaticAnalyzerCore
+    clangARCMigrate)
 
 add_clang_library(clangFrontendTool
   ExecuteCompilerInvocation.cpp
index 664b53351dc123c548369ad013125022b5f77ee5..7ad263e14b8cc66915eb347d1597947ebc3f290c 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "clang/FrontendTool/Utils.h"
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
+#include "clang/ARCMigrate/ARCMTActions.h"
 #include "clang/CodeGen/CodeGenAction.h"
 #include "clang/Driver/CC1Options.h"
 #include "clang/Driver/OptTable.h"
@@ -89,6 +90,21 @@ static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
   if (!Act)
     return 0;
 
+  // Potentially wrap the base FE action in an ARC Migrate Tool action.
+  switch (CI.getFrontendOpts().ARCMTAction) {
+  case FrontendOptions::ARCMT_None:
+    break;
+  case FrontendOptions::ARCMT_Check:
+    Act = new arcmt::CheckAction(Act);
+    break;
+  case FrontendOptions::ARCMT_Modify:
+    Act = new arcmt::TransformationAction(Act);
+    break;
+  case FrontendOptions::ARCMT_ModifyInMemory:
+    Act = new arcmt::InMemoryTransformationAction(Act);
+    break;
+  }
+
   // If there are any AST files to merge, create a frontend action
   // adaptor to perform the merge.
   if (!CI.getFrontendOpts().ASTMergeFiles.empty())