2009-02-28 03:31:52 +08:00
|
|
|
//===------- 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.
|
|
|
|
//===----------------------------------------------------------------------===/
|
|
|
|
//
|
|
|
|
// This file implements C++ template instantiation.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===/
|
|
|
|
|
2010-08-26 06:03:47 +08:00
|
|
|
#include "clang/Sema/SemaInternal.h"
|
2009-08-05 00:50:30 +08:00
|
|
|
#include "TreeTransform.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/ASTConsumer.h"
|
|
|
|
#include "clang/AST/ASTContext.h"
|
2013-10-23 14:44:28 +08:00
|
|
|
#include "clang/AST/ASTLambda.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/Basic/LangOptions.h"
|
2010-08-21 02:27:03 +08:00
|
|
|
#include "clang/Sema/DeclSpec.h"
|
2011-06-12 01:19:42 +08:00
|
|
|
#include "clang/Sema/Initialization.h"
|
2010-08-13 04:07:10 +08:00
|
|
|
#include "clang/Sema/Lookup.h"
|
2010-08-24 15:21:54 +08:00
|
|
|
#include "clang/Sema/Template.h"
|
2010-08-25 13:32:35 +08:00
|
|
|
#include "clang/Sema/TemplateDeduction.h"
|
2009-02-28 03:31:52 +08:00
|
|
|
|
|
|
|
using namespace clang;
|
2010-08-25 13:32:35 +08:00
|
|
|
using namespace sema;
|
2009-02-28 03:31:52 +08:00
|
|
|
|
2009-03-11 02:03:33 +08:00
|
|
|
//===----------------------------------------------------------------------===/
|
|
|
|
// Template Instantiation Support
|
|
|
|
//===----------------------------------------------------------------------===/
|
|
|
|
|
2009-08-29 04:31:08 +08:00
|
|
|
/// \brief Retrieve the template argument list(s) that should be used to
|
|
|
|
/// instantiate the definition of the given declaration.
|
2009-11-10 03:17:50 +08:00
|
|
|
///
|
|
|
|
/// \param D the declaration for which we are computing template instantiation
|
|
|
|
/// arguments.
|
|
|
|
///
|
|
|
|
/// \param Innermost if non-NULL, the innermost template argument list.
|
2010-02-05 15:33:43 +08:00
|
|
|
///
|
|
|
|
/// \param RelativeToPrimary true if we should get the template
|
|
|
|
/// arguments relative to the primary template, even when we're
|
|
|
|
/// dealing with a specialization. This is only relevant for function
|
|
|
|
/// template specializations.
|
2010-05-04 07:29:10 +08:00
|
|
|
///
|
|
|
|
/// \param Pattern If non-NULL, indicates the pattern from which we will be
|
|
|
|
/// instantiating the definition of the given declaration, \p D. This is
|
|
|
|
/// used to determine the proper set of template instantiation arguments for
|
|
|
|
/// friend function template specializations.
|
2009-08-29 01:37:35 +08:00
|
|
|
MultiLevelTemplateArgumentList
|
2009-11-10 03:17:50 +08:00
|
|
|
Sema::getTemplateInstantiationArgs(NamedDecl *D,
|
2010-02-05 15:33:43 +08:00
|
|
|
const TemplateArgumentList *Innermost,
|
2010-05-04 07:29:10 +08:00
|
|
|
bool RelativeToPrimary,
|
|
|
|
const FunctionDecl *Pattern) {
|
2009-08-29 01:37:35 +08:00
|
|
|
// Accumulate the set of template argument lists in this structure.
|
|
|
|
MultiLevelTemplateArgumentList Result;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-11-10 03:17:50 +08:00
|
|
|
if (Innermost)
|
|
|
|
Result.addOuterTemplateArguments(Innermost);
|
|
|
|
|
2009-08-29 01:37:35 +08:00
|
|
|
DeclContext *Ctx = dyn_cast<DeclContext>(D);
|
2011-05-22 08:21:10 +08:00
|
|
|
if (!Ctx) {
|
2009-08-29 01:37:35 +08:00
|
|
|
Ctx = D->getDeclContext();
|
2013-08-06 09:03:05 +08:00
|
|
|
|
|
|
|
// Add template arguments from a variable template instantiation.
|
|
|
|
if (VarTemplateSpecializationDecl *Spec =
|
|
|
|
dyn_cast<VarTemplateSpecializationDecl>(D)) {
|
|
|
|
// We're done when we hit an explicit specialization.
|
|
|
|
if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization &&
|
|
|
|
!isa<VarTemplatePartialSpecializationDecl>(Spec))
|
|
|
|
return Result;
|
|
|
|
|
|
|
|
Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
|
|
|
|
|
|
|
|
// If this variable template specialization was instantiated from a
|
|
|
|
// specialized member that is a variable template, we're done.
|
|
|
|
assert(Spec->getSpecializedTemplate() && "No variable template?");
|
2014-01-17 07:39:20 +08:00
|
|
|
llvm::PointerUnion<VarTemplateDecl*,
|
|
|
|
VarTemplatePartialSpecializationDecl*> Specialized
|
|
|
|
= Spec->getSpecializedTemplateOrPartial();
|
|
|
|
if (VarTemplatePartialSpecializationDecl *Partial =
|
|
|
|
Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
|
|
|
|
if (Partial->isMemberSpecialization())
|
|
|
|
return Result;
|
|
|
|
} else {
|
|
|
|
VarTemplateDecl *Tmpl = Specialized.get<VarTemplateDecl *>();
|
|
|
|
if (Tmpl->isMemberSpecialization())
|
|
|
|
return Result;
|
|
|
|
}
|
2013-08-06 09:03:05 +08:00
|
|
|
}
|
|
|
|
|
2011-06-15 22:20:42 +08:00
|
|
|
// If we have a template template parameter with translation unit context,
|
|
|
|
// then we're performing substitution into a default template argument of
|
|
|
|
// this template template parameter before we've constructed the template
|
|
|
|
// that will own this template template parameter. In this case, we
|
|
|
|
// use empty template parameter lists for all of the outer templates
|
|
|
|
// to avoid performing any substitutions.
|
|
|
|
if (Ctx->isTranslationUnit()) {
|
|
|
|
if (TemplateTemplateParmDecl *TTP
|
|
|
|
= dyn_cast<TemplateTemplateParmDecl>(D)) {
|
|
|
|
for (unsigned I = 0, N = TTP->getDepth() + 1; I != N; ++I)
|
2013-05-17 11:04:50 +08:00
|
|
|
Result.addOuterTemplateArguments(None);
|
2011-06-15 22:20:42 +08:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
}
|
2011-05-22 08:21:10 +08:00
|
|
|
}
|
|
|
|
|
2009-08-29 11:16:09 +08:00
|
|
|
while (!Ctx->isFileContext()) {
|
2009-08-29 01:37:35 +08:00
|
|
|
// Add template arguments from a class template instantiation.
|
2009-09-09 23:08:12 +08:00
|
|
|
if (ClassTemplateSpecializationDecl *Spec
|
2009-08-29 01:37:35 +08:00
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
|
|
|
|
// We're done when we hit an explicit specialization.
|
2010-07-09 02:37:38 +08:00
|
|
|
if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization &&
|
|
|
|
!isa<ClassTemplatePartialSpecializationDecl>(Spec))
|
2009-08-29 01:37:35 +08:00
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-29 01:37:35 +08:00
|
|
|
Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
|
2009-10-14 00:30:37 +08:00
|
|
|
|
|
|
|
// If this class template specialization was instantiated from a
|
|
|
|
// specialized member that is a class template, we're done.
|
|
|
|
assert(Spec->getSpecializedTemplate() && "No class template?");
|
|
|
|
if (Spec->getSpecializedTemplate()->isMemberSpecialization())
|
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
}
|
2009-08-29 01:37:35 +08:00
|
|
|
// Add template arguments from a function template specialization.
|
2009-08-29 11:16:09 +08:00
|
|
|
else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
|
2010-02-05 15:33:43 +08:00
|
|
|
if (!RelativeToPrimary &&
|
2011-08-14 11:52:19 +08:00
|
|
|
(Function->getTemplateSpecializationKind() ==
|
|
|
|
TSK_ExplicitSpecialization &&
|
|
|
|
!Function->getClassScopeSpecializationPattern()))
|
2009-10-14 00:30:37 +08:00
|
|
|
break;
|
|
|
|
|
2009-08-29 01:37:35 +08:00
|
|
|
if (const TemplateArgumentList *TemplateArgs
|
2009-10-14 00:30:37 +08:00
|
|
|
= Function->getTemplateSpecializationArgs()) {
|
|
|
|
// Add the template arguments for this specialization.
|
2009-08-29 01:37:35 +08:00
|
|
|
Result.addOuterTemplateArguments(TemplateArgs);
|
2009-08-29 11:16:09 +08:00
|
|
|
|
2009-10-14 00:30:37 +08:00
|
|
|
// If this function was instantiated from a specialized member that is
|
|
|
|
// a function template, we're done.
|
|
|
|
assert(Function->getPrimaryTemplate() && "No function template?");
|
|
|
|
if (Function->getPrimaryTemplate()->isMemberSpecialization())
|
|
|
|
break;
|
2013-10-23 14:44:28 +08:00
|
|
|
|
|
|
|
// If this function is a generic lambda specialization, we are done.
|
|
|
|
if (isGenericLambdaCallOperatorSpecialization(Function))
|
|
|
|
break;
|
|
|
|
|
2011-03-06 01:54:25 +08:00
|
|
|
} else if (FunctionTemplateDecl *FunTmpl
|
|
|
|
= Function->getDescribedFunctionTemplate()) {
|
|
|
|
// Add the "injected" template arguments.
|
2013-05-17 11:04:50 +08:00
|
|
|
Result.addOuterTemplateArguments(FunTmpl->getInjectedTemplateArgs());
|
2009-10-14 00:30:37 +08:00
|
|
|
}
|
|
|
|
|
2009-08-29 11:16:09 +08:00
|
|
|
// If this is a friend declaration and it declares an entity at
|
|
|
|
// namespace scope, take arguments from its lexical parent
|
2010-05-04 07:29:10 +08:00
|
|
|
// instead of its semantic parent, unless of course the pattern we're
|
|
|
|
// instantiating actually comes from the file's context!
|
2009-08-29 11:16:09 +08:00
|
|
|
if (Function->getFriendObjectKind() &&
|
2010-05-04 07:29:10 +08:00
|
|
|
Function->getDeclContext()->isFileContext() &&
|
|
|
|
(!Pattern || !Pattern->getLexicalDeclContext()->isFileContext())) {
|
2009-08-29 11:16:09 +08:00
|
|
|
Ctx = Function->getLexicalDeclContext();
|
2010-02-05 15:33:43 +08:00
|
|
|
RelativeToPrimary = false;
|
2009-08-29 11:16:09 +08:00
|
|
|
continue;
|
2010-07-09 02:37:38 +08:00
|
|
|
}
|
|
|
|
} else if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Ctx)) {
|
|
|
|
if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
|
|
|
|
QualType T = ClassTemplate->getInjectedClassNameSpecialization();
|
2013-05-17 11:04:50 +08:00
|
|
|
const TemplateSpecializationType *TST =
|
|
|
|
cast<TemplateSpecializationType>(Context.getCanonicalType(T));
|
|
|
|
Result.addOuterTemplateArguments(
|
|
|
|
llvm::makeArrayRef(TST->getArgs(), TST->getNumArgs()));
|
2010-07-09 02:37:38 +08:00
|
|
|
if (ClassTemplate->isMemberSpecialization())
|
|
|
|
break;
|
2009-08-29 11:16:09 +08:00
|
|
|
}
|
2009-08-29 01:37:35 +08:00
|
|
|
}
|
2009-08-29 11:16:09 +08:00
|
|
|
|
|
|
|
Ctx = Ctx->getParent();
|
2010-02-05 15:33:43 +08:00
|
|
|
RelativeToPrimary = false;
|
2009-05-15 07:26:13 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-29 01:37:35 +08:00
|
|
|
return Result;
|
2009-05-15 07:26:13 +08:00
|
|
|
}
|
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
bool Sema::ActiveTemplateInstantiation::isInstantiationRecord() const {
|
|
|
|
switch (Kind) {
|
|
|
|
case TemplateInstantiation:
|
Implement DR1330 in C++11 mode, to support libstdc++4.7 which uses it.
We have a new flavor of exception specification, EST_Uninstantiated. A function
type with this exception specification carries a pointer to a FunctionDecl, and
the exception specification for that FunctionDecl is instantiated (if needed)
and used in the place of the function type's exception specification.
When a function template declaration with a non-trivial exception specification
is instantiated, the specialization's exception specification is set to this
new 'uninstantiated' kind rather than being instantiated immediately.
Expr::CanThrow has migrated onto Sema, so it can instantiate exception specs
on-demand. Also, any odr-use of a function triggers the instantiation of its
exception specification (the exception specification could be needed by IRGen).
In passing, fix two places where a DeclRefExpr was created but the corresponding
function was not actually marked odr-used. We used to get away with this, but
don't any more.
Also fix a bug where instantiating an exception specification which refers to
function parameters resulted in a crash. We still have the same bug in default
arguments, which I'll be looking into next.
This, plus a tiny patch to fix libstdc++'s common_type, is enough for clang to
parse (and, in very limited testing, support) all of libstdc++4.7's standard
headers.
llvm-svn: 154886
2012-04-17 08:58:00 +08:00
|
|
|
case ExceptionSpecInstantiation:
|
2009-11-12 05:54:23 +08:00
|
|
|
case DefaultTemplateArgumentInstantiation:
|
|
|
|
case DefaultFunctionArgumentInstantiation:
|
|
|
|
case ExplicitTemplateArgumentSubstitution:
|
|
|
|
case DeducedTemplateArgumentSubstitution:
|
|
|
|
case PriorTemplateArgumentSubstitution:
|
2012-07-08 10:38:24 +08:00
|
|
|
return true;
|
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
case DefaultTemplateArgumentChecking:
|
|
|
|
return false;
|
|
|
|
}
|
2012-01-17 14:56:22 +08:00
|
|
|
|
|
|
|
llvm_unreachable("Invalid InstantiationKind!");
|
2009-11-12 05:54:23 +08:00
|
|
|
}
|
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind,
|
2014-03-14 04:34:22 +08:00
|
|
|
SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
|
|
|
|
Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
|
2015-03-07 00:36:50 +08:00
|
|
|
sema::TemplateDeductionInfo *DeductionInfo)
|
|
|
|
: SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext) {
|
2015-01-30 13:01:23 +08:00
|
|
|
// Don't allow further instantiation if a fatal error has occcured. Any
|
|
|
|
// diagnostics we might have raised will not be visible.
|
|
|
|
if (SemaRef.Diags.hasFatalErrorOccurred()) {
|
|
|
|
Invalid = true;
|
|
|
|
return;
|
|
|
|
}
|
2014-03-14 04:34:22 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
|
2009-03-11 04:44:00 +08:00
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
2014-03-14 04:34:22 +08:00
|
|
|
Inst.Kind = Kind;
|
2009-03-11 04:44:00 +08:00
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = Entity;
|
2014-03-14 04:34:22 +08:00
|
|
|
Inst.Template = Template;
|
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
|
|
|
Inst.DeductionInfo = DeductionInfo;
|
2009-03-11 04:44:00 +08:00
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
2011-01-28 06:31:44 +08:00
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
2009-03-11 04:44:00 +08:00
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
2014-03-14 04:34:22 +08:00
|
|
|
if (!Inst.isInstantiationRecord())
|
|
|
|
++SemaRef.NonInstantiationEntries;
|
2009-03-11 04:44:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity,
|
|
|
|
SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(SemaRef,
|
|
|
|
ActiveTemplateInstantiation::TemplateInstantiation,
|
|
|
|
PointOfInstantiation, InstantiationRange, Entity) {}
|
2014-03-14 04:34:22 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionDecl *Entity,
|
|
|
|
ExceptionSpecification, SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef, ActiveTemplateInstantiation::ExceptionSpecInstantiation,
|
|
|
|
PointOfInstantiation, InstantiationRange, Entity) {}
|
Implement DR1330 in C++11 mode, to support libstdc++4.7 which uses it.
We have a new flavor of exception specification, EST_Uninstantiated. A function
type with this exception specification carries a pointer to a FunctionDecl, and
the exception specification for that FunctionDecl is instantiated (if needed)
and used in the place of the function type's exception specification.
When a function template declaration with a non-trivial exception specification
is instantiated, the specialization's exception specification is set to this
new 'uninstantiated' kind rather than being instantiated immediately.
Expr::CanThrow has migrated onto Sema, so it can instantiate exception specs
on-demand. Also, any odr-use of a function triggers the instantiation of its
exception specification (the exception specification could be needed by IRGen).
In passing, fix two places where a DeclRefExpr was created but the corresponding
function was not actually marked odr-used. We used to get away with this, but
don't any more.
Also fix a bug where instantiating an exception specification which refers to
function parameters resulted in a crash. We still have the same bug in default
arguments, which I'll be looking into next.
This, plus a tiny patch to fix libstdc++'s common_type, is enough for clang to
parse (and, in very limited testing, support) all of libstdc++4.7's standard
headers.
llvm-svn: 154886
2012-04-17 08:58:00 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef,
|
|
|
|
ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation,
|
|
|
|
PointOfInstantiation, InstantiationRange, Template, nullptr,
|
|
|
|
TemplateArgs) {}
|
2009-03-10 08:06:19 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
FunctionTemplateDecl *FunctionTemplate,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
ActiveTemplateInstantiation::InstantiationKind Kind,
|
|
|
|
sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
|
|
|
|
InstantiationRange, FunctionTemplate, nullptr,
|
|
|
|
TemplateArgs, &DeductionInfo) {}
|
2009-07-02 06:01:06 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
ClassTemplatePartialSpecializationDecl *PartialSpec,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef,
|
|
|
|
ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
|
|
|
|
PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
|
|
|
|
TemplateArgs, &DeductionInfo) {}
|
2013-08-06 09:03:05 +08:00
|
|
|
|
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
VarTemplatePartialSpecializationDecl *PartialSpec,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
|
2015-03-07 00:36:50 +08:00
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef,
|
|
|
|
ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
|
|
|
|
PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
|
|
|
|
TemplateArgs, &DeductionInfo) {}
|
2009-11-12 03:13:48 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef,
|
|
|
|
ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation,
|
|
|
|
PointOfInstantiation, InstantiationRange, Param, nullptr,
|
|
|
|
TemplateArgs) {}
|
2014-03-14 04:34:22 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
|
|
|
|
NonTypeTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef,
|
|
|
|
ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution,
|
|
|
|
PointOfInstantiation, InstantiationRange, Param, Template,
|
|
|
|
TemplateArgs) {}
|
2009-11-12 03:13:48 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
|
|
|
|
TemplateTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef,
|
|
|
|
ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution,
|
|
|
|
PointOfInstantiation, InstantiationRange, Param, Template,
|
|
|
|
TemplateArgs) {}
|
2009-11-12 05:54:23 +08:00
|
|
|
|
2015-03-07 00:36:50 +08:00
|
|
|
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|
|
|
Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
|
|
|
|
NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
|
|
|
: InstantiatingTemplate(
|
|
|
|
SemaRef, ActiveTemplateInstantiation::DefaultTemplateArgumentChecking,
|
|
|
|
PointOfInstantiation, InstantiationRange, Param, Template,
|
|
|
|
TemplateArgs) {}
|
2009-09-05 13:14:19 +08:00
|
|
|
|
2009-05-19 01:01:57 +08:00
|
|
|
void Sema::InstantiatingTemplate::Clear() {
|
|
|
|
if (!Invalid) {
|
2009-11-12 05:54:23 +08:00
|
|
|
if (!SemaRef.ActiveTemplateInstantiations.back().isInstantiationRecord()) {
|
|
|
|
assert(SemaRef.NonInstantiationEntries > 0);
|
|
|
|
--SemaRef.NonInstantiationEntries;
|
|
|
|
}
|
2011-01-28 06:31:44 +08:00
|
|
|
SemaRef.InNonInstantiationSFINAEContext
|
|
|
|
= SavedInNonInstantiationSFINAEContext;
|
When we perform dependent name lookup during template instantiation, it's not
sufficient to only consider names visible at the point of instantiation,
because that may not include names that were visible when the template was
defined. More generally, if the instantiation backtrace goes through a module
M, then every declaration visible within M should be available to the
instantiation. Any of those declarations might be part of the interface that M
intended to export to a template that it instantiates.
The fix here has two parts:
1) If we find a non-visible declaration during name lookup during template
instantiation, check whether the declaration was visible from the defining
module of all entities on the active template instantiation stack. The defining
module is not the owning module in all cases: we look at the module in which a
template was defined, not the module in which it was first instantiated.
2) Perform pending instantiations at the end of a module, not at the end of the
translation unit. This is general goodness, since it significantly cuts down
the amount of redundant work that is performed in every TU importing a module,
and also implicitly adds the module containing the point of instantiation to
the set of modules checked for declarations in a lookup within a template
instantiation.
There's a known issue here with template instantiations performed while
building a module, if additional imports are added later on. I'll fix that
in a subsequent commit.
llvm-svn: 187167
2013-07-26 07:08:39 +08:00
|
|
|
|
|
|
|
// Name lookup no longer looks in this template's defining module.
|
|
|
|
assert(SemaRef.ActiveTemplateInstantiations.size() >=
|
|
|
|
SemaRef.ActiveTemplateInstantiationLookupModules.size() &&
|
|
|
|
"forgot to remove a lookup module for a template instantiation");
|
|
|
|
if (SemaRef.ActiveTemplateInstantiations.size() ==
|
|
|
|
SemaRef.ActiveTemplateInstantiationLookupModules.size()) {
|
|
|
|
if (Module *M = SemaRef.ActiveTemplateInstantiationLookupModules.back())
|
|
|
|
SemaRef.LookupModulesCache.erase(M);
|
|
|
|
SemaRef.ActiveTemplateInstantiationLookupModules.pop_back();
|
|
|
|
}
|
|
|
|
|
2009-03-10 08:06:19 +08:00
|
|
|
SemaRef.ActiveTemplateInstantiations.pop_back();
|
2009-05-19 01:01:57 +08:00
|
|
|
Invalid = true;
|
|
|
|
}
|
2009-03-10 08:06:19 +08:00
|
|
|
}
|
|
|
|
|
2009-03-11 04:44:00 +08:00
|
|
|
bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
|
|
|
|
SourceLocation PointOfInstantiation,
|
|
|
|
SourceRange InstantiationRange) {
|
2009-11-12 05:54:23 +08:00
|
|
|
assert(SemaRef.NonInstantiationEntries <=
|
|
|
|
SemaRef.ActiveTemplateInstantiations.size());
|
|
|
|
if ((SemaRef.ActiveTemplateInstantiations.size() -
|
|
|
|
SemaRef.NonInstantiationEntries)
|
2012-03-11 15:00:24 +08:00
|
|
|
<= SemaRef.getLangOpts().InstantiationDepth)
|
2009-03-11 04:44:00 +08:00
|
|
|
return false;
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
SemaRef.Diag(PointOfInstantiation,
|
2009-03-11 04:44:00 +08:00
|
|
|
diag::err_template_recursion_depth_exceeded)
|
2012-03-11 15:00:24 +08:00
|
|
|
<< SemaRef.getLangOpts().InstantiationDepth
|
2009-03-11 04:44:00 +08:00
|
|
|
<< InstantiationRange;
|
|
|
|
SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)
|
2012-03-11 15:00:24 +08:00
|
|
|
<< SemaRef.getLangOpts().InstantiationDepth;
|
2009-03-11 04:44:00 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-03-11 02:03:33 +08:00
|
|
|
/// \brief Prints the current instantiation stack through a series of
|
|
|
|
/// notes.
|
|
|
|
void Sema::PrintInstantiationStack() {
|
2010-04-20 15:18:24 +08:00
|
|
|
// Determine which template instantiations to skip, if any.
|
|
|
|
unsigned SkipStart = ActiveTemplateInstantiations.size(), SkipEnd = SkipStart;
|
|
|
|
unsigned Limit = Diags.getTemplateBacktraceLimit();
|
|
|
|
if (Limit && Limit < ActiveTemplateInstantiations.size()) {
|
|
|
|
SkipStart = Limit / 2 + Limit % 2;
|
|
|
|
SkipEnd = ActiveTemplateInstantiations.size() - Limit / 2;
|
|
|
|
}
|
|
|
|
|
2009-07-02 06:01:06 +08:00
|
|
|
// FIXME: In all of these cases, we need to show the template arguments
|
2010-04-20 15:18:24 +08:00
|
|
|
unsigned InstantiationIdx = 0;
|
2013-07-04 11:08:24 +08:00
|
|
|
for (SmallVectorImpl<ActiveTemplateInstantiation>::reverse_iterator
|
2009-03-11 02:03:33 +08:00
|
|
|
Active = ActiveTemplateInstantiations.rbegin(),
|
|
|
|
ActiveEnd = ActiveTemplateInstantiations.rend();
|
|
|
|
Active != ActiveEnd;
|
2010-04-20 15:18:24 +08:00
|
|
|
++Active, ++InstantiationIdx) {
|
|
|
|
// Skip this instantiation?
|
|
|
|
if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
|
|
|
|
if (InstantiationIdx == SkipStart) {
|
|
|
|
// Note that we're skipping instantiations.
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2010-04-20 15:18:24 +08:00
|
|
|
diag::note_instantiation_contexts_suppressed)
|
|
|
|
<< unsigned(ActiveTemplateInstantiations.size() - Limit);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-03-11 04:44:00 +08:00
|
|
|
switch (Active->Kind) {
|
|
|
|
case ActiveTemplateInstantiation::TemplateInstantiation: {
|
2012-11-16 16:40:59 +08:00
|
|
|
Decl *D = Active->Entity;
|
2009-05-19 01:01:57 +08:00
|
|
|
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
|
|
|
|
unsigned DiagID = diag::note_template_member_class_here;
|
|
|
|
if (isa<ClassTemplateSpecializationDecl>(Record))
|
|
|
|
DiagID = diag::note_template_class_instantiation_here;
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation, DiagID)
|
2009-05-19 01:01:57 +08:00
|
|
|
<< Context.getTypeDeclType(Record)
|
|
|
|
<< Active->InstantiationRange;
|
2009-07-25 04:34:43 +08:00
|
|
|
} else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
|
2009-06-26 08:10:03 +08:00
|
|
|
unsigned DiagID;
|
|
|
|
if (Function->getPrimaryTemplate())
|
|
|
|
DiagID = diag::note_function_template_spec_here;
|
|
|
|
else
|
|
|
|
DiagID = diag::note_template_member_function_here;
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation, DiagID)
|
2009-05-19 01:01:57 +08:00
|
|
|
<< Function
|
|
|
|
<< Active->InstantiationRange;
|
2011-05-06 05:57:07 +08:00
|
|
|
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2013-08-15 04:15:02 +08:00
|
|
|
VD->isStaticDataMember()?
|
|
|
|
diag::note_template_static_data_member_def_here
|
|
|
|
: diag::note_template_variable_def_here)
|
2011-05-06 05:57:07 +08:00
|
|
|
<< VD
|
|
|
|
<< Active->InstantiationRange;
|
2012-03-15 07:13:10 +08:00
|
|
|
} else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
|
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
|
|
|
diag::note_template_enum_def_here)
|
|
|
|
<< ED
|
|
|
|
<< Active->InstantiationRange;
|
2014-11-18 07:36:45 +08:00
|
|
|
} else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
|
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
|
|
|
diag::note_template_nsdmi_here)
|
|
|
|
<< FD << Active->InstantiationRange;
|
2011-05-06 05:57:07 +08:00
|
|
|
} else {
|
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
|
|
|
diag::note_template_type_alias_instantiation_here)
|
|
|
|
<< cast<TypeAliasTemplateDecl>(D)
|
2009-07-25 04:34:43 +08:00
|
|
|
<< Active->InstantiationRange;
|
2009-05-19 01:01:57 +08:00
|
|
|
}
|
2009-03-11 04:44:00 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: {
|
2012-11-16 16:40:59 +08:00
|
|
|
TemplateDecl *Template = cast<TemplateDecl>(Active->Entity);
|
2013-02-22 23:46:01 +08:00
|
|
|
SmallVector<char, 128> TemplateArgsStr;
|
|
|
|
llvm::raw_svector_ostream OS(TemplateArgsStr);
|
|
|
|
Template->printName(OS);
|
|
|
|
TemplateSpecializationType::PrintTemplateArgumentList(OS,
|
2009-09-09 23:08:12 +08:00
|
|
|
Active->TemplateArgs,
|
2009-05-30 04:38:28 +08:00
|
|
|
Active->NumTemplateArgs,
|
2011-09-28 07:30:47 +08:00
|
|
|
getPrintingPolicy());
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2009-03-11 04:44:00 +08:00
|
|
|
diag::note_default_arg_instantiation_here)
|
2013-02-22 23:46:01 +08:00
|
|
|
<< OS.str()
|
2009-03-11 04:44:00 +08:00
|
|
|
<< Active->InstantiationRange;
|
|
|
|
break;
|
|
|
|
}
|
2009-06-11 07:47:09 +08:00
|
|
|
|
2009-07-02 06:01:06 +08:00
|
|
|
case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: {
|
2012-11-16 16:40:59 +08:00
|
|
|
FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>(Active->Entity);
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2009-07-02 06:01:06 +08:00
|
|
|
diag::note_explicit_template_arg_substitution_here)
|
2010-03-31 04:35:20 +08:00
|
|
|
<< FnTmpl
|
|
|
|
<< getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
|
|
|
|
Active->TemplateArgs,
|
|
|
|
Active->NumTemplateArgs)
|
|
|
|
<< Active->InstantiationRange;
|
2009-06-11 07:47:09 +08:00
|
|
|
break;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-02 06:01:06 +08:00
|
|
|
case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
|
2012-11-16 16:40:59 +08:00
|
|
|
if (ClassTemplatePartialSpecializationDecl *PartialSpec =
|
|
|
|
dyn_cast<ClassTemplatePartialSpecializationDecl>(Active->Entity)) {
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2009-07-02 06:01:06 +08:00
|
|
|
diag::note_partial_spec_deduct_instantiation_here)
|
|
|
|
<< Context.getTypeDeclType(PartialSpec)
|
2010-03-31 04:35:20 +08:00
|
|
|
<< getTemplateArgumentBindingsText(
|
|
|
|
PartialSpec->getTemplateParameters(),
|
|
|
|
Active->TemplateArgs,
|
|
|
|
Active->NumTemplateArgs)
|
2009-07-02 06:01:06 +08:00
|
|
|
<< Active->InstantiationRange;
|
|
|
|
} else {
|
|
|
|
FunctionTemplateDecl *FnTmpl
|
2012-11-16 16:40:59 +08:00
|
|
|
= cast<FunctionTemplateDecl>(Active->Entity);
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2009-07-02 06:01:06 +08:00
|
|
|
diag::note_function_template_deduction_instantiation_here)
|
2010-03-31 04:35:20 +08:00
|
|
|
<< FnTmpl
|
|
|
|
<< getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
|
|
|
|
Active->TemplateArgs,
|
|
|
|
Active->NumTemplateArgs)
|
|
|
|
<< Active->InstantiationRange;
|
2009-07-02 06:01:06 +08:00
|
|
|
}
|
|
|
|
break;
|
2009-06-11 07:47:09 +08:00
|
|
|
|
2009-09-05 13:14:19 +08:00
|
|
|
case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: {
|
2012-11-16 16:40:59 +08:00
|
|
|
ParmVarDecl *Param = cast<ParmVarDecl>(Active->Entity);
|
2009-09-05 13:14:19 +08:00
|
|
|
FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2013-02-22 23:46:01 +08:00
|
|
|
SmallVector<char, 128> TemplateArgsStr;
|
|
|
|
llvm::raw_svector_ostream OS(TemplateArgsStr);
|
|
|
|
FD->printName(OS);
|
|
|
|
TemplateSpecializationType::PrintTemplateArgumentList(OS,
|
2009-09-09 23:08:12 +08:00
|
|
|
Active->TemplateArgs,
|
2009-09-05 13:14:19 +08:00
|
|
|
Active->NumTemplateArgs,
|
2011-09-28 07:30:47 +08:00
|
|
|
getPrintingPolicy());
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2009-09-05 13:14:19 +08:00
|
|
|
diag::note_default_function_arg_instantiation_here)
|
2013-02-22 23:46:01 +08:00
|
|
|
<< OS.str()
|
2009-09-05 13:14:19 +08:00
|
|
|
<< Active->InstantiationRange;
|
|
|
|
break;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-11-12 03:13:48 +08:00
|
|
|
case ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution: {
|
2012-11-16 16:40:59 +08:00
|
|
|
NamedDecl *Parm = cast<NamedDecl>(Active->Entity);
|
2009-11-12 03:13:48 +08:00
|
|
|
std::string Name;
|
|
|
|
if (!Parm->getName().empty())
|
|
|
|
Name = std::string(" '") + Parm->getName().str() + "'";
|
2014-05-26 14:22:03 +08:00
|
|
|
|
|
|
|
TemplateParameterList *TemplateParams = nullptr;
|
2011-01-05 07:35:54 +08:00
|
|
|
if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
|
|
|
|
TemplateParams = Template->getTemplateParameters();
|
|
|
|
else
|
|
|
|
TemplateParams =
|
|
|
|
cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
|
|
|
|
->getTemplateParameters();
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2009-11-12 03:13:48 +08:00
|
|
|
diag::note_prior_template_arg_substitution)
|
|
|
|
<< isa<TemplateTemplateParmDecl>(Parm)
|
|
|
|
<< Name
|
2011-01-05 07:35:54 +08:00
|
|
|
<< getTemplateArgumentBindingsText(TemplateParams,
|
2009-11-12 03:13:48 +08:00
|
|
|
Active->TemplateArgs,
|
|
|
|
Active->NumTemplateArgs)
|
|
|
|
<< Active->InstantiationRange;
|
|
|
|
break;
|
|
|
|
}
|
2009-11-12 05:54:23 +08:00
|
|
|
|
|
|
|
case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking: {
|
2014-05-26 14:22:03 +08:00
|
|
|
TemplateParameterList *TemplateParams = nullptr;
|
2011-01-05 07:35:54 +08:00
|
|
|
if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
|
|
|
|
TemplateParams = Template->getTemplateParameters();
|
|
|
|
else
|
|
|
|
TemplateParams =
|
|
|
|
cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
|
|
|
|
->getTemplateParameters();
|
|
|
|
|
2010-11-19 04:06:41 +08:00
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
2009-11-12 05:54:23 +08:00
|
|
|
diag::note_template_default_arg_checking)
|
2011-01-05 07:35:54 +08:00
|
|
|
<< getTemplateArgumentBindingsText(TemplateParams,
|
2009-11-12 05:54:23 +08:00
|
|
|
Active->TemplateArgs,
|
|
|
|
Active->NumTemplateArgs)
|
|
|
|
<< Active->InstantiationRange;
|
|
|
|
break;
|
|
|
|
}
|
Implement DR1330 in C++11 mode, to support libstdc++4.7 which uses it.
We have a new flavor of exception specification, EST_Uninstantiated. A function
type with this exception specification carries a pointer to a FunctionDecl, and
the exception specification for that FunctionDecl is instantiated (if needed)
and used in the place of the function type's exception specification.
When a function template declaration with a non-trivial exception specification
is instantiated, the specialization's exception specification is set to this
new 'uninstantiated' kind rather than being instantiated immediately.
Expr::CanThrow has migrated onto Sema, so it can instantiate exception specs
on-demand. Also, any odr-use of a function triggers the instantiation of its
exception specification (the exception specification could be needed by IRGen).
In passing, fix two places where a DeclRefExpr was created but the corresponding
function was not actually marked odr-used. We used to get away with this, but
don't any more.
Also fix a bug where instantiating an exception specification which refers to
function parameters resulted in a crash. We still have the same bug in default
arguments, which I'll be looking into next.
This, plus a tiny patch to fix libstdc++'s common_type, is enough for clang to
parse (and, in very limited testing, support) all of libstdc++4.7's standard
headers.
llvm-svn: 154886
2012-04-17 08:58:00 +08:00
|
|
|
|
|
|
|
case ActiveTemplateInstantiation::ExceptionSpecInstantiation:
|
|
|
|
Diags.Report(Active->PointOfInstantiation,
|
|
|
|
diag::note_template_exception_spec_instantiation_here)
|
2012-11-16 16:40:59 +08:00
|
|
|
<< cast<FunctionDecl>(Active->Entity)
|
Implement DR1330 in C++11 mode, to support libstdc++4.7 which uses it.
We have a new flavor of exception specification, EST_Uninstantiated. A function
type with this exception specification carries a pointer to a FunctionDecl, and
the exception specification for that FunctionDecl is instantiated (if needed)
and used in the place of the function type's exception specification.
When a function template declaration with a non-trivial exception specification
is instantiated, the specialization's exception specification is set to this
new 'uninstantiated' kind rather than being instantiated immediately.
Expr::CanThrow has migrated onto Sema, so it can instantiate exception specs
on-demand. Also, any odr-use of a function triggers the instantiation of its
exception specification (the exception specification could be needed by IRGen).
In passing, fix two places where a DeclRefExpr was created but the corresponding
function was not actually marked odr-used. We used to get away with this, but
don't any more.
Also fix a bug where instantiating an exception specification which refers to
function parameters resulted in a crash. We still have the same bug in default
arguments, which I'll be looking into next.
This, plus a tiny patch to fix libstdc++'s common_type, is enough for clang to
parse (and, in very limited testing, support) all of libstdc++4.7's standard
headers.
llvm-svn: 154886
2012-04-17 08:58:00 +08:00
|
|
|
<< Active->InstantiationRange;
|
|
|
|
break;
|
2009-03-11 04:44:00 +08:00
|
|
|
}
|
2009-03-11 02:03:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
|
2011-01-28 06:31:44 +08:00
|
|
|
if (InNonInstantiationSFINAEContext)
|
2014-05-26 14:22:03 +08:00
|
|
|
return Optional<TemplateDeductionInfo *>(nullptr);
|
2011-01-28 06:31:44 +08:00
|
|
|
|
2013-07-04 11:08:24 +08:00
|
|
|
for (SmallVectorImpl<ActiveTemplateInstantiation>::const_reverse_iterator
|
2009-06-14 15:33:30 +08:00
|
|
|
Active = ActiveTemplateInstantiations.rbegin(),
|
|
|
|
ActiveEnd = ActiveTemplateInstantiations.rend();
|
|
|
|
Active != ActiveEnd;
|
2009-11-12 05:54:23 +08:00
|
|
|
++Active)
|
|
|
|
{
|
2009-06-14 15:33:30 +08:00
|
|
|
switch(Active->Kind) {
|
2011-01-28 06:31:44 +08:00
|
|
|
case ActiveTemplateInstantiation::TemplateInstantiation:
|
2012-04-26 15:24:08 +08:00
|
|
|
// An instantiation of an alias template may or may not be a SFINAE
|
|
|
|
// context, depending on what else is on the stack.
|
2012-11-16 16:40:59 +08:00
|
|
|
if (isa<TypeAliasTemplateDecl>(Active->Entity))
|
2012-04-26 15:24:08 +08:00
|
|
|
break;
|
|
|
|
// Fall through.
|
|
|
|
case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
|
Implement DR1330 in C++11 mode, to support libstdc++4.7 which uses it.
We have a new flavor of exception specification, EST_Uninstantiated. A function
type with this exception specification carries a pointer to a FunctionDecl, and
the exception specification for that FunctionDecl is instantiated (if needed)
and used in the place of the function type's exception specification.
When a function template declaration with a non-trivial exception specification
is instantiated, the specialization's exception specification is set to this
new 'uninstantiated' kind rather than being instantiated immediately.
Expr::CanThrow has migrated onto Sema, so it can instantiate exception specs
on-demand. Also, any odr-use of a function triggers the instantiation of its
exception specification (the exception specification could be needed by IRGen).
In passing, fix two places where a DeclRefExpr was created but the corresponding
function was not actually marked odr-used. We used to get away with this, but
don't any more.
Also fix a bug where instantiating an exception specification which refers to
function parameters resulted in a crash. We still have the same bug in default
arguments, which I'll be looking into next.
This, plus a tiny patch to fix libstdc++'s common_type, is enough for clang to
parse (and, in very limited testing, support) all of libstdc++4.7's standard
headers.
llvm-svn: 154886
2012-04-17 08:58:00 +08:00
|
|
|
case ActiveTemplateInstantiation::ExceptionSpecInstantiation:
|
2009-07-02 06:01:06 +08:00
|
|
|
// This is a template instantiation, so there is no SFINAE.
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-14 15:33:30 +08:00
|
|
|
case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation:
|
2009-11-12 03:13:48 +08:00
|
|
|
case ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution:
|
2009-11-12 05:54:23 +08:00
|
|
|
case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking:
|
2009-11-12 03:13:48 +08:00
|
|
|
// A default template argument instantiation and substitution into
|
|
|
|
// template parameters with arguments for prior parameters may or may
|
|
|
|
// not be a SFINAE context; look further up the stack.
|
2009-06-14 15:33:30 +08:00
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-02 06:01:06 +08:00
|
|
|
case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution:
|
|
|
|
case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
|
|
|
|
// We're either substitution explicitly-specified template arguments
|
|
|
|
// or deduced template arguments, so SFINAE applies.
|
2010-10-13 07:32:35 +08:00
|
|
|
assert(Active->DeductionInfo && "Missing deduction info pointer");
|
|
|
|
return Active->DeductionInfo;
|
2009-06-14 15:33:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2009-06-14 15:33:30 +08:00
|
|
|
}
|
|
|
|
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
/// \brief Retrieve the depth and index of a parameter pack.
|
|
|
|
static std::pair<unsigned, unsigned>
|
|
|
|
getDepthAndIndex(NamedDecl *ND) {
|
|
|
|
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
|
|
|
|
return std::make_pair(TTP->getDepth(), TTP->getIndex());
|
|
|
|
|
|
|
|
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
|
|
|
|
return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
|
|
|
|
|
|
|
|
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
|
|
|
|
return std::make_pair(TTP->getDepth(), TTP->getIndex());
|
|
|
|
}
|
|
|
|
|
2009-02-28 03:31:52 +08:00
|
|
|
//===----------------------------------------------------------------------===/
|
|
|
|
// Template Instantiation for Types
|
|
|
|
//===----------------------------------------------------------------------===/
|
2009-02-28 08:25:32 +08:00
|
|
|
namespace {
|
2010-05-01 02:55:50 +08:00
|
|
|
class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {
|
2009-08-29 04:31:08 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs;
|
2009-02-28 08:25:32 +08:00
|
|
|
SourceLocation Loc;
|
|
|
|
DeclarationName Entity;
|
|
|
|
|
|
|
|
public:
|
2009-08-20 15:17:43 +08:00
|
|
|
typedef TreeTransform<TemplateInstantiator> inherited;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
|
|
|
TemplateInstantiator(Sema &SemaRef,
|
2009-08-29 04:31:08 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2009-08-05 00:50:30 +08:00
|
|
|
SourceLocation Loc,
|
2009-09-09 23:08:12 +08:00
|
|
|
DeclarationName Entity)
|
|
|
|
: inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
|
2009-08-20 15:17:43 +08:00
|
|
|
Entity(Entity) { }
|
2009-08-05 00:50:30 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
/// \brief Determine whether the given type \p T has already been
|
2009-08-05 00:50:30 +08:00
|
|
|
/// transformed.
|
|
|
|
///
|
|
|
|
/// For the purposes of template instantiation, a type has already been
|
|
|
|
/// transformed if it is NULL or if it is not dependent.
|
2010-05-08 07:12:07 +08:00
|
|
|
bool AlreadyTransformed(QualType T);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-05 00:50:30 +08:00
|
|
|
/// \brief Returns the location of the entity being instantiated, if known.
|
|
|
|
SourceLocation getBaseLocation() { return Loc; }
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-05 00:50:30 +08:00
|
|
|
/// \brief Returns the name of the entity being instantiated, if any.
|
|
|
|
DeclarationName getBaseEntity() { return Entity; }
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-10-27 14:26:26 +08:00
|
|
|
/// \brief Sets the "base" location and entity when that
|
|
|
|
/// information is known based on another transformation.
|
|
|
|
void setBase(SourceLocation Loc, DeclarationName Entity) {
|
|
|
|
this->Loc = Loc;
|
|
|
|
this->Entity = Entity;
|
|
|
|
}
|
2010-12-21 06:05:00 +08:00
|
|
|
|
|
|
|
bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
|
|
|
|
SourceRange PatternRange,
|
2013-08-10 02:02:13 +08:00
|
|
|
ArrayRef<UnexpandedParameterPack> Unexpanded,
|
|
|
|
bool &ShouldExpand, bool &RetainExpansion,
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> &NumExpansions) {
|
2010-12-21 08:52:54 +08:00
|
|
|
return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
|
|
|
|
PatternRange, Unexpanded,
|
|
|
|
TemplateArgs,
|
|
|
|
ShouldExpand,
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
RetainExpansion,
|
2010-12-21 08:52:54 +08:00
|
|
|
NumExpansions);
|
|
|
|
}
|
2010-12-21 06:05:00 +08:00
|
|
|
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {
|
|
|
|
SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Pack);
|
|
|
|
}
|
|
|
|
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
TemplateArgument ForgetPartiallySubstitutedPack() {
|
|
|
|
TemplateArgument Result;
|
|
|
|
if (NamedDecl *PartialPack
|
|
|
|
= SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
|
|
|
|
MultiLevelTemplateArgumentList &TemplateArgs
|
|
|
|
= const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
|
|
|
|
unsigned Depth, Index;
|
2014-03-02 21:01:17 +08:00
|
|
|
std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
if (TemplateArgs.hasTemplateArgument(Depth, Index)) {
|
|
|
|
Result = TemplateArgs(Depth, Index);
|
|
|
|
TemplateArgs.setArgument(Depth, Index, TemplateArgument());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RememberPartiallySubstitutedPack(TemplateArgument Arg) {
|
|
|
|
if (Arg.isNull())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (NamedDecl *PartialPack
|
|
|
|
= SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
|
|
|
|
MultiLevelTemplateArgumentList &TemplateArgs
|
|
|
|
= const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
|
|
|
|
unsigned Depth, Index;
|
2014-03-02 21:01:17 +08:00
|
|
|
std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
TemplateArgs.setArgument(Depth, Index, Arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-05 00:50:30 +08:00
|
|
|
/// \brief Transform the given declaration by instantiating a reference to
|
|
|
|
/// this declaration.
|
2010-03-01 23:56:25 +08:00
|
|
|
Decl *TransformDecl(SourceLocation Loc, Decl *D);
|
2009-08-11 13:31:07 +08:00
|
|
|
|
2012-02-14 06:00:16 +08:00
|
|
|
void transformAttrs(Decl *Old, Decl *New) {
|
|
|
|
SemaRef.InstantiateAttrs(TemplateArgs, Old, New);
|
|
|
|
}
|
|
|
|
|
|
|
|
void transformedLocalDecl(Decl *Old, Decl *New) {
|
2015-04-28 05:27:54 +08:00
|
|
|
// If we've instantiated the call operator of a lambda or the call
|
|
|
|
// operator template of a generic lambda, update the "instantiation of"
|
|
|
|
// information.
|
|
|
|
auto *NewMD = dyn_cast<CXXMethodDecl>(New);
|
|
|
|
if (NewMD && isLambdaCallOperator(NewMD)) {
|
|
|
|
auto *OldMD = dyn_cast<CXXMethodDecl>(Old);
|
|
|
|
if (auto *NewTD = NewMD->getDescribedFunctionTemplate())
|
|
|
|
NewTD->setInstantiatedFromMemberTemplate(
|
|
|
|
OldMD->getDescribedFunctionTemplate());
|
|
|
|
else
|
|
|
|
NewMD->setInstantiationOfMemberFunction(OldMD,
|
|
|
|
TSK_ImplicitInstantiation);
|
|
|
|
}
|
|
|
|
|
2012-02-14 06:00:16 +08:00
|
|
|
SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
|
2016-03-24 04:07:07 +08:00
|
|
|
|
|
|
|
// We recreated a local declaration, but not by instantiating it. There
|
|
|
|
// may be pending dependent diagnostics to produce.
|
|
|
|
if (auto *DC = dyn_cast<DeclContext>(Old))
|
|
|
|
SemaRef.PerformDependentDiagnostics(DC, TemplateArgs);
|
2012-02-14 06:00:16 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
/// \brief Transform the definition of the given declaration by
|
2009-08-20 15:17:43 +08:00
|
|
|
/// instantiating it.
|
2010-03-02 01:25:41 +08:00
|
|
|
Decl *TransformDefinition(SourceLocation Loc, Decl *D);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-09-13 01:01:48 +08:00
|
|
|
/// \brief Transform the first qualifier within a scope by instantiating the
|
2009-10-20 13:58:46 +08:00
|
|
|
/// declaration.
|
|
|
|
NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
|
|
|
|
|
2009-08-20 15:17:43 +08:00
|
|
|
/// \brief Rebuild the exception declaration and register the declaration
|
|
|
|
/// as an instantiated local.
|
2010-09-10 01:09:21 +08:00
|
|
|
VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *Declarator,
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation StartLoc,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
IdentifierInfo *Name);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-04-27 01:57:08 +08:00
|
|
|
/// \brief Rebuild the Objective-C exception declaration and register the
|
|
|
|
/// declaration as an instantiated local.
|
|
|
|
VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
|
|
|
|
TypeSourceInfo *TSInfo, QualType T);
|
|
|
|
|
2009-09-11 12:59:25 +08:00
|
|
|
/// \brief Check for tag mismatches when instantiating an
|
|
|
|
/// elaborated type.
|
2010-11-05 03:04:38 +08:00
|
|
|
QualType RebuildElaboratedType(SourceLocation KeywordLoc,
|
|
|
|
ElaboratedTypeKeyword Keyword,
|
2011-03-02 02:12:44 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc,
|
|
|
|
QualType T);
|
2009-09-11 12:59:25 +08:00
|
|
|
|
2014-05-26 14:22:03 +08:00
|
|
|
TemplateName
|
|
|
|
TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
QualType ObjectType = QualType(),
|
|
|
|
NamedDecl *FirstQualifierInScope = nullptr);
|
2011-03-03 02:07:45 +08:00
|
|
|
|
2014-10-13 04:46:07 +08:00
|
|
|
const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult TransformPredefinedExpr(PredefinedExpr *E);
|
|
|
|
ExprResult TransformDeclRefExpr(DeclRefExpr *E);
|
|
|
|
ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
|
2012-09-12 08:56:43 +08:00
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
|
2010-12-24 08:15:10 +08:00
|
|
|
NonTypeTemplateParmDecl *D);
|
2011-01-15 09:15:58 +08:00
|
|
|
ExprResult TransformSubstNonTypeTemplateParmPackExpr(
|
|
|
|
SubstNonTypeTemplateParmPackExpr *E);
|
2012-09-12 08:56:43 +08:00
|
|
|
|
|
|
|
/// \brief Rebuild a DeclRefExpr for a ParmVarDecl reference.
|
|
|
|
ExprResult RebuildParmVarDeclRefExpr(ParmVarDecl *PD, SourceLocation Loc);
|
|
|
|
|
|
|
|
/// \brief Transform a reference to a function parameter pack.
|
|
|
|
ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E,
|
|
|
|
ParmVarDecl *PD);
|
|
|
|
|
|
|
|
/// \brief Transform a FunctionParmPackExpr which was built when we couldn't
|
|
|
|
/// expand a function parameter pack reference which refers to an expanded
|
|
|
|
/// pack.
|
|
|
|
ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
|
|
|
|
|
Revert r217995 and follow-ups:
r218053: Use exceptions() instead of getNumExceptions()/getExceptionType() to avoid
r218011: Work around MSVC parser bug by putting redundant braces around the body of
r217997: Skip parens when detecting whether we're instantiating a function declaration.
r217995: Instantiate exception specifications when instantiating function types (other
The Windows build was broken for 16 hours and no one had any good ideas of how to
fix it. Reverting for now to make the builders green. See the cfe-commits thread [1] for
more info.
This was the build error (from [2]):
C:\bb-win7\ninja-clang-i686-msc17-R\llvm-project\clang\lib\Sema\SemaTemplateInstantiate.cpp(1590) : error C2668: '`anonymous-namespace'::TemplateInstantiator::TransformFunctionProtoType' : ambiguous call to overloaded function
C:\bb-win7\ninja-clang-i686-msc17-R\llvm-project\clang\lib\Sema\SemaTemplateInstantiate.cpp(1313): could be 'clang::QualType `anonymous-namespace'::TemplateInstantiator::TransformFunctionProtoType<clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>>(clang::TypeLocBuilder &,clang::FunctionProtoTypeLoc,clang::CXXRecordDecl *,unsigned int,Fn)'
with
[
Fn=clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>
]
c:\bb-win7\ninja-clang-i686-msc17-r\llvm-project\clang\lib\sema\TreeTransform.h(4532): or 'clang::QualType clang::TreeTransform<Derived>::TransformFunctionProtoType<clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>>(clang::TypeLocBuilder &,clang::FunctionProtoTypeLoc,clang::CXXRecordDecl *,unsigned int,Fn)'
with
[
Derived=`anonymous-namespace'::TemplateInstantiator,
Fn=clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>
]
while trying to match the argument list '(clang::TypeLocBuilder, clang::FunctionProtoTypeLoc, clang::CXXRecordDecl *, unsigned int, clang::Sema::SubstFunctionDeclType::<lambda_756edcbe7bd5c7584849a6e3a1491735>)'
1. http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20140915/115011.html
2. http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/10515/steps/build_clang_tools_1/logs/stdio
llvm-svn: 218058
2014-09-19 00:01:32 +08:00
|
|
|
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
|
2014-11-12 10:00:47 +08:00
|
|
|
FunctionProtoTypeLoc TL) {
|
|
|
|
// Call the base version; it will forward to our overridden version below.
|
|
|
|
return inherited::TransformFunctionProtoType(TLB, TL);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Fn>
|
2012-04-16 15:05:22 +08:00
|
|
|
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
|
|
|
|
FunctionProtoTypeLoc TL,
|
|
|
|
CXXRecordDecl *ThisContext,
|
2014-11-12 10:00:47 +08:00
|
|
|
unsigned ThisTypeQuals,
|
|
|
|
Fn TransformExceptionSpec);
|
2012-04-16 15:05:22 +08:00
|
|
|
|
2011-01-15 06:40:04 +08:00
|
|
|
ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
|
2011-05-02 06:35:37 +08:00
|
|
|
int indexAdjustment,
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> NumExpansions,
|
2012-01-26 00:15:54 +08:00
|
|
|
bool ExpectParameterPack);
|
2010-03-11 17:03:00 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
/// \brief Transforms a template type parameter type by performing
|
2009-08-05 00:50:30 +08:00
|
|
|
/// substitution of the corresponding template type argument.
|
2009-10-21 08:40:46 +08:00
|
|
|
QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
|
2010-11-12 16:19:04 +08:00
|
|
|
TemplateTypeParmTypeLoc TL);
|
2010-07-07 03:51:49 +08:00
|
|
|
|
2011-01-14 10:55:32 +08:00
|
|
|
/// \brief Transforms an already-substituted template type parameter pack
|
|
|
|
/// into either itself (if we aren't substituting into its pack expansion)
|
|
|
|
/// or the appropriate substituted argument.
|
|
|
|
QualType TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
|
|
|
|
SubstTemplateTypeParmPackTypeLoc TL);
|
|
|
|
|
2012-07-25 11:56:55 +08:00
|
|
|
ExprResult TransformLambdaExpr(LambdaExpr *E) {
|
|
|
|
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
|
|
|
|
return TreeTransform<TemplateInstantiator>::TransformLambdaExpr(E);
|
|
|
|
}
|
|
|
|
|
2014-03-03 02:46:05 +08:00
|
|
|
TemplateParameterList *TransformTemplateParameterList(
|
2013-10-23 14:44:28 +08:00
|
|
|
TemplateParameterList *OrigTPL) {
|
|
|
|
if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
|
|
|
|
|
|
|
|
DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
|
|
|
|
TemplateDeclInstantiator DeclInstantiator(getSema(),
|
|
|
|
/* DeclContext *Owner */ Owner, TemplateArgs);
|
|
|
|
return DeclInstantiator.SubstTemplateParams(OrigTPL);
|
2012-07-25 11:56:55 +08:00
|
|
|
}
|
2011-07-15 13:09:51 +08:00
|
|
|
private:
|
|
|
|
ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm,
|
|
|
|
SourceLocation loc,
|
2012-07-09 11:07:20 +08:00
|
|
|
TemplateArgument arg);
|
2009-05-14 02:28:20 +08:00
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2009-02-28 03:31:52 +08:00
|
|
|
|
2010-05-08 07:12:07 +08:00
|
|
|
bool TemplateInstantiator::AlreadyTransformed(QualType T) {
|
|
|
|
if (T.isNull())
|
|
|
|
return true;
|
|
|
|
|
2011-07-01 09:22:09 +08:00
|
|
|
if (T->isInstantiationDependentType() || T->isVariablyModifiedType())
|
2010-05-08 07:12:07 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
getSema().MarkDeclarationsReferencedInType(Loc, T);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-07-20 03:40:38 +08:00
|
|
|
static TemplateArgument
|
|
|
|
getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {
|
|
|
|
assert(S.ArgumentPackSubstitutionIndex >= 0);
|
|
|
|
assert(S.ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
|
|
|
|
Arg = Arg.pack_begin()[S.ArgumentPackSubstitutionIndex];
|
|
|
|
if (Arg.isPackExpansion())
|
|
|
|
Arg = Arg.getPackExpansionPattern();
|
|
|
|
return Arg;
|
|
|
|
}
|
|
|
|
|
2010-03-01 23:56:25 +08:00
|
|
|
Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
|
2009-09-04 05:38:09 +08:00
|
|
|
if (!D)
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-09-04 05:38:09 +08:00
|
|
|
if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
|
2009-08-29 04:31:08 +08:00
|
|
|
if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
|
2010-02-06 03:54:12 +08:00
|
|
|
// If the corresponding template argument is NULL or non-existent, it's
|
|
|
|
// because we are performing instantiation from explicitly-specified
|
|
|
|
// template arguments in a function template, but there were some
|
|
|
|
// arguments left unspecified.
|
|
|
|
if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
|
|
|
|
TTP->getPosition()))
|
|
|
|
return D;
|
|
|
|
|
2011-01-05 23:48:55 +08:00
|
|
|
TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
|
|
|
|
|
|
|
|
if (TTP->isParameterPack()) {
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Pack &&
|
|
|
|
"Missing argument pack");
|
2013-07-20 03:40:38 +08:00
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
2011-01-05 23:48:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TemplateName Template = Arg.getAsTemplate();
|
2009-11-11 09:00:40 +08:00
|
|
|
assert(!Template.isNull() && Template.getAsTemplateDecl() &&
|
2009-08-29 04:31:08 +08:00
|
|
|
"Wrong kind of template template argument");
|
2009-11-11 09:00:40 +08:00
|
|
|
return Template.getAsTemplateDecl();
|
2009-08-29 04:31:08 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
// Fall through to find the instantiated declaration for this template
|
|
|
|
// template parameter.
|
2009-08-06 14:41:21 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-03-01 23:56:25 +08:00
|
|
|
return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), TemplateArgs);
|
2009-02-28 03:31:52 +08:00
|
|
|
}
|
|
|
|
|
2010-03-02 01:25:41 +08:00
|
|
|
Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {
|
2009-08-26 06:02:44 +08:00
|
|
|
Decl *Inst = getSema().SubstDecl(D, getSema().CurContext, TemplateArgs);
|
2009-08-20 15:17:43 +08:00
|
|
|
if (!Inst)
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-20 15:17:43 +08:00
|
|
|
getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);
|
|
|
|
return Inst;
|
|
|
|
}
|
|
|
|
|
2009-10-20 13:58:46 +08:00
|
|
|
NamedDecl *
|
|
|
|
TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
|
|
|
|
SourceLocation Loc) {
|
|
|
|
// If the first part of the nested-name-specifier was a template type
|
|
|
|
// parameter, instantiate that type parameter down to a tag type.
|
|
|
|
if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null<TemplateTypeParmDecl>(D)) {
|
|
|
|
const TemplateTypeParmType *TTP
|
|
|
|
= cast<TemplateTypeParmType>(getSema().Context.getTypeDeclType(TTPD));
|
2010-12-21 06:48:17 +08:00
|
|
|
|
2009-10-20 13:58:46 +08:00
|
|
|
if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
|
2010-12-21 06:48:17 +08:00
|
|
|
// FIXME: This needs testing w/ member access expressions.
|
|
|
|
TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getIndex());
|
|
|
|
|
|
|
|
if (TTP->isParameterPack()) {
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Pack &&
|
|
|
|
"Missing argument pack");
|
|
|
|
|
2011-01-15 07:41:42 +08:00
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1)
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
|
|
|
|
2013-07-20 03:40:38 +08:00
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
2010-12-21 06:48:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
QualType T = Arg.getAsType();
|
2009-10-20 13:58:46 +08:00
|
|
|
if (T.isNull())
|
2010-03-01 23:56:25 +08:00
|
|
|
return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
|
2009-10-20 13:58:46 +08:00
|
|
|
|
|
|
|
if (const TagType *Tag = T->getAs<TagType>())
|
|
|
|
return Tag->getDecl();
|
|
|
|
|
|
|
|
// The resulting type is not a tag; complain.
|
|
|
|
getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2009-10-20 13:58:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-01 23:56:25 +08:00
|
|
|
return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
|
2009-10-20 13:58:46 +08:00
|
|
|
}
|
|
|
|
|
2009-08-20 15:17:43 +08:00
|
|
|
VarDecl *
|
|
|
|
TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *Declarator,
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation StartLoc,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
IdentifierInfo *Name) {
|
2010-09-10 01:09:21 +08:00
|
|
|
VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, Declarator,
|
2011-03-08 16:55:46 +08:00
|
|
|
StartLoc, NameLoc, Name);
|
2010-04-27 01:57:08 +08:00
|
|
|
if (Var)
|
|
|
|
getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
|
|
|
|
return Var;
|
|
|
|
}
|
|
|
|
|
|
|
|
VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
|
|
|
|
TypeSourceInfo *TSInfo,
|
|
|
|
QualType T) {
|
|
|
|
VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
|
|
|
|
if (Var)
|
2009-08-20 15:17:43 +08:00
|
|
|
getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
|
|
|
|
return Var;
|
|
|
|
}
|
|
|
|
|
2009-09-11 12:59:25 +08:00
|
|
|
QualType
|
2010-11-05 03:04:38 +08:00
|
|
|
TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
|
|
|
|
ElaboratedTypeKeyword Keyword,
|
2011-03-02 02:12:44 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc,
|
2010-05-12 05:36:43 +08:00
|
|
|
QualType T) {
|
2009-09-11 12:59:25 +08:00
|
|
|
if (const TagType *TT = T->getAs<TagType>()) {
|
|
|
|
TagDecl* TD = TT->getDecl();
|
|
|
|
|
2010-11-05 03:04:38 +08:00
|
|
|
SourceLocation TagLocation = KeywordLoc;
|
2009-09-11 12:59:25 +08:00
|
|
|
|
|
|
|
IdentifierInfo *Id = TD->getIdentifier();
|
|
|
|
|
|
|
|
// TODO: should we even warn on struct/class mismatches for this? Seems
|
|
|
|
// like it's likely to produce a lot of spurious errors.
|
2012-08-17 08:12:27 +08:00
|
|
|
if (Id && Keyword != ETK_None && Keyword != ETK_Typename) {
|
2010-05-12 05:36:43 +08:00
|
|
|
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
|
2011-06-10 11:11:26 +08:00
|
|
|
if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, /*isDefinition*/false,
|
2015-07-11 07:05:47 +08:00
|
|
|
TagLocation, Id)) {
|
2010-05-12 05:36:43 +08:00
|
|
|
SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
|
|
|
|
<< Id
|
|
|
|
<< FixItHint::CreateReplacement(SourceRange(TagLocation),
|
|
|
|
TD->getKindName());
|
|
|
|
SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
|
|
|
|
}
|
2009-09-11 12:59:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-05 03:04:38 +08:00
|
|
|
return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(KeywordLoc,
|
|
|
|
Keyword,
|
2011-03-02 02:12:44 +08:00
|
|
|
QualifierLoc,
|
|
|
|
T);
|
2009-09-11 12:59:25 +08:00
|
|
|
}
|
|
|
|
|
2011-03-03 02:07:45 +08:00
|
|
|
TemplateName TemplateInstantiator::TransformTemplateName(CXXScopeSpec &SS,
|
|
|
|
TemplateName Name,
|
2014-07-28 08:02:09 +08:00
|
|
|
SourceLocation NameLoc,
|
2011-03-03 02:07:45 +08:00
|
|
|
QualType ObjectType,
|
|
|
|
NamedDecl *FirstQualifierInScope) {
|
|
|
|
if (TemplateTemplateParmDecl *TTP
|
|
|
|
= dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
|
|
|
|
if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
|
|
|
|
// If the corresponding template argument is NULL or non-existent, it's
|
|
|
|
// because we are performing instantiation from explicitly-specified
|
|
|
|
// template arguments in a function template, but there were some
|
|
|
|
// arguments left unspecified.
|
|
|
|
if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
|
|
|
|
TTP->getPosition()))
|
|
|
|
return Name;
|
|
|
|
|
|
|
|
TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
|
|
|
|
|
|
|
|
if (TTP->isParameterPack()) {
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Pack &&
|
|
|
|
"Missing argument pack");
|
|
|
|
|
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1) {
|
|
|
|
// We have the template argument pack to substitute, but we're not
|
|
|
|
// actually expanding the enclosing pack expansion yet. So, just
|
|
|
|
// keep the entire argument pack.
|
|
|
|
return getSema().Context.getSubstTemplateTemplateParmPack(TTP, Arg);
|
|
|
|
}
|
2013-07-20 03:40:38 +08:00
|
|
|
|
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
2011-03-03 02:07:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TemplateName Template = Arg.getAsTemplate();
|
2011-05-06 05:57:07 +08:00
|
|
|
assert(!Template.isNull() && "Null template template argument");
|
2011-06-30 16:33:18 +08:00
|
|
|
|
2011-03-06 04:06:51 +08:00
|
|
|
// We don't ever want to substitute for a qualified template name, since
|
|
|
|
// the qualifier is handled separately. So, look through the qualified
|
|
|
|
// template name to its underlying declaration.
|
|
|
|
if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
|
|
|
|
Template = TemplateName(QTN->getTemplateDecl());
|
2011-06-30 16:33:18 +08:00
|
|
|
|
|
|
|
Template = getSema().Context.getSubstTemplateTemplateParm(TTP, Template);
|
2011-03-03 02:07:45 +08:00
|
|
|
return Template;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SubstTemplateTemplateParmPackStorage *SubstPack
|
|
|
|
= Name.getAsSubstTemplateTemplateParmPack()) {
|
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1)
|
|
|
|
return Name;
|
|
|
|
|
2013-07-20 03:40:38 +08:00
|
|
|
TemplateArgument Arg = SubstPack->getArgumentPack();
|
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
|
|
|
return Arg.getAsTemplate();
|
2011-03-03 02:07:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
|
|
|
|
FirstQualifierInScope);
|
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult
|
2009-12-08 17:21:05 +08:00
|
|
|
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
|
2009-09-11 09:22:35 +08:00
|
|
|
if (!E->isTypeDependent())
|
2014-05-29 22:05:12 +08:00
|
|
|
return E;
|
2009-09-11 09:22:35 +08:00
|
|
|
|
2013-09-16 21:57:27 +08:00
|
|
|
return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
|
2009-09-11 09:22:35 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult
|
2010-02-06 16:42:39 +08:00
|
|
|
TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
|
2010-02-09 07:41:45 +08:00
|
|
|
NonTypeTemplateParmDecl *NTTP) {
|
2010-02-06 16:42:39 +08:00
|
|
|
// If the corresponding template argument is NULL or non-existent, it's
|
|
|
|
// because we are performing instantiation from explicitly-specified
|
|
|
|
// template arguments in a function template, but there were some
|
|
|
|
// arguments left unspecified.
|
|
|
|
if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
|
|
|
|
NTTP->getPosition()))
|
2014-05-29 22:05:12 +08:00
|
|
|
return E;
|
2009-11-01 01:21:17 +08:00
|
|
|
|
2010-12-24 08:15:10 +08:00
|
|
|
TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
|
|
|
|
if (NTTP->isParameterPack()) {
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Pack &&
|
|
|
|
"Missing argument pack");
|
|
|
|
|
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1) {
|
2011-01-15 09:15:58 +08:00
|
|
|
// We have an argument pack, but we can't select a particular argument
|
|
|
|
// out of it yet. Therefore, we'll build an expression to hold on to that
|
|
|
|
// argument pack.
|
|
|
|
QualType TargetType = SemaRef.SubstType(NTTP->getType(), TemplateArgs,
|
|
|
|
E->getLocation(),
|
|
|
|
NTTP->getDeclName());
|
|
|
|
if (TargetType.isNull())
|
|
|
|
return ExprError();
|
|
|
|
|
|
|
|
return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(TargetType,
|
|
|
|
NTTP,
|
|
|
|
E->getLocation(),
|
|
|
|
Arg);
|
2010-12-24 08:15:10 +08:00
|
|
|
}
|
|
|
|
|
2013-07-20 03:40:38 +08:00
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
2010-12-24 08:15:10 +08:00
|
|
|
}
|
2009-11-01 01:21:17 +08:00
|
|
|
|
2011-07-15 13:09:51 +08:00
|
|
|
return transformNonTypeTemplateParmRef(NTTP, E->getLocation(), Arg);
|
|
|
|
}
|
|
|
|
|
2014-10-13 04:46:07 +08:00
|
|
|
const LoopHintAttr *
|
|
|
|
TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) {
|
|
|
|
Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get();
|
|
|
|
|
|
|
|
if (TransformedExpr == LH->getValue())
|
|
|
|
return LH;
|
|
|
|
|
|
|
|
// Generate error if there is a problem with the value.
|
|
|
|
if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation()))
|
|
|
|
return LH;
|
|
|
|
|
|
|
|
// Create new LoopHintValueAttr with integral expression in place of the
|
|
|
|
// non-type template parameter.
|
|
|
|
return LoopHintAttr::CreateImplicit(
|
|
|
|
getSema().Context, LH->getSemanticSpelling(), LH->getOption(),
|
|
|
|
LH->getState(), TransformedExpr, LH->getRange());
|
|
|
|
}
|
|
|
|
|
2011-07-15 13:09:51 +08:00
|
|
|
ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
|
|
|
|
NonTypeTemplateParmDecl *parm,
|
|
|
|
SourceLocation loc,
|
2012-07-09 11:07:20 +08:00
|
|
|
TemplateArgument arg) {
|
2011-07-15 13:09:51 +08:00
|
|
|
ExprResult result;
|
|
|
|
QualType type;
|
|
|
|
|
2010-02-06 16:42:39 +08:00
|
|
|
// The template argument itself might be an expression, in which
|
|
|
|
// case we just return that expression.
|
2011-07-15 13:09:51 +08:00
|
|
|
if (arg.getKind() == TemplateArgument::Expression) {
|
|
|
|
Expr *argExpr = arg.getAsExpr();
|
2014-05-29 22:05:12 +08:00
|
|
|
result = argExpr;
|
2011-07-15 13:09:51 +08:00
|
|
|
type = argExpr->getType();
|
2009-11-01 01:21:17 +08:00
|
|
|
|
2012-09-26 10:36:12 +08:00
|
|
|
} else if (arg.getKind() == TemplateArgument::Declaration ||
|
|
|
|
arg.getKind() == TemplateArgument::NullPtr) {
|
2012-04-07 06:40:38 +08:00
|
|
|
ValueDecl *VD;
|
2012-09-26 10:36:12 +08:00
|
|
|
if (arg.getKind() == TemplateArgument::Declaration) {
|
|
|
|
VD = cast<ValueDecl>(arg.getAsDecl());
|
2012-04-07 06:40:38 +08:00
|
|
|
|
|
|
|
// Find the instantiation of the template argument. This is
|
|
|
|
// required for nested templates.
|
|
|
|
VD = cast_or_null<ValueDecl>(
|
|
|
|
getSema().FindInstantiatedDecl(loc, VD, TemplateArgs));
|
|
|
|
if (!VD)
|
|
|
|
return ExprError();
|
|
|
|
} else {
|
|
|
|
// Propagate NULL template argument.
|
2014-05-26 14:22:03 +08:00
|
|
|
VD = nullptr;
|
2012-04-07 06:40:38 +08:00
|
|
|
}
|
|
|
|
|
2010-02-06 18:23:53 +08:00
|
|
|
// Derive the type we want the substituted decl to have. This had
|
|
|
|
// better be non-dependent, or these checks will have serious problems.
|
2011-07-15 13:09:51 +08:00
|
|
|
if (parm->isExpandedParameterPack()) {
|
|
|
|
type = parm->getExpansionType(SemaRef.ArgumentPackSubstitutionIndex);
|
|
|
|
} else if (parm->isParameterPack() &&
|
|
|
|
isa<PackExpansionType>(parm->getType())) {
|
|
|
|
type = SemaRef.SubstType(
|
|
|
|
cast<PackExpansionType>(parm->getType())->getPattern(),
|
|
|
|
TemplateArgs, loc, parm->getDeclName());
|
|
|
|
} else {
|
|
|
|
type = SemaRef.SubstType(parm->getType(), TemplateArgs,
|
|
|
|
loc, parm->getDeclName());
|
|
|
|
}
|
|
|
|
assert(!type.isNull() && "type substitution failed for param type");
|
|
|
|
assert(!type->isDependentType() && "param type still dependent");
|
|
|
|
result = SemaRef.BuildExpressionFromDeclTemplateArgument(arg, type, loc);
|
|
|
|
|
|
|
|
if (!result.isInvalid()) type = result.get()->getType();
|
|
|
|
} else {
|
|
|
|
result = SemaRef.BuildExpressionFromIntegralTemplateArgument(arg, loc);
|
|
|
|
|
|
|
|
// Note that this type can be different from the type of 'result',
|
|
|
|
// e.g. if it's an enum type.
|
|
|
|
type = arg.getIntegralType();
|
2010-02-06 16:42:39 +08:00
|
|
|
}
|
2011-07-15 13:09:51 +08:00
|
|
|
if (result.isInvalid()) return ExprError();
|
2010-02-06 16:42:39 +08:00
|
|
|
|
2014-05-29 18:55:11 +08:00
|
|
|
Expr *resultExpr = result.get();
|
2014-05-29 22:05:12 +08:00
|
|
|
return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
|
|
|
|
type, resultExpr->getValueKind(), loc, parm, resultExpr);
|
2010-02-06 16:42:39 +08:00
|
|
|
}
|
|
|
|
|
2011-01-15 09:15:58 +08:00
|
|
|
ExprResult
|
|
|
|
TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
|
|
|
|
SubstNonTypeTemplateParmPackExpr *E) {
|
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1) {
|
|
|
|
// We aren't expanding the parameter pack, so just return ourselves.
|
2014-05-29 22:05:12 +08:00
|
|
|
return E;
|
2011-01-15 09:15:58 +08:00
|
|
|
}
|
2013-07-20 03:40:38 +08:00
|
|
|
|
|
|
|
TemplateArgument Arg = E->getArgumentPack();
|
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
2011-07-15 13:09:51 +08:00
|
|
|
return transformNonTypeTemplateParmRef(E->getParameterPack(),
|
|
|
|
E->getParameterPackLocation(),
|
|
|
|
Arg);
|
2011-01-15 09:15:58 +08:00
|
|
|
}
|
2010-02-06 16:42:39 +08:00
|
|
|
|
2012-09-12 08:56:43 +08:00
|
|
|
ExprResult
|
|
|
|
TemplateInstantiator::RebuildParmVarDeclRefExpr(ParmVarDecl *PD,
|
|
|
|
SourceLocation Loc) {
|
|
|
|
DeclarationNameInfo NameInfo(PD->getDeclName(), Loc);
|
|
|
|
return getSema().BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo, PD);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExprResult
|
|
|
|
TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
|
|
|
|
if (getSema().ArgumentPackSubstitutionIndex != -1) {
|
|
|
|
// We can expand this parameter pack now.
|
|
|
|
ParmVarDecl *D = E->getExpansion(getSema().ArgumentPackSubstitutionIndex);
|
|
|
|
ValueDecl *VD = cast_or_null<ValueDecl>(TransformDecl(E->getExprLoc(), D));
|
|
|
|
if (!VD)
|
|
|
|
return ExprError();
|
|
|
|
return RebuildParmVarDeclRefExpr(cast<ParmVarDecl>(VD), E->getExprLoc());
|
|
|
|
}
|
|
|
|
|
|
|
|
QualType T = TransformType(E->getType());
|
|
|
|
if (T.isNull())
|
|
|
|
return ExprError();
|
|
|
|
|
|
|
|
// Transform each of the parameter expansions into the corresponding
|
|
|
|
// parameters in the instantiation of the function decl.
|
2015-09-30 22:04:23 +08:00
|
|
|
SmallVector<ParmVarDecl *, 8> Parms;
|
2012-09-12 08:56:43 +08:00
|
|
|
Parms.reserve(E->getNumExpansions());
|
|
|
|
for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
|
|
|
|
I != End; ++I) {
|
|
|
|
ParmVarDecl *D =
|
|
|
|
cast_or_null<ParmVarDecl>(TransformDecl(E->getExprLoc(), *I));
|
|
|
|
if (!D)
|
|
|
|
return ExprError();
|
|
|
|
Parms.push_back(D);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FunctionParmPackExpr::Create(getSema().Context, T,
|
|
|
|
E->getParameterPack(),
|
|
|
|
E->getParameterPackLocation(), Parms);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExprResult
|
|
|
|
TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
|
|
|
|
ParmVarDecl *PD) {
|
|
|
|
typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
|
|
|
|
llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found
|
|
|
|
= getSema().CurrentInstantiationScope->findInstantiationOf(PD);
|
|
|
|
assert(Found && "no instantiation for parameter pack");
|
|
|
|
|
|
|
|
Decl *TransformedDecl;
|
|
|
|
if (DeclArgumentPack *Pack = Found->dyn_cast<DeclArgumentPack *>()) {
|
2014-07-28 08:02:09 +08:00
|
|
|
// If this is a reference to a function parameter pack which we can
|
|
|
|
// substitute but can't yet expand, build a FunctionParmPackExpr for it.
|
2012-09-12 08:56:43 +08:00
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1) {
|
|
|
|
QualType T = TransformType(E->getType());
|
|
|
|
if (T.isNull())
|
|
|
|
return ExprError();
|
|
|
|
return FunctionParmPackExpr::Create(getSema().Context, T, PD,
|
|
|
|
E->getExprLoc(), *Pack);
|
|
|
|
}
|
|
|
|
|
|
|
|
TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];
|
|
|
|
} else {
|
|
|
|
TransformedDecl = Found->get<Decl*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
// We have either an unexpanded pack or a specific expansion.
|
|
|
|
return RebuildParmVarDeclRefExpr(cast<ParmVarDecl>(TransformedDecl),
|
|
|
|
E->getExprLoc());
|
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult
|
2010-02-06 16:42:39 +08:00
|
|
|
TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
|
|
|
|
NamedDecl *D = E->getDecl();
|
2012-09-12 08:56:43 +08:00
|
|
|
|
|
|
|
// Handle references to non-type template parameters and non-type template
|
|
|
|
// parameter packs.
|
2010-02-06 16:42:39 +08:00
|
|
|
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
|
|
|
|
if (NTTP->getDepth() < TemplateArgs.getNumLevels())
|
|
|
|
return TransformTemplateParmRefExpr(E, NTTP);
|
2009-11-01 01:21:17 +08:00
|
|
|
|
|
|
|
// We have a non-type template parameter that isn't fully substituted;
|
|
|
|
// FindInstantiatedDecl will find it in the local instantiation scope.
|
2009-08-11 13:31:07 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-09-12 08:56:43 +08:00
|
|
|
// Handle references to function parameter packs.
|
|
|
|
if (ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
|
|
|
|
if (PD->isParameterPack())
|
|
|
|
return TransformFunctionParmPackRefExpr(E, PD);
|
|
|
|
|
2009-12-08 17:21:05 +08:00
|
|
|
return TreeTransform<TemplateInstantiator>::TransformDeclRefExpr(E);
|
2009-08-11 13:31:07 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
|
2009-12-08 17:21:05 +08:00
|
|
|
CXXDefaultArgExpr *E) {
|
2009-11-08 21:56:19 +08:00
|
|
|
assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
|
|
|
|
getDescribedFunctionTemplate() &&
|
|
|
|
"Default arg expressions are never formed in dependent cases.");
|
2009-12-24 07:03:06 +08:00
|
|
|
return SemaRef.BuildCXXDefaultArgExpr(E->getUsedLocation(),
|
|
|
|
cast<FunctionDecl>(E->getParam()->getDeclContext()),
|
|
|
|
E->getParam());
|
2009-11-08 21:56:19 +08:00
|
|
|
}
|
|
|
|
|
2014-11-12 10:00:47 +08:00
|
|
|
template<typename Fn>
|
2012-04-16 15:05:22 +08:00
|
|
|
QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
|
|
|
|
FunctionProtoTypeLoc TL,
|
|
|
|
CXXRecordDecl *ThisContext,
|
2014-11-12 10:00:47 +08:00
|
|
|
unsigned ThisTypeQuals,
|
|
|
|
Fn TransformExceptionSpec) {
|
2012-04-16 15:05:22 +08:00
|
|
|
// We need a local instantiation scope for this function prototype.
|
|
|
|
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
|
2014-11-12 10:00:47 +08:00
|
|
|
return inherited::TransformFunctionProtoType(
|
|
|
|
TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);
|
2012-04-16 15:05:22 +08:00
|
|
|
}
|
|
|
|
|
2010-03-11 17:03:00 +08:00
|
|
|
ParmVarDecl *
|
2011-01-15 06:40:04 +08:00
|
|
|
TemplateInstantiator::TransformFunctionTypeParam(ParmVarDecl *OldParm,
|
2011-05-02 06:35:37 +08:00
|
|
|
int indexAdjustment,
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> NumExpansions,
|
2012-01-26 00:15:54 +08:00
|
|
|
bool ExpectParameterPack) {
|
2011-05-02 06:35:37 +08:00
|
|
|
return SemaRef.SubstParmVarDecl(OldParm, TemplateArgs, indexAdjustment,
|
2012-01-26 00:15:54 +08:00
|
|
|
NumExpansions, ExpectParameterPack);
|
2010-03-11 17:03:00 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
QualType
|
2009-10-21 08:40:46 +08:00
|
|
|
TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
|
2010-11-12 16:19:04 +08:00
|
|
|
TemplateTypeParmTypeLoc TL) {
|
2011-01-19 14:33:43 +08:00
|
|
|
const TemplateTypeParmType *T = TL.getTypePtr();
|
2009-08-29 04:31:08 +08:00
|
|
|
if (T->getDepth() < TemplateArgs.getNumLevels()) {
|
2009-02-28 03:31:52 +08:00
|
|
|
// Replace the template type parameter with its corresponding
|
|
|
|
// template argument.
|
2009-09-09 23:08:12 +08:00
|
|
|
|
|
|
|
// If the corresponding template argument is NULL or doesn't exist, it's
|
|
|
|
// because we are performing instantiation from explicitly-specified
|
|
|
|
// template arguments in a function template class, but there were some
|
2009-07-01 08:28:38 +08:00
|
|
|
// arguments left unspecified.
|
2009-10-21 08:40:46 +08:00
|
|
|
if (!TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex())) {
|
|
|
|
TemplateTypeParmTypeLoc NewTL
|
|
|
|
= TLB.push<TemplateTypeParmTypeLoc>(TL.getType());
|
|
|
|
NewTL.setNameLoc(TL.getNameLoc());
|
|
|
|
return TL.getType();
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-12-21 06:05:00 +08:00
|
|
|
TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
|
|
|
|
|
|
|
|
if (T->isParameterPack()) {
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Pack &&
|
|
|
|
"Missing argument pack");
|
|
|
|
|
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1) {
|
2011-01-14 10:55:32 +08:00
|
|
|
// We have the template argument pack, but we're not expanding the
|
|
|
|
// enclosing pack expansion yet. Just save the template argument
|
|
|
|
// pack for later substitution.
|
|
|
|
QualType Result
|
|
|
|
= getSema().Context.getSubstTemplateTypeParmPackType(T, Arg);
|
|
|
|
SubstTemplateTypeParmPackTypeLoc NewTL
|
|
|
|
= TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
|
|
|
|
NewTL.setNameLoc(TL.getNameLoc());
|
|
|
|
return Result;
|
2010-12-21 06:05:00 +08:00
|
|
|
}
|
|
|
|
|
2013-07-20 03:40:38 +08:00
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
2010-12-21 06:05:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Type &&
|
2009-02-28 03:31:52 +08:00
|
|
|
"Template argument kind mismatch");
|
2009-08-29 04:31:08 +08:00
|
|
|
|
2010-12-21 06:05:00 +08:00
|
|
|
QualType Replacement = Arg.getAsType();
|
2009-10-18 17:09:24 +08:00
|
|
|
|
|
|
|
// TODO: only do this uniquing once, at the start of instantiation.
|
2009-10-21 08:40:46 +08:00
|
|
|
QualType Result
|
|
|
|
= getSema().Context.getSubstTemplateTypeParmType(T, Replacement);
|
|
|
|
SubstTemplateTypeParmTypeLoc NewTL
|
|
|
|
= TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
|
|
|
|
NewTL.setNameLoc(TL.getNameLoc());
|
|
|
|
return Result;
|
2009-09-09 23:08:12 +08:00
|
|
|
}
|
2009-02-28 03:31:52 +08:00
|
|
|
|
|
|
|
// The template type parameter comes from an inner template (e.g.,
|
|
|
|
// the template parameter list of a member template inside the
|
|
|
|
// template we are instantiating). Create a new template type
|
|
|
|
// parameter with the template "level" reduced by one.
|
2014-05-26 14:22:03 +08:00
|
|
|
TemplateTypeParmDecl *NewTTPDecl = nullptr;
|
Re-applies the patch first applied way back in r106099, with
accompanying fixes to make it work today.
The core of this patch is to provide a link from a TemplateTypeParmType
back to the TemplateTypeParmDecl node which declared it. This in turn
provides much more precise information about the type, where it came
from, and how it functions for AST consumers.
To make the patch work almost a year after its first attempt, it needed
serialization support, and it now retains the old getName() interface.
Finally, it requires us to not attempt to instantiate the type in an
unsupported friend decl -- specifically those coming from template
friend decls but which refer to a specific type through a dependent
name.
A cleaner representation of the last item would be to build
FriendTemplateDecl nodes for these, storing their template parameters
etc, and to perform proper instantation of them like any other template
declaration. They can still be flagged as unsupported for the purpose of
access checking, etc.
This passed an asserts-enabled bootstrap for me, and the reduced test
case mentioned in the original review thread no longer causes issues,
likely fixed at somewhere amidst the 24k revisions that have elapsed.
llvm-svn: 130628
2011-05-01 08:51:33 +08:00
|
|
|
if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
|
|
|
|
NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
|
|
|
|
TransformDecl(TL.getNameLoc(), OldTTPDecl));
|
|
|
|
|
2009-10-21 08:40:46 +08:00
|
|
|
QualType Result
|
|
|
|
= getSema().Context.getTemplateTypeParmType(T->getDepth()
|
|
|
|
- TemplateArgs.getNumLevels(),
|
|
|
|
T->getIndex(),
|
|
|
|
T->isParameterPack(),
|
Re-applies the patch first applied way back in r106099, with
accompanying fixes to make it work today.
The core of this patch is to provide a link from a TemplateTypeParmType
back to the TemplateTypeParmDecl node which declared it. This in turn
provides much more precise information about the type, where it came
from, and how it functions for AST consumers.
To make the patch work almost a year after its first attempt, it needed
serialization support, and it now retains the old getName() interface.
Finally, it requires us to not attempt to instantiate the type in an
unsupported friend decl -- specifically those coming from template
friend decls but which refer to a specific type through a dependent
name.
A cleaner representation of the last item would be to build
FriendTemplateDecl nodes for these, storing their template parameters
etc, and to perform proper instantation of them like any other template
declaration. They can still be flagged as unsupported for the purpose of
access checking, etc.
This passed an asserts-enabled bootstrap for me, and the reduced test
case mentioned in the original review thread no longer causes issues,
likely fixed at somewhere amidst the 24k revisions that have elapsed.
llvm-svn: 130628
2011-05-01 08:51:33 +08:00
|
|
|
NewTTPDecl);
|
2009-10-21 08:40:46 +08:00
|
|
|
TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
|
|
|
|
NewTL.setNameLoc(TL.getNameLoc());
|
|
|
|
return Result;
|
2011-01-14 10:55:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
QualType
|
|
|
|
TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
|
|
|
|
TypeLocBuilder &TLB,
|
|
|
|
SubstTemplateTypeParmPackTypeLoc TL) {
|
|
|
|
if (getSema().ArgumentPackSubstitutionIndex == -1) {
|
|
|
|
// We aren't expanding the parameter pack, so just return ourselves.
|
|
|
|
SubstTemplateTypeParmPackTypeLoc NewTL
|
|
|
|
= TLB.push<SubstTemplateTypeParmPackTypeLoc>(TL.getType());
|
|
|
|
NewTL.setNameLoc(TL.getNameLoc());
|
|
|
|
return TL.getType();
|
|
|
|
}
|
2013-07-20 03:40:38 +08:00
|
|
|
|
|
|
|
TemplateArgument Arg = TL.getTypePtr()->getArgumentPack();
|
|
|
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
|
|
|
QualType Result = Arg.getAsType();
|
|
|
|
|
2011-01-14 10:55:32 +08:00
|
|
|
Result = getSema().Context.getSubstTemplateTypeParmType(
|
|
|
|
TL.getTypePtr()->getReplacedParameter(),
|
|
|
|
Result);
|
|
|
|
SubstTemplateTypeParmTypeLoc NewTL
|
|
|
|
= TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
|
|
|
|
NewTL.setNameLoc(TL.getNameLoc());
|
|
|
|
return Result;
|
2009-02-28 08:25:32 +08:00
|
|
|
}
|
2009-02-28 03:31:52 +08:00
|
|
|
|
2009-08-26 06:02:44 +08:00
|
|
|
/// \brief Perform substitution on the type T with a given set of template
|
|
|
|
/// arguments.
|
2009-02-28 03:31:52 +08:00
|
|
|
///
|
|
|
|
/// This routine substitutes the given template arguments into the
|
|
|
|
/// type T and produces the instantiated type.
|
|
|
|
///
|
|
|
|
/// \param T the type into which the template arguments will be
|
|
|
|
/// substituted. If this type is not dependent, it will be returned
|
|
|
|
/// immediately.
|
|
|
|
///
|
2012-06-15 05:40:34 +08:00
|
|
|
/// \param Args the template arguments that will be
|
2009-02-28 03:31:52 +08:00
|
|
|
/// substituted for the top-level template parameters within T.
|
|
|
|
///
|
|
|
|
/// \param Loc the location in the source code where this substitution
|
|
|
|
/// is being performed. It will typically be the location of the
|
|
|
|
/// declarator (if we're instantiating the type of some declaration)
|
|
|
|
/// or the location of the type in the source code (if, e.g., we're
|
|
|
|
/// instantiating the type of a cast expression).
|
|
|
|
///
|
|
|
|
/// \param Entity the name of the entity associated with a declaration
|
|
|
|
/// being instantiated (if any). May be empty to indicate that there
|
|
|
|
/// is no such entity (if, e.g., this is a type that occurs as part of
|
|
|
|
/// a cast expression) or that the entity has no name (e.g., an
|
|
|
|
/// unnamed function parameter).
|
|
|
|
///
|
|
|
|
/// \returns If the instantiation succeeds, the instantiated
|
|
|
|
/// type. Otherwise, produces diagnostics and returns a NULL type.
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
|
2009-10-21 08:58:09 +08:00
|
|
|
const MultiLevelTemplateArgumentList &Args,
|
|
|
|
SourceLocation Loc,
|
|
|
|
DeclarationName Entity) {
|
|
|
|
assert(!ActiveTemplateInstantiations.empty() &&
|
|
|
|
"Cannot perform an instantiation without some context on the "
|
|
|
|
"instantiation stack");
|
|
|
|
|
2011-07-01 09:22:09 +08:00
|
|
|
if (!T->getType()->isInstantiationDependentType() &&
|
2010-05-25 01:22:01 +08:00
|
|
|
!T->getType()->isVariablyModifiedType())
|
2009-10-21 08:58:09 +08:00
|
|
|
return T;
|
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
|
|
|
|
return Instantiator.TransformType(T);
|
|
|
|
}
|
|
|
|
|
2011-01-06 07:12:31 +08:00
|
|
|
TypeSourceInfo *Sema::SubstType(TypeLoc TL,
|
|
|
|
const MultiLevelTemplateArgumentList &Args,
|
|
|
|
SourceLocation Loc,
|
|
|
|
DeclarationName Entity) {
|
|
|
|
assert(!ActiveTemplateInstantiations.empty() &&
|
|
|
|
"Cannot perform an instantiation without some context on the "
|
|
|
|
"instantiation stack");
|
|
|
|
|
|
|
|
if (TL.getType().isNull())
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2011-01-06 07:12:31 +08:00
|
|
|
|
2011-07-01 09:22:09 +08:00
|
|
|
if (!TL.getType()->isInstantiationDependentType() &&
|
2011-01-06 07:12:31 +08:00
|
|
|
!TL.getType()->isVariablyModifiedType()) {
|
|
|
|
// FIXME: Make a copy of the TypeLoc data here, so that we can
|
|
|
|
// return a new TypeSourceInfo. Inefficient!
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
TLB.pushFullCopy(TL);
|
|
|
|
return TLB.getTypeSourceInfo(Context, TL.getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
TLB.reserve(TL.getFullDataSize());
|
|
|
|
QualType Result = Instantiator.TransformType(TLB, TL);
|
|
|
|
if (Result.isNull())
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2011-01-06 07:12:31 +08:00
|
|
|
|
|
|
|
return TLB.getTypeSourceInfo(Context, Result);
|
|
|
|
}
|
|
|
|
|
2009-10-21 08:58:09 +08:00
|
|
|
/// Deprecated form of the above.
|
2009-09-09 23:08:12 +08:00
|
|
|
QualType Sema::SubstType(QualType T,
|
2009-08-29 04:31:08 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2009-08-26 06:02:44 +08:00
|
|
|
SourceLocation Loc, DeclarationName Entity) {
|
2009-03-11 04:44:00 +08:00
|
|
|
assert(!ActiveTemplateInstantiations.empty() &&
|
|
|
|
"Cannot perform an instantiation without some context on the "
|
|
|
|
"instantiation stack");
|
|
|
|
|
2010-05-25 01:22:01 +08:00
|
|
|
// If T is not a dependent type or a variably-modified type, there
|
|
|
|
// is nothing to do.
|
2011-07-01 09:22:09 +08:00
|
|
|
if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType())
|
2009-02-28 03:31:52 +08:00
|
|
|
return T;
|
|
|
|
|
2009-08-05 00:50:30 +08:00
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
|
|
|
|
return Instantiator.TransformType(T);
|
2009-02-28 03:31:52 +08:00
|
|
|
}
|
2009-03-03 12:44:36 +08:00
|
|
|
|
2010-04-10 01:38:44 +08:00
|
|
|
static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
|
2016-02-02 06:31:51 +08:00
|
|
|
if (T->getType()->isInstantiationDependentType() ||
|
2011-07-01 09:22:09 +08:00
|
|
|
T->getType()->isVariablyModifiedType())
|
2010-04-10 01:38:44 +08:00
|
|
|
return true;
|
|
|
|
|
2010-12-15 06:11:44 +08:00
|
|
|
TypeLoc TL = T->getTypeLoc().IgnoreParens();
|
2013-02-19 06:06:02 +08:00
|
|
|
if (!TL.getAs<FunctionProtoTypeLoc>())
|
2010-04-10 01:38:44 +08:00
|
|
|
return false;
|
|
|
|
|
2013-02-19 06:06:02 +08:00
|
|
|
FunctionProtoTypeLoc FP = TL.castAs<FunctionProtoTypeLoc>();
|
2016-02-02 06:31:51 +08:00
|
|
|
for (ParmVarDecl *P : FP.getParams()) {
|
2013-08-01 05:00:18 +08:00
|
|
|
// This must be synthesized from a typedef.
|
|
|
|
if (!P) continue;
|
|
|
|
|
2016-02-02 06:31:51 +08:00
|
|
|
// If there are any parameters, a new TypeSourceInfo that refers to the
|
|
|
|
// instantiated parameters must be built.
|
|
|
|
return true;
|
2010-04-10 01:38:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A form of SubstType intended specifically for instantiating the
|
|
|
|
/// type of a FunctionDecl. Its purpose is solely to force the
|
2014-11-12 10:00:47 +08:00
|
|
|
/// instantiation of default-argument expressions and to avoid
|
|
|
|
/// instantiating an exception-specification.
|
2010-04-10 01:38:44 +08:00
|
|
|
TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
|
|
|
|
const MultiLevelTemplateArgumentList &Args,
|
|
|
|
SourceLocation Loc,
|
2012-04-16 15:05:22 +08:00
|
|
|
DeclarationName Entity,
|
|
|
|
CXXRecordDecl *ThisContext,
|
|
|
|
unsigned ThisTypeQuals) {
|
2010-04-10 01:38:44 +08:00
|
|
|
assert(!ActiveTemplateInstantiations.empty() &&
|
|
|
|
"Cannot perform an instantiation without some context on the "
|
|
|
|
"instantiation stack");
|
2016-02-02 06:31:51 +08:00
|
|
|
|
2010-04-10 01:38:44 +08:00
|
|
|
if (!NeedsInstantiationAsFunctionType(T))
|
|
|
|
return T;
|
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
|
|
|
|
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
|
|
|
|
TypeLoc TL = T->getTypeLoc();
|
|
|
|
TLB.reserve(TL.getFullDataSize());
|
|
|
|
|
2012-04-16 15:05:22 +08:00
|
|
|
QualType Result;
|
2013-02-19 06:06:02 +08:00
|
|
|
|
2014-11-12 10:00:47 +08:00
|
|
|
if (FunctionProtoTypeLoc Proto =
|
|
|
|
TL.IgnoreParens().getAs<FunctionProtoTypeLoc>()) {
|
|
|
|
// Instantiate the type, other than its exception specification. The
|
|
|
|
// exception specification is instantiated in InitFunctionInstantiation
|
|
|
|
// once we've built the FunctionDecl.
|
|
|
|
// FIXME: Set the exception specification to EST_Uninstantiated here,
|
|
|
|
// instead of rebuilding the function type again later.
|
|
|
|
Result = Instantiator.TransformFunctionProtoType(
|
|
|
|
TLB, Proto, ThisContext, ThisTypeQuals,
|
|
|
|
[](FunctionProtoType::ExceptionSpecInfo &ESI,
|
|
|
|
bool &Changed) { return false; });
|
2012-04-16 15:05:22 +08:00
|
|
|
} else {
|
|
|
|
Result = Instantiator.TransformType(TLB, TL);
|
|
|
|
}
|
2010-04-10 01:38:44 +08:00
|
|
|
if (Result.isNull())
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2010-04-10 01:38:44 +08:00
|
|
|
|
|
|
|
return TLB.getTypeSourceInfo(Context, Result);
|
|
|
|
}
|
|
|
|
|
2014-11-12 10:00:47 +08:00
|
|
|
void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
|
|
|
|
const MultiLevelTemplateArgumentList &Args) {
|
|
|
|
FunctionProtoType::ExceptionSpecInfo ESI =
|
|
|
|
Proto->getExtProtoInfo().ExceptionSpec;
|
|
|
|
assert(ESI.Type != EST_Uninstantiated);
|
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, Args, New->getLocation(),
|
|
|
|
New->getDeclName());
|
|
|
|
|
|
|
|
SmallVector<QualType, 4> ExceptionStorage;
|
|
|
|
bool Changed = false;
|
|
|
|
if (Instantiator.TransformExceptionSpec(
|
|
|
|
New->getTypeSourceInfo()->getTypeLoc().getLocEnd(), ESI,
|
|
|
|
ExceptionStorage, Changed))
|
|
|
|
// On error, recover by dropping the exception specification.
|
|
|
|
ESI.Type = EST_None;
|
|
|
|
|
|
|
|
UpdateExceptionSpec(New, ESI);
|
|
|
|
}
|
|
|
|
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
|
2011-01-15 06:40:04 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2011-05-02 06:35:37 +08:00
|
|
|
int indexAdjustment,
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> NumExpansions,
|
2012-01-26 00:15:54 +08:00
|
|
|
bool ExpectParameterPack) {
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
|
2014-05-26 14:22:03 +08:00
|
|
|
TypeSourceInfo *NewDI = nullptr;
|
|
|
|
|
2011-01-06 07:12:31 +08:00
|
|
|
TypeLoc OldTL = OldDI->getTypeLoc();
|
2013-02-19 06:06:02 +08:00
|
|
|
if (PackExpansionTypeLoc ExpansionTL = OldTL.getAs<PackExpansionTypeLoc>()) {
|
|
|
|
|
2011-01-06 07:12:31 +08:00
|
|
|
// We have a function parameter pack. Substitute into the pattern of the
|
|
|
|
// expansion.
|
|
|
|
NewDI = SubstType(ExpansionTL.getPatternLoc(), TemplateArgs,
|
|
|
|
OldParm->getLocation(), OldParm->getDeclName());
|
|
|
|
if (!NewDI)
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
|
|
|
|
2011-01-06 07:12:31 +08:00
|
|
|
if (NewDI->getType()->containsUnexpandedParameterPack()) {
|
|
|
|
// We still have unexpanded parameter packs, which means that
|
|
|
|
// our function parameter is still a function parameter pack.
|
|
|
|
// Therefore, make its type a pack expansion type.
|
2011-01-15 01:04:44 +08:00
|
|
|
NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(),
|
2011-01-15 06:40:04 +08:00
|
|
|
NumExpansions);
|
2012-01-26 00:15:54 +08:00
|
|
|
} else if (ExpectParameterPack) {
|
|
|
|
// We expected to get a parameter pack but didn't (because the type
|
|
|
|
// itself is not a pack expansion type), so complain. This can occur when
|
|
|
|
// the substitution goes through an alias template that "loses" the
|
|
|
|
// pack expansion.
|
|
|
|
Diag(OldParm->getLocation(),
|
|
|
|
diag::err_function_parameter_pack_without_parameter_packs)
|
|
|
|
<< NewDI->getType();
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2012-01-26 00:15:54 +08:00
|
|
|
}
|
2011-01-06 07:12:31 +08:00
|
|
|
} else {
|
|
|
|
NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
|
|
|
|
OldParm->getDeclName());
|
|
|
|
}
|
|
|
|
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
if (!NewDI)
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
|
|
|
|
if (NewDI->getType()->isVoidType()) {
|
|
|
|
Diag(OldParm->getLocation(), diag::err_param_with_void_type);
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ParmVarDecl *NewParm = CheckParameter(Context.getTranslationUnitDecl(),
|
2011-03-08 16:55:46 +08:00
|
|
|
OldParm->getInnerLocStart(),
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
OldParm->getLocation(),
|
2011-03-08 16:55:46 +08:00
|
|
|
OldParm->getIdentifier(),
|
|
|
|
NewDI->getType(), NewDI,
|
2013-04-04 03:27:57 +08:00
|
|
|
OldParm->getStorageClass());
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
if (!NewParm)
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
|
|
|
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
// Mark the (new) default argument as uninstantiated (if any).
|
|
|
|
if (OldParm->hasUninstantiatedDefaultArg()) {
|
|
|
|
Expr *Arg = OldParm->getUninstantiatedDefaultArg();
|
|
|
|
NewParm->setUninstantiatedDefaultArg(Arg);
|
2010-10-13 02:23:32 +08:00
|
|
|
} else if (OldParm->hasUnparsedDefaultArg()) {
|
|
|
|
NewParm->setUnparsedDefaultArg();
|
|
|
|
UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
|
2015-06-30 01:50:19 +08:00
|
|
|
} else if (Expr *Arg = OldParm->getDefaultArg()) {
|
|
|
|
FunctionDecl *OwningFunc = cast<FunctionDecl>(OldParm->getDeclContext());
|
2015-08-23 18:22:28 +08:00
|
|
|
if (OwningFunc->isLexicallyWithinFunctionOrMethod()) {
|
|
|
|
// Instantiate default arguments for methods of local classes (DR1484)
|
|
|
|
// and non-defining declarations.
|
|
|
|
Sema::ContextRAII SavedContext(*this, OwningFunc);
|
2015-06-30 01:50:19 +08:00
|
|
|
LocalInstantiationScope Local(*this);
|
|
|
|
ExprResult NewArg = SubstExpr(Arg, TemplateArgs);
|
2015-12-11 09:56:36 +08:00
|
|
|
if (NewArg.isUsable()) {
|
|
|
|
// It would be nice if we still had this.
|
|
|
|
SourceLocation EqualLoc = NewArg.get()->getLocStart();
|
|
|
|
SetParamDefaultArgument(NewParm, NewArg.get(), EqualLoc);
|
|
|
|
}
|
2015-06-30 01:50:19 +08:00
|
|
|
} else {
|
|
|
|
// FIXME: if we non-lazily instantiated non-dependent default args for
|
|
|
|
// non-dependent parameter types we could remove a bunch of duplicate
|
|
|
|
// conversion warnings for such arguments.
|
|
|
|
NewParm->setUninstantiatedDefaultArg(Arg);
|
|
|
|
}
|
|
|
|
}
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
|
|
|
|
NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
|
2012-01-26 00:15:54 +08:00
|
|
|
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
if (OldParm->isParameterPack() && !NewParm->isParameterPack()) {
|
2012-01-25 10:14:59 +08:00
|
|
|
// Add the new parameter to the instantiated parameter pack.
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
CurrentInstantiationScope->InstantiatedLocalPackArg(OldParm, NewParm);
|
|
|
|
} else {
|
|
|
|
// Introduce an Old -> New mapping
|
2011-01-06 07:12:31 +08:00
|
|
|
CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
}
|
2011-01-06 07:12:31 +08:00
|
|
|
|
2010-07-19 18:14:41 +08:00
|
|
|
// FIXME: OldParm may come from a FunctionProtoType, in which case CurContext
|
|
|
|
// can be anything, is this right ?
|
2010-07-14 05:05:02 +08:00
|
|
|
NewParm->setDeclContext(CurContext);
|
2011-05-02 06:35:37 +08:00
|
|
|
|
|
|
|
NewParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
|
|
|
|
OldParm->getFunctionScopeIndex() + indexAdjustment);
|
2013-03-09 06:25:36 +08:00
|
|
|
|
|
|
|
InstantiateAttrs(TemplateArgs, OldParm, NewParm);
|
|
|
|
|
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
|
|
|
return NewParm;
|
|
|
|
}
|
|
|
|
|
2011-01-07 08:20:55 +08:00
|
|
|
/// \brief Substitute the given template arguments into the given set of
|
|
|
|
/// parameters, producing the set of parameter types that would be generated
|
|
|
|
/// from such a substitution.
|
|
|
|
bool Sema::SubstParmTypes(SourceLocation Loc,
|
|
|
|
ParmVarDecl **Params, unsigned NumParams,
|
2016-03-01 10:09:25 +08:00
|
|
|
const FunctionProtoType::ExtParameterInfo *ExtParamInfos,
|
2011-01-07 08:20:55 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<QualType> &ParamTypes,
|
2016-03-01 10:09:25 +08:00
|
|
|
SmallVectorImpl<ParmVarDecl *> *OutParams,
|
|
|
|
ExtParameterInfoBuilder &ParamInfos) {
|
2011-01-07 08:20:55 +08:00
|
|
|
assert(!ActiveTemplateInstantiations.empty() &&
|
|
|
|
"Cannot perform an instantiation without some context on the "
|
|
|
|
"instantiation stack");
|
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
|
|
|
|
DeclarationName());
|
2014-05-26 14:22:03 +08:00
|
|
|
return Instantiator.TransformFunctionTypeParams(Loc, Params, NumParams,
|
2016-03-01 10:09:25 +08:00
|
|
|
nullptr, ExtParamInfos,
|
|
|
|
ParamTypes, OutParams,
|
|
|
|
ParamInfos);
|
2011-01-07 08:20:55 +08:00
|
|
|
}
|
|
|
|
|
2009-08-26 06:02:44 +08:00
|
|
|
/// \brief Perform substitution on the base class specifiers of the
|
|
|
|
/// given class template specialization.
|
2009-03-03 12:44:36 +08:00
|
|
|
///
|
|
|
|
/// Produces a diagnostic and returns true on error, returns false and
|
|
|
|
/// attaches the instantiated base classes to the class template
|
|
|
|
/// specialization if successful.
|
2009-09-09 23:08:12 +08:00
|
|
|
bool
|
2009-08-26 06:02:44 +08:00
|
|
|
Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
|
|
|
|
CXXRecordDecl *Pattern,
|
2009-08-29 04:31:08 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs) {
|
2009-03-03 12:44:36 +08:00
|
|
|
bool Invalid = false;
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<CXXBaseSpecifier*, 4> InstantiatedBases;
|
2015-04-15 09:21:42 +08:00
|
|
|
for (const auto &Base : Pattern->bases()) {
|
2014-03-13 23:41:46 +08:00
|
|
|
if (!Base.getType()->isDependentType()) {
|
|
|
|
if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) {
|
2013-06-22 02:58:32 +08:00
|
|
|
if (RD->isInvalidDecl())
|
|
|
|
Instantiation->setInvalidDecl();
|
|
|
|
}
|
2014-03-13 23:41:46 +08:00
|
|
|
InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(Base));
|
2009-03-03 12:44:36 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-01-04 06:36:02 +08:00
|
|
|
SourceLocation EllipsisLoc;
|
2011-03-02 10:04:06 +08:00
|
|
|
TypeSourceInfo *BaseTypeLoc;
|
2014-03-13 23:41:46 +08:00
|
|
|
if (Base.isPackExpansion()) {
|
2011-01-04 06:36:02 +08:00
|
|
|
// This is a pack expansion. See whether we should expand it now, or
|
|
|
|
// wait until later.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
2014-03-13 23:41:46 +08:00
|
|
|
collectUnexpandedParameterPacks(Base.getTypeSourceInfo()->getTypeLoc(),
|
2011-01-04 06:36:02 +08:00
|
|
|
Unexpanded);
|
|
|
|
bool ShouldExpand = false;
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
bool RetainExpansion = false;
|
2013-02-21 06:23:23 +08:00
|
|
|
Optional<unsigned> NumExpansions;
|
2014-03-13 23:41:46 +08:00
|
|
|
if (CheckParameterPacksForExpansion(Base.getEllipsisLoc(),
|
|
|
|
Base.getSourceRange(),
|
2011-09-22 10:34:54 +08:00
|
|
|
Unexpanded,
|
2011-01-04 06:36:02 +08:00
|
|
|
TemplateArgs, ShouldExpand,
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
RetainExpansion,
|
2011-01-04 06:36:02 +08:00
|
|
|
NumExpansions)) {
|
|
|
|
Invalid = true;
|
2011-01-04 08:32:56 +08:00
|
|
|
continue;
|
2011-01-04 06:36:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we should expand this pack expansion now, do so.
|
|
|
|
if (ShouldExpand) {
|
2011-01-15 01:04:44 +08:00
|
|
|
for (unsigned I = 0; I != *NumExpansions; ++I) {
|
2011-01-04 06:36:02 +08:00
|
|
|
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
|
|
|
|
|
2014-03-13 23:41:46 +08:00
|
|
|
TypeSourceInfo *BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
|
2011-01-04 06:36:02 +08:00
|
|
|
TemplateArgs,
|
2014-03-13 23:41:46 +08:00
|
|
|
Base.getSourceRange().getBegin(),
|
2011-01-04 06:36:02 +08:00
|
|
|
DeclarationName());
|
|
|
|
if (!BaseTypeLoc) {
|
|
|
|
Invalid = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CXXBaseSpecifier *InstantiatedBase
|
|
|
|
= CheckBaseSpecifier(Instantiation,
|
2014-03-13 23:41:46 +08:00
|
|
|
Base.getSourceRange(),
|
|
|
|
Base.isVirtual(),
|
|
|
|
Base.getAccessSpecifierAsWritten(),
|
2011-01-04 06:36:02 +08:00
|
|
|
BaseTypeLoc,
|
|
|
|
SourceLocation()))
|
|
|
|
InstantiatedBases.push_back(InstantiatedBase);
|
|
|
|
else
|
|
|
|
Invalid = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The resulting base specifier will (still) be a pack expansion.
|
2014-03-13 23:41:46 +08:00
|
|
|
EllipsisLoc = Base.getEllipsisLoc();
|
2011-03-02 10:04:06 +08:00
|
|
|
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
|
2014-03-13 23:41:46 +08:00
|
|
|
BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
|
2011-03-02 10:04:06 +08:00
|
|
|
TemplateArgs,
|
2014-03-13 23:41:46 +08:00
|
|
|
Base.getSourceRange().getBegin(),
|
2011-03-02 10:04:06 +08:00
|
|
|
DeclarationName());
|
|
|
|
} else {
|
2014-03-13 23:41:46 +08:00
|
|
|
BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
|
2011-03-02 10:04:06 +08:00
|
|
|
TemplateArgs,
|
2014-03-13 23:41:46 +08:00
|
|
|
Base.getSourceRange().getBegin(),
|
2011-03-02 10:04:06 +08:00
|
|
|
DeclarationName());
|
2011-01-04 06:36:02 +08:00
|
|
|
}
|
|
|
|
|
2010-07-27 00:56:01 +08:00
|
|
|
if (!BaseTypeLoc) {
|
2009-03-03 12:44:36 +08:00
|
|
|
Invalid = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CXXBaseSpecifier *InstantiatedBase
|
2009-03-26 05:17:03 +08:00
|
|
|
= CheckBaseSpecifier(Instantiation,
|
2014-03-13 23:41:46 +08:00
|
|
|
Base.getSourceRange(),
|
|
|
|
Base.isVirtual(),
|
|
|
|
Base.getAccessSpecifierAsWritten(),
|
2011-01-04 06:36:02 +08:00
|
|
|
BaseTypeLoc,
|
|
|
|
EllipsisLoc))
|
2009-03-03 12:44:36 +08:00
|
|
|
InstantiatedBases.push_back(InstantiatedBase);
|
|
|
|
else
|
|
|
|
Invalid = true;
|
|
|
|
}
|
|
|
|
|
2015-12-28 05:55:19 +08:00
|
|
|
if (!Invalid && AttachBaseSpecifiers(Instantiation, InstantiatedBases))
|
2009-03-03 12:44:36 +08:00
|
|
|
Invalid = true;
|
|
|
|
|
|
|
|
return Invalid;
|
|
|
|
}
|
|
|
|
|
2012-01-21 06:50:54 +08:00
|
|
|
// Defined via #include from SemaTemplateInstantiateDecl.cpp
|
2012-02-06 19:13:08 +08:00
|
|
|
namespace clang {
|
|
|
|
namespace sema {
|
|
|
|
Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs);
|
|
|
|
}
|
|
|
|
}
|
2012-01-21 06:50:54 +08:00
|
|
|
|
2012-03-15 07:13:10 +08:00
|
|
|
/// Determine whether we would be unable to instantiate this template (because
|
|
|
|
/// it either has no definition, or is in the process of being instantiated).
|
|
|
|
static bool DiagnoseUninstantiableTemplate(Sema &S,
|
|
|
|
SourceLocation PointOfInstantiation,
|
|
|
|
TagDecl *Instantiation,
|
|
|
|
bool InstantiatedFromMember,
|
|
|
|
TagDecl *Pattern,
|
|
|
|
TagDecl *PatternDef,
|
|
|
|
TemplateSpecializationKind TSK,
|
|
|
|
bool Complain = true) {
|
|
|
|
if (PatternDef && !PatternDef->isBeingDefined())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!Complain || (PatternDef && PatternDef->isInvalidDecl())) {
|
|
|
|
// Say nothing
|
|
|
|
} else if (PatternDef) {
|
|
|
|
assert(PatternDef->isBeingDefined());
|
|
|
|
S.Diag(PointOfInstantiation,
|
|
|
|
diag::err_template_instantiate_within_definition)
|
|
|
|
<< (TSK != TSK_ImplicitInstantiation)
|
|
|
|
<< S.Context.getTypeDeclType(Instantiation);
|
|
|
|
// Not much point in noting the template declaration here, since
|
|
|
|
// we're lexically inside it.
|
|
|
|
Instantiation->setInvalidDecl();
|
|
|
|
} else if (InstantiatedFromMember) {
|
|
|
|
S.Diag(PointOfInstantiation,
|
|
|
|
diag::err_implicit_instantiate_member_undefined)
|
|
|
|
<< S.Context.getTypeDeclType(Instantiation);
|
2014-05-28 20:20:14 +08:00
|
|
|
S.Diag(Pattern->getLocation(), diag::note_member_declared_at);
|
2012-03-15 07:13:10 +08:00
|
|
|
} else {
|
|
|
|
S.Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
|
|
|
|
<< (TSK != TSK_ImplicitInstantiation)
|
|
|
|
<< S.Context.getTypeDeclType(Instantiation);
|
|
|
|
S.Diag(Pattern->getLocation(), diag::note_template_decl_here);
|
|
|
|
}
|
|
|
|
|
|
|
|
// In general, Instantiation isn't marked invalid to get more than one
|
|
|
|
// error for multiple undefined instantiations. But the code that does
|
|
|
|
// explicit declaration -> explicit definition conversion can't handle
|
|
|
|
// invalid declarations, so mark as invalid in that case.
|
|
|
|
if (TSK == TSK_ExplicitInstantiationDeclaration)
|
|
|
|
Instantiation->setInvalidDecl();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-03-26 05:17:03 +08:00
|
|
|
/// \brief Instantiate the definition of a class from a given pattern.
|
|
|
|
///
|
|
|
|
/// \param PointOfInstantiation The point of instantiation within the
|
|
|
|
/// source code.
|
|
|
|
///
|
|
|
|
/// \param Instantiation is the declaration whose definition is being
|
|
|
|
/// instantiated. This will be either a class template specialization
|
|
|
|
/// or a member class of a class template specialization.
|
|
|
|
///
|
|
|
|
/// \param Pattern is the pattern from which the instantiation
|
|
|
|
/// occurs. This will be either the declaration of a class template or
|
|
|
|
/// the declaration of a member class of a class template.
|
|
|
|
///
|
|
|
|
/// \param TemplateArgs The template arguments to be substituted into
|
|
|
|
/// the pattern.
|
|
|
|
///
|
2009-09-05 06:48:11 +08:00
|
|
|
/// \param TSK the kind of implicit or explicit instantiation to perform.
|
2009-08-24 23:23:48 +08:00
|
|
|
///
|
|
|
|
/// \param Complain whether to complain if the class cannot be instantiated due
|
|
|
|
/// to the lack of a definition.
|
|
|
|
///
|
2009-03-26 05:17:03 +08:00
|
|
|
/// \returns true if an error occurred, false otherwise.
|
|
|
|
bool
|
|
|
|
Sema::InstantiateClass(SourceLocation PointOfInstantiation,
|
|
|
|
CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
|
2009-08-29 04:31:08 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2009-09-05 06:48:11 +08:00
|
|
|
TemplateSpecializationKind TSK,
|
2009-08-24 23:23:48 +08:00
|
|
|
bool Complain) {
|
2009-09-09 23:08:12 +08:00
|
|
|
CXXRecordDecl *PatternDef
|
2010-02-11 09:04:33 +08:00
|
|
|
= cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
|
2012-03-15 07:13:10 +08:00
|
|
|
if (DiagnoseUninstantiableTemplate(*this, PointOfInstantiation, Instantiation,
|
|
|
|
Instantiation->getInstantiatedFromMemberClass(),
|
|
|
|
Pattern, PatternDef, TSK, Complain))
|
2009-03-03 12:44:36 +08:00
|
|
|
return true;
|
2009-03-26 05:17:03 +08:00
|
|
|
Pattern = PatternDef;
|
2009-03-03 12:44:36 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
// \brief Record the point of instantiation.
|
|
|
|
if (MemberSpecializationInfo *MSInfo
|
|
|
|
= Instantiation->getMemberSpecializationInfo()) {
|
|
|
|
MSInfo->setTemplateSpecializationKind(TSK);
|
|
|
|
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
2009-10-27 14:26:26 +08:00
|
|
|
} else if (ClassTemplateSpecializationDecl *Spec
|
2011-12-21 04:32:49 +08:00
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
|
2009-10-27 14:26:26 +08:00
|
|
|
Spec->setTemplateSpecializationKind(TSK);
|
|
|
|
Spec->setPointOfInstantiation(PointOfInstantiation);
|
2009-10-15 23:54:05 +08:00
|
|
|
}
|
2014-03-10 08:04:29 +08:00
|
|
|
|
2009-03-26 05:23:52 +08:00
|
|
|
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
2013-10-08 16:09:04 +08:00
|
|
|
if (Inst.isInvalid())
|
2009-03-10 08:06:19 +08:00
|
|
|
return true;
|
|
|
|
|
2009-03-03 12:44:36 +08:00
|
|
|
// Enter the scope of this instantiation. We don't use
|
|
|
|
// PushDeclContext because we don't have a scope.
|
2010-04-29 08:35:03 +08:00
|
|
|
ContextRAII SavedContext(*this, Instantiation);
|
2010-05-13 01:27:19 +08:00
|
|
|
EnterExpressionEvaluationContext EvalContext(*this,
|
2010-08-27 07:41:50 +08:00
|
|
|
Sema::PotentiallyEvaluated);
|
2009-03-03 12:44:36 +08:00
|
|
|
|
2010-03-24 09:33:17 +08:00
|
|
|
// If this is an instantiation of a local class, merge this local
|
|
|
|
// instantiation scope with the enclosing scope. Otherwise, every
|
|
|
|
// instantiation of a class has its own local instantiation scope.
|
|
|
|
bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
|
2010-08-25 13:32:35 +08:00
|
|
|
LocalInstantiationScope Scope(*this, MergeWithParentScope);
|
2010-03-24 09:33:17 +08:00
|
|
|
|
2016-02-27 03:51:02 +08:00
|
|
|
// All dllexported classes created during instantiation should be fully
|
|
|
|
// emitted after instantiation completes. We may not be ready to emit any
|
|
|
|
// delayed classes already on the stack, so save them away and put them back
|
|
|
|
// later.
|
|
|
|
decltype(DelayedDllExportClasses) ExportedClasses;
|
|
|
|
std::swap(ExportedClasses, DelayedDllExportClasses);
|
|
|
|
|
2010-08-01 10:01:53 +08:00
|
|
|
// Pull attributes from the pattern onto the instantiation.
|
|
|
|
InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
|
|
|
|
|
2009-03-03 12:44:36 +08:00
|
|
|
// Start the definition of this instantiation.
|
2009-03-26 05:17:03 +08:00
|
|
|
Instantiation->startDefinition();
|
2014-03-10 08:04:29 +08:00
|
|
|
|
|
|
|
// The instantiation is visible here, even if it was first declared in an
|
|
|
|
// unimported module.
|
|
|
|
Instantiation->setHidden(false);
|
|
|
|
|
|
|
|
// FIXME: This loses the as-written tag kind for an explicit instantiation.
|
2010-05-06 08:28:52 +08:00
|
|
|
Instantiation->setTagKind(Pattern->getTagKind());
|
2009-03-03 12:44:36 +08:00
|
|
|
|
2009-08-26 06:02:44 +08:00
|
|
|
// Do substitution on the base class specifiers.
|
|
|
|
if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
|
2012-07-03 05:00:41 +08:00
|
|
|
Instantiation->setInvalidDecl();
|
2009-03-03 12:44:36 +08:00
|
|
|
|
2010-11-11 03:44:59 +08:00
|
|
|
TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<Decl*, 4> Fields;
|
2012-01-21 06:50:54 +08:00
|
|
|
// Delay instantiation of late parsed attributes.
|
|
|
|
LateInstantiatedAttrVec LateAttrs;
|
|
|
|
Instantiator.enableLateAttributeInstantiation(&LateAttrs);
|
|
|
|
|
2014-03-08 03:56:05 +08:00
|
|
|
for (auto *Member : Pattern->decls()) {
|
2010-11-04 11:18:57 +08:00
|
|
|
// Don't instantiate members not belonging in this semantic context.
|
|
|
|
// e.g. for:
|
|
|
|
// @code
|
|
|
|
// template <int i> class A {
|
|
|
|
// class B *g;
|
|
|
|
// };
|
|
|
|
// @endcode
|
|
|
|
// 'class B' has the template as lexical context but semantically it is
|
|
|
|
// introduced in namespace scope.
|
2014-03-08 03:56:05 +08:00
|
|
|
if (Member->getDeclContext() != Pattern)
|
2010-11-04 11:18:57 +08:00
|
|
|
continue;
|
|
|
|
|
2014-03-08 03:56:05 +08:00
|
|
|
if (Member->isInvalidDecl()) {
|
2012-07-12 06:37:56 +08:00
|
|
|
Instantiation->setInvalidDecl();
|
2010-11-11 03:44:59 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-03-08 03:56:05 +08:00
|
|
|
Decl *NewMember = Instantiator.Visit(Member);
|
2009-03-18 05:15:40 +08:00
|
|
|
if (NewMember) {
|
2011-06-12 01:19:42 +08:00
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) {
|
2010-08-21 17:40:31 +08:00
|
|
|
Fields.push_back(Field);
|
2012-03-23 11:33:32 +08:00
|
|
|
} else if (EnumDecl *Enum = dyn_cast<EnumDecl>(NewMember)) {
|
|
|
|
// C++11 [temp.inst]p1: The implicit instantiation of a class template
|
|
|
|
// specialization causes the implicit instantiation of the definitions
|
|
|
|
// of unscoped member enumerations.
|
|
|
|
// Record a point of instantiation for this implicit instantiation.
|
2012-03-24 07:09:08 +08:00
|
|
|
if (TSK == TSK_ImplicitInstantiation && !Enum->isScoped() &&
|
|
|
|
Enum->isCompleteDefinition()) {
|
2012-03-23 11:33:32 +08:00
|
|
|
MemberSpecializationInfo *MSInfo =Enum->getMemberSpecializationInfo();
|
|
|
|
assert(MSInfo && "no spec info for member enum specialization");
|
|
|
|
MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation);
|
|
|
|
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
}
|
2012-07-12 06:37:56 +08:00
|
|
|
} else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(NewMember)) {
|
|
|
|
if (SA->isFailed()) {
|
|
|
|
// A static_assert failed. Bail out; instantiating this
|
|
|
|
// class is probably not meaningful.
|
|
|
|
Instantiation->setInvalidDecl();
|
|
|
|
break;
|
|
|
|
}
|
2012-03-23 11:33:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (NewMember->isInvalidDecl())
|
2012-07-03 05:00:41 +08:00
|
|
|
Instantiation->setInvalidDecl();
|
2009-03-18 05:15:40 +08:00
|
|
|
} else {
|
|
|
|
// FIXME: Eventually, a NULL return will mean that one of the
|
2012-07-03 05:00:41 +08:00
|
|
|
// instantiations was a semantic disaster, and we'll want to mark the
|
|
|
|
// declaration invalid.
|
|
|
|
// For now, we expect to skip some members that we can't yet handle.
|
2009-03-12 00:48:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-12 02:59:21 +08:00
|
|
|
// Finish checking fields.
|
2014-05-26 14:22:03 +08:00
|
|
|
ActOnFields(nullptr, Instantiation->getLocation(), Instantiation, Fields,
|
|
|
|
SourceLocation(), SourceLocation(), nullptr);
|
2010-07-03 01:43:08 +08:00
|
|
|
CheckCompletedCXXClass(Instantiation);
|
2011-06-12 01:19:42 +08:00
|
|
|
|
2015-03-18 05:51:43 +08:00
|
|
|
// Default arguments are parsed, if not instantiated. We can go instantiate
|
|
|
|
// default arg exprs for default constructors if necessary now.
|
2015-08-15 09:18:16 +08:00
|
|
|
ActOnFinishCXXNonNestedClass(Instantiation);
|
2015-03-18 05:51:43 +08:00
|
|
|
|
2016-02-27 03:51:02 +08:00
|
|
|
// Put back the delayed exported classes that we moved out of the way.
|
|
|
|
std::swap(ExportedClasses, DelayedDllExportClasses);
|
|
|
|
|
2012-01-21 06:50:54 +08:00
|
|
|
// Instantiate late parsed attributes, and attach them to their decls.
|
|
|
|
// See Sema::InstantiateAttrs
|
|
|
|
for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(),
|
|
|
|
E = LateAttrs.end(); I != E; ++I) {
|
|
|
|
assert(CurrentInstantiationScope == Instantiator.getStartingScope());
|
|
|
|
CurrentInstantiationScope = I->Scope;
|
2013-06-07 10:33:37 +08:00
|
|
|
|
|
|
|
// Allow 'this' within late-parsed attributes.
|
|
|
|
NamedDecl *ND = dyn_cast<NamedDecl>(I->NewDecl);
|
|
|
|
CXXRecordDecl *ThisContext =
|
|
|
|
dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
|
|
|
|
CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0,
|
|
|
|
ND && ND->isCXXInstanceMember());
|
|
|
|
|
2012-01-21 06:50:54 +08:00
|
|
|
Attr *NewAttr =
|
|
|
|
instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs);
|
|
|
|
I->NewDecl->addAttr(NewAttr);
|
|
|
|
LocalInstantiationScope::deleteScopes(I->Scope,
|
|
|
|
Instantiator.getStartingScope());
|
|
|
|
}
|
|
|
|
Instantiator.disableLateAttributeInstantiation();
|
|
|
|
LateAttrs.clear();
|
|
|
|
|
Final piece of core issue 1330: delay computing the exception specification of
a defaulted special member function until the exception specification is needed
(using the same criteria used for the delayed instantiation of exception
specifications for function temploids).
EST_Delayed is now EST_Unevaluated (using 1330's terminology), and, like
EST_Uninstantiated, carries a pointer to the FunctionDecl which will be used to
resolve the exception specification.
This is enabled for all C++ modes: it's a little faster in the case where the
exception specification isn't used, allows our C++11-in-C++98 extensions to
work, and is still correct for C++98, since in that mode the computation of the
exception specification can't fail.
The diagnostics here aren't great (in particular, we should include implicit
evaluation of exception specifications for defaulted special members in the
template instantiation backtraces), but they're not much worse than before.
Our approach to the problem of cycles between in-class initializers and the
exception specification for a defaulted default constructor is modified a
little by this change -- we now reject any odr-use of a defaulted default
constructor if that constructor uses an in-class initializer and the use is in
an in-class initialzer which is declared lexically earlier. This is a closer
approximation to the current draft solution in core issue 1351, but isn't an
exact match (but the current draft wording isn't reasonable, so that's to be
expected).
llvm-svn: 160847
2012-07-27 12:22:15 +08:00
|
|
|
ActOnFinishDelayedMemberInitializers(Instantiation);
|
2011-06-12 01:19:42 +08:00
|
|
|
|
2014-03-10 08:04:29 +08:00
|
|
|
// FIXME: We should do something similar for explicit instantiations so they
|
|
|
|
// end up in the right module.
|
2011-11-18 16:08:52 +08:00
|
|
|
if (TSK == TSK_ImplicitInstantiation) {
|
2012-02-11 09:59:57 +08:00
|
|
|
Instantiation->setLocation(Pattern->getLocation());
|
2011-11-18 16:08:52 +08:00
|
|
|
Instantiation->setLocStart(Pattern->getInnerLocStart());
|
2011-10-04 04:34:03 +08:00
|
|
|
Instantiation->setRBraceLoc(Pattern->getRBraceLoc());
|
2011-11-18 16:08:52 +08:00
|
|
|
}
|
2011-10-04 04:34:03 +08:00
|
|
|
|
2012-07-03 05:00:41 +08:00
|
|
|
if (!Instantiation->isInvalidDecl()) {
|
2012-08-10 11:15:35 +08:00
|
|
|
// Perform any dependent diagnostics from the pattern.
|
|
|
|
PerformDependentDiagnostics(Pattern, TemplateArgs);
|
|
|
|
|
2010-11-11 03:44:59 +08:00
|
|
|
// Instantiate any out-of-line class template partial
|
|
|
|
// specializations now.
|
2013-09-26 11:49:48 +08:00
|
|
|
for (TemplateDeclInstantiator::delayed_partial_spec_iterator
|
2010-11-11 03:44:59 +08:00
|
|
|
P = Instantiator.delayed_partial_spec_begin(),
|
|
|
|
PEnd = Instantiator.delayed_partial_spec_end();
|
|
|
|
P != PEnd; ++P) {
|
|
|
|
if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
|
2013-09-26 11:49:48 +08:00
|
|
|
P->first, P->second)) {
|
|
|
|
Instantiation->setInvalidDecl();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Instantiate any out-of-line variable template partial
|
|
|
|
// specializations now.
|
|
|
|
for (TemplateDeclInstantiator::delayed_var_partial_spec_iterator
|
|
|
|
P = Instantiator.delayed_var_partial_spec_begin(),
|
|
|
|
PEnd = Instantiator.delayed_var_partial_spec_end();
|
|
|
|
P != PEnd; ++P) {
|
|
|
|
if (!Instantiator.InstantiateVarTemplatePartialSpecialization(
|
|
|
|
P->first, P->second)) {
|
2012-07-03 05:00:41 +08:00
|
|
|
Instantiation->setInvalidDecl();
|
2010-11-11 03:44:59 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-03 12:44:36 +08:00
|
|
|
// Exit the scope of this instantiation.
|
2010-04-29 08:35:03 +08:00
|
|
|
SavedContext.pop();
|
2009-03-03 12:44:36 +08:00
|
|
|
|
2012-07-03 05:00:41 +08:00
|
|
|
if (!Instantiation->isInvalidDecl()) {
|
2009-05-27 04:50:29 +08:00
|
|
|
Consumer.HandleTagDeclDefinition(Instantiation);
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// Always emit the vtable for an explicit instantiation definition
|
|
|
|
// of a polymorphic class template specialization.
|
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition)
|
|
|
|
MarkVTableUsed(PointOfInstantiation, Instantiation, true);
|
|
|
|
}
|
|
|
|
|
2012-07-03 05:00:41 +08:00
|
|
|
return Instantiation->isInvalidDecl();
|
2009-03-03 12:44:36 +08:00
|
|
|
}
|
Introduce a new expression type, UnresolvedDeclRefExpr, that describes
dependent qualified-ids such as
Fibonacci<N - 1>::value
where N is a template parameter. These references are "unresolved"
because the name is dependent and, therefore, cannot be resolved to a
declaration node (as we would do for a DeclRefExpr or
QualifiedDeclRefExpr). UnresolvedDeclRefExprs instantiate to
DeclRefExprs, QualifiedDeclRefExprs, etc.
Also, be a bit more careful about keeping only a single set of
specializations for a class template, and instantiating from the
definition of that template rather than a previous declaration. In
general, we need a better solution for this for all TagDecls, because
it's too easy to accidentally look at a declaration that isn't the
definition.
We can now process a simple Fibonacci computation described as a
template metaprogram.
llvm-svn: 67308
2009-03-20 01:26:29 +08:00
|
|
|
|
2012-03-15 07:13:10 +08:00
|
|
|
/// \brief Instantiate the definition of an enum from a given pattern.
|
|
|
|
///
|
|
|
|
/// \param PointOfInstantiation The point of instantiation within the
|
|
|
|
/// source code.
|
|
|
|
/// \param Instantiation is the declaration whose definition is being
|
|
|
|
/// instantiated. This will be a member enumeration of a class
|
|
|
|
/// temploid specialization, or a local enumeration within a
|
|
|
|
/// function temploid specialization.
|
|
|
|
/// \param Pattern The templated declaration from which the instantiation
|
|
|
|
/// occurs.
|
|
|
|
/// \param TemplateArgs The template arguments to be substituted into
|
|
|
|
/// the pattern.
|
|
|
|
/// \param TSK The kind of implicit or explicit instantiation to perform.
|
|
|
|
///
|
|
|
|
/// \return \c true if an error occurred, \c false otherwise.
|
|
|
|
bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
|
|
|
|
EnumDecl *Instantiation, EnumDecl *Pattern,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
|
|
|
TemplateSpecializationKind TSK) {
|
|
|
|
EnumDecl *PatternDef = Pattern->getDefinition();
|
|
|
|
if (DiagnoseUninstantiableTemplate(*this, PointOfInstantiation, Instantiation,
|
|
|
|
Instantiation->getInstantiatedFromMemberEnum(),
|
|
|
|
Pattern, PatternDef, TSK,/*Complain*/true))
|
|
|
|
return true;
|
|
|
|
Pattern = PatternDef;
|
|
|
|
|
|
|
|
// Record the point of instantiation.
|
|
|
|
if (MemberSpecializationInfo *MSInfo
|
|
|
|
= Instantiation->getMemberSpecializationInfo()) {
|
|
|
|
MSInfo->setTemplateSpecializationKind(TSK);
|
|
|
|
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
}
|
|
|
|
|
|
|
|
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
2013-10-08 16:09:04 +08:00
|
|
|
if (Inst.isInvalid())
|
2012-03-15 07:13:10 +08:00
|
|
|
return true;
|
|
|
|
|
2014-03-10 08:04:29 +08:00
|
|
|
// The instantiation is visible here, even if it was first declared in an
|
|
|
|
// unimported module.
|
|
|
|
Instantiation->setHidden(false);
|
|
|
|
|
2012-03-15 07:13:10 +08:00
|
|
|
// Enter the scope of this instantiation. We don't use
|
|
|
|
// PushDeclContext because we don't have a scope.
|
|
|
|
ContextRAII SavedContext(*this, Instantiation);
|
|
|
|
EnterExpressionEvaluationContext EvalContext(*this,
|
|
|
|
Sema::PotentiallyEvaluated);
|
|
|
|
|
|
|
|
LocalInstantiationScope Scope(*this, /*MergeWithParentScope*/true);
|
|
|
|
|
|
|
|
// Pull attributes from the pattern onto the instantiation.
|
|
|
|
InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
|
|
|
|
|
|
|
|
TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
|
|
|
|
Instantiator.InstantiateEnumDefinition(Instantiation, Pattern);
|
|
|
|
|
|
|
|
// Exit the scope of this instantiation.
|
|
|
|
SavedContext.pop();
|
|
|
|
|
|
|
|
return Instantiation->isInvalidDecl();
|
|
|
|
}
|
|
|
|
|
2014-11-18 07:36:45 +08:00
|
|
|
|
|
|
|
/// \brief Instantiate the definition of a field from the given pattern.
|
|
|
|
///
|
|
|
|
/// \param PointOfInstantiation The point of instantiation within the
|
|
|
|
/// source code.
|
|
|
|
/// \param Instantiation is the declaration whose definition is being
|
|
|
|
/// instantiated. This will be a class of a class temploid
|
|
|
|
/// specialization, or a local enumeration within a function temploid
|
|
|
|
/// specialization.
|
|
|
|
/// \param Pattern The templated declaration from which the instantiation
|
|
|
|
/// occurs.
|
|
|
|
/// \param TemplateArgs The template arguments to be substituted into
|
|
|
|
/// the pattern.
|
|
|
|
///
|
|
|
|
/// \return \c true if an error occurred, \c false otherwise.
|
|
|
|
bool Sema::InstantiateInClassInitializer(
|
|
|
|
SourceLocation PointOfInstantiation, FieldDecl *Instantiation,
|
|
|
|
FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs) {
|
|
|
|
// If there is no initializer, we don't need to do anything.
|
|
|
|
if (!Pattern->hasInClassInitializer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
assert(Instantiation->getInClassInitStyle() ==
|
|
|
|
Pattern->getInClassInitStyle() &&
|
|
|
|
"pattern and instantiation disagree about init style");
|
|
|
|
|
|
|
|
// Error out if we haven't parsed the initializer of the pattern yet because
|
|
|
|
// we are waiting for the closing brace of the outer class.
|
|
|
|
Expr *OldInit = Pattern->getInClassInitializer();
|
|
|
|
if (!OldInit) {
|
|
|
|
RecordDecl *PatternRD = Pattern->getParent();
|
|
|
|
RecordDecl *OutermostClass = PatternRD->getOuterLexicalRecordContext();
|
|
|
|
if (OutermostClass == PatternRD) {
|
|
|
|
Diag(Pattern->getLocEnd(), diag::err_in_class_initializer_not_yet_parsed)
|
|
|
|
<< PatternRD << Pattern;
|
|
|
|
} else {
|
|
|
|
Diag(Pattern->getLocEnd(),
|
|
|
|
diag::err_in_class_initializer_not_yet_parsed_outer_class)
|
|
|
|
<< PatternRD << OutermostClass << Pattern;
|
|
|
|
}
|
|
|
|
Instantiation->setInvalidDecl();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
|
|
|
if (Inst.isInvalid())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Enter the scope of this instantiation. We don't use PushDeclContext because
|
|
|
|
// we don't have a scope.
|
|
|
|
ContextRAII SavedContext(*this, Instantiation->getParent());
|
|
|
|
EnterExpressionEvaluationContext EvalContext(*this,
|
|
|
|
Sema::PotentiallyEvaluated);
|
|
|
|
|
2015-04-29 01:58:47 +08:00
|
|
|
LocalInstantiationScope Scope(*this, true);
|
2014-11-18 07:36:45 +08:00
|
|
|
|
|
|
|
// Instantiate the initializer.
|
|
|
|
ActOnStartCXXInClassMemberInitializer();
|
|
|
|
CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), /*TypeQuals=*/0);
|
|
|
|
|
|
|
|
ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
|
|
|
|
/*CXXDirectInit=*/false);
|
|
|
|
Expr *Init = NewInit.get();
|
|
|
|
assert((!Init || !isa<ParenListExpr>(Init)) && "call-style init in class");
|
|
|
|
ActOnFinishCXXInClassMemberInitializer(
|
|
|
|
Instantiation, Init ? Init->getLocStart() : SourceLocation(), Init);
|
|
|
|
|
|
|
|
// Exit the scope of this instantiation.
|
|
|
|
SavedContext.pop();
|
|
|
|
|
|
|
|
// Return true if the in-class initializer is still missing.
|
|
|
|
return !Instantiation->getInClassInitializer();
|
|
|
|
}
|
|
|
|
|
2010-10-13 07:32:35 +08:00
|
|
|
namespace {
|
|
|
|
/// \brief A partial specialization whose template arguments have matched
|
|
|
|
/// a given template-id.
|
|
|
|
struct PartialSpecMatchResult {
|
|
|
|
ClassTemplatePartialSpecializationDecl *Partial;
|
|
|
|
TemplateArgumentList *Args;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2013-08-22 08:59:14 +08:00
|
|
|
bool Sema::InstantiateClassTemplateSpecialization(
|
|
|
|
SourceLocation PointOfInstantiation,
|
|
|
|
ClassTemplateSpecializationDecl *ClassTemplateSpec,
|
|
|
|
TemplateSpecializationKind TSK, bool Complain) {
|
2009-03-26 05:17:03 +08:00
|
|
|
// Perform the actual instantiation on the canonical declaration.
|
|
|
|
ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
|
2009-07-18 08:34:25 +08:00
|
|
|
ClassTemplateSpec->getCanonicalDecl());
|
2009-09-16 00:51:42 +08:00
|
|
|
if (ClassTemplateSpec->isInvalidDecl())
|
|
|
|
return true;
|
|
|
|
|
2009-03-26 05:17:03 +08:00
|
|
|
ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
|
2014-05-26 14:22:03 +08:00
|
|
|
CXXRecordDecl *Pattern = nullptr;
|
2009-05-31 17:31:02 +08:00
|
|
|
|
2009-06-13 06:31:52 +08:00
|
|
|
// C++ [temp.class.spec.match]p1:
|
|
|
|
// When a class template is used in a context that requires an
|
|
|
|
// instantiation of the class, it is necessary to determine
|
|
|
|
// whether the instantiation is to be generated using the primary
|
|
|
|
// template or one of the partial specializations. This is done by
|
|
|
|
// matching the template arguments of the class template
|
|
|
|
// specialization with the template argument lists of the partial
|
|
|
|
// specializations.
|
2010-10-13 07:32:35 +08:00
|
|
|
typedef PartialSpecMatchResult MatchResult;
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<MatchResult, 4> Matched;
|
|
|
|
SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
|
2010-04-30 13:56:50 +08:00
|
|
|
Template->getPartialSpecializations(PartialSpecs);
|
2013-07-20 07:00:19 +08:00
|
|
|
TemplateSpecCandidateSet FailedCandidates(PointOfInstantiation);
|
2010-04-30 13:56:50 +08:00
|
|
|
for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
|
|
|
|
ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
|
2013-07-20 07:00:19 +08:00
|
|
|
TemplateDeductionInfo Info(FailedCandidates.getLocation());
|
2009-06-13 02:26:56 +08:00
|
|
|
if (TemplateDeductionResult Result
|
2010-04-30 13:56:50 +08:00
|
|
|
= DeduceTemplateArguments(Partial,
|
2009-06-13 02:26:56 +08:00
|
|
|
ClassTemplateSpec->getTemplateArgs(),
|
|
|
|
Info)) {
|
2013-07-20 07:00:19 +08:00
|
|
|
// Store the failed-deduction information for use in diagnostics, later.
|
|
|
|
// TODO: Actually use the failed-deduction info?
|
|
|
|
FailedCandidates.addCandidate()
|
|
|
|
.set(Partial, MakeDeductionFailureInfo(Context, Result, Info));
|
2009-06-13 02:26:56 +08:00
|
|
|
(void)Result;
|
|
|
|
} else {
|
2010-10-13 07:32:35 +08:00
|
|
|
Matched.push_back(PartialSpecMatchResult());
|
|
|
|
Matched.back().Partial = Partial;
|
|
|
|
Matched.back().Args = Info.take();
|
2009-06-13 02:26:56 +08:00
|
|
|
}
|
2009-05-31 17:31:02 +08:00
|
|
|
}
|
|
|
|
|
2011-01-20 04:10:05 +08:00
|
|
|
// If we're dealing with a member template where the template parameters
|
|
|
|
// have been instantiated, this provides the original template parameters
|
|
|
|
// from which the member template's parameters were instantiated.
|
2013-11-27 13:22:15 +08:00
|
|
|
|
2009-10-29 08:04:11 +08:00
|
|
|
if (Matched.size() >= 1) {
|
2013-07-04 11:08:24 +08:00
|
|
|
SmallVectorImpl<MatchResult>::iterator Best = Matched.begin();
|
2009-10-29 08:04:11 +08:00
|
|
|
if (Matched.size() == 1) {
|
|
|
|
// -- If exactly one matching specialization is found, the
|
|
|
|
// instantiation is generated from that specialization.
|
|
|
|
// We don't need to do anything for this.
|
|
|
|
} else {
|
|
|
|
// -- If more than one matching specialization is found, the
|
|
|
|
// partial order rules (14.5.4.2) are used to determine
|
|
|
|
// whether one of the specializations is more specialized
|
|
|
|
// than the others. If none of the specializations is more
|
|
|
|
// specialized than all of the other matching
|
|
|
|
// specializations, then the use of the class template is
|
|
|
|
// ambiguous and the program is ill-formed.
|
2013-07-04 11:08:24 +08:00
|
|
|
for (SmallVectorImpl<MatchResult>::iterator P = Best + 1,
|
|
|
|
PEnd = Matched.end();
|
2009-10-29 08:04:11 +08:00
|
|
|
P != PEnd; ++P) {
|
2010-10-13 07:32:35 +08:00
|
|
|
if (getMoreSpecializedPartialSpecialization(P->Partial, Best->Partial,
|
2010-02-09 07:07:23 +08:00
|
|
|
PointOfInstantiation)
|
2010-10-13 07:32:35 +08:00
|
|
|
== P->Partial)
|
2009-10-29 08:04:11 +08:00
|
|
|
Best = P;
|
2009-09-16 00:23:51 +08:00
|
|
|
}
|
|
|
|
|
2009-10-29 08:04:11 +08:00
|
|
|
// Determine if the best partial specialization is more specialized than
|
|
|
|
// the others.
|
|
|
|
bool Ambiguous = false;
|
2013-07-04 11:08:24 +08:00
|
|
|
for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
|
|
|
|
PEnd = Matched.end();
|
2009-10-29 08:04:11 +08:00
|
|
|
P != PEnd; ++P) {
|
|
|
|
if (P != Best &&
|
2010-10-13 07:32:35 +08:00
|
|
|
getMoreSpecializedPartialSpecialization(P->Partial, Best->Partial,
|
2010-02-09 07:07:23 +08:00
|
|
|
PointOfInstantiation)
|
2010-10-13 07:32:35 +08:00
|
|
|
!= Best->Partial) {
|
2009-10-29 08:04:11 +08:00
|
|
|
Ambiguous = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Ambiguous) {
|
|
|
|
// Partial ordering did not produce a clear winner. Complain.
|
|
|
|
ClassTemplateSpec->setInvalidDecl();
|
|
|
|
Diag(PointOfInstantiation, diag::err_partial_spec_ordering_ambiguous)
|
|
|
|
<< ClassTemplateSpec;
|
|
|
|
|
|
|
|
// Print the matching partial specializations.
|
2013-07-04 11:08:24 +08:00
|
|
|
for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
|
|
|
|
PEnd = Matched.end();
|
2009-10-29 08:04:11 +08:00
|
|
|
P != PEnd; ++P)
|
2010-10-13 07:32:35 +08:00
|
|
|
Diag(P->Partial->getLocation(), diag::note_partial_spec_match)
|
|
|
|
<< getTemplateArgumentBindingsText(
|
|
|
|
P->Partial->getTemplateParameters(),
|
|
|
|
*P->Args);
|
2009-10-29 08:04:11 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2009-09-16 00:23:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Instantiate using the best class template partial specialization.
|
2010-10-13 07:32:35 +08:00
|
|
|
ClassTemplatePartialSpecializationDecl *OrigPartialSpec = Best->Partial;
|
2009-10-29 08:04:11 +08:00
|
|
|
while (OrigPartialSpec->getInstantiatedFromMember()) {
|
|
|
|
// If we've found an explicit specialization of this class template,
|
|
|
|
// stop here and use that as the pattern.
|
|
|
|
if (OrigPartialSpec->isMemberSpecialization())
|
|
|
|
break;
|
|
|
|
|
|
|
|
OrigPartialSpec = OrigPartialSpec->getInstantiatedFromMember();
|
|
|
|
}
|
|
|
|
|
|
|
|
Pattern = OrigPartialSpec;
|
2010-10-13 07:32:35 +08:00
|
|
|
ClassTemplateSpec->setInstantiationOf(Best->Partial, Best->Args);
|
2009-06-13 06:31:52 +08:00
|
|
|
} else {
|
|
|
|
// -- If no matches are found, the instantiation is generated
|
|
|
|
// from the primary template.
|
2009-08-29 04:31:08 +08:00
|
|
|
ClassTemplateDecl *OrigTemplate = Template;
|
2009-10-14 00:30:37 +08:00
|
|
|
while (OrigTemplate->getInstantiatedFromMemberTemplate()) {
|
|
|
|
// If we've found an explicit specialization of this class template,
|
|
|
|
// stop here and use that as the pattern.
|
|
|
|
if (OrigTemplate->isMemberSpecialization())
|
|
|
|
break;
|
|
|
|
|
2009-08-29 04:31:08 +08:00
|
|
|
OrigTemplate = OrigTemplate->getInstantiatedFromMemberTemplate();
|
2009-10-14 00:30:37 +08:00
|
|
|
}
|
|
|
|
|
2009-08-29 04:31:08 +08:00
|
|
|
Pattern = OrigTemplate->getTemplatedDecl();
|
2009-05-31 17:31:02 +08:00
|
|
|
}
|
2009-03-26 05:17:03 +08:00
|
|
|
|
2009-10-27 14:26:26 +08:00
|
|
|
bool Result = InstantiateClass(PointOfInstantiation, ClassTemplateSpec,
|
|
|
|
Pattern,
|
|
|
|
getTemplateInstantiationArgs(ClassTemplateSpec),
|
2009-09-05 06:48:11 +08:00
|
|
|
TSK,
|
2009-08-24 23:23:48 +08:00
|
|
|
Complain);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-05 08:53:49 +08:00
|
|
|
return Result;
|
2009-03-26 05:17:03 +08:00
|
|
|
}
|
|
|
|
|
2009-08-26 06:02:44 +08:00
|
|
|
/// \brief Instantiates the definitions of all of the member
|
|
|
|
/// of the given class, which is an instantiation of a class template
|
|
|
|
/// or a member class of a template.
|
2009-05-14 04:28:22 +08:00
|
|
|
void
|
|
|
|
Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
|
2009-09-05 06:48:11 +08:00
|
|
|
CXXRecordDecl *Instantiation,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
|
|
|
TemplateSpecializationKind TSK) {
|
2014-04-25 06:45:46 +08:00
|
|
|
// FIXME: We need to notify the ASTMutationListener that we did all of these
|
|
|
|
// things, in case we have an explicit instantiation definition in a PCM, a
|
|
|
|
// module, or preamble, and the declaration is in an imported AST.
|
2013-11-27 16:20:38 +08:00
|
|
|
assert(
|
|
|
|
(TSK == TSK_ExplicitInstantiationDefinition ||
|
|
|
|
TSK == TSK_ExplicitInstantiationDeclaration ||
|
|
|
|
(TSK == TSK_ImplicitInstantiation && Instantiation->isLocalClass())) &&
|
|
|
|
"Unexpected template specialization kind!");
|
2014-03-08 03:56:05 +08:00
|
|
|
for (auto *D : Instantiation->decls()) {
|
2009-10-28 02:42:08 +08:00
|
|
|
bool SuppressNew = false;
|
2014-03-08 03:56:05 +08:00
|
|
|
if (auto *Function = dyn_cast<FunctionDecl>(D)) {
|
2009-10-28 02:42:08 +08:00
|
|
|
if (FunctionDecl *Pattern
|
|
|
|
= Function->getInstantiatedFromMemberFunction()) {
|
|
|
|
MemberSpecializationInfo *MSInfo
|
|
|
|
= Function->getMemberSpecializationInfo();
|
|
|
|
assert(MSInfo && "No member specialization information?");
|
2010-04-10 05:02:29 +08:00
|
|
|
if (MSInfo->getTemplateSpecializationKind()
|
|
|
|
== TSK_ExplicitSpecialization)
|
|
|
|
continue;
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
|
|
|
|
Function,
|
|
|
|
MSInfo->getTemplateSpecializationKind(),
|
2010-09-28 05:02:09 +08:00
|
|
|
MSInfo->getPointOfInstantiation(),
|
2009-10-28 02:42:08 +08:00
|
|
|
SuppressNew) ||
|
|
|
|
SuppressNew)
|
2009-10-08 23:14:33 +08:00
|
|
|
continue;
|
2014-04-25 06:45:46 +08:00
|
|
|
|
|
|
|
// C++11 [temp.explicit]p8:
|
|
|
|
// An explicit instantiation definition that names a class template
|
|
|
|
// specialization explicitly instantiates the class template
|
|
|
|
// specialization and is only an explicit instantiation definition
|
|
|
|
// of members whose definition is visible at the point of
|
|
|
|
// instantiation.
|
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition && !Pattern->isDefined())
|
2009-10-28 02:42:08 +08:00
|
|
|
continue;
|
|
|
|
|
2014-04-25 06:45:46 +08:00
|
|
|
Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
|
|
|
|
|
|
|
if (Function->isDefined()) {
|
|
|
|
// Let the ASTConsumer know that this function has been explicitly
|
|
|
|
// instantiated now, and its linkage might have changed.
|
|
|
|
Consumer.HandleTopLevelDecl(DeclGroupRef(Function));
|
|
|
|
} else if (TSK == TSK_ExplicitInstantiationDefinition) {
|
2009-10-28 02:42:08 +08:00
|
|
|
InstantiateFunctionDefinition(PointOfInstantiation, Function);
|
2014-04-25 06:45:46 +08:00
|
|
|
} else if (TSK == TSK_ImplicitInstantiation) {
|
|
|
|
PendingLocalImplicitInstantiations.push_back(
|
|
|
|
std::make_pair(Function, PointOfInstantiation));
|
2009-10-28 02:42:08 +08:00
|
|
|
}
|
2009-10-08 23:14:33 +08:00
|
|
|
}
|
2014-03-08 03:56:05 +08:00
|
|
|
} else if (auto *Var = dyn_cast<VarDecl>(D)) {
|
2013-09-28 04:14:12 +08:00
|
|
|
if (isa<VarTemplateSpecializationDecl>(Var))
|
|
|
|
continue;
|
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
if (Var->isStaticDataMember()) {
|
2009-10-28 02:42:08 +08:00
|
|
|
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
|
|
|
|
assert(MSInfo && "No member specialization information?");
|
2010-04-10 05:02:29 +08:00
|
|
|
if (MSInfo->getTemplateSpecializationKind()
|
|
|
|
== TSK_ExplicitSpecialization)
|
|
|
|
continue;
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
|
|
|
|
Var,
|
|
|
|
MSInfo->getTemplateSpecializationKind(),
|
2010-09-28 05:02:09 +08:00
|
|
|
MSInfo->getPointOfInstantiation(),
|
2009-10-28 02:42:08 +08:00
|
|
|
SuppressNew) ||
|
|
|
|
SuppressNew)
|
2009-10-08 23:14:33 +08:00
|
|
|
continue;
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition) {
|
|
|
|
// C++0x [temp.explicit]p8:
|
|
|
|
// An explicit instantiation definition that names a class template
|
|
|
|
// specialization explicitly instantiates the class template
|
|
|
|
// specialization and is only an explicit instantiation definition
|
|
|
|
// of members whose definition is visible at the point of
|
|
|
|
// instantiation.
|
|
|
|
if (!Var->getInstantiatedFromStaticDataMember()
|
|
|
|
->getOutOfLineDefinition())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
2009-10-08 15:24:58 +08:00
|
|
|
InstantiateStaticDataMemberDefinition(PointOfInstantiation, Var);
|
2009-10-28 02:42:08 +08:00
|
|
|
} else {
|
|
|
|
Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
|
|
|
}
|
|
|
|
}
|
2014-03-08 03:56:05 +08:00
|
|
|
} else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) {
|
2010-04-19 02:11:38 +08:00
|
|
|
// Always skip the injected-class-name, along with any
|
|
|
|
// redeclarations of nested classes, since both would cause us
|
|
|
|
// to try to instantiate the members of a class twice.
|
2014-11-21 06:56:34 +08:00
|
|
|
// Skip closure types; they'll get instantiated when we instantiate
|
|
|
|
// the corresponding lambda-expression.
|
|
|
|
if (Record->isInjectedClassName() || Record->getPreviousDecl() ||
|
|
|
|
Record->isLambda())
|
2009-10-08 07:56:10 +08:00
|
|
|
continue;
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo();
|
|
|
|
assert(MSInfo && "No member specialization information?");
|
2010-04-10 05:02:29 +08:00
|
|
|
|
|
|
|
if (MSInfo->getTemplateSpecializationKind()
|
|
|
|
== TSK_ExplicitSpecialization)
|
|
|
|
continue;
|
2010-09-28 05:02:09 +08:00
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
|
|
|
|
Record,
|
|
|
|
MSInfo->getTemplateSpecializationKind(),
|
2010-09-28 05:02:09 +08:00
|
|
|
MSInfo->getPointOfInstantiation(),
|
2009-10-28 02:42:08 +08:00
|
|
|
SuppressNew) ||
|
|
|
|
SuppressNew)
|
2009-10-08 23:14:33 +08:00
|
|
|
continue;
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
|
|
|
|
assert(Pattern && "Missing instantiated-from-template information");
|
|
|
|
|
2010-02-11 09:04:33 +08:00
|
|
|
if (!Record->getDefinition()) {
|
|
|
|
if (!Pattern->getDefinition()) {
|
2009-10-28 02:42:08 +08:00
|
|
|
// C++0x [temp.explicit]p8:
|
|
|
|
// An explicit instantiation definition that names a class template
|
|
|
|
// specialization explicitly instantiates the class template
|
|
|
|
// specialization and is only an explicit instantiation definition
|
|
|
|
// of members whose definition is visible at the point of
|
|
|
|
// instantiation.
|
|
|
|
if (TSK == TSK_ExplicitInstantiationDeclaration) {
|
|
|
|
MSInfo->setTemplateSpecializationKind(TSK);
|
|
|
|
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
InstantiateClass(PointOfInstantiation, Record, Pattern,
|
2009-09-05 06:48:11 +08:00
|
|
|
TemplateArgs,
|
|
|
|
TSK);
|
2010-09-28 05:02:09 +08:00
|
|
|
} else {
|
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition &&
|
|
|
|
Record->getTemplateSpecializationKind() ==
|
|
|
|
TSK_ExplicitInstantiationDeclaration) {
|
|
|
|
Record->setTemplateSpecializationKind(TSK);
|
|
|
|
MarkVTableUsed(PointOfInstantiation, Record, true);
|
|
|
|
}
|
2009-10-28 02:42:08 +08:00
|
|
|
}
|
2009-10-08 09:19:17 +08:00
|
|
|
|
2010-02-11 09:04:33 +08:00
|
|
|
Pattern = cast_or_null<CXXRecordDecl>(Record->getDefinition());
|
2009-10-28 02:42:08 +08:00
|
|
|
if (Pattern)
|
|
|
|
InstantiateClassMembers(PointOfInstantiation, Pattern, TemplateArgs,
|
|
|
|
TSK);
|
2014-03-08 03:56:05 +08:00
|
|
|
} else if (auto *Enum = dyn_cast<EnumDecl>(D)) {
|
2012-03-15 07:13:10 +08:00
|
|
|
MemberSpecializationInfo *MSInfo = Enum->getMemberSpecializationInfo();
|
|
|
|
assert(MSInfo && "No member specialization information?");
|
|
|
|
|
|
|
|
if (MSInfo->getTemplateSpecializationKind()
|
|
|
|
== TSK_ExplicitSpecialization)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (CheckSpecializationInstantiationRedecl(
|
|
|
|
PointOfInstantiation, TSK, Enum,
|
|
|
|
MSInfo->getTemplateSpecializationKind(),
|
|
|
|
MSInfo->getPointOfInstantiation(), SuppressNew) ||
|
|
|
|
SuppressNew)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Enum->getDefinition())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
EnumDecl *Pattern = Enum->getInstantiatedFromMemberEnum();
|
|
|
|
assert(Pattern && "Missing instantiated-from-template information");
|
|
|
|
|
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition) {
|
|
|
|
if (!Pattern->getDefinition())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
InstantiateEnum(PointOfInstantiation, Enum, Pattern, TemplateArgs, TSK);
|
|
|
|
} else {
|
|
|
|
MSInfo->setTemplateSpecializationKind(TSK);
|
|
|
|
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
}
|
2014-11-18 07:36:45 +08:00
|
|
|
} else if (auto *Field = dyn_cast<FieldDecl>(D)) {
|
|
|
|
// No need to instantiate in-class initializers during explicit
|
|
|
|
// instantiation.
|
|
|
|
if (Field->hasInClassInitializer() && TSK == TSK_ImplicitInstantiation) {
|
|
|
|
CXXRecordDecl *ClassPattern =
|
|
|
|
Instantiation->getTemplateInstantiationPattern();
|
|
|
|
DeclContext::lookup_result Lookup =
|
|
|
|
ClassPattern->lookup(Field->getDeclName());
|
|
|
|
assert(Lookup.size() == 1);
|
|
|
|
FieldDecl *Pattern = cast<FieldDecl>(Lookup[0]);
|
|
|
|
InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern,
|
|
|
|
TemplateArgs);
|
|
|
|
}
|
2009-05-14 04:28:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Instantiate the definitions of all of the members of the
|
|
|
|
/// given class template specialization, which was named as part of an
|
|
|
|
/// explicit instantiation.
|
2009-09-09 23:08:12 +08:00
|
|
|
void
|
2009-09-05 06:48:11 +08:00
|
|
|
Sema::InstantiateClassTemplateSpecializationMembers(
|
2009-05-14 04:28:22 +08:00
|
|
|
SourceLocation PointOfInstantiation,
|
2009-09-05 06:48:11 +08:00
|
|
|
ClassTemplateSpecializationDecl *ClassTemplateSpec,
|
|
|
|
TemplateSpecializationKind TSK) {
|
2009-05-14 04:28:22 +08:00
|
|
|
// C++0x [temp.explicit]p7:
|
|
|
|
// An explicit instantiation that names a class template
|
|
|
|
// specialization is an explicit instantion of the same kind
|
|
|
|
// (declaration or definition) of each of its members (not
|
|
|
|
// including members inherited from base classes) that has not
|
|
|
|
// been previously explicitly specialized in the translation unit
|
|
|
|
// containing the explicit instantiation, except as described
|
|
|
|
// below.
|
|
|
|
InstantiateClassMembers(PointOfInstantiation, ClassTemplateSpec,
|
2009-09-05 06:48:11 +08:00
|
|
|
getTemplateInstantiationArgs(ClassTemplateSpec),
|
|
|
|
TSK);
|
2009-05-14 04:28:22 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
StmtResult
|
2009-08-29 04:31:08 +08:00
|
|
|
Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
|
2009-08-20 15:17:43 +08:00
|
|
|
if (!S)
|
2014-05-29 22:05:12 +08:00
|
|
|
return S;
|
2009-08-20 15:17:43 +08:00
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs,
|
|
|
|
SourceLocation(),
|
|
|
|
DeclarationName());
|
|
|
|
return Instantiator.TransformStmt(S);
|
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult
|
2009-08-29 04:31:08 +08:00
|
|
|
Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
|
2009-08-11 13:31:07 +08:00
|
|
|
if (!E)
|
2014-05-29 22:05:12 +08:00
|
|
|
return E;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-11 13:31:07 +08:00
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs,
|
|
|
|
SourceLocation(),
|
|
|
|
DeclarationName());
|
|
|
|
return Instantiator.TransformExpr(E);
|
|
|
|
}
|
|
|
|
|
2012-12-19 09:39:02 +08:00
|
|
|
ExprResult Sema::SubstInitializer(Expr *Init,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
|
|
|
bool CXXDirectInit) {
|
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs,
|
|
|
|
SourceLocation(),
|
|
|
|
DeclarationName());
|
|
|
|
return Instantiator.TransformInitializer(Init, CXXDirectInit);
|
|
|
|
}
|
|
|
|
|
2015-12-25 07:58:29 +08:00
|
|
|
bool Sema::SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall,
|
2011-01-08 03:35:17 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<Expr *> &Outputs) {
|
2015-12-25 07:58:29 +08:00
|
|
|
if (Exprs.empty())
|
2011-01-08 03:35:17 +08:00
|
|
|
return false;
|
2012-12-19 09:39:02 +08:00
|
|
|
|
2011-01-08 03:35:17 +08:00
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs,
|
|
|
|
SourceLocation(),
|
|
|
|
DeclarationName());
|
2015-12-25 07:58:29 +08:00
|
|
|
return Instantiator.TransformExprs(Exprs.data(), Exprs.size(),
|
|
|
|
IsCall, Outputs);
|
2011-01-08 03:35:17 +08:00
|
|
|
}
|
|
|
|
|
2011-02-25 10:25:35 +08:00
|
|
|
NestedNameSpecifierLoc
|
|
|
|
Sema::SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs) {
|
|
|
|
if (!NNS)
|
|
|
|
return NestedNameSpecifierLoc();
|
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs, NNS.getBeginLoc(),
|
|
|
|
DeclarationName());
|
|
|
|
return Instantiator.TransformNestedNameSpecifierLoc(NNS);
|
|
|
|
}
|
|
|
|
|
2010-08-12 06:01:17 +08:00
|
|
|
/// \brief Do template substitution on declaration name info.
|
|
|
|
DeclarationNameInfo
|
|
|
|
Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs) {
|
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
|
|
|
|
NameInfo.getName());
|
|
|
|
return Instantiator.TransformDeclarationNameInfo(NameInfo);
|
|
|
|
}
|
|
|
|
|
2009-04-01 02:38:02 +08:00
|
|
|
TemplateName
|
2011-03-03 02:46:51 +08:00
|
|
|
Sema::SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,
|
|
|
|
TemplateName Name, SourceLocation Loc,
|
2009-08-29 04:31:08 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs) {
|
2009-08-06 14:41:21 +08:00
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
|
|
|
|
DeclarationName());
|
2011-03-03 02:46:51 +08:00
|
|
|
CXXScopeSpec SS;
|
|
|
|
SS.Adopt(QualifierLoc);
|
|
|
|
return Instantiator.TransformTemplateName(SS, Name, Loc);
|
2009-04-01 02:38:02 +08:00
|
|
|
}
|
2009-06-11 08:06:24 +08:00
|
|
|
|
2010-12-23 05:19:48 +08:00
|
|
|
bool Sema::Subst(const TemplateArgumentLoc *Args, unsigned NumArgs,
|
|
|
|
TemplateArgumentListInfo &Result,
|
2009-10-29 16:12:44 +08:00
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs) {
|
2009-08-05 06:27:00 +08:00
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
|
|
|
|
DeclarationName());
|
2010-12-23 05:19:48 +08:00
|
|
|
|
|
|
|
return Instantiator.TransformTemplateArguments(Args, NumArgs, Result);
|
2009-06-11 08:06:24 +08:00
|
|
|
}
|
2010-05-01 02:55:50 +08:00
|
|
|
|
2015-01-09 09:19:56 +08:00
|
|
|
static const Decl *getCanonicalParmVarDecl(const Decl *D) {
|
2012-09-27 01:57:31 +08:00
|
|
|
// When storing ParmVarDecls in the local instantiation scope, we always
|
|
|
|
// want to use the ParmVarDecl from the canonical function declaration,
|
|
|
|
// since the map is then valid for any redeclaration or definition of that
|
|
|
|
// function.
|
|
|
|
if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(D)) {
|
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
|
|
|
|
unsigned i = PV->getFunctionScopeIndex();
|
2015-01-09 09:19:56 +08:00
|
|
|
// 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)
|
|
|
|
return FD->getCanonicalDecl()->getParamDecl(i);
|
2012-09-27 01:57:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return D;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *
|
|
|
|
LocalInstantiationScope::findInstantiationOf(const Decl *D) {
|
2012-09-27 01:57:31 +08:00
|
|
|
D = getCanonicalParmVarDecl(D);
|
2011-02-18 04:34:02 +08:00
|
|
|
for (LocalInstantiationScope *Current = this; Current;
|
2010-05-01 02:55:50 +08:00
|
|
|
Current = Current->Outer) {
|
2011-02-18 04:34:02 +08:00
|
|
|
|
2010-05-01 02:55:50 +08:00
|
|
|
// Check if we found something within this scope.
|
2010-12-22 05:22:51 +08:00
|
|
|
const Decl *CheckD = D;
|
|
|
|
do {
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
LocalDeclsMap::iterator Found = Current->LocalDecls.find(CheckD);
|
2010-12-22 05:22:51 +08:00
|
|
|
if (Found != Current->LocalDecls.end())
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
return &Found->second;
|
2010-12-22 05:22:51 +08:00
|
|
|
|
|
|
|
// If this is a tag declaration, it's possible that we need to look for
|
|
|
|
// a previous declaration.
|
|
|
|
if (const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
|
2012-01-15 00:38:05 +08:00
|
|
|
CheckD = Tag->getPreviousDecl();
|
2010-12-22 05:22:51 +08:00
|
|
|
else
|
2014-05-26 14:22:03 +08:00
|
|
|
CheckD = nullptr;
|
2010-12-22 05:22:51 +08:00
|
|
|
} while (CheckD);
|
|
|
|
|
2010-05-01 02:55:50 +08:00
|
|
|
// If we aren't combined with our outer scope, we're done.
|
|
|
|
if (!Current->CombineWithOuterScope)
|
|
|
|
break;
|
|
|
|
}
|
2011-02-18 04:34:02 +08:00
|
|
|
|
2013-07-15 14:14:07 +08:00
|
|
|
// If we're performing a partial substitution during template argument
|
|
|
|
// deduction, we may not have values for template parameters yet.
|
|
|
|
if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
|
|
|
|
isa<TemplateTemplateParmDecl>(D))
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2013-07-15 14:14:07 +08:00
|
|
|
|
2015-05-15 18:10:28 +08:00
|
|
|
// Local types referenced prior to definition may require instantiation.
|
|
|
|
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
|
|
|
|
if (RD->isLocalClass())
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
// Enumeration types referenced prior to definition may appear as a result of
|
|
|
|
// error recovery.
|
|
|
|
if (isa<EnumDecl>(D))
|
2015-05-05 00:44:39 +08:00
|
|
|
return nullptr;
|
|
|
|
|
2011-02-18 04:34:02 +08:00
|
|
|
// If we didn't find the decl, then we either have a sema bug, or we have a
|
|
|
|
// forward reference to a label declaration. Return null to indicate that
|
|
|
|
// we have an uninstantiated label.
|
|
|
|
assert(isa<LabelDecl>(D) && "declaration not instantiated in this scope");
|
2014-05-26 14:22:03 +08:00
|
|
|
return nullptr;
|
2010-05-01 02:55:50 +08:00
|
|
|
}
|
|
|
|
|
2010-08-25 13:32:35 +08:00
|
|
|
void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
|
2012-09-27 01:57:31 +08:00
|
|
|
D = getCanonicalParmVarDecl(D);
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
|
2015-01-09 09:19:56 +08:00
|
|
|
if (Stored.isNull()) {
|
|
|
|
#ifndef NDEBUG
|
|
|
|
// It should not be present in any surrounding scope either.
|
|
|
|
LocalInstantiationScope *Current = this;
|
|
|
|
while (Current->CombineWithOuterScope && Current->Outer) {
|
|
|
|
Current = Current->Outer;
|
|
|
|
assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() &&
|
|
|
|
"Instantiated local in inner and outer scopes");
|
|
|
|
}
|
|
|
|
#endif
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
Stored = Inst;
|
2015-01-09 09:19:56 +08:00
|
|
|
} else if (DeclArgumentPack *Pack = Stored.dyn_cast<DeclArgumentPack *>()) {
|
2015-09-30 22:04:23 +08:00
|
|
|
Pack->push_back(cast<ParmVarDecl>(Inst));
|
2015-01-09 09:19:56 +08:00
|
|
|
} else {
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
assert(Stored.get<Decl *>() == Inst && "Already instantiated this local");
|
2015-01-09 09:19:56 +08:00
|
|
|
}
|
2010-05-01 02:55:50 +08:00
|
|
|
}
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
|
2015-09-30 22:04:23 +08:00
|
|
|
void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,
|
|
|
|
ParmVarDecl *Inst) {
|
2012-09-27 01:57:31 +08:00
|
|
|
D = getCanonicalParmVarDecl(D);
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
DeclArgumentPack *Pack = LocalDecls[D].get<DeclArgumentPack *>();
|
|
|
|
Pack->push_back(Inst);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {
|
2015-01-09 09:19:56 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
// This should be the first time we've been told about this decl.
|
|
|
|
for (LocalInstantiationScope *Current = this;
|
|
|
|
Current && Current->CombineWithOuterScope; Current = Current->Outer)
|
|
|
|
assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() &&
|
|
|
|
"Creating local pack after instantiation of local");
|
|
|
|
#endif
|
|
|
|
|
2012-09-27 01:57:31 +08:00
|
|
|
D = getCanonicalParmVarDecl(D);
|
Implement substitution of a function parameter pack for its set of
instantiated function parameters, enabling instantiation of arbitrary
pack expansions involving function parameter packs. At this point, we
can now correctly compile a simple, variadic print() example:
#include <iostream>
#include <string>
void print() {}
template<typename Head, typename ...Tail>
void print(const Head &head, const Tail &...tail) {
std::cout << head;
print(tail...);
}
int main() {
std::string hello = "Hello";
print(hello, ", world!", " ", 2011, '\n');
}
llvm-svn: 123000
2011-01-08 00:43:16 +08:00
|
|
|
llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
|
|
|
|
DeclArgumentPack *Pack = new DeclArgumentPack;
|
|
|
|
Stored = Pack;
|
|
|
|
ArgumentPacks.push_back(Pack);
|
|
|
|
}
|
|
|
|
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
void LocalInstantiationScope::SetPartiallySubstitutedPack(NamedDecl *Pack,
|
|
|
|
const TemplateArgument *ExplicitArgs,
|
|
|
|
unsigned NumExplicitArgs) {
|
|
|
|
assert((!PartiallySubstitutedPack || PartiallySubstitutedPack == Pack) &&
|
|
|
|
"Already have a partially-substituted pack");
|
|
|
|
assert((!PartiallySubstitutedPack
|
|
|
|
|| NumArgsInPartiallySubstitutedPack == NumExplicitArgs) &&
|
|
|
|
"Wrong number of arguments in partially-substituted pack");
|
|
|
|
PartiallySubstitutedPack = Pack;
|
|
|
|
ArgsInPartiallySubstitutedPack = ExplicitArgs;
|
|
|
|
NumArgsInPartiallySubstitutedPack = NumExplicitArgs;
|
|
|
|
}
|
|
|
|
|
|
|
|
NamedDecl *LocalInstantiationScope::getPartiallySubstitutedPack(
|
|
|
|
const TemplateArgument **ExplicitArgs,
|
|
|
|
unsigned *NumExplicitArgs) const {
|
|
|
|
if (ExplicitArgs)
|
2014-05-26 14:22:03 +08:00
|
|
|
*ExplicitArgs = nullptr;
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
if (NumExplicitArgs)
|
|
|
|
*NumExplicitArgs = 0;
|
|
|
|
|
|
|
|
for (const LocalInstantiationScope *Current = this; Current;
|
|
|
|
Current = Current->Outer) {
|
|
|
|
if (Current->PartiallySubstitutedPack) {
|
|
|
|
if (ExplicitArgs)
|
|
|
|
*ExplicitArgs = Current->ArgsInPartiallySubstitutedPack;
|
|
|
|
if (NumExplicitArgs)
|
|
|
|
*NumExplicitArgs = Current->NumArgsInPartiallySubstitutedPack;
|
|
|
|
|
|
|
|
return Current->PartiallySubstitutedPack;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Current->CombineWithOuterScope)
|
|
|
|
break;
|
|
|
|
}
|
2014-05-26 14:22:03 +08:00
|
|
|
|
|
|
|
return nullptr;
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
}
|