diff options
author | Edwin Vane <edwin.vane@intel.com> | 2013-09-26 19:10:04 +0000 |
---|---|---|
committer | Edwin Vane <edwin.vane@intel.com> | 2013-09-26 19:10:04 +0000 |
commit | e228d1070909d55a253640a0c50046a969f0bff2 (patch) | |
tree | 434f2242fda5e7e6a14a39b6c2b50005e1b3e444 /clang-tools-extra/clang-modernize/LoopConvert | |
parent | b1a63bdf55b03f0252a8e46c08eb338d821a96cb (diff) | |
download | bcm5719-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')
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 |