summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-06-18 15:44:58 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-06-18 15:44:58 +0000
commitba6b32d1ce34dacaca5df11dfb5e460b1445914a (patch)
tree25b663f04bcef53af13f02efa948e48f296ae65a /clang-tools-extra
parent75d8fa51c9894df24e224b61c8b1f2cfbf6fc89d (diff)
downloadbcm5719-llvm-ba6b32d1ce34dacaca5df11dfb5e460b1445914a.tar.gz
bcm5719-llvm-ba6b32d1ce34dacaca5df11dfb5e460b1445914a.zip
cpp11-migrate: Transforms honour header modification flag
Transforms will now make changes to headers if header modifications have been enabled. FIXME: Only UseNullptr contains a cursory header modification test. Other transforms should have them too. llvm-svn: 184197
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp4
-rw-r--r--clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp4
-rw-r--r--clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h9
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Transform.cpp15
-rw-r--r--clang-tools-extra/cpp11-migrate/Core/Transform.h5
-rw-r--r--clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp2
-rw-r--r--clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h29
-rw-r--r--clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp13
-rw-r--r--clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp4
-rw-r--r--clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp4
-rw-r--r--clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h12
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp21
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h6
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp5
-rw-r--r--clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp3
-rw-r--r--clang-tools-extra/test/cpp11-migrate/UseNullptr/Inputs/basic.h1
-rw-r--r--clang-tools-extra/test/cpp11-migrate/UseNullptr/basic.cpp11
-rw-r--r--clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp116
18 files changed, 206 insertions, 58 deletions
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp
index f9a3a512675..1b77e128406 100644
--- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp
+++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp
@@ -40,7 +40,9 @@ int AddOverrideTransform::apply(FileOverrides &InputStates,
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- AddOverrideFixer Fixer(getReplacements(), AcceptedChanges, DetectMacros);
+
+ AddOverrideFixer Fixer(getReplacements(), AcceptedChanges, DetectMacros,
+ /*Owner=*/ *this);
Finder.addMatcher(makeCandidateForOverrideAttrMatcher(), &Fixer);
// Make Fixer available to handleBeginSource().
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp
index 008e947410e..6407b86b9db 100644
--- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp
@@ -15,6 +15,7 @@
#include "AddOverrideActions.h"
#include "AddOverrideMatchers.h"
+#include "Core/Transform.h"
#include "clang/Basic/CharInfo.h"
#include "clang/AST/ASTContext.h"
@@ -61,8 +62,7 @@ void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) {
if (const FunctionDecl *TemplateMethod = M->getTemplateInstantiationPattern())
M = cast<CXXMethodDecl>(TemplateMethod);
- // Check that the method declaration is in the main file
- if (!SM.isFromMainFile(M->getLocStart()))
+ if (!Owner.isFileModifiable(SM, M->getLocStart()))
return;
// First check that there isn't already an override attribute.
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h
index 831344344a1..1d125ebb7e1 100644
--- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h
+++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h
@@ -15,18 +15,20 @@
#ifndef LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_ADD_OVERRIDE_ACTIONS_H
#define LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_ADD_OVERRIDE_ACTIONS_H
-#include "Core/Transform.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Tooling/Refactoring.h"
+class Transform;
+
/// \brief The callback to be used for add-override migration matchers.
///
class AddOverrideFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
AddOverrideFixer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, bool DetectMacros)
+ unsigned &AcceptedChanges, bool DetectMacros,
+ const Transform &Owner)
: Replace(Replace), AcceptedChanges(AcceptedChanges),
- DetectMacros(DetectMacros) {}
+ DetectMacros(DetectMacros), Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
@@ -38,6 +40,7 @@ private:
clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
bool DetectMacros;
+ const Transform &Owner;
};
#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_ADD_OVERRIDE_ACTIONS_H
diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp
index 5fd73ad0380..7be91993bb8 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp
+++ b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp
@@ -156,6 +156,21 @@ Transform::Transform(llvm::StringRef Name, const TransformOptions &Options)
Transform::~Transform() {}
+bool Transform::isFileModifiable(const SourceManager &SM,
+ const SourceLocation &Loc) const {
+ if (SM.isFromMainFile(Loc))
+ return true;
+
+ if (!GlobalOptions.EnableHeaderModifications)
+ return false;
+
+ const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
+ if (!FE)
+ return false;
+
+ return GlobalOptions.ModifiableHeaders.isFileIncluded(FE->getName());
+}
+
bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
assert(Overrides != 0 && "Subclass transform didn't provide InputState");
diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h
index 651ee32e65f..1894d4464ce 100644
--- a/clang-tools-extra/cpp11-migrate/Core/Transform.h
+++ b/clang-tools-extra/cpp11-migrate/Core/Transform.h
@@ -131,6 +131,11 @@ public:
DeferredChanges = 0;
}
+ /// \brief Tests if the file containing \a Loc is allowed to be modified by
+ /// the Migrator.
+ bool isFileModifiable(const clang::SourceManager &SM,
+ const clang::SourceLocation &Loc) const;
+
/// \brief Called before parsing a translation unit for a FrontendAction.
///
/// Transform uses this function to apply file overrides and start
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp
index 88c219aefec..f25e7d89476 100644
--- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.cpp
@@ -1030,7 +1030,7 @@ void LoopFixer::run(const MatchFinder::MatchResult &Result) {
ASTContext *Context = Result.Context;
const ForStmt *TheLoop = Nodes.getStmtAs<ForStmt>(LoopName);
- if (!Context->getSourceManager().isFromMainFile(TheLoop->getForLoc()))
+ if (!Owner.isFileModifiable(Context->getSourceManager(),TheLoop->getForLoc()))
return;
// Check that we have exactly one index variable and at most one end variable.
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h
index eebee338208..542f1a8c4f0 100644
--- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h
+++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopActions.h
@@ -39,20 +39,20 @@ enum LoopFixerKind {
/// convert the for loop, if possible.
class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- LoopFixer(StmtAncestorASTVisitor *ParentFinder,
- clang::tooling::Replacements *Replace,
- StmtGeneratedVarNameMap *GeneratedDecls,
- ReplacedVarsMap *ReplacedVarRanges,
- unsigned *AcceptedChanges, unsigned *DeferredChanges,
- unsigned *RejectedChanges,
- RiskLevel MaxRisk,
- LoopFixerKind FixerKind) :
- ParentFinder(ParentFinder), Replace(Replace),
- GeneratedDecls(GeneratedDecls), ReplacedVarRanges(ReplacedVarRanges),
- AcceptedChanges(AcceptedChanges), DeferredChanges(DeferredChanges),
- RejectedChanges(RejectedChanges),
- MaxRisk(MaxRisk), FixerKind(FixerKind) { }
- virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
+ LoopFixer(StmtAncestorASTVisitor *ParentFinder,
+ clang::tooling::Replacements *Replace,
+ StmtGeneratedVarNameMap *GeneratedDecls,
+ ReplacedVarsMap *ReplacedVarRanges, unsigned *AcceptedChanges,
+ unsigned *DeferredChanges, unsigned *RejectedChanges,
+ RiskLevel MaxRisk, LoopFixerKind FixerKind, const Transform &Owner)
+ : ParentFinder(ParentFinder), Replace(Replace),
+ GeneratedDecls(GeneratedDecls), ReplacedVarRanges(ReplacedVarRanges),
+ AcceptedChanges(AcceptedChanges), DeferredChanges(DeferredChanges),
+ RejectedChanges(RejectedChanges), MaxRisk(MaxRisk),
+ FixerKind(FixerKind), Owner(Owner) {}
+
+ virtual void
+ run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
private:
StmtAncestorASTVisitor *ParentFinder;
@@ -64,6 +64,7 @@ class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
unsigned *RejectedChanges;
RiskLevel MaxRisk;
LoopFixerKind FixerKind;
+ const Transform &Owner;
/// \brief Computes the changes needed to convert a given for loop, and
/// applies it.
diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp
index 1ab526a90f7..858ee0623d2 100644
--- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp
+++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp
@@ -40,17 +40,18 @@ int LoopConvertTransform::apply(FileOverrides &InputStates,
MatchFinder Finder;
LoopFixer ArrayLoopFixer(&ParentFinder, &getReplacements(), &GeneratedDecls,
&ReplacedVars, &AcceptedChanges, &DeferredChanges,
- &RejectedChanges, Options().MaxRiskLevel, LFK_Array);
+ &RejectedChanges, Options().MaxRiskLevel, LFK_Array,
+ /*Owner=*/ *this);
Finder.addMatcher(makeArrayLoopMatcher(), &ArrayLoopFixer);
- LoopFixer IteratorLoopFixer(&ParentFinder, &getReplacements(),
- &GeneratedDecls, &ReplacedVars, &AcceptedChanges,
- &DeferredChanges, &RejectedChanges,
- Options().MaxRiskLevel, LFK_Iterator);
+ LoopFixer IteratorLoopFixer(
+ &ParentFinder, &getReplacements(), &GeneratedDecls, &ReplacedVars,
+ &AcceptedChanges, &DeferredChanges, &RejectedChanges,
+ Options().MaxRiskLevel, LFK_Iterator, /*Owner=*/ *this);
Finder.addMatcher(makeIteratorLoopMatcher(), &IteratorLoopFixer);
LoopFixer PseudoarrrayLoopFixer(
&ParentFinder, &getReplacements(), &GeneratedDecls, &ReplacedVars,
&AcceptedChanges, &DeferredChanges, &RejectedChanges,
- Options().MaxRiskLevel, LFK_PseudoArray);
+ Options().MaxRiskLevel, LFK_PseudoArray, /*Owner=*/ *this);
Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
setOverrides(InputStates);
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp
index 0a8d0d2e3a8..b85f54712a7 100644
--- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp
@@ -29,9 +29,9 @@ int UseAutoTransform::apply(FileOverrides &InputStates,
MatchFinder Finder;
IteratorReplacer ReplaceIterators(getReplacements(), AcceptedChanges,
- Options().MaxRiskLevel);
+ Options().MaxRiskLevel, /*Owner=*/ *this);
NewReplacer ReplaceNew(getReplacements(), AcceptedChanges,
- Options().MaxRiskLevel);
+ Options().MaxRiskLevel, /*Owner=*/ *this);
Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew);
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp
index 47050a7b84d..e20affa5e2b 100644
--- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp
@@ -25,7 +25,7 @@ void IteratorReplacer::run(const MatchFinder::MatchResult &Result) {
assert(D && "Bad Callback. No node provided");
SourceManager &SM = *Result.SourceManager;
- if (!SM.isFromMainFile(D->getLocStart()))
+ if (!Owner.isFileModifiable(SM, D->getLocStart()))
return;
for (clang::DeclStmt::const_decl_iterator DI = D->decl_begin(),
@@ -81,7 +81,7 @@ void NewReplacer::run(const MatchFinder::MatchResult &Result) {
assert(D && "Bad Callback. No node provided");
SourceManager &SM = *Result.SourceManager;
- if (!SM.isFromMainFile(D->getLocStart()))
+ if (!Owner.isFileModifiable(SM, D->getLocStart()))
return;
const VarDecl *FirstDecl = cast<VarDecl>(*D->decl_begin());
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h
index 31c41fb53ec..01170a68d23 100644
--- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h
+++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h
@@ -25,9 +25,8 @@ class IteratorReplacer
: public clang::ast_matchers::MatchFinder::MatchCallback {
public:
IteratorReplacer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, RiskLevel)
- : Replace(Replace), AcceptedChanges(AcceptedChanges) {
- }
+ unsigned &AcceptedChanges, RiskLevel, const Transform &Owner)
+ : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
@@ -36,6 +35,7 @@ public:
private:
clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
+ const Transform &Owner;
};
/// \brief The callback used when replacing type specifiers of variable
@@ -43,9 +43,8 @@ private:
class NewReplacer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
NewReplacer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
- RiskLevel)
- : Replace(Replace), AcceptedChanges(AcceptedChanges) {
- }
+ RiskLevel, const Transform &Owner)
+ : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {}
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
@@ -54,6 +53,7 @@ public:
private:
clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
+ const Transform &Owner;
};
#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_USE_AUTO_ACTIONS_H
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
index 38e44d21e23..6f476113367 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
@@ -37,8 +37,9 @@ static llvm::cl::opt<std::string> UserNullMacroNames(
llvm::cl::init(""));
bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc,
- const SourceManager &SM) {
- return SM.isFromSameFile(StartLoc, EndLoc) && SM.isFromMainFile(StartLoc);
+ const SourceManager &SM, const Transform &Owner) {
+ return SM.isFromSameFile(StartLoc, EndLoc) &&
+ Owner.isFileModifiable(SM, StartLoc);
}
/// \brief Replaces the provided range with the text "nullptr", but only if
@@ -152,10 +153,10 @@ class CastSequenceVisitor : public RecursiveASTVisitor<CastSequenceVisitor> {
public:
CastSequenceVisitor(tooling::Replacements &R, ASTContext &Context,
const UserMacroNames &UserNullMacros,
- unsigned &AcceptedChanges)
+ unsigned &AcceptedChanges, const Transform &Owner)
: Replace(R), SM(Context.getSourceManager()), Context(Context),
UserNullMacros(UserNullMacros), AcceptedChanges(AcceptedChanges),
- FirstSubExpr(0), PruneSubtree(false) {}
+ Owner(Owner), FirstSubExpr(0), PruneSubtree(false) {}
bool TraverseStmt(Stmt *S) {
// Stop traversing down the tree if requested.
@@ -191,7 +192,7 @@ public:
if (SM.isMacroArgExpansion(StartLoc) && SM.isMacroArgExpansion(EndLoc)) {
SourceLocation FileLocStart = SM.getFileLoc(StartLoc),
FileLocEnd = SM.getFileLoc(EndLoc);
- if (isReplaceableRange(FileLocStart, FileLocEnd, SM) &&
+ if (isReplaceableRange(FileLocStart, FileLocEnd, SM, Owner) &&
allArgUsesValid(C)) {
ReplaceWithNullptr(Replace, SM, FileLocStart, FileLocEnd);
++AcceptedChanges;
@@ -214,7 +215,7 @@ public:
EndLoc = SM.getFileLoc(EndLoc);
}
- if (!isReplaceableRange(StartLoc, EndLoc, SM)) {
+ if (!isReplaceableRange(StartLoc, EndLoc, SM, Owner)) {
return skipSubTree();
}
ReplaceWithNullptr(Replace, SM, StartLoc, EndLoc);
@@ -419,14 +420,16 @@ private:
ASTContext &Context;
const UserMacroNames &UserNullMacros;
unsigned &AcceptedChanges;
+ const Transform &Owner;
Expr *FirstSubExpr;
bool PruneSubtree;
};
} // namespace
NullptrFixer::NullptrFixer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges, RiskLevel)
- : Replace(Replace), AcceptedChanges(AcceptedChanges) {
+ unsigned &AcceptedChanges, RiskLevel,
+ const Transform &Owner)
+ : Replace(Replace), AcceptedChanges(AcceptedChanges), Owner(Owner) {
if (!UserNullMacroNames.empty()) {
llvm::StringRef S = UserNullMacroNames;
S.split(UserNullMacros, ",");
@@ -441,6 +444,6 @@ void NullptrFixer::run(const ast_matchers::MatchFinder::MatchResult &Result) {
// null-to-pointer cast within use CastSequenceVisitor to identify sequences
// of explicit casts that can be converted into 'nullptr'.
CastSequenceVisitor Visitor(Replace, *Result.Context, UserNullMacros,
- AcceptedChanges);
+ AcceptedChanges, Owner);
Visitor.TraverseStmt(const_cast<CastExpr *>(NullCast));
}
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h
index c0779f9fa7b..6e70ddadfb5 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.h
@@ -26,9 +26,8 @@ typedef llvm::SmallVector<llvm::StringRef, 1> UserMacroNames;
///
class NullptrFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
- NullptrFixer(clang::tooling::Replacements &Replace,
- unsigned &AcceptedChanges,
- RiskLevel);
+ NullptrFixer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
+ RiskLevel, const Transform &Owner);
/// \brief Entry point to the callback called when matches are made.
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
@@ -37,6 +36,7 @@ private:
clang::tooling::Replacements &Replace;
unsigned &AcceptedChanges;
UserMacroNames UserNullMacros;
+ const Transform &Owner;
};
#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_NULLPTR_ACTIONS_H
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp
index 75d3b00b639..759d3366188 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp
@@ -33,8 +33,9 @@ int UseNullptrTransform::apply(FileOverrides &InputStates,
unsigned AcceptedChanges = 0;
MatchFinder Finder;
- NullptrFixer Fixer(getReplacements(), AcceptedChanges,
- Options().MaxRiskLevel);
+ NullptrFixer Fixer(getReplacements(), AcceptedChanges, Options().MaxRiskLevel,
+ /*Owner=*/ *this);
+
Finder.addMatcher(makeCastSequenceMatcher(), &Fixer);
setOverrides(InputStates);
diff --git a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
index 773ba009a5d..f5b3818f7f0 100644
--- a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
+++ b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp
@@ -171,8 +171,6 @@ int main(int argc, const char **argv) {
E = FileStates.end();
I != E; ++I) {
if (I->second.isSourceOverriden()) {
- llvm::errs() << "Writing source: " << I->first << "\n";
-
std::string ErrorInfo;
llvm::raw_fd_ostream FileStream(I->first.c_str(), ErrorInfo,
llvm::raw_fd_ostream::F_Binary);
@@ -187,7 +185,6 @@ int main(int argc, const char **argv) {
for (HeaderOverrides::const_iterator HeaderI = I->second.Headers.begin(),
HeaderE = I->second.Headers.end();
HeaderI != HeaderE; ++HeaderI) {
- llvm::errs() << "Writing header: " << HeaderI->first << "\n";
assert(!HeaderI->second.FileOverride.empty() &&
"A header override should not be empty");
std::string ErrorInfo;
diff --git a/clang-tools-extra/test/cpp11-migrate/UseNullptr/Inputs/basic.h b/clang-tools-extra/test/cpp11-migrate/UseNullptr/Inputs/basic.h
index 68c5a032ccd..144db769c29 100644
--- a/clang-tools-extra/test/cpp11-migrate/UseNullptr/Inputs/basic.h
+++ b/clang-tools-extra/test/cpp11-migrate/UseNullptr/Inputs/basic.h
@@ -1,2 +1,3 @@
int *global_p = 0;
// CHECK: int *global_p = 0;
+// HEADERS: int *global_p = nullptr;
diff --git a/clang-tools-extra/test/cpp11-migrate/UseNullptr/basic.cpp b/clang-tools-extra/test/cpp11-migrate/UseNullptr/basic.cpp
index 03606f6acd3..9057c1a17d7 100644
--- a/clang-tools-extra/test/cpp11-migrate/UseNullptr/basic.cpp
+++ b/clang-tools-extra/test/cpp11-migrate/UseNullptr/basic.cpp
@@ -1,8 +1,13 @@
+// RUN: mkdir -p %T/Inputs
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic.h > %T/basic.h
-// RUN: cpp11-migrate -use-nullptr %t.cpp -- -std=c++98 -I %S
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic.h > %T/Inputs/basic.h
+// RUN: cpp11-migrate -use-nullptr %t.cpp -- -std=c++98 -I %T -Wno-non-literal-null-conversion
// RUN: FileCheck -input-file=%t.cpp %s
-// RUN: FileCheck -input-file=%T/basic.h %S/Inputs/basic.h
+// RUN: FileCheck -input-file=%T/Inputs/basic.h %S/Inputs/basic.h
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic.h > %T/Inputs/basic.h
+// RUN: cpp11-migrate -headers -include=%T -use-nullptr %t.cpp -- -std=c++98 -I %T -Wno-non-literal-null-conversion
+// RUN: FileCheck -check-prefix=HEADERS -input-file=%T/Inputs/basic.h %S/Inputs/basic.h
#include "Inputs/basic.h"
diff --git a/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp b/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp
index af8a7a703ac..ab0c7e3783a 100644
--- a/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp
+++ b/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp
@@ -2,12 +2,14 @@
#include "Core/Transform.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclGroup.h"
-#include "clang/Tooling/Tooling.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PathV1.h"
using namespace clang;
+using namespace ast_matchers;
class DummyTransform : public Transform {
public:
@@ -171,3 +173,115 @@ TEST(Transform, Timings) {
++I;
EXPECT_EQ(T.timing_end(), I);
}
+
+class ModifiableCallback
+ : public clang::ast_matchers::MatchFinder::MatchCallback {
+public:
+ ModifiableCallback(const Transform &Owner, bool HeadersModifiable)
+ : Owner(Owner), HeadersModifiable(HeadersModifiable) {}
+
+ virtual void
+ run(const clang::ast_matchers::MatchFinder::MatchResult &Result) {
+ const VarDecl *Decl = Result.Nodes.getNodeAs<VarDecl>("decl");
+ ASSERT_TRUE(Decl != 0);
+
+ const SourceManager &SM = *Result.SourceManager;
+
+ // Decl 'a' comes from the main source file. This test should always pass.
+ if (Decl->getName().equals("a"))
+ EXPECT_TRUE(Owner.isFileModifiable(SM, Decl->getLocStart()));
+
+ // Decl 'c' comes from an excluded header. This test should never pass.
+ else if (Decl->getName().equals("c"))
+ EXPECT_FALSE(Owner.isFileModifiable(SM, Decl->getLocStart()));
+
+ // Decl 'b' comes from an included header. It should be modifiable only if
+ // header modifications are allowed.
+ else if (Decl->getName().equals("b"))
+ EXPECT_EQ(HeadersModifiable,
+ Owner.isFileModifiable(SM, Decl->getLocStart()));
+
+ // Make sure edge cases are handled gracefully (they should never be
+ // allowed).
+ SourceLocation DummyLoc;
+ EXPECT_FALSE(Owner.isFileModifiable(SM, DummyLoc));
+ }
+
+private:
+ const Transform &Owner;
+ bool HeadersModifiable;
+};
+
+TEST(Transform, isFileModifiable) {
+ TransformOptions Options;
+
+ ///
+ /// SETUP
+ ///
+ /// To test Transform::isFileModifiable() we need a SourceManager primed with
+ /// actual files and SourceLocations to test. Easiest way to accomplish this
+ /// is to use Tooling classes.
+ ///
+ /// 1) Simulate a source file that includes two headers, one that is allowed
+ /// to be modified and the other that is not allowed. Each of the three
+ /// files involved will declare a single variable with a different name.
+ /// 2) A matcher is created to find VarDecls.
+ /// 3) A MatchFinder callback calls Transform::isFileModifiable() with the
+ /// SourceLocations of found VarDecls and thus tests the function.
+ ///
+
+ // All the path stuff is to make the test work independently of OS.
+
+ // The directory used is not important since the path gets mapped to a virtual
+ // file anyway. What is important is that we have an absolute path with which
+ // to use with mapVirtualFile().
+ llvm::sys::Path SourceFile = llvm::sys::Path::GetCurrentDirectory();
+ std::string CurrentDir = SourceFile.str();
+ SourceFile.appendComponent("a.cc");
+ std::string SourceFileName = SourceFile.str();
+
+ llvm::sys::Path HeaderFile = llvm::sys::Path::GetCurrentDirectory();
+ HeaderFile.appendComponent("a.h");
+ std::string HeaderFileName = HeaderFile.str();
+
+ llvm::sys::Path HeaderBFile = llvm::sys::Path::GetCurrentDirectory();
+ HeaderBFile.appendComponent("temp");
+ std::string ExcludeDir = HeaderBFile.str();
+ HeaderBFile.appendComponent("b.h");
+ std::string HeaderBFileName = HeaderBFile.str();
+
+ IncludeExcludeInfo IncInfo;
+ Options.ModifiableHeaders.readListFromString(CurrentDir, ExcludeDir);
+
+ tooling::FixedCompilationDatabase Compilations(CurrentDir, std::vector<std::string>());
+ std::vector<std::string> Sources;
+ Sources.push_back(SourceFileName);
+ tooling::ClangTool Tool(Compilations, Sources);
+
+ Tool.mapVirtualFile(SourceFileName,
+ "#include \"a.h\"\n"
+ "#include \"temp/b.h\"\n"
+ "int a;");
+ Tool.mapVirtualFile(HeaderFileName, "int b;");
+ Tool.mapVirtualFile(HeaderBFileName, "int c;");
+
+ // Run tests with header modifications turned off.
+ {
+ SCOPED_TRACE("Header Modifications are OFF");
+ Options.EnableHeaderModifications = false;
+ DummyTransform T("dummy", Options);
+ MatchFinder Finder;
+ Finder.addMatcher(varDecl().bind("decl"), new ModifiableCallback(T, false));
+ Tool.run(tooling::newFrontendActionFactory(&Finder));
+ }
+
+ // Run again with header modifications turned on.
+ {
+ SCOPED_TRACE("Header Modifications are ON");
+ Options.EnableHeaderModifications = true;
+ DummyTransform T("dummy", Options);
+ MatchFinder Finder;
+ Finder.addMatcher(varDecl().bind("decl"), new ModifiableCallback(T, true));
+ Tool.run(tooling::newFrontendActionFactory(&Finder));
+ }
+}
OpenPOWER on IntegriCloud