diff options
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 96abeed824..af56ff06ac 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1,9 +1,8 @@ //===------- SemaTemplateInstantiate.cpp - C++ Template Instantiation ------===/ // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception //===----------------------------------------------------------------------===/ // // This file implements C++ template instantiation. @@ -26,6 +25,7 @@ #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/TemplateInstCallback.h" +#include "llvm/Support/TimeProfiler.h" using namespace clang; using namespace sema; @@ -66,9 +66,12 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D, if (!Ctx) { Ctx = D->getDeclContext(); - // Add template arguments from a variable template instantiation. - if (VarTemplateSpecializationDecl *Spec = - dyn_cast<VarTemplateSpecializationDecl>(D)) { + // Add template arguments from a variable template instantiation. For a + // class-scope explicit specialization, there are no template arguments + // at this level, but there may be enclosing template arguments. + VarTemplateSpecializationDecl *Spec = + dyn_cast<VarTemplateSpecializationDecl>(D); + if (Spec && !Spec->isClassScopeExplicitSpecialization()) { // We're done when we hit an explicit specialization. if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization && !isa<VarTemplatePartialSpecializationDecl>(Spec)) @@ -111,8 +114,9 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D, while (!Ctx->isFileContext()) { // Add template arguments from a class template instantiation. - if (ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) { + ClassTemplateSpecializationDecl *Spec + = dyn_cast<ClassTemplateSpecializationDecl>(Ctx); + if (Spec && !Spec->isClassScopeExplicitSpecialization()) { // We're done when we hit an explicit specialization. if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization && !isa<ClassTemplatePartialSpecializationDecl>(Spec)) @@ -129,9 +133,8 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D, // Add template arguments from a function template specialization. else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) { if (!RelativeToPrimary && - (Function->getTemplateSpecializationKind() == - TSK_ExplicitSpecialization && - !Function->getClassScopeSpecializationPattern())) + Function->getTemplateSpecializationKindForInstantiation() == + TSK_ExplicitSpecialization) break; if (const TemplateArgumentList *TemplateArgs @@ -2009,6 +2012,11 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, Instantiation->getInstantiatedFromMemberClass(), Pattern, PatternDef, TSK, Complain)) return true; + + llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() { + return Instantiation->getQualifiedNameAsString(); + }); + Pattern = PatternDef; // Record the point of instantiation. @@ -2675,11 +2683,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, == TSK_ExplicitSpecialization) continue; - if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || - Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) && + if (Context.getTargetInfo().getTriple().isOSWindows() && TSK == TSK_ExplicitInstantiationDeclaration) { - // In MSVC and Windows Itanium mode, explicit instantiation decl of the - // outer class doesn't affect the inner class. + // On Windows, explicit instantiation decl of the outer class doesn't + // affect the inner class. Typically extern template declarations are + // used in combination with dll import/export annotations, but those + // are not propagated from the outer class templates to inner classes. + // Therefore, do not instantiate inner classes on this platform, so + // that users don't end up with undefined symbols during linking. continue; } @@ -2887,7 +2898,7 @@ static const Decl *getCanonicalParmVarDecl(const Decl *D) { unsigned i = PV->getFunctionScopeIndex(); // This parameter might be from a freestanding function type within the // function and isn't necessarily referring to one of FD's parameters. - if (FD->getParamDecl(i) == PV) + if (i < FD->getNumParams() && FD->getParamDecl(i) == PV) return FD->getCanonicalDecl()->getParamDecl(i); } } |