diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-06 04:44:19 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-06 04:44:19 +0000 |
commit | 159ef1ed9f024f73028aa3c9b27ae0717e43786c (patch) | |
tree | cc5d9f70e3b34f7a3d169586a5104b08fe013247 /lib/Sema/SemaDecl.cpp | |
parent | 8a8da7d17d4eb281b61d08d603c7bb180d280d5a (diff) |
Make our marking of virtual members functions in a class be
deterministic and work properly with templates. Once a class that
needs a vtable has been defined, we now do one if two things:
- If the class has no key function, we place the class on a list of
classes whose virtual functions will need to be "marked" at the
end of the translation unit. The delay until the end of the
translation unit is needed because we might see template
specializations of these virtual functions.
- If the class has a key function, we do nothing; when the key
function is defined, the class will be placed on the
aforementioned list.
At the end of the translation unit, we "mark" all of the virtual
functions of the classes on the list as used, possibly causing
template instantiation and other classes to be added to the
list. This gets LLVM's lib/Support/CommandLine.cpp compiling again.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92821 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 0fc61e3b58..383893cc2f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5098,6 +5098,16 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD, // Exit this scope of this tag's definition. PopDeclContext(); + // If this is a polymorphic C++ class without a key function, we'll + // have to mark all of the virtual members to allow emission of a vtable + // in this translation unit. + if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Tag)) { + if (!Record->isDependentContext() && Record->isDynamicClass() && + !Context.getKeyFunction(Record)) + ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(Record, + RBraceLoc)); + } + // Notify the consumer that we've defined a tag. Consumer.HandleTagDeclDefinition(Tag); } |