@@ -15,6 +15,7 @@ SmallVector<char> GetUSR(const FunctionDecl *FD) {
1515
1616class CallCollector : public ast_matchers ::MatchFinder::MatchCallback {
1717 std::set<SmallVector<char >> Calls;
18+ bool callsOpaqueSymbol = false ;
1819
1920 virtual void
2021 run (const ast_matchers::MatchFinder::MatchResult &Result) override {
@@ -23,28 +24,40 @@ class CallCollector : public ast_matchers::MatchFinder::MatchCallback {
2324 return ;
2425
2526 const auto *Callee = llvm::dyn_cast<FunctionDecl>(Call->getCalleeDecl ());
27+ if (!Callee) {
28+ callsOpaqueSymbol = true ;
29+ return ;
30+ }
31+
32+ if (const auto *MD = llvm::dyn_cast<CXXMethodDecl>(Callee);
33+ MD && MD->isVirtual ()) {
34+ callsOpaqueSymbol = true ;
35+ return ;
36+ }
37+
2638 Calls.emplace (GetUSR (Callee));
2739 }
2840
2941public:
30- std::set<SmallVector<char >> collect (const FunctionDecl *FD) {
42+ std::pair<std:: set<SmallVector<char >>, bool > collect (const FunctionDecl *FD) {
3143 using namespace ast_matchers ;
3244 MatchFinder Finder;
3345
3446 Finder.addMatcher (functionDecl (forEachDescendant (callExpr ().bind (" call" ))),
3547 this );
3648 Finder.match (*FD, FD->getASTContext ());
3749
38- return Calls;
50+ return { Calls, callsOpaqueSymbol} ;
3951 }
4052};
4153} // namespace
4254
4355FunctionSummary::FunctionSummary (SmallVector<char > ID,
4456 std::set<const SummaryAttr *> FunctionAttrs,
45- std::set<SmallVector<char >> Calls)
57+ std::set<SmallVector<char >> Calls,
58+ bool CallsOpaque)
4659 : ID(std::move(ID)), Attrs(std::move(FunctionAttrs)),
47- Calls (std::move(Calls)) {}
60+ Calls (std::move(Calls)), CallsOpaque(CallsOpaque) {}
4861
4962template <typename T> void SummaryContext::registerAttr () {
5063 std::unique_ptr<T> attr (new T ());
@@ -60,9 +73,10 @@ SummaryContext::SummaryContext() { registerAttr<NoWriteGlobalAttr>(); }
6073
6174void SummaryContext::CreateSummary (SmallVector<char > ID,
6275 std::set<const SummaryAttr *> Attrs,
63- std::set<SmallVector<char >> Calls) {
76+ std::set<SmallVector<char >> Calls,
77+ bool CallsOpaque) {
6478 auto Summary = std::make_unique<FunctionSummary>(
65- std::move (ID), std::move (Attrs), std::move (Calls));
79+ std::move (ID), std::move (Attrs), std::move (Calls), CallsOpaque );
6680 auto *SummaryPtr = FunctionSummaries.emplace_back (std::move (Summary)).get ();
6781 IDToSummary[SummaryPtr->getID ()] = SummaryPtr;
6882}
@@ -81,7 +95,9 @@ void SummaryContext::SummarizeFunctionBody(const FunctionDecl *FD) {
8195 Attrs.emplace (Attr.get ());
8296 }
8397
84- CreateSummary (GetUSR (FD), std::move (Attrs), CallCollector ().collect (FD));
98+ auto [calls, opaque] = CallCollector ().collect (FD);
99+
100+ CreateSummary (GetUSR (FD), std::move (Attrs), std::move (calls), opaque);
85101}
86102
87103void SummaryContext::ParseSummaryFromJSON (const llvm::json::Array &Summary) {
@@ -101,14 +117,18 @@ void SummaryContext::ParseSummaryFromJSON(const llvm::json::Array &Summary) {
101117 }
102118
103119 std::set<SmallVector<char >> Calls;
104- const llvm::json::Array *CallEntries = FunctionSummary->getArray (" calls" );
120+ const llvm::json::Object *CallsObject = FunctionSummary->getObject (" calls" );
121+ bool callsOpaue = *CallsObject->getBoolean (" opaque" );
122+
123+ const llvm::json::Array *CallEntries = CallsObject->getArray (" functions" );
105124 for (auto callIt = CallEntries->begin (); callIt != CallEntries->end ();
106125 ++callIt) {
107126 auto *Obj = callIt->getAsObject ();
108127 Calls.emplace (SmallString<128 >(*Obj->getString (" id" )));
109128 }
110129
111- CreateSummary (std::move (ID), std::move (FunctionAttrs), std::move (Calls));
130+ CreateSummary (std::move (ID), std::move (FunctionAttrs), std::move (Calls),
131+ callsOpaue);
112132 }
113133}
114134
@@ -118,17 +138,10 @@ bool SummaryContext::ReduceFunctionSummary(FunctionSummary &Function) {
118138 for (auto &&call : Function.getCalls ()) {
119139 std::set<const SummaryAttr *> reducedAttrs;
120140
121- // If we don't have a summary about a called function, we forget
122- // everything about the current one as well.
123- if (!IDToSummary.count (call)) {
124- Function.replaceAttributes (std::move (reducedAttrs));
125- return true ;
126- }
127-
128- const FunctionSummary *callSummary = IDToSummary[call];
129-
141+ const FunctionSummary *callSummary =
142+ IDToSummary.count (call) ? IDToSummary[call] : nullptr ;
130143 for (auto &&Attr : Attributes) {
131- if (Attr->merge (Function, * callSummary))
144+ if (Attr->merge (Function, callSummary))
132145 reducedAttrs.emplace (Attr.get ());
133146 }
134147
0 commit comments