summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-modernize/LoopConvert
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-09-26 19:10:04 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-09-26 19:10:04 +0000
commite228d1070909d55a253640a0c50046a969f0bff2 (patch)
tree434f2242fda5e7e6a14a39b6c2b50005e1b3e444 /clang-tools-extra/clang-modernize/LoopConvert
parentb1a63bdf55b03f0252a8e46c08eb338d821a96cb (diff)
downloadbcm5719-llvm-e228d1070909d55a253640a0c50046a969f0bff2.tar.gz
bcm5719-llvm-e228d1070909d55a253640a0c50046a969f0bff2.zip
clang-modernize: Reset LoopConvert's TU tracking info per TU
The LoopConvert transform makes use of data structures it builds up over the course of transforming a TU. Until now, these data structures weren't being cleared out before the next TU was being processed. Fixes PR17253. Differential Revision: http://llvm-reviews.chandlerc.com/D175 llvm-svn: 191448
Diffstat (limited to 'clang-tools-extra/clang-modernize/LoopConvert')
-rw-r--r--clang-tools-extra/clang-modernize/LoopConvert/LoopActions.cpp19
-rw-r--r--clang-tools-extra/clang-modernize/LoopConvert/LoopActions.h72
-rw-r--r--clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.cpp25
-rw-r--r--clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.h8
4 files changed, 74 insertions, 50 deletions
diff --git a/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.cpp b/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.cpp
index 4dab6aba75f..dad3cbf3152 100644
--- a/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.cpp
+++ b/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.cpp
@@ -821,7 +821,8 @@ void LoopFixer::doConversion(ASTContext *Context,
// No further replacements are made to the loop, since the iterator or index
// was used exactly once - in the initialization of AliasVar.
} else {
- VariableNamer Namer(GeneratedDecls, &ParentFinder->getStmtToParentStmtMap(),
+ VariableNamer Namer(&TUInfo.getGeneratedDecls(),
+ &TUInfo.getParentFinder().getStmtToParentStmtMap(),
TheLoop, IndexVar, MaybeContainer, Context);
VarName = Namer.createIndexName();
// First, replace all usages of the array subscript expression with our new
@@ -829,7 +830,7 @@ void LoopFixer::doConversion(ASTContext *Context,
for (UsageResult::const_iterator I = Usages.begin(), E = Usages.end();
I != E; ++I) {
std::string ReplaceText = I->IsArrow ? VarName + "." : VarName;
- ReplacedVarRanges->insert(std::make_pair(TheLoop, IndexVar));
+ TUInfo.getReplacedVars().insert(std::make_pair(TheLoop, IndexVar));
Owner.addReplacementForCurrentTU(
Replacement(Context->getSourceManager(),
CharSourceRange::getTokenRange(I->Range), ReplaceText));
@@ -864,7 +865,7 @@ void LoopFixer::doConversion(ASTContext *Context,
Owner.addReplacementForCurrentTU(
Replacement(Context->getSourceManager(),
CharSourceRange::getTokenRange(ParenRange), Range));
- GeneratedDecls->insert(make_pair(TheLoop, VarName));
+ TUInfo.getGeneratedDecls().insert(make_pair(TheLoop, VarName));
}
/// \brief Determine whether Init appears to be an initializing an iterator.
@@ -933,18 +934,18 @@ StringRef LoopFixer::checkDeferralsAndRejections(ASTContext *Context,
// updates on this iteration.
// FIXME: Once Replacements can detect conflicting edits, replace this
// implementation and rely on conflicting edit detection instead.
- if (ReplacedVarRanges->count(TheLoop)) {
+ if (TUInfo.getReplacedVars().count(TheLoop)) {
++*DeferredChanges;
return "";
}
- ParentFinder->gatherAncestors(Context->getTranslationUnitDecl());
+ TUInfo.getParentFinder().gatherAncestors(Context->getTranslationUnitDecl());
// Ensure that we do not try to move an expression dependent on a local
// variable declared inside the loop outside of it!
- DependencyFinderASTVisitor
- DependencyFinder(&ParentFinder->getStmtToParentStmtMap(),
- &ParentFinder->getDeclToParentStmtMap(),
- ReplacedVarRanges, TheLoop);
+ DependencyFinderASTVisitor DependencyFinder(
+ &TUInfo.getParentFinder().getStmtToParentStmtMap(),
+ &TUInfo.getParentFinder().getDeclToParentStmtMap(),
+ &TUInfo.getReplacedVars(), TheLoop);
// Not all of these are actually deferred changes.
// FIXME: Determine when the external dependency isn't an expression converted
diff --git a/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.h b/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.h
index f70f5736f0c..db37561fb9e 100644
--- a/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.h
+++ b/clang-tools-extra/clang-modernize/LoopConvert/LoopActions.h
@@ -34,30 +34,47 @@ enum LoopFixerKind {
LFK_PseudoArray
};
+struct TUTrackingInfo {
+
+ /// \brief Reset and initialize per-TU tracking information.
+ ///
+ /// Must be called before using container accessors.
+ void reset() {
+ ParentFinder.reset(new StmtAncestorASTVisitor);
+ GeneratedDecls.clear();
+ ReplacedVars.clear();
+ }
+
+ /// \name Accessors
+ /// \{
+ StmtAncestorASTVisitor &getParentFinder() { return *ParentFinder; }
+ StmtGeneratedVarNameMap &getGeneratedDecls() { return GeneratedDecls; }
+ ReplacedVarsMap &getReplacedVars() { return ReplacedVars; }
+ /// \}
+
+private:
+ llvm::OwningPtr<StmtAncestorASTVisitor> ParentFinder;
+ StmtGeneratedVarNameMap GeneratedDecls;
+ ReplacedVarsMap ReplacedVars;
+};
+
/// \brief The callback to be used for loop migration matchers.
///
/// The callback does extra checking not possible in matchers, and attempts to
/// convert the for loop, if possible.
class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
- public:
- LoopFixer(StmtAncestorASTVisitor *ParentFinder,
- StmtGeneratedVarNameMap *GeneratedDecls,
- ReplacedVarsMap *ReplacedVarRanges, unsigned *AcceptedChanges,
- unsigned *DeferredChanges, unsigned *RejectedChanges,
- RiskLevel MaxRisk, LoopFixerKind FixerKind, Transform &Owner)
- : ParentFinder(ParentFinder),
- GeneratedDecls(GeneratedDecls), ReplacedVarRanges(ReplacedVarRanges),
- AcceptedChanges(AcceptedChanges), DeferredChanges(DeferredChanges),
- RejectedChanges(RejectedChanges), MaxRisk(MaxRisk),
- FixerKind(FixerKind), Owner(Owner) {}
+public:
+ LoopFixer(TUTrackingInfo &TUInfo, unsigned *AcceptedChanges,
+ unsigned *DeferredChanges, unsigned *RejectedChanges,
+ RiskLevel MaxRisk, LoopFixerKind FixerKind, Transform &Owner)
+ : TUInfo(TUInfo), AcceptedChanges(AcceptedChanges),
+ DeferredChanges(DeferredChanges), RejectedChanges(RejectedChanges),
+ MaxRisk(MaxRisk), FixerKind(FixerKind), Owner(Owner) {}
- virtual void
- run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
+ virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
- private:
- StmtAncestorASTVisitor *ParentFinder;
- StmtGeneratedVarNameMap *GeneratedDecls;
- ReplacedVarsMap *ReplacedVarRanges;
+private:
+ TUTrackingInfo &TUInfo;
unsigned *AcceptedChanges;
unsigned *DeferredChanges;
unsigned *RejectedChanges;
@@ -67,17 +84,12 @@ class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
/// \brief Computes the changes needed to convert a given for loop, and
/// applies it.
- void doConversion(clang::ASTContext *Context,
- const clang::VarDecl *IndexVar,
+ void doConversion(clang::ASTContext *Context, const clang::VarDecl *IndexVar,
const clang::VarDecl *MaybeContainer,
- llvm::StringRef ContainerString,
- const UsageResult &Usages,
- const clang::DeclStmt *AliasDecl,
- bool AliasUseRequired,
- bool AliasFromForInit,
- const clang::ForStmt *TheLoop,
- bool ContainerNeedsDereference,
- bool DerefByValue,
+ llvm::StringRef ContainerString, const UsageResult &Usages,
+ const clang::DeclStmt *AliasDecl, bool AliasUseRequired,
+ bool AliasFromForInit, const clang::ForStmt *TheLoop,
+ bool ContainerNeedsDereference, bool DerefByValue,
bool DerefByConstRef);
/// \brief Given a loop header that would be convertible, discover all usages
@@ -87,10 +99,8 @@ class LoopFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
const clang::VarDecl *EndVar,
const clang::Expr *ContainerExpr,
const clang::Expr *BoundExpr,
- bool ContainerNeedsDereference,
- bool DerefByValue,
- bool DerefByConstRef,
- const clang::ForStmt *TheLoop,
+ bool ContainerNeedsDereference, bool DerefByValue,
+ bool DerefByConstRef, const clang::ForStmt *TheLoop,
Confidence ConfidenceLevel);
/// \brief Determine if the change should be deferred or rejected, returning
diff --git a/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.cpp b/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.cpp
index 2dfa4562929..e41d758c50b 100644
--- a/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.cpp
+++ b/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.cpp
@@ -29,26 +29,22 @@ int LoopConvertTransform::apply(const FileOverrides &InputStates,
const std::vector<std::string> &SourcePaths) {
ClangTool LoopTool(Database, SourcePaths);
- StmtAncestorASTVisitor ParentFinder;
- StmtGeneratedVarNameMap GeneratedDecls;
- ReplacedVarsMap ReplacedVars;
unsigned AcceptedChanges = 0;
unsigned DeferredChanges = 0;
unsigned RejectedChanges = 0;
+ TUInfo.reset(new TUTrackingInfo);
+
MatchFinder Finder;
- LoopFixer ArrayLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
- &AcceptedChanges, &DeferredChanges, &RejectedChanges,
- Options().MaxRiskLevel, LFK_Array,
+ LoopFixer ArrayLoopFixer(*TUInfo, &AcceptedChanges, &DeferredChanges,
+ &RejectedChanges, Options().MaxRiskLevel, LFK_Array,
/*Owner=*/ *this);
Finder.addMatcher(makeArrayLoopMatcher(), &ArrayLoopFixer);
- LoopFixer IteratorLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
- &AcceptedChanges, &DeferredChanges,
+ LoopFixer IteratorLoopFixer(*TUInfo, &AcceptedChanges, &DeferredChanges,
&RejectedChanges, Options().MaxRiskLevel,
LFK_Iterator, /*Owner=*/ *this);
Finder.addMatcher(makeIteratorLoopMatcher(), &IteratorLoopFixer);
- LoopFixer PseudoarrrayLoopFixer(&ParentFinder, &GeneratedDecls, &ReplacedVars,
- &AcceptedChanges, &DeferredChanges,
+ LoopFixer PseudoarrrayLoopFixer(*TUInfo, &AcceptedChanges, &DeferredChanges,
&RejectedChanges, Options().MaxRiskLevel,
LFK_PseudoArray, /*Owner=*/ *this);
Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
@@ -67,6 +63,15 @@ int LoopConvertTransform::apply(const FileOverrides &InputStates,
return 0;
}
+bool
+LoopConvertTransform::handleBeginSource(clang::CompilerInstance &CI,
+ llvm::StringRef Filename) {
+ // Reset and initialize per-TU tracking structures.
+ TUInfo->reset();
+
+ return Transform::handleBeginSource(CI, Filename);
+}
+
struct LoopConvertFactory : TransformFactory {
LoopConvertFactory() {
Since.Clang = Version(3, 0);
diff --git a/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.h b/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.h
index 5b0366b7cb0..74452795448 100644
--- a/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.h
+++ b/clang-tools-extra/clang-modernize/LoopConvert/LoopConvert.h
@@ -20,6 +20,9 @@
#include "Core/Transform.h"
#include "llvm/Support/Compiler.h" // For LLVM_OVERRIDE
+// Forward decl for private implementation.
+struct TUTrackingInfo;
+
/// \brief Subclass of Transform that transforms for-loops into range-based
/// for-loops where possible.
class LoopConvertTransform : public Transform {
@@ -31,6 +34,11 @@ public:
virtual int apply(const FileOverrides &InputStates,
const clang::tooling::CompilationDatabase &Database,
const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
+
+ virtual bool handleBeginSource(clang::CompilerInstance &CI,
+ llvm::StringRef Filename) LLVM_OVERRIDE;
+private:
+ llvm::OwningPtr<TUTrackingInfo> TUInfo;
};
#endif // CLANG_MODERNIZE_LOOP_CONVERT_H
OpenPOWER on IntegriCloud