diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2017-07-13 06:08:27 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2017-07-13 06:08:27 +0000 |
commit | ed14d7adea8dda8882104c6dfac3b3d233fff64d (patch) | |
tree | 5d0be874d4abc6d111c20cb8bd16670202901259 /include | |
parent | 48dec96ecc02497042ad46c7371383db981b1482 (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.h | 13 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 2 |
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); |