r338630 - [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 1 13:48:16 PDT 2018


Author: erichkeane
Date: Wed Aug  1 13:48:16 2018
New Revision: 338630

URL: http://llvm.org/viewvc/llvm-project?rev=338630&view=rev
Log:
[AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

DeclContext has a little less than 8 bytes free due to the alignment
requirements on 64 bits archs. This set of patches moves the
bit-fields from classes deriving from DeclContext into DeclContext.

On 32 bits archs this increases the size of DeclContext by 4 bytes
but this is balanced by an equal or larger reduction in the size
of the classes deriving from it.

On 64 bits archs the size of DeclContext stays the same but
most of the classes deriving from it shrink by 8/16 bytes.
(-print-stats diff here https://reviews.llvm.org/D49728)
When doing an -fsyntax-only on all of Boost this result
in a 3.6% reduction in the size of all Decls and
a 1% reduction in the run time due to the lower cache
miss rate.

For now CXXRecordDecl is not touched but there is
an easy 6 (if I count correctly) bytes gain available there
by moving some bits from DefinitionData into the free
space of DeclContext. This will be the subject of another patch.

This patch sequence also enable the possibility of refactoring
FunctionDecl: To save space some bits from classes deriving from
FunctionDecl were moved to FunctionDecl. This resulted in a
lot of stuff in FunctionDecl which do not belong logically to it.
After this set of patches however it is just a simple matter of
adding a SomethingDeclBitfields in DeclContext and moving the
bits to it from FunctionDecl.

This first patch introduces the anonymous union in DeclContext
and all the *DeclBitfields classes holding the bit-fields, and moves
the bits from TagDecl, EnumDecl and RecordDecl into DeclContext.

This patch is followed by https://reviews.llvm.org/D49732,
https://reviews.llvm.org/D49733 and https://reviews.llvm.org/D49734.

Differential Revision: https://reviews.llvm.org/D49729

Patch By: bricci


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Aug  1 13:48:16 2018
@@ -3014,64 +3014,16 @@ public:
 };
 
 /// Represents the declaration of a struct/union/class/enum.
-class TagDecl
-  : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
+class TagDecl : public TypeDecl,
+                public DeclContext,
+                public Redeclarable<TagDecl> {
+  // 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;
 
   // A struct representing syntactic qualifier info,
@@ -3097,16 +3049,7 @@ private:
 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<TagDecl>;
 
@@ -3127,6 +3070,17 @@ protected:
   /// 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 @@ public:
   }
 
   /// 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 @@ public:
   ///  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<TagKind>(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 @@ public:
 /// 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 @@ class EnumDecl : public TagDecl {
   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 @@ public:
 
   /// 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 @@ public:
   ///                       -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 @@ public:
 ///   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 @@ public:
     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 @@ public:
     return const_cast<RecordDecl*>(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 @@ public:
   ///  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 @@ public:
   }
 
   ArgPassingKind getArgPassingRestrictions() const {
-    return static_cast<ArgPassingKind>(ArgPassingRestrictions);
+    return static_cast<ArgPassingKind>(RecordDeclBits.ArgPassingRestrictions);
   }
 
   void setArgPassingRestrictions(ArgPassingKind Kind) {
-    ArgPassingRestrictions = static_cast<uint8_t>(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

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Aug  1 13:48:16 2018
@@ -1260,37 +1260,407 @@ public:
 ///   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.
 
-  /// Whether this declaration context also has some external
-  /// storage that contains additional declarations that are lexically
-  /// part of this context.
-  mutable bool ExternalLexicalStorage : 1;
-
-  /// 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 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 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;
+  /// Number of bits in DeclContextBitfields.
+  enum { NumDeclContextBits = 13 };
 
-  /// If \c true, this context may have local lexical declarations
-  /// that are missing from the lookup table.
-  mutable bool HasLazyLocalLexicalLookups : 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;
+
+    /// The TagKind enum.
+    uint64_t 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.
+    uint64_t IsCompleteDefinition : 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;
+  };
 
-  /// If \c true, the external source may have lexical declarations
-  /// that are missing from the lookup table.
-  mutable bool HasLazyExternalLexicalLookups : 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;
 
-  /// If \c true, lookups should only return identifier from
-  /// DeclContext scope (for example TranslationUnit). Used in
-  /// LookupQualifiedName()
-  mutable bool UseQualifiedLookup : 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<init_expr> 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;
+  };
+
+  /// 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 @@ class DeclContext {
   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 @@ protected:
   static std::pair<Decl *, Decl *>
   BuildDeclChain(ArrayRef<Decl*> 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<Decl::Kind>(DeclKind);
+    return static_cast<Decl::Kind>(DeclContextBits.DeclKind);
   }
 
   const char *getDeclKindName() const;
@@ -1371,54 +1781,54 @@ public:
     return cast<Decl>(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 @@ public:
   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 @@ public:
 
   /// 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 @@ public:
                  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 @@ public:
                    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;

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Aug  1 13:48:16 2018
@@ -3767,6 +3767,22 @@ void FieldDecl::setCapturedVLAType(const
 // 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);
 }
@@ -3789,7 +3805,7 @@ void TagDecl::setTypedefNameForAnonDecl(
 }
 
 void TagDecl::startDefinition() {
-  IsBeingDefined = true;
+  setBeingDefined(true);
 
   if (auto *D = dyn_cast<CXXRecordDecl>(this)) {
     struct CXXRecordDecl::DefinitionData *Data =
@@ -3804,8 +3820,8 @@ void TagDecl::completeDefinition() {
           cast<CXXRecordDecl>(this)->hasDefinition()) &&
          "definition completed but not started");
 
-  IsCompleteDefinition = true;
-  IsBeingDefined = false;
+  setCompleteDefinition(true);
+  setBeingDefined(false);
 
   if (ASTMutationListener *L = getASTMutationListener())
     L->CompletedTagDefinition(this);
@@ -3816,7 +3832,7 @@ TagDecl *TagDecl::getDefinition() const
     return const_cast<TagDecl *>(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);
@@ -3869,6 +3885,21 @@ void TagDecl::setTemplateParameterListsI
 // 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,
@@ -3878,7 +3909,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C
                            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;
 }
@@ -3887,7 +3918,7 @@ EnumDecl *EnumDecl::CreateDeserialized(A
   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;
 }
 
@@ -3971,12 +4002,12 @@ void EnumDecl::setInstantiationOfMemberE
 }
 
 unsigned EnumDecl::getODRHash() {
-  if (HasODRHash)
+  if (hasODRHash())
     return ODRHash;
 
   class ODRHash Hash;
   Hash.AddEnumDecl(this);
-  HasODRHash = true;
+  setHasODRHash(true);
   ODRHash = Hash.CalculateHash();
   return ODRHash;
 }
@@ -3989,14 +4020,18 @@ RecordDecl::RecordDecl(Kind DK, TagKind
                        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<Decl*>(this)) && "Invalid Kind!");
+    : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
+  assert(classof(static_cast<Decl *>(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,
@@ -4004,7 +4039,7 @@ RecordDecl *RecordDecl::Create(const AST
                                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;
@@ -4014,7 +4049,7 @@ RecordDecl *RecordDecl::CreateDeserializ
   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;
 }
 
@@ -4038,7 +4073,7 @@ void RecordDecl::setCapturedRecord() {
 }
 
 RecordDecl::field_iterator RecordDecl::field_begin() const {
-  if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage)
+  if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage())
     LoadFieldsFromExternalStorage();
 
   return field_iterator(decl_iterator(FirstDecl));
@@ -4066,7 +4101,7 @@ void RecordDecl::LoadFieldsFromExternalS
   ExternalASTSource::Deserializing TheFields(Source);
 
   SmallVector<Decl*, 64> Decls;
-  LoadedFieldsFromExternalStorage = true;
+  setHasLoadedFieldsFromExternalStorage(true);
   Source->FindExternalLexicalDecls(this, [](Decl::Kind K) {
     return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K);
   }, Decls);

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Aug  1 13:48:16 2018
@@ -153,7 +153,7 @@ void Decl::setInvalidDecl(bool Invalid)
 }
 
 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 @@ Decl *DeclContext::getNonClosureAncestor
 // 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::isDependentContext() c
 }
 
 bool DeclContext::isTransparentContext() const {
-  if (DeclKind == Decl::Enum)
+  if (getDeclKind() == Decl::Enum)
     return !cast<EnumDecl>(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 @@ bool DeclContext::Encloses(const DeclCon
 }
 
 DeclContext *DeclContext::getPrimaryContext() {
-  switch (DeclKind) {
+  switch (getDeclKind()) {
   case Decl::TranslationUnit:
   case Decl::ExternCContext:
   case Decl::LinkageSpec:
@@ -1154,7 +1164,7 @@ DeclContext *DeclContext::getPrimaryCont
     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<TagDecl>(this);
@@ -1174,7 +1184,8 @@ DeclContext *DeclContext::getPrimaryCont
       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 @@ void
 DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts){
   Contexts.clear();
 
-  if (DeclKind != Decl::Namespace) {
+  if (getDeclKind() != Decl::Namespace) {
     Contexts.push_back(this);
     return;
   }
@@ -1222,8 +1233,8 @@ DeclContext::BuildDeclChain(ArrayRef<Dec
 /// 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 @@ DeclContext::LoadLexicalDeclsFromExterna
 
   // Load the external declarations, if any.
   SmallVector<Decl*, 64> Decls;
-  ExternalLexicalStorage = false;
+  setHasExternalLexicalStorage(false);
   Source->FindExternalLexicalDecls(this, Decls);
 
   if (Decls.empty())
@@ -1252,7 +1263,7 @@ DeclContext::LoadLexicalDeclsFromExterna
   // we need to ignore them.
   bool FieldsAlreadyLoaded = false;
   if (const auto *RD = dyn_cast<RecordDecl>(this))
-    FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage;
+    FieldsAlreadyLoaded = RD->hasLoadedFieldsFromExternalStorage();
 
   // Splice the newly-read declarations into the beginning of the list
   // of declarations.
@@ -1273,7 +1284,7 @@ ExternalASTSource::SetNoExternalVisibleD
   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 @@ ExternalASTSource::SetExternalVisibleDec
   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 @@ void DeclContext::addDeclInternal(Decl *
 StoredDeclsMap *DeclContext::buildLookup() {
   assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
 
-  if (!HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups)
+  if (!hasLazyLocalLexicalLookups() &&
+      !hasLazyExternalLexicalLookups())
     return LookupPtr;
 
   SmallVector<DeclContext *, 2> 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 @@ StoredDeclsMap *DeclContext::buildLookup
     buildLookupImpl(DC, hasExternalVisibleStorage());
 
   // We no longer have any lazy decls.
-  HasLazyLocalLexicalLookups = false;
+  setHasLazyLocalLexicalLookups(false);
   return LookupPtr;
 }
 
@@ -1543,7 +1557,8 @@ NamedDecl *const DeclContextLookupResult
 
 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 @@ DeclContext::lookup(DeclarationName Name
   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<DeclContext*>(this)->buildLookup();
 
@@ -1590,7 +1606,8 @@ DeclContext::lookup(DeclarationName Name
   }
 
   StoredDeclsMap *Map = LookupPtr;
-  if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups)
+  if (hasLazyLocalLexicalLookups() ||
+      hasLazyExternalLexicalLookups())
     Map = const_cast<DeclContext*>(this)->buildLookup();
 
   if (!Map)
@@ -1605,7 +1622,8 @@ DeclContext::lookup(DeclarationName Name
 
 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 @@ DeclContext::noload_lookup(DeclarationNa
 // 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<DeclContext *, 2> Contexts;
     collectAllContexts(Contexts);
     for (auto *Context : Contexts)
       buildLookupImpl(Context, hasExternalVisibleStorage());
-    HasLazyLocalLexicalLookups = false;
+    setHasLazyLocalLexicalLookups(false);
   }
 }
 
@@ -1649,7 +1667,8 @@ void DeclContext::localUncachedLookup(De
 
   // 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 @@ void DeclContext::makeDeclVisibleInConte
     buildLookup();
     makeDeclVisibleInContextImpl(D, Internal);
   } else {
-    HasLazyLocalLexicalLookups = true;
+    setHasLazyLocalLexicalLookups(true);
   }
 
   // If we are a transparent context or inline namespace, insert into our

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Aug  1 13:48:16 2018
@@ -128,7 +128,7 @@ CXXRecordDecl *CXXRecordDecl::Create(con
                                      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 @@ CXXRecordDecl::CreateLambda(const ASTCon
                             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 @@ CXXRecordDecl::CreateDeserialized(const
   auto *R = new (C, ID) CXXRecordDecl(
       CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(),
       nullptr, nullptr);
-  R->MayHaveOutOfDateDef = false;
+  R->setMayHaveOutOfDateDef(false);
   return R;
 }
 

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Wed Aug  1 13:48:16 2018
@@ -712,7 +712,7 @@ ClassTemplateSpecializationDecl::Create(
       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 @@ ClassTemplateSpecializationDecl::CreateD
                                                     unsigned ID) {
   auto *Result =
     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
-  Result->MayHaveOutOfDateDef = false;
+  Result->setMayHaveOutOfDateDef(false);
   return Result;
 }
 
@@ -830,7 +830,7 @@ Create(ASTContext &Context, TagKind TK,D
                                              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 *
 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                            unsigned ID) {
   auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
-  Result->MayHaveOutOfDateDef = false;
+  Result->setMayHaveOutOfDateDef(false);
   return Result;
 }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Aug  1 13:48:16 2018
@@ -742,16 +742,16 @@ void ASTDeclReader::VisitEnumDecl(EnumDe
   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 @@ void ASTDeclReader::VisitEnumDecl(EnumDe
     }
     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 @@ void ASTDeclReader::MergeDefinitionData(
     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 @@ void ASTDeclReader::ReadCXXRecordDefinit
   }
 
   // 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 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CX
   // 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 @@ DeclContext *ASTDeclReader::getPrimaryCo
     // 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;
 

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Aug  1 13:48:16 2018
@@ -3960,7 +3960,8 @@ public:
 
 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 @@ bool ASTWriter::isLookupResultEntirelyEx
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
                                    llvm::SmallVectorImpl<char> &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.

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=338630&r1=338629&r2=338630&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Aug  1 13:48:16 2018
@@ -1275,7 +1275,7 @@ void ASTDeclWriter::VisitCXXRecordDecl(C
 
   // 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;




More information about the cfe-commits mailing list