summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2017-07-13 06:08:27 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2017-07-13 06:08:27 +0000
commited14d7adea8dda8882104c6dfac3b3d233fff64d (patch)
tree5d0be874d4abc6d111c20cb8bd16670202901259 /include
parent48dec96ecc02497042ad46c7371383db981b1482 (diff)
[Sema] Mark a virtual CXXMethodDecl as used if a call to it can be
devirtualized. The code to detect devirtualized calls is already in IRGen, so move the code to lib/AST and make it a shared utility between Sema and IRGen. This commit fixes a linkage error I was seeing when compiling the following code: $ cat test1.cpp struct Base { virtual void operator()() {} }; template<class T> struct Derived final : Base { void operator()() override {} }; Derived<int> *d; int main() { if (d) (*d)(); return 0; } rdar://problem/33195657 Differential Revision: https://reviews.llvm.org/D34301 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307883 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/DeclCXX.h13
-rw-r--r--include/clang/Sema/Sema.h2
2 files changed, 14 insertions, 1 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 6965e8143f..9d64f0244e 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1886,6 +1886,19 @@ public:
return (CD->begin_overridden_methods() != CD->end_overridden_methods());
}
+ /// If it's possible to devirtualize a call to this method, return the called
+ /// function. Otherwise, return null.
+
+ /// \param Base The object on which this virtual function is called.
+ /// \param IsAppleKext True if we are compiling for Apple kext.
+ CXXMethodDecl *getDevirtualizedMethod(const Expr *Base, bool IsAppleKext);
+
+ const CXXMethodDecl *getDevirtualizedMethod(const Expr *Base,
+ bool IsAppleKext) const {
+ return const_cast<CXXMethodDecl *>(this)->getDevirtualizedMethod(
+ Base, IsAppleKext);
+ }
+
/// \brief Determine whether this is a usual deallocation function
/// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
/// delete or delete[] operator with a particular signature.
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 31728a9f23..95629a2591 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3944,7 +3944,7 @@ public:
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
bool MightBeOdrUse = true);
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
- void MarkDeclRefReferenced(DeclRefExpr *E);
+ void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr);
void MarkMemberReferenced(MemberExpr *E);
void UpdateMarkingForLValueToRValue(Expr *E);