/// \brief Transform the given template name by instantiating it.
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
/// substitution of the corresponding template type argument.
QualType TransformTemplateTypeParmType(const TemplateTypeParmType *T);
TemplateArgs);
}
-TemplateArgument
-TemplateInstantiator::TransformTemplateArgument(const TemplateArgument &Arg) {
- return getSema().Instantiate(Arg, TemplateArgs);
-}
-
QualType
TemplateInstantiator::TransformTemplateTypeParmType(
const TemplateTypeParmType *T) {
TemplateArgument Sema::Instantiate(TemplateArgument Arg,
const TemplateArgumentList &TemplateArgs) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- assert(false && "Should never have a NULL template argument");
- 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();
+ TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
+ DeclarationName());
+ return Instantiator.TransformTemplateArgument(Arg);
}
/// a new AST node.
///
/// 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(),
/// TransformTemplateName(), or TransformTemplateArgument() with entirely
/// new implementations.
/// \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);
#define ABSTRACT_TYPE(CLASS, PARENT)
}
};
+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
//===----------------------------------------------------------------------===//
if (ElementType.isNull())
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() &&
- ElementType == T->getElementType())
+ ElementType == T->getElementType() &&
+ Size.get() == T->getSizeExpr())
return QualType(T, 0);
return getDerived().RebuildConstantArrayWithExprType(ElementType,
T->getSizeModifier(),
T->getSize(),
- /*FIXME: Transform?*/T->getSizeExpr(),
+ Size.takeAs<Expr>(),
T->getIndexTypeQualifier(),
T->getBracketsRange());
}
if (ElementType.isNull())
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 (ElementType.isNull())
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 (ElementType.isNull())
return QualType();
+ // Vector sizes are not potentially evaluated contexts
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
if (Size.isInvalid())
return QualType();
template<typename Derived>
QualType TreeTransform<Derived>::TransformTypeOfExprType(
const TypeOfExprType *T) {
+ // typeof expressions are not potentially evaluated contexts
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
if (E.isInvalid())
return QualType();
template<typename Derived>
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());
if (E.isInvalid())
return QualType();