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"
|
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-05-27 04:50:29 +08:00
|
|
|
#include "clang/AST/ASTConsumer.h"
|
2009-02-28 03:31:52 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/AST/DeclTemplate.h"
|
|
|
|
#include "clang/Basic/LangOptions.h"
|
|
|
|
|
|
|
|
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();
|
2011-05-22 08:21:10 +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)
|
|
|
|
Result.addOuterTemplateArguments(0, 0);
|
|
|
|
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;
|
2011-03-06 01:54:25 +08:00
|
|
|
} else if (FunctionTemplateDecl *FunTmpl
|
|
|
|
= Function->getDescribedFunctionTemplate()) {
|
|
|
|
// Add the "injected" template arguments.
|
|
|
|
std::pair<const TemplateArgument *, unsigned>
|
|
|
|
Injected = FunTmpl->getInjectedTemplateArgs();
|
|
|
|
Result.addOuterTemplateArguments(Injected.first, Injected.second);
|
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();
|
|
|
|
const TemplateSpecializationType *TST
|
|
|
|
= cast<TemplateSpecializationType>(Context.getCanonicalType(T));
|
|
|
|
Result.addOuterTemplateArguments(TST->getArgs(), TST->getNumArgs());
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2009-03-10 08:06:19 +08:00
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
2009-05-19 01:01:57 +08:00
|
|
|
Decl *Entity,
|
2009-03-10 08:06:19 +08:00
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2009-03-11 04:44:00 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation,
|
|
|
|
InstantiationRange);
|
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind = ActiveTemplateInstantiation::TemplateInstantiation;
|
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = Entity;
|
2009-03-13 02:36:18 +08:00
|
|
|
Inst.TemplateArgs = 0;
|
|
|
|
Inst.NumTemplateArgs = 0;
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
FunctionDecl *Entity, ExceptionSpecification,
|
|
|
|
SourceRange InstantiationRange)
|
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation,
|
|
|
|
InstantiationRange);
|
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind = ActiveTemplateInstantiation::ExceptionSpecInstantiation;
|
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = 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
|
|
|
Inst.TemplateArgs = 0;
|
|
|
|
Inst.NumTemplateArgs = 0;
|
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-16 09:09:10 +08:00
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
TemplateDecl *Template,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2009-03-11 04:44:00 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation,
|
|
|
|
InstantiationRange);
|
|
|
|
if (!Invalid) {
|
2009-03-10 08:06:19 +08:00
|
|
|
ActiveTemplateInstantiation Inst;
|
2009-09-09 23:08:12 +08:00
|
|
|
Inst.Kind
|
2009-03-11 04:44:00 +08:00
|
|
|
= ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation;
|
2009-03-10 08:06:19 +08:00
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = Template;
|
2012-07-16 09:09:10 +08:00
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
2009-03-10 08:06:19 +08:00
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
2011-01-28 06:31:44 +08:00
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
2009-03-10 08:06:19 +08:00
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-16 09:09:10 +08:00
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
FunctionTemplateDecl *FunctionTemplate,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
ActiveTemplateInstantiation::InstantiationKind Kind,
|
|
|
|
sema::TemplateDeductionInfo &DeductionInfo,
|
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2012-07-08 10:38:24 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
|
2009-07-02 06:01:06 +08:00
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind = Kind;
|
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = FunctionTemplate;
|
2012-07-16 09:09:10 +08:00
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
2010-10-13 07:32:35 +08:00
|
|
|
Inst.DeductionInfo = &DeductionInfo;
|
2009-07-02 06:01:06 +08:00
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
2011-01-28 06:31:44 +08:00
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
2009-07-02 06:01:06 +08:00
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
2009-11-12 05:54:23 +08:00
|
|
|
|
|
|
|
if (!Inst.isInstantiationRecord())
|
|
|
|
++SemaRef.NonInstantiationEntries;
|
2009-07-02 06:01:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-16 09:09:10 +08:00
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
ClassTemplatePartialSpecializationDecl *PartialSpec,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
sema::TemplateDeductionInfo &DeductionInfo,
|
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2012-07-08 10:38:24 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
|
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
|
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = PartialSpec;
|
2012-07-16 09:09:10 +08:00
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
2012-07-08 10:38:24 +08:00
|
|
|
Inst.DeductionInfo = &DeductionInfo;
|
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
|
|
|
}
|
2009-06-11 07:47:09 +08:00
|
|
|
}
|
|
|
|
|
2012-07-16 09:09:10 +08:00
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
|
|
|
ParmVarDecl *Param,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2009-11-12 03:13:48 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
|
2009-09-05 13:14:19 +08:00
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind
|
|
|
|
= ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation;
|
2009-11-12 03:13:48 +08:00
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = Param;
|
2012-07-16 09:09:10 +08:00
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
2009-11-12 03:13:48 +08:00
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
2011-01-28 06:31:44 +08:00
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
2009-11-12 03:13:48 +08:00
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
2012-07-16 09:09:10 +08:00
|
|
|
NamedDecl *Template, NonTypeTemplateParmDecl *Param,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2012-07-08 10:38:24 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
|
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
|
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
|
|
|
Inst.Template = Template;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = Param;
|
2012-07-16 09:09:10 +08:00
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
2012-07-08 10:38:24 +08:00
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
|
|
|
}
|
2009-11-12 03:13:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
2012-07-16 09:09:10 +08:00
|
|
|
NamedDecl *Template, TemplateTemplateParmDecl *Param,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2012-07-08 10:38:24 +08:00
|
|
|
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
|
|
|
|
if (!Invalid) {
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
|
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
|
|
|
Inst.Template = Template;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = Param;
|
2012-07-16 09:09:10 +08:00
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
2012-07-08 10:38:24 +08:00
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
|
|
|
}
|
2009-11-12 05:54:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Sema::InstantiatingTemplate::
|
|
|
|
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
2012-07-16 09:09:10 +08:00
|
|
|
TemplateDecl *Template, NamedDecl *Param,
|
|
|
|
ArrayRef<TemplateArgument> TemplateArgs,
|
|
|
|
SourceRange InstantiationRange)
|
2011-01-28 06:31:44 +08:00
|
|
|
: SemaRef(SemaRef),
|
|
|
|
SavedInNonInstantiationSFINAEContext(
|
|
|
|
SemaRef.InNonInstantiationSFINAEContext)
|
|
|
|
{
|
2009-11-12 05:54:23 +08:00
|
|
|
Invalid = false;
|
|
|
|
|
|
|
|
ActiveTemplateInstantiation Inst;
|
|
|
|
Inst.Kind = ActiveTemplateInstantiation::DefaultTemplateArgumentChecking;
|
|
|
|
Inst.PointOfInstantiation = PointOfInstantiation;
|
|
|
|
Inst.Template = Template;
|
2012-11-16 16:40:59 +08:00
|
|
|
Inst.Entity = Param;
|
2012-07-16 09:09:10 +08:00
|
|
|
Inst.TemplateArgs = TemplateArgs.data();
|
|
|
|
Inst.NumTemplateArgs = TemplateArgs.size();
|
2009-11-12 05:54:23 +08:00
|
|
|
Inst.InstantiationRange = InstantiationRange;
|
2011-01-28 06:31:44 +08:00
|
|
|
SemaRef.InNonInstantiationSFINAEContext = false;
|
2009-11-12 05:54:23 +08:00
|
|
|
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
|
|
|
|
|
|
|
assert(!Inst.isInstantiationRecord());
|
|
|
|
++SemaRef.NonInstantiationEntries;
|
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;
|
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;
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVector<ActiveTemplateInstantiation, 16>::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,
|
2009-07-25 04:34:43 +08:00
|
|
|
diag::note_template_static_data_member_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;
|
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);
|
2009-03-11 04:44:00 +08:00
|
|
|
std::string TemplateArgsStr
|
2009-03-31 06:58:21 +08:00
|
|
|
= TemplateSpecializationType::PrintTemplateArgumentList(
|
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)
|
|
|
|
<< (Template->getNameAsString() + TemplateArgsStr)
|
|
|
|
<< 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
|
|
|
|
2009-09-05 13:14:19 +08:00
|
|
|
std::string TemplateArgsStr
|
|
|
|
= TemplateSpecializationType::PrintTemplateArgumentList(
|
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)
|
2009-09-05 13:38:54 +08:00
|
|
|
<< (FD->getNameAsString() + TemplateArgsStr)
|
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() + "'";
|
2011-01-05 07:35:54 +08:00
|
|
|
|
|
|
|
TemplateParameterList *TemplateParams = 0;
|
|
|
|
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: {
|
2011-01-05 07:35:54 +08:00
|
|
|
TemplateParameterList *TemplateParams = 0;
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-28 06:31:44 +08:00
|
|
|
llvm::Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
|
|
|
|
if (InNonInstantiationSFINAEContext)
|
|
|
|
return llvm::Optional<TemplateDeductionInfo *>(0);
|
|
|
|
|
2009-06-14 15:33:30 +08:00
|
|
|
for (SmallVector<ActiveTemplateInstantiation, 16>::const_reverse_iterator
|
|
|
|
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.
|
2011-01-28 06:31:44 +08:00
|
|
|
return llvm::Optional<TemplateDeductionInfo *>();
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-28 06:31:44 +08:00
|
|
|
return llvm::Optional<TemplateDeductionInfo *>();
|
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,
|
2011-09-22 10:34:54 +08:00
|
|
|
llvm::ArrayRef<UnexpandedParameterPack> Unexpanded,
|
2010-12-21 06:05:00 +08:00
|
|
|
bool &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
|
|
|
bool &RetainExpansion,
|
2011-01-15 01:04:44 +08:00
|
|
|
llvm::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;
|
|
|
|
llvm::tie(Depth, Index) = getDepthAndIndex(PartialPack);
|
|
|
|
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;
|
|
|
|
llvm::tie(Depth, Index) = getDepthAndIndex(PartialPack);
|
|
|
|
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) {
|
|
|
|
SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2011-03-03 02:07:45 +08:00
|
|
|
TemplateName TransformTemplateName(CXXScopeSpec &SS,
|
|
|
|
TemplateName Name,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
QualType ObjectType = QualType(),
|
|
|
|
NamedDecl *FirstQualifierInScope = 0);
|
|
|
|
|
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);
|
|
|
|
|
2010-05-01 02:55:50 +08:00
|
|
|
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
|
2010-11-12 16:19:04 +08:00
|
|
|
FunctionProtoTypeLoc TL);
|
2012-04-16 15:05:22 +08:00
|
|
|
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
|
|
|
|
FunctionProtoTypeLoc TL,
|
|
|
|
CXXRecordDecl *ThisContext,
|
|
|
|
unsigned ThisTypeQuals);
|
|
|
|
|
2011-01-15 06:40:04 +08:00
|
|
|
ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
|
2011-05-02 06:35:37 +08:00
|
|
|
int indexAdjustment,
|
2012-01-26 00:15:54 +08:00
|
|
|
llvm::Optional<unsigned> NumExpansions,
|
|
|
|
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);
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult TransformCallExpr(CallExpr *CE) {
|
2010-07-07 03:51:49 +08:00
|
|
|
getSema().CallsUndergoingInstantiation.push_back(CE);
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult Result =
|
2010-07-07 03:51:49 +08:00
|
|
|
TreeTransform<TemplateInstantiator>::TransformCallExpr(CE);
|
|
|
|
getSema().CallsUndergoingInstantiation.pop_back();
|
2012-08-24 05:35:17 +08:00
|
|
|
return Result;
|
2010-07-07 03:51:49 +08:00
|
|
|
}
|
2011-07-15 13:09:51 +08:00
|
|
|
|
2012-07-25 11:56:55 +08:00
|
|
|
ExprResult TransformLambdaExpr(LambdaExpr *E) {
|
|
|
|
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
|
|
|
|
return TreeTransform<TemplateInstantiator>::TransformLambdaExpr(E);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExprResult TransformLambdaScope(LambdaExpr *E,
|
|
|
|
CXXMethodDecl *CallOperator) {
|
|
|
|
CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(),
|
|
|
|
TSK_ImplicitInstantiation);
|
|
|
|
return TreeTransform<TemplateInstantiator>::
|
|
|
|
TransformLambdaScope(E, CallOperator);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
};
|
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;
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
return 0;
|
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");
|
|
|
|
|
2011-01-15 14:45:20 +08:00
|
|
|
assert(getSema().ArgumentPackSubstitutionIndex >= 0);
|
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(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
|
2011-01-05 23:48:55 +08:00
|
|
|
Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
return 0;
|
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)
|
2010-12-21 06:48:17 +08:00
|
|
|
return 0;
|
|
|
|
|
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(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
|
2010-12-21 06:48:17 +08:00
|
|
|
Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
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,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
|
|
|
|
Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
const TemplateArgument &ArgPack = SubstPack->getArgumentPack();
|
|
|
|
assert(getSema().ArgumentPackSubstitutionIndex < (int)ArgPack.pack_size() &&
|
|
|
|
"Pack substitution index out-of-range");
|
|
|
|
return ArgPack.pack_begin()[getSema().ArgumentPackSubstitutionIndex]
|
|
|
|
.getAsTemplate();
|
|
|
|
}
|
|
|
|
|
|
|
|
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())
|
2010-10-26 15:05:15 +08:00
|
|
|
return SemaRef.Owned(E);
|
2009-09-11 09:22:35 +08:00
|
|
|
|
|
|
|
FunctionDecl *currentDecl = getSema().getCurFunctionDecl();
|
|
|
|
assert(currentDecl && "Must have current function declaration when "
|
|
|
|
"instantiating.");
|
|
|
|
|
|
|
|
PredefinedExpr::IdentType IT = E->getIdentType();
|
|
|
|
|
2010-02-12 02:20:28 +08:00
|
|
|
unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
|
2009-09-11 09:22:35 +08:00
|
|
|
|
|
|
|
llvm::APInt LengthI(32, Length + 1);
|
2012-06-26 06:34:48 +08:00
|
|
|
QualType ResTy;
|
|
|
|
if (IT == PredefinedExpr::LFunction)
|
|
|
|
ResTy = getSema().Context.WCharTy.withConst();
|
|
|
|
else
|
|
|
|
ResTy = getSema().Context.CharTy.withConst();
|
2009-09-11 09:22:35 +08:00
|
|
|
ResTy = getSema().Context.getConstantArrayType(ResTy, LengthI,
|
|
|
|
ArrayType::Normal, 0);
|
|
|
|
PredefinedExpr *PE =
|
|
|
|
new (getSema().Context) PredefinedExpr(E->getLocation(), ResTy, IT);
|
|
|
|
return getSema().Owned(PE);
|
|
|
|
}
|
|
|
|
|
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()))
|
2010-10-26 15:05:15 +08:00
|
|
|
return SemaRef.Owned(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
|
|
|
}
|
|
|
|
|
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(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
|
2010-12-24 08:15:10 +08:00
|
|
|
Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
|
|
|
|
}
|
2009-11-01 01:21:17 +08:00
|
|
|
|
2011-07-15 13:09:51 +08:00
|
|
|
return transformNonTypeTemplateParmRef(NTTP, E->getLocation(), Arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2012-07-09 11:07:20 +08:00
|
|
|
// If the argument is a pack expansion, the parameter must actually be a
|
|
|
|
// parameter pack, and we should substitute the pattern itself, producing
|
|
|
|
// an expression which contains an unexpanded parameter pack.
|
|
|
|
if (arg.isPackExpansion()) {
|
|
|
|
assert(parm->isParameterPack() && "pack expansion for non-pack");
|
|
|
|
arg = arg.getPackExpansionPattern();
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
result = SemaRef.Owned(argExpr);
|
|
|
|
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.
|
|
|
|
VD = 0;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2011-07-15 13:09:51 +08:00
|
|
|
Expr *resultExpr = result.take();
|
|
|
|
return SemaRef.Owned(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.
|
|
|
|
return getSema().Owned(E);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TemplateArgument &ArgPack = E->getArgumentPack();
|
|
|
|
unsigned Index = (unsigned)getSema().ArgumentPackSubstitutionIndex;
|
|
|
|
assert(Index < ArgPack.pack_size() && "Substitution index out-of-range");
|
|
|
|
|
|
|
|
const TemplateArgument &Arg = ArgPack.pack_begin()[Index];
|
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.
|
|
|
|
llvm::SmallVector<Decl*, 8> Parms;
|
|
|
|
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 *>()) {
|
|
|
|
// If this is a reference to a function parameter pack which we can substitute
|
|
|
|
// but can't yet expand, build a FunctionParmPackExpr for it.
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2010-05-01 02:55:50 +08:00
|
|
|
QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
|
2010-11-12 16:19:04 +08:00
|
|
|
FunctionProtoTypeLoc TL) {
|
2010-05-01 02:55:50 +08:00
|
|
|
// We need a local instantiation scope for this function prototype.
|
2010-08-25 13:32:35 +08:00
|
|
|
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
|
2010-11-12 16:19:04 +08:00
|
|
|
return inherited::TransformFunctionProtoType(TLB, TL);
|
2010-03-11 17:03:00 +08:00
|
|
|
}
|
|
|
|
|
2012-04-16 15:05:22 +08:00
|
|
|
QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
|
|
|
|
FunctionProtoTypeLoc TL,
|
|
|
|
CXXRecordDecl *ThisContext,
|
|
|
|
unsigned ThisTypeQuals) {
|
|
|
|
// We need a local instantiation scope for this function prototype.
|
|
|
|
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
|
|
|
|
return inherited::TransformFunctionProtoType(TLB, TL, ThisContext,
|
|
|
|
ThisTypeQuals);
|
|
|
|
}
|
|
|
|
|
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,
|
2012-01-26 00:15:54 +08:00
|
|
|
llvm::Optional<unsigned> NumExpansions,
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
|
2010-12-21 06:05:00 +08:00
|
|
|
Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
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.
|
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
|
|
|
TemplateTypeParmDecl *NewTTPDecl = 0;
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
const TemplateArgument &ArgPack = TL.getTypePtr()->getArgumentPack();
|
|
|
|
unsigned Index = (unsigned)getSema().ArgumentPackSubstitutionIndex;
|
|
|
|
assert(Index < ArgPack.pack_size() && "Substitution index out-of-range");
|
|
|
|
|
|
|
|
QualType Result = ArgPack.pack_begin()[Index].getAsType();
|
|
|
|
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())
|
|
|
|
return 0;
|
|
|
|
|
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())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
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) {
|
2011-07-01 09:22:09 +08:00
|
|
|
if (T->getType()->isInstantiationDependentType() ||
|
|
|
|
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();
|
2010-04-10 01:38:44 +08:00
|
|
|
if (!isa<FunctionProtoTypeLoc>(TL))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
FunctionProtoTypeLoc FP = cast<FunctionProtoTypeLoc>(TL);
|
|
|
|
for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) {
|
|
|
|
ParmVarDecl *P = FP.getArg(I);
|
|
|
|
|
2011-05-10 04:45:16 +08:00
|
|
|
// The parameter's type as written might be dependent even if the
|
|
|
|
// decayed type was not dependent.
|
|
|
|
if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo())
|
2011-07-01 09:22:09 +08:00
|
|
|
if (TSInfo->getType()->isInstantiationDependentType())
|
2011-05-10 04:45:16 +08:00
|
|
|
return true;
|
|
|
|
|
2010-04-10 01:38:44 +08:00
|
|
|
// TODO: currently we always rebuild expressions. When we
|
|
|
|
// properly get lazier about this, we should use the same
|
|
|
|
// logic to avoid rebuilding prototypes here.
|
2011-01-06 05:14:17 +08:00
|
|
|
if (P->hasDefaultArg())
|
2010-04-10 01:38:44 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A form of SubstType intended specifically for instantiating the
|
|
|
|
/// type of a FunctionDecl. Its purpose is solely to force the
|
|
|
|
/// instantiation of default-argument expressions.
|
|
|
|
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");
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (FunctionProtoTypeLoc *Proto = dyn_cast<FunctionProtoTypeLoc>(&TL)) {
|
|
|
|
Result = Instantiator.TransformFunctionProtoType(TLB, *Proto, ThisContext,
|
|
|
|
ThisTypeQuals);
|
|
|
|
} else {
|
|
|
|
Result = Instantiator.TransformType(TLB, TL);
|
|
|
|
}
|
2010-04-10 01:38:44 +08:00
|
|
|
if (Result.isNull())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return TLB.getTypeSourceInfo(Context, Result);
|
|
|
|
}
|
|
|
|
|
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,
|
2012-01-26 00:15:54 +08:00
|
|
|
llvm::Optional<unsigned> NumExpansions,
|
|
|
|
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();
|
2011-01-06 07:12:31 +08:00
|
|
|
TypeSourceInfo *NewDI = 0;
|
|
|
|
|
|
|
|
TypeLoc OldTL = OldDI->getTypeLoc();
|
|
|
|
if (isa<PackExpansionTypeLoc>(OldTL)) {
|
|
|
|
PackExpansionTypeLoc ExpansionTL = cast<PackExpansionTypeLoc>(OldTL);
|
|
|
|
|
|
|
|
// We have a function parameter pack. Substitute into the pattern of the
|
|
|
|
// expansion.
|
|
|
|
NewDI = SubstType(ExpansionTL.getPatternLoc(), TemplateArgs,
|
|
|
|
OldParm->getLocation(), OldParm->getDeclName());
|
|
|
|
if (!NewDI)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
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();
|
|
|
|
return 0;
|
|
|
|
}
|
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)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (NewDI->getType()->isVoidType()) {
|
|
|
|
Diag(OldParm->getLocation(), diag::err_param_with_void_type);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2010-04-20 06:54:31 +08:00
|
|
|
OldParm->getStorageClass(),
|
|
|
|
OldParm->getStorageClassAsWritten());
|
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)
|
|
|
|
return 0;
|
2010-05-20 01:02:24 +08:00
|
|
|
|
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);
|
2012-05-01 14:05:57 +08:00
|
|
|
} else if (Expr *Arg = OldParm->getDefaultArg())
|
|
|
|
// 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);
|
2010-07-14 04:05:58 +08:00
|
|
|
|
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,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<QualType> &ParamTypes,
|
|
|
|
SmallVectorImpl<ParmVarDecl *> *OutParams) {
|
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());
|
|
|
|
return Instantiator.TransformFunctionTypeParams(Loc, Params, NumParams, 0,
|
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
|
|
|
ParamTypes, OutParams);
|
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;
|
2009-09-09 23:08:12 +08:00
|
|
|
for (ClassTemplateSpecializationDecl::base_class_iterator
|
2009-03-26 05:17:03 +08:00
|
|
|
Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end();
|
2009-03-11 02:52:44 +08:00
|
|
|
Base != BaseEnd; ++Base) {
|
2009-03-03 12:44:36 +08:00
|
|
|
if (!Base->getType()->isDependentType()) {
|
2009-07-23 01:41:53 +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;
|
2011-01-04 06:36:02 +08:00
|
|
|
if (Base->isPackExpansion()) {
|
|
|
|
// 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;
|
2011-01-04 06:36:02 +08:00
|
|
|
collectUnexpandedParameterPacks(Base->getTypeSourceInfo()->getTypeLoc(),
|
|
|
|
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;
|
2011-01-15 01:04:44 +08:00
|
|
|
llvm::Optional<unsigned> NumExpansions;
|
2011-01-04 06:36:02 +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);
|
|
|
|
|
|
|
|
TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
|
|
|
|
TemplateArgs,
|
|
|
|
Base->getSourceRange().getBegin(),
|
|
|
|
DeclarationName());
|
|
|
|
if (!BaseTypeLoc) {
|
|
|
|
Invalid = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CXXBaseSpecifier *InstantiatedBase
|
|
|
|
= CheckBaseSpecifier(Instantiation,
|
|
|
|
Base->getSourceRange(),
|
|
|
|
Base->isVirtual(),
|
|
|
|
Base->getAccessSpecifierAsWritten(),
|
|
|
|
BaseTypeLoc,
|
|
|
|
SourceLocation()))
|
|
|
|
InstantiatedBases.push_back(InstantiatedBase);
|
|
|
|
else
|
|
|
|
Invalid = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The resulting base specifier will (still) be a pack expansion.
|
|
|
|
EllipsisLoc = Base->getEllipsisLoc();
|
2011-03-02 10:04:06 +08:00
|
|
|
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
|
|
|
|
BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
|
|
|
|
TemplateArgs,
|
|
|
|
Base->getSourceRange().getBegin(),
|
|
|
|
DeclarationName());
|
|
|
|
} else {
|
|
|
|
BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
|
|
|
|
TemplateArgs,
|
|
|
|
Base->getSourceRange().getBegin(),
|
|
|
|
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,
|
2009-03-03 12:44:36 +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;
|
|
|
|
}
|
|
|
|
|
2009-03-11 02:52:44 +08:00
|
|
|
if (!Invalid &&
|
2009-05-21 17:52:38 +08:00
|
|
|
AttachBaseSpecifiers(Instantiation, InstantiatedBases.data(),
|
2009-03-03 12:44:36 +08:00
|
|
|
InstantiatedBases.size()))
|
|
|
|
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);
|
|
|
|
S.Diag(Pattern->getLocation(), diag::note_member_of_template_here);
|
|
|
|
} 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
|
|
|
}
|
|
|
|
|
2009-03-26 05:23:52 +08:00
|
|
|
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
2009-03-10 08:06:19 +08:00
|
|
|
if (Inst)
|
|
|
|
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
|
|
|
|
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();
|
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;
|
|
|
|
SmallVector<std::pair<FieldDecl*, FieldDecl*>, 4>
|
2011-06-12 01:19:42 +08:00
|
|
|
FieldsWithMemberInitializers;
|
2012-01-21 06:50:54 +08:00
|
|
|
// Delay instantiation of late parsed attributes.
|
|
|
|
LateInstantiatedAttrVec LateAttrs;
|
|
|
|
Instantiator.enableLateAttributeInstantiation(&LateAttrs);
|
|
|
|
|
2009-06-30 10:36:12 +08:00
|
|
|
for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
|
2009-09-09 23:08:12 +08:00
|
|
|
MemberEnd = Pattern->decls_end();
|
2009-04-10 05:40:53 +08:00
|
|
|
Member != MemberEnd; ++Member) {
|
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.
|
|
|
|
if ((*Member)->getDeclContext() != Pattern)
|
|
|
|
continue;
|
|
|
|
|
2010-11-11 03:44:59 +08:00
|
|
|
if ((*Member)->isInvalidDecl()) {
|
2012-07-12 06:37:56 +08:00
|
|
|
Instantiation->setInvalidDecl();
|
2010-11-11 03:44:59 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2011-06-12 01:19:42 +08:00
|
|
|
FieldDecl *OldField = cast<FieldDecl>(*Member);
|
|
|
|
if (OldField->getInClassInitializer())
|
|
|
|
FieldsWithMemberInitializers.push_back(std::make_pair(OldField,
|
|
|
|
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.
|
2011-09-22 10:58:26 +08:00
|
|
|
ActOnFields(0, Instantiation->getLocation(), Instantiation, Fields,
|
|
|
|
SourceLocation(), SourceLocation(), 0);
|
2010-07-03 01:43:08 +08:00
|
|
|
CheckCompletedCXXClass(Instantiation);
|
2011-06-12 01:19:42 +08:00
|
|
|
|
|
|
|
// Attach any in-class member initializers now the class is complete.
|
2012-05-17 20:01:52 +08:00
|
|
|
if (!FieldsWithMemberInitializers.empty()) {
|
2012-04-16 15:05:22 +08:00
|
|
|
// C++11 [expr.prim.general]p4:
|
|
|
|
// Otherwise, if a member-declarator declares a non-static data member
|
|
|
|
// (9.2) of a class X, the expression this is a prvalue of type "pointer
|
|
|
|
// to X" within the optional brace-or-equal-initializer. It shall not
|
|
|
|
// appear elsewhere in the member-declarator.
|
|
|
|
CXXThisScopeRAII ThisScope(*this, Instantiation, (unsigned)0);
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = FieldsWithMemberInitializers.size(); I != N; ++I) {
|
|
|
|
FieldDecl *OldField = FieldsWithMemberInitializers[I].first;
|
|
|
|
FieldDecl *NewField = FieldsWithMemberInitializers[I].second;
|
|
|
|
Expr *OldInit = OldField->getInClassInitializer();
|
|
|
|
|
|
|
|
ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
|
|
|
|
/*CXXDirectInit=*/false);
|
|
|
|
if (NewInit.isInvalid())
|
|
|
|
NewField->setInvalidDecl();
|
|
|
|
else {
|
|
|
|
Expr *Init = NewInit.take();
|
|
|
|
assert(Init && "no-argument initializer in class");
|
|
|
|
assert(!isa<ParenListExpr>(Init) && "call-style init in class");
|
2012-06-10 11:12:00 +08:00
|
|
|
ActOnCXXInClassMemberInitializer(NewField, Init->getLocStart(), Init);
|
2012-04-16 15:05:22 +08:00
|
|
|
}
|
2011-07-20 08:12:52 +08:00
|
|
|
}
|
2011-06-12 01:19:42 +08:00
|
|
|
}
|
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;
|
|
|
|
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
|
|
|
|
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.
|
|
|
|
for (TemplateDeclInstantiator::delayed_partial_spec_iterator
|
|
|
|
P = Instantiator.delayed_partial_spec_begin(),
|
|
|
|
PEnd = Instantiator.delayed_partial_spec_end();
|
|
|
|
P != PEnd; ++P) {
|
|
|
|
if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
|
|
|
|
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);
|
|
|
|
if (Inst)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
bool
|
2009-03-26 05:17:03 +08:00
|
|
|
Sema::InstantiateClassTemplateSpecialization(
|
2009-10-27 14:26:26 +08:00
|
|
|
SourceLocation PointOfInstantiation,
|
2009-03-26 05:17:03 +08:00
|
|
|
ClassTemplateSpecializationDecl *ClassTemplateSpec,
|
2009-09-05 06:48:11 +08:00
|
|
|
TemplateSpecializationKind TSK,
|
2009-08-24 23:23:48 +08:00
|
|
|
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-03-26 05:17:03 +08:00
|
|
|
|
2009-09-12 05:19:12 +08:00
|
|
|
// Check whether we have already instantiated or specialized this class
|
|
|
|
// template specialization.
|
|
|
|
if (ClassTemplateSpec->getSpecializationKind() != TSK_Undeclared) {
|
|
|
|
if (ClassTemplateSpec->getSpecializationKind() ==
|
|
|
|
TSK_ExplicitInstantiationDeclaration &&
|
|
|
|
TSK == TSK_ExplicitInstantiationDefinition) {
|
|
|
|
// An explicit instantiation definition follows an explicit instantiation
|
|
|
|
// declaration (C++0x [temp.explicit]p10); go ahead and perform the
|
|
|
|
// explicit instantiation.
|
|
|
|
ClassTemplateSpec->setSpecializationKind(TSK);
|
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
|
|
|
|
|
|
|
// If this is an explicit instantiation definition, mark the
|
|
|
|
// vtable as used.
|
2011-12-21 04:32:49 +08:00
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition &&
|
|
|
|
!ClassTemplateSpec->isInvalidDecl())
|
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
|
|
|
MarkVTableUsed(PointOfInstantiation, ClassTemplateSpec, true);
|
|
|
|
|
2009-09-12 05:19:12 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We can only instantiate something that hasn't already been
|
|
|
|
// instantiated or specialized. Fail without any diagnostics: our
|
|
|
|
// caller will provide an error message.
|
2009-03-26 05:17:03 +08:00
|
|
|
return true;
|
2009-09-12 05:19:12 +08:00
|
|
|
}
|
2009-03-26 05:17:03 +08:00
|
|
|
|
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();
|
2009-08-29 04:31:08 +08:00
|
|
|
CXXRecordDecl *Pattern = 0;
|
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);
|
|
|
|
for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
|
|
|
|
ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
|
2012-09-19 10:26:47 +08:00
|
|
|
TemplateDeductionInfo Info(PointOfInstantiation);
|
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)) {
|
|
|
|
// FIXME: Store the failed-deduction information for use in
|
|
|
|
// diagnostics, later.
|
|
|
|
(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.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<const NamedDecl *, 4> InstantiatedTemplateParameters;
|
2011-01-20 04:10:05 +08:00
|
|
|
|
2009-10-29 08:04:11 +08:00
|
|
|
if (Matched.size() >= 1) {
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<MatchResult, 4>::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.
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVector<MatchResult, 4>::iterator P = Best + 1,
|
2009-10-29 08:04:11 +08:00
|
|
|
PEnd = Matched.end();
|
|
|
|
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;
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVector<MatchResult, 4>::iterator P = Matched.begin(),
|
2009-09-16 00:23:51 +08:00
|
|
|
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.
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVector<MatchResult, 4>::iterator P = Matched.begin(),
|
2009-10-29 08:04:11 +08:00
|
|
|
PEnd = Matched.end();
|
|
|
|
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) {
|
2009-06-30 10:36:12 +08:00
|
|
|
for (DeclContext::decl_iterator D = Instantiation->decls_begin(),
|
|
|
|
DEnd = Instantiation->decls_end();
|
2009-05-14 04:28:22 +08:00
|
|
|
D != DEnd; ++D) {
|
2009-10-28 02:42:08 +08:00
|
|
|
bool SuppressNew = false;
|
2009-05-14 04:28:22 +08:00
|
|
|
if (FunctionDecl *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;
|
|
|
|
|
2011-05-07 04:44:56 +08:00
|
|
|
if (Function->isDefined())
|
2009-10-28 02:42:08 +08:00
|
|
|
continue;
|
|
|
|
|
|
|
|
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.
|
2011-05-07 04:44:56 +08:00
|
|
|
if (!Pattern->isDefined())
|
2009-10-28 02:42:08 +08:00
|
|
|
continue;
|
|
|
|
|
|
|
|
Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
|
|
|
|
|
|
|
InstantiateFunctionDefinition(PointOfInstantiation, Function);
|
|
|
|
} else {
|
|
|
|
Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
|
|
|
|
}
|
2009-10-08 23:14:33 +08:00
|
|
|
}
|
2009-05-14 04:28:22 +08:00
|
|
|
} else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) {
|
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);
|
|
|
|
}
|
|
|
|
}
|
2009-05-14 04:28:22 +08:00
|
|
|
} else if (CXXRecordDecl *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.
|
2012-01-15 00:38:05 +08:00
|
|
|
if (Record->isInjectedClassName() || Record->getPreviousDecl())
|
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);
|
2012-03-15 07:13:10 +08:00
|
|
|
} else if (EnumDecl *Enum = dyn_cast<EnumDecl>(*D)) {
|
|
|
|
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);
|
|
|
|
}
|
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)
|
|
|
|
return Owned(S);
|
|
|
|
|
|
|
|
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)
|
|
|
|
return Owned(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);
|
|
|
|
}
|
|
|
|
|
2011-01-08 03:35:17 +08:00
|
|
|
bool Sema::SubstExprs(Expr **Exprs, unsigned NumExprs, bool IsCall,
|
|
|
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<Expr *> &Outputs) {
|
2011-01-08 03:35:17 +08:00
|
|
|
if (NumExprs == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TemplateInstantiator Instantiator(*this, TemplateArgs,
|
|
|
|
SourceLocation(),
|
|
|
|
DeclarationName());
|
|
|
|
return Instantiator.TransformExprs(Exprs, NumExprs, IsCall, Outputs);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2012-09-27 01:57:31 +08:00
|
|
|
|
|
|
|
static const Decl* getCanonicalParmVarDecl(const Decl *D) {
|
|
|
|
// 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();
|
|
|
|
return FD->getCanonicalDecl()->getParamDecl(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
|
CheckD = 0;
|
|
|
|
} 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
|
|
|
|
|
|
|
// 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");
|
2010-05-01 02:55:50 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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];
|
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 (Stored.isNull())
|
|
|
|
Stored = Inst;
|
|
|
|
else if (Stored.is<Decl *>()) {
|
|
|
|
assert(Stored.get<Decl *>() == Inst && "Already instantiated this local");
|
|
|
|
Stored = Inst;
|
|
|
|
} else
|
|
|
|
LocalDecls[D].get<DeclArgumentPack *>()->push_back(Inst);
|
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
|
|
|
|
|
|
|
void LocalInstantiationScope::InstantiatedLocalPackArg(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
|
|
|
DeclArgumentPack *Pack = LocalDecls[D].get<DeclArgumentPack *>();
|
|
|
|
Pack->push_back(Inst);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {
|
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];
|
|
|
|
assert(Stored.isNull() && "Already instantiated this local");
|
|
|
|
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)
|
|
|
|
*ExplicitArgs = 0;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|