diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2019-08-20 02:22:37 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2019-08-20 02:22:37 +0000 |
commit | 8cf3dfea54187769b9c3feeb032f084857e8c79c (patch) | |
tree | 2f8a88ea9f55c6612e3b0df1e7067de8c71fe68e /clang/lib/Analysis/CallGraph.cpp | |
parent | ee92f12fd18e42dd417174bcbb6429da60f47afa (diff) | |
download | bcm5719-llvm-8cf3dfea54187769b9c3feeb032f084857e8c79c.tar.gz bcm5719-llvm-8cf3dfea54187769b9c3feeb032f084857e8c79c.zip |
[CallGraph] Take into accound calls that aren't within any function bodies.
This patch improves Clang call graph analysis by adding in expressions
that are not found in regular function bodies, such as default arguments
or member initializers.
Patch by Joshua Cranmer!
Differential Revision: https://reviews.llvm.org/D65453
llvm-svn: 369321
Diffstat (limited to 'clang/lib/Analysis/CallGraph.cpp')
-rw-r--r-- | clang/lib/Analysis/CallGraph.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/clang/lib/Analysis/CallGraph.cpp b/clang/lib/Analysis/CallGraph.cpp index 71219161d05..865840eb341 100644 --- a/clang/lib/Analysis/CallGraph.cpp +++ b/clang/lib/Analysis/CallGraph.cpp @@ -79,6 +79,34 @@ public: VisitChildren(CE); } + void VisitLambdaExpr(LambdaExpr *LE) { + if (CXXMethodDecl *MD = LE->getCallOperator()) + G->VisitFunctionDecl(MD); + } + + void VisitCXXNewExpr(CXXNewExpr *E) { + if (FunctionDecl *FD = E->getOperatorNew()) + addCalledDecl(FD); + VisitChildren(E); + } + + void VisitCXXConstructExpr(CXXConstructExpr *E) { + CXXConstructorDecl *Ctor = E->getConstructor(); + if (FunctionDecl *Def = Ctor->getDefinition()) + addCalledDecl(Def); + VisitChildren(E); + } + + // Include the evaluation of the default argument. + void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { + Visit(E->getExpr()); + } + + // Include the evaluation of the default initializers in a class. + void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { + Visit(E->getExpr()); + } + // Adds may-call edges for the ObjC message sends. void VisitObjCMessageExpr(ObjCMessageExpr *ME) { if (ObjCInterfaceDecl *IDecl = ME->getReceiverInterface()) { @@ -143,13 +171,20 @@ bool CallGraph::includeInGraph(const Decl *D) { void CallGraph::addNodeForDecl(Decl* D, bool IsGlobal) { assert(D); - // Allocate a new node, mark it as root, and process it's calls. + // Allocate a new node, mark it as root, and process its calls. CallGraphNode *Node = getOrInsertNode(D); // Process all the calls by this function as well. CGBuilder builder(this, Node); if (Stmt *Body = D->getBody()) builder.Visit(Body); + + // Include C++ constructor member initializers. + if (auto constructor = dyn_cast<CXXConstructorDecl>(D)) { + for (CXXCtorInitializer *init : constructor->inits()) { + builder.Visit(init->getInit()); + } + } } CallGraphNode *CallGraph::getNode(const Decl *F) const { |