From d7432dfb0a01759e97840b8bbfb686eef2638bbd Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Mon, 12 Oct 2009 19:41:04 +0000 Subject: Factor out devirtualization checking into a separate function and make it handle references correctly. llvm-svn: 83880 --- clang/lib/CodeGen/CGCXX.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'clang/lib/CodeGen/CGCXX.cpp') diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index af499427387..0744b79d45d 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -198,6 +198,20 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD, Callee, Args, MD); } +/// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given +/// expr can be devirtualized. +static bool canDevirtualizeMemberFunctionCalls(const Expr *Base) { + if (const DeclRefExpr *DRE = dyn_cast(Base)) { + if (const VarDecl *VD = dyn_cast(DRE->getDecl())) { + // This is a record decl. We know the type and can devirtualize it. + return VD->getType()->isRecordType(); + } + } + + // We can't devirtualize the call. + return false; +} + RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { if (isa(CE->getCallee())) return EmitCXXMemberPointerCallExpr(CE); @@ -235,7 +249,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { // because then we know what the type is. llvm::Value *Callee; if (MD->isVirtual() && !ME->hasQualifier() && - !ME->getBase()->getType()->isRecordType()) + !canDevirtualizeMemberFunctionCalls(ME->getBase())) Callee = BuildVirtualCall(MD, This, Ty); else if (const CXXDestructorDecl *Destructor = dyn_cast(MD)) -- cgit v1.2.3