Index: include/clang/AST/ExprCXX.h =================================================================== --- include/clang/AST/ExprCXX.h +++ include/clang/AST/ExprCXX.h @@ -2658,58 +2658,54 @@ /// A reference to an overloaded function set, either an /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr. class OverloadExpr : public Expr { + friend class ASTStmtReader; + friend class ASTStmtWriter; + /// The common name of these declarations. DeclarationNameInfo NameInfo; /// The nested-name-specifier that qualifies the name, if any. NestedNameSpecifierLoc QualifierLoc; - /// The results. These are undesugared, which is to say, they may - /// include UsingShadowDecls. Access is relative to the naming - /// class. - // FIXME: Allocate this data after the OverloadExpr subclass. - DeclAccessPair *Results = nullptr; - - unsigned NumResults = 0; - protected: - /// Whether the name includes info for explicit template - /// keyword and arguments. - bool HasTemplateKWAndArgsInfo = false; - - OverloadExpr(StmtClass K, const ASTContext &C, + OverloadExpr(StmtClass SC, const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, - bool KnownDependent, - bool KnownInstantiationDependent, + bool KnownDependent, bool KnownInstantiationDependent, bool KnownContainsUnexpandedParameterPack); - OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {} + OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults, + bool HasTemplateKWAndArgsInfo); - /// Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo * - getTrailingASTTemplateKWAndArgsInfo(); // defined far below. + /// Return the results. Defined after UnresolvedMemberExpr. + inline DeclAccessPair *getTrailingResults(); + const DeclAccessPair *getTrailingResults() const { + return const_cast(this)->getTrailingResults(); + } /// Return the optional template keyword and arguments info. + /// Defined after UnresolvedMemberExpr. + inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo(); const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const { return const_cast(this) ->getTrailingASTTemplateKWAndArgsInfo(); } - /// Return the optional template arguments. - TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below + /// Return the optional template arguments. Defined after + /// UnresolvedMemberExpr. + inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); + const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const { + return const_cast(this)->getTrailingTemplateArgumentLoc(); + } - void initializeResults(const ASTContext &C, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End); + bool hasTemplateKWAndArgsInfo() const { + return OverloadExprBits.HasTemplateKWAndArgsInfo; + } public: - friend class ASTStmtReader; - friend class ASTStmtWriter; - struct FindResult { OverloadExpr *Expression; bool IsAddressOfOperand; @@ -2745,20 +2741,26 @@ } /// Gets the naming class of this lookup, if any. - CXXRecordDecl *getNamingClass() const; + /// Defined after UnresolvedMemberExpr. + inline CXXRecordDecl *getNamingClass(); + const CXXRecordDecl *getNamingClass() const { + return const_cast(this)->getNamingClass(); + } using decls_iterator = UnresolvedSetImpl::iterator; - decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); } + decls_iterator decls_begin() const { + return UnresolvedSetIterator(getTrailingResults()); + } decls_iterator decls_end() const { - return UnresolvedSetIterator(Results + NumResults); + return UnresolvedSetIterator(getTrailingResults() + getNumDecls()); } llvm::iterator_range decls() const { return llvm::make_range(decls_begin(), decls_end()); } /// Gets the number of declarations in the unresolved set. - unsigned getNumDecls() const { return NumResults; } + unsigned getNumDecls() const { return OverloadExprBits.NumResults; } /// Gets the full name info. const DeclarationNameInfo &getNameInfo() const { return NameInfo; } @@ -2781,21 +2783,24 @@ /// Retrieve the location of the template keyword preceding /// this name, if any. SourceLocation getTemplateKeywordLoc() const { - if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + if (!hasTemplateKWAndArgsInfo()) + return SourceLocation(); return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc; } /// Retrieve the location of the left angle bracket starting the /// explicit template argument list following the name, if any. SourceLocation getLAngleLoc() const { - if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + if (!hasTemplateKWAndArgsInfo()) + return SourceLocation(); return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc; } /// Retrieve the location of the right angle bracket ending the /// explicit template argument list following the name, if any. SourceLocation getRAngleLoc() const { - if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + if (!hasTemplateKWAndArgsInfo()) + return SourceLocation(); return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc; } @@ -2847,86 +2852,82 @@ /// members and therefore appear only in UnresolvedMemberLookupExprs. class UnresolvedLookupExpr final : public OverloadExpr, - private llvm::TrailingObjects< - UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { + private llvm::TrailingObjects { friend class ASTStmtReader; friend class OverloadExpr; friend TrailingObjects; - /// True if these lookup results should be extended by - /// argument-dependent lookup if this is the operand of a function - /// call. - bool RequiresADL = false; - - /// True if these lookup results are overloaded. This is pretty - /// trivially rederivable if we urgently need to kill this field. - bool Overloaded = false; - /// The naming class (C++ [class.access.base]p5) of the lookup, if /// any. This can generally be recalculated from the context chain, - /// but that can be fairly expensive for unqualified lookups. If we - /// want to improve memory use here, this could go in a union - /// against the qualified-lookup bits. - CXXRecordDecl *NamingClass = nullptr; + /// but that can be fairly expensive for unqualified lookups. + CXXRecordDecl *NamingClass; - UnresolvedLookupExpr(const ASTContext &C, - CXXRecordDecl *NamingClass, + // UnresolvedLookupExpr is followed by several trailing objects. + // They are in order: + // + // * An array of getNumResults() DeclAccessPair for the results. These are + // undesugared, which is to say, they may include UsingShadowDecls. + // Access is relative to the naming class. + // + // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified + // template keyword and arguments. Present if and only if + // hasTemplateKWAndArgsInfo(). + // + // * An array of getNumTemplateArgs() TemplateArgumentLoc containing + // location information for the explicitly specified template arguments. + + UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - bool RequiresADL, bool Overloaded, + const DeclarationNameInfo &NameInfo, bool RequiresADL, + bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, - UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc, - NameInfo, TemplateArgs, Begin, End, false, false, false), - RequiresADL(RequiresADL), - Overloaded(Overloaded), NamingClass(NamingClass) {} + UnresolvedSetIterator Begin, UnresolvedSetIterator End); - UnresolvedLookupExpr(EmptyShell Empty) - : OverloadExpr(UnresolvedLookupExprClass, Empty) {} + UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults, + bool HasTemplateKWAndArgsInfo); - size_t numTrailingObjects(OverloadToken) const { - return HasTemplateKWAndArgsInfo ? 1 : 0; + unsigned numTrailingObjects(OverloadToken) const { + return getNumDecls(); + } + + unsigned numTrailingObjects(OverloadToken) const { + return hasTemplateKWAndArgsInfo(); } public: - static UnresolvedLookupExpr *Create(const ASTContext &C, - CXXRecordDecl *NamingClass, - NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo, - bool ADL, bool Overloaded, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End) { - return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, - SourceLocation(), NameInfo, - ADL, Overloaded, nullptr, Begin, End); - } - - static UnresolvedLookupExpr *Create(const ASTContext &C, - CXXRecordDecl *NamingClass, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - bool ADL, - const TemplateArgumentListInfo *Args, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End); - - static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C, + static UnresolvedLookupExpr * + Create(const ASTContext &Context, CXXRecordDecl *NamingClass, + NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, + UnresolvedSetIterator Begin, UnresolvedSetIterator End); + + static UnresolvedLookupExpr * + Create(const ASTContext &Context, CXXRecordDecl *NamingClass, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + const DeclarationNameInfo &NameInfo, bool RequiresADL, + const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin, + UnresolvedSetIterator End); + + static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context, + unsigned NumResults, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); /// True if this declaration should be extended by /// argument-dependent lookup. - bool requiresADL() const { return RequiresADL; } + bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; } /// True if this lookup is overloaded. - bool isOverloaded() const { return Overloaded; } + bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; } /// Gets the 'naming class' (in the sense of C++0x /// [class.access.base]p5) of the lookup. This is the scope /// that was looked in to find these results. - CXXRecordDecl *getNamingClass() const { return NamingClass; } + CXXRecordDecl *getNamingClass() { return NamingClass; } + const CXXRecordDecl *getNamingClass() const { return NamingClass; } SourceLocation getBeginLoc() const LLVM_READONLY { if (NestedNameSpecifierLoc l = getQualifierLoc()) @@ -3559,25 +3560,18 @@ /// DeclRefExpr, depending on whether the member is static. class UnresolvedMemberExpr final : public OverloadExpr, - private llvm::TrailingObjects< - UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { + private llvm::TrailingObjects { friend class ASTStmtReader; friend class OverloadExpr; friend TrailingObjects; - /// Whether this member expression used the '->' operator or - /// the '.' operator. - bool IsArrow : 1; - - /// Whether the lookup results contain an unresolved using - /// declaration. - bool HasUnresolvedUsing : 1; - /// The expression for the base pointer or class reference, /// e.g., the \c x in x.f. /// /// This can be null if this is an 'unbased' member expression. - Stmt *Base = nullptr; + Stmt *Base; /// The type of the base expression; never null. QualType BaseType; @@ -3585,7 +3579,21 @@ /// The location of the '->' or '.' operator. SourceLocation OperatorLoc; - UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, + // UnresolvedMemberExpr is followed by several trailing objects. + // They are in order: + // + // * An array of getNumResults() DeclAccessPair for the results. These are + // undesugared, which is to say, they may include UsingShadowDecls. + // Access is relative to the naming class. + // + // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified + // template keyword and arguments. Present if and only if + // hasTemplateKWAndArgsInfo(). + // + // * An array of getNumTemplateArgs() TemplateArgumentLoc containing + // location information for the explicitly specified template arguments. + + UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, @@ -3594,28 +3602,30 @@ const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End); - UnresolvedMemberExpr(EmptyShell Empty) - : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), - HasUnresolvedUsing(false) {} + UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults, + bool HasTemplateKWAndArgsInfo); - size_t numTrailingObjects(OverloadToken) const { - return HasTemplateKWAndArgsInfo ? 1 : 0; + unsigned numTrailingObjects(OverloadToken) const { + return getNumDecls(); + } + + unsigned numTrailingObjects(OverloadToken) const { + return hasTemplateKWAndArgsInfo(); } public: static UnresolvedMemberExpr * - Create(const ASTContext &C, bool HasUnresolvedUsing, - Expr *Base, QualType BaseType, bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, + Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base, + QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End); - static UnresolvedMemberExpr * - CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, - unsigned NumTemplateArgs); + static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context, + unsigned NumResults, + bool HasTemplateKWAndArgsInfo, + unsigned NumTemplateArgs); /// True if this is an implicit access, i.e., one in which the /// member being accessed was not written in the source. @@ -3638,32 +3648,36 @@ /// Determine whether the lookup results contain an unresolved using /// declaration. - bool hasUnresolvedUsing() const { return HasUnresolvedUsing; } + bool hasUnresolvedUsing() const { + return UnresolvedMemberExprBits.HasUnresolvedUsing; + } /// Determine whether this member expression used the '->' /// operator; otherwise, it used the '.' operator. - bool isArrow() const { return IsArrow; } + bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; } /// Retrieve the location of the '->' or '.' operator. SourceLocation getOperatorLoc() const { return OperatorLoc; } /// Retrieve the naming class of this lookup. - CXXRecordDecl *getNamingClass() const; + CXXRecordDecl *getNamingClass(); + const CXXRecordDecl *getNamingClass() const { + return const_cast(this)->getNamingClass(); + } /// Retrieve the full name info for the member that this expression /// refers to. const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); } - /// Retrieve the name of the member that this expression - /// refers to. + /// Retrieve the name of the member that this expression refers to. DeclarationName getMemberName() const { return getName(); } - // Retrieve the location of the name of the member that this - // expression refers to. + /// Retrieve the location of the name of the member that this + /// expression refers to. SourceLocation getMemberLoc() const { return getNameLoc(); } - // Return the preferred location (the member name) for the arrow when - // diagnosing a problem with this expression. + /// Return the preferred location (the member name) for the arrow when + /// diagnosing a problem with this expression. SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); } SourceLocation getBeginLoc() const LLVM_READONLY { @@ -3692,26 +3706,33 @@ } }; -inline ASTTemplateKWAndArgsInfo * -OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) +DeclAccessPair *OverloadExpr::getTrailingResults() { + if (auto *ULE = dyn_cast(this)) + return ULE->getTrailingObjects(); + return cast(this)->getTrailingObjects(); +} + +ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() { + if (!hasTemplateKWAndArgsInfo()) return nullptr; - if (isa(this)) - return cast(this) - ->getTrailingObjects(); - else - return cast(this) - ->getTrailingObjects(); + if (auto *ULE = dyn_cast(this)) + return ULE->getTrailingObjects(); + return cast(this) + ->getTrailingObjects(); +} + +TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() { + if (auto *ULE = dyn_cast(this)) + return ULE->getTrailingObjects(); + return cast(this) + ->getTrailingObjects(); } -inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() { - if (isa(this)) - return cast(this) - ->getTrailingObjects(); - else - return cast(this) - ->getTrailingObjects(); +CXXRecordDecl *OverloadExpr::getNamingClass() { + if (auto *ULE = dyn_cast(this)) + return ULE->getNamingClass(); + return cast(this)->getNamingClass(); } /// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). Index: include/clang/AST/Stmt.h =================================================================== --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -769,6 +769,61 @@ SourceLocation OperatorLoc; }; + class OverloadExprBitfields { + friend class ASTStmtReader; + friend class OverloadExpr; + + unsigned : NumExprBits; + + /// Whether the name includes info for explicit template + /// keyword and arguments. + unsigned HasTemplateKWAndArgsInfo : 1; + + /// Padding used by the derived classes to store various bits. If you + /// need to add some data here, shrink this padding and add your data + /// above. NumOverloadExprBits also needs to be updated. + unsigned : 32 - NumExprBits - 1; + + /// The number of results. + unsigned NumResults; + }; + enum { NumOverloadExprBits = NumExprBits + 1 }; + + class UnresolvedLookupExprBitfields { + friend class ASTStmtReader; + friend class UnresolvedLookupExpr; + + unsigned : NumOverloadExprBits; + + /// True if these lookup results should be extended by + /// argument-dependent lookup if this is the operand of a function call. + unsigned RequiresADL : 1; + + /// True if these lookup results are overloaded. This is pretty trivially + /// rederivable if we urgently need to kill this field. + unsigned Overloaded : 1; + }; + static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4, + "UnresolvedLookupExprBitfields must be <= than 4 bytes to" + "avoid trashing OverloadExprBitfields::NumResults!"); + + class UnresolvedMemberExprBitfields { + friend class ASTStmtReader; + friend class UnresolvedMemberExpr; + + unsigned : NumOverloadExprBits; + + /// Whether this member expression used the '->' operator or + /// the '.' operator. + unsigned IsArrow : 1; + + /// Whether the lookup results contain an unresolved using declaration. + unsigned HasUnresolvedUsing : 1; + }; + static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4, + "UnresolvedMemberExprBitfields must be <= than 4 bytes to" + "avoid trashing OverloadExprBitfields::NumResults!"); + class CXXNoexceptExprBitfields { friend class ASTStmtReader; friend class CXXNoexceptExpr; @@ -877,6 +932,9 @@ ExprWithCleanupsBitfields ExprWithCleanupsBits; CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits; CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits; + OverloadExprBitfields OverloadExprBits; + UnresolvedLookupExprBitfields UnresolvedLookupExprBits; + UnresolvedMemberExprBitfields UnresolvedMemberExprBits; CXXNoexceptExprBitfields CXXNoexceptExprBits; SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits; Index: lib/AST/ExprCXX.cpp =================================================================== --- lib/AST/ExprCXX.cpp +++ lib/AST/ExprCXX.cpp @@ -302,68 +302,95 @@ } // UnresolvedLookupExpr -UnresolvedLookupExpr * -UnresolvedLookupExpr::Create(const ASTContext &C, - CXXRecordDecl *NamingClass, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - bool ADL, - const TemplateArgumentListInfo *Args, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End) { - assert(Args || TemplateKWLoc.isValid()); - unsigned num_args = Args ? Args->size() : 0; +UnresolvedLookupExpr::UnresolvedLookupExpr( + const ASTContext &Context, CXXRecordDecl *NamingClass, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, + const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, + UnresolvedSetIterator End) + : OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc, + TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false, + false, false), + NamingClass(NamingClass) { + UnresolvedLookupExprBits.RequiresADL = RequiresADL; + UnresolvedLookupExprBits.Overloaded = Overloaded; +} + +UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty, + unsigned NumResults, + bool HasTemplateKWAndArgsInfo) + : OverloadExpr(UnresolvedLookupExprClass, Empty, NumResults, + HasTemplateKWAndArgsInfo) {} + +UnresolvedLookupExpr *UnresolvedLookupExpr::Create( + const ASTContext &Context, CXXRecordDecl *NamingClass, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, + bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, + UnresolvedSetIterator End) { + unsigned NumResults = End - Begin; + unsigned Size = totalSizeToAlloc(NumResults, 0, 0); + void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr)); + return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc, + SourceLocation(), NameInfo, RequiresADL, + Overloaded, nullptr, Begin, End); +} - std::size_t Size = - totalSizeToAlloc(1, - num_args); - void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr)); - return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, - TemplateKWLoc, NameInfo, - ADL, /*Overload*/ true, Args, - Begin, End); -} - -UnresolvedLookupExpr * -UnresolvedLookupExpr::CreateEmpty(const ASTContext &C, - bool HasTemplateKWAndArgsInfo, - unsigned NumTemplateArgs) { +UnresolvedLookupExpr *UnresolvedLookupExpr::Create( + const ASTContext &Context, CXXRecordDecl *NamingClass, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + const DeclarationNameInfo &NameInfo, bool RequiresADL, + const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin, + UnresolvedSetIterator End) { + assert(Args || TemplateKWLoc.isValid()); + unsigned NumResults = End - Begin; + unsigned NumTemplateArgs = Args ? Args->size() : 0; + unsigned Size = + totalSizeToAlloc(NumResults, 1, NumTemplateArgs); + void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr)); + return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc, + TemplateKWLoc, NameInfo, RequiresADL, + /*Overloaded*/ true, Args, Begin, End); +} + +UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty( + const ASTContext &Context, unsigned NumResults, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); - std::size_t Size = - totalSizeToAlloc( - HasTemplateKWAndArgsInfo, NumTemplateArgs); - void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr)); - auto *E = new (Mem) UnresolvedLookupExpr(EmptyShell()); - E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; - return E; + unsigned Size = totalSizeToAlloc( + NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); + void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr)); + return new (Mem) + UnresolvedLookupExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo); } -OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C, +OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, - UnresolvedSetIterator End, - bool KnownDependent, + UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent, bool KnownContainsUnexpandedParameterPack) - : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, - KnownDependent, - (KnownInstantiationDependent || - NameInfo.isInstantiationDependent() || - (QualifierLoc && + : Expr( + SC, Context.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, + KnownDependent, + (KnownInstantiationDependent || NameInfo.isInstantiationDependent() || + (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), - (KnownContainsUnexpandedParameterPack || - NameInfo.containsUnexpandedParameterPack() || - (QualifierLoc && - QualifierLoc.getNestedNameSpecifier() - ->containsUnexpandedParameterPack()))), - NameInfo(NameInfo), QualifierLoc(QualifierLoc), NumResults(End - Begin), - HasTemplateKWAndArgsInfo(TemplateArgs != nullptr || - TemplateKWLoc.isValid()) { - NumResults = End - Begin; + (KnownContainsUnexpandedParameterPack || + NameInfo.containsUnexpandedParameterPack() || + (QualifierLoc && QualifierLoc.getNestedNameSpecifier() + ->containsUnexpandedParameterPack()))), + NameInfo(NameInfo), QualifierLoc(QualifierLoc) { + unsigned NumResults = End - Begin; + OverloadExprBits.NumResults = NumResults; + OverloadExprBits.HasTemplateKWAndArgsInfo = + (TemplateArgs != nullptr ) || TemplateKWLoc.isValid(); + if (NumResults) { // Determine whether this expression is type-dependent. for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) { @@ -375,8 +402,9 @@ } } - Results = static_cast(C.Allocate( - sizeof(DeclAccessPair) * NumResults, alignof(DeclAccessPair))); + // Copy the results to the trailing array past UnresolvedLookupExpr + // or UnresolvedMemberExpr. + DeclAccessPair *Results = getTrailingResults(); memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair)); } @@ -404,28 +432,14 @@ } if (isTypeDependent()) - setType(C.DependentTy); -} - -void OverloadExpr::initializeResults(const ASTContext &C, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End) { - assert(!Results && "Results already initialized!"); - NumResults = End - Begin; - if (NumResults) { - Results = static_cast( - C.Allocate(sizeof(DeclAccessPair) * NumResults, - - alignof(DeclAccessPair))); - memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair)); - } + setType(Context.DependentTy); } -CXXRecordDecl *OverloadExpr::getNamingClass() const { - if (isa(this)) - return cast(this)->getNamingClass(); - else - return cast(this)->getNamingClass(); +OverloadExpr::OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults, + bool HasTemplateKWAndArgsInfo) + : Expr(SC, Empty) { + OverloadExprBits.NumResults = NumResults; + OverloadExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; } // DependentScopeDeclRefExpr @@ -1401,19 +1415,15 @@ return true; } -UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C, - bool HasUnresolvedUsing, - Expr *Base, QualType BaseType, - bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &MemberNameInfo, - const TemplateArgumentListInfo *TemplateArgs, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End) +UnresolvedMemberExpr::UnresolvedMemberExpr( + const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base, + QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + const DeclarationNameInfo &MemberNameInfo, + const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, + UnresolvedSetIterator End) : OverloadExpr( - UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc, + UnresolvedMemberExprClass, Context, QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End, // Dependent ((Base && Base->isTypeDependent()) || BaseType->isDependentType()), @@ -1422,14 +1432,22 @@ // Contains unexpanded parameter pack ((Base && Base->containsUnexpandedParameterPack()) || BaseType->containsUnexpandedParameterPack())), - IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), Base(Base), - BaseType(BaseType), OperatorLoc(OperatorLoc) { + Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) { + UnresolvedMemberExprBits.IsArrow = IsArrow; + UnresolvedMemberExprBits.HasUnresolvedUsing = HasUnresolvedUsing; + // Check whether all of the members are non-static member functions, // and if so, mark give this bound-member type instead of overload type. if (hasOnlyNonStaticMemberFunctions(Begin, End)) - setType(C.BoundMemberTy); + setType(Context.BoundMemberTy); } +UnresolvedMemberExpr::UnresolvedMemberExpr(EmptyShell Empty, + unsigned NumResults, + bool HasTemplateKWAndArgsInfo) + : OverloadExpr(UnresolvedMemberExprClass, Empty, NumResults, + HasTemplateKWAndArgsInfo) {} + bool UnresolvedMemberExpr::isImplicitAccess() const { if (!Base) return true; @@ -1438,39 +1456,37 @@ } UnresolvedMemberExpr *UnresolvedMemberExpr::Create( - const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, - bool IsArrow, SourceLocation OperatorLoc, + const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base, + QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) { + unsigned NumResults = End - Begin; bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); - std::size_t Size = - totalSizeToAlloc( - HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0); - - void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr)); + unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0; + unsigned Size = totalSizeToAlloc( + NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); + void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr)); return new (Mem) UnresolvedMemberExpr( - C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, - TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End); + Context, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, + QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End); } -UnresolvedMemberExpr * -UnresolvedMemberExpr::CreateEmpty(const ASTContext &C, - bool HasTemplateKWAndArgsInfo, - unsigned NumTemplateArgs) { +UnresolvedMemberExpr *UnresolvedMemberExpr::CreateEmpty( + const ASTContext &Context, unsigned NumResults, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); - std::size_t Size = - totalSizeToAlloc( - HasTemplateKWAndArgsInfo, NumTemplateArgs); - - void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr)); - auto *E = new (Mem) UnresolvedMemberExpr(EmptyShell()); - E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; - return E; + unsigned Size = totalSizeToAlloc( + NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); + void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr)); + return new (Mem) + UnresolvedMemberExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo); } -CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { +CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() { // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this. // If there was a nested name specifier, it names the naming class. Index: lib/Serialization/ASTReaderStmt.cpp =================================================================== --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -1648,19 +1648,33 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - if (Record.readInt()) // HasTemplateKWAndArgsInfo + unsigned NumResults = Record.readInt(); + bool HasTemplateKWAndArgsInfo = Record.readInt(); + assert((E->getNumDecls() == NumResults) && "Wrong NumResults!"); + assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) && + "Wrong HasTemplateKWAndArgsInfo!"); + + if (HasTemplateKWAndArgsInfo) { + unsigned NumTemplateArgs = Record.readInt(); ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(), E->getTrailingTemplateArgumentLoc(), - /*NumTemplateArgs=*/Record.readInt()); + NumTemplateArgs); + assert((E->getNumTemplateArgs() == NumTemplateArgs) && + "Wrong NumTemplateArgs!"); + } - unsigned NumDecls = Record.readInt(); UnresolvedSet<8> Decls; - for (unsigned i = 0; i != NumDecls; ++i) { + for (unsigned I = 0; I != NumResults; ++I) { auto *D = ReadDeclAs(); auto AS = (AccessSpecifier)Record.readInt(); Decls.addDecl(D, AS); } - E->initializeResults(Record.getContext(), Decls.begin(), Decls.end()); + + DeclAccessPair *Results = E->getTrailingResults(); + UnresolvedSetIterator Iter = Decls.begin(); + for (unsigned I = 0; I != NumResults; ++I) { + Results[I] = (Iter + I).getPair(); + } ReadDeclarationNameInfo(E->NameInfo); E->QualifierLoc = Record.readNestedNameSpecifierLoc(); @@ -1668,8 +1682,8 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { VisitOverloadExpr(E); - E->IsArrow = Record.readInt(); - E->HasUnresolvedUsing = Record.readInt(); + E->UnresolvedMemberExprBits.IsArrow = Record.readInt(); + E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt(); E->Base = Record.readSubExpr(); E->BaseType = Record.readType(); E->OperatorLoc = ReadSourceLocation(); @@ -1677,8 +1691,8 @@ void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); - E->RequiresADL = Record.readInt(); - E->Overloaded = Record.readInt(); + E->UnresolvedLookupExprBits.RequiresADL = Record.readInt(); + E->UnresolvedLookupExprBits.Overloaded = Record.readInt(); E->NamingClass = ReadDeclAs(); } @@ -3261,19 +3275,25 @@ break; case EXPR_CXX_UNRESOLVED_MEMBER: - S = UnresolvedMemberExpr::CreateEmpty(Context, - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] - ? Record[ASTStmtReader::NumExprFields + 1] - : 0); + S = UnresolvedMemberExpr::CreateEmpty( + Context, + /*NumResults=*/Record[ASTStmtReader::NumExprFields], + /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1], + /*NumTemplateArgs=*/ + Record[ASTStmtReader::NumExprFields + 1] + ? Record[ASTStmtReader::NumExprFields + 2] + : 0); break; case EXPR_CXX_UNRESOLVED_LOOKUP: - S = UnresolvedLookupExpr::CreateEmpty(Context, - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] - ? Record[ASTStmtReader::NumExprFields + 1] - : 0); + S = UnresolvedLookupExpr::CreateEmpty( + Context, + /*NumResults=*/Record[ASTStmtReader::NumExprFields], + /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1], + /*NumTemplateArgs=*/ + Record[ASTStmtReader::NumExprFields + 1] + ? Record[ASTStmtReader::NumExprFields + 2] + : 0); break; case EXPR_TYPE_TRAIT: Index: lib/Serialization/ASTWriterStmt.cpp =================================================================== --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -1625,25 +1625,23 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - // Don't emit anything here, HasTemplateKWAndArgsInfo must be - // emitted first. - - Record.push_back(E->HasTemplateKWAndArgsInfo); - if (E->HasTemplateKWAndArgsInfo) { + Record.push_back(E->getNumDecls()); + Record.push_back(E->hasTemplateKWAndArgsInfo()); + if (E->hasTemplateKWAndArgsInfo()) { const ASTTemplateKWAndArgsInfo &ArgInfo = *E->getTrailingASTTemplateKWAndArgsInfo(); Record.push_back(ArgInfo.NumTemplateArgs); AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc()); } - Record.push_back(E->getNumDecls()); - for (OverloadExpr::decls_iterator - OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) { + for (OverloadExpr::decls_iterator OvI = E->decls_begin(), + OvE = E->decls_end(); + OvI != OvE; ++OvI) { Record.AddDeclRef(OvI.getDecl()); Record.push_back(OvI.getAccess()); } - Record.AddDeclarationNameInfo(E->NameInfo); + Record.AddDeclarationNameInfo(E->getNameInfo()); Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); }