forked from OSchip/llvm-project
Reduce sizeof(TemplateArgument) from 32 to 24.
No intended functionality change. llvm-svn: 188959
This commit is contained in:
parent
e44104b001
commit
2d1611b2de
|
@ -70,57 +70,68 @@ public:
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -131,8 +142,7 @@ public:
|
|||
|
||||
/// \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();
|
||||
}
|
||||
|
@ -145,8 +155,8 @@ public:
|
|||
/// 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;
|
||||
}
|
||||
|
@ -162,9 +172,8 @@ public:
|
|||
///
|
||||
/// \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;
|
||||
|
@ -177,15 +186,17 @@ public:
|
|||
/// 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;
|
||||
}
|
||||
|
@ -201,10 +212,10 @@ public:
|
|||
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
|
||||
|
@ -224,40 +235,40 @@ public:
|
|||
|
||||
/// \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);
|
||||
|
@ -270,7 +281,7 @@ public:
|
|||
/// \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);
|
||||
|
@ -282,19 +293,19 @@ public:
|
|||
|
||||
/// \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.
|
||||
|
@ -303,27 +314,27 @@ public:
|
|||
/// \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);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ static void printIntegral(const TemplateArgument &TemplArg,
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
|
||||
QualType Type)
|
||||
: Kind(Integral) {
|
||||
QualType Type) {
|
||||
Integer.Kind = Integral;
|
||||
// Copy the APSInt value into our decomposed form.
|
||||
Integer.BitWidth = Value.getBitWidth();
|
||||
Integer.IsUnsigned = Value.isUnsigned();
|
||||
|
@ -225,7 +225,7 @@ bool TemplateArgument::containsUnexpandedParameterPack() const {
|
|||
}
|
||||
|
||||
Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
|
||||
assert(Kind == TemplateExpansion);
|
||||
assert(getKind() == TemplateExpansion);
|
||||
if (TemplateArg.NumExpansions)
|
||||
return TemplateArg.NumExpansions - 1;
|
||||
|
||||
|
@ -234,8 +234,8 @@ Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
|
|||
|
||||
void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
|
||||
const ASTContext &Context) const {
|
||||
ID.AddInteger(Kind);
|
||||
switch (Kind) {
|
||||
ID.AddInteger(getKind());
|
||||
switch (getKind()) {
|
||||
case Null:
|
||||
break;
|
||||
|
||||
|
@ -243,6 +243,10 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
|
|||
getAsType().Profile(ID);
|
||||
break;
|
||||
|
||||
case NullPtr:
|
||||
getNullPtrType().Profile(ID);
|
||||
break;
|
||||
|
||||
case Declaration:
|
||||
ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
|
||||
break;
|
||||
|
@ -291,7 +295,7 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
|
|||
case Template:
|
||||
case TemplateExpansion:
|
||||
case NullPtr:
|
||||
return TypeOrValue == Other.TypeOrValue;
|
||||
return TypeOrValue.V == Other.TypeOrValue.V;
|
||||
|
||||
case Declaration:
|
||||
return getAsDecl() == Other.getAsDecl() &&
|
||||
|
|
Loading…
Reference in New Issue