Unifies the name-lookup mechanisms used in various parts of the AST
and separates lexical name lookup from qualified name lookup. In
particular:
  * Make DeclContext the central data structure for storing and
    looking up declarations within existing declarations, e.g., members
    of structs/unions/classes, enumerators in C++0x enums, members of
    C++ namespaces, and (later) members of Objective-C
    interfaces/implementations. DeclContext uses a lazily-constructed
    data structure optimized for fast lookup (array for small contexts,
    hash table for larger contexts). 

  * Implement C++ qualified name lookup in terms of lookup into
    DeclContext.

  * Implement C++ unqualified name lookup in terms of
    qualified+unqualified name lookup (since unqualified lookup is not
    purely lexical in C++!)

  * Limit the use of the chains of declarations stored in
    IdentifierInfo to those names declared lexically.

  * Eliminate CXXFieldDecl, collapsing its behavior into
    FieldDecl. (FieldDecl is now a ScopedDecl).

  * Make RecordDecl into a DeclContext and eliminates its
    Members/NumMembers fields (since one can just iterate through the
    DeclContext to get the fields).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60878 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/CXXFieldCollector.h b/lib/Sema/CXXFieldCollector.h
index 44d4826..69d1351 100644
--- a/lib/Sema/CXXFieldCollector.h
+++ b/lib/Sema/CXXFieldCollector.h
@@ -18,15 +18,15 @@
 #include "llvm/ADT/SmallVector.h"
 
 namespace clang {
-  class CXXFieldDecl;
+  class FieldDecl;
 
 /// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
 /// C++ classes.
 class CXXFieldCollector {
-  /// Fields - Contains all CXXFieldDecls collected during parsing of a C++
+  /// Fields - Contains all FieldDecls collected during parsing of a C++
   /// class. When a nested class is entered, its fields are appended to the
   /// fields of its parent class, when it is exited its fields are removed.
-  llvm::SmallVector<CXXFieldDecl*, 32> Fields;
+  llvm::SmallVector<FieldDecl*, 32> Fields;
 
   /// FieldCount - Each entry represents the number of fields collected during
   /// the parsing of a C++ class. When a nested class is entered, a new field
@@ -52,7 +52,7 @@
   void StartClass() { FieldCount.push_back(0); }
 
   /// Add - Called by Sema::ActOnCXXMemberDeclarator.
-  void Add(CXXFieldDecl *D) {
+  void Add(FieldDecl *D) {
     Fields.push_back(D);
     ++FieldCount.back();
   }
@@ -62,7 +62,7 @@
 
   /// getCurFields - Pointer to array of fields added to the currently parsed
   /// class.
-  CXXFieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
+  FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
 
   /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
   void FinishClass() {
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 5fb18f6..4441503 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -51,9 +51,6 @@
 DeclContext *IdentifierResolver::LookupContext::getContext(Decl *D) {
   DeclContext *Ctx;
 
-  if (CXXFieldDecl *FD = dyn_cast<CXXFieldDecl>(D))
-    return FD->getParent();
-
   if (EnumConstantDecl *EnumD = dyn_cast<EnumConstantDecl>(D)) {
     Ctx = EnumD->getDeclContext()->getParent();
   } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D))
@@ -149,7 +146,7 @@
 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
 /// true if 'D' belongs to the given declaration context.
 bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
-                                       Scope *S) const {
+                                       ASTContext &Context, Scope *S) const {
   if (Ctx->isFunctionOrMethod()) {
     if (S->isDeclScope(D))
       return true;
@@ -169,7 +166,7 @@
     return false;
   }
 
-  return LookupContext(D) == LookupContext(Ctx);
+  return LookupContext(D) == LookupContext(Ctx->getPrimaryContext(Context));
 }
 
 /// AddDecl - Link the decl to its shadowed decl chain.
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
index 9d78513..bc9da61 100644
--- a/lib/Sema/IdentifierResolver.h
+++ b/lib/Sema/IdentifierResolver.h
@@ -208,7 +208,8 @@
   /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
   /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
   /// true if 'D' belongs to the given declaration context.
-  bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) const;
+  bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context,
+                     Scope *S = 0) const;
 
   /// AddDecl - Link the decl to its shadowed decl chain.
   void AddDecl(NamedDecl *D);
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 13226c0..650b8d7 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -68,7 +68,7 @@
 
 void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
   TUScope = S;
-  PushDeclContext(Context.getTranslationUnitDecl());
+  PushDeclContext(S, Context.getTranslationUnitDecl());
   if (!PP.getLangOptions().ObjC1) return;
   
   // Synthesize "typedef struct objc_selector *SEL;"
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 4a8f830..97e8507 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -300,10 +300,10 @@
                          IdentifierInfo *Name, SourceLocation NameLoc,
                          AttributeList *Attr);  
   
-  virtual void ActOnDefs(Scope *S, SourceLocation DeclStart,
+  virtual void ActOnDefs(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
                          IdentifierInfo *ClassName,
                          llvm::SmallVectorImpl<DeclTy*> &Decls);
-  virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart,
+  virtual DeclTy *ActOnField(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
                              Declarator &D, ExprTy *BitfieldWidth);
   
   virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart,
@@ -326,7 +326,7 @@
   DeclContext *getContainingDC(DeclContext *DC);
 
   /// Set the current declaration context until it gets popped.
-  void PushDeclContext(DeclContext *DC);
+  void PushDeclContext(Scope *S, DeclContext *DC);
   void PopDeclContext();
   
   /// getCurFunctionDecl - If inside of a function body, this returns a pointer
@@ -351,7 +351,7 @@
   /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
   /// true if 'D' belongs to the given declaration context.
   bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) {
-    return IdResolver.isDeclInScope(D, Ctx, S);
+    return IdResolver.isDeclInScope(D, Ctx, Context, S);
   }
 
   /// Subroutines of ActOnDeclarator().
@@ -478,7 +478,8 @@
   /// More parsing and symbol table subroutines...
   Decl *LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
                    const DeclContext *LookupCtx = 0,
-                   bool enableLazyBuiltinCreation = true);
+                   bool enableLazyBuiltinCreation = true,
+                  bool LookInParent = true);
   ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
   ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, 
                                   Scope *S);
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 1f92b6f..d01552c 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -20,7 +20,25 @@
 

 namespace {

   Decl *LookupNestedName(DeclContext *LookupCtx, bool LookInParentCtx,

-                         DeclarationName Name, bool &IdIsUndeclared) {

+                         DeclarationName Name, bool &IdIsUndeclared,

+                        ASTContext &Context) {

+    if (LookupCtx && !LookInParentCtx) {

+      IdIsUndeclared = true;

+      for (DeclContext::lookup_const_result I = LookupCtx->lookup(Context, Name);

+          I.first != I.second; ++I.first) {

+       IdIsUndeclared = false;

+       if (((*I.first)->getIdentifierNamespace() & Decl::IDNS_Tag) &&

+           !isa<EnumDecl>(*I.first))

+         return *I.first;

+      }

+

+      return 0;

+    }

+

+    // FIXME: Decouple this from the IdentifierResolver so that we can

+    // deal with lookups into the semantic parent contexts that aren't

+    // lexical parent contexts.

+

     IdentifierResolver::iterator

       I = IdentifierResolver::begin(Name, LookupCtx, LookInParentCtx),

       E = IdentifierResolver::end();

@@ -73,10 +91,11 @@
   bool IdIsUndeclared;

 

   if (DC)

-    SD = LookupNestedName(DC, false/*LookInParentCtx*/, &II, IdIsUndeclared);

+    SD = LookupNestedName(DC, false/*LookInParentCtx*/, &II, IdIsUndeclared,

+                         Context);

   else

     SD = LookupNestedName(CurContext, true/*LookInParent*/, &II, 

-                          IdIsUndeclared);

+                          IdIsUndeclared, Context);

 

   if (SD) {

     if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {

diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 41587c5..b541f59 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -74,14 +74,16 @@
   return DC->getLexicalParent();
 }
 
-void Sema::PushDeclContext(DeclContext *DC) {
+void Sema::PushDeclContext(Scope *S, DeclContext *DC) {
   assert(getContainingDC(DC) == CurContext &&
       "The next DeclContext should be lexically contained in the current one.");
   CurContext = DC;
+  S->setEntity(DC);
 }
 
 void Sema::PopDeclContext() {
   assert(CurContext && "DeclContext imbalance!");
+
   CurContext = getContainingDC(CurContext);
 }
 
@@ -97,53 +99,90 @@
   //   in this case the class name or enumeration name is hidden.
   if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
     // We are pushing the name of a tag (enum or class).
-    IdentifierResolver::iterator
-        I = IdResolver.begin(TD->getIdentifier(),
-                             TD->getDeclContext(), false/*LookInParentCtx*/);
-    if (I != IdResolver.end() && isDeclInScope(*I, TD->getDeclContext(), S)) {
-      // There is already a declaration with the same name in the same
-      // scope. It must be found before we find the new declaration,
-      // so swap the order on the shadowed declaration chain.
+    if (CurContext == TD->getDeclContext()) {
+      // We're pushing the tag into the current context, which might
+      // require some reshuffling in the identifier resolver.
+      IdentifierResolver::iterator
+        I = IdResolver.begin(TD->getIdentifier(), CurContext, 
+                            false/*LookInParentCtx*/);
+      if (I != IdResolver.end()) {
+       // There is already a declaration with the same name in the same
+       // scope. It must be found before we find the new declaration,
+       // so swap the order on the shadowed declaration chain.
+       IdResolver.AddShadowedDecl(TD, *I);
 
-      IdResolver.AddShadowedDecl(TD, *I);
-      return;
+       // Add this declaration to the current context.
+       CurContext->addDecl(Context, TD);
+       
+       return;
+      }
     }
   } else if (getLangOptions().CPlusPlus && isa<FunctionDecl>(D)) {
-    FunctionDecl *FD = cast<FunctionDecl>(D);
     // We are pushing the name of a function, which might be an
     // overloaded name.
-    IdentifierResolver::iterator
-        I = IdResolver.begin(FD->getDeclName(),
-                             FD->getDeclContext(), false/*LookInParentCtx*/);
-    if (I != IdResolver.end() &&
-        IdResolver.isDeclInScope(*I, FD->getDeclContext(), S) &&
-        (isa<OverloadedFunctionDecl>(*I) || isa<FunctionDecl>(*I))) {
-      // There is already a declaration with the same name in the same
-      // scope. It must be a function or an overloaded function.
-      OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(*I);
+    FunctionDecl *FD = cast<FunctionDecl>(D);
+    Decl *Prev = LookupDecl(FD->getDeclName(), Decl::IDNS_Ordinary, S,
+                           FD->getDeclContext(), false, false);
+    if (Prev && (isa<OverloadedFunctionDecl>(Prev) || isa<FunctionDecl>(Prev))) {
+      // There is already a declaration with the same name in
+      // the same scope. It must be a function or an overloaded
+      // function.
+      OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(Prev);
       if (!Ovl) {
         // We haven't yet overloaded this function. Take the existing
         // FunctionDecl and put it into an OverloadedFunctionDecl.
         Ovl = OverloadedFunctionDecl::Create(Context, 
                                              FD->getDeclContext(),
                                              FD->getDeclName());
-        Ovl->addOverload(dyn_cast<FunctionDecl>(*I));
+        Ovl->addOverload(dyn_cast<FunctionDecl>(Prev));
         
-        // Remove the name binding to the existing FunctionDecl...
-        IdResolver.RemoveDecl(*I);
-
-        // ... and put the OverloadedFunctionDecl in its place.
+       // If there is an name binding for the existing FunctionDecl,
+       // remove it.
+       for (IdentifierResolver::iterator I 
+              = IdResolver.begin(FD->getDeclName(), FD->getDeclContext(), 
+                                 false/*LookInParentCtx*/);
+            I != IdResolver.end(); ++I) {
+         if (*I == Prev) {
+           IdResolver.RemoveDecl(*I);
+           S->RemoveDecl(*I);
+           break;
+         }
+       }
+       
+       // Add the name binding for the OverloadedFunctionDecl.
         IdResolver.AddDecl(Ovl);
+
+        // Update the context with the newly-created overloaded
+        // function set.
+        FD->getDeclContext()->insert(Context, Ovl);
+
+       S->AddDecl(Ovl);
       }
 
+      // We added this function declaration to the scope earlier, but
+      // we don't want it there because it is part of the overloaded
+      // function declaration.
+      S->RemoveDecl(FD);
+
       // We have an OverloadedFunctionDecl. Add the new FunctionDecl
       // to its list of overloads.
       Ovl->addOverload(FD);
 
-      return;
+      // Add this new function declaration to the declaration context.
+      CurContext->addDecl(Context, FD, false);
+
+      return;      
     }
   }
 
+  if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D))
+    CurContext->addDecl(Context, SD);
+  else {
+    // Other kinds of declarations don't currently have a context
+    // where they need to be inserted.
+  }
+
+
   IdResolver.AddDecl(D);
 }
 
@@ -157,25 +196,13 @@
     Decl *TmpD = static_cast<Decl*>(*I);
     assert(TmpD && "This decl didn't get pushed??");
 
-    if (isa<CXXFieldDecl>(TmpD)) continue;
+    assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
+    NamedDecl *D = cast<NamedDecl>(TmpD);
 
-    assert(isa<ScopedDecl>(TmpD) && "Decl isn't ScopedDecl?");
-    ScopedDecl *D = cast<ScopedDecl>(TmpD);
-    
-    IdentifierInfo *II = D->getIdentifier();
-    if (!II) continue;
-    
-    // We only want to remove the decls from the identifier decl chains for
-    // local scopes, when inside a function/method.
-    // However, we *always* remove template parameters, since they are
-    // purely lexically scoped (and can never be found by qualified
-    // name lookup).
-    if (S->getFnParent() != 0 || isa<TemplateTypeParmDecl>(D))
-      IdResolver.RemoveDecl(D);
+    if (!D->getDeclName()) continue;
 
-    // Chain this decl to the containing DeclContext.
-    D->setNext(CurContext->getDeclChain());
-    CurContext->setDeclChain(D);
+    // Remove this name from our lexical scope.
+    IdResolver.RemoveDecl(D);
   }
 }
 
@@ -193,21 +220,76 @@
 /// namespace.
 Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
                        const DeclContext *LookupCtx,
-                       bool enableLazyBuiltinCreation) {
+                       bool enableLazyBuiltinCreation,
+                      bool LookInParent) {
   if (!Name) return 0;
   unsigned NS = NSI;
   if (getLangOptions().CPlusPlus && (NS & Decl::IDNS_Ordinary))
     NS |= Decl::IDNS_Tag;
 
-  IdentifierResolver::iterator 
-    I = LookupCtx ? IdResolver.begin(Name, LookupCtx, false/*LookInParentCtx*/)
-                  : IdResolver.begin(Name, CurContext, true/*LookInParentCtx*/);
-  // Scan up the scope chain looking for a decl that matches this identifier
-  // that is in the appropriate namespace.  This search should not take long, as
-  // shadowing of names is uncommon, and deep shadowing is extremely uncommon.
-  for (; I != IdResolver.end(); ++I)
-    if ((*I)->getIdentifierNamespace() & NS)
-      return *I;
+  if (LookupCtx) {
+    assert(getLangOptions().CPlusPlus && "No qualified name lookup in C");
+
+    // Perform qualified name lookup into the LookupCtx.
+    // FIXME: Will need to look into base classes and such.
+    for (DeclContext::lookup_const_result I = LookupCtx->lookup(Context, Name);
+        I.first != I.second; ++I.first)
+      if ((*I.first)->getIdentifierNamespace() & NS)
+       return *I.first;
+  } else if (getLangOptions().CPlusPlus && 
+               (NS & (Decl::IDNS_Ordinary | Decl::IDNS_Tag))) {
+    // Name lookup for ordinary names and tag names in C++ requires
+    // looking into scopes that aren't strictly lexical, and
+    // therefore we walk through the context as well as walking
+    // through the scopes.
+    IdentifierResolver::iterator 
+      I = IdResolver.begin(Name, CurContext, true/*LookInParentCtx*/),
+      IEnd = IdResolver.end();
+    for (; S; S = S->getParent()) {
+      // Check whether the IdResolver has anything in this scope.
+      // FIXME: The isDeclScope check could be expensive. Can we do better?
+      for (; I != IEnd && S->isDeclScope(*I); ++I)
+        if ((*I)->getIdentifierNamespace() & NS)
+          return *I;
+      
+      // If there is an entity associated with this scope, it's a
+      // DeclContext. We might need to perform qualified lookup into
+      // it.
+      DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity());
+      while (Ctx && Ctx->isFunctionOrMethod())
+        Ctx = Ctx->getParent();
+      while (Ctx && (Ctx->isNamespace() || Ctx->isCXXRecord())) {
+        // Look for declarations of this name in this scope.
+        for (DeclContext::lookup_const_result I = Ctx->lookup(Context, Name);
+             I.first != I.second; ++I.first) {
+          // FIXME: Cache this result in the IdResolver
+          if ((*I.first)->getIdentifierNamespace() & NS)
+            return  *I.first;
+        }
+        
+        Ctx = Ctx->getParent();
+      }
+      
+      if (!LookInParent)
+        return 0;
+    }
+  } else {
+    // Unqualified name lookup for names in our lexical scope. This
+    // name lookup suffices when all of the potential names are known
+    // to have been pushed onto the IdResolver, as happens in C
+    // (always) and in C++ for names in the "label" namespace.
+    assert(!LookupCtx && "Can't perform qualified name lookup here");
+    IdentifierResolver::iterator I
+      = IdResolver.begin(Name, CurContext, LookInParent);
+    
+    // Scan up the scope chain looking for a decl that matches this
+    // identifier that is in the appropriate namespace.  This search
+    // should not take long, as shadowing of names is uncommon, and
+    // deep shadowing is extremely uncommon.
+    for (; I != IdResolver.end(); ++I)
+      if ((*I)->getIdentifierNamespace() & NS)
+         return *I;
+  }
 
   // If we didn't find a use of this identifier, and if the identifier
   // corresponds to a compiler builtin, create the decl object for the builtin
@@ -826,7 +908,8 @@
   
   // The scope passed in may not be a decl scope.  Zip up the scope tree until
   // we find one that is.
-  while ((S->getFlags() & Scope::DeclScope) == 0)
+  while ((S->getFlags() & Scope::DeclScope) == 0 ||
+        (S->getFlags() & Scope::TemplateParamScope) != 0)
     S = S->getParent();
   
   DeclContext *DC;
@@ -854,6 +937,7 @@
       // No previous declaration in the qualifying scope.
       Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member)
         << Name << D.getCXXScopeSpec().getRange();
+      InvalidDecl = true;
     } else if (!CurContext->Encloses(DC)) {
       // The qualifying scope doesn't enclose the original declaration.
       // Emit diagnostic based on current scope.
@@ -865,6 +949,7 @@
         Diag(L, diag::err_invalid_declarator_scope)
           << Name << cast<NamedDecl>(DC)->getDeclName() << R;
       }
+      InvalidDecl = true;
     }
   }
 
@@ -1127,23 +1212,42 @@
 
           if (OldDecl == PrevDecl) {
             // Remove the name binding for the previous
-            // declaration. We'll add the binding back later, but then
-            // it will refer to the new declaration (which will
-            // contain more information).
-            IdResolver.RemoveDecl(cast<NamedDecl>(PrevDecl));
+            // declaration.
+           if (S->isDeclScope(PrevDecl)) {
+             IdResolver.RemoveDecl(cast<NamedDecl>(PrevDecl));
+             S->RemoveDecl(PrevDecl);
+           }
+
+           // Introduce the new binding for this declaration.
+           IdResolver.AddDecl(NewFD);
+           if (getLangOptions().CPlusPlus && NewFD->getParent())
+             NewFD->getParent()->insert(Context, NewFD);
+
+           // Add the redeclaration to the current scope, since we'll
+           // be skipping PushOnScopeChains.
+           S->AddDecl(NewFD);
           } else {
             // We need to update the OverloadedFunctionDecl with the
             // latest declaration of this function, so that name
             // lookup will always refer to the latest declaration of
             // this function.
             *MatchedDecl = NewFD;
+         }
            
-            // Add the redeclaration to the current scope, since we'll
-            // be skipping PushOnScopeChains.
-            S->AddDecl(NewFD);
+          if (getLangOptions().CPlusPlus) {
+            // Add this declaration to the current context.
+            CurContext->addDecl(Context, NewFD, false);
 
-            return NewFD;
+            // Check default arguments now that we have merged decls.
+            CheckCXXDefaultArguments(NewFD);
           }
+
+         // Set the lexical context. If the declarator has a C++
+         // scope specifier, the lexical context will be different
+         // from the semantic context.
+         NewFD->setLexicalDeclContext(CurContext);
+
+         return NewFD;
         }
       }
     }
@@ -2071,7 +2175,7 @@
     parmDeclType = Context.getArrayDecayedType(parmDeclType);
   } else if (parmDeclType->isFunctionType())
     parmDeclType = Context.getPointerType(parmDeclType);
-  
+
   ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, 
                                          D.getIdentifierLoc(), II,
                                          parmDeclType, StorageClass, 
@@ -2079,9 +2183,11 @@
   
   if (D.getInvalidType())
     New->setInvalidDecl();
-    
+
+  // Add the parameter declaration into this scope.
+  S->AddDecl(New);
   if (II)
-    PushOnScopeChains(New, S);
+    IdResolver.AddDecl(New);
 
   ProcessDeclAttributes(New, D);
   return New;
@@ -2133,7 +2239,7 @@
     Diag(Definition->getLocation(), diag::note_previous_definition);
   }
 
-  PushDeclContext(FD);
+  PushDeclContext(FnBodyScope, FD);
     
   // Check the validity of our function parameters
   CheckParmsForFunctionDef(FD);
@@ -2573,17 +2679,19 @@
 
 /// Collect the instance variables declared in an Objective-C object.  Used in
 /// the creation of structures from objects using the @defs directive.
-static void CollectIvars(ObjCInterfaceDecl *Class, ASTContext& Ctx,
+static void CollectIvars(ObjCInterfaceDecl *Class, RecordDecl *Record,
+                         ASTContext& Ctx,
                          llvm::SmallVectorImpl<Sema::DeclTy*> &ivars) {
   if (Class->getSuperClass())
-    CollectIvars(Class->getSuperClass(), Ctx, ivars);
+    CollectIvars(Class->getSuperClass(), Record, Ctx, ivars);
   
   // For each ivar, create a fresh ObjCAtDefsFieldDecl.
   for (ObjCInterfaceDecl::ivar_iterator
         I=Class->ivar_begin(), E=Class->ivar_end(); I!=E; ++I) {
     
     ObjCIvarDecl* ID = *I;
-    ivars.push_back(ObjCAtDefsFieldDecl::Create(Ctx, ID->getLocation(),
+    ivars.push_back(ObjCAtDefsFieldDecl::Create(Ctx, Record,
+                                                ID->getLocation(),
                                                 ID->getIdentifier(),
                                                 ID->getType(),
                                                 ID->getBitWidth()));
@@ -2592,7 +2700,7 @@
 
 /// Called whenever @defs(ClassName) is encountered in the source.  Inserts the
 /// instance variables of ClassName into Decls.
-void Sema::ActOnDefs(Scope *S, SourceLocation DeclStart, 
+void Sema::ActOnDefs(Scope *S, DeclTy *TagD, SourceLocation DeclStart, 
                      IdentifierInfo *ClassName,
                      llvm::SmallVectorImpl<DeclTy*> &Decls) {
   // Check that ClassName is a valid class
@@ -2602,7 +2710,17 @@
     return;
   }
   // Collect the instance variables
-  CollectIvars(Class, Context, Decls);
+  CollectIvars(Class, dyn_cast<RecordDecl>((Decl*)TagD), Context, Decls);
+
+  // Introduce all of these fields into the appropriate scope.
+  for (llvm::SmallVectorImpl<DeclTy*>::iterator D = Decls.begin();
+       D != Decls.end(); ++D) {
+    FieldDecl *FD = cast<FieldDecl>((Decl*)*D);
+    if (getLangOptions().CPlusPlus)
+      PushOnScopeChains(cast<FieldDecl>(FD), S);
+    else if (RecordDecl *Record = dyn_cast<RecordDecl>((Decl*)TagD))
+      Record->addDecl(Context, FD);
+  }
 }
 
 /// TryToFixInvalidVariablyModifiedType - Helper method to turn variable array
@@ -2657,12 +2775,13 @@
 
 /// ActOnField - Each field of a struct/union/class is passed into this in order
 /// to create a FieldDecl object for it.
-Sema::DeclTy *Sema::ActOnField(Scope *S,
+Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
                                SourceLocation DeclStart, 
                                Declarator &D, ExprTy *BitfieldWidth) {
   IdentifierInfo *II = D.getIdentifier();
   Expr *BitWidth = (Expr*)BitfieldWidth;
   SourceLocation Loc = DeclStart;
+  RecordDecl *Record = (RecordDecl *)TagD;
   if (II) Loc = D.getIdentifierLoc();
   
   // FIXME: Unnamed fields can be handled in various different ways, for
@@ -2699,22 +2818,24 @@
   // FIXME: Chain fielddecls together.
   FieldDecl *NewFD;
 
-  if (getLangOptions().CPlusPlus) {
-    // FIXME: Replace CXXFieldDecls with FieldDecls for simple structs.
-    NewFD = CXXFieldDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
-                                 Loc, II, T,
-                                 D.getDeclSpec().getStorageClassSpec() ==
-                                   DeclSpec::SCS_mutable, BitWidth);
-    if (II)
-      PushOnScopeChains(NewFD, S);
-  }
-  else
-    NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
-  
+  // FIXME: We don't want CurContext for C, do we? No, we'll need some
+  // other way to determine the current RecordDecl.
+  NewFD = FieldDecl::Create(Context, Record,
+                            Loc, II, T, BitWidth,
+                            D.getDeclSpec().getStorageClassSpec() ==
+                              DeclSpec::SCS_mutable,
+                            /*PrevDecl=*/0);
+
   ProcessDeclAttributes(NewFD, D);
 
   if (D.getInvalidType() || InvalidDecl)
     NewFD->setInvalidDecl();
+
+  if (II && getLangOptions().CPlusPlus)
+    PushOnScopeChains(NewFD, S);
+  else
+    Record->addDecl(Context, NewFD);
+
   return NewFD;
 }
 
@@ -2921,7 +3042,7 @@
  
   // Okay, we successfully defined 'Record'.
   if (Record) {
-    Record->defineBody(Context, &RecFields[0], RecFields.size());
+    Record->completeDefinition(Context);
     // If this is a C++ record, HandleTagDeclDefinition will be invoked in
     // Sema::ActOnFinishCXXClassDef.
     if (!isa<CXXRecordDecl>(Record))
@@ -3189,7 +3310,7 @@
     ECD->setType(NewTy);
   }
   
-  Enum->defineElements(EltList, BestType);
+  Enum->completeDefinition(Context, BestType);
   Consumer.HandleTagDeclDefinition(Enum);
 }
 
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index bff650d..5c2b494 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -904,8 +904,10 @@
 
   // FIXME: This isn't supposed to be restricted to pointers, but otherwise
   // we might silently generate incorrect code; see following code
-  for (int i = 0; i < RD->getNumMembers(); i++) {
-    if (!RD->getMember(i)->getType()->isPointerType()) {
+  for (RecordDecl::field_iterator Field = RD->field_begin(),
+                               FieldEnd = RD->field_end();
+       Field != FieldEnd; ++Field) {
+    if (!Field->getType()->isPointerType()) {
       S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
       return;
     }
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index bedf3f7..31ecfba 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -382,7 +382,7 @@
 /// definition, when on C++.
 void Sema::ActOnStartCXXClassDef(Scope *S, DeclTy *D, SourceLocation LBrace) {
   CXXRecordDecl *Dcl = cast<CXXRecordDecl>(static_cast<Decl *>(D));
-  PushDeclContext(Dcl);
+  PushDeclContext(S, Dcl);
   FieldCollector->StartClass();
 
   if (Dcl->getIdentifier()) {
@@ -486,7 +486,8 @@
   bool InvalidDecl = false;
 
   if (isInstField)
-    Member = static_cast<Decl*>(ActOnField(S, Loc, D, BitWidth));
+    Member = static_cast<Decl*>(ActOnField(S, cast<CXXRecordDecl>(CurContext), 
+                                           Loc, D, BitWidth));
   else
     Member = static_cast<Decl*>(ActOnDeclarator(S, D, LastInGroup));
 
@@ -593,7 +594,7 @@
     Member->setInvalidDecl();
 
   if (isInstField) {
-    FieldCollector->Add(cast<CXXFieldDecl>(Member));
+    FieldCollector->Add(cast<FieldDecl>(Member));
     return LastInGroup;
   }
   return Member;
@@ -632,7 +633,10 @@
   //   mem-initializer-id for the hidden base class may be specified
   //   using a qualified name. ]
   // Look for a member, first.
-  CXXFieldDecl *Member = ClassDecl->getMember(MemberOrBase);
+  FieldDecl *Member = 0;
+  DeclContext::lookup_result Result = ClassDecl->lookup(Context, MemberOrBase);
+  if (Result.first != Result.second)
+    Member = dyn_cast<FieldDecl>(*Result.first);
 
   // FIXME: Handle members of an anonymous union.
 
@@ -1251,43 +1255,42 @@
     // in that declarative region, it is treated as an original-namespace-name.
 
     Decl *PrevDecl =
-        LookupDecl(II, Decl::IDNS_Tag | Decl::IDNS_Ordinary, DeclRegionScope, 0,
-                   /*enableLazyBuiltinCreation=*/false);
+      LookupDecl(II, Decl::IDNS_Tag | Decl::IDNS_Ordinary, DeclRegionScope, 0,
+                /*enableLazyBuiltinCreation=*/false, 
+                /*LookupInParent=*/false);
+    
+    if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
+      // This is an extended namespace definition.
+      // Attach this namespace decl to the chain of extended namespace
+      // definitions.
+      OrigNS->setNextNamespace(Namespc);
+      Namespc->setOriginalNamespace(OrigNS->getOriginalNamespace());
 
-    if (PrevDecl && isDeclInScope(PrevDecl, CurContext, DeclRegionScope)) {
-      if (NamespaceDecl *OrigNS = dyn_cast<NamespaceDecl>(PrevDecl)) {
-        // This is an extended namespace definition.
-        // Attach this namespace decl to the chain of extended namespace
-        // definitions.
-        NamespaceDecl *NextNS = OrigNS;
-        while (NextNS->getNextNamespace())
-          NextNS = NextNS->getNextNamespace();
-
-        NextNS->setNextNamespace(Namespc);
-        Namespc->setOriginalNamespace(OrigNS);
-
-        // We won't add this decl to the current scope. We want the namespace
-        // name to return the original namespace decl during a name lookup.
-      } else {
-        // This is an invalid name redefinition.
-        Diag(Namespc->getLocation(), diag::err_redefinition_different_kind)
-          << Namespc->getDeclName();
-        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-        Namespc->setInvalidDecl();
-        // Continue on to push Namespc as current DeclContext and return it.
+      // Remove the previous declaration from the scope.      
+      if (DeclRegionScope->isDeclScope(OrigNS)) {
+       IdResolver.RemoveDecl(OrigNS);
+       DeclRegionScope->RemoveDecl(OrigNS);
       }
-    } else {
-      // This namespace name is declared for the first time.
-      PushOnScopeChains(Namespc, DeclRegionScope);
-    }
-  }
-  else {
+    } else if (PrevDecl) {
+      // This is an invalid name redefinition.
+      Diag(Namespc->getLocation(), diag::err_redefinition_different_kind)
+       << Namespc->getDeclName();
+      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      Namespc->setInvalidDecl();
+      // Continue on to push Namespc as current DeclContext and return it.
+    } 
+
+    PushOnScopeChains(Namespc, DeclRegionScope);
+  } else {
     // FIXME: Handle anonymous namespaces
   }
 
   // Although we could have an invalid decl (i.e. the namespace name is a
   // redefinition), push it as current DeclContext and try to continue parsing.
-  PushDeclContext(Namespc->getOriginalNamespace());
+  // FIXME: We should be able to push Namespc here, so that the
+  // each DeclContext for the namespace has the declarations
+  // that showed up in that particular namespace definition.
+  PushDeclContext(NamespcScope, Namespc);
   return Namespc;
 }
 
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index fa73bcf..d135724 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -36,7 +36,7 @@
     AddFactoryMethodToGlobalPool(MDecl);
   
   // Allow all of Sema to see that we are entering a method definition.
-  PushDeclContext(MDecl);
+  PushDeclContext(FnBodyScope, MDecl);
 
   // Create Decl objects for each parameter, entrring them in the scope for
   // binding to their use.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index b254254..ba5d28a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -453,13 +453,13 @@
     }
   }
   
-  if (CXXFieldDecl *FD = dyn_cast<CXXFieldDecl>(D)) {
+  if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
       if (MD->isStatic())
         // "invalid use of member 'x' in static member function"
         return Diag(Loc, diag::err_invalid_member_use_in_static_method)
            << FD->getDeclName();
-      if (cast<CXXRecordDecl>(MD->getParent()) != FD->getParent())
+      if (MD->getParent() != FD->getDeclContext())
         // "invalid use of nonstatic data member 'x'"
         return Diag(Loc, diag::err_invalid_non_static_member_use)
           << FD->getDeclName();
@@ -1231,20 +1231,28 @@
       return Diag(OpLoc, diag::err_typecheck_incomplete_tag)
                << RDecl->getDeclName() << BaseExpr->getSourceRange();
     // The record definition is complete, now make sure the member is valid.
-    FieldDecl *MemberDecl = RDecl->getMember(&Member);
-    if (!MemberDecl)
+    // FIXME: Qualified name lookup for C++ is a bit more complicated
+    // than this.
+    DeclContext::lookup_result Lookup = RDecl->lookup(Context, &Member);
+    if (Lookup.first == Lookup.second) {
       return Diag(MemberLoc, diag::err_typecheck_no_member)
                << &Member << BaseExpr->getSourceRange();
+    } 
+
+    FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
+    if (!MemberDecl) {
+      unsigned DiagID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error,
+                          "Clang only supports references to members");
+      return Diag(MemberLoc, DiagID);
+    }
 
     // Figure out the type of the member; see C99 6.5.2.3p3
     // FIXME: Handle address space modifiers
     QualType MemberType = MemberDecl->getType();
     unsigned combinedQualifiers =
         MemberType.getCVRQualifiers() | BaseType.getCVRQualifiers();
-    if (CXXFieldDecl *CXXMember = dyn_cast<CXXFieldDecl>(MemberDecl)) {
-      if (CXXMember->isMutable())
-        combinedQualifiers &= ~QualType::Const;
-    }
+    if (MemberDecl->isMutable())
+      combinedQualifiers &= ~QualType::Const;
     MemberType = MemberType.getQualifiedType(combinedQualifiers);
 
     return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl,
@@ -3484,7 +3492,11 @@
       
     // Get the decl corresponding to this.
     RecordDecl *RD = RC->getDecl();
-    FieldDecl *MemberDecl = RD->getMember(OC.U.IdentInfo);
+    FieldDecl *MemberDecl = 0;
+    DeclContext::lookup_result Lookup = RD->lookup(Context, OC.U.IdentInfo);
+    if (Lookup.first != Lookup.second)
+      MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
+
     if (!MemberDecl)
       return Diag(BuiltinLoc, diag::err_typecheck_no_member)
        << OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd);
@@ -3552,7 +3564,7 @@
   BSI->TheScope = BlockScope;
   
   BSI->TheDecl = BlockDecl::Create(Context, CurContext, CaretLoc);
-  PushDeclContext(BSI->TheDecl);
+  PushDeclContext(BlockScope, BSI->TheDecl);
 }
 
 void Sema::ActOnBlockArguments(Declarator &ParamInfo) {
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 27b0ba3..a32a6f6 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -412,9 +412,8 @@
                                   DeclContext *Ctx, bool AllowMissing,
                                   FunctionDecl *&Operator)
 {
-  IdentifierResolver::iterator I =
-    IdResolver.begin(Name, Ctx, /*LookInParentCtx=*/false);
-  if (I == IdResolver.end()) {
+  DeclContext::lookup_result Lookup = Ctx->lookup(Context, Name);
+  if (Lookup.first == Lookup.second) {
     if (AllowMissing)
       return false;
     // FIXME: Bad location information.
@@ -423,7 +422,7 @@
   }
 
   OverloadCandidateSet Candidates;
-  NamedDecl *Decl = *I;
+  NamedDecl *Decl = *Lookup.first;
   // Even member operator new/delete are implicitly treated as static, so don't
   // use AddMemberCandidate.
   if (FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(Decl))
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 42f9b14..f36d3a5 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -15,6 +15,8 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/Diagnostic.h"
+#include <algorithm> // for std::count_if
+#include <functional> // for std::mem_fun
 
 namespace clang {
 
@@ -39,10 +41,9 @@
 
 int InitListChecker::numStructUnionElements(QualType DeclType) {
   RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
-  int InitializableMembers = 0;
-  for (int i = 0; i < structDecl->getNumMembers(); i++)
-    if (structDecl->getMember(i)->getIdentifier())
-      ++InitializableMembers;
+  int InitializableMembers 
+    = std::count_if(structDecl->field_begin(), structDecl->field_end(),
+                    std::mem_fun(&FieldDecl::getDeclName));
   if (structDecl->isUnion())
     return std::min(InitializableMembers, 1);
   return InitializableMembers - structDecl->hasFlexibleArrayMember();
@@ -286,21 +287,28 @@
   // If structDecl is a forward declaration, this loop won't do anything;
   // That's okay, because an error should get printed out elsewhere. It
   // might be worthwhile to skip over the rest of the initializer, though.
-  int numMembers = DeclType->getAsRecordType()->getDecl()->getNumMembers() -
-                   structDecl->hasFlexibleArrayMember();
-  for (int i = 0; i < numMembers; i++) {
+  RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
+  for (RecordDecl::field_iterator Field = RD->field_begin(),
+                               FieldEnd = RD->field_end();
+       Field != FieldEnd; ++Field) {
+    // If we've hit the flexible array member at the end, we're done.
+    if (Field->getType()->isIncompleteArrayType())
+      break;
+
     // Don't attempt to go past the end of the init list
     if (Index >= IList->getNumInits())
       break;
-    FieldDecl * curField = structDecl->getMember(i);
-    if (!curField->getIdentifier()) {
+
+    if (!Field->getIdentifier()) {
       // Don't initialize unnamed fields, e.g. "int : 20;"
       continue;
     }
-    CheckSubElementType(IList, curField->getType(), Index);
+
+    CheckSubElementType(IList, Field->getType(), Index);
     if (DeclType->isUnionType())
       break;
   }
+
   // FIXME: Implement flexible array initialization GCC extension (it's a 
   // really messy extension to implement, unfortunately...the necessary
   // information isn't actually even here!)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 8a68d5b..307abe3 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1955,10 +1955,9 @@
   //        (13.3.1.1.1); otherwise, the set of member candidates is
   //        empty.
   if (const RecordType *T1Rec = T1->getAsRecordType()) {
-    IdentifierResolver::iterator I 
-      = IdResolver.begin(OpName, cast<CXXRecordType>(T1Rec)->getDecl(), 
-                         /*LookInParentCtx=*/false);
-    NamedDecl *MemberOps = (I == IdResolver.end())? 0 : *I;
+    DeclContext::lookup_const_result Lookup 
+      = cast<CXXRecordType>(T1Rec)->getDecl()->lookup(Context, OpName);
+    NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first;
     if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps))
       AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet,
                          /*SuppressUserConversions=*/false);
@@ -3118,11 +3117,10 @@
   //  ordinary lookup of the name operator() in the context of
   //  (E).operator().
   OverloadCandidateSet CandidateSet;
-  IdentifierResolver::iterator I 
-    = IdResolver.begin(Context.DeclarationNames.getCXXOperatorName(OO_Call), 
-                       cast<CXXRecordType>(Record)->getDecl(), 
-                       /*LookInParentCtx=*/false);
-  NamedDecl *MemberOps = (I == IdResolver.end())? 0 : *I;
+  DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
+  DeclContext::lookup_const_result Lookup 
+    = cast<CXXRecordType>(Record)->getDecl()->lookup(Context, OpName);
+  NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first;
   if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps))
     AddMethodCandidate(Method, Object, Args, NumArgs, CandidateSet,
                        /*SuppressUserConversions=*/false);
@@ -3315,10 +3313,9 @@
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow);
   OverloadCandidateSet CandidateSet;
   const RecordType *BaseRecord = Base->getType()->getAsRecordType();
-  IdentifierResolver::iterator I
-    = IdResolver.begin(OpName, cast<CXXRecordType>(BaseRecord)->getDecl(),
-                       /*LookInParentCtx=*/false);
-  NamedDecl *MemberOps = (I == IdResolver.end())? 0 : *I;
+  DeclContext::lookup_const_result Lookup 
+    = cast<CXXRecordType>(BaseRecord)->getDecl()->lookup(Context, OpName);
+  NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first;
   if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps))
     AddMethodCandidate(Method, Base, 0, 0, CandidateSet,
                        /*SuppressUserConversions=*/false);