bricci created this revision.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

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
all 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.

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.


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: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1273,7 +1273,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/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/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,13 +742,13 @@
   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());
 
   // 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()];
@@ -764,7 +764,7 @@
     }
     if (OldDef) {
       Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-      ED->IsCompleteDefinition = false;
+      ED->setCompleteDefinition(false);
       Reader.mergeDefinitionVisibility(OldDef, ED);
     } else {
       OldDef = ED;
@@ -1739,7 +1739,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");
@@ -1879,7 +1879,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
@@ -1941,7 +1941,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.
@@ -3071,7 +3071,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/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/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/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,38 @@
 // DeclContext Implementation
 //===----------------------------------------------------------------------===//
 
+DeclContext::DeclContext(Decl::Kind K) {
+  DeclContextBits.DeclKind = K;
+  setHasExternalLexicalStorage(false);
+  setHasExternalVisibleStorage(false);
+  setNeedToReconcileExternalVisibleStorage(false);
+  setHasLazyLocalLexicalLookups(false);
+  setHasLazyExternalLexicalLookups(false);
+  setUseQualifiedLookup(false);
+  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!");
+}
+
 bool DeclContext::classof(const Decl *D) {
   switch (D->getKind()) {
 #define DECL(NAME, BASE)
@@ -1070,9 +1102,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 +1150,7 @@
 }
 
 DeclContext *DeclContext::getPrimaryContext() {
-  switch (DeclKind) {
+  switch (getDeclKind()) {
   case Decl::TranslationUnit:
   case Decl::ExternCContext:
   case Decl::LinkageSpec:
@@ -1154,7 +1186,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 +1206,8 @@
       return Tag;
     }
 
-    assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction &&
+    assert(getDeclKind() >= Decl::firstFunction &&
+           getDeclKind() <= Decl::lastFunction &&
           "Unknown DeclContext kind");
     return this;
   }
@@ -1184,7 +1217,7 @@
 DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts){
   Contexts.clear();
   
-  if (DeclKind != Decl::Namespace) {
+  if (getDeclKind() != Decl::Namespace) {
     Contexts.push_back(this);
     return;
   }
@@ -1222,8 +1255,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 +1275,7 @@
 
   // Load the external declarations, if any.
   SmallVector<Decl*, 64> Decls;
-  ExternalLexicalStorage = false;
+  setHasExternalLexicalStorage(false);
   Source->FindExternalLexicalDecls(this, Decls);
 
   if (Decls.empty())
@@ -1252,7 +1285,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 +1306,7 @@
   StoredDeclsMap *Map;
   if (!(Map = DC->LookupPtr))
     Map = DC->CreateStoredDeclsMap(Context);
-  if (DC->NeedToReconcileExternalVisibleStorage)
+  if (DC->hasNeedToReconcileExternalVisibleStorage())
     DC->reconcileExternalVisibleStorage();
 
   (*Map)[Name].removeExternalDecls();
@@ -1289,7 +1322,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 +1516,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 +1579,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 +1597,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 +1628,8 @@
   }
 
   StoredDeclsMap *Map = LookupPtr;
-  if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups)
+  if (hasLazyLocalLexicalLookups() ||
+      hasLazyExternalLexicalLookups())
     Map = const_cast<DeclContext*>(this)->buildLookup();
 
   if (!Map)
@@ -1605,7 +1644,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 +1666,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 +1689,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 +1799,7 @@
     buildLookup();
     makeDeclVisibleInContextImpl(D, Internal);
   } else {
-    HasLazyLocalLexicalLookups = true;
+    setHasLazyLocalLexicalLookups(true);
   }
 
   // If we are a transparent context or inline namespace, insert into our
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -3770,6 +3770,22 @@
 // TagDecl Implementation
 //===----------------------------------------------------------------------===//
 
+TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
+          SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
+          SourceLocation StartL)
+      : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
+        TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) {
+  assert((DK != Enum || TK == TTK_Enum) &&
+         "EnumDecl not matched with TTK_Enum");
+  setPreviousDecl(PrevDecl);
+  setTagKind(TK);
+  setCompleteDefinition(false);
+  setBeingDefined(false);
+  setEmbeddedInDeclarator(false);
+  setFreeStanding(false);
+  setCompleteDefinitionRequired(false);
+}
+
 SourceLocation TagDecl::getOuterLocStart() const {
   return getTemplateOrInnerLocStart(this);
 }
@@ -3792,7 +3808,7 @@
 }
 
 void TagDecl::startDefinition() {
-  IsBeingDefined = true;
+  setBeingDefined(true);
 
   if (auto *D = dyn_cast<CXXRecordDecl>(this)) {
     struct CXXRecordDecl::DefinitionData *Data =
@@ -3807,8 +3823,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);
@@ -3819,7 +3835,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);
@@ -3872,6 +3888,19 @@
 // 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 = (const Type *)nullptr;
+  setNumPositiveBits(0);
+  setNumNegativeBits(0);
+  setScoped(Scoped);
+  setScopedUsingClassTag(ScopedUsingClassTag);
+  setFixed(Fixed);
+}
+
 void EnumDecl::anchor() {}
 
 EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
@@ -3881,16 +3910,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;
 }
 
@@ -3981,22 +4010,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) {
+    : 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;
@@ -4006,7 +4039,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;
 }
 
@@ -4030,7 +4063,7 @@
 }
 
 RecordDecl::field_iterator RecordDecl::field_begin() const {
-  if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage)
+  if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage())
     LoadFieldsFromExternalStorage();
 
   return field_iterator(decl_iterator(FirstDecl));
@@ -4058,7 +4091,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: include/clang/AST/DeclBase.h
===================================================================
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -1250,47 +1250,415 @@
 /// that directly derive from DeclContext are mentioned, not their subclasses):
 ///
 ///   TranslationUnitDecl
+///   ExternCContext
 ///   NamespaceDecl
-///   FunctionDecl
 ///   TagDecl
+///   OMPDeclareReductionDecl
+///   FunctionDecl
 ///   ObjCMethodDecl
 ///   ObjCContainerDecl
 ///   LinkageSpecDecl
 ///   ExportDecl
 ///   BlockDecl
-///   OMPDeclareReductionDecl
+///   CapturedDecl
 class DeclContext {
-  /// DeclKind - This indicates which class this is.
-  unsigned DeclKind : 8;
-
-  /// 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;
-
-  /// 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;
-
-  /// If \c true, this context may have local lexical declarations
-  /// that are missing from the lookup table.
-  mutable bool HasLazyLocalLexicalLookups : 1;
-
-  /// If \c true, the external source may have lexical declarations
-  /// that are missing from the lookup table.
-  mutable bool HasLazyExternalLexicalLookups : 1;
+  /// For makeDeclVisibleInContextImpl
+  friend class ASTDeclReader;
+  /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap
+  friend class ExternalASTSource;
+  /// For CreateStoredDeclsMap
+  friend class DependentDiagnostic;
 
-  /// If \c true, lookups should only return identifier from
-  /// DeclContext scope (for example TranslationUnit). Used in
-  /// LookupQualifiedName()
-  mutable bool UseQualifiedLookup : 1;
+  /// DeclContextBitfields - 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 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 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;
+  };
+  /// NumDeclContextBits - Number of bits in DeclContextBitfields.
+  enum { NumDeclContextBits = 13 };
+
+  /// TagDeclBitfields - 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;
+  };
+  /// NumTagDeclBits - Number of non-inherited bits in TagDeclBitfields.
+  enum { NumTagDeclBits = 9 };
+
+  /// EnumDeclBitfields - 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;
+
+    /// These are used by (and only defined for) EnumDecl.
+    uint64_t NumPositiveBits : 8;
+    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;
+  };
+  /// NumEnumDeclBits - Number of non-inherited bits in EnumDeclBitfields.
+  enum { NumEnumDeclBits = 19 };
+
+  /// RecordDeclBitfields - 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;
+  };
+  /// NumRecordDeclBits - Number of non-inherited bits in RecordDeclBitfields.
+  enum { NumRecordDeclBits = 11 };
+
+  /// OMPDeclareReductionDeclBitfields -
+  /// 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;
+  };
+  /// NumOMPDeclareReductionDeclBits -
+  /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields.
+  enum { NumOMPDeclareReductionDeclBits = 2 };
+
+  /// FunctionDeclBitfields - 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;
+  };
+  /// NumFunctionDeclBits -
+  /// Number of non-inherited bits in FunctionDeclBitfields.
+  enum { NumFunctionDeclBits = 25 };
+
+  /// CXXConstructorDeclBitfields - 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;
+  };
+  /// NumCXXConstructorDeclBits -
+  /// Number of non-inherited bits in CXXConstructorDeclBitfields.
+  enum { NumCXXConstructorDeclBits = 26 };
+
+  /// ObjCMethodDeclBitfields - 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;
+
+    // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
+    /// \@required/\@optional
+    uint64_t DeclImplementation : 2;
+
+    // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
+    /// 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;
+  };
+  /// NumObjCMethodDeclBits -
+  /// Number of non-inherited bits in ObjCMethodDeclBitfields.
+  enum { NumObjCMethodDeclBits = 24 };
+
+  /// ObjCContainerDeclBitfields - 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 save space.
+    // Note that ObjCContainerDeclBitfields is full.
+    SourceLocation AtStart;
+  };
+  /// NumObjCContainerDeclBits -
+  /// 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 };
+
+  /// LinkageSpecDeclBitfields - 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;
+  };
+  /// NumLinkageSpecDeclBits -
+  /// Number of non-inherited bits in LinkageSpecDeclBitfields.
+  enum { NumLinkageSpecDeclBits = 4 };
+
+  /// BlockDeclBitfields - 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;
+  };
+  /// NumBlockDeclBits -
+  /// 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,9 +1669,27 @@
   mutable StoredDeclsMap *LookupPtr = nullptr;
 
 protected:
-  friend class ASTDeclReader;
-  friend class ASTWriter;
-  friend class ExternalASTSource;
+  /// 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;
+  };
 
   /// FirstDecl - The first declaration stored within this declaration
   /// context.
@@ -1321,18 +1707,12 @@
   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;
@@ -1372,52 +1752,56 @@
   }
 
   bool isClosure() const {
-    return DeclKind == Decl::Block;
+    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) {
-    case Decl::Block:
-    case Decl::Captured:
-    case Decl::ObjCMethod:
-      return true;
-    default:
-      return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
+    switch (getDeclKind()) {
+      case Decl::Block:
+      case Decl::Captured:
+      case Decl::ObjCMethod:
+        return true;
+      default:
+        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;
+    return getDeclKind() == Decl::Namespace;
   }
 
   bool isStdNamespace() const;
@@ -1886,7 +2270,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 +2282,48 @@
 
   /// 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;
+  }
+
+  /// 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.
+  bool hasNeedToReconcileExternalVisibleStorage() const {
+    return DeclContextBits.NeedToReconcileExternalVisibleStorage;
+  }
+
+  /// 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, the external source may have lexical declarations
+  /// that are missing from the lookup table.
+  bool hasLazyExternalLexicalLookups() const {
+    return DeclContextBits.HasLazyExternalLexicalLookups;
   }
 
   /// Determine whether the given declaration is stored in the list of
@@ -1925,14 +2333,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,19 +2352,29 @@
                    bool Deserialize = false) const;
 
 private:
-  friend class DependentDiagnostic;
+  /// State that 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.
+  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.
+  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.
+  void setHasLazyExternalLexicalLookups(bool HasLELL = true) const {
+    DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
+  }
 
   void reconcileExternalVisibleStorage() const;
   bool LoadLexicalDeclsFromExternalStorage() const;
 
-  /// Makes a declaration visible within this context, but
-  /// suppresses searches for external declarations with the same
-  /// name.
-  ///
-  /// Analogous to makeDeclVisibleInContext, but for the exclusive
-  /// use of addDeclInternal().
-  void makeDeclVisibleInContextInternal(NamedDecl *D);
-
   StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
 
   void loadLazyLocalLexicalLookups();
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -3016,61 +3016,12 @@
 /// Represents the declaration of a struct/union/class/enum.
 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;
 
@@ -3097,16 +3048,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>;
 
@@ -3166,30 +3108,56 @@
 
   /// Return true if this decl has its body fully specified.
   bool isCompleteDefinition() const {
-    return IsCompleteDefinition;
+    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;
+  }
+
+  /// 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 IsBeingDefined;
+    return TagDeclBits.IsBeingDefined;
+  }
+
+  /// True if this decl is currently being defined.
+  void setBeingDefined(bool V = true) {
+    TagDeclBits.IsBeingDefined = V;
   }
 
   bool isEmbeddedInDeclarator() const {
-    return IsEmbeddedInDeclarator;
+    return TagDeclBits.IsEmbeddedInDeclarator;
   }
+
   void setEmbeddedInDeclarator(bool isInDeclarator) {
-    IsEmbeddedInDeclarator = isInDeclarator;
+    TagDeclBits.IsEmbeddedInDeclarator = isInDeclarator;
   }
 
-  bool isFreeStanding() const { return IsFreeStanding; }
+  bool isFreeStanding() const { return TagDeclBits.IsFreeStanding; }
+
   void setFreeStanding(bool isFreeStanding = true) {
-    IsFreeStanding = isFreeStanding;
+    TagDeclBits.IsFreeStanding = isFreeStanding;
+  }
+
+  bool mayHaveOutOfDateDef() const {
+    return TagDeclBits.MayHaveOutOfDateDef;
+  }
+
+  void setMayHaveOutOfDateDef(bool V = true) {
+    TagDeclBits.MayHaveOutOfDateDef = V;
   }
 
   /// Whether this declaration declares a type that is
@@ -3214,21 +3182,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 +3270,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.
@@ -3337,16 +3302,7 @@
 
   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;
-  }
+           bool Scoped, bool ScopedUsingClassTag, bool Fixed);
 
   void anchor() override;
 
@@ -3457,11 +3413,11 @@
   /// Returns the width in bits required to store all the
   /// non-negative enumerators of this enum.
   unsigned getNumPositiveBits() const {
-    return NumPositiveBits;
+    return EnumDeclBits.NumPositiveBits;
   }
   void setNumPositiveBits(unsigned Num) {
-    NumPositiveBits = Num;
-    assert(NumPositiveBits == Num && "can't store this bitcount");
+    EnumDeclBits.NumPositiveBits = Num;
+    assert(EnumDeclBits.NumPositiveBits == Num && "can't store this bitcount");
   }
 
   /// Returns the width in bits required to store all the
@@ -3474,26 +3430,42 @@
   ///                      -10     1110110                     5
   ///                     -101     1001011                     8
   unsigned getNumNegativeBits() const {
-    return NumNegativeBits;
+    return EnumDeclBits.NumNegativeBits;
   }
   void setNumNegativeBits(unsigned Num) {
-    NumNegativeBits = Num;
+    EnumDeclBits.NumNegativeBits = Num;
   }
 
   /// Returns true if this is a C++11 scoped enumeration.
   bool isScoped() const {
-    return IsScoped;
+    return EnumDeclBits.IsScoped;
+  }
+
+  /// True if this is a C++11 scoped enumeration.
+  void setScoped(bool Scoped = true) {
+    EnumDeclBits.IsScoped = Scoped;
   }
 
   /// Returns true if this is a C++11 scoped enumeration.
   bool isScopedUsingClassTag() const {
-    return IsScopedUsingClassTag;
+    return EnumDeclBits.IsScopedUsingClassTag;
+  }
+
+  /// True if this is a C++11 scoped enumeration.
+  void setScopedUsingClassTag(bool ScopedUCT = true) {
+    EnumDeclBits.IsScopedUsingClassTag = ScopedUCT;
   }
 
   /// Returns true if this is an Objective-C, C++11, or
   /// Microsoft-style enumeration with a fixed underlying type.
   bool isFixed() const {
-    return IsFixed;
+    return EnumDeclBits.IsFixed;
+  }
+
+  /// 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;
   }
 
   /// Returns true if this can be considered a complete type.
@@ -3557,7 +3529,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
@@ -3580,47 +3555,6 @@
     /// indirectly.
     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,
@@ -3647,8 +3581,12 @@
     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
@@ -3661,47 +3599,57 @@
   ///  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,
@@ -3712,19 +3660,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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to