char Value[sizeof(llvm::APSInt)];
void *Type;
} Integer;
+ struct {
+ TemplateArgument *Args;
+ unsigned NumArgs;
+ bool CopyArgs;
+ } Args;
};
/// \brief Location of the beginning of this template argument.
/// \brief The type of template argument we're storing.
enum ArgKind {
Null = 0,
- /// The template argument is a type. It's value is stored in the
+ /// The template argument is a type. Its value is stored in the
/// TypeOrValue field.
Type = 1,
/// The template argument is a declaration
Integral = 3,
/// The template argument is a value- or type-dependent expression
/// stored in an Expr*.
- Expression = 4
+ Expression = 4,
+
+ /// The template argument is actually a parameter pack. Arguments are stored
+ /// in the Args struct.
+ Pack = 5
} Kind;
/// \brief Construct an empty, invalid template argument.
/// occur in a non-dependent, canonical template argument list.
TemplateArgument(Expr *E);
+ /// \brief Construct a template argument pack.
+ TemplateArgument(SourceLocation Loc, TemplateArgument *Args,
+ unsigned NumArgs, bool OwnsArgs);
+
/// \brief Copy constructor for a template argument.
TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+ assert(Kind != Pack && "FIXME: Handle packs");
if (Kind == Integral) {
new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
Integer.Type = Other.Integer.Type;
// safety.
using llvm::APSInt;
+ // FIXME: Handle Packs
+ assert(Kind != Pack && "FIXME: Handle packs");
+ assert(Other.Kind != Pack && "FIXME: Handle packs");
+
if (Kind == Other.Kind && Kind == Integral) {
// Copy integral values.
*this->getAsIntegral() = *Other.getAsIntegral();
if (Kind == Integral)
getAsIntegral()->~APSInt();
+ else if (Kind == Pack && Args.CopyArgs)
+ delete[] Args.Args;
}
/// \brief Return the kind of stored template argument.
// FIXME: We need a canonical representation of expressions.
ID.AddPointer(getAsExpr());
break;
+
+ case Pack:
+ ID.AddInteger(Args.NumArgs);
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I].Profile(ID);
}
}
};
StartLoc = E->getSourceRange().getBegin();
}
+/// \brief Construct a template argument pack.
+TemplateArgument::TemplateArgument(SourceLocation Loc, TemplateArgument *args,
+ unsigned NumArgs, bool CopyArgs)
+ : Kind(Pack) {
+ Args.NumArgs = NumArgs;
+ Args.CopyArgs = CopyArgs;
+ if (!Args.CopyArgs) {
+ Args.Args = args;
+ return;
+ }
+
+ Args.Args = new TemplateArgument[NumArgs];
+ for (unsigned I = 0; I != NumArgs; ++I)
+ Args.Args[I] = args[I];
+}
+
//===----------------------------------------------------------------------===//
// TemplateArgumentListBuilder Implementation
//===----------------------------------------------------------------------===//
Args[Idx].getAsExpr()->isValueDependent())
return true;
break;
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
}
Args[Arg].getAsExpr()->printPretty(s, 0, Policy);
break;
}
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
// If this is the first argument and its string representation
Canonical.push_back(TemplateArgument(SourceLocation(), CanonType));
break;
}
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
}
}
Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr);
Diag((*Param)->getLocation(), diag::note_template_param_here);
Invalid = true;
+ break;
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
} else {
// Check template template parameters.
case TemplateArgument::Integral:
assert(false && "Integral argument with template template parameter");
break;
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
}
}
// Can't deduce anything, but that's okay.
return Sema::TDK_Success;
}
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
return Sema::TDK_Success;
case TemplateArgument::Expression:
MarkDeducedTemplateParameters(TemplateArg.getAsExpr(), Deduced);
break;
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
}
return TemplateArgument();
return TemplateArgument(E.takeAs<Expr>());
}
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
assert(false && "Unhandled template argument kind");