This revision was automatically updated to reflect the committed changes.
Closed by commit rC338630: [AST][1/4] Move the bit-fields from TagDecl, 
EnumDecl and RecordDecl into… (authored by erichkeane, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D49729?vs=158498&id=158624#toc

Repository:
  rC Clang

https://reviews.llvm.org/D49729

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

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.
 
-  /// 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;
+
+    /// 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 };
 
-  /// If \c true, lookups should only return identifier from
-  /// DeclContext scope (for example TranslationUnit). Used in
-  /// LookupQualifiedName()
-  mutable bool UseQualifiedLookup : 1;
+  /// 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 @@
   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<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 @@
     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 @@
   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: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -3014,64 +3014,16 @@
 };
 
 /// 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 @@
 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 @@
   /// 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<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 @@
 /// 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<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 @@
   ///  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<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
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<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.
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;
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/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -3767,6 +3767,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);
 }
@@ -3789,7 +3805,7 @@
 }
 
 void TagDecl::startDefinition() {
-  IsBeingDefined = true;
+  setBeingDefined(true);
 
   if (auto *D = dyn_cast<CXXRecordDecl>(this)) {
     struct CXXRecordDecl::DefinitionData *Data =
@@ -3804,8 +3820,8 @@
           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 @@
     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 @@
 // 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,16 +3909,16 @@
                            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;
 }
 
 EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
   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 @@
 }
 
 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,22 +4020,26 @@
                        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,
                                SourceLocation StartLoc, SourceLocation IdLoc,
                                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 *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 @@
 }
 
 RecordDecl::field_iterator RecordDecl::field_begin() const {
-  if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage)
+  if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage())
     LoadFieldsFromExternalStorage();
 
   return field_iterator(decl_iterator(FirstDecl));
@@ -4066,7 +4101,7 @@
   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);
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/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<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 @@
 }
 
 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<TagDecl>(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<DeclContext *> &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<Decl*, 64> 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<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 @@
   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,29 +1494,32 @@
 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;
   }
 
   for (auto *DC : Contexts)
     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<DeclContext*>(this)->buildLookup();
 
@@ -1590,7 +1606,8 @@
   }
 
   StoredDeclsMap *Map = LookupPtr;
-  if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups)
+  if (hasLazyLocalLexicalLookups() ||
+      hasLazyExternalLexicalLookups())
     Map = const_cast<DeclContext*>(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<DeclContext *, 2> 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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to