Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit f7f8188

Browse files
committed
Raise the ARCMT functionality in Clang into proper FrontendActions.
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
1 parent 119f19b commit f7f8188

File tree

9 files changed

+191
-31
lines changed

9 files changed

+191
-31
lines changed
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
11+
#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
12+
13+
#include "clang/Frontend/FrontendAction.h"
14+
#include "llvm/ADT/OwningPtr.h"
15+
16+
namespace clang {
17+
namespace arcmt {
18+
19+
class CheckAction : public WrapperFrontendAction {
20+
protected:
21+
virtual void ExecuteAction();
22+
23+
public:
24+
CheckAction(FrontendAction *WrappedAction);
25+
};
26+
27+
class TransformationAction : public WrapperFrontendAction {
28+
protected:
29+
virtual void ExecuteAction();
30+
31+
public:
32+
TransformationAction(FrontendAction *WrappedAction);
33+
};
34+
35+
class InMemoryTransformationAction : public WrapperFrontendAction {
36+
protected:
37+
virtual void ExecuteAction();
38+
39+
public:
40+
InMemoryTransformationAction(FrontendAction *WrappedAction);
41+
};
42+
43+
}
44+
}
45+
46+
#endif

include/clang/Frontend/FrontendAction.h

+30
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class FrontendAction {
5151
llvm::OwningPtr<ASTUnit> CurrentASTUnit;
5252
CompilerInstance *Instance;
5353
friend class ASTMergeAction;
54+
friend class WrapperFrontendAction;
5455

5556
private:
5657
ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
@@ -253,6 +254,35 @@ class PreprocessorFrontendAction : public FrontendAction {
253254
virtual bool usesPreprocessorOnly() const { return true; }
254255
};
255256

257+
/// WrapperFrontendAction - A frontend action which simply wraps some other
258+
/// runtime specified frontend action. Deriving from this class allows an
259+
/// action to inject custom logic around some existing action's behavior. It
260+
/// implements every virtual method in the FrontendAction interface by
261+
/// forwarding to the wrapped action.
262+
class WrapperFrontendAction : public FrontendAction {
263+
llvm::OwningPtr<FrontendAction> WrappedAction;
264+
265+
protected:
266+
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
267+
llvm::StringRef InFile);
268+
virtual bool BeginSourceFileAction(CompilerInstance &CI,
269+
llvm::StringRef Filename);
270+
virtual void ExecuteAction();
271+
virtual void EndSourceFileAction();
272+
273+
public:
274+
/// Construct a WrapperFrontendAction from an existing action, taking
275+
/// ownership of it.
276+
WrapperFrontendAction(FrontendAction *WrappedAction);
277+
278+
virtual bool usesPreprocessorOnly() const;
279+
virtual bool usesCompleteTranslationUnit();
280+
virtual bool hasPCHSupport() const;
281+
virtual bool hasASTFileSupport() const;
282+
virtual bool hasIRSupport() const;
283+
virtual bool hasCodeCompletionSupport() const;
284+
};
285+
256286
} // end namespace clang
257287

258288
#endif

lib/ARCMigrate/ARCMTActions.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===--- ARCMTActions.cpp - ARC Migrate Tool Frontend Actions ---*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "clang/ARCMigrate/ARCMTActions.h"
11+
#include "clang/ARCMigrate/ARCMT.h"
12+
#include "clang/Frontend/CompilerInstance.h"
13+
14+
using namespace clang;
15+
using namespace arcmt;
16+
17+
void CheckAction::ExecuteAction() {
18+
CompilerInstance &CI = getCompilerInstance();
19+
if (arcmt::checkForManualIssues(CI.getInvocation(), getCurrentFile(),
20+
getCurrentFileKind(),
21+
CI.getDiagnostics().getClient()))
22+
return;
23+
24+
// We only want to see warnings reported from arcmt::checkForManualIssues.
25+
CI.getDiagnostics().setIgnoreAllWarnings(true);
26+
WrapperFrontendAction::ExecuteAction();
27+
}
28+
29+
CheckAction::CheckAction(FrontendAction *WrappedAction)
30+
: WrapperFrontendAction(WrappedAction) {}
31+
32+
void TransformationAction::ExecuteAction() {
33+
CompilerInstance &CI = getCompilerInstance();
34+
if (arcmt::applyTransformations(CI.getInvocation(), getCurrentFile(),
35+
getCurrentFileKind(),
36+
CI.getDiagnostics().getClient()))
37+
return;
38+
39+
WrapperFrontendAction::ExecuteAction();
40+
}
41+
42+
TransformationAction::TransformationAction(FrontendAction *WrappedAction)
43+
: WrapperFrontendAction(WrappedAction) {}
44+
45+
void InMemoryTransformationAction::ExecuteAction() {
46+
CompilerInstance &CI = getCompilerInstance();
47+
if (arcmt::applyTransformationsInMemory(CI.getInvocation(), getCurrentFile(),
48+
getCurrentFileKind(),
49+
CI.getDiagnostics().getClient()))
50+
return;
51+
52+
WrapperFrontendAction::ExecuteAction();
53+
}
54+
55+
InMemoryTransformationAction::InMemoryTransformationAction(
56+
FrontendAction *WrappedAction)
57+
: WrapperFrontendAction(WrappedAction) {}
58+

lib/ARCMigrate/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ set(LLVM_USED_LIBS clangBasic clangAST clangParse clangFrontend clangRewrite)
22

33
add_clang_library(clangARCMigrate
44
ARCMT.cpp
5+
ARCMTActions.cpp
56
FileRemapper.cpp
67
TransformActions.cpp
78
Transforms.cpp

lib/Frontend/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
set( LLVM_USED_LIBS
2-
clangARCMigrate
32
clangAST
43
clangBasic
54
clangDriver

lib/Frontend/CompilerInstance.cpp

-29
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include "clang/Frontend/TextDiagnosticPrinter.h"
2727
#include "clang/Frontend/VerifyDiagnosticsClient.h"
2828
#include "clang/Frontend/Utils.h"
29-
#include "clang/ARCMigrate/ARCMT.h"
3029
#include "clang/Serialization/ASTReader.h"
3130
#include "clang/Sema/CodeCompleteConsumer.h"
3231
#include "llvm/Support/FileSystem.h"
@@ -597,34 +596,6 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
597596
if (hasSourceManager())
598597
getSourceManager().clearIDTables();
599598

600-
switch (getFrontendOpts().ARCMTAction) {
601-
default:
602-
break;
603-
604-
case FrontendOptions::ARCMT_Check:
605-
if (arcmt::checkForManualIssues(getInvocation(), InFile,
606-
getFrontendOpts().Inputs[i].first,
607-
getDiagnostics().getClient()))
608-
continue;
609-
// We only want to see warnings reported from arcmt::checkForManualIssues.
610-
getDiagnostics().setIgnoreAllWarnings(true);
611-
break;
612-
613-
case FrontendOptions::ARCMT_Modify:
614-
if (arcmt::applyTransformations(getInvocation(), InFile,
615-
getFrontendOpts().Inputs[i].first,
616-
getDiagnostics().getClient()))
617-
continue;
618-
break;
619-
620-
case FrontendOptions::ARCMT_ModifyInMemory:
621-
if (arcmt::applyTransformationsInMemory(getInvocation(), InFile,
622-
getFrontendOpts().Inputs[i].first,
623-
getDiagnostics().getClient()))
624-
continue;
625-
break;
626-
}
627-
628599
if (Act.BeginSourceFile(*this, InFile, getFrontendOpts().Inputs[i].first)) {
629600
Act.Execute();
630601
Act.EndSourceFile();

lib/Frontend/FrontendAction.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,41 @@ PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
381381
llvm::StringRef InFile) {
382382
llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
383383
}
384+
385+
ASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
386+
llvm::StringRef InFile) {
387+
return WrappedAction->CreateASTConsumer(CI, InFile);
388+
}
389+
bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI,
390+
llvm::StringRef Filename) {
391+
return WrappedAction->BeginSourceFileAction(CI, Filename);
392+
}
393+
void WrapperFrontendAction::ExecuteAction() {
394+
WrappedAction->ExecuteAction();
395+
}
396+
void WrapperFrontendAction::EndSourceFileAction() {
397+
WrappedAction->EndSourceFileAction();
398+
}
399+
400+
bool WrapperFrontendAction::usesPreprocessorOnly() const {
401+
return WrappedAction->usesPreprocessorOnly();
402+
}
403+
bool WrapperFrontendAction::usesCompleteTranslationUnit() {
404+
return WrappedAction->usesCompleteTranslationUnit();
405+
}
406+
bool WrapperFrontendAction::hasPCHSupport() const {
407+
return WrappedAction->hasPCHSupport();
408+
}
409+
bool WrapperFrontendAction::hasASTFileSupport() const {
410+
return WrappedAction->hasASTFileSupport();
411+
}
412+
bool WrapperFrontendAction::hasIRSupport() const {
413+
return WrappedAction->hasIRSupport();
414+
}
415+
bool WrapperFrontendAction::hasCodeCompletionSupport() const {
416+
return WrappedAction->hasCodeCompletionSupport();
417+
}
418+
419+
WrapperFrontendAction::WrapperFrontendAction(FrontendAction *WrappedAction)
420+
: WrappedAction(WrappedAction) {}
421+

lib/FrontendTool/CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
set(LLVM_USED_LIBS clangDriver clangFrontend clangRewrite clangCodeGen
2-
clangStaticAnalyzerFrontend clangStaticAnalyzerCheckers clangStaticAnalyzerCore)
2+
clangStaticAnalyzerFrontend clangStaticAnalyzerCheckers clangStaticAnalyzerCore
3+
clangARCMigrate)
34

45
add_clang_library(clangFrontendTool
56
ExecuteCompilerInvocation.cpp

lib/FrontendTool/ExecuteCompilerInvocation.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "clang/FrontendTool/Utils.h"
1616
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
17+
#include "clang/ARCMigrate/ARCMTActions.h"
1718
#include "clang/CodeGen/CodeGenAction.h"
1819
#include "clang/Driver/CC1Options.h"
1920
#include "clang/Driver/OptTable.h"
@@ -89,6 +90,21 @@ static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
8990
if (!Act)
9091
return 0;
9192

93+
// Potentially wrap the base FE action in an ARC Migrate Tool action.
94+
switch (CI.getFrontendOpts().ARCMTAction) {
95+
case FrontendOptions::ARCMT_None:
96+
break;
97+
case FrontendOptions::ARCMT_Check:
98+
Act = new arcmt::CheckAction(Act);
99+
break;
100+
case FrontendOptions::ARCMT_Modify:
101+
Act = new arcmt::TransformationAction(Act);
102+
break;
103+
case FrontendOptions::ARCMT_ModifyInMemory:
104+
Act = new arcmt::InMemoryTransformationAction(Act);
105+
break;
106+
}
107+
92108
// If there are any AST files to merge, create a frontend action
93109
// adaptor to perform the merge.
94110
if (!CI.getFrontendOpts().ASTMergeFiles.empty())

0 commit comments

Comments
 (0)