diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1593,31 +1593,38 @@ private: unsigned Value; - SourceLocation Loc; + public: // type should be IntTy CharacterLiteral(unsigned value, CharacterKind kind, QualType type, SourceLocation l) : Expr(CharacterLiteralClass, type, VK_PRValue, OK_Ordinary), - Value(value), Loc(l) { + Value(value) { CharacterLiteralBits.Kind = kind; + CharacterLiteralBits.Loc = l; setDependence(ExprDependence::None); } /// Construct an empty character literal. CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { } - SourceLocation getLocation() const { return Loc; } + SourceLocation getLocation() const { return CharacterLiteralBits.Loc; } CharacterKind getKind() const { return static_cast(CharacterLiteralBits.Kind); } - SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } - SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } + SourceLocation getBeginLoc() const LLVM_READONLY { + return CharacterLiteralBits.Loc; + } + SourceLocation getEndLoc() const LLVM_READONLY { + return CharacterLiteralBits.Loc; + } unsigned getValue() const { return Value; } - void setLocation(SourceLocation Location) { Loc = Location; } + void setLocation(SourceLocation Location) { + CharacterLiteralBits.Loc = Location; + } void setKind(CharacterKind kind) { CharacterLiteralBits.Kind = kind; } void setValue(unsigned Val) { Value = Val; } @@ -1637,8 +1644,6 @@ }; class FloatingLiteral : public Expr, private APFloatStorage { - SourceLocation Loc; - FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L); @@ -1691,11 +1696,15 @@ /// debugging dumps, etc. double getValueAsApproximateDouble() const; - SourceLocation getLocation() const { return Loc; } - void setLocation(SourceLocation L) { Loc = L; } + SourceLocation getLocation() const { return FloatingLiteralBits.Loc; } + void setLocation(SourceLocation L) { FloatingLiteralBits.Loc = L; } - SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } - SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } + SourceLocation getBeginLoc() const LLVM_READONLY { + return FloatingLiteralBits.Loc; + } + SourceLocation getEndLoc() const LLVM_READONLY { + return FloatingLiteralBits.Loc; + } static bool classof(const Stmt *T) { return T->getStmtClass() == FloatingLiteralClass; @@ -2551,7 +2560,7 @@ TypeSourceInfo *Ty; Stmt *Ex; } Argument; - SourceLocation OpLoc, RParenLoc; + SourceLocation RParenLoc; public: UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo, @@ -2559,9 +2568,10 @@ SourceLocation rp) : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_PRValue, OK_Ordinary), - OpLoc(op), RParenLoc(rp) { + RParenLoc(rp) { assert(ExprKind <= UETT_Last && "invalid enum value!"); UnaryExprOrTypeTraitExprBits.Kind = ExprKind; + UnaryExprOrTypeTraitExprBits.OpLoc = op; assert(static_cast(ExprKind) == UnaryExprOrTypeTraitExprBits.Kind && "UnaryExprOrTypeTraitExprBits.Kind overflow!"); @@ -2619,13 +2629,19 @@ return isArgumentType() ? getArgumentType() : getArgumentExpr()->getType(); } - SourceLocation getOperatorLoc() const { return OpLoc; } - void setOperatorLoc(SourceLocation L) { OpLoc = L; } + SourceLocation getOperatorLoc() const { + return UnaryExprOrTypeTraitExprBits.OpLoc; + } + void setOperatorLoc(SourceLocation L) { + UnaryExprOrTypeTraitExprBits.OpLoc = L; + } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceLocation getBeginLoc() const LLVM_READONLY { return OpLoc; } + SourceLocation getBeginLoc() const LLVM_READONLY { + return UnaryExprOrTypeTraitExprBits.OpLoc; + } SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { @@ -4682,7 +4698,7 @@ /// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), /// __builtin_FUNCTION(), or __builtin_FILE(). class SourceLocExpr final : public Expr { - SourceLocation BuiltinLoc, RParenLoc; + SourceLocation RParenLoc; DeclContext *ParentContext; public: @@ -4724,8 +4740,8 @@ const DeclContext *getParentContext() const { return ParentContext; } DeclContext *getParentContext() { return ParentContext; } - SourceLocation getLocation() const { return BuiltinLoc; } - SourceLocation getBeginLoc() const { return BuiltinLoc; } + SourceLocation getLocation() const { return SourceLocExprBits.BuiltinLoc; } + SourceLocation getBeginLoc() const { return SourceLocExprBits.BuiltinLoc; } SourceLocation getEndLoc() const { return RParenLoc; } child_range children() { @@ -4793,7 +4809,7 @@ // FIXME: Eliminate this vector in favor of ASTContext allocation typedef ASTVector InitExprsTy; InitExprsTy InitExprs; - SourceLocation LBraceLoc, RBraceLoc; + SourceLocation RBraceLoc; /// The alternative form of the initializer list (if it exists). /// The int part of the pair stores whether this initializer list is @@ -4922,7 +4938,7 @@ // FIXME: This is wrong; InitListExprs created by semantic analysis have // valid source locations too! bool isExplicit() const { - return LBraceLoc.isValid() && RBraceLoc.isValid(); + return InitListExprBits.LBraceLoc.isValid() && RBraceLoc.isValid(); } // Is this an initializer for an array of characters, initialized by a string @@ -4938,8 +4954,8 @@ /// idiomatic? bool isIdiomaticZeroInitializer(const LangOptions &LangOpts) const; - SourceLocation getLBraceLoc() const { return LBraceLoc; } - void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; } + SourceLocation getLBraceLoc() const { return InitListExprBits.LBraceLoc; } + void setLBraceLoc(SourceLocation Loc) { InitListExprBits.LBraceLoc = Loc; } SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; } diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3998,14 +3998,15 @@ friend class ASTStmtReader; Stmt *Operand; - SourceRange Range; + SourceLocation RParenLoc; public: CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, SourceLocation Keyword, SourceLocation RParen) : Expr(CXXNoexceptExprClass, Ty, VK_PRValue, OK_Ordinary), - Operand(Operand), Range(Keyword, RParen) { + Operand(Operand), RParenLoc(RParen) { CXXNoexceptExprBits.Value = Val == CT_Cannot; + CXXNoexceptExprBits.KeywordLoc = Keyword; setDependence(computeDependence(this, Val)); } @@ -4013,9 +4014,11 @@ Expr *getOperand() const { return static_cast(Operand); } - SourceLocation getBeginLoc() const { return Range.getBegin(); } - SourceLocation getEndLoc() const { return Range.getEnd(); } - SourceRange getSourceRange() const { return Range; } + SourceLocation getBeginLoc() const { return CXXNoexceptExprBits.KeywordLoc; } + SourceLocation getEndLoc() const { return RParenLoc; } + SourceRange getSourceRange() const { + return {CXXNoexceptExprBits.KeywordLoc, RParenLoc}; + } bool getValue() const { return CXXNoexceptExprBits.Value; } @@ -4679,8 +4682,6 @@ class CoroutineSuspendExpr : public Expr { friend class ASTStmtReader; - SourceLocation KeywordLoc; - enum SubExpr { Common, Ready, Suspend, Resume, Count }; Stmt *SubExprs[SubExpr::Count]; @@ -4692,7 +4693,8 @@ OpaqueValueExpr *OpaqueValue) : Expr(SC, Resume->getType(), Resume->getValueKind(), Resume->getObjectKind()), - KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) { + OpaqueValue(OpaqueValue) { + CoroutineSuspendExprBits.KeywordLoc = KeywordLoc; SubExprs[SubExpr::Common] = Common; SubExprs[SubExpr::Ready] = Ready; SubExprs[SubExpr::Suspend] = Suspend; @@ -4702,9 +4704,10 @@ CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty, Expr *Common) - : Expr(SC, Ty, VK_PRValue, OK_Ordinary), KeywordLoc(KeywordLoc) { + : Expr(SC, Ty, VK_PRValue, OK_Ordinary) { assert(Common->isTypeDependent() && Ty->isDependentType() && "wrong constructor for non-dependent co_await/co_yield expression"); + CoroutineSuspendExprBits.KeywordLoc = KeywordLoc; SubExprs[SubExpr::Common] = Common; SubExprs[SubExpr::Ready] = nullptr; SubExprs[SubExpr::Suspend] = nullptr; @@ -4719,7 +4722,9 @@ SubExprs[SubExpr::Resume] = nullptr; } - SourceLocation getKeywordLoc() const { return KeywordLoc; } + SourceLocation getKeywordLoc() const { + return CoroutineSuspendExprBits.KeywordLoc; + } Expr *getCommonExpr() const { return static_cast(SubExprs[SubExpr::Common]); @@ -4740,7 +4745,9 @@ return static_cast(SubExprs[SubExpr::Resume]); } - SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; } + SourceLocation getBeginLoc() const LLVM_READONLY { + return CoroutineSuspendExprBits.KeywordLoc; + } SourceLocation getEndLoc() const LLVM_READONLY { return getCommonExpr()->getEndLoc(); diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -389,6 +389,8 @@ unsigned Semantics : 3; // Provides semantics for APFloat construction unsigned IsExact : 1; + + SourceLocation Loc; }; class StringLiteralBitfields { @@ -419,6 +421,8 @@ unsigned : NumExprBits; unsigned Kind : 3; + + unsigned Value; }; class UnaryOperatorBitfields { @@ -444,6 +448,8 @@ unsigned Kind : 3; unsigned IsType : 1; // true if operand is a type, false if an expression. + + SourceLocation OpLoc; }; class ArrayOrMatrixSubscriptExprBitfields { @@ -553,6 +559,8 @@ /// Whether this initializer list originally had a GNU array-range /// designator in it. This is a temporary marker used by CodeGen. unsigned HadArrayRangeDesignator : 1; + + SourceLocation LBraceLoc; }; class ParenListExprBitfields { @@ -596,6 +604,8 @@ /// The kind of source location builtin represented by the SourceLocExpr. /// Ex. __builtin_LINE, __builtin_FUNCTION, ect. unsigned Kind : 2; + + SourceLocation BuiltinLoc; }; class StmtExprBitfields { @@ -919,6 +929,8 @@ unsigned : NumExprBits; unsigned Value : 1; + + SourceLocation KeywordLoc; }; class SubstNonTypeTemplateParmExprBitfields { @@ -966,14 +978,31 @@ //===--- C++ Coroutines TS bitfields classes ---===// + class CoroutineSuspendExprBitfields { + friend class CoroutineSuspendExpr; + friend class ASTStmtReader; + + unsigned : NumExprBits; + + unsigned : 32 - NumExprBits; + + SourceLocation KeywordLoc; + }; + + enum { NumCoroutineSuspendExprBits = NumExprBits }; + class CoawaitExprBitfields { friend class CoawaitExpr; - unsigned : NumExprBits; + unsigned : NumCoroutineSuspendExprBits; unsigned IsImplicit : 1; }; + static_assert(sizeof(CoawaitExprBitfields) <= 4, + "CoawaitExprBitfields must be <= than 4 bytes to" + "avoid trashing CoroutineSuspendExprBitfields::KeywordLoc!"); + //===--- Obj-C Expression bitfields classes ---===// class ObjCIndirectCopyRestoreExprBitfields { @@ -1069,6 +1098,7 @@ RequiresExprBitfields RequiresExprBits; // C++ Coroutines TS expressions + CoroutineSuspendExprBitfields CoroutineSuspendExprBits; CoawaitExprBitfields CoawaitBits; // Obj-C Expressions diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1013,9 +1013,10 @@ FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) - : Expr(FloatingLiteralClass, Type, VK_PRValue, OK_Ordinary), Loc(L) { + : Expr(FloatingLiteralClass, Type, VK_PRValue, OK_Ordinary) { setSemantics(V.getSemantics()); FloatingLiteralBits.IsExact = isexact; + FloatingLiteralBits.Loc = L; setValue(C, V); setDependence(ExprDependence::None); } @@ -1631,9 +1632,10 @@ UnaryExprOrTypeTrait ExprKind, Expr *E, QualType resultType, SourceLocation op, SourceLocation rp) : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_PRValue, OK_Ordinary), - OpLoc(op), RParenLoc(rp) { + RParenLoc(rp) { assert(ExprKind <= UETT_Last && "invalid enum value!"); UnaryExprOrTypeTraitExprBits.Kind = ExprKind; + UnaryExprOrTypeTraitExprBits.OpLoc = op; assert(static_cast(ExprKind) == UnaryExprOrTypeTraitExprBits.Kind && "UnaryExprOrTypeTraitExprBits.Kind overflow!"); UnaryExprOrTypeTraitExprBits.IsType = false; @@ -2195,8 +2197,9 @@ DeclContext *ParentContext) : Expr(SourceLocExprClass, getDecayedSourceLocExprType(Ctx, Kind), VK_PRValue, OK_Ordinary), - BuiltinLoc(BLoc), RParenLoc(RParenLoc), ParentContext(ParentContext) { + RParenLoc(RParenLoc), ParentContext(ParentContext) { SourceLocExprBits.Kind = Kind; + SourceLocExprBits.BuiltinLoc = BLoc; setDependence(ExprDependence::None); } @@ -2266,8 +2269,9 @@ InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef initExprs, SourceLocation rbraceloc) : Expr(InitListExprClass, QualType(), VK_PRValue, OK_Ordinary), - InitExprs(C, initExprs.size()), LBraceLoc(lbraceloc), - RBraceLoc(rbraceloc), AltForm(nullptr, true) { + InitExprs(C, initExprs.size()), RBraceLoc(rbraceloc), + AltForm(nullptr, true) { + InitListExprBits.LBraceLoc = lbraceloc; sawArrayRangeDesignator(false); InitExprs.insert(C, InitExprs.end(), initExprs.begin(), initExprs.end()); @@ -2356,7 +2360,7 @@ SourceLocation InitListExpr::getBeginLoc() const { if (InitListExpr *SyntacticForm = getSyntacticForm()) return SyntacticForm->getBeginLoc(); - SourceLocation Beg = LBraceLoc; + SourceLocation Beg = InitListExprBits.LBraceLoc; if (Beg.isInvalid()) { // Find the first non-null initializer. for (InitExprsTy::const_iterator I = InitExprs.begin(), diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -468,21 +468,21 @@ S->IsImplicit = Record.readInt() != 0; } -void ASTStmtReader::VisitCoawaitExpr(CoawaitExpr *E) { +void ASTStmtReader::VisitCoroutineSuspendExpr(CoroutineSuspendExpr *E) { VisitExpr(E); - E->KeywordLoc = readSourceLocation(); - for (auto &SubExpr: E->SubExprs) + E->CoroutineSuspendExprBits.KeywordLoc = readSourceLocation(); + for (auto &SubExpr : E->SubExprs) SubExpr = Record.readSubStmt(); E->OpaqueValue = cast_or_null(Record.readSubStmt()); +} + +void ASTStmtReader::VisitCoawaitExpr(CoawaitExpr *E) { + VisitCoroutineSuspendExpr(E); E->setIsImplicit(Record.readInt() != 0); } void ASTStmtReader::VisitCoyieldExpr(CoyieldExpr *E) { - VisitExpr(E); - E->KeywordLoc = readSourceLocation(); - for (auto &SubExpr: E->SubExprs) - SubExpr = Record.readSubStmt(); - E->OpaqueValue = cast_or_null(Record.readSubStmt()); + VisitCoroutineSuspendExpr(E); } void ASTStmtReader::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) { @@ -1298,7 +1298,7 @@ void ASTStmtReader::VisitSourceLocExpr(SourceLocExpr *E) { VisitExpr(E); E->ParentContext = readDeclAs(); - E->BuiltinLoc = readSourceLocation(); + E->SourceLocExprBits.BuiltinLoc = readSourceLocation(); E->RParenLoc = readSourceLocation(); E->SourceLocExprBits.Kind = static_cast(Record.readInt()); @@ -2100,7 +2100,9 @@ void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { VisitExpr(E); E->CXXNoexceptExprBits.Value = Record.readInt(); - E->Range = readSourceRange(); + SourceRange R = readSourceRange(); + E->CXXNoexceptExprBits.KeywordLoc = R.getBegin(); + E->RParenLoc = R.getEnd(); E->Operand = Record.readSubExpr(); }