diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-04-22 22:25:37 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-04-22 22:25:37 +0000 |
commit | 788440378c442562497c09610939cbe6218ab43d (patch) | |
tree | 52f680b7a10d2c59d34d5c5aebcd12320b8a049b /lib/Sema/Sema.cpp | |
parent | 8387e2a41eef6fa17fb140a18c29b6eee9dd2b8a (diff) |
At the end of the translation unit, defining a vtable can introduce
new templates that need to be instantiated and vice-versa. Iterate
until we've instantiated all required templates and defined all
required vtables. Fixed PR9325 / <rdar://problem/9055177>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130023 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/Sema.cpp')
-rw-r--r-- | lib/Sema/Sema.cpp | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index dc1270243d..c954c64e7d 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -373,22 +373,30 @@ void Sema::ActOnEndOfTranslationUnit() { } } - // If DefinedUsedVTables ends up marking any virtual member functions it - // might lead to more pending template instantiations, which we then need - // to instantiate. - DefineUsedVTables(); - - // C++: Perform implicit template instantiations. - // - // FIXME: When we perform these implicit instantiations, we do not - // carefully keep track of the point of instantiation (C++ [temp.point]). - // This means that name lookup that occurs within the template - // instantiation will always happen at the end of the translation unit, - // so it will find some names that should not be found. Although this is - // common behavior for C++ compilers, it is technically wrong. In the - // future, we either need to be able to filter the results of name lookup - // or we need to perform template instantiations earlier. - PerformPendingInstantiations(); + bool SomethingChanged; + do { + SomethingChanged = false; + + // If DefinedUsedVTables ends up marking any virtual member functions it + // might lead to more pending template instantiations, which we then need + // to instantiate. + if (DefineUsedVTables()) + SomethingChanged = true; + + // C++: Perform implicit template instantiations. + // + // FIXME: When we perform these implicit instantiations, we do not + // carefully keep track of the point of instantiation (C++ [temp.point]). + // This means that name lookup that occurs within the template + // instantiation will always happen at the end of the translation unit, + // so it will find some names that should not be found. Although this is + // common behavior for C++ compilers, it is technically wrong. In the + // future, we either need to be able to filter the results of name lookup + // or we need to perform template instantiations earlier. + if (PerformPendingInstantiations()) + SomethingChanged = true; + + } while (SomethingChanged); } // Remove file scoped decls that turned out to be used. |