diff options
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/AST/Stmt.h')
-rw-r--r-- | contrib/llvm-project/clang/include/clang/AST/Stmt.h | 409 |
1 files changed, 350 insertions, 59 deletions
diff --git a/contrib/llvm-project/clang/include/clang/AST/Stmt.h b/contrib/llvm-project/clang/include/clang/AST/Stmt.h index c2e69a91e55d..55eca4007d17 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm-project/clang/include/clang/AST/Stmt.h @@ -13,13 +13,21 @@ #ifndef LLVM_CLANG_AST_STMT_H #define LLVM_CLANG_AST_STMT_H +#include "clang/AST/APValue.h" #include "clang/AST/DeclGroup.h" #include "clang/AST/DependenceFlags.h" +#include "clang/AST/OperationKinds.h" #include "clang/AST/StmtIterator.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/Lambda.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Basic/TypeTraits.h" +#include "llvm/ADT/APFloat.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/PointerIntPair.h" @@ -33,6 +41,7 @@ #include <cassert> #include <cstddef> #include <iterator> +#include <optional> #include <string> namespace llvm { @@ -58,6 +67,13 @@ class SourceManager; class StringLiteral; class Token; class VarDecl; +enum class CharacterLiteralKind; +enum class ConstantResultStorageKind; +enum class CXXConstructionKind; +enum class CXXNewInitializationStyle; +enum class PredefinedIdentKind; +enum class SourceLocIdentKind; +enum class StringLiteralKind; //===----------------------------------------------------------------------===// // AST classes for statements. @@ -99,6 +115,7 @@ protected: friend class Stmt; /// The statement class. + LLVM_PREFERRED_TYPE(StmtClass) unsigned sClass : 8; }; enum { NumStmtBits = 8 }; @@ -108,6 +125,7 @@ protected: friend class ASTStmtWriter; friend class NullStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// True if the null statement was preceded by an empty macro, e.g: @@ -115,6 +133,7 @@ protected: /// #define CALL(x) /// CALL(0); /// @endcode + LLVM_PREFERRED_TYPE(bool) unsigned HasLeadingEmptyMacro : 1; /// The location of the semi-colon. @@ -125,17 +144,21 @@ protected: friend class ASTStmtReader; friend class CompoundStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; - unsigned NumStmts : 32 - NumStmtBits; + /// True if the compound statement has one or more pragmas that set some + /// floating-point features. + LLVM_PREFERRED_TYPE(bool) + unsigned HasFPFeatures : 1; - /// The location of the opening "{". - SourceLocation LBraceLoc; + unsigned NumStmts; }; class LabelStmtBitfields { friend class LabelStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; SourceLocation IdentLoc; @@ -145,6 +168,7 @@ protected: friend class ASTStmtReader; friend class AttributedStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// Number of attributes. @@ -158,18 +182,23 @@ protected: friend class ASTStmtReader; friend class IfStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; - /// True if this if statement is a constexpr if. - unsigned IsConstexpr : 1; + /// Whether this is a constexpr if, or a consteval if, or neither. + LLVM_PREFERRED_TYPE(IfStatementKind) + unsigned Kind : 3; /// True if this if statement has storage for an else statement. + LLVM_PREFERRED_TYPE(bool) unsigned HasElse : 1; /// True if this if statement has storage for a variable declaration. + LLVM_PREFERRED_TYPE(bool) unsigned HasVar : 1; /// True if this if statement has storage for an init statement. + LLVM_PREFERRED_TYPE(bool) unsigned HasInit : 1; /// The location of the "if". @@ -179,17 +208,21 @@ protected: class SwitchStmtBitfields { friend class SwitchStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// True if the SwitchStmt has storage for an init statement. + LLVM_PREFERRED_TYPE(bool) unsigned HasInit : 1; /// True if the SwitchStmt has storage for a condition variable. + LLVM_PREFERRED_TYPE(bool) unsigned HasVar : 1; /// If the SwitchStmt is a switch on an enum value, records whether all /// the enum values were covered by CaseStmts. The coverage information /// value is meant to be a hint for possible clients. + LLVM_PREFERRED_TYPE(bool) unsigned AllEnumCasesCovered : 1; /// The location of the "switch". @@ -200,9 +233,11 @@ protected: friend class ASTStmtReader; friend class WhileStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// True if the WhileStmt has storage for a condition variable. + LLVM_PREFERRED_TYPE(bool) unsigned HasVar : 1; /// The location of the "while". @@ -212,6 +247,7 @@ protected: class DoStmtBitfields { friend class DoStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// The location of the "do". @@ -221,6 +257,7 @@ protected: class ForStmtBitfields { friend class ForStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// The location of the "for". @@ -231,6 +268,7 @@ protected: friend class GotoStmt; friend class IndirectGotoStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// The location of the "goto". @@ -240,6 +278,7 @@ protected: class ContinueStmtBitfields { friend class ContinueStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// The location of the "continue". @@ -249,6 +288,7 @@ protected: class BreakStmtBitfields { friend class BreakStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// The location of the "break". @@ -258,9 +298,11 @@ protected: class ReturnStmtBitfields { friend class ReturnStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// True if this ReturnStmt has storage for an NRVO candidate. + LLVM_PREFERRED_TYPE(bool) unsigned HasNRVOCandidate : 1; /// The location of the "return". @@ -271,10 +313,12 @@ protected: friend class SwitchCase; friend class CaseStmt; + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; /// Used by CaseStmt to store whether it is a case statement /// of the form case LHS ... RHS (a GNU extension). + LLVM_PREFERRED_TYPE(bool) unsigned CaseStmtIsGNURange : 1; /// The location of the "case" or "default" keyword. @@ -307,11 +351,15 @@ protected: friend class PseudoObjectExpr; // ctor friend class ShuffleVectorExpr; // ctor + LLVM_PREFERRED_TYPE(StmtBitfields) unsigned : NumStmtBits; + LLVM_PREFERRED_TYPE(ExprValueKind) unsigned ValueKind : 2; + LLVM_PREFERRED_TYPE(ExprObjectKind) unsigned ObjectKind : 3; - unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>; + LLVM_PREFERRED_TYPE(ExprDependence) + unsigned Dependent : llvm::BitWidth<ExprDependence>; }; enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> }; @@ -320,28 +368,35 @@ protected: friend class ASTStmtWriter; friend class ConstantExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The kind of result that is tail-allocated. + LLVM_PREFERRED_TYPE(ConstantResultStorageKind) unsigned ResultKind : 2; - /// The kind of Result as defined by APValue::Kind. + /// The kind of Result as defined by APValue::ValueKind. + LLVM_PREFERRED_TYPE(APValue::ValueKind) unsigned APValueKind : 4; - /// When ResultKind == RSK_Int64, true if the tail-allocated integer is - /// unsigned. + /// When ResultKind == ConstantResultStorageKind::Int64, true if the + /// tail-allocated integer is unsigned. + LLVM_PREFERRED_TYPE(bool) unsigned IsUnsigned : 1; - /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated - /// integer. 7 bits because it is the minimal number of bits to represent a - /// value from 0 to 64 (the size of the tail-allocated integer). + /// When ResultKind == ConstantResultStorageKind::Int64. the BitWidth of the + /// tail-allocated integer. 7 bits because it is the minimal number of bits + /// to represent a value from 0 to 64 (the size of the tail-allocated + /// integer). unsigned BitWidth : 7; - /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the - /// tail-allocated APValue. + /// When ResultKind == ConstantResultStorageKind::APValue, true if the + /// ASTContext will cleanup the tail-allocated APValue. + LLVM_PREFERRED_TYPE(bool) unsigned HasCleanup : 1; /// True if this ConstantExpr was created for immediate invocation. + LLVM_PREFERRED_TYPE(bool) unsigned IsImmediateInvocation : 1; }; @@ -349,16 +404,22 @@ protected: friend class ASTStmtReader; friend class PredefinedExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; - /// The kind of this PredefinedExpr. One of the enumeration values - /// in PredefinedExpr::IdentKind. + LLVM_PREFERRED_TYPE(PredefinedIdentKind) unsigned Kind : 4; /// True if this PredefinedExpr has a trailing "StringLiteral *" /// for the predefined identifier. + LLVM_PREFERRED_TYPE(bool) unsigned HasFunctionName : 1; + /// True if this PredefinedExpr should be treated as a StringLiteral (for + /// MSVC compatibility). + LLVM_PREFERRED_TYPE(bool) + unsigned IsTransparent : 1; + /// The location of this PredefinedExpr. SourceLocation Loc; }; @@ -367,14 +428,25 @@ protected: friend class ASTStmtReader; // deserialization friend class DeclRefExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(bool) unsigned HasQualifier : 1; + LLVM_PREFERRED_TYPE(bool) unsigned HasTemplateKWAndArgsInfo : 1; + LLVM_PREFERRED_TYPE(bool) unsigned HasFoundDecl : 1; + LLVM_PREFERRED_TYPE(bool) unsigned HadMultipleCandidates : 1; + LLVM_PREFERRED_TYPE(bool) unsigned RefersToEnclosingVariableOrCapture : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1; + LLVM_PREFERRED_TYPE(NonOdrUseReason) unsigned NonOdrUseReason : 2; + LLVM_PREFERRED_TYPE(bool) + unsigned IsImmediateEscalating : 1; /// The location of the declaration name itself. SourceLocation Loc; @@ -384,9 +456,15 @@ protected: class FloatingLiteralBitfields { friend class FloatingLiteral; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; - unsigned Semantics : 3; // Provides semantics for APFloat construction + static_assert( + llvm::APFloat::S_MaxSemantics < 16, + "Too many Semantics enum values to fit in bitfield of size 4"); + LLVM_PREFERRED_TYPE(llvm::APFloat::Semantics) + unsigned Semantics : 4; // Provides semantics for APFloat construction + LLVM_PREFERRED_TYPE(bool) unsigned IsExact : 1; }; @@ -394,10 +472,12 @@ protected: friend class ASTStmtReader; friend class StringLiteral; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The kind of this string literal. /// One of the enumeration values of StringLiteral::StringKind. + LLVM_PREFERRED_TYPE(StringLiteralKind) unsigned Kind : 3; /// The width of a single character in bytes. Only values of 1, 2, @@ -405,6 +485,7 @@ protected: /// the target + string kind to the appropriate CharByteWidth. unsigned CharByteWidth : 3; + LLVM_PREFERRED_TYPE(bool) unsigned IsPascal : 1; /// The number of concatenated token this string is made of. @@ -415,22 +496,28 @@ protected: class CharacterLiteralBitfields { friend class CharacterLiteral; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(CharacterLiteralKind) unsigned Kind : 3; }; class UnaryOperatorBitfields { friend class UnaryOperator; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(UnaryOperatorKind) unsigned Opc : 5; + LLVM_PREFERRED_TYPE(bool) unsigned CanOverflow : 1; // /// This is only meaningful for operations on floating point /// types when additional values need to be in trailing storage. /// It is 0 otherwise. + LLVM_PREFERRED_TYPE(bool) unsigned HasFPFeatures : 1; SourceLocation Loc; @@ -439,9 +526,12 @@ protected: class UnaryExprOrTypeTraitExprBitfields { friend class UnaryExprOrTypeTraitExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(UnaryExprOrTypeTrait) unsigned Kind : 3; + LLVM_PREFERRED_TYPE(bool) unsigned IsType : 1; // true if operand is a type, false if an expression. }; @@ -449,6 +539,7 @@ protected: friend class ArraySubscriptExpr; friend class MatrixSubscriptExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; SourceLocation RBracketLoc; @@ -457,14 +548,17 @@ protected: class CallExprBitfields { friend class CallExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; unsigned NumPreArgs : 1; /// True if the callee of the call expression was found using ADL. + LLVM_PREFERRED_TYPE(bool) unsigned UsesADL : 1; /// True if the call expression has some floating-point features. + LLVM_PREFERRED_TYPE(bool) unsigned HasFPFeatures : 1; /// Padding used to align OffsetToTrailingObjects to a byte multiple. @@ -481,15 +575,18 @@ protected: friend class ASTStmtReader; friend class MemberExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// IsArrow - True if this is "X->F", false if this is "X.F". + LLVM_PREFERRED_TYPE(bool) 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. + LLVM_PREFERRED_TYPE(bool) unsigned HasQualifierOrFoundDecl : 1; /// True if this member expression specified a template keyword @@ -497,15 +594,18 @@ protected: /// x->template f, x->template f<int>. /// When true, an ASTTemplateKWAndArgsInfo structure and its /// TemplateArguments (if any) are present. + LLVM_PREFERRED_TYPE(bool) unsigned HasTemplateKWAndArgsInfo : 1; /// True if this member expression refers to a method that /// was resolved from an overloaded set having size greater than 1. + LLVM_PREFERRED_TYPE(bool) unsigned HadMultipleCandidates : 1; /// Value of type NonOdrUseReason indicating why this MemberExpr does /// not constitute an odr-use of the named declaration. Meaningful only /// when naming a static member. + LLVM_PREFERRED_TYPE(NonOdrUseReason) unsigned NonOdrUseReason : 2; /// This is the location of the -> or . in the expression. @@ -516,12 +616,16 @@ protected: friend class CastExpr; friend class ImplicitCastExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; - unsigned Kind : 6; + LLVM_PREFERRED_TYPE(CastKind) + unsigned Kind : 7; + LLVM_PREFERRED_TYPE(bool) unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr. /// True if the call expression has some floating-point features. + LLVM_PREFERRED_TYPE(bool) unsigned HasFPFeatures : 1; /// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough @@ -532,13 +636,16 @@ protected: class BinaryOperatorBitfields { friend class BinaryOperator; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(BinaryOperatorKind) unsigned Opc : 6; /// This is only meaningful for operations on floating point /// types when additional values need to be in trailing storage. /// It is 0 otherwise. + LLVM_PREFERRED_TYPE(bool) unsigned HasFPFeatures : 1; SourceLocation OpLoc; @@ -547,10 +654,12 @@ protected: class InitListExprBitfields { friend class InitListExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Whether this initializer list originally had a GNU array-range /// designator in it. This is a temporary marker used by CodeGen. + LLVM_PREFERRED_TYPE(bool) unsigned HadArrayRangeDesignator : 1; }; @@ -558,6 +667,7 @@ protected: friend class ASTStmtReader; friend class ParenListExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The number of expressions in the paren list. @@ -568,6 +678,7 @@ protected: friend class ASTStmtReader; friend class GenericSelectionExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The location of the "_Generic". @@ -578,29 +689,31 @@ protected: friend class ASTStmtReader; // deserialization friend class PseudoObjectExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; - // These don't need to be particularly wide, because they're - // strictly limited by the forms of expressions we permit. - unsigned NumSubExprs : 8; - unsigned ResultIndex : 32 - 8 - NumExprBits; + unsigned NumSubExprs : 16; + unsigned ResultIndex : 16; }; class SourceLocExprBitfields { friend class ASTStmtReader; friend class SourceLocExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The kind of source location builtin represented by the SourceLocExpr. - /// Ex. __builtin_LINE, __builtin_FUNCTION, ect. - unsigned Kind : 2; + /// Ex. __builtin_LINE, __builtin_FUNCTION, etc. + LLVM_PREFERRED_TYPE(SourceLocIdentKind) + unsigned Kind : 3; }; class StmtExprBitfields { friend class ASTStmtReader; friend class StmtExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The number of levels of template parameters enclosing this statement @@ -615,10 +728,12 @@ protected: friend class ASTStmtReader; friend class CXXOperatorCallExpr; + LLVM_PREFERRED_TYPE(CallExprBitfields) unsigned : NumCallExprBits; /// The kind of this overloaded operator. One of the enumerator /// value of OverloadedOperatorKind. + LLVM_PREFERRED_TYPE(OverloadedOperatorKind) unsigned OperatorKind : 6; }; @@ -626,17 +741,21 @@ protected: friend class ASTStmtReader; friend class CXXRewrittenBinaryOperator; + LLVM_PREFERRED_TYPE(CallExprBitfields) unsigned : NumCallExprBits; + LLVM_PREFERRED_TYPE(bool) unsigned IsReversed : 1; }; class CXXBoolLiteralExprBitfields { friend class CXXBoolLiteralExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The value of the boolean literal. + LLVM_PREFERRED_TYPE(bool) unsigned Value : 1; /// The location of the boolean literal. @@ -646,6 +765,7 @@ protected: class CXXNullPtrLiteralExprBitfields { friend class CXXNullPtrLiteralExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The location of the null pointer literal. @@ -655,9 +775,11 @@ protected: class CXXThisExprBitfields { friend class CXXThisExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Whether this is an implicit "this". + LLVM_PREFERRED_TYPE(bool) unsigned IsImplicit : 1; /// The location of the "this". @@ -668,9 +790,11 @@ protected: friend class ASTStmtReader; friend class CXXThrowExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Whether the thrown variable (if any) is in scope. + LLVM_PREFERRED_TYPE(bool) unsigned IsThrownVariableInScope : 1; /// The location of the "throw". @@ -681,8 +805,13 @@ protected: friend class ASTStmtReader; friend class CXXDefaultArgExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + /// Whether this CXXDefaultArgExpr rewrote its argument and stores a copy. + LLVM_PREFERRED_TYPE(bool) + unsigned HasRewrittenInit : 1; + /// The location where the default argument expression was used. SourceLocation Loc; }; @@ -691,8 +820,14 @@ protected: friend class ASTStmtReader; friend class CXXDefaultInitExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + /// Whether this CXXDefaultInitExprBitfields rewrote its argument and stores + /// a copy. + LLVM_PREFERRED_TYPE(bool) + unsigned HasRewrittenInit : 1; + /// The location where the default initializer expression was used. SourceLocation Loc; }; @@ -701,6 +836,7 @@ protected: friend class ASTStmtReader; friend class CXXScalarValueInitExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; SourceLocation RParenLoc; @@ -711,28 +847,37 @@ protected: friend class ASTStmtWriter; friend class CXXNewExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Was the usage ::new, i.e. is the global new to be used? + LLVM_PREFERRED_TYPE(bool) unsigned IsGlobalNew : 1; /// Do we allocate an array? If so, the first trailing "Stmt *" is the /// size expression. + LLVM_PREFERRED_TYPE(bool) unsigned IsArray : 1; /// Should the alignment be passed to the allocation function? + LLVM_PREFERRED_TYPE(bool) unsigned ShouldPassAlignment : 1; /// If this is an array allocation, does the usual deallocation /// function for the allocated type want to know the allocated size? + LLVM_PREFERRED_TYPE(bool) unsigned UsualArrayDeleteWantsSize : 1; - /// What kind of initializer do we have? Could be none, parens, or braces. - /// In storage, we distinguish between "none, and no initializer expr", and - /// "none, but an implicit initializer expr". + // Is initializer expr present? + LLVM_PREFERRED_TYPE(bool) + unsigned HasInitializer : 1; + + /// What kind of initializer syntax used? Could be none, parens, or braces. + LLVM_PREFERRED_TYPE(CXXNewInitializationStyle) unsigned StoredInitializationStyle : 2; /// True if the allocated type was expressed as a parenthesized type-id. + LLVM_PREFERRED_TYPE(bool) unsigned IsParenTypeId : 1; /// The number of placement new arguments. @@ -743,21 +888,26 @@ protected: friend class ASTStmtReader; friend class CXXDeleteExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Is this a forced global delete, i.e. "::delete"? + LLVM_PREFERRED_TYPE(bool) unsigned GlobalDelete : 1; /// Is this the array form of delete, i.e. "delete[]"? + LLVM_PREFERRED_TYPE(bool) unsigned ArrayForm : 1; /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is /// applied to pointer-to-array type (ArrayFormAsWritten will be false /// while ArrayForm will be true). + LLVM_PREFERRED_TYPE(bool) unsigned ArrayFormAsWritten : 1; /// Does the usual deallocation function for the element type require /// a size_t argument? + LLVM_PREFERRED_TYPE(bool) unsigned UsualArrayDeleteWantsSize : 1; /// Location of the expression. @@ -769,13 +919,16 @@ protected: friend class ASTStmtWriter; friend class TypeTraitExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The kind of type trait, which is a value of a TypeTrait enumerator. + LLVM_PREFERRED_TYPE(TypeTrait) unsigned Kind : 8; /// If this expression is not value-dependent, this indicates whether /// the trait evaluated true or false. + LLVM_PREFERRED_TYPE(bool) unsigned Value : 1; /// The number of arguments to this type trait. According to [implimits] @@ -789,10 +942,12 @@ protected: friend class ASTStmtWriter; friend class DependentScopeDeclRefExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Whether the name includes info for explicit template /// keyword and arguments. + LLVM_PREFERRED_TYPE(bool) unsigned HasTemplateKWAndArgsInfo : 1; }; @@ -800,14 +955,23 @@ protected: friend class ASTStmtReader; friend class CXXConstructExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(bool) unsigned Elidable : 1; + LLVM_PREFERRED_TYPE(bool) unsigned HadMultipleCandidates : 1; + LLVM_PREFERRED_TYPE(bool) unsigned ListInitialization : 1; + LLVM_PREFERRED_TYPE(bool) unsigned StdInitListInitialization : 1; + LLVM_PREFERRED_TYPE(bool) unsigned ZeroInitialization : 1; + LLVM_PREFERRED_TYPE(CXXConstructionKind) unsigned ConstructionKind : 3; + LLVM_PREFERRED_TYPE(bool) + unsigned IsImmediateEscalating : 1; SourceLocation Loc; }; @@ -816,9 +980,11 @@ protected: friend class ASTStmtReader; // deserialization friend class ExprWithCleanups; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; // When false, it must not have side effects. + LLVM_PREFERRED_TYPE(bool) unsigned CleanupsHaveSideEffects : 1; unsigned NumObjects : 32 - 1 - NumExprBits; @@ -828,6 +994,7 @@ protected: friend class ASTStmtReader; friend class CXXUnresolvedConstructExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The number of arguments used to construct the type. @@ -838,18 +1005,22 @@ protected: friend class ASTStmtReader; friend class CXXDependentScopeMemberExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Whether this member expression used the '->' operator or /// the '.' operator. + LLVM_PREFERRED_TYPE(bool) unsigned IsArrow : 1; /// Whether this member expression has info for explicit template /// keyword and arguments. + LLVM_PREFERRED_TYPE(bool) unsigned HasTemplateKWAndArgsInfo : 1; /// See getFirstQualifierFoundInScope() and the comment listing /// the trailing objects. + LLVM_PREFERRED_TYPE(bool) unsigned HasFirstQualifierFoundInScope : 1; /// The location of the '->' or '.' operator. @@ -860,10 +1031,12 @@ protected: friend class ASTStmtReader; friend class OverloadExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// Whether the name includes info for explicit template /// keyword and arguments. + LLVM_PREFERRED_TYPE(bool) unsigned HasTemplateKWAndArgsInfo : 1; /// Padding used by the derived classes to store various bits. If you @@ -880,14 +1053,17 @@ protected: friend class ASTStmtReader; friend class UnresolvedLookupExpr; + LLVM_PREFERRED_TYPE(OverloadExprBitfields) unsigned : NumOverloadExprBits; /// True if these lookup results should be extended by /// argument-dependent lookup if this is the operand of a function call. + LLVM_PREFERRED_TYPE(bool) unsigned RequiresADL : 1; /// True if these lookup results are overloaded. This is pretty trivially /// rederivable if we urgently need to kill this field. + LLVM_PREFERRED_TYPE(bool) unsigned Overloaded : 1; }; static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4, @@ -898,13 +1074,16 @@ protected: friend class ASTStmtReader; friend class UnresolvedMemberExpr; + LLVM_PREFERRED_TYPE(OverloadExprBitfields) unsigned : NumOverloadExprBits; /// Whether this member expression used the '->' operator or /// the '.' operator. + LLVM_PREFERRED_TYPE(bool) unsigned IsArrow : 1; /// Whether the lookup results contain an unresolved using declaration. + LLVM_PREFERRED_TYPE(bool) unsigned HasUnresolvedUsing : 1; }; static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4, @@ -915,8 +1094,10 @@ protected: friend class ASTStmtReader; friend class CXXNoexceptExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(bool) unsigned Value : 1; }; @@ -924,6 +1105,7 @@ protected: friend class ASTStmtReader; friend class SubstNonTypeTemplateParmExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The location of the non-type template parameter reference. @@ -935,17 +1117,21 @@ protected: friend class ASTStmtWriter; friend class LambdaExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The default capture kind, which is a value of type /// LambdaCaptureDefault. + LLVM_PREFERRED_TYPE(LambdaCaptureDefault) unsigned CaptureDefault : 2; /// Whether this lambda had an explicit parameter list vs. an /// implicit (and empty) parameter list. + LLVM_PREFERRED_TYPE(bool) unsigned ExplicitParams : 1; /// Whether this lambda had the result type explicitly specified. + LLVM_PREFERRED_TYPE(bool) unsigned ExplicitResultType : 1; /// The number of captures. @@ -957,19 +1143,23 @@ protected: friend class ASTStmtWriter; friend class RequiresExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(bool) unsigned IsSatisfied : 1; SourceLocation RequiresKWLoc; }; - //===--- C++ Coroutines TS bitfields classes ---===// + //===--- C++ Coroutines bitfields classes ---===// class CoawaitExprBitfields { friend class CoawaitExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(bool) unsigned IsImplicit : 1; }; @@ -978,8 +1168,10 @@ protected: class ObjCIndirectCopyRestoreExprBitfields { friend class ObjCIndirectCopyRestoreExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; + LLVM_PREFERRED_TYPE(bool) unsigned ShouldCopy : 1; }; @@ -989,10 +1181,12 @@ protected: friend class ASTStmtReader; friend class OpaqueValueExpr; + LLVM_PREFERRED_TYPE(ExprBitfields) unsigned : NumExprBits; /// The OVE is a unique semantic reference to its source expression if this /// bit is set to true. + LLVM_PREFERRED_TYPE(bool) unsigned IsUnique : 1; SourceLocation Loc; @@ -1067,7 +1261,7 @@ protected: LambdaExprBitfields LambdaExprBits; RequiresExprBitfields RequiresExprBits; - // C++ Coroutines TS expressions + // C++ Coroutines expressions CoawaitExprBitfields CoawaitBits; // Obj-C Expressions @@ -1215,6 +1409,11 @@ public: const PrintingPolicy &Policy, unsigned Indentation = 0, StringRef NewlineSymbol = "\n", const ASTContext *Context = nullptr) const; + void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper, + const PrintingPolicy &Policy, + unsigned Indentation = 0, + StringRef NewlineSymbol = "\n", + const ASTContext *Context = nullptr) const; /// Pretty-prints in JSON format. void printJson(raw_ostream &Out, PrinterHelper *Helper, @@ -1238,7 +1437,7 @@ public: } /// Child Iterators: All subclasses must implement 'children' - /// to permit easy iteration over the substatements/subexpessions of an + /// to permit easy iteration over the substatements/subexpressions of an /// AST node. This permits easy iteration over all nodes in the AST. using child_iterator = StmtIterator; using const_child_iterator = ConstStmtIterator; @@ -1271,8 +1470,13 @@ public: /// parameters are identified by index/level rather than their /// declaration pointers) or the exact representation of the statement as /// written in the source. + /// \param ProfileLambdaExpr whether or not to profile lambda expressions. + /// When false, the lambda expressions are never considered to be equal to + /// other lambda expressions. When true, the lambda expressions with the same + /// implementation will be considered to be the same. ProfileLambdaExpr should + /// only be true when we try to merge two declarations within modules. void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, - bool Canonical) const; + bool Canonical, bool ProfileLambdaExpr = false) const; /// Calculate a unique representation for a statement that is /// stable across compiler invocations. @@ -1395,36 +1599,63 @@ public: }; /// CompoundStmt - This represents a group of statements like { stmt stmt }. -class CompoundStmt final : public Stmt, - private llvm::TrailingObjects<CompoundStmt, Stmt *> { +class CompoundStmt final + : public Stmt, + private llvm::TrailingObjects<CompoundStmt, Stmt *, FPOptionsOverride> { friend class ASTStmtReader; friend TrailingObjects; - /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits. + /// The location of the opening "{". + SourceLocation LBraceLoc; + + /// The location of the closing "}". SourceLocation RBraceLoc; - CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB, SourceLocation RB); + CompoundStmt(ArrayRef<Stmt *> Stmts, FPOptionsOverride FPFeatures, + SourceLocation LB, SourceLocation RB); explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {} void setStmts(ArrayRef<Stmt *> Stmts); + /// Set FPOptionsOverride in trailing storage. Used only by Serialization. + void setStoredFPFeatures(FPOptionsOverride F) { + assert(hasStoredFPFeatures()); + *getTrailingObjects<FPOptionsOverride>() = F; + } + + size_t numTrailingObjects(OverloadToken<Stmt *>) const { + return CompoundStmtBits.NumStmts; + } + public: static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts, - SourceLocation LB, SourceLocation RB); + FPOptionsOverride FPFeatures, SourceLocation LB, + SourceLocation RB); // Build an empty compound statement with a location. - explicit CompoundStmt(SourceLocation Loc) - : Stmt(CompoundStmtClass), RBraceLoc(Loc) { + explicit CompoundStmt(SourceLocation Loc) : CompoundStmt(Loc, Loc) {} + + CompoundStmt(SourceLocation Loc, SourceLocation EndLoc) + : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(EndLoc) { CompoundStmtBits.NumStmts = 0; - CompoundStmtBits.LBraceLoc = Loc; + CompoundStmtBits.HasFPFeatures = 0; } // Build an empty compound statement. - static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts); + static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts, + bool HasFPFeatures); bool body_empty() const { return CompoundStmtBits.NumStmts == 0; } unsigned size() const { return CompoundStmtBits.NumStmts; } + bool hasStoredFPFeatures() const { return CompoundStmtBits.HasFPFeatures; } + + /// Get FPOptionsOverride from trailing storage. + FPOptionsOverride getStoredFPFeatures() const { + assert(hasStoredFPFeatures()); + return *getTrailingObjects<FPOptionsOverride>(); + } + using body_iterator = Stmt **; using body_range = llvm::iterator_range<body_iterator>; @@ -1499,10 +1730,10 @@ public: return const_cast<CompoundStmt *>(this)->getStmtExprResult(); } - SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; } + SourceLocation getBeginLoc() const { return LBraceLoc; } SourceLocation getEndLoc() const { return RBraceLoc; } - SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; } + SourceLocation getLBracLoc() const { return LBraceLoc; } SourceLocation getRBracLoc() const { return RBraceLoc; } static bool classof(const Stmt *T) { @@ -1798,6 +2029,7 @@ public: class LabelStmt : public ValueStmt { LabelDecl *TheDecl; Stmt *SubStmt; + bool SideEntry = false; public: /// Build a label statement. @@ -1833,6 +2065,8 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == LabelStmtClass; } + bool isSideEntry() const { return SideEntry; } + void setSideEntry(bool SE) { SideEntry = SE; } }; /// Represents an attribute applied to a statement. @@ -1876,7 +2110,7 @@ public: SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; } ArrayRef<const Attr *> getAttrs() const { - return llvm::makeArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs); + return llvm::ArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs); } Stmt *getSubStmt() { return SubStmt; } @@ -1947,8 +2181,8 @@ class IfStmt final unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; } /// Build an if/then/else statement. - IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init, - VarDecl *Var, Expr *Cond, SourceLocation LParenLoc, + IfStmt(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind, + Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc, SourceLocation RParenLoc, Stmt *Then, SourceLocation EL, Stmt *Else); /// Build an empty if/then/else statement. @@ -1957,9 +2191,9 @@ class IfStmt final public: /// Create an IfStmt. static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL, - bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond, - SourceLocation LPL, SourceLocation RPL, Stmt *Then, - SourceLocation EL = SourceLocation(), + IfStatementKind Kind, Stmt *Init, VarDecl *Var, + Expr *Cond, SourceLocation LPL, SourceLocation RPL, + Stmt *Then, SourceLocation EL = SourceLocation(), Stmt *Else = nullptr); /// Create an empty IfStmt optionally with storage for an else statement, @@ -2044,6 +2278,11 @@ public: : nullptr; } + void setConditionVariableDeclStmt(DeclStmt *CondVar) { + assert(hasVarStorage()); + getTrailingObjects<Stmt *>()[varOffset()] = CondVar; + } + Stmt *getInit() { return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()] : nullptr; @@ -2074,12 +2313,35 @@ public: *getTrailingObjects<SourceLocation>() = ElseLoc; } - bool isConstexpr() const { return IfStmtBits.IsConstexpr; } - void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; } + bool isConsteval() const { + return getStatementKind() == IfStatementKind::ConstevalNonNegated || + getStatementKind() == IfStatementKind::ConstevalNegated; + } + + bool isNonNegatedConsteval() const { + return getStatementKind() == IfStatementKind::ConstevalNonNegated; + } + + bool isNegatedConsteval() const { + return getStatementKind() == IfStatementKind::ConstevalNegated; + } + + bool isConstexpr() const { + return getStatementKind() == IfStatementKind::Constexpr; + } + + void setStatementKind(IfStatementKind Kind) { + IfStmtBits.Kind = static_cast<unsigned>(Kind); + } + + IfStatementKind getStatementKind() const { + return static_cast<IfStatementKind>(IfStmtBits.Kind); + } /// If this is an 'if constexpr', determine which substatement will be taken. - /// Otherwise, or if the condition is value-dependent, returns None. - Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const; + /// Otherwise, or if the condition is value-dependent, returns std::nullopt. + std::optional<const Stmt *> getNondiscardedCase(const ASTContext &Ctx) const; + std::optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx); bool isObjCAvailabilityCheck() const; @@ -2097,13 +2359,19 @@ public: // Iterators over subexpressions. The iterators will include iterating // over the initialization expression referenced by the condition variable. child_range children() { - return child_range(getTrailingObjects<Stmt *>(), + // We always store a condition, but there is none for consteval if + // statements, so skip it. + return child_range(getTrailingObjects<Stmt *>() + + (isConsteval() ? thenOffset() : 0), getTrailingObjects<Stmt *>() + numTrailingObjects(OverloadToken<Stmt *>())); } const_child_range children() const { - return const_child_range(getTrailingObjects<Stmt *>(), + // We always store a condition, but there is none for consteval if + // statements, so skip it. + return const_child_range(getTrailingObjects<Stmt *>() + + (isConsteval() ? thenOffset() : 0), getTrailingObjects<Stmt *>() + numTrailingObjects(OverloadToken<Stmt *>())); } @@ -2119,7 +2387,7 @@ class SwitchStmt final : public Stmt, friend TrailingObjects; /// Points to a linked list of case and default statements. - SwitchCase *FirstCase; + SwitchCase *FirstCase = nullptr; // SwitchStmt is followed by several trailing objects, // some of which optional. Note that it would be more convenient to @@ -2247,6 +2515,11 @@ public: : nullptr; } + void setConditionVariableDeclStmt(DeclStmt *CondVar) { + assert(hasVarStorage()); + getTrailingObjects<Stmt *>()[varOffset()] = CondVar; + } + SwitchCase *getSwitchCaseList() { return FirstCase; } const SwitchCase *getSwitchCaseList() const { return FirstCase; } void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } @@ -2410,6 +2683,11 @@ public: : nullptr; } + void setConditionVariableDeclStmt(DeclStmt *CondVar) { + assert(hasVarStorage()); + getTrailingObjects<Stmt *>()[varOffset()] = CondVar; + } + SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; } void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; } @@ -2499,6 +2777,8 @@ public: /// the init/cond/inc parts of the ForStmt will be null if they were not /// specified in the source. class ForStmt : public Stmt { + friend class ASTStmtReader; + enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. SourceLocation LParenLoc, RParenLoc; @@ -2526,10 +2806,18 @@ public: /// If this ForStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. + DeclStmt *getConditionVariableDeclStmt() { + return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]); + } + const DeclStmt *getConditionVariableDeclStmt() const { return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]); } + void setConditionVariableDeclStmt(DeclStmt *CondVar) { + SubExprs[CONDVAR] = CondVar; + } + Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } Stmt *getBody() { return SubExprs[BODY]; } @@ -3258,16 +3546,16 @@ public: //===--- Other ---===// ArrayRef<StringRef> getAllConstraints() const { - return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs); + return llvm::ArrayRef(Constraints, NumInputs + NumOutputs); } ArrayRef<StringRef> getClobbers() const { - return llvm::makeArrayRef(Clobbers, NumClobbers); + return llvm::ArrayRef(Clobbers, NumClobbers); } ArrayRef<Expr*> getAllExprs() const { - return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs), - NumInputs + NumOutputs); + return llvm::ArrayRef(reinterpret_cast<Expr **>(Exprs), + NumInputs + NumOutputs); } StringRef getClobber(unsigned i) const { return getClobbers()[i]; } @@ -3481,8 +3769,11 @@ public: llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind; SourceLocation Loc; + Capture() = default; + public: friend class ASTStmtReader; + friend class CapturedStmt; /// Create a new capture. /// |