From c0afea9495ba535ac5de07c32b68a5559622737e Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 21 Aug 2013 23:05:56 +0000 Subject: [PATCH] Reduce sizeof(TemplateArgument) from 32 to 24. No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188959 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/TemplateBase.h | 93 ++++++++++++++++++-------------- lib/AST/TemplateBase.cpp | 16 +++--- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 6441312244..490a83743a 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -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(T.getAsOpaquePtr()); + TemplateArgument(QualType T, bool isNullPtr = false) { + TypeOrValue.Kind = isNullPtr ? NullPtr : Type; + TypeOrValue.V = reinterpret_cast(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 NumExpansions) - : Kind(TemplateExpansion) - { + TemplateArgument(TemplateName Name, Optional 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(E); + TemplateArgument(Expr *E) { + TypeOrValue.Kind = Expression; + TypeOrValue.V = reinterpret_cast(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(TypeOrValue)); + assert(getKind() == Type && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast(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(TypeOrValue)); + assert(getKind() == NullPtr && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast(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(TypeOrValue); + assert(getKind() == Expression && "Unexpected kind"); + return reinterpret_cast(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 getPackAsArray() const { - assert(Kind == Pack); + assert(getKind() == Pack); return llvm::ArrayRef(Args.Args, Args.NumArgs); } diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 2a9ffd68a3..16efb790b6 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -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 TemplateArgument::getNumTemplateExpansions() const { - assert(Kind == TemplateExpansion); + assert(getKind() == TemplateExpansion); if (TemplateArg.NumExpansions) return TemplateArg.NumExpansions - 1; @@ -234,8 +234,8 @@ Optional 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() && -- 2.40.0