Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -1038,12 +1038,13 @@ private llvm::TrailingObjects { + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + /// The declaration that we are referencing. ValueDecl *D; - /// The location of the declaration name itself. - SourceLocation Loc; - /// Provides source/type location info for the declaration name /// embedded in D. DeclarationNameLoc DNLoc; @@ -1064,18 +1065,15 @@ /// this DRE. bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } - DeclRefExpr(const ASTContext &Ctx, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - ValueDecl *D, bool RefersToEnlosingVariableOrCapture, - const DeclarationNameInfo &NameInfo, - NamedDecl *FoundD, - const TemplateArgumentListInfo *TemplateArgs, - QualType T, ExprValueKind VK); + DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, + bool RefersToEnlosingVariableOrCapture, + const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, + const TemplateArgumentListInfo *TemplateArgs, QualType T, + ExprValueKind VK); /// Construct an empty declaration reference expression. - explicit DeclRefExpr(EmptyShell Empty) - : Expr(DeclRefExprClass, Empty) { } + explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} /// Computes the type- and value-dependence flags for this /// declaration reference expression. @@ -1085,12 +1083,13 @@ DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, ExprValueKind VK, SourceLocation L, const DeclarationNameLoc &LocInfo = DeclarationNameLoc()) - : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), - D(D), Loc(L), DNLoc(LocInfo) { - DeclRefExprBits.HasQualifier = 0; - DeclRefExprBits.HasTemplateKWAndArgsInfo = 0; - DeclRefExprBits.HasFoundDecl = 0; - DeclRefExprBits.HadMultipleCandidates = 0; + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), + D(D), DNLoc(LocInfo) { + DeclRefExprBits.Loc = L; + DeclRefExprBits.HasQualifier = false; + DeclRefExprBits.HasTemplateKWAndArgsInfo = false; + DeclRefExprBits.HasFoundDecl = false; + DeclRefExprBits.HadMultipleCandidates = false; DeclRefExprBits.RefersToEnclosingVariableOrCapture = RefersToEnclosingVariableOrCapture; computeDependence(D->getASTContext()); @@ -1112,8 +1111,7 @@ const TemplateArgumentListInfo *TemplateArgs = nullptr); /// Construct an empty declaration reference expression. - static DeclRefExpr *CreateEmpty(const ASTContext &Context, - bool HasQualifier, + static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, bool HasFoundDecl, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); @@ -1123,11 +1121,11 @@ void setDecl(ValueDecl *NewD) { D = NewD; } DeclarationNameInfo getNameInfo() const { - return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc); + return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc); } - SourceLocation getLocation() const { return Loc; } - void setLocation(SourceLocation L) { Loc = L; } + SourceLocation getLocation() const { return DeclRefExprBits.Loc; } + void setLocation(SourceLocation L) { DeclRefExprBits.Loc = L; } SourceLocation getBeginLoc() const LLVM_READONLY; SourceLocation getEndLoc() const LLVM_READONLY; @@ -1172,21 +1170,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 getTrailingObjects()->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 getTrailingObjects()->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 getTrailingObjects()->RAngleLoc; } @@ -1258,10 +1259,6 @@ const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } - - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// Used by IntegerLiteral/FloatingLiteral to store the numeric without @@ -1874,15 +1871,11 @@ /// later returns zero in the type of the operand. /// class UnaryOperator : public Expr { + Stmt *Val; + public: typedef UnaryOperatorKind Opcode; -private: - unsigned Opc : 5; - unsigned CanOverflow : 1; - SourceLocation Loc; - Stmt *Val; -public: UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow) : Expr(UnaryOperatorClass, type, VK, OK, @@ -1891,21 +1884,28 @@ (input->isInstantiationDependent() || type->isInstantiationDependentType()), input->containsUnexpandedParameterPack()), - Opc(opc), CanOverflow(CanOverflow), Loc(l), Val(input) {} + Val(input) { + setOpcode(opc); + setCanOverflow(CanOverflow); + setOperatorLoc(l); + } /// Build an empty unary operator. - explicit UnaryOperator(EmptyShell Empty) - : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { } + explicit UnaryOperator(EmptyShell Empty) : Expr(UnaryOperatorClass, Empty) { + setOpcode(UO_AddrOf); + } - Opcode getOpcode() const { return static_cast(Opc); } - void setOpcode(Opcode O) { Opc = O; } + Opcode getOpcode() const { + return static_cast(UnaryOperatorBits.OperatorKind); + } + void setOpcode(Opcode Opc) { UnaryOperatorBits.OperatorKind = Opc; } Expr *getSubExpr() const { return cast(Val); } void setSubExpr(Expr *E) { Val = E; } /// getOperatorLoc - Return the location of the operator. - SourceLocation getOperatorLoc() const { return Loc; } - void setOperatorLoc(SourceLocation L) { Loc = L; } + SourceLocation getOperatorLoc() const { return UnaryOperatorBits.Loc; } + void setOperatorLoc(SourceLocation L) { UnaryOperatorBits.Loc = L; } /// Returns true if the unary operator can cause an overflow. For instance, /// signed int i = INT_MAX; i++; @@ -1913,8 +1913,8 @@ /// Due to integer promotions, c++ is promoted to an int before the postfix /// increment, and the result is an int that cannot overflow. However, i++ /// can overflow. - bool canOverflow() const { return CanOverflow; } - void setCanOverflow(bool C) { CanOverflow = C; } + bool canOverflow() const { return UnaryOperatorBits.CanOverflow; } + void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; } /// isPostfix - Return true if this is a postfix operation, like x++. static bool isPostfix(Opcode Op) { @@ -1922,9 +1922,7 @@ } /// isPrefix - Return true if this is a prefix operation, like --x. - static bool isPrefix(Opcode Op) { - return Op == UO_PreInc || Op == UO_PreDec; - } + static bool isPrefix(Opcode Op) { return Op == UO_PreInc || Op == UO_PreDec; } bool isPrefix() const { return isPrefix(getOpcode()); } bool isPostfix() const { return isPostfix(getOpcode()); } @@ -1932,16 +1930,12 @@ static bool isIncrementOp(Opcode Op) { return Op == UO_PreInc || Op == UO_PostInc; } - bool isIncrementOp() const { - return isIncrementOp(getOpcode()); - } + bool isIncrementOp() const { return isIncrementOp(getOpcode()); } static bool isDecrementOp(Opcode Op) { return Op == UO_PreDec || Op == UO_PostDec; } - bool isDecrementOp() const { - return isDecrementOp(getOpcode()); - } + bool isDecrementOp() const { return isDecrementOp(getOpcode()); } static bool isIncrementDecrementOp(Opcode Op) { return Op <= UO_PreDec; } bool isIncrementDecrementOp() const { @@ -1966,19 +1960,19 @@ static OverloadedOperatorKind getOverloadedOperator(Opcode Opc); SourceLocation getBeginLoc() const LLVM_READONLY { - return isPostfix() ? Val->getBeginLoc() : Loc; + return isPostfix() ? Val->getBeginLoc() : getOperatorLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { - return isPostfix() ? Loc : Val->getEndLoc(); + return isPostfix() ? getOperatorLoc() : Val->getEndLoc(); } - SourceLocation getExprLoc() const LLVM_READONLY { return Loc; } + SourceLocation getExprLoc() const { return getOperatorLoc(); } static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryOperatorClass; } // Iterators - child_range children() { return child_range(&Val, &Val+1); } + child_range children() { return child_range(&Val, &Val + 1); } const_child_range children() const { return const_child_range(&Val, &Val + 1); } @@ -2561,6 +2555,10 @@ private llvm::TrailingObjects { + friend TrailingObjects; + friend class ASTReader; + friend class ASTStmtWriter; + /// Base - the expression for the base pointer or structure references. In /// X.F, this is "X". Stmt *Base; @@ -2579,32 +2577,12 @@ /// This is the location of the -> or . in the expression. SourceLocation OperatorLoc; - /// IsArrow - True if this is "X->F", false if this is "X.F". - bool IsArrow : 1; - - /// True if this member expression used a nested-name-specifier to - /// refer to the member, e.g., "x->Base::f", or found its member via a using - /// declaration. When true, a MemberExprNameQualifier - /// structure is allocated immediately after the MemberExpr. - bool HasQualifierOrFoundDecl : 1; - - /// True if this member expression specified a template keyword - /// and/or a template argument list explicitly, e.g., x->f, - /// x->template f, x->template f. - /// When true, an ASTTemplateKWAndArgsInfo structure and its - /// TemplateArguments (if any) are present. - bool HasTemplateKWAndArgsInfo : 1; - - /// True if this member expression refers to a method that - /// was resolved from an overloaded set having size greater than 1. - bool HadMultipleCandidates : 1; - size_t numTrailingObjects(OverloadToken) const { - return HasQualifierOrFoundDecl ? 1 : 0; + return MemberExprBits.HasQualifierOrFoundDecl ? 1 : 0; } size_t numTrailingObjects(OverloadToken) const { - return HasTemplateKWAndArgsInfo ? 1 : 0; + return MemberExprBits.HasTemplateKWAndArgsInfo ? 1 : 0; } public: @@ -2615,10 +2593,12 @@ base->isValueDependent(), base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()), - MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc), - IsArrow(isarrow), HasQualifierOrFoundDecl(false), - HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) { + MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc) { assert(memberdecl->getDeclName() == NameInfo.getName()); + MemberExprBits.IsArrow = isarrow; + MemberExprBits.HasQualifierOrFoundDecl = false; + MemberExprBits.HasTemplateKWAndArgsInfo = false; + MemberExprBits.HadMultipleCandidates = false; } // NOTE: this constructor should be used only when it is known that @@ -2632,9 +2612,12 @@ base->isValueDependent(), base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l), - OperatorLoc(operatorloc), IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), - HadMultipleCandidates(false) {} + OperatorLoc(operatorloc) { + MemberExprBits.IsArrow = isarrow; + MemberExprBits.HasQualifierOrFoundDecl = false; + MemberExprBits.HasTemplateKWAndArgsInfo = false; + MemberExprBits.HadMultipleCandidates = false; + } static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow, SourceLocation OperatorLoc, @@ -2657,7 +2640,7 @@ /// Retrieves the declaration found by lookup. DeclAccessPair getFoundDecl() const { - if (!HasQualifierOrFoundDecl) + if (!MemberExprBits.HasQualifierOrFoundDecl) return DeclAccessPair::make(getMemberDecl(), getMemberDecl()->getAccess()); return getTrailingObjects()->FoundDecl; @@ -2672,7 +2655,7 @@ /// nested-name-specifier that precedes the member name, with source-location /// information. NestedNameSpecifierLoc getQualifierLoc() const { - if (!HasQualifierOrFoundDecl) + if (!MemberExprBits.HasQualifierOrFoundDecl) return NestedNameSpecifierLoc(); return getTrailingObjects()->QualifierLoc; @@ -2688,21 +2671,24 @@ /// Retrieve the location of the template keyword preceding /// the member name, if any. SourceLocation getTemplateKeywordLoc() const { - if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + if (!MemberExprBits.HasTemplateKWAndArgsInfo) + return SourceLocation(); return getTrailingObjects()->TemplateKWLoc; } /// Retrieve the location of the left angle bracket starting the /// explicit template argument list following the member name, if any. SourceLocation getLAngleLoc() const { - if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + if (!MemberExprBits.HasTemplateKWAndArgsInfo) + return SourceLocation(); return getTrailingObjects()->LAngleLoc; } /// Retrieve the location of the right angle bracket ending the /// explicit template argument list following the member name, if any. SourceLocation getRAngleLoc() const { - if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + if (!MemberExprBits.HasTemplateKWAndArgsInfo) + return SourceLocation(); return getTrailingObjects()->RAngleLoc; } @@ -2745,14 +2731,14 @@ /// Retrieve the member declaration name info. DeclarationNameInfo getMemberNameInfo() const { - return DeclarationNameInfo(MemberDecl->getDeclName(), - MemberLoc, MemberDNLoc); + return DeclarationNameInfo(MemberDecl->getDeclName(), MemberLoc, + MemberDNLoc); } SourceLocation getOperatorLoc() const LLVM_READONLY { return OperatorLoc; } - bool isArrow() const { return IsArrow; } - void setArrow(bool A) { IsArrow = A; } + bool isArrow() const { return MemberExprBits.IsArrow; } + void setArrow(bool A) { MemberExprBits.IsArrow = A; } /// getMemberLoc - Return the location of the "member", in X->F, it is the /// location of 'F'. @@ -2772,13 +2758,13 @@ /// Returns true if this member expression refers to a method that /// was resolved from an overloaded set having size greater than 1. bool hadMultipleCandidates() const { - return HadMultipleCandidates; + return MemberExprBits.HadMultipleCandidates; } /// Sets the flag telling whether this expression refers to /// a method that was resolved from an overloaded set having size /// greater than 1. void setHadMultipleCandidates(bool V = true) { - HadMultipleCandidates = V; + MemberExprBits.HadMultipleCandidates = V; } /// Returns true if virtual dispatch is performed. @@ -2794,14 +2780,10 @@ } // Iterators - child_range children() { return child_range(&Base, &Base+1); } + child_range children() { return child_range(&Base, &Base + 1); } const_child_range children() const { return const_child_range(&Base, &Base + 1); } - - friend TrailingObjects; - friend class ASTReader; - friend class ASTStmtWriter; }; /// CompoundLiteralExpr - [C99 6.5.2.5] @@ -3192,32 +3174,25 @@ /// "+" resolves to an overloaded operator, CXXOperatorCallExpr will /// be used to express the computation. class BinaryOperator : public Expr { -public: - typedef BinaryOperatorKind Opcode; - -private: - unsigned Opc : 6; - - // This is only meaningful for operations on floating point types and 0 - // otherwise. - unsigned FPFeatures : 3; - SourceLocation OpLoc; - enum { LHS, RHS, END_EXPR }; - Stmt* SubExprs[END_EXPR]; + Stmt *SubExprs[END_EXPR]; + public: + typedef BinaryOperatorKind Opcode; BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, FPOptions FPFeatures) - : Expr(BinaryOperatorClass, ResTy, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())), - Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) { + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, + FPOptions FPFeatures) + : Expr(BinaryOperatorClass, ResTy, VK, OK, + lhs->isTypeDependent() || rhs->isTypeDependent(), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())) { + setOpcode(opc); + setFPFeatures(FPFeatures); + setOperatorLoc(opLoc); SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; assert(!isCompoundAssignmentOp() && @@ -3225,15 +3200,19 @@ } /// Construct an empty binary operator. - explicit BinaryOperator(EmptyShell Empty) - : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { } + explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) { + setOpcode(BO_Comma); + } - SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; } - SourceLocation getOperatorLoc() const { return OpLoc; } - void setOperatorLoc(SourceLocation L) { OpLoc = L; } + SourceLocation getExprLoc() const { return BinaryOperatorBits.OpLoc; } + SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; } + void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; } + + Opcode getOpcode() const { + return static_cast(BinaryOperatorBits.OperatorKind); + } - Opcode getOpcode() const { return static_cast(Opc); } - void setOpcode(Opcode O) { Opc = O; } + void setOpcode(Opcode Opc) { BinaryOperatorBits.OperatorKind = Opc; } Expr *getLHS() const { return cast(SubExprs[LHS]); } void setLHS(Expr *E) { SubExprs[LHS] = E; } @@ -3262,38 +3241,56 @@ static OverloadedOperatorKind getOverloadedOperator(Opcode Opc); /// predicates to categorize the respective opcodes. - bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; } + static bool isPtrMemOp(Opcode Opc) { + return Opc == BO_PtrMemD || Opc == BO_PtrMemI; + } + bool isPtrMemOp() const { return isPtrMemOp(getOpcode()); } + static bool isMultiplicativeOp(Opcode Opc) { return Opc >= BO_Mul && Opc <= BO_Rem; } bool isMultiplicativeOp() const { return isMultiplicativeOp(getOpcode()); } - static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; } + + static bool isAdditiveOp(Opcode Opc) { + return Opc == BO_Add || Opc == BO_Sub; + } bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); } + static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; } bool isShiftOp() const { return isShiftOp(getOpcode()); } static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; } bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); } - static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; } + static bool isRelationalOp(Opcode Opc) { + return Opc >= BO_LT && Opc <= BO_GE; + } bool isRelationalOp() const { return isRelationalOp(getOpcode()); } static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; } bool isEqualityOp() const { return isEqualityOp(getOpcode()); } - static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; } + static bool isComparisonOp(Opcode Opc) { + return Opc >= BO_Cmp && Opc <= BO_NE; + } bool isComparisonOp() const { return isComparisonOp(getOpcode()); } static Opcode negateComparisonOp(Opcode Opc) { switch (Opc) { default: llvm_unreachable("Not a comparison operator."); - case BO_LT: return BO_GE; - case BO_GT: return BO_LE; - case BO_LE: return BO_GT; - case BO_GE: return BO_LT; - case BO_EQ: return BO_NE; - case BO_NE: return BO_EQ; + case BO_LT: + return BO_GE; + case BO_GT: + return BO_LE; + case BO_LE: + return BO_GT; + case BO_GE: + return BO_LT; + case BO_EQ: + return BO_NE; + case BO_NE: + return BO_EQ; } } @@ -3301,17 +3298,23 @@ switch (Opc) { default: llvm_unreachable("Not a comparison operator."); - case BO_LT: return BO_GT; - case BO_GT: return BO_LT; - case BO_LE: return BO_GE; - case BO_GE: return BO_LE; + case BO_LT: + return BO_GT; + case BO_GT: + return BO_LT; + case BO_LE: + return BO_GE; + case BO_GE: + return BO_LE; case BO_EQ: case BO_NE: return Opc; } } - static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; } + static bool isLogicalOp(Opcode Opc) { + return Opc == BO_LAnd || Opc == BO_LOr; + } bool isLogicalOp() const { return isLogicalOp(getOpcode()); } static bool isAssignmentOp(Opcode Opc) { @@ -3336,9 +3339,7 @@ static bool isShiftAssignOp(Opcode Opc) { return Opc == BO_ShlAssign || Opc == BO_ShrAssign; } - bool isShiftAssignOp() const { - return isShiftAssignOp(getOpcode()); - } + bool isShiftAssignOp() const { return isShiftAssignOp(getOpcode()); } // Return true if a binary operator using the specified opcode and operands // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized @@ -3353,48 +3354,54 @@ // Iterators child_range children() { - return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); + return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } + const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } // Set the FP contractability status of this operator. Only meaningful for // operations on floating point types. - void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); } + void setFPFeatures(FPOptions F) { + BinaryOperatorBits.FPFeatures = F.getInt(); + } - FPOptions getFPFeatures() const { return FPOptions(FPFeatures); } + FPOptions getFPFeatures() const { + return FPOptions(BinaryOperatorBits.FPFeatures); + } // Get the FP contractability status of this operator. Only meaningful for // operations on floating point types. bool isFPContractableWithinStatement() const { - return FPOptions(FPFeatures).allowFPContractWithinStatement(); + return getFPFeatures().allowFPContractWithinStatement(); } // Get the FENV_ACCESS status of this operator. Only meaningful for // operations on floating point types. - bool isFEnvAccessOn() const { - return FPOptions(FPFeatures).allowFEnvAccess(); - } + bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); } protected: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, FPOptions FPFeatures, bool dead2) - : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())), - Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) { + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, + FPOptions FPFeatures, bool dead2) + : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, + lhs->isTypeDependent() || rhs->isTypeDependent(), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())) { + setOpcode(opc); + setFPFeatures(FPFeatures); + setOperatorLoc(opLoc); SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; } - BinaryOperator(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty), Opc(BO_MulAssign) { } + BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { + setOpcode(BO_MulAssign); + } }; /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep Index: include/clang/AST/Stmt.h =================================================================== --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -378,6 +378,58 @@ unsigned HasFoundDecl : 1; unsigned HadMultipleCandidates : 1; unsigned RefersToEnclosingVariableOrCapture : 1; + + /// The location of the declaration name itself. + SourceLocation Loc; + }; + + class UnaryOperatorBitfields { + friend class UnaryOperator; + + unsigned : NumExprBits; + + /// The operator kind. + unsigned OperatorKind : 5; + + unsigned CanOverflow : 1; + + /// The location of the operator. + SourceLocation Loc; + }; + + class CallExprBitfields { + friend class CallExpr; + + unsigned : NumExprBits; + + unsigned NumPreArgs : 1; + }; + + class MemberExprBitfields { + friend class ASTStmtWriter; + friend class MemberExpr; + + unsigned : NumExprBits; + + /// IsArrow - True if this is "X->F", false if this is "X.F". + unsigned IsArrow : 1; + + /// True if this member expression used a nested-name-specifier to + /// refer to the member, e.g., "x->Base::f", or found its member via a using + /// declaration. When true, a MemberExprNameQualifier + /// structure is allocated immediately after the MemberExpr. + unsigned HasQualifierOrFoundDecl : 1; + + /// True if this member expression specified a template keyword + /// and/or a template argument list explicitly, e.g., x->f, + /// x->template f, x->template f. + /// When true, an ASTTemplateKWAndArgsInfo structure and its + /// TemplateArguments (if any) are present. + unsigned HasTemplateKWAndArgsInfo : 1; + + /// True if this member expression refers to a method that + /// was resolved from an overloaded set having size greater than 1. + unsigned HadMultipleCandidates : 1; }; class CastExprBitfields { @@ -391,12 +443,20 @@ unsigned BasePathIsEmpty : 1; }; - class CallExprBitfields { - friend class CallExpr; + class BinaryOperatorBitfields { + friend class BinaryOperator; unsigned : NumExprBits; - unsigned NumPreArgs : 1; + /// The kind of this binary operator. + unsigned OperatorKind : 6; + + /// This is only meaningful for operations on floating + /// point types and 0 otherwise. + unsigned FPFeatures : 3; + + /// The location of the operator. + SourceLocation OpLoc; }; class ExprWithCleanupsBitfields { @@ -502,8 +562,11 @@ FloatingLiteralBitfields FloatingLiteralBits; UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; DeclRefExprBitfields DeclRefExprBits; - CastExprBitfields CastExprBits; + UnaryOperatorBitfields UnaryOperatorBits; CallExprBitfields CallExprBits; + MemberExprBitfields MemberExprBits; + CastExprBitfields CastExprBits; + BinaryOperatorBitfields BinaryOperatorBits; ExprWithCleanupsBitfields ExprWithCleanupsBits; PseudoObjectExprBitfields PseudoObjectExprBits; OpaqueValueExprBitfields OpaqueValueExprBits; Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -351,7 +351,8 @@ const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), - D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { + D(D), DNLoc(NameInfo.getInfo()) { + DeclRefExprBits.Loc = NameInfo.getLoc(); DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; if (QualifierLoc) { new (getTrailingObjects()) @@ -1527,7 +1528,7 @@ QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) E->setInstantiationDependent(true); - E->HasQualifierOrFoundDecl = true; + E->MemberExprBits.HasQualifierOrFoundDecl = true; MemberExprNameQualifier *NQ = E->getTrailingObjects(); @@ -1535,7 +1536,7 @@ NQ->FoundDecl = founddecl; } - E->HasTemplateKWAndArgsInfo = (targs || TemplateKWLoc.isValid()); + E->MemberExprBits.HasTemplateKWAndArgsInfo = (targs || TemplateKWLoc.isValid()); if (targs) { bool Dependent = false; Index: lib/Serialization/ASTWriterStmt.cpp =================================================================== --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -655,8 +655,8 @@ if (E->hasQualifier()) Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); - Record.push_back(E->HasTemplateKWAndArgsInfo); - if (E->HasTemplateKWAndArgsInfo) { + Record.push_back(E->MemberExprBits.HasTemplateKWAndArgsInfo); + if (E->MemberExprBits.HasTemplateKWAndArgsInfo) { Record.AddSourceLocation(E->getTemplateKeywordLoc()); unsigned NumTemplateArgs = E->getNumTemplateArgs(); Record.push_back(NumTemplateArgs);