forked from OSchip/llvm-project
Move the template instantiation logic for template arguments into the
general tree transformation. Also, implement template instantiation for parameter packs. In addition, introduce logic to enter the appropriate context for subexpressions that are not potentially evaluated. llvm-svn: 78114
This commit is contained in:
parent
28c2d9809d
commit
e922c77ddd
|
@ -331,9 +331,6 @@ namespace {
|
||||||
/// \brief Transform the given template name by instantiating it.
|
/// \brief Transform the given template name by instantiating it.
|
||||||
TemplateName TransformTemplateName(TemplateName Template);
|
TemplateName TransformTemplateName(TemplateName Template);
|
||||||
|
|
||||||
/// \brief Transform the given template argument by instantiating it.
|
|
||||||
TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
|
|
||||||
|
|
||||||
/// \brief Transforms a template type parameter type by performing
|
/// \brief Transforms a template type parameter type by performing
|
||||||
/// substitution of the corresponding template type argument.
|
/// substitution of the corresponding template type argument.
|
||||||
QualType TransformTemplateTypeParmType(const TemplateTypeParmType *T);
|
QualType TransformTemplateTypeParmType(const TemplateTypeParmType *T);
|
||||||
|
@ -360,11 +357,6 @@ TemplateInstantiator::TransformTemplateName(TemplateName Template) {
|
||||||
TemplateArgs);
|
TemplateArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateArgument
|
|
||||||
TemplateInstantiator::TransformTemplateArgument(const TemplateArgument &Arg) {
|
|
||||||
return getSema().Instantiate(Arg, TemplateArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
QualType
|
QualType
|
||||||
TemplateInstantiator::TransformTemplateTypeParmType(
|
TemplateInstantiator::TransformTemplateTypeParmType(
|
||||||
const TemplateTypeParmType *T) {
|
const TemplateTypeParmType *T) {
|
||||||
|
@ -852,42 +844,7 @@ Sema::InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
|
||||||
|
|
||||||
TemplateArgument Sema::Instantiate(TemplateArgument Arg,
|
TemplateArgument Sema::Instantiate(TemplateArgument Arg,
|
||||||
const TemplateArgumentList &TemplateArgs) {
|
const TemplateArgumentList &TemplateArgs) {
|
||||||
switch (Arg.getKind()) {
|
TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
|
||||||
case TemplateArgument::Null:
|
DeclarationName());
|
||||||
assert(false && "Should never have a NULL template argument");
|
return Instantiator.TransformTemplateArgument(Arg);
|
||||||
break;
|
|
||||||
|
|
||||||
case TemplateArgument::Type: {
|
|
||||||
QualType T = InstantiateType(Arg.getAsType(), TemplateArgs,
|
|
||||||
Arg.getLocation(), DeclarationName());
|
|
||||||
if (T.isNull())
|
|
||||||
return TemplateArgument();
|
|
||||||
|
|
||||||
return TemplateArgument(Arg.getLocation(), T);
|
|
||||||
}
|
|
||||||
|
|
||||||
case TemplateArgument::Declaration:
|
|
||||||
// FIXME: Template instantiation for template template parameters.
|
|
||||||
return Arg;
|
|
||||||
|
|
||||||
case TemplateArgument::Integral:
|
|
||||||
return Arg;
|
|
||||||
|
|
||||||
case TemplateArgument::Expression: {
|
|
||||||
// Template argument expressions are not potentially evaluated.
|
|
||||||
EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
|
|
||||||
|
|
||||||
Sema::OwningExprResult E = InstantiateExpr(Arg.getAsExpr(), TemplateArgs);
|
|
||||||
if (E.isInvalid())
|
|
||||||
return TemplateArgument();
|
|
||||||
return TemplateArgument(E.takeAs<Expr>());
|
|
||||||
}
|
|
||||||
|
|
||||||
case TemplateArgument::Pack:
|
|
||||||
assert(0 && "FIXME: Implement!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(false && "Unhandled template argument kind");
|
|
||||||
return TemplateArgument();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace clang {
|
||||||
/// a new AST node.
|
/// a new AST node.
|
||||||
///
|
///
|
||||||
/// Subclasses can customize the transformation at various levels. The
|
/// Subclasses can customize the transformation at various levels. The
|
||||||
/// most course-grained transformations involve replacing TransformType(),
|
/// most coarse-grained transformations involve replacing TransformType(),
|
||||||
/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
|
/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
|
||||||
/// TransformTemplateName(), or TransformTemplateArgument() with entirely
|
/// TransformTemplateName(), or TransformTemplateArgument() with entirely
|
||||||
/// new implementations.
|
/// new implementations.
|
||||||
|
@ -172,7 +172,10 @@ public:
|
||||||
|
|
||||||
/// \brief Transform the given template argument.
|
/// \brief Transform the given template argument.
|
||||||
///
|
///
|
||||||
/// FIXME: At the moment, subclasses must override this.
|
/// By default, this operation transforms the type, expression, or
|
||||||
|
/// declaration stored within the template argument and constructs a
|
||||||
|
/// new template argument from the transformed result. Subclasses may
|
||||||
|
/// override this function to provide alternate behavior.
|
||||||
TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
|
TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
|
||||||
|
|
||||||
#define ABSTRACT_TYPE(CLASS, PARENT)
|
#define ABSTRACT_TYPE(CLASS, PARENT)
|
||||||
|
@ -397,6 +400,62 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
TemplateArgument
|
||||||
|
TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
|
||||||
|
switch (Arg.getKind()) {
|
||||||
|
case TemplateArgument::Null:
|
||||||
|
case TemplateArgument::Integral:
|
||||||
|
return Arg;
|
||||||
|
|
||||||
|
case TemplateArgument::Type: {
|
||||||
|
QualType T = getDerived().TransformType(Arg.getAsType());
|
||||||
|
if (T.isNull())
|
||||||
|
return TemplateArgument();
|
||||||
|
return TemplateArgument(Arg.getLocation(), T);
|
||||||
|
}
|
||||||
|
|
||||||
|
case TemplateArgument::Declaration: {
|
||||||
|
Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
|
||||||
|
if (!D)
|
||||||
|
return TemplateArgument();
|
||||||
|
return TemplateArgument(Arg.getLocation(), D);
|
||||||
|
}
|
||||||
|
|
||||||
|
case TemplateArgument::Expression: {
|
||||||
|
// Template argument expressions are not potentially evaluated.
|
||||||
|
EnterExpressionEvaluationContext Unevaluated(getSema(),
|
||||||
|
Action::Unevaluated);
|
||||||
|
|
||||||
|
Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
|
||||||
|
if (E.isInvalid())
|
||||||
|
return TemplateArgument();
|
||||||
|
return TemplateArgument(E.takeAs<Expr>());
|
||||||
|
}
|
||||||
|
|
||||||
|
case TemplateArgument::Pack: {
|
||||||
|
llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
|
||||||
|
TransformedArgs.reserve(Arg.pack_size());
|
||||||
|
for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
|
||||||
|
AEnd = Arg.pack_end();
|
||||||
|
A != AEnd; ++A) {
|
||||||
|
TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
|
||||||
|
if (TA.isNull())
|
||||||
|
return TA;
|
||||||
|
|
||||||
|
TransformedArgs.push_back(TA);
|
||||||
|
}
|
||||||
|
TemplateArgument Result;
|
||||||
|
Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
|
||||||
|
true);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Work around bogus GCC warning
|
||||||
|
return TemplateArgument();
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Type transformation
|
// Type transformation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -558,14 +617,22 @@ TreeTransform<Derived>::TransformConstantArrayWithExprType(
|
||||||
if (ElementType.isNull())
|
if (ElementType.isNull())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
|
||||||
|
// Array bounds are not potentially evaluated contexts
|
||||||
|
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||||
|
|
||||||
|
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
||||||
|
if (Size.isInvalid())
|
||||||
|
return QualType();
|
||||||
|
|
||||||
if (!getDerived().AlwaysRebuild() &&
|
if (!getDerived().AlwaysRebuild() &&
|
||||||
ElementType == T->getElementType())
|
ElementType == T->getElementType() &&
|
||||||
|
Size.get() == T->getSizeExpr())
|
||||||
return QualType(T, 0);
|
return QualType(T, 0);
|
||||||
|
|
||||||
return getDerived().RebuildConstantArrayWithExprType(ElementType,
|
return getDerived().RebuildConstantArrayWithExprType(ElementType,
|
||||||
T->getSizeModifier(),
|
T->getSizeModifier(),
|
||||||
T->getSize(),
|
T->getSize(),
|
||||||
/*FIXME: Transform?*/T->getSizeExpr(),
|
Size.takeAs<Expr>(),
|
||||||
T->getIndexTypeQualifier(),
|
T->getIndexTypeQualifier(),
|
||||||
T->getBracketsRange());
|
T->getBracketsRange());
|
||||||
}
|
}
|
||||||
|
@ -611,6 +678,9 @@ QualType TreeTransform<Derived>::TransformVariableArrayType(
|
||||||
if (ElementType.isNull())
|
if (ElementType.isNull())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
|
||||||
|
// Array bounds are not potentially evaluated contexts
|
||||||
|
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||||
|
|
||||||
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
||||||
if (Size.isInvalid())
|
if (Size.isInvalid())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
@ -636,6 +706,9 @@ QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
|
||||||
if (ElementType.isNull())
|
if (ElementType.isNull())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
|
||||||
|
// Array bounds are not potentially evaluated contexts
|
||||||
|
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||||
|
|
||||||
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
||||||
if (Size.isInvalid())
|
if (Size.isInvalid())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
@ -661,6 +734,9 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
|
||||||
if (ElementType.isNull())
|
if (ElementType.isNull())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
|
||||||
|
// Vector sizes are not potentially evaluated contexts
|
||||||
|
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||||
|
|
||||||
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
|
||||||
if (Size.isInvalid())
|
if (Size.isInvalid())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
@ -757,6 +833,9 @@ QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
QualType TreeTransform<Derived>::TransformTypeOfExprType(
|
QualType TreeTransform<Derived>::TransformTypeOfExprType(
|
||||||
const TypeOfExprType *T) {
|
const TypeOfExprType *T) {
|
||||||
|
// typeof expressions are not potentially evaluated contexts
|
||||||
|
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||||
|
|
||||||
Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
|
Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
|
||||||
if (E.isInvalid())
|
if (E.isInvalid())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
@ -785,6 +864,9 @@ QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
|
QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
|
||||||
|
// decltype expressions are not potentially evaluated contexts
|
||||||
|
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||||
|
|
||||||
Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
|
Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
|
||||||
if (E.isInvalid())
|
if (E.isInvalid())
|
||||||
return QualType();
|
return QualType();
|
||||||
|
|
Loading…
Reference in New Issue