Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -3014,63 +3014,15 @@ }; /// Represents the declaration of a struct/union/class/enum. -class TagDecl - : public TypeDecl, public DeclContext, public Redeclarable { +class TagDecl : public TypeDecl, + public DeclContext, + public Redeclarable { + // This class stores some data in DeclContext::TagDeclBits + // to save some space. Use the provided accessors to access it. public: // This is really ugly. using TagKind = TagTypeKind; -private: - // FIXME: This can be packed into the bitfields in Decl. - /// The TagKind enum. - unsigned TagDeclKind : 3; - - /// True if this is a definition ("struct foo {};"), false if it is a - /// declaration ("struct foo;"). It is not considered a definition - /// until the definition has been fully processed. - unsigned IsCompleteDefinition : 1; - -protected: - /// True if this is currently being defined. - unsigned IsBeingDefined : 1; - -private: - /// True if this tag declaration is "embedded" (i.e., defined or declared - /// for the very first time) in the syntax of a declarator. - unsigned IsEmbeddedInDeclarator : 1; - - /// True if this tag is free standing, e.g. "struct foo;". - unsigned IsFreeStanding : 1; - -protected: - // These are used by (and only defined for) EnumDecl. - unsigned NumPositiveBits : 8; - unsigned NumNegativeBits : 8; - - /// True if this tag declaration is a scoped enumeration. Only - /// possible in C++11 mode. - unsigned IsScoped : 1; - - /// If this tag declaration is a scoped enum, - /// then this is true if the scoped enum was declared using the class - /// tag, false if it was declared with the struct tag. No meaning is - /// associated if this tag declaration is not a scoped enum. - unsigned IsScopedUsingClassTag : 1; - - /// True if this is an enumeration with fixed underlying type. Only - /// possible in C++11, Microsoft extensions, or Objective C mode. - unsigned IsFixed : 1; - - /// Indicates whether it is possible for declarations of this kind - /// to have an out-of-date definition. - /// - /// This option is only enabled when modules are enabled. - unsigned MayHaveOutOfDateDef : 1; - - /// Has the full definition of this type been required by a use somewhere in - /// the TU. - unsigned IsCompleteDefinitionRequired : 1; - private: SourceRange BraceRange; @@ -3097,16 +3049,7 @@ protected: TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, - SourceLocation StartL) - : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C), - TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false), - IsEmbeddedInDeclarator(false), IsFreeStanding(false), - IsCompleteDefinitionRequired(false), - TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) { - assert((DK != Enum || TK == TTK_Enum) && - "EnumDecl not matched with TTK_Enum"); - setPreviousDecl(PrevDecl); - } + SourceLocation StartL); using redeclarable_base = Redeclarable; @@ -3127,6 +3070,17 @@ /// This is a helper function for derived classes. void completeDefinition(); + /// True if this decl is currently being defined. + void setBeingDefined(bool V = true) { TagDeclBits.IsBeingDefined = V; } + + /// Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + void setMayHaveOutOfDateDef(bool V = true) { + TagDeclBits.MayHaveOutOfDateDef = V; + } + public: friend class ASTDeclReader; friend class ASTDeclWriter; @@ -3165,33 +3119,54 @@ } /// Return true if this decl has its body fully specified. - bool isCompleteDefinition() const { - return IsCompleteDefinition; + bool isCompleteDefinition() const { return TagDeclBits.IsCompleteDefinition; } + + /// True if this decl has its body fully specified. + void setCompleteDefinition(bool V = true) { + TagDeclBits.IsCompleteDefinition = V; } /// Return true if this complete decl is /// required to be complete for some existing use. bool isCompleteDefinitionRequired() const { - return IsCompleteDefinitionRequired; + return TagDeclBits.IsCompleteDefinitionRequired; } - /// Return true if this decl is currently being defined. - bool isBeingDefined() const { - return IsBeingDefined; + /// True if this complete decl is + /// required to be complete for some existing use. + void setCompleteDefinitionRequired(bool V = true) { + TagDeclBits.IsCompleteDefinitionRequired = V; } + /// Return true if this decl is currently being defined. + bool isBeingDefined() const { return TagDeclBits.IsBeingDefined; } + + /// True if this tag declaration is "embedded" (i.e., defined or declared + /// for the very first time) in the syntax of a declarator. bool isEmbeddedInDeclarator() const { - return IsEmbeddedInDeclarator; + return TagDeclBits.IsEmbeddedInDeclarator; } + + /// True if this tag declaration is "embedded" (i.e., defined or declared + /// for the very first time) in the syntax of a declarator. void setEmbeddedInDeclarator(bool isInDeclarator) { - IsEmbeddedInDeclarator = isInDeclarator; + TagDeclBits.IsEmbeddedInDeclarator = isInDeclarator; } - bool isFreeStanding() const { return IsFreeStanding; } + /// True if this tag is free standing, e.g. "struct foo;". + bool isFreeStanding() const { return TagDeclBits.IsFreeStanding; } + + /// True if this tag is free standing, e.g. "struct foo;". void setFreeStanding(bool isFreeStanding = true) { - IsFreeStanding = isFreeStanding; + TagDeclBits.IsFreeStanding = isFreeStanding; } + /// Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + bool mayHaveOutOfDateDef() const { return TagDeclBits.MayHaveOutOfDateDef; } + /// Whether this declaration declares a type that is /// dependent, i.e., a type that somehow depends on template /// parameters. @@ -3214,21 +3189,15 @@ /// the struct/union/class/enum. TagDecl *getDefinition() const; - void setCompleteDefinition(bool V) { IsCompleteDefinition = V; } - - void setCompleteDefinitionRequired(bool V = true) { - IsCompleteDefinitionRequired = V; - } - StringRef getKindName() const { return TypeWithKeyword::getTagTypeKindName(getTagKind()); } TagKind getTagKind() const { - return TagKind(TagDeclKind); + return static_cast(TagDeclBits.TagDeclKind); } - void setTagKind(TagKind TK) { TagDeclKind = TK; } + void setTagKind(TagKind TK) { TagDeclBits.TagDeclKind = TK; } bool isStruct() const { return getTagKind() == TTK_Struct; } bool isInterface() const { return getTagKind() == TTK_Interface; } @@ -3308,6 +3277,9 @@ /// with a fixed underlying type, and in C we allow them to be forward-declared /// with no underlying type as an extension. class EnumDecl : public TagDecl { + // This class stores some data in DeclContext::EnumDeclBits + // to save some space. Use the provided accessors to access it. + /// This represent the integer type that the enum corresponds /// to for code generation purposes. Note that the enumerator constants may /// have a different type than this does. @@ -3336,28 +3308,50 @@ MemberSpecializationInfo *SpecializationInfo = nullptr; /// Store the ODRHash after first calculation. - unsigned HasODRHash : 1; + /// The corresponding flag HasODRHash is in EnumDeclBits + /// and can be accessed with the provided accessors. unsigned ODRHash; EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, - bool Scoped, bool ScopedUsingClassTag, bool Fixed) - : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) { - assert(Scoped || !ScopedUsingClassTag); - IntegerType = (const Type *)nullptr; - NumNegativeBits = 0; - NumPositiveBits = 0; - IsScoped = Scoped; - IsScopedUsingClassTag = ScopedUsingClassTag; - IsFixed = Fixed; - HasODRHash = false; - ODRHash = 0; - } + bool Scoped, bool ScopedUsingClassTag, bool Fixed); void anchor() override; void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, TemplateSpecializationKind TSK); + + /// Sets the width in bits required to store all the + /// non-negative enumerators of this enum. + void setNumPositiveBits(unsigned Num) { + EnumDeclBits.NumPositiveBits = Num; + assert(EnumDeclBits.NumPositiveBits == Num && "can't store this bitcount"); + } + + /// Returns the width in bits required to store all the + /// negative enumerators of this enum. (see getNumNegativeBits) + void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; } + + /// True if this tag declaration is a scoped enumeration. Only + /// possible in C++11 mode. + void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; } + + /// If this tag declaration is a scoped enum, + /// then this is true if the scoped enum was declared using the class + /// tag, false if it was declared with the struct tag. No meaning is + /// associated if this tag declaration is not a scoped enum. + void setScopedUsingClassTag(bool ScopedUCT = true) { + EnumDeclBits.IsScopedUsingClassTag = ScopedUCT; + } + + /// True if this is an Objective-C, C++11, or + /// Microsoft-style enumeration with a fixed underlying type. + void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; } + + /// True if a valid hash is stored in ODRHash. + bool hasODRHash() const { return EnumDeclBits.HasODRHash; } + void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; } + public: friend class ASTDeclReader; @@ -3462,13 +3456,7 @@ /// Returns the width in bits required to store all the /// non-negative enumerators of this enum. - unsigned getNumPositiveBits() const { - return NumPositiveBits; - } - void setNumPositiveBits(unsigned Num) { - NumPositiveBits = Num; - assert(NumPositiveBits == Num && "can't store this bitcount"); - } + unsigned getNumPositiveBits() const { return EnumDeclBits.NumPositiveBits; } /// Returns the width in bits required to store all the /// negative enumerators of this enum. These widths include @@ -3479,28 +3467,19 @@ /// -1 1111111 1 /// -10 1110110 5 /// -101 1001011 8 - unsigned getNumNegativeBits() const { - return NumNegativeBits; - } - void setNumNegativeBits(unsigned Num) { - NumNegativeBits = Num; - } + unsigned getNumNegativeBits() const { return EnumDeclBits.NumNegativeBits; } /// Returns true if this is a C++11 scoped enumeration. - bool isScoped() const { - return IsScoped; - } + bool isScoped() const { return EnumDeclBits.IsScoped; } /// Returns true if this is a C++11 scoped enumeration. bool isScopedUsingClassTag() const { - return IsScopedUsingClassTag; + return EnumDeclBits.IsScopedUsingClassTag; } /// Returns true if this is an Objective-C, C++11, or /// Microsoft-style enumeration with a fixed underlying type. - bool isFixed() const { - return IsFixed; - } + bool isFixed() const { return EnumDeclBits.IsFixed; } unsigned getODRHash(); @@ -3565,7 +3544,10 @@ /// union Y { int A, B; }; // Has body with members A and B (FieldDecls). /// This decl will be marked invalid if *any* members are invalid. class RecordDecl : public TagDecl { + // This class stores some data in DeclContext::RecordDeclBits + // to save some space. Use the provided accessors to access it. public: + friend class DeclContext; /// Enum that represents the different ways arguments are passed to and /// returned from function calls. This takes into account the target-specific /// and version-specific rules along with the rules determined by the @@ -3589,46 +3571,6 @@ APK_CanNeverPassInRegs }; -private: - friend class DeclContext; - - // FIXME: This can be packed into the bitfields in Decl. - /// This is true if this struct ends with a flexible - /// array member (e.g. int X[]) or if this union contains a struct that does. - /// If so, this cannot be contained in arrays or other structs as a member. - unsigned HasFlexibleArrayMember : 1; - - /// Whether this is the type of an anonymous struct or union. - unsigned AnonymousStructOrUnion : 1; - - /// This is true if this struct has at least one member - /// containing an Objective-C object pointer type. - unsigned HasObjectMember : 1; - - /// This is true if struct has at least one member of - /// 'volatile' type. - unsigned HasVolatileMember : 1; - - /// Whether the field declarations of this record have been loaded - /// from external storage. To avoid unnecessary deserialization of - /// methods/nested types we allow deserialization of just the fields - /// when needed. - mutable unsigned LoadedFieldsFromExternalStorage : 1; - - /// Basic properties of non-trivial C structs. - unsigned NonTrivialToPrimitiveDefaultInitialize : 1; - unsigned NonTrivialToPrimitiveCopy : 1; - unsigned NonTrivialToPrimitiveDestroy : 1; - - /// Indicates whether this struct is destroyed in the callee. - /// - /// Please note that MSVC won't merge adjacent bitfields if they don't have - /// the same type. - unsigned ParamDestroyedInCallee : 1; - - /// Represents the way this type is passed to a function. - unsigned ArgPassingRestrictions : 2; - protected: RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -3655,8 +3597,13 @@ return const_cast(this)->getMostRecentDecl(); } - bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } - void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; } + bool hasFlexibleArrayMember() const { + return RecordDeclBits.HasFlexibleArrayMember; + } + + void setHasFlexibleArrayMember(bool V) { + RecordDeclBits.HasFlexibleArrayMember = V; + } /// Whether this is an anonymous struct or union. To be an anonymous /// struct or union, it must have been declared without a name and @@ -3669,47 +3616,54 @@ /// union X { int i; float f; }; /// union { int i; float f; } obj; /// @endcode - bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; } + bool isAnonymousStructOrUnion() const { + return RecordDeclBits.AnonymousStructOrUnion; + } + void setAnonymousStructOrUnion(bool Anon) { - AnonymousStructOrUnion = Anon; + RecordDeclBits.AnonymousStructOrUnion = Anon; } - bool hasObjectMember() const { return HasObjectMember; } - void setHasObjectMember (bool val) { HasObjectMember = val; } + bool hasObjectMember() const { return RecordDeclBits.HasObjectMember; } + void setHasObjectMember(bool val) { RecordDeclBits.HasObjectMember = val; } - bool hasVolatileMember() const { return HasVolatileMember; } - void setHasVolatileMember (bool val) { HasVolatileMember = val; } + bool hasVolatileMember() const { return RecordDeclBits.HasVolatileMember; } + + void setHasVolatileMember(bool val) { + RecordDeclBits.HasVolatileMember = val; + } bool hasLoadedFieldsFromExternalStorage() const { - return LoadedFieldsFromExternalStorage; + return RecordDeclBits.LoadedFieldsFromExternalStorage; } - void setHasLoadedFieldsFromExternalStorage(bool val) { - LoadedFieldsFromExternalStorage = val; + + void setHasLoadedFieldsFromExternalStorage(bool val) const { + RecordDeclBits.LoadedFieldsFromExternalStorage = val; } /// Functions to query basic properties of non-trivial C structs. bool isNonTrivialToPrimitiveDefaultInitialize() const { - return NonTrivialToPrimitiveDefaultInitialize; + return RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize; } void setNonTrivialToPrimitiveDefaultInitialize(bool V) { - NonTrivialToPrimitiveDefaultInitialize = V; + RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize = V; } bool isNonTrivialToPrimitiveCopy() const { - return NonTrivialToPrimitiveCopy; + return RecordDeclBits.NonTrivialToPrimitiveCopy; } void setNonTrivialToPrimitiveCopy(bool V) { - NonTrivialToPrimitiveCopy = V; + RecordDeclBits.NonTrivialToPrimitiveCopy = V; } bool isNonTrivialToPrimitiveDestroy() const { - return NonTrivialToPrimitiveDestroy; + return RecordDeclBits.NonTrivialToPrimitiveDestroy; } void setNonTrivialToPrimitiveDestroy(bool V) { - NonTrivialToPrimitiveDestroy = V; + RecordDeclBits.NonTrivialToPrimitiveDestroy = V; } /// Determine whether this class can be passed in registers. In C++ mode, @@ -3720,19 +3674,19 @@ } ArgPassingKind getArgPassingRestrictions() const { - return static_cast(ArgPassingRestrictions); + return static_cast(RecordDeclBits.ArgPassingRestrictions); } void setArgPassingRestrictions(ArgPassingKind Kind) { - ArgPassingRestrictions = static_cast(Kind); + RecordDeclBits.ArgPassingRestrictions = Kind; } bool isParamDestroyedInCallee() const { - return ParamDestroyedInCallee; + return RecordDeclBits.ParamDestroyedInCallee; } void setParamDestroyedInCallee(bool V) { - ParamDestroyedInCallee = V; + RecordDeclBits.ParamDestroyedInCallee = V; } /// Determines whether this declaration represents the Index: include/clang/AST/DeclBase.h =================================================================== --- include/clang/AST/DeclBase.h +++ include/clang/AST/DeclBase.h @@ -1260,37 +1260,407 @@ /// BlockDecl /// OMPDeclareReductionDecl class DeclContext { - /// DeclKind - This indicates which class this is. - unsigned DeclKind : 8; + // We use uint64_t in the bit-fields below since some bit-fields + // cross the unsigned boundary and this breaks the packing. + + /// Stores the bits used by DeclContext. + /// If modified NumDeclContextBit, the ctor of DeclContext and the accessor + /// methods in DeclContext should be updated appropriately. + class DeclContextBitfields { + friend class DeclContext; + /// DeclKind - This indicates which class this is. + uint64_t DeclKind : 7; + + /// Whether this declaration context also has some external + /// storage that contains additional declarations that are lexically + /// part of this context. + mutable uint64_t ExternalLexicalStorage : 1; + + /// Whether this declaration context also has some external + /// storage that contains additional declarations that are visible + /// in this context. + mutable uint64_t ExternalVisibleStorage : 1; + + /// Whether this declaration context has had externally visible + /// storage added since the last lookup. In this case, \c LookupPtr's + /// invariant may not hold and needs to be fixed before we perform + /// another lookup. + mutable uint64_t NeedToReconcileExternalVisibleStorage : 1; + + /// If \c true, this context may have local lexical declarations + /// that are missing from the lookup table. + mutable uint64_t HasLazyLocalLexicalLookups : 1; + + /// If \c true, the external source may have lexical declarations + /// that are missing from the lookup table. + mutable uint64_t HasLazyExternalLexicalLookups : 1; + + /// If \c true, lookups should only return identifier from + /// DeclContext scope (for example TranslationUnit). Used in + /// LookupQualifiedName() + mutable uint64_t UseQualifiedLookup : 1; + }; - /// Whether this declaration context also has some external - /// storage that contains additional declarations that are lexically - /// part of this context. - mutable bool ExternalLexicalStorage : 1; + /// Number of bits in DeclContextBitfields. + enum { NumDeclContextBits = 13 }; - /// Whether this declaration context also has some external - /// storage that contains additional declarations that are visible - /// in this context. - mutable bool ExternalVisibleStorage : 1; + /// Stores the bits used by TagDecl. + /// If modified NumTagDeclBits and the accessor + /// methods in TagDecl should be updated appropriately. + class TagDeclBitfields { + friend class TagDecl; + /// For the bits in DeclContextBitfields + uint64_t : NumDeclContextBits; - /// Whether this declaration context has had external visible - /// storage added since the last lookup. In this case, \c LookupPtr's - /// invariant may not hold and needs to be fixed before we perform - /// another lookup. - mutable bool NeedToReconcileExternalVisibleStorage : 1; + /// The TagKind enum. + uint64_t TagDeclKind : 3; - /// If \c true, this context may have local lexical declarations - /// that are missing from the lookup table. - mutable bool HasLazyLocalLexicalLookups : 1; + /// True if this is a definition ("struct foo {};"), false if it is a + /// declaration ("struct foo;"). It is not considered a definition + /// until the definition has been fully processed. + uint64_t IsCompleteDefinition : 1; - /// If \c true, the external source may have lexical declarations - /// that are missing from the lookup table. - mutable bool HasLazyExternalLexicalLookups : 1; + /// True if this is currently being defined. + uint64_t IsBeingDefined : 1; + + /// True if this tag declaration is "embedded" (i.e., defined or declared + /// for the very first time) in the syntax of a declarator. + uint64_t IsEmbeddedInDeclarator : 1; + + /// True if this tag is free standing, e.g. "struct foo;". + uint64_t IsFreeStanding : 1; + + /// Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + uint64_t MayHaveOutOfDateDef : 1; + + /// Has the full definition of this type been required by a use somewhere in + /// the TU. + uint64_t IsCompleteDefinitionRequired : 1; + }; + + /// Number of non-inherited bits in TagDeclBitfields. + enum { NumTagDeclBits = 9 }; + + /// Stores the bits used by EnumDecl. + /// If modified NumEnumDeclBit and the accessor + /// methods in EnumDecl should be updated appropriately. + class EnumDeclBitfields { + friend class EnumDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + /// For the bits in TagDeclBitfields. + uint64_t : NumTagDeclBits; + + /// Width in bits required to store all the non-negative + /// enumerators of this enum. + uint64_t NumPositiveBits : 8; + + /// Width in bits required to store all the negative + /// enumerators of this enum. + uint64_t NumNegativeBits : 8; + + /// True if this tag declaration is a scoped enumeration. Only + /// possible in C++11 mode. + uint64_t IsScoped : 1; + + /// If this tag declaration is a scoped enum, + /// then this is true if the scoped enum was declared using the class + /// tag, false if it was declared with the struct tag. No meaning is + /// associated if this tag declaration is not a scoped enum. + uint64_t IsScopedUsingClassTag : 1; + + /// True if this is an enumeration with fixed underlying type. Only + /// possible in C++11, Microsoft extensions, or Objective C mode. + uint64_t IsFixed : 1; + + /// True if a valid hash is stored in ODRHash. + uint64_t HasODRHash : 1; + }; + + /// Number of non-inherited bits in EnumDeclBitfields. + enum { NumEnumDeclBits = 20 }; + + /// Stores the bits used by RecordDecl. + /// If modified NumRecordDeclBits and the accessor + /// methods in RecordDecl should be updated appropriately. + class RecordDeclBitfields { + friend class RecordDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + /// For the bits in TagDeclBitfields. + uint64_t : NumTagDeclBits; + + /// This is true if this struct ends with a flexible + /// array member (e.g. int X[]) or if this union contains a struct that does. + /// If so, this cannot be contained in arrays or other structs as a member. + uint64_t HasFlexibleArrayMember : 1; + + /// Whether this is the type of an anonymous struct or union. + uint64_t AnonymousStructOrUnion : 1; + + /// This is true if this struct has at least one member + /// containing an Objective-C object pointer type. + uint64_t HasObjectMember : 1; + + /// This is true if struct has at least one member of + /// 'volatile' type. + uint64_t HasVolatileMember : 1; + + /// Whether the field declarations of this record have been loaded + /// from external storage. To avoid unnecessary deserialization of + /// methods/nested types we allow deserialization of just the fields + /// when needed. + mutable uint64_t LoadedFieldsFromExternalStorage : 1; + + /// Basic properties of non-trivial C structs. + uint64_t NonTrivialToPrimitiveDefaultInitialize : 1; + uint64_t NonTrivialToPrimitiveCopy : 1; + uint64_t NonTrivialToPrimitiveDestroy : 1; + + /// Indicates whether this struct is destroyed in the callee. + uint64_t ParamDestroyedInCallee : 1; + + /// Represents the way this type is passed to a function. + uint64_t ArgPassingRestrictions : 2; + }; + + /// Number of non-inherited bits in RecordDeclBitfields. + enum { NumRecordDeclBits = 11 }; + + /// Stores the bits used by OMPDeclareReductionDecl. + /// If modified NumOMPDeclareReductionDeclBits and the accessor + /// methods in OMPDeclareReductionDecl should be updated appropriately. + class OMPDeclareReductionDeclBitfields { + friend class OMPDeclareReductionDecl; + /// For the bits in DeclContextBitfields + uint64_t : NumDeclContextBits; + + /// Kind of initializer, + /// function call or omp_priv initializtion. + uint64_t InitializerKind : 2; + }; + + /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields. + enum { NumOMPDeclareReductionDeclBits = 2 }; + + /// Stores the bits used by FunctionDecl. + /// If modified NumFunctionDeclBits and the accessor + /// methods in FunctionDecl and CXXDeductionGuideDecl + /// (for IsCopyDeductionCandidate) should be updated appropriately. + class FunctionDeclBitfields { + friend class FunctionDecl; + /// For IsCopyDeductionCandidate + friend class CXXDeductionGuideDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + uint64_t SClass : 3; + uint64_t IsInline : 1; + uint64_t IsInlineSpecified : 1; + + /// This is shared by CXXConstructorDecl, + /// CXXConversionDecl, and CXXDeductionGuideDecl. + uint64_t IsExplicitSpecified : 1; + + uint64_t IsVirtualAsWritten : 1; + uint64_t IsPure : 1; + uint64_t HasInheritedPrototype : 1; + uint64_t HasWrittenPrototype : 1; + uint64_t IsDeleted : 1; + /// Used by CXXMethodDecl + uint64_t IsTrivial : 1; + + /// This flag indicates whether this function is trivial for the purpose of + /// calls. This is meaningful only when this function is a copy/move + /// constructor or a destructor. + uint64_t IsTrivialForCall : 1; + + /// Used by CXXMethodDecl + uint64_t IsDefaulted : 1; + /// Used by CXXMethodDecl + uint64_t IsExplicitlyDefaulted : 1; + uint64_t HasImplicitReturnZero : 1; + uint64_t IsLateTemplateParsed : 1; + uint64_t IsConstexpr : 1; + uint64_t InstantiationIsPending : 1; + + /// Indicates if the function uses __try. + uint64_t UsesSEHTry : 1; + + /// Indicates if the function was a definition + /// but its body was skipped. + uint64_t HasSkippedBody : 1; + + /// Indicates if the function declaration will + /// have a body, once we're done parsing it. + uint64_t WillHaveBody : 1; + + /// Indicates that this function is a multiversioned + /// function using attribute 'target'. + uint64_t IsMultiVersion : 1; + + /// [C++17] Only used by CXXDeductionGuideDecl. Indicates that + /// the Deduction Guide is the implicitly generated 'copy + /// deduction candidate' (is used during overload resolution). + uint64_t IsCopyDeductionCandidate : 1; + + /// Store the ODRHash after first calculation. + uint64_t HasODRHash : 1; + }; + + /// Number of non-inherited bits in FunctionDeclBitfields. + enum { NumFunctionDeclBits = 25 }; + + /// Stores the bits used by CXXConstructorDecl. If modified + /// NumCXXConstructorDeclBits and the accessor + /// methods in CXXConstructorDecl should be updated appropriately. + class CXXConstructorDeclBitfields { + friend class CXXConstructorDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + /// For the bits in FunctionDeclBitfields. + uint64_t : NumFunctionDeclBits; + + /// 25 bits to fit in the remaining availible space. + /// Note that this makes CXXConstructorDeclBitfields take + /// exactly 64 bits and thus the width of NumCtorInitializers + /// will need to be shrunk if some bit is added to NumDeclContextBitfields, + /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. + uint64_t NumCtorInitializers : 25; + uint64_t IsInheritingConstructor : 1; + }; + + /// Number of non-inherited bits in CXXConstructorDeclBitfields. + enum { NumCXXConstructorDeclBits = 26 }; + + /// Stores the bits used by ObjCMethodDecl. + /// If modified NumObjCMethodDeclBits and the accessor + /// methods in ObjCMethodDecl should be updated appropriately. + class ObjCMethodDeclBitfields { + friend class ObjCMethodDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + /// This is needed for the bitwidth of Family below but + /// is defined in Basic/IdentifierTable.h which we do not include. + /// To avoid mismatches between the two definitions we have + /// a static_assert in the ctor of ObjCMethodDecl which checks + /// that these two ObjCMethodFamilyBitWidth are equal. + enum { ObjCMethodFamilyBitWidth = 4 }; + + /// The conventional meaning of this method; an ObjCMethodFamily. + /// This is not serialized; instead, it is computed on demand and + /// cached. + mutable uint64_t Family : ObjCMethodFamilyBitWidth; + + /// instance (true) or class (false) method. + uint64_t IsInstance : 1; + uint64_t IsVariadic : 1; + + /// True if this method is the getter or setter for an explicit property. + uint64_t IsPropertyAccessor : 1; + + /// Method has a definition. + uint64_t IsDefined : 1; + + /// Method redeclaration in the same interface. + uint64_t IsRedeclaration : 1; + + /// Is redeclared in the same interface. + mutable uint64_t HasRedeclaration : 1; + + /// \@required/\@optional + uint64_t DeclImplementation : 2; + + /// in, inout, etc. + uint64_t objcDeclQualifier : 7; + + /// Indicates whether this method has a related result type. + uint64_t RelatedResultType : 1; + + /// Whether the locations of the selector identifiers are in a + /// "standard" position, a enum SelectorLocationsKind. + uint64_t SelLocsKind : 2; + + /// Whether this method overrides any other in the class hierarchy. + /// + /// A method is said to override any method in the class's + /// base classes, its protocols, or its categories' protocols, that has + /// the same selector and is of the same kind (class or instance). + /// A method in an implementation is not considered as overriding the same + /// method in the interface or its categories. + uint64_t IsOverriding : 1; + + /// Indicates if the method was a definition but its body was skipped. + uint64_t HasSkippedBody : 1; + }; + + /// Number of non-inherited bits in ObjCMethodDeclBitfields. + enum { NumObjCMethodDeclBits = 24 }; + + /// Stores the bits used by ObjCContainerDecl. + /// If modified NumObjCContainerDeclBits and the accessor + /// methods in ObjCContainerDecl should be updated appropriately. + class ObjCContainerDeclBitfields { + friend class ObjCContainerDecl; + /// For the bits in DeclContextBitfields + uint32_t : NumDeclContextBits; + + // Not a bitfield but this saves space. + // Note that ObjCContainerDeclBitfields is full. + SourceLocation AtStart; + }; + + /// Number of non-inherited bits in ObjCContainerDeclBitfields. + /// Note that here we rely on the fact that SourceLocation is 32 bits + /// wide. We check this with the static_assert in the ctor of DeclContext. + enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits }; + + /// Stores the bits used by LinkageSpecDecl. + /// If modified NumLinkageSpecDeclBits and the accessor + /// methods in LinkageSpecDecl should be updated appropriately. + class LinkageSpecDeclBitfields { + friend class LinkageSpecDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + /// The language for this linkage specification with values + /// in the enum LinkageSpecDecl::LanguageIDs. + uint64_t Language : 3; + + /// True if this linkage spec has braces. + /// This is needed so that hasBraces() returns the correct result while the + /// linkage spec body is being parsed. Once RBraceLoc has been set this is + /// not used, so it doesn't need to be serialized. + uint64_t HasBraces : 1; + }; + + /// Number of non-inherited bits in LinkageSpecDeclBitfields. + enum { NumLinkageSpecDeclBits = 4 }; + + /// Stores the bits used by BlockDecl. + /// If modified NumBlockDeclBits and the accessor + /// methods in BlockDecl should be updated appropriately. + class BlockDeclBitfields { + friend class BlockDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + uint64_t IsVariadic : 1; + uint64_t CapturesCXXThis : 1; + uint64_t BlockMissingReturnType : 1; + uint64_t IsConversionFromLambda : 1; + + /// A bit that indicates this block is passed directly to a function as a + /// non-escaping parameter. + uint64_t DoesNotEscape : 1; + }; - /// If \c true, lookups should only return identifier from - /// DeclContext scope (for example TranslationUnit). Used in - /// LookupQualifiedName() - mutable bool UseQualifiedLookup : 1; + /// Number of non-inherited bits in BlockDeclBitfields. + enum { NumBlockDeclBits = 5 }; /// Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a @@ -1301,6 +1671,51 @@ mutable StoredDeclsMap *LookupPtr = nullptr; protected: + /// This anonymous union stores the bits belonging to DeclContext and classes + /// deriving from it. The goal is to use otherwise wasted + /// space in DeclContext to store data belonging to derived classes. + /// The space saved is especially significient when pointers are aligned + /// to 8 bytes. In this case due to alignment requirements we have a + /// little less than 8 bytes free in DeclContext which we can use. + /// We check that none of the classes in this union is larger than + /// 8 bytes with static_asserts in the ctor of DeclContext. + union { + DeclContextBitfields DeclContextBits; + TagDeclBitfields TagDeclBits; + EnumDeclBitfields EnumDeclBits; + RecordDeclBitfields RecordDeclBits; + OMPDeclareReductionDeclBitfields OMPDeclareReductionDeclBits; + FunctionDeclBitfields FunctionDeclBits; + CXXConstructorDeclBitfields CXXConstructorDeclBits; + ObjCMethodDeclBitfields ObjCMethodDeclBits; + ObjCContainerDeclBitfields ObjCContainerDeclBits; + LinkageSpecDeclBitfields LinkageSpecDeclBits; + BlockDeclBitfields BlockDeclBits; + + static_assert(sizeof(DeclContextBitfields) <= 8, + "DeclContextBitfields is larger than 8 bytes!"); + static_assert(sizeof(TagDeclBitfields) <= 8, + "TagDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(EnumDeclBitfields) <= 8, + "EnumDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(RecordDeclBitfields) <= 8, + "RecordDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(OMPDeclareReductionDeclBitfields) <= 8, + "OMPDeclareReductionDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(FunctionDeclBitfields) <= 8, + "FunctionDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(CXXConstructorDeclBitfields) <= 8, + "CXXConstructorDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(ObjCMethodDeclBitfields) <= 8, + "ObjCMethodDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(ObjCContainerDeclBitfields) <= 8, + "ObjCContainerDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(LinkageSpecDeclBitfields) <= 8, + "LinkageSpecDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(BlockDeclBitfields) <= 8, + "BlockDeclBitfields is larger than 8 bytes!"); + }; + friend class ASTDeclReader; friend class ASTWriter; friend class ExternalASTSource; @@ -1321,18 +1736,13 @@ static std::pair BuildDeclChain(ArrayRef Decls, bool FieldsAlreadyLoaded); - DeclContext(Decl::Kind K) - : DeclKind(K), ExternalLexicalStorage(false), - ExternalVisibleStorage(false), - NeedToReconcileExternalVisibleStorage(false), - HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), - UseQualifiedLookup(false) {} + DeclContext(Decl::Kind K); public: ~DeclContext(); Decl::Kind getDeclKind() const { - return static_cast(DeclKind); + return static_cast(DeclContextBits.DeclKind); } const char *getDeclKindName() const; @@ -1371,54 +1781,54 @@ return cast(this)->getASTContext(); } - bool isClosure() const { - return DeclKind == Decl::Block; - } + bool isClosure() const { return getDeclKind() == Decl::Block; } bool isObjCContainer() const { - switch (DeclKind) { - case Decl::ObjCCategory: - case Decl::ObjCCategoryImpl: - case Decl::ObjCImplementation: - case Decl::ObjCInterface: - case Decl::ObjCProtocol: - return true; + switch (getDeclKind()) { + case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCProtocol: + return true; + default: + return false; } - return false; } bool isFunctionOrMethod() const { - switch (DeclKind) { + switch (getDeclKind()) { case Decl::Block: case Decl::Captured: case Decl::ObjCMethod: return true; default: - return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction; + return getDeclKind() >= Decl::firstFunction && + getDeclKind() <= Decl::lastFunction; } } /// Test whether the context supports looking up names. bool isLookupContext() const { - return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec && - DeclKind != Decl::Export; + return !isFunctionOrMethod() && getDeclKind() != Decl::LinkageSpec && + getDeclKind() != Decl::Export; } bool isFileContext() const { - return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace; + return getDeclKind() == Decl::TranslationUnit || + getDeclKind() == Decl::Namespace; } bool isTranslationUnit() const { - return DeclKind == Decl::TranslationUnit; + return getDeclKind() == Decl::TranslationUnit; } bool isRecord() const { - return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord; + return getDeclKind() >= Decl::firstRecord && + getDeclKind() <= Decl::lastRecord; } - bool isNamespace() const { - return DeclKind == Decl::Namespace; - } + bool isNamespace() const { return getDeclKind() == Decl::Namespace; } bool isStdNamespace() const; @@ -1886,7 +2296,7 @@ void setMustBuildLookupTable() { assert(this == getPrimaryContext() && "should only be called on primary context"); - HasLazyExternalLexicalLookups = true; + DeclContextBits.HasLazyExternalLexicalLookups = true; } /// Retrieve the internal representation of the lookup structure. @@ -1898,24 +2308,28 @@ /// Whether this DeclContext has external storage containing /// additional declarations that are lexically in this context. - bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; } + bool hasExternalLexicalStorage() const { + return DeclContextBits.ExternalLexicalStorage; + } /// State whether this DeclContext has external storage for /// declarations lexically in this context. - void setHasExternalLexicalStorage(bool ES = true) { - ExternalLexicalStorage = ES; + void setHasExternalLexicalStorage(bool ES = true) const { + DeclContextBits.ExternalLexicalStorage = ES; } /// Whether this DeclContext has external storage containing /// additional declarations that are visible in this context. - bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; } + bool hasExternalVisibleStorage() const { + return DeclContextBits.ExternalVisibleStorage; + } /// State whether this DeclContext has external storage for /// declarations visible in this context. - void setHasExternalVisibleStorage(bool ES = true) { - ExternalVisibleStorage = ES; + void setHasExternalVisibleStorage(bool ES = true) const { + DeclContextBits.ExternalVisibleStorage = ES; if (ES && LookupPtr) - NeedToReconcileExternalVisibleStorage = true; + DeclContextBits.NeedToReconcileExternalVisibleStorage = true; } /// Determine whether the given declaration is stored in the list of @@ -1925,14 +2339,14 @@ D == LastDecl); } - bool setUseQualifiedLookup(bool use = true) { - bool old_value = UseQualifiedLookup; - UseQualifiedLookup = use; + bool setUseQualifiedLookup(bool use = true) const { + bool old_value = DeclContextBits.UseQualifiedLookup; + DeclContextBits.UseQualifiedLookup = use; return old_value; } bool shouldUseQualifiedLookup() const { - return UseQualifiedLookup; + return DeclContextBits.UseQualifiedLookup; } static bool classof(const Decl *D); @@ -1944,6 +2358,46 @@ bool Deserialize = false) const; private: + /// Whether this declaration context has had externally visible + /// storage added since the last lookup. In this case, \c LookupPtr's + /// invariant may not hold and needs to be fixed before we perform + /// another lookup. + bool hasNeedToReconcileExternalVisibleStorage() const { + return DeclContextBits.NeedToReconcileExternalVisibleStorage; + } + + /// State that this declaration context has had externally visible + /// storage added since the last lookup. In this case, \c LookupPtr's + /// invariant may not hold and needs to be fixed before we perform + /// another lookup. + void setNeedToReconcileExternalVisibleStorage(bool Need = true) const { + DeclContextBits.NeedToReconcileExternalVisibleStorage = Need; + } + + /// If \c true, this context may have local lexical declarations + /// that are missing from the lookup table. + bool hasLazyLocalLexicalLookups() const { + return DeclContextBits.HasLazyLocalLexicalLookups; + } + + /// If \c true, this context may have local lexical declarations + /// that are missing from the lookup table. + void setHasLazyLocalLexicalLookups(bool HasLLLL = true) const { + DeclContextBits.HasLazyLocalLexicalLookups = HasLLLL; + } + + /// If \c true, the external source may have lexical declarations + /// that are missing from the lookup table. + bool hasLazyExternalLexicalLookups() const { + return DeclContextBits.HasLazyExternalLexicalLookups; + } + + /// If \c true, the external source may have lexical declarations + /// that are missing from the lookup table. + void setHasLazyExternalLexicalLookups(bool HasLELL = true) const { + DeclContextBits.HasLazyExternalLexicalLookups = HasLELL; + } + friend class DependentDiagnostic; void reconcileExternalVisibleStorage() const; Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -3770,6 +3770,22 @@ // TagDecl Implementation //===----------------------------------------------------------------------===// +TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, + SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C), + TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) { + assert((DK != Enum || TK == TTK_Enum) && + "EnumDecl not matched with TTK_Enum"); + setPreviousDecl(PrevDecl); + setTagKind(TK); + setCompleteDefinition(false); + setBeingDefined(false); + setEmbeddedInDeclarator(false); + setFreeStanding(false); + setCompleteDefinitionRequired(false); +} + SourceLocation TagDecl::getOuterLocStart() const { return getTemplateOrInnerLocStart(this); } @@ -3792,7 +3808,7 @@ } void TagDecl::startDefinition() { - IsBeingDefined = true; + setBeingDefined(true); if (auto *D = dyn_cast(this)) { struct CXXRecordDecl::DefinitionData *Data = @@ -3807,8 +3823,8 @@ cast(this)->hasDefinition()) && "definition completed but not started"); - IsCompleteDefinition = true; - IsBeingDefined = false; + setCompleteDefinition(true); + setBeingDefined(false); if (ASTMutationListener *L = getASTMutationListener()) L->CompletedTagDefinition(this); @@ -3819,7 +3835,7 @@ return const_cast(this); // If it's possible for us to have an out-of-date definition, check now. - if (MayHaveOutOfDateDef) { + if (mayHaveOutOfDateDef()) { if (IdentifierInfo *II = getIdentifier()) { if (II->isOutOfDate()) { updateOutOfDate(*II); @@ -3872,6 +3888,21 @@ // EnumDecl Implementation //===----------------------------------------------------------------------===// +EnumDecl::EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, + bool Scoped, bool ScopedUsingClassTag, bool Fixed) + : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) { + assert(Scoped || !ScopedUsingClassTag); + IntegerType = nullptr; + setNumPositiveBits(0); + setNumNegativeBits(0); + setScoped(Scoped); + setScopedUsingClassTag(ScopedUsingClassTag); + setFixed(Fixed); + setHasODRHash(false); + ODRHash = 0; +} + void EnumDecl::anchor() {} EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, @@ -3881,7 +3912,7 @@ bool IsScopedUsingClassTag, bool IsFixed) { auto *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl, IsScoped, IsScopedUsingClassTag, IsFixed); - Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules; + Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules); C.getTypeDeclType(Enum, PrevDecl); return Enum; } @@ -3890,7 +3921,7 @@ EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); - Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules; + Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules); return Enum; } @@ -3974,12 +4005,12 @@ } unsigned EnumDecl::getODRHash() { - if (HasODRHash) + if (hasODRHash()) return ODRHash; class ODRHash Hash; Hash.AddEnumDecl(this); - HasODRHash = true; + setHasODRHash(true); ODRHash = Hash.CalculateHash(); return ODRHash; } @@ -3992,14 +4023,18 @@ DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl) - : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc), - HasFlexibleArrayMember(false), AnonymousStructOrUnion(false), - HasObjectMember(false), HasVolatileMember(false), - LoadedFieldsFromExternalStorage(false), - NonTrivialToPrimitiveDefaultInitialize(false), - NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false), - ParamDestroyedInCallee(false), ArgPassingRestrictions(APK_CanPassInRegs) { - assert(classof(static_cast(this)) && "Invalid Kind!"); + : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) { + assert(classof(static_cast(this)) && "Invalid Kind!"); + setHasFlexibleArrayMember(false); + setAnonymousStructOrUnion(false); + setHasObjectMember(false); + setHasVolatileMember(false); + setHasLoadedFieldsFromExternalStorage(false); + setNonTrivialToPrimitiveDefaultInitialize(false); + setNonTrivialToPrimitiveCopy(false); + setNonTrivialToPrimitiveDestroy(false); + setParamDestroyedInCallee(false); + setArgPassingRestrictions(APK_CanPassInRegs); } RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, @@ -4007,7 +4042,7 @@ IdentifierInfo *Id, RecordDecl* PrevDecl) { RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl); - R->MayHaveOutOfDateDef = C.getLangOpts().Modules; + R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); C.getTypeDeclType(R, PrevDecl); return R; @@ -4017,7 +4052,7 @@ RecordDecl *R = new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); - R->MayHaveOutOfDateDef = C.getLangOpts().Modules; + R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); return R; } @@ -4041,7 +4076,7 @@ } RecordDecl::field_iterator RecordDecl::field_begin() const { - if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage) + if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage()) LoadFieldsFromExternalStorage(); return field_iterator(decl_iterator(FirstDecl)); @@ -4069,7 +4104,7 @@ ExternalASTSource::Deserializing TheFields(Source); SmallVector Decls; - LoadedFieldsFromExternalStorage = true; + setHasLoadedFieldsFromExternalStorage(true); Source->FindExternalLexicalDecls(this, [](Decl::Kind K) { return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K); }, Decls); Index: lib/AST/DeclBase.cpp =================================================================== --- lib/AST/DeclBase.cpp +++ lib/AST/DeclBase.cpp @@ -153,7 +153,7 @@ } const char *DeclContext::getDeclKindName() const { - switch (DeclKind) { + switch (getDeclKind()) { default: llvm_unreachable("Declaration context not in DeclNodes.inc!"); #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED; #define ABSTRACT_DECL(DECL) @@ -980,6 +980,16 @@ // DeclContext Implementation //===----------------------------------------------------------------------===// +DeclContext::DeclContext(Decl::Kind K) { + DeclContextBits.DeclKind = K; + setHasExternalLexicalStorage(false); + setHasExternalVisibleStorage(false); + setNeedToReconcileExternalVisibleStorage(false); + setHasLazyLocalLexicalLookups(false); + setHasLazyExternalLexicalLookups(false); + setUseQualifiedLookup(false); +} + bool DeclContext::classof(const Decl *D) { switch (D->getKind()) { #define DECL(NAME, BASE) @@ -1070,9 +1080,9 @@ } bool DeclContext::isTransparentContext() const { - if (DeclKind == Decl::Enum) + if (getDeclKind() == Decl::Enum) return !cast(this)->isScoped(); - else if (DeclKind == Decl::LinkageSpec || DeclKind == Decl::Export) + else if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export) return true; return false; @@ -1118,7 +1128,7 @@ } DeclContext *DeclContext::getPrimaryContext() { - switch (DeclKind) { + switch (getDeclKind()) { case Decl::TranslationUnit: case Decl::ExternCContext: case Decl::LinkageSpec: @@ -1154,7 +1164,7 @@ return this; default: - if (DeclKind >= Decl::firstTag && DeclKind <= Decl::lastTag) { + if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) { // If this is a tag type that has a definition or is currently // being defined, that definition is our primary context. auto *Tag = cast(this); @@ -1174,7 +1184,8 @@ return Tag; } - assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction && + assert(getDeclKind() >= Decl::firstFunction && + getDeclKind() <= Decl::lastFunction && "Unknown DeclContext kind"); return this; } @@ -1184,7 +1195,7 @@ DeclContext::collectAllContexts(SmallVectorImpl &Contexts){ Contexts.clear(); - if (DeclKind != Decl::Namespace) { + if (getDeclKind() != Decl::Namespace) { Contexts.push_back(this); return; } @@ -1222,8 +1233,8 @@ /// built a lookup map. For every name in the map, pull in the new names from /// the external storage. void DeclContext::reconcileExternalVisibleStorage() const { - assert(NeedToReconcileExternalVisibleStorage && LookupPtr); - NeedToReconcileExternalVisibleStorage = false; + assert(hasNeedToReconcileExternalVisibleStorage() && LookupPtr); + setNeedToReconcileExternalVisibleStorage(false); for (auto &Lookup : *LookupPtr) Lookup.second.setHasExternalDecls(); @@ -1242,7 +1253,7 @@ // Load the external declarations, if any. SmallVector Decls; - ExternalLexicalStorage = false; + setHasExternalLexicalStorage(false); Source->FindExternalLexicalDecls(this, Decls); if (Decls.empty()) @@ -1252,7 +1263,7 @@ // we need to ignore them. bool FieldsAlreadyLoaded = false; if (const auto *RD = dyn_cast(this)) - FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage; + FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage(); // Splice the newly-read declarations into the beginning of the list // of declarations. @@ -1273,7 +1284,7 @@ StoredDeclsMap *Map; if (!(Map = DC->LookupPtr)) Map = DC->CreateStoredDeclsMap(Context); - if (DC->NeedToReconcileExternalVisibleStorage) + if (DC->hasNeedToReconcileExternalVisibleStorage()) DC->reconcileExternalVisibleStorage(); (*Map)[Name].removeExternalDecls(); @@ -1289,7 +1300,7 @@ StoredDeclsMap *Map; if (!(Map = DC->LookupPtr)) Map = DC->CreateStoredDeclsMap(Context); - if (DC->NeedToReconcileExternalVisibleStorage) + if (DC->hasNeedToReconcileExternalVisibleStorage()) DC->reconcileExternalVisibleStorage(); StoredDeclsList &List = (*Map)[Name]; @@ -1483,21 +1494,24 @@ StoredDeclsMap *DeclContext::buildLookup() { assert(this == getPrimaryContext() && "buildLookup called on non-primary DC"); - if (!HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups) + if (!hasLazyLocalLexicalLookups() && + !hasLazyExternalLexicalLookups()) return LookupPtr; SmallVector Contexts; collectAllContexts(Contexts); - if (HasLazyExternalLexicalLookups) { - HasLazyExternalLexicalLookups = false; + if (hasLazyExternalLexicalLookups()) { + setHasLazyExternalLexicalLookups(false); for (auto *DC : Contexts) { - if (DC->hasExternalLexicalStorage()) - HasLazyLocalLexicalLookups |= - DC->LoadLexicalDeclsFromExternalStorage(); + if (DC->hasExternalLexicalStorage()) { + bool LoadedDecls = DC->LoadLexicalDeclsFromExternalStorage(); + setHasLazyLocalLexicalLookups( + hasLazyLocalLexicalLookups() | LoadedDecls ); + } } - if (!HasLazyLocalLexicalLookups) + if (!hasLazyLocalLexicalLookups()) return LookupPtr; } @@ -1505,7 +1519,7 @@ buildLookupImpl(DC, hasExternalVisibleStorage()); // We no longer have any lazy decls. - HasLazyLocalLexicalLookups = false; + setHasLazyLocalLexicalLookups(false); return LookupPtr; } @@ -1543,7 +1557,8 @@ DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) const { - assert(DeclKind != Decl::LinkageSpec && DeclKind != Decl::Export && + assert(getDeclKind() != Decl::LinkageSpec && + getDeclKind() != Decl::Export && "should not perform lookups into transparent contexts"); const DeclContext *PrimaryContext = getPrimaryContext(); @@ -1560,12 +1575,13 @@ if (hasExternalVisibleStorage()) { assert(Source && "external visible storage but no external source?"); - if (NeedToReconcileExternalVisibleStorage) + if (hasNeedToReconcileExternalVisibleStorage()) reconcileExternalVisibleStorage(); StoredDeclsMap *Map = LookupPtr; - if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups) + if (hasLazyLocalLexicalLookups() || + hasLazyExternalLexicalLookups()) // FIXME: Make buildLookup const? Map = const_cast(this)->buildLookup(); @@ -1590,7 +1606,8 @@ } StoredDeclsMap *Map = LookupPtr; - if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups) + if (hasLazyLocalLexicalLookups() || + hasLazyExternalLexicalLookups()) Map = const_cast(this)->buildLookup(); if (!Map) @@ -1605,7 +1622,8 @@ DeclContext::lookup_result DeclContext::noload_lookup(DeclarationName Name) { - assert(DeclKind != Decl::LinkageSpec && DeclKind != Decl::Export && + assert(getDeclKind() != Decl::LinkageSpec && + getDeclKind() != Decl::Export && "should not perform lookups into transparent contexts"); DeclContext *PrimaryContext = getPrimaryContext(); @@ -1626,12 +1644,12 @@ // now. Don't import any external declarations, not even if we know we have // some missing from the external visible lookups. void DeclContext::loadLazyLocalLexicalLookups() { - if (HasLazyLocalLexicalLookups) { + if (hasLazyLocalLexicalLookups()) { SmallVector Contexts; collectAllContexts(Contexts); for (auto *Context : Contexts) buildLookupImpl(Context, hasExternalVisibleStorage()); - HasLazyLocalLexicalLookups = false; + setHasLazyLocalLexicalLookups(false); } } @@ -1649,7 +1667,8 @@ // If we have a lookup table, check there first. Maybe we'll get lucky. // FIXME: Should we be checking these flags on the primary context? - if (Name && !HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups) { + if (Name && !hasLazyLocalLexicalLookups() && + !hasLazyExternalLexicalLookups()) { if (StoredDeclsMap *Map = LookupPtr) { StoredDeclsMap::iterator Pos = Map->find(Name); if (Pos != Map->end()) { @@ -1758,7 +1777,7 @@ buildLookup(); makeDeclVisibleInContextImpl(D, Internal); } else { - HasLazyLocalLexicalLookups = true; + setHasLazyLocalLexicalLookups(true); } // If we are a transparent context or inline namespace, insert into our Index: lib/AST/DeclCXX.cpp =================================================================== --- lib/AST/DeclCXX.cpp +++ lib/AST/DeclCXX.cpp @@ -128,7 +128,7 @@ bool DelayTypeCreation) { auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl); - R->MayHaveOutOfDateDef = C.getLangOpts().Modules; + R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); // FIXME: DelayTypeCreation seems like such a hack if (!DelayTypeCreation) @@ -143,11 +143,11 @@ LambdaCaptureDefault CaptureDefault) { auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc, nullptr, nullptr); - R->IsBeingDefined = true; + R->setBeingDefined(true); R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric, CaptureDefault); - R->MayHaveOutOfDateDef = false; + R->setMayHaveOutOfDateDef(false); R->setImplicit(true); C.getTypeDeclType(R, /*PrevDecl=*/nullptr); return R; @@ -158,7 +158,7 @@ auto *R = new (C, ID) CXXRecordDecl( CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); - R->MayHaveOutOfDateDef = false; + R->setMayHaveOutOfDateDef(false); return R; } Index: lib/AST/DeclTemplate.cpp =================================================================== --- lib/AST/DeclTemplate.cpp +++ lib/AST/DeclTemplate.cpp @@ -712,7 +712,7 @@ new (Context, DC) ClassTemplateSpecializationDecl( Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, SpecializedTemplate, Args, PrevDecl); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); Context.getTypeDeclType(Result, PrevDecl); return Result; @@ -723,7 +723,7 @@ unsigned ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); return Result; } @@ -830,7 +830,7 @@ Params, SpecializedTemplate, Args, ASTArgInfos, PrevDecl); Result->setSpecializationKind(TSK_ExplicitSpecialization); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); Context.getInjectedClassNameType(Result, CanonInjectedType); return Result; @@ -840,7 +840,7 @@ ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); return Result; } Index: lib/Serialization/ASTReaderDecl.cpp =================================================================== --- lib/Serialization/ASTReaderDecl.cpp +++ lib/Serialization/ASTReaderDecl.cpp @@ -742,16 +742,16 @@ ED->setPromotionType(Record.readType()); ED->setNumPositiveBits(Record.readInt()); ED->setNumNegativeBits(Record.readInt()); - ED->IsScoped = Record.readInt(); - ED->IsScopedUsingClassTag = Record.readInt(); - ED->IsFixed = Record.readInt(); + ED->setScoped(Record.readInt()); + ED->setScopedUsingClassTag(Record.readInt()); + ED->setFixed(Record.readInt()); - ED->HasODRHash = true; + ED->setHasODRHash(true); ED->ODRHash = Record.readInt(); // If this is a definition subject to the ODR, and we already have a // definition, merge this one into it. - if (ED->IsCompleteDefinition && + if (ED->isCompleteDefinition() && Reader.getContext().getLangOpts().Modules && Reader.getContext().getLangOpts().CPlusPlus) { EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()]; @@ -767,7 +767,7 @@ } if (OldDef) { Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef)); - ED->IsCompleteDefinition = false; + ED->setCompleteDefinition(false); Reader.mergeDefinitionVisibility(OldDef, ED); if (OldDef->getODRHash() != ED->getODRHash()) Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED); @@ -1744,7 +1744,7 @@ Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition, DD.Definition)); Reader.PendingDefinitions.erase(MergeDD.Definition); - MergeDD.Definition->IsCompleteDefinition = false; + MergeDD.Definition->setCompleteDefinition(false); Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition); assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() && "already loaded pending lookups for merged definition"); @@ -1884,7 +1884,7 @@ } // Mark this declaration as being a definition. - D->IsCompleteDefinition = true; + D->setCompleteDefinition(true); // If this is not the first declaration or is an update record, we can have // other redeclarations already. Make a note that we need to propagate the @@ -1946,7 +1946,7 @@ // compute it. if (WasDefinition) { DeclID KeyFn = ReadDeclID(); - if (KeyFn && D->IsCompleteDefinition) + if (KeyFn && D->isCompleteDefinition()) // FIXME: This is wrong for the ARM ABI, where some other module may have // made this function no longer be a key function. We need an update // record or similar for that case. @@ -3076,7 +3076,7 @@ // we load the update record. if (!DD) { DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD); - RD->IsCompleteDefinition = true; + RD->setCompleteDefinition(true); RD->DefinitionData = DD; RD->getCanonicalDecl()->DefinitionData = DD; Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -3960,7 +3960,8 @@ bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC) { - return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage; + return Result.hasExternalDecls() && + DC->hasNeedToReconcileExternalVisibleStorage(); } bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result, @@ -3975,8 +3976,8 @@ void ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC, llvm::SmallVectorImpl &LookupTable) { - assert(!ConstDC->HasLazyLocalLexicalLookups && - !ConstDC->HasLazyExternalLexicalLookups && + assert(!ConstDC->hasLazyLocalLexicalLookups() && + !ConstDC->hasLazyExternalLexicalLookups() && "must call buildLookups first"); // FIXME: We need to build the lookups table, which is logically const. Index: lib/Serialization/ASTWriterDecl.cpp =================================================================== --- lib/Serialization/ASTWriterDecl.cpp +++ lib/Serialization/ASTWriterDecl.cpp @@ -1275,7 +1275,7 @@ // Store (what we currently believe to be) the key function to avoid // deserializing every method so we can compute it. - if (D->IsCompleteDefinition) + if (D->isCompleteDefinition()) Record.AddDeclRef(Context.getCurrentKeyFunction(D)); Code = serialization::DECL_CXX_RECORD;