Skip to content

Commit 56970f9

Browse files
committed
[cxx-interop] Allow many specializations of a class template
An old piece of logic in ClangImporter was trying to limit the number of instantiations for each C++ class template to prevent long compile times. Unfortunately this started causing hard-to-reproduce deserialization errors on large projects which use many different instantiations of `std::vector` and `std::allocator`. The instantiation limit was arbitrary, it serves no real purpose and causes issues. This change removes it. rdar://158397914
1 parent 3ee222f commit 56970f9

File tree

3 files changed

+5
-2936
lines changed

3 files changed

+5
-2936
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3237,26 +3237,11 @@ namespace {
32373237

32383238
Decl *VisitClassTemplateSpecializationDecl(
32393239
const clang::ClassTemplateSpecializationDecl *decl) {
3240-
bool isPair = decl->getSpecializedTemplate()->isInStdNamespace() &&
3241-
decl->getSpecializedTemplate()->getName() == "pair";
3242-
3243-
// Before we go any further, check if we've already got tens of thousands
3244-
// of specializations. If so, it means we're likely instantiating a very
3245-
// deep/complex template, or we've run into an infinite loop. In either
3246-
// case, its not worth the compile time, so bail.
3247-
// TODO: this could be configurable at some point.
3248-
size_t specializationLimit = !isPair ? 1000 : 10000;
3249-
if (size_t(
3250-
llvm::size(decl->getSpecializedTemplate()->specializations())) >
3251-
specializationLimit) {
3252-
// Note: it would be nice to import a dummy unavailable struct,
3253-
// but we would then need to instantiate the template here,
3254-
// as we cannot import a struct without a definition. That would
3255-
// defeat the purpose. Also, we can't make the dummy
3256-
// struct simply unavailable, as that still makes the
3257-
// typelias that references it available.
3240+
// Importing std::conditional substantially increases compile times when
3241+
// building with libstdc++, i.e. on most Linux distros.
3242+
if (decl->isInStdNamespace() && decl->getIdentifier() &&
3243+
decl->getName() == "conditional")
32583244
return nullptr;
3259-
}
32603245

32613246
// `decl->getDefinition()` can return nullptr before the call to sema and
32623247
// return its definition afterwards.

0 commit comments

Comments
 (0)