Index: lib/ASTMatchers/ASTMatchFinder.cpp =================================================================== --- lib/ASTMatchers/ASTMatchFinder.cpp +++ lib/ASTMatchers/ASTMatchFinder.cpp @@ -311,31 +311,26 @@ public ASTMatchFinder { public: MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, - const MatchFinder::MatchFinderOptions &Options) - : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} - - ~MatchASTVisitor() override { - if (Options.CheckProfiling) { - Options.CheckProfiling->Records = std::move(TimeByBucket); - } + MatchFinder::MatchFinderOptions &Options) + : Matchers(Matchers), ActiveASTContext(nullptr) { + if (Options.CheckProfiling.hasValue()) + TimeByBucket = &(Options.CheckProfiling->Records); } void onStartOfTranslationUnit() { - const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); TimeBucketRegion Timer; for (MatchCallback *MC : Matchers->AllCallbacks) { - if (EnableCheckProfiling) - Timer.setBucket(&TimeByBucket[MC->getID()]); + if (TimeByBucket) + Timer.setBucket(&(*TimeByBucket)[MC->getID()]); MC->onStartOfTranslationUnit(); } } void onEndOfTranslationUnit() { - const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); TimeBucketRegion Timer; for (MatchCallback *MC : Matchers->AllCallbacks) { - if (EnableCheckProfiling) - Timer.setBucket(&TimeByBucket[MC->getID()]); + if (TimeByBucket) + Timer.setBucket(&(*TimeByBucket)[MC->getID()]); MC->onEndOfTranslationUnit(); } } @@ -539,11 +534,10 @@ /// Used by \c matchDispatch() below. template void matchWithoutFilter(const T &Node, const MC &Matchers) { - const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); TimeBucketRegion Timer; for (const auto &MP : Matchers) { - if (EnableCheckProfiling) - Timer.setBucket(&TimeByBucket[MP.second->getID()]); + if (TimeByBucket) + Timer.setBucket(&(*TimeByBucket)[MP.second->getID()]); BoundNodesTreeBuilder Builder; if (MP.first.matches(Node, this, &Builder)) { MatchVisitor Visitor(ActiveASTContext, MP.second); @@ -561,13 +555,12 @@ if (Filter.empty()) return; - const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); TimeBucketRegion Timer; auto &Matchers = this->Matchers->DeclOrStmt; for (unsigned short I : Filter) { auto &MP = Matchers[I]; - if (EnableCheckProfiling) - Timer.setBucket(&TimeByBucket[MP.second->getID()]); + if (TimeByBucket) + Timer.setBucket(&(*TimeByBucket)[MP.second->getID()]); BoundNodesTreeBuilder Builder; if (MP.first.matchesNoKindCheck(DynNode, this, &Builder)) { MatchVisitor Visitor(ActiveASTContext, MP.second); @@ -755,7 +748,7 @@ /// \brief Bucket to record map. /// /// Used to get the appropriate bucket for each matcher. - llvm::StringMap TimeByBucket; + llvm::StringMap *TimeByBucket = nullptr; const MatchFinder::MatchersByType *Matchers; @@ -770,7 +763,6 @@ llvm::DenseMap> MatcherFiltersMap; - const MatchFinder::MatchFinderOptions &Options; ASTContext *ActiveASTContext; // Maps a canonical type to its TypedefDecls. Index: unittests/ASTMatchers/ASTMatchersInternalTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersInternalTest.cpp +++ unittests/ASTMatchers/ASTMatchersInternalTest.cpp @@ -119,6 +119,46 @@ EXPECT_EQ("MyID", Records.begin()->getKey()); } +TEST(MatchFinder, CheckProfilingTwoTU) { + llvm::StringMap Records; + + MatchFinder::MatchFinderOptions Options0; + Options0.CheckProfiling.emplace(Records); + MatchFinder Finder0(std::move(Options0)); + + struct NamedCallback0 : public MatchFinder::MatchCallback { + void run(const MatchFinder::MatchResult &Result) override {} + StringRef getID() const override { return "MyID0"; } + } Callback0; + Finder0.addMatcher(decl(), &Callback0); + std::unique_ptr Factory0( + newFrontendActionFactory(&Finder0)); + + MatchFinder::MatchFinderOptions Options1; + Options1.CheckProfiling.emplace(Records); // **before** using the first one. + MatchFinder Finder1(std::move(Options1)); + + struct NamedCallback1 : public MatchFinder::MatchCallback { + void run(const MatchFinder::MatchResult &Result) override {} + StringRef getID() const override { return "MyID1"; } + } Callback1; + Finder1.addMatcher(decl(), &Callback1); + std::unique_ptr Factory1( + newFrontendActionFactory(&Finder1)); + + ASSERT_TRUE(tooling::runToolOnCode(Factory0->create(), "int x;")); + + EXPECT_EQ(1u, Records.size()); + EXPECT_EQ("MyID0", Records.begin()->getKey()); + EXPECT_NE(Records.find("MyID0"), Records.end()); + + ASSERT_TRUE(tooling::runToolOnCode(Factory1->create(), "int x;")); + + EXPECT_EQ(2u, Records.size()); + EXPECT_NE(Records.find("MyID0"), Records.end()); + EXPECT_NE(Records.find("MyID1"), Records.end()); +} + class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback { public: VerifyStartOfTranslationUnit() : Called(false) {}