private:
/// \brief The kind of template argument we're storing.
- unsigned Kind;
struct DA {
- ValueDecl *D;
+ unsigned Kind;
bool ForRefParam;
+ ValueDecl *D;
};
struct I {
+ unsigned Kind;
// We store a decomposed APSInt with the data allocated by ASTContext if
// BitWidth > 64. The memory may be shared between multiple
// TemplateArgument instances.
+ unsigned BitWidth : 31;
+ unsigned IsUnsigned : 1;
union {
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
const uint64_t *pVal; ///< Used to store the >64 bits integer value.
};
- unsigned BitWidth : 31;
- unsigned IsUnsigned : 1;
void *Type;
};
struct A {
- const TemplateArgument *Args;
+ unsigned Kind;
unsigned NumArgs;
+ const TemplateArgument *Args;
};
struct TA {
- void *Name;
+ unsigned Kind;
unsigned NumExpansions;
+ void *Name;
+ };
+ struct TV {
+ unsigned Kind;
+ uintptr_t V;
};
union {
struct DA DeclArg;
struct I Integer;
struct A Args;
struct TA TemplateArg;
- uintptr_t TypeOrValue;
+ struct TV TypeOrValue;
};
TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
public:
/// \brief Construct an empty, invalid template argument.
- TemplateArgument() : Kind(Null), TypeOrValue(0) { }
+ TemplateArgument() {
+ TypeOrValue.Kind = Null;
+ TypeOrValue.V = 0;
+ }
/// \brief Construct a template type argument.
- TemplateArgument(QualType T, bool isNullPtr = false)
- : Kind(isNullPtr ? NullPtr : Type) {
- TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+ TemplateArgument(QualType T, bool isNullPtr = false) {
+ TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
+ TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
}
/// \brief Construct a template argument that refers to a
/// declaration, which is either an external declaration or a
/// template declaration.
- TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) {
+ TemplateArgument(ValueDecl *D, bool ForRefParam) {
assert(D && "Expected decl");
+ DeclArg.Kind = Declaration;
DeclArg.D = D;
DeclArg.ForRefParam = ForRefParam;
}
/// \brief Construct an integral constant template argument with the same
/// value as Other but a different type.
- TemplateArgument(const TemplateArgument &Other, QualType Type)
- : Kind(Integral) {
+ TemplateArgument(const TemplateArgument &Other, QualType Type) {
Integer = Other.Integer;
Integer.Type = Type.getAsOpaquePtr();
}
/// is taken.
///
/// \param Name The template name.
- TemplateArgument(TemplateName Name) : Kind(Template)
- {
+ TemplateArgument(TemplateName Name) {
+ TemplateArg.Kind = Template;
TemplateArg.Name = Name.getAsVoidPointer();
TemplateArg.NumExpansions = 0;
}
///
/// \param NumExpansions The number of expansions that will be generated by
/// instantiating
- TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions)
- : Kind(TemplateExpansion)
- {
+ TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
+ TemplateArg.Kind = TemplateExpansion;
TemplateArg.Name = Name.getAsVoidPointer();
if (NumExpansions)
TemplateArg.NumExpansions = *NumExpansions + 1;
/// This form of template argument only occurs in template argument
/// lists used for dependent types and for expression; it will not
/// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E) : Kind(Expression) {
- TypeOrValue = reinterpret_cast<uintptr_t>(E);
+ TemplateArgument(Expr *E) {
+ TypeOrValue.Kind = Expression;
+ TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
}
/// \brief Construct a template argument that is a template argument pack.
///
/// We assume that storage for the template arguments provided
/// outlives the TemplateArgument itself.
- TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){
+ TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) {
+ this->Args.Kind = Pack;
this->Args.Args = Args;
this->Args.NumArgs = NumArgs;
}
unsigned NumArgs);
/// \brief Return the kind of stored template argument.
- ArgKind getKind() const { return (ArgKind)Kind; }
+ ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
/// \brief Determine whether this template argument has no value.
- bool isNull() const { return Kind == Null; }
+ bool isNull() const { return getKind() == Null; }
/// \brief Whether this template argument is dependent on a template
/// parameter such that its result can change from one instantiation to
/// \brief Retrieve the type for a type template argument.
QualType getAsType() const {
- assert(Kind == Type && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
+ assert(getKind() == Type && "Unexpected kind");
+ return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
}
/// \brief Retrieve the declaration for a declaration non-type
/// template argument.
ValueDecl *getAsDecl() const {
- assert(Kind == Declaration && "Unexpected kind");
+ assert(getKind() == Declaration && "Unexpected kind");
return DeclArg.D;
}
/// \brief Retrieve whether a declaration is binding to a
/// reference parameter in a declaration non-type template argument.
bool isDeclForReferenceParam() const {
- assert(Kind == Declaration && "Unexpected kind");
+ assert(getKind() == Declaration && "Unexpected kind");
return DeclArg.ForRefParam;
}
/// \brief Retrieve the type for null non-type template argument.
QualType getNullPtrType() const {
- assert(Kind == NullPtr && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
+ assert(getKind() == NullPtr && "Unexpected kind");
+ return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
}
/// \brief Retrieve the template name for a template name argument.
TemplateName getAsTemplate() const {
- assert(Kind == Template && "Unexpected kind");
+ assert(getKind() == Template && "Unexpected kind");
return TemplateName::getFromVoidPointer(TemplateArg.Name);
}
/// \brief Retrieve the template argument as a template name; if the argument
/// is a pack expansion, return the pattern as a template name.
TemplateName getAsTemplateOrTemplatePattern() const {
- assert((Kind == Template || Kind == TemplateExpansion) &&
+ assert((getKind() == Template || getKind() == TemplateExpansion) &&
"Unexpected kind");
return TemplateName::getFromVoidPointer(TemplateArg.Name);
/// \brief Retrieve the template argument as an integral value.
// FIXME: Provide a way to read the integral data without copying the value.
llvm::APSInt getAsIntegral() const {
- assert(Kind == Integral && "Unexpected kind");
+ assert(getKind() == Integral && "Unexpected kind");
using namespace llvm;
if (Integer.BitWidth <= 64)
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
/// \brief Retrieve the type of the integral value.
QualType getIntegralType() const {
- assert(Kind == Integral && "Unexpected kind");
+ assert(getKind() == Integral && "Unexpected kind");
return QualType::getFromOpaquePtr(Integer.Type);
}
void setIntegralType(QualType T) {
- assert(Kind == Integral && "Unexpected kind");
+ assert(getKind() == Integral && "Unexpected kind");
Integer.Type = T.getAsOpaquePtr();
}
/// \brief Retrieve the template argument as an expression.
Expr *getAsExpr() const {
- assert(Kind == Expression && "Unexpected kind");
- return reinterpret_cast<Expr *>(TypeOrValue);
+ assert(getKind() == Expression && "Unexpected kind");
+ return reinterpret_cast<Expr *>(TypeOrValue.V);
}
/// \brief Iterator that traverses the elements of a template argument pack.
/// \brief Iterator referencing the first argument of a template argument
/// pack.
pack_iterator pack_begin() const {
- assert(Kind == Pack);
+ assert(getKind() == Pack);
return Args.Args;
}
/// \brief Iterator referencing one past the last argument of a template
/// argument pack.
pack_iterator pack_end() const {
- assert(Kind == Pack);
+ assert(getKind() == Pack);
return Args.Args + Args.NumArgs;
}
/// \brief The number of template arguments in the given template argument
/// pack.
unsigned pack_size() const {
- assert(Kind == Pack);
+ assert(getKind() == Pack);
return Args.NumArgs;
}
/// \brief Return the array of arguments in this template argument pack.
llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
- assert(Kind == Pack);
+ assert(getKind() == Pack);
return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
}