[cfe-commits] r60878 - in /cfe/trunk: Driver/ include/clang/AST/ include/clang/Parse/ lib/AST/ lib/Analysis/ lib/CodeGen/ lib/Parse/ lib/Sema/ test/SemaCXX/

Douglas Gregor dgregor at apple.com
Thu Dec 11 08:49:31 PST 2008


Author: dgregor
Date: Thu Dec 11 10:49:14 2008
New Revision: 60878

URL: http://llvm.org/viewvc/llvm-project?rev=60878&view=rev
Log:
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).


Added:
    cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp
Modified:
    cfe/trunk/Driver/PrintParserCallbacks.cpp
    cfe/trunk/Driver/RewriteObjC.cpp
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/AST/DeclarationName.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Scope.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/AST/DeclSerialization.cpp
    cfe/trunk/lib/AST/DeclarationName.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/Analysis/RegionStore.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/CXXFieldCollector.h
    cfe/trunk/lib/Sema/IdentifierResolver.cpp
    cfe/trunk/lib/Sema/IdentifierResolver.h
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/namespace.cpp

Modified: cfe/trunk/Driver/PrintParserCallbacks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/PrintParserCallbacks.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/Driver/PrintParserCallbacks.cpp (original)
+++ cfe/trunk/Driver/PrintParserCallbacks.cpp Thu Dec 11 10:49:14 2008
@@ -185,13 +185,14 @@
   
     /// Act on @defs() element found when parsing a structure.  ClassName is the
     /// name of the referenced class.   
-    virtual void ActOnDefs(Scope *S, SourceLocation DeclStart,
+    virtual void ActOnDefs(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
                            IdentifierInfo *ClassName,
                            llvm::SmallVectorImpl<DeclTy*> &Decls) {
       llvm::cout << __FUNCTION__ << "\n";
     }
 
-    virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart,
+    virtual DeclTy *ActOnField(Scope *S, DeclTy *TagD, 
+                               SourceLocation DeclStart,
                                Declarator &D, ExprTy *BitfieldWidth) {
       llvm::cout << __FUNCTION__ << "\n";
       return 0;

Modified: cfe/trunk/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteObjC.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteObjC.cpp (original)
+++ cfe/trunk/Driver/RewriteObjC.cpp Thu Dec 11 10:49:14 2008
@@ -2169,14 +2169,18 @@
     FieldTypes[0] = Context->getObjCIdType();  
     // struct objc_class *super;
     FieldTypes[1] = Context->getObjCClassType();  
+
     // Create fields
-    FieldDecl *FieldDecls[2];
-  
-    for (unsigned i = 0; i < 2; ++i)
-      FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0, 
-                                        FieldTypes[i]);
+    for (unsigned i = 0; i < 2; ++i) {
+      SuperStructDecl->addDecl(*Context, 
+                               FieldDecl::Create(*Context, SuperStructDecl, 
+                                                 SourceLocation(), 0, 
+                                                 FieldTypes[i], /*BitWidth=*/0,
+                                                 /*Mutable=*/false, 0),
+                               true);
+    }
   
-    SuperStructDecl->defineBody(*Context, FieldDecls, 4);
+    SuperStructDecl->completeDefinition(*Context);
   }
   return Context->getTagDeclType(SuperStructDecl);
 }
@@ -2196,14 +2200,20 @@
     FieldTypes[2] = Context->getPointerType(Context->CharTy);  
     // long length;
     FieldTypes[3] = Context->LongTy;  
+
     // Create fields
-    FieldDecl *FieldDecls[4];
-  
-    for (unsigned i = 0; i < 4; ++i)
-      FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0,
-                                        FieldTypes[i]);
-  
-    ConstantStringDecl->defineBody(*Context, FieldDecls, 4);
+    for (unsigned i = 0; i < 4; ++i) {
+      ConstantStringDecl->addDecl(*Context, 
+                                  FieldDecl::Create(*Context, 
+                                                    ConstantStringDecl, 
+                                                    SourceLocation(), 0,
+                                                    FieldTypes[i], 
+                                                    /*BitWidth=*/0,
+                                                    /*Mutable=*/true, 0),
+                                  true);
+    }
+
+    ConstantStringDecl->completeDefinition(*Context);
   }
   return Context->getTagDeclType(ConstantStringDecl);
 }
@@ -3788,8 +3798,9 @@
   ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), BlkCast);
   //PE->dump();
   
-  FieldDecl *FD = FieldDecl::Create(*Context, SourceLocation(),
-                     &Context->Idents.get("FuncPtr"), Context->VoidPtrTy);
+  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
+                     &Context->Idents.get("FuncPtr"), Context->VoidPtrTy, 
+                                    /*BitWidth=*/0, /*Mutable=*/true, 0);
   MemberExpr *ME = new MemberExpr(PE, true, FD, SourceLocation(), FD->getType());
   
   CastExpr *FunkCast = new CStyleCastExpr(PtrToFuncCastType, ME, PtrToFuncCastType, SourceLocation(), SourceLocation());

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Dec 11 10:49:14 2008
@@ -513,10 +513,12 @@
   void InitBuiltinTypes();
   void InitBuiltinType(QualType &R, BuiltinType::Kind K);
   
-  /// setRecordDefinition - Used by RecordDecl::defineBody to inform ASTContext
-  ///  about which RecordDecl serves as the definition of a particular
-  ///  struct/union/class.  This will eventually be used by enums as well.
+  /// setTagDefinition - Used by RecordDecl::completeDefinition and
+  /// EnumDecl::completeDefinition to inform 
+  /// about which RecordDecl/EnumDecl serves as the definition of a particular
+  /// struct/union/class/enum.
   void setTagDefinition(TagDecl* R);
+  friend class EnumDecl;
   friend class RecordDecl;
 
   // Return the ObjC type encoding for a given type.

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu Dec 11 10:49:14 2008
@@ -115,12 +115,6 @@
   /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
   ScopedDecl *NextDeclarator;
   
-  /// When this decl is in scope while parsing, the Next field contains a
-  /// pointer to the shadowed decl of the same name.  When the scope is popped,
-  /// Decls are relinked onto a containing decl object.
-  ///
-  ScopedDecl *Next;
-
   /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
   /// For declarations that don't contain C++ scope specifiers, it contains
   /// the DeclContext where the ScopedDecl was declared.
@@ -150,7 +144,7 @@
 protected:
   ScopedDecl(Kind DK, DeclContext *DC, SourceLocation L,
              DeclarationName N, ScopedDecl *PrevDecl)
-    : NamedDecl(DK, L, N), NextDeclarator(PrevDecl), Next(0),
+    : NamedDecl(DK, L, N), NextDeclarator(PrevDecl),
       DeclCtx(reinterpret_cast<uintptr_t>(DC)) {}
 
   virtual ~ScopedDecl();
@@ -188,9 +182,6 @@
 
   void setLexicalDeclContext(DeclContext *DC);
 
-  ScopedDecl *getNext() const { return Next; }
-  void setNext(ScopedDecl *N) { Next = N; }
-  
   /// getNextDeclarator - If this decl was part of a multi-declarator
   /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
   /// declarator.  Otherwise it returns null.
@@ -680,22 +671,31 @@
 
 /// FieldDecl - An instance of this class is created by Sema::ActOnField to 
 /// represent a member of a struct/union/class.
-class FieldDecl : public NamedDecl {
+class FieldDecl : public ScopedDecl {
+  bool Mutable : 1;
   QualType DeclType;  
   Expr *BitWidth;
 protected:
-  FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
-            Expr *BW = NULL)
-    : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW) {}
-  FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW)
-    : NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {}
+  FieldDecl(Kind DK, DeclContext *DC, SourceLocation L, 
+            IdentifierInfo *Id, QualType T, Expr *BW, bool Mutable, 
+            ScopedDecl *PrevDecl)
+    : ScopedDecl(DK, DC, L, Id, PrevDecl), Mutable(Mutable), DeclType(T), 
+      BitWidth(BW)
+      { }
+
 public:
-  static FieldDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
-                           QualType T, Expr *BW = NULL);
+  static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, 
+                           IdentifierInfo *Id, QualType T, Expr *BW, 
+                           bool Mutable, ScopedDecl *PrevDecl);
 
   QualType getType() const { return DeclType; }
-  
+
+  /// isMutable - Determines whether this field is mutable (C++ only).
+  bool isMutable() const { return Mutable; }
+
+  /// isBitfield - Determines whether this field is a bitfield.
   bool isBitField() const { return BitWidth != NULL; }
+
   Expr *getBitWidth() const { return BitWidth; }
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
@@ -888,9 +888,6 @@
 /// EnumDecl - Represents an enum.  As an extension, we allow forward-declared
 /// enums.
 class EnumDecl : public TagDecl, public DeclContext {
-  // EnumDecl's DeclChain points to a linked list of EnumConstantDecl's which
-  // are linked together through their getNextDeclarator pointers.
-
   /// IntegerType - 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.
@@ -908,30 +905,46 @@
   
   virtual void Destroy(ASTContext& C);
 
-  /// defineElements - When created, EnumDecl correspond to a forward declared
-  /// enum.  This method is used to mark the decl as being defined, with the
-  /// specified list of enums.
-  void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
-    assert(!isDefinition() && "Cannot redefine enums!");
-    setDeclChain(ListHead);
-    setDefinition(true);
-    
-    IntegerType = NewType;
+  /// completeDefinition - When created, the EnumDecl corresponds to a
+  /// forward-declared enum. This method is used to mark the
+  /// declaration as being defined; it's enumerators have already been
+  /// added (via DeclContext::addDecl). NewType is the new underlying
+  /// type of the enumeration type.
+  void completeDefinition(ASTContext &C, QualType NewType);
+  
+  // enumerator_iterator - Iterates through the enumerators of this
+  // enumeration.
+  struct enumerator_iterator : public DeclContext::decl_iterator {
+    typedef EnumConstantDecl* value_type;
+    typedef EnumConstantDecl* reference;
+    typedef EnumConstantDecl* pointer;
+
+    enumerator_iterator() : DeclContext::decl_iterator() { }
+
+    explicit enumerator_iterator(DeclContext::decl_iterator Pos)
+      : DeclContext::decl_iterator(Pos) { }
+
+    reference operator*() const { 
+      return cast<EnumConstantDecl>(DeclContext::decl_iterator::operator*());
+    }
+
+    pointer operator->() const {
+      return cast<EnumConstantDecl>(DeclContext::decl_iterator::operator*());
+    }
+  };
+
+  enumerator_iterator enumerator_begin() const { 
+    return enumerator_iterator(this->decls_begin());
   }
-  
+
+  enumerator_iterator enumerator_end() const { 
+    return enumerator_iterator(this->decls_end());
+  }
+
   /// getIntegerType - Return the integer type this enum decl corresponds to.
   /// This returns a null qualtype for an enum forward definition.
   QualType getIntegerType() const { return IntegerType; }
-  
-  /// getEnumConstantList - Return the first EnumConstantDecl in the enum.
-  ///
-  EnumConstantDecl *getEnumConstantList() {
-    return cast_or_null<EnumConstantDecl>(getDeclChain());
-  }
-  const EnumConstantDecl *getEnumConstantList() const {
-    return cast_or_null<const EnumConstantDecl>(getDeclChain());
-  }
-  
+    
   static bool classof(const Decl *D) { return D->getKind() == Enum; }
   static bool classof(const EnumDecl *D) { return true; }
   static DeclContext *castToDeclContext(const EnumDecl *D) {
@@ -957,16 +970,12 @@
 ///   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 {
+class RecordDecl : public TagDecl, public DeclContext {
   /// HasFlexibleArrayMember - 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.
   bool HasFlexibleArrayMember : 1;
   
-  /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
-  FieldDecl **Members;   // Null if not defined.
-  int NumMembers;   // -1 if not defined.
-
 protected:
   RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
              SourceLocation L, IdentifierInfo *Id);
@@ -993,42 +1002,74 @@
     return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
   }
   
-  /// getNumMembers - Return the number of members, or -1 if this is a forward
-  /// definition.
-  int getNumMembers() const { return NumMembers; }
-  const FieldDecl *getMember(unsigned i) const { return Members[i]; }
-  FieldDecl *getMember(unsigned i) { return Members[i]; }
-
   // Iterator access to field members.
-  typedef FieldDecl **field_iterator;
-  typedef FieldDecl * const *field_const_iterator;
+  class field_iterator {
+    /// Current - Current position within the sequence of declarations
+    /// in this record. 
+    DeclContext::decl_iterator Current;
+
+    /// End - Last position in the sequence of declarations in this
+    /// record.
+    DeclContext::decl_iterator End;
+
+    /// SkipToNextField - Advances the current position up to the next
+    /// FieldDecl.
+    void SkipToNextField() {
+      while (Current != End && !isa<FieldDecl>(*Current))
+        ++Current;
+    }
 
-  field_iterator field_begin() {
-    assert(isDefinition() && "Not a definition!");
-    return Members;
-  }
-  field_iterator field_end() {
-    assert(isDefinition() && "Not a definition!");
-    return Members + getNumMembers();
-  }
+  public:
+    typedef FieldDecl*                value_type;
+    typedef FieldDecl*                reference;
+    typedef FieldDecl*                pointer;
+    typedef std::ptrdiff_t            difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    field_iterator() : Current(), End() { }
+
+    field_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
+      : Current(C), End(E) {
+      SkipToNextField();
+    }
+
+    reference operator*() const { return cast<FieldDecl>(*Current); }
+
+    pointer operator->() const { return cast<FieldDecl>(*Current); }
 
-  field_const_iterator field_begin() const {
-    assert(isDefinition() && "Not a definition!");
-    return Members;
+    field_iterator& operator++() {
+      ++Current;
+      SkipToNextField();
+      return *this;
+    }
+
+    field_iterator operator++(int) {
+      field_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(const field_iterator& x, const field_iterator& y) {
+      return x.Current == y.Current;
+    }
+
+    friend bool operator!=(const field_iterator& x, const field_iterator& y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  typedef field_iterator field_const_iterator;
+
+  field_iterator field_begin() const {
+    return field_iterator(decls_begin(), decls_end());
   }
-  field_const_iterator field_end() const {
-    assert(isDefinition() && "Not a definition!");
-    return Members + getNumMembers();
+  field_iterator field_end() const {
+    return field_iterator(decls_end(), decls_end());
   }
 
-  /// defineBody - When created, RecordDecl's correspond to a forward declared
-  /// record.  This method is used to mark the decl as being defined, with the
-  /// specified contents.
-  void defineBody(ASTContext& C, FieldDecl **Members, unsigned numMembers);
-
-  /// getMember - If the member doesn't exist, or there are no members, this 
-  /// function will return 0;
-  FieldDecl *getMember(IdentifierInfo *name);
+  /// completeDefinition - Notes that the definition of this type is
+  /// now complete.
+  void completeDefinition(ASTContext& C);
 
   static bool classof(const Decl *D) {
     return D->getKind() >= RecordFirst && D->getKind() <= RecordLast;

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Thu Dec 11 10:49:14 2008
@@ -17,11 +17,14 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <vector>
 
 namespace clang {
 class DeclContext;
 class TranslationUnitDecl;
 class NamespaceDecl;
+class NamedDecl;
 class ScopedDecl;
 class FunctionDecl;
 class CXXRecordDecl;
@@ -29,6 +32,7 @@
 class ObjCMethodDecl;
 class ObjCInterfaceDecl;
 class BlockDecl;
+class DeclarationName;
 
 /// Decl - This represents one declaration (or definition), e.g. a variable, 
 /// typedef, function, struct, etc.  
@@ -44,10 +48,6 @@
     // Decl
          TranslationUnit,  // [DeclContext]
     //   NamedDecl
-           Field,
-             CXXField,
-             ObjCIvar,
-             ObjCAtDefsField,
            OverloadedFunction,
            ObjCCategory,
            ObjCCategoryImpl,
@@ -56,13 +56,16 @@
            ObjCProtocol,
            ObjCProperty,
     //     ScopedDecl
+             Field,
+               ObjCIvar,
+               ObjCAtDefsField,
              Namespace,  // [DeclContext]
     //       TypeDecl
                Typedef,
     //         TagDecl
                  Enum,  // [DeclContext]
-                 Record,
-                   CXXRecord,  // [DeclContext]
+                 Record, // [DeclContext]
+                   CXXRecord,  
  	       TemplateTypeParm,
     //       ValueDecl
                EnumConstant,
@@ -87,9 +90,9 @@
   
     // For each non-leaf class, we now define a mapping to the first/last member
     // of the class, to allow efficient classof.
-    NamedFirst     = Field        , NamedLast     = NonTypeTemplateParm,
+    NamedFirst     = OverloadedFunction , NamedLast     = NonTypeTemplateParm,
     FieldFirst     = Field        , FieldLast     = ObjCAtDefsField,
-    ScopedFirst    = Namespace    , ScopedLast    = NonTypeTemplateParm,
+    ScopedFirst    = Field        , ScopedLast    = NonTypeTemplateParm,
     TypeFirst      = Typedef      , TypeLast      = TemplateTypeParm,
     TagFirst       = Enum         , TagLast       = CXXRecord,
     RecordFirst    = Record       , RecordLast    = CXXRecord,
@@ -183,10 +186,10 @@
     case ParmVar:
     case EnumConstant:
     case NonTypeTemplateParm:
+    case Field:
     case ObjCInterface:
     case ObjCCompatibleAlias:
     case OverloadedFunction:
-    case CXXField:
     case CXXMethod:
     case CXXConversion:
     case CXXClassVar:
@@ -247,7 +250,7 @@
 ///   TranslationUnitDecl
 ///   NamespaceDecl
 ///   FunctionDecl
-///   CXXRecordDecl
+///   RecordDecl/CXXRecordDecl
 ///   EnumDecl
 ///   ObjCMethodDecl
 ///   ObjCInterfaceDecl
@@ -257,9 +260,26 @@
   /// DeclKind - This indicates which class this is.
   Decl::Kind DeclKind   :  8;
 
-  /// DeclChain - Linked list of declarations that are defined inside this
-  /// declaration context.
-  ScopedDecl *DeclChain;
+  /// LookupPtrKind - Describes what kind of pointer LookupPtr
+  /// actually is. 
+  enum LookupPtrKind {
+    /// LookupIsMap - Indicates that LookupPtr is actually a
+    /// DenseMap<DeclarationName, TwoNamedDecls> pointer.
+    LookupIsMap = 7
+  };
+
+  /// LookupPtr - Pointer to a data structure used to lookup
+  /// declarations within this context. If the context contains fewer
+  /// than seven declarations, the number of declarations is provided
+  /// in the 3 lowest-order bits and the upper bits are treated as a
+  /// pointer to an array of NamedDecl pointers. If the context
+  /// contains seven or more declarations, the upper bits are treated
+  /// as a pointer to a DenseMap<DeclarationName, TwoNamedDecls>.
+  llvm::PointerIntPair<void*, 3> LookupPtr;
+
+  /// Decls - Contains all of the declarations that are defined inside
+  /// this declaration context. 
+  std::vector<ScopedDecl*> Decls;
 
   // Used in the CastTo template to get the DeclKind
   // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
@@ -281,6 +301,8 @@
         return static_cast<NamespaceDecl*>(const_cast<From*>(D));
       case Decl::Enum:
         return static_cast<EnumDecl*>(const_cast<From*>(D));
+      case Decl::Record:
+        return static_cast<RecordDecl*>(const_cast<From*>(D));
       case Decl::CXXRecord:
         return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
       case Decl::ObjCMethod:
@@ -296,10 +318,19 @@
     }
   }
 
+  /// isLookupMap - Determine if the lookup structure is a
+  /// DenseMap. Othewise, it is an array.
+  bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; }
+
 protected:
-  DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {}
+  DeclContext(Decl::Kind K) : DeclKind(K), LookupPtr() {
+  }
+
+  void DestroyDecls(ASTContext &C);
 
 public:
+  ~DeclContext();
+
   /// getParent - Returns the containing DeclContext if this is a ScopedDecl,
   /// else returns NULL.
   const DeclContext *getParent() const;
@@ -309,12 +340,12 @@
   }
 
   /// getLexicalParent - Returns the containing lexical DeclContext. May be
-  /// different from getParent, e.g.:
-  ///
-  ///   namespace A {
-  ///      struct S;
-  ///   }
-  ///   struct A::S {}; // getParent() == namespace 'A'
+  /// different from getParent, e.g.:
+  ///
+  ///   namespace A {
+  ///      struct S;
+  ///   }
+  ///   struct A::S {}; // getParent() == namespace 'A'
   ///                   // getLexicalParent() == translation unit
   ///
   const DeclContext *getLexicalParent() const;
@@ -326,11 +357,12 @@
   bool isFunctionOrMethod() const {
     switch (DeclKind) {
       case Decl::Block:
-      case Decl::Function:
-      case Decl::CXXMethod:
       case Decl::ObjCMethod:
         return true;
+
       default:
+       if (DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast)
+         return true;
         return false;
     }
   }
@@ -343,6 +375,10 @@
     return DeclKind == Decl::CXXRecord;
   }
 
+  bool isNamespace() const {
+    return DeclKind == Decl::Namespace;
+  }
+
   bool Encloses(DeclContext *DC) const {
     for (; DC; DC = DC->getParent())
       if (DC == this)
@@ -350,15 +386,105 @@
     return false;
   }
 
-  const ScopedDecl *getDeclChain() const { return DeclChain; }
-  ScopedDecl *getDeclChain() { return DeclChain; }
-  void setDeclChain(ScopedDecl *D) { DeclChain = D; }
+  /// getPrimaryContext - There may be many different
+  /// declarations of the same entity (including forward declarations
+  /// of classes, multiple definitions of namespaces, etc.), each with
+  /// a different set of declarations. This routine returns the
+  /// "primary" DeclContext structure, which will contain the
+  /// information needed to perform name lookup into this context.
+  DeclContext *getPrimaryContext(ASTContext &Context);
+
+  /// getNextContext - If this is a DeclContext that may have other
+  /// DeclContexts that are semantically connected but syntactically
+  /// different, such as C++ namespaces, this routine retrieves the
+  /// next DeclContext in the link. Iteration through the chain of
+  /// DeclContexts should begin at the primary DeclContext and
+  /// continue until this function returns NULL. For example, given:
+  /// @code
+  /// namespace N {
+  ///   int x;
+  /// }
+  /// namespace N {
+  ///   int y;
+  /// }
+  /// @endcode
+  /// The first occurrence of namespace N will be the primary
+  /// DeclContext. Its getNextContext will return the second
+  /// occurrence of namespace N.
+  DeclContext *getNextContext();
+
+  /// decl_iterator - Iterates through the declarations stored
+  /// within this context.
+  typedef std::vector<ScopedDecl*>::const_iterator decl_iterator;
+
+  /// reverse_decl_iterator - Iterates through the declarations stored
+  /// within this context in reverse order.
+  typedef std::vector<ScopedDecl*>::const_reverse_iterator 
+    reverse_decl_iterator;
+
+  /// decls_begin/decls_end - Iterate over the declarations stored in
+  /// this context. 
+  decl_iterator decls_begin() const { return Decls.begin(); }
+  decl_iterator decls_end()   const { return Decls.end(); }
+
+  /// decls_rbegin/decls_rend - Iterate over the declarations stored
+  /// in this context in reverse order.
+  reverse_decl_iterator decls_rbegin() const { return Decls.rbegin(); }
+  reverse_decl_iterator decls_rend() const { return Decls.rend(); }
+
+  /// addDecl - Add the declaration D to this scope. Note that
+  /// declarations are added at the beginning of the declaration
+  /// chain, so reverseDeclChain() should be called after all
+  /// declarations have been added. If AllowLookup, also adds this
+  /// declaration into data structure for name lookup.
+  void addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup = true);
+
+  /// reverseDeclChain - Reverse the chain of declarations stored in
+  /// this scope. Typically called once after all declarations have
+  /// been added and the scope is closed.
+  void reverseDeclChain();
+
+  /// lookup_iterator - An iterator that provides access to the results
+  /// of looking up a name within this context.
+  typedef NamedDecl **lookup_iterator;
+
+  /// lookup_const_iterator - An iterator that provides non-mutable
+  /// access to the results of lookup up a name within this context.
+  typedef NamedDecl * const * lookup_const_iterator;
+
+  typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
+  typedef std::pair<lookup_const_iterator, lookup_const_iterator>
+    lookup_const_result;
+
+  /// lookup - Find the declarations (if any) with the given Name in
+  /// this context. Returns a range of iterators that contains all of
+  /// the declarations with this name (which may be 0, 1, or 2
+  /// declarations). If two declarations are returned, the declaration
+  /// in the "ordinary" identifier namespace will precede the
+  /// declaration in the "tag" identifier namespace (e.g., values
+  /// before types). Note that this routine will not look into parent
+  /// contexts.
+  lookup_result lookup(ASTContext &Context, DeclarationName Name);
+  lookup_const_result lookup(ASTContext &Context, DeclarationName Name) const;
+
+  /// insert - Insert the declaration D into this context. Up to two
+  /// declarations with the same name can be inserted into a single
+  /// declaration context, one in the "tag" namespace (e.g., for
+  /// classes and enums) and one in the "ordinary" namespaces (e.g.,
+  /// for variables, functions, and other values). Note that, if there
+  /// is already a declaration with the same name and identifier
+  /// namespace, D will replace it. It is up to the caller to ensure
+  /// that this replacement is semantically correct, e.g., that
+  /// declarations are only replaced by later declarations of the same
+  /// entity and not a declaration of some other kind of entity.
+  void insert(ASTContext &Context, NamedDecl *D);
 
   static bool classof(const Decl *D) {
     switch (D->getKind()) {
       case Decl::TranslationUnit:
       case Decl::Namespace:
       case Decl::Enum:
+      case Decl::Record:
       case Decl::CXXRecord:
       case Decl::ObjCMethod:
       case Decl::ObjCInterface:
@@ -375,6 +501,7 @@
   static bool classof(const TranslationUnitDecl *D) { return true; }
   static bool classof(const NamespaceDecl *D) { return true; }
   static bool classof(const FunctionDecl *D) { return true; }
+  static bool classof(const RecordDecl *D) { return true; }
   static bool classof(const CXXRecordDecl *D) { return true; }
   static bool classof(const EnumDecl *D) { return true; }
   static bool classof(const ObjCMethodDecl *D) { return true; }
@@ -382,6 +509,8 @@
   static bool classof(const BlockDecl *D) { return true; }
 
 private:
+  void insertImpl(NamedDecl *D);
+
   void EmitOutRec(llvm::Serializer& S) const;
   void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
 
@@ -430,6 +559,20 @@
   }
 };
 
+template<class FromTy>
+struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
+  static const ::clang::DeclContext &doit(const FromTy &Val) {
+    return *FromTy::castToDeclContext(&Val);
+  }
+};
+
+template<class FromTy>
+struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
+  static const ::clang::DeclContext *doit(const FromTy *Val) {
+    return FromTy::castToDeclContext(Val);
+  }
+};
+
 /// Implement cast_convert_val for DeclContext -> Decl conversions.
 template<class ToTy>
 struct cast_convert_val<ToTy,

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Dec 11 10:49:14 2008
@@ -116,8 +116,6 @@
   /// addOverload - Add an overloaded function FD to this set of
   /// overloaded functions.
   void addOverload(FunctionDecl *FD) {
-    assert((!getNumFunctions() || (FD->getDeclContext() == getDeclContext())) &&
-           "Overloaded functions must all be in the same context");
     assert((FD->getDeclName() == getDeclName() ||
             isa<CXXConversionDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
            "Overloaded functions must have the same name");
@@ -173,29 +171,6 @@
   friend class CXXRecordDecl;
 };
 
-/// CXXFieldDecl - Represents an instance field of a C++ struct/union/class.
-class CXXFieldDecl : public FieldDecl {
-  CXXRecordDecl *Parent;
-  bool Mutable;
-
-  CXXFieldDecl(CXXRecordDecl *RD, SourceLocation L, IdentifierInfo *Id,
-               QualType T, bool Mut, Expr *BW = NULL)
-    : FieldDecl(CXXField, L, Id, T, BW), Parent(RD), Mutable(Mut) {}
-public:
-  static CXXFieldDecl *Create(ASTContext &C, CXXRecordDecl *RD,SourceLocation L,
-                              IdentifierInfo *Id, QualType T, bool Mut,
-                              Expr *BW = NULL);
-
-  void setAccess(AccessSpecifier AS) { Access = AS; }
-  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
-  CXXRecordDecl *getParent() const { return Parent; }
-  bool isMutable() const { return Mutable; }
-    
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Decl *D) { return D->getKind() == CXXField; }
-  static bool classof(const CXXFieldDecl *D) { return true; }
-};
-
 /// CXXBaseSpecifier - A base class of a C++ class.
 ///
 /// Each CXXBaseSpecifier represents a single, direct base class (or
@@ -277,11 +252,9 @@
 };
 
 /// CXXRecordDecl - Represents a C++ struct/union/class.
-/// CXXRecordDecl differs from RecordDecl in several ways. First, it
-/// is a DeclContext, because it can contain other
-/// declarations. Second, it provides additional C++ fields, including
-/// storage for base classes and constructors.
-class CXXRecordDecl : public RecordDecl, public DeclContext {
+/// FIXME: This class will disappear once we've properly taught RecordDecl
+/// to deal with C++-specific things.
+class CXXRecordDecl : public RecordDecl {
   /// UserDeclaredConstructor - True when this class has a
   /// user-declared constructor. 
   bool UserDeclaredConstructor : 1;
@@ -348,19 +321,6 @@
   base_class_iterator       bases_end()         { return Bases + NumBases; }
   base_class_const_iterator bases_end()   const { return Bases + NumBases; }
 
-  const CXXFieldDecl *getMember(unsigned i) const {
-    return cast<const CXXFieldDecl>(RecordDecl::getMember(i));
-  }
-  CXXFieldDecl *getMember(unsigned i) {
-    return cast<CXXFieldDecl>(RecordDecl::getMember(i));
-  }
-
-  /// getMember - If the member doesn't exist, or there are no members, this 
-  /// function will return 0;
-  CXXFieldDecl *getMember(IdentifierInfo *name) {
-    return cast_or_null<CXXFieldDecl>(RecordDecl::getMember(name));
-  }
-
   /// getConstructors - Retrieve the overload set containing all of
   /// the constructors of this class.
   OverloadedFunctionDecl       *getConstructors()       { return &Constructors; }
@@ -537,7 +497,7 @@
 class CXXBaseOrMemberInitializer {
   /// BaseOrMember - This points to the entity being initialized,
   /// which is either a base class (a Type) or a non-static data
-  /// member (a CXXFieldDecl). When the low bit is 1, it's a base
+  /// member. When the low bit is 1, it's a base
   /// class; when the low bit is 0, it's a member.
   uintptr_t BaseOrMember;
 
@@ -552,7 +512,7 @@
 
   /// CXXBaseOrMemberInitializer - Creates a new member initializer.
   explicit 
-  CXXBaseOrMemberInitializer(CXXFieldDecl *Member, Expr **Args, unsigned NumArgs);
+  CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs);
 
   /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
   ~CXXBaseOrMemberInitializer();
@@ -598,9 +558,9 @@
   /// getMember - If this is a member initializer, returns the
   /// declaration of the non-static data member being
   /// initialized. Otherwise, returns NULL.
-  CXXFieldDecl *getMember() { 
+  FieldDecl *getMember() { 
     if (isMemberInitializer())
-      return reinterpret_cast<CXXFieldDecl *>(BaseOrMember); 
+      return reinterpret_cast<FieldDecl *>(BaseOrMember); 
     else
       return 0;
   }
@@ -917,14 +877,14 @@
     if (ScopedDecl *SD = dyn_cast<ScopedDecl>(MD)) {
       return cast<CXXRecordDecl>(SD->getDeclContext());
     }
-    return cast<CXXFieldDecl>(MD)->getParent();
+    return cast<CXXRecordDecl>(cast<FieldDecl>(MD)->getDeclContext());
   }
 
   static bool isMember(Decl *D) {
     if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
       return isa<CXXRecordDecl>(SD->getDeclContext());
     }
-    return isa<CXXFieldDecl>(D);
+    return isa<FieldDecl>(D);
   }
 };
   

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Thu Dec 11 10:49:14 2008
@@ -506,7 +506,8 @@
 private:
   ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
                AccessControl ac, Expr *BW)
-    : FieldDecl(ObjCIvar, L, Id, T, BW), DeclAccess(ac) {}
+    : FieldDecl(ObjCIvar, 0, L, Id, T, BW, /*Mutable=*/false, 0), 
+      DeclAccess(ac) {}
   
 public:
   static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L,
@@ -534,12 +535,13 @@
 ///  @defs(...).
 class ObjCAtDefsFieldDecl : public FieldDecl {
 private:
-  ObjCAtDefsFieldDecl(SourceLocation L, IdentifierInfo *Id,
+  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
                       QualType T, Expr *BW)
-  : FieldDecl(ObjCAtDefsField, L, Id, T, BW) {}
+    : FieldDecl(ObjCAtDefsField, DC, L, Id, T, BW, /*Mutable=*/false, 0) {}
   
 public:
-  static ObjCAtDefsFieldDecl *Create(ASTContext &C, SourceLocation L,
+  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation L,
                                      IdentifierInfo *Id, QualType T,
                                      Expr *BW);
     

Modified: cfe/trunk/include/clang/AST/DeclarationName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclarationName.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclarationName.h (original)
+++ cfe/trunk/include/clang/AST/DeclarationName.h Thu Dec 11 10:49:14 2008
@@ -198,6 +198,10 @@
   /// name as an opaque integer.
   uintptr_t getAsOpaqueInteger() const { return Ptr; }
 
+  /// getAsOpaquePtr - Get the representation of this declaration name as
+  /// an opaque pointer.
+  void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
+
   static DeclarationName getFromOpaqueInteger(uintptr_t P) {
     DeclarationName N;
     N.Ptr = P;

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Dec 11 10:49:14 2008
@@ -265,10 +265,10 @@
   
   /// Act on @defs() element found when parsing a structure.  ClassName is the
   /// name of the referenced class.   
-  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) {
     return 0;
   }

Modified: cfe/trunk/include/clang/Parse/Scope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Scope.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Scope.h (original)
+++ cfe/trunk/include/clang/Parse/Scope.h Thu Dec 11 10:49:14 2008
@@ -112,6 +112,12 @@
   typedef llvm::SmallPtrSet<Action::DeclTy*, 32> DeclSetTy;
   DeclSetTy DeclsInScope;
   
+  /// Entity - The entity with which this scope is associated. For
+  /// example, the entity of a class scope is the class itself, the
+  /// entity of a function scope is a function, etc. This field is
+  /// maintained by the Action implementation.
+  void *Entity;
+
 public:
   Scope(Scope *Parent, unsigned ScopeFlags) {
     Init(Parent, ScopeFlags);
@@ -178,12 +184,19 @@
     DeclsInScope.insert(D);
   }
 
+  void RemoveDecl(Action::DeclTy *D) {
+    DeclsInScope.erase(D);
+  }
+
   /// isDeclScope - Return true if this is the scope that the specified decl is
   /// declared in.
   bool isDeclScope(Action::DeclTy *D) {
     return DeclsInScope.count(D) != 0;
   }
 
+  void* getEntity() const { return Entity; }
+  void setEntity(void *E) { Entity = E; }
+
   /// isCXXClassScope - Return true if this scope is a C++ class scope.
   bool isCXXClassScope() const {
     return (getFlags() & Scope::CXXClassScope);
@@ -242,6 +255,7 @@
     if (Flags & BlockScope)    	    BlockParent = this;
     if (Flags & TemplateParamScope) TemplateParamParent = this;
     DeclsInScope.clear();
+    Entity = 0;
   }
 };
     

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Dec 11 10:49:14 2008
@@ -539,7 +539,7 @@
   ASTRecordLayout *NewEntry = new ASTRecordLayout();
   Entry = NewEntry;
 
-  NewEntry->InitializeLayout(D->getNumMembers());
+  NewEntry->InitializeLayout(std::distance(D->field_begin(), D->field_end()));
   bool IsUnion = D->isUnion();
 
   unsigned StructPacking = 0;
@@ -552,10 +552,11 @@
 
   // Layout each field, for now, just sequentially, respecting alignment.  In
   // the future, this will need to be tweakable by targets.
-  for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
-    const FieldDecl *FD = D->getMember(i);
-    NewEntry->LayoutField(FD, i, IsUnion, StructPacking, *this);
-  }
+  unsigned FieldIdx = 0;
+  for (RecordDecl::field_iterator Field = D->field_begin(),
+                               FieldEnd = D->field_end();
+       Field != FieldEnd; (void)++Field, ++FieldIdx)
+    NewEntry->LayoutField(*Field, FieldIdx, IsUnion, StructPacking, *this);
 
   // Finally, round the size of the total struct up to the alignment of the
   // struct itself.
@@ -996,12 +997,16 @@
   return QualType(Decl->TypeForDecl, 0);
 }
 
-/// setTagDefinition - Used by RecordDecl::defineBody to inform ASTContext
-///  about which RecordDecl serves as the definition of a particular
-///  struct/union/class.  This will eventually be used by enums as well.
+/// setTagDefinition - Used by RecordDecl::completeDefinition and
+/// EnumDecl::completeDefinition to inform about which
+/// RecordDecl/EnumDecl serves as the definition of a particular
+/// struct/union/class/enum.
 void ASTContext::setTagDefinition(TagDecl* D) {
   assert (D->isDefinition());
-  cast<TagType>(D->TypeForDecl)->decl = D;  
+  if (!D->TypeForDecl)
+    getTypeDeclType(D);
+  else
+    cast<TagType>(D->TypeForDecl)->decl = D;  
 }
 
 /// getTypedefType - Return the unique reference to the type for the
@@ -1460,14 +1465,17 @@
     FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));  
     // long length;
     FieldTypes[3] = LongTy;  
-    // Create fields
-    FieldDecl *FieldDecls[4];
-  
-    for (unsigned i = 0; i < 4; ++i)
-      FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0,
-                                        FieldTypes[i]);
   
-    CFConstantStringTypeDecl->defineBody(*this, FieldDecls, 4);
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl, 
+                                           SourceLocation(), 0,
+                                           FieldTypes[i], /*BitWidth=*/0, 
+                                           /*Mutable=*/false, /*PrevDecl=*/0);
+      CFConstantStringTypeDecl->addDecl(*this, Field, true);
+    }
+
+    CFConstantStringTypeDecl->completeDefinition(*this);
   }
   
   return getTagDeclType(CFConstantStringTypeDecl);
@@ -1476,6 +1484,10 @@
 QualType ASTContext::getObjCFastEnumerationStateType()
 {
   if (!ObjCFastEnumerationStateTypeDecl) {
+    ObjCFastEnumerationStateTypeDecl =
+      RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+                         &Idents.get("__objcFastEnumerationState"));
+    
     QualType FieldTypes[] = {
       UnsignedLongTy,
       getPointerType(ObjCIdType),
@@ -1484,16 +1496,16 @@
                            llvm::APInt(32, 5), ArrayType::Normal, 0)
     };
     
-    FieldDecl *FieldDecls[4];
-    for (size_t i = 0; i < 4; ++i)
-      FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0, 
-                                        FieldTypes[i]);
-    
-    ObjCFastEnumerationStateTypeDecl =
-      RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
-                         &Idents.get("__objcFastEnumerationState"));
+    for (size_t i = 0; i < 4; ++i) {
+      FieldDecl *Field = FieldDecl::Create(*this, 
+                                           ObjCFastEnumerationStateTypeDecl, 
+                                           SourceLocation(), 0, 
+                                           FieldTypes[i], /*BitWidth=*/0, 
+                                           /*Mutable=*/false, /*PrevDecl=*/0);
+      ObjCFastEnumerationStateTypeDecl->addDecl(*this, Field, true);
+    }
     
-    ObjCFastEnumerationStateTypeDecl->defineBody(*this, FieldDecls, 4);
+    ObjCFastEnumerationStateTypeDecl->completeDefinition(*this);
   }
   
   return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
@@ -1745,16 +1757,17 @@
     }
     if (ExpandStructures) {
       S += '=';
-      for (int i = 0; i < RDecl->getNumMembers(); i++) {
-        FieldDecl *FD = RDecl->getMember(i);
+      for (RecordDecl::field_iterator Field = RDecl->field_begin(),
+                                   FieldEnd = RDecl->field_end();
+           Field != FieldEnd; ++Field) {
         if (NameFields) {
           S += '"';
-          S += FD->getNameAsString();
+          S += Field->getNameAsString();
           S += '"';
         }
         
         // Special case bit-fields.
-        if (const Expr *E = FD->getBitWidth()) {
+        if (const Expr *E = Field->getBitWidth()) {
           // FIXME: Fix constness.
           ASTContext *Ctx = const_cast<ASTContext*>(this);
           unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue();
@@ -1763,7 +1776,8 @@
           S += 'b';
           S += llvm::utostr(N);
         } else {
-          getObjCEncodingForTypeImpl(FD->getType(), S, false, true, NameFields);
+          getObjCEncodingForTypeImpl(Field->getType(), S, false, true, 
+                                     NameFields);
         }
       }
     }

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu Dec 11 10:49:14 2008
@@ -81,10 +81,11 @@
   return new (Mem) BlockDecl(DC, L);
 }
 
-FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
-                             IdentifierInfo *Id, QualType T, Expr *BW) {
+FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                             IdentifierInfo *Id, QualType T, Expr *BW,
+                             bool Mutable, ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<FieldDecl>();
-  return new (Mem) FieldDecl(L, Id, T, BW);
+  return new (Mem) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable, PrevDecl);
 }
 
 
@@ -118,10 +119,21 @@
 }
 
 void EnumDecl::Destroy(ASTContext& C) {
-  if (getEnumConstantList()) getEnumConstantList()->Destroy(C);
+  DeclContext::DestroyDecls(C);
   Decl::Destroy(C);
 }
 
+void EnumDecl::completeDefinition(ASTContext &C, QualType NewType) {
+  assert(!isDefinition() && "Cannot redefine enums!");
+  setDefinition(true);
+
+  IntegerType = NewType;
+
+  // Let ASTContext know that this is the defining EnumDecl for this
+  // type.
+  C.setTagDefinition(this);
+}
+
 FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
                                            SourceLocation L,
                                            StringLiteral *Str) {
@@ -248,12 +260,10 @@
 
 RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
                        IdentifierInfo *Id)
-: TagDecl(DK, TK, DC, L, Id, 0) {
+  : TagDecl(DK, TK, DC, L, Id, 0), DeclContext(DK) {
   
   HasFlexibleArrayMember = false;
   assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
-  Members = 0;
-  NumMembers = -1;  
 }
 
 RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
@@ -267,46 +277,25 @@
 }
 
 RecordDecl::~RecordDecl() {
-  delete[] Members;
 }
 
 void RecordDecl::Destroy(ASTContext& C) {
-  if (isDefinition())
-    for (field_iterator I=field_begin(), E=field_end(); I!=E; ++I)
-      (*I)->Destroy(C);
-
+  DeclContext::DestroyDecls(C);
   TagDecl::Destroy(C);
 }
 
-/// defineBody - When created, RecordDecl's correspond to a forward declared
-/// record.  This method is used to mark the decl as being defined, with the
-/// specified contents.
-void RecordDecl::defineBody(ASTContext& C, FieldDecl **members,
-                            unsigned numMembers) {
+/// completeDefinition - Notes that the definition of this type is now
+/// complete.
+void RecordDecl::completeDefinition(ASTContext& C) {
   assert(!isDefinition() && "Cannot redefine record!");
+
   setDefinition(true);
-  NumMembers = numMembers;
-  if (numMembers) {
-    Members = new FieldDecl*[numMembers];
-    memcpy(Members, members, numMembers*sizeof(Decl*));
-  }
   
-  // Let ASTContext know that this is the defining RecordDecl this type.
+  // Let ASTContext know that this is the defining RecordDecl for this
+  // type.
   C.setTagDefinition(this);
 }
 
-
-FieldDecl *RecordDecl::getMember(IdentifierInfo *II) {
-  if (Members == 0 || NumMembers < 0)
-    return 0;
-  
-  // Linear search.  When C++ classes come along, will likely need to revisit.
-  for (int i = 0; i != NumMembers; ++i)
-    if (Members[i]->getIdentifier() == II)
-      return Members[i];
-  return 0;
-}
-
 //===----------------------------------------------------------------------===//
 // BlockDecl Implementation
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Thu Dec 11 10:49:14 2008
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
 #include "llvm/ADT/DenseMap.h"
 using namespace clang;
 
@@ -34,7 +35,6 @@
 static unsigned nOverFuncs = 0;
 static unsigned nTypedef = 0;
 static unsigned nFieldDecls = 0;
-static unsigned nCXXFieldDecls = 0;
 static unsigned nInterfaceDecls = 0;
 static unsigned nClassDecls = 0;
 static unsigned nMethodDecls = 0;
@@ -95,7 +95,7 @@
 void Decl::PrintStats() {
   fprintf(stderr, "*** Decl Stats:\n");
   fprintf(stderr, "  %d decls total.\n", 
-          int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+nCXXFieldDecls+nCXXSUC+
+          int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+nCXXSUC+
               nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
               nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
               nAtDefsFieldDecls+nNamespaces+nOverFuncs));
@@ -122,9 +122,6 @@
   fprintf(stderr, "    %d struct/union/class decls, %d each (%d bytes)\n", 
           nSUC, (int)sizeof(RecordDecl),
           int(nSUC*sizeof(RecordDecl)));
-  fprintf(stderr, "    %d C++ field decls, %d each (%d bytes)\n", 
-          nCXXFieldDecls, (int)sizeof(CXXFieldDecl),
-          int(nCXXFieldDecls*sizeof(CXXFieldDecl)));
   fprintf(stderr, "    %d C++ struct/union/class decls, %d each (%d bytes)\n", 
           nCXXSUC, (int)sizeof(CXXRecordDecl),
           int(nCXXSUC*sizeof(CXXRecordDecl)));
@@ -183,7 +180,7 @@
           int(nFuncs*sizeof(FunctionDecl)+
               nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
               nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
-              nCXXFieldDecls*sizeof(CXXFieldDecl)+nCXXSUC*sizeof(CXXRecordDecl)+
+              nCXXSUC*sizeof(CXXRecordDecl)+
               nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
               nTypedef*sizeof(TypedefDecl)+
               nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
@@ -236,7 +233,6 @@
   case ImplicitParam:
   case TranslationUnit:     break;
 
-  case CXXField:            nCXXFieldDecls++; break;
   case CXXRecord:           nCXXSUC++; break;
   // FIXME: Statistics for C++ decls.
   case TemplateTypeParm:
@@ -372,3 +368,269 @@
     return SD->getLexicalDeclContext();
   return getParent();
 }
+
+/// TwoNamedDecls - Stores up to two NamedDecls. The first
+/// declaration, if any, is in the ordinary identifier namespace, and
+/// corresponds to values (functions, variables, etc.). The second
+/// declaration, if any, is in the tag identifier namespace, and
+/// corresponds to tag types (classes, enums).
+struct TwoNamedDecls {
+  NamedDecl* Decls[2];
+};
+
+// FIXME: We really want to use a DenseSet here to eliminate the
+// redundant storage of the declaration names, but (1) it doesn't give
+// us the ability to search based on DeclarationName, (2) we really
+// need something more like a DenseMultiSet, and (3) it's
+// implemented in terms of DenseMap anyway.
+typedef llvm::DenseMap<DeclarationName, TwoNamedDecls> StoredDeclsMap;
+
+DeclContext::~DeclContext() {
+  unsigned Size = LookupPtr.getInt();
+  if (Size == LookupIsMap) {
+    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
+    delete Map;
+  } else {
+    NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
+    delete [] Array;
+  }
+}
+
+void DeclContext::DestroyDecls(ASTContext &C) {
+  for (decl_iterator D = Decls.begin(); D != Decls.end(); ++D) {
+    if ((*D)->getLexicalDeclContext() == this)
+      (*D)->Destroy(C);
+  }
+}
+
+DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
+  switch (DeclKind) {
+  case Decl::Block:
+  case Decl::TranslationUnit:
+    // There is only one DeclContext for these entities.
+    return this;
+
+  case Decl::Namespace:
+    // The original namespace is our primary context.
+    return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
+
+  case Decl::Enum:
+    // The declaration associated with the enumeration type is our
+    // primary context.
+    return Context.getTypeDeclType(static_cast<EnumDecl*>(this))
+             ->getAsEnumType()->getDecl();
+
+  case Decl::Record:
+  case Decl::CXXRecord: {
+    // The declaration associated with the type is be our primary
+    // context. 
+#if 0
+    // FIXME: This is what we expect to do. However, it doesn't work
+    // because ASTContext::setTagDefinition changes the result of
+    // Context.getTypeDeclType, meaning that our "primary" declaration
+    // of a RecordDecl/CXXRecordDecl will change, and we won't be able
+    // to find any values inserted into the earlier "primary"
+    // declaration. We need better tracking of redeclarations and
+    // definitions.
+    QualType Type = Context.getTypeDeclType(static_cast<RecordDecl*>(this));
+    return Type->getAsRecordType()->getDecl();
+#else
+    // FIXME: This hack will work for now, because the declaration we
+    // create when we're defining the record is the one we'll use as
+    // the definition later.
+    return this;
+#endif
+  }
+
+  case Decl::ObjCMethod:
+    return this;
+
+  case Decl::ObjCInterface:
+    // FIXME: Can Objective-C interfaces be forward-declared?
+    return this;
+
+  default:
+    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
+          "Unknown DeclContext kind");
+    return this;
+  }
+}
+
+DeclContext *DeclContext::getNextContext() {
+  switch (DeclKind) {
+  case Decl::Block:
+  case Decl::TranslationUnit:
+  case Decl::Enum:
+  case Decl::Record:
+  case Decl::CXXRecord:
+  case Decl::ObjCMethod:
+  case Decl::ObjCInterface:
+    // There is only one DeclContext for these entities.
+    return 0;
+
+  case Decl::Namespace:
+    // Return the next namespace
+    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
+
+  default:
+    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
+          "Unknown DeclContext kind");
+    return 0;
+  }
+}
+
+void DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup) {
+  Decls.push_back(D);
+  if (AllowLookup)
+    D->getDeclContext()->insert(Context, D);
+}
+
+DeclContext::lookup_result 
+DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
+  DeclContext *PrimaryContext = getPrimaryContext(Context);
+  if (PrimaryContext != this)
+    return PrimaryContext->lookup(Context, Name);
+
+  /// If there is no lookup data structure, build one now by talking
+  /// all of the linked DeclContexts (in declaration order!) and
+  /// inserting their values.
+  if (LookupPtr.getPointer() == 0) {
+    for (DeclContext *DCtx = this; DCtx; DCtx = DCtx->getNextContext())
+      for (decl_iterator D = DCtx->decls_begin(); D != DCtx->decls_end(); ++D)
+        insertImpl(*D);
+  }
+
+  lookup_result Result(0, 0);
+  if (isLookupMap()) {
+    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
+    StoredDeclsMap::iterator Pos = Map->find(Name);
+    if (Pos != Map->end()) {
+      Result.first = Pos->second.Decls[0]? &Pos->second.Decls[0] 
+                                        : &Pos->second.Decls[1];
+      Result.second = Pos->second.Decls[1]? &Pos->second.Decls[2]
+                                         : &Pos->second.Decls[1];
+    }
+    return Result;
+  } 
+
+  // We have a small array. Look into it.
+  unsigned Size = LookupPtr.getInt();
+  NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
+  for (unsigned Idx = 0; Idx < Size; ++Idx)
+    if (Array[Idx]->getDeclName() == Name) {
+      Result.first = &Array[Idx];
+      Result.second = Result.first + 1;
+      if (Idx + 1 < Size && Array[Idx + 1]->getDeclName() == Name)
+        ++Result.second;
+      break;
+    }
+
+  return Result;
+}
+
+DeclContext::lookup_const_result 
+DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
+  return const_cast<DeclContext*>(this)->lookup(Context, Name);
+}
+
+void DeclContext::insert(ASTContext &Context, NamedDecl *D) {
+  DeclContext *PrimaryContext = getPrimaryContext(Context);
+  if (PrimaryContext != this) {
+    PrimaryContext->insert(Context, D);
+    return;
+  }
+
+  // If we already have a lookup data structure, perform the insertion
+  // into it. Otherwise, be lazy and don't build that structure until
+  // someone asks for it.
+  if (LookupPtr.getPointer())
+    insertImpl(D);
+}
+
+void DeclContext::insertImpl(NamedDecl *D) {
+  if (!isLookupMap()) {
+    unsigned Size = LookupPtr.getInt();
+
+    // The lookup data is stored as an array. Search through the array
+    // to find the insertion location.
+    NamedDecl **Array;
+    if (Size == 0) {
+      Array = new NamedDecl*[LookupIsMap - 1];
+      LookupPtr.setPointer(Array);
+    } else {
+      Array = static_cast<NamedDecl **>(LookupPtr.getPointer());
+    }
+
+    // We always keep declarations of the same name next to each other
+    // in the array, so that it is easy to return multiple results
+    // from lookup(). There will be zero, one, or two declarations of
+    // the same name.
+    unsigned Match;
+    for (Match = 0; Match < Size; ++Match) {
+      if (Array[Match]->getDeclName() == D->getDeclName())
+       break;
+    }
+
+    if (Match < Size) {
+      // We found another declaration with the same name. If it's also
+      // in the same identifier namespace, update the declaration in
+      // place.
+      Decl::IdentifierNamespace NS = D->getIdentifierNamespace();
+      if (Array[Match]->getIdentifierNamespace() == NS) {
+       Array[Match] = D;
+       return;
+      }
+      if (Match + 1 < Size && Array[Match + 1]->getIdentifierNamespace() == NS) {
+       Array[Match + 1] = D;
+       return;
+      }
+
+      // If there is an existing declaration in the namespace of
+      // ordinary identifiers, then it must precede the tag
+      // declaration for C++ name lookup to operate properly. Therefore,
+      // if our match is an ordinary name and the new name is in the
+      // tag namespace, we'll insert the new declaration after it. 
+      if (Match < Size && (NS == Decl::IDNS_Tag) && 
+         (Array[Match]->getIdentifierNamespace() & Decl::IDNS_Ordinary))
+       ++Match;
+    }
+       
+    if (Size < LookupIsMap - 1) {
+      // The new declaration will fit in the array. Insert the new
+      // declaration at the position Match in the array. 
+      for (unsigned Idx = Size; Idx > Match; --Idx)
+       Array[Idx] = Array[Idx-1];
+      
+      Array[Match] = D;
+      LookupPtr.setInt(Size + 1);
+      return;
+    }
+
+    // We've reached capacity in this array. Create a map and copy in
+    // all of the declarations that were stored in the array.
+    StoredDeclsMap *Map = new StoredDeclsMap(16);
+    LookupPtr.setPointer(Map);
+    LookupPtr.setInt(LookupIsMap);
+    for (unsigned Idx = 0; Idx < LookupIsMap - 1; ++Idx) 
+      insertImpl(Array[Idx]);
+    delete [] Array;
+
+    // Fall through to perform insertion into the map.
+  } 
+
+  // Insert this declaration into the map.
+  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
+  StoredDeclsMap::iterator Pos = Map->find(D->getDeclName());
+  unsigned IndexOfD = D->getIdentifierNamespace() & Decl::IDNS_Ordinary? 0 : 1;
+
+  if (Pos == Map->end()) {
+    // Put this declaration into the appropriate slot.
+    TwoNamedDecls Val;
+    Val.Decls[0] = 0;
+    Val.Decls[1] = 0;
+    Val.Decls[IndexOfD] = D;
+    Pos = Map->insert(std::make_pair(D->getDeclName(),Val)).first;
+  } else {
+    Pos->second.Decls[IndexOfD] = D;
+  }
+}

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Dec 11 10:49:14 2008
@@ -36,16 +36,9 @@
   return new (Mem) NonTypeTemplateParmDecl(DC, L, Id, T, TypeSpecStartLoc);
 }
 
-CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                                   SourceLocation L, IdentifierInfo *Id,
-                                   QualType T, bool Mut, Expr *BW) {
-  void *Mem = C.getAllocator().Allocate<CXXFieldDecl>();
-  return new (Mem) CXXFieldDecl(RD, L, Id, T, Mut, BW);
-}
-
 CXXRecordDecl::CXXRecordDecl(TagKind TK, DeclContext *DC,
                              SourceLocation L, IdentifierInfo *Id) 
-  : RecordDecl(CXXRecord, TK, DC, L, Id), DeclContext(CXXRecord),
+  : RecordDecl(CXXRecord, TK, DC, L, Id),
     UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
     Aggregate(true), Polymorphic(false), Bases(0), NumBases(0),
     Constructors(DC, DeclarationName()),
@@ -74,11 +67,6 @@
   if (isDefinition())
     Destructor->Destroy(C);
 
-  for (OverloadedFunctionDecl::function_iterator func 
-         = Conversions.function_begin();
-       func != Conversions.function_end(); ++func)
-    (*func)->Destroy(C);
-
   RecordDecl::Destroy(C);
 }
 
@@ -176,7 +164,7 @@
 }
 
 CXXBaseOrMemberInitializer::
-CXXBaseOrMemberInitializer(CXXFieldDecl *Member, Expr **Args, unsigned NumArgs)
+CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
   : Args(0), NumArgs(0) {
   BaseOrMember = reinterpret_cast<uintptr_t>(Member);
   assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");  

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Dec 11 10:49:14 2008
@@ -95,10 +95,10 @@
 
 
 ObjCAtDefsFieldDecl
-*ObjCAtDefsFieldDecl::Create(ASTContext &C, SourceLocation L,
+*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                              IdentifierInfo *Id, QualType T, Expr *BW) {
   void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
-  return new (Mem) ObjCAtDefsFieldDecl(L, Id, T, BW);
+  return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
 }
 
 void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {

Modified: cfe/trunk/lib/AST/DeclSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclSerialization.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclSerialization.cpp (original)
+++ cfe/trunk/lib/AST/DeclSerialization.cpp Thu Dec 11 10:49:14 2008
@@ -120,11 +120,29 @@
 //===----------------------------------------------------------------------===//
 
 void DeclContext::EmitOutRec(Serializer& S) const {
-  S.EmitPtr(DeclChain);
+  S.EmitInt(Decls.size());
+  for (decl_iterator D = decls_begin(); D != decls_end(); ++D) {
+    bool Owned = ((*D)->getLexicalDeclContext() == this &&
+                  DeclKind != Decl::TranslationUnit &&
+                  !isFunctionOrMethod());
+    S.EmitBool(Owned);
+    if (Owned)
+      S.EmitOwnedPtr(*D);
+    else
+      S.EmitPtr(*D);
+  }
 }
 
 void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
-  D.ReadPtr(DeclChain);
+  unsigned NumDecls = D.ReadInt();
+  Decls.resize(NumDecls);
+  for (unsigned Idx = 0; Idx < NumDecls; ++Idx) {
+    bool Owned = D.ReadBool();
+    if (Owned)
+      Decls[Idx] = cast_or_null<ScopedDecl>(D.ReadOwnedPtr<Decl>(C));
+    else
+      D.ReadPtr<ScopedDecl>(Decls[Idx]);
+  }
 }
 
 //===----------------------------------------------------------------------===//
@@ -205,14 +223,12 @@
 
 void ScopedDecl::EmitInRec(Serializer& S) const {
   NamedDecl::EmitInRec(S);
-  S.EmitPtr(getNext());                     // From ScopedDecl.  
   S.EmitPtr(cast_or_null<Decl>(getDeclContext()));  // From ScopedDecl.
   S.EmitPtr(cast_or_null<Decl>(getLexicalDeclContext()));  // From ScopedDecl.
 }
 
 void ScopedDecl::ReadInRec(Deserializer& D, ASTContext& C) {
   NamedDecl::ReadInRec(D, C);
-  D.ReadPtr(Next);                                  // From ScopedDecl.
 
   assert(DeclCtx == 0);
 
@@ -394,8 +410,8 @@
 void EnumDecl::EmitImpl(Serializer& S) const {
   ScopedDecl::EmitInRec(S);
   S.EmitBool(isDefinition());
-  S.Emit(IntegerType);  
-  S.BatchEmitOwnedPtrs(getEnumConstantList(),getNextDeclarator());
+  S.Emit(IntegerType);
+  S.EmitOwnedPtr(getNextDeclarator());
 }
 
 EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) {
@@ -406,12 +422,7 @@
   decl->setDefinition(D.ReadBool());
   decl->IntegerType = QualType::ReadVal(D);
   
-  Decl* next_declarator;
-  Decl* Elist;
-  
-  D.BatchReadOwnedPtrs(Elist, next_declarator, C);
-  
-  decl->setDeclChain(cast_or_null<EnumConstantDecl>(Elist));
+  Decl* next_declarator = D.ReadOwnedPtr<Decl>(C);
   decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
   
   return decl;
@@ -451,14 +462,17 @@
 //===----------------------------------------------------------------------===//
 
 void FieldDecl::EmitImpl(Serializer& S) const {
+  S.EmitBool(Mutable);
   S.Emit(getType());
-  NamedDecl::EmitInRec(S);
+  ScopedDecl::EmitInRec(S);
   S.EmitOwnedPtr(BitWidth);  
 }
 
 FieldDecl* FieldDecl::CreateImpl(Deserializer& D, ASTContext& C) {
   void *Mem = C.getAllocator().Allocate<FieldDecl>();
-  FieldDecl* decl = new (Mem) FieldDecl(SourceLocation(), NULL, QualType(), 0);
+  FieldDecl* decl = new (Mem) FieldDecl(Field, 0, SourceLocation(), NULL, 
+                                        QualType(), 0, false, 0);
+  decl->Mutable = D.ReadBool();
   decl->DeclType.ReadBackpatch(D);  
   decl->ReadInRec(D, C);
   decl->BitWidth = D.ReadOwnedPtr<Expr>(C);
@@ -579,13 +593,7 @@
   ScopedDecl::EmitInRec(S);
   S.EmitBool(isDefinition());
   S.EmitBool(hasFlexibleArrayMember());
-  S.EmitSInt(getNumMembers());
-  if (getNumMembers() > 0) {
-    assert (Members);
-    S.BatchEmitOwnedPtrs((unsigned) getNumMembers(), (Decl**) &Members[0]);
-  }
-  else
-    ScopedDecl::EmitOutRec(S);
+  ScopedDecl::EmitOutRec(S);
 }
 
 RecordDecl* RecordDecl::CreateImpl(Deserializer& D, ASTContext& C) {
@@ -597,17 +605,8 @@
   decl->ScopedDecl::ReadInRec(D, C);
   decl->setDefinition(D.ReadBool());
   decl->setHasFlexibleArrayMember(D.ReadBool());
-  decl->NumMembers = D.ReadSInt();
-  
-  if (decl->getNumMembers() > 0) {
-    decl->Members = new FieldDecl*[(unsigned) decl->getNumMembers()];
-                              
-    D.BatchReadOwnedPtrs((unsigned) decl->getNumMembers(),
-                         (Decl**) &decl->Members[0], C);
-  }
-  else
-    decl->ScopedDecl::ReadOutRec(D, C);
-  
+  decl->ScopedDecl::ReadOutRec(D, C);
+    
   return decl;
 }
 

Modified: cfe/trunk/lib/AST/DeclarationName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)
+++ cfe/trunk/lib/AST/DeclarationName.cpp Thu Dec 11 10:49:14 2008
@@ -311,3 +311,9 @@
   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
 }
 
+unsigned 
+llvm::DenseMapInfo<clang::DeclarationName>::
+getHashValue(clang::DeclarationName N) {
+  return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
+}
+

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Dec 11 10:49:14 2008
@@ -353,7 +353,7 @@
         = dyn_cast<NonTypeTemplateParmDecl>(Decl))
     return NTTParm->getType()->isReferenceType();
 
-  return isa<VarDecl>(Decl) || isa<CXXFieldDecl>(Decl) ||
+  return isa<VarDecl>(Decl) || isa<FieldDecl>(Decl) ||
     // C++ 3.10p2: An lvalue refers to an object or function.
     (Ctx.getLangOptions().CPlusPlus &&
      (isa<FunctionDecl>(Decl) || isa<OverloadedFunctionDecl>(Decl)));
@@ -1222,10 +1222,15 @@
     const ASTRecordLayout &RL = C.getASTRecordLayout(RD);
     FieldDecl *FD = ME->getMemberDecl();
     
-    // FIXME: This is linear time.
-    unsigned i = 0, e = 0;
-    for (i = 0, e = RD->getNumMembers(); i != e; i++) {
-      if (RD->getMember(i) == FD)
+    // FIXME: This is linear time. And the fact that we're indexing
+    // into the layout by position in the record means that we're
+    // either stuck numbering the fields in the AST or we have to keep
+    // the linear search (yuck and yuck).
+    unsigned i = 0;
+    for (RecordDecl::field_iterator Field = RD->field_begin(),
+                                 FieldEnd = RD->field_end();
+         Field != FieldEnd; (void)++Field, ++i) {
+      if (*Field == FD)
         break;
     }
     

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Dec 11 10:49:14 2008
@@ -156,9 +156,11 @@
   FieldDecl *FD = E->getMemberDecl();
     
   // FIXME: This is linear time.
-  unsigned i = 0, e = 0;
-  for (i = 0, e = RD->getNumMembers(); i != e; i++) {
-    if (RD->getMember(i) == FD)
+  unsigned i = 0;
+  for (RecordDecl::field_iterator Field = RD->field_begin(),
+                               FieldEnd = RD->field_end();
+       Field != FieldEnd; (void)++Field, ++i) {
+    if (*Field == FD)
       break;
   }
 

Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Thu Dec 11 10:49:14 2008
@@ -433,8 +433,13 @@
 
   llvm::ImmutableList<SVal> StructVal = getBasicVals().getEmptySValList();
 
-  for (int i = RD->getNumMembers() - 1; i >= 0; --i) {
-    FieldRegion* FR = MRMgr.getFieldRegion(RD->getMember(i), R);
+  for (DeclContext::reverse_decl_iterator Mem = RD->decls_rbegin();
+       Mem != RD->decls_rend(); ++Mem) {
+    FieldDecl *FD = dyn_cast<FieldDecl>(*Mem);
+    if (!FD)
+      continue;
+
+    FieldRegion* FR = MRMgr.getFieldRegion(FD, R);
     RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(store));
     RegionBindingsTy::data_type* data = B.lookup(FR);
 

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Dec 11 10:49:14 2008
@@ -289,10 +289,11 @@
   llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators;
 
   // Create DIEnumerator elements for each enumerator.
-  for (EnumConstantDecl *Elt = Decl->getEnumConstantList(); Elt;
-       Elt = dyn_cast_or_null<EnumConstantDecl>(Elt->getNextDeclarator())) {
-    Enumerators.push_back(DebugFactory.CreateEnumerator(Elt->getNameAsString(),
-                                            Elt->getInitVal().getZExtValue()));
+  for (EnumDecl::enumerator_iterator Enum = Decl->enumerator_begin(),
+                                  EnumEnd = Decl->enumerator_end();
+       Enum != EnumEnd; ++Enum) {
+    Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getNameAsString(),
+                                            Enum->getInitVal().getZExtValue()));
   }
   
   // Return a CompositeType for the enum itself.

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Dec 11 10:49:14 2008
@@ -434,20 +434,24 @@
   // the optimizer, especially with bitfields.
   unsigned NumInitElements = E->getNumInits();
   RecordDecl *SD = E->getType()->getAsRecordType()->getDecl();
-  unsigned NumMembers = SD->getNumMembers() - SD->hasFlexibleArrayMember();
   unsigned CurInitVal = 0;
   bool isUnion = E->getType()->isUnionType();
   
   // Here we iterate over the fields; this makes it simpler to both
   // default-initialize fields and skip over unnamed fields.
-  for (unsigned CurFieldNo = 0; CurFieldNo != NumMembers; ++CurFieldNo) {
-    FieldDecl *CurField = SD->getMember(CurFieldNo);
-    if (CurField->getIdentifier() == 0) {
+  for (RecordDecl::field_iterator Field = SD->field_begin(),
+                               FieldEnd = SD->field_end();
+       Field != FieldEnd; ++Field) {
+    // We're done once we hit the flexible array member
+    if (Field->getType()->isIncompleteArrayType())
+      break;
+
+    if (Field->getIdentifier() == 0) {
       // Initializers can't initialize unnamed fields, e.g. "int : 20;"
       continue;
     }
     // FIXME: volatility
-    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, CurField, isUnion,0);
+    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, isUnion,0);
     if (CurInitVal < NumInitElements) {
       // Store the initializer into the field
       // This will probably have to get a bit smarter when we support
@@ -455,7 +459,7 @@
       EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc);
     } else {
       // We're out of initalizers; default-initialize to null
-      EmitNullInitializationToLValue(FieldLoc, CurField->getType());
+      EmitNullInitializationToLValue(FieldLoc, Field->getType());
     }
 
     // Unions only initialize one field.

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu Dec 11 10:49:14 2008
@@ -187,16 +187,17 @@
     unsigned EltNo = 0;  // Element no in ILE
     int FieldNo = 0; // Field no in RecordDecl
     bool RewriteType = false;
-    while (EltNo < ILE->getNumInits() && FieldNo < RD->getNumMembers()) {
-      FieldDecl* curField = RD->getMember(FieldNo);
+    for (RecordDecl::field_iterator Field = RD->field_begin(),
+                                 FieldEnd = RD->field_end();
+         EltNo < ILE->getNumInits() && Field != FieldEnd; ++Field) {
       FieldNo++;
-      if (!curField->getIdentifier())
+      if (!Field->getIdentifier())
         continue;
 
-      if (curField->isBitField()) {
-        InsertBitfieldIntoStruct(Elts, curField, ILE->getInit(EltNo));
+      if (Field->isBitField()) {
+        InsertBitfieldIntoStruct(Elts, *Field, ILE->getInit(EltNo));
       } else {
-        unsigned FieldNo = CGM.getTypes().getLLVMFieldNo(curField);
+        unsigned FieldNo = CGM.getTypes().getLLVMFieldNo(*Field);
         llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(EltNo), CGF);
         RewriteType |= (C->getType() != Elts[FieldNo]->getType());
         Elts[FieldNo] = C;
@@ -223,8 +224,10 @@
     // Find the field decl we're initializing, if any
     int FieldNo = 0; // Field no in RecordDecl
     FieldDecl* curField = 0;
-    while (FieldNo < RD->getNumMembers()) {
-      curField = RD->getMember(FieldNo);
+    for (RecordDecl::field_iterator Field = RD->field_begin(),
+                                 FieldEnd = RD->field_end();
+         Field != FieldEnd; ++Field) {
+      curField = *Field;
       FieldNo++;
       if (curField->getIdentifier())
         break;

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Dec 11 10:49:14 2008
@@ -2373,12 +2373,15 @@
   RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
                                       SourceLocation(),
                                       &Ctx.Idents.get("_objc_super"));  
-  FieldDecl *FieldDecls[2];
-  FieldDecls[0] = FieldDecl::Create(Ctx, SourceLocation(), 0, 
-                                    Ctx.getObjCIdType());
-  FieldDecls[1] = FieldDecl::Create(Ctx, SourceLocation(), 0,
-                                    Ctx.getObjCClassType());
-  RD->defineBody(Ctx, FieldDecls, 2);
+  RD->addDecl(Ctx, 
+              FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 
+                                Ctx.getObjCIdType(), 0, false, 0), 
+              true);
+  RD->addDecl(Ctx, 
+              FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+                                Ctx.getObjCClassType(), 0, false, 0), 
+              true);
+  RD->completeDefinition(Ctx);
 
   SuperCTy = Ctx.getTagDeclType(RD);
   SuperPtrCTy = Ctx.getPointerType(SuperCTy);

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Dec 11 10:49:14 2008
@@ -775,21 +775,20 @@
 
 static void appendFieldAndPadding(CodeGenModule &CGM,
                                   std::vector<llvm::Constant*>& Fields,
-                                  int FieldNo, llvm::Constant* Field,
+                                  FieldDecl *FieldD, FieldDecl *NextFieldD,
+                                  llvm::Constant* Field,
                                   RecordDecl* RD, const llvm::StructType *STy)
 {
   // Append the field.
   Fields.push_back(Field);
   
-  int StructFieldNo = 
-    CGM.getTypes().getLLVMFieldNo(RD->getMember(FieldNo));
+  int StructFieldNo = CGM.getTypes().getLLVMFieldNo(FieldD);
   
   int NextStructFieldNo;
-  if (FieldNo + 1 == RD->getNumMembers()) {
+  if (!NextFieldD) {
     NextStructFieldNo = STy->getNumElements();
   } else {
-    NextStructFieldNo = 
-      CGM.getTypes().getLLVMFieldNo(RD->getMember(FieldNo + 1));
+    NextStructFieldNo = CGM.getTypes().getLLVMFieldNo(NextFieldD);
   }
   
   // Append padding
@@ -841,29 +840,38 @@
     cast<llvm::StructType>(getTypes().ConvertType(CFTy));
 
   std::vector<llvm::Constant*> Fields;
-  
-  
+  RecordDecl::field_iterator Field = CFRD->field_begin();
+
   // Class pointer.
-  appendFieldAndPadding(*this, Fields, 0, CFConstantStringClassRef, CFRD, STy);
+  FieldDecl *CurField = *Field++;
+  FieldDecl *NextField = *Field++;
+  appendFieldAndPadding(*this, Fields, CurField, NextField,
+                        CFConstantStringClassRef, CFRD, STy);
   
   // Flags.
+  CurField = NextField;
+  NextField = *Field++;
   const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
-  appendFieldAndPadding(*this, Fields, 1, llvm::ConstantInt::get(Ty, 0x07C8), 
-                        CFRD, STy);
+  appendFieldAndPadding(*this, Fields, CurField, NextField,
+                        llvm::ConstantInt::get(Ty, 0x07C8), CFRD, STy);
     
   // String pointer.
+  CurField = NextField;
+  NextField = *Field++;
   llvm::Constant *C = llvm::ConstantArray::get(str);
   C = new llvm::GlobalVariable(C->getType(), true, 
                                llvm::GlobalValue::InternalLinkage,
                                C, ".str", &getModule());
-  appendFieldAndPadding(*this, Fields, 2, 
+  appendFieldAndPadding(*this, Fields, CurField, NextField,
                         llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2),
                         CFRD, STy);
   
   // String length.
+  CurField = NextField;
+  NextField = 0;
   Ty = getTypes().ConvertType(getContext().LongTy);
-  appendFieldAndPadding(*this, Fields, 3, llvm::ConstantInt::get(Ty, str.length()),
-                        CFRD, STy);
+  appendFieldAndPadding(*this, Fields, CurField, NextField,
+                        llvm::ConstantInt::get(Ty, str.length()), CFRD, STy);
   
   // The struct.
   C = llvm::ConstantStruct::get(STy, Fields);

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Thu Dec 11 10:49:14 2008
@@ -392,7 +392,7 @@
   } else if (TD->isUnion()) {
     // Just use the largest element of the union, breaking ties with the
     // highest aligned member.
-    if (RD->getNumMembers() != 0) {
+    if (RD->field_begin() != RD->field_end()) {
       RecordOrganizer RO(*this, *RD);
       
       RO.layoutUnionFields(Context.getASTRecordLayout(RD));
@@ -478,16 +478,17 @@
   uint64_t llvmSize = 0;
   // FIXME: Make this a SmallVector
   std::vector<const llvm::Type*> LLVMFields;
-  int NumMembers = RD.getNumMembers();
 
-  for (int curField = 0; curField < NumMembers; curField++) {
-    const FieldDecl *FD = RD.getMember(curField);
+  unsigned curField = 0;
+  for (RecordDecl::field_iterator Field = RD.field_begin(),
+                               FieldEnd = RD.field_end();
+       Field != FieldEnd; ++Field) {
     uint64_t offset = RL.getFieldOffset(curField);
-    const llvm::Type *Ty = CGT.ConvertTypeRecursive(FD->getType());
+    const llvm::Type *Ty = CGT.ConvertTypeRecursive(Field->getType());
     uint64_t size = CGT.getTargetData().getABITypeSizeInBits(Ty);
 
-    if (FD->isBitField()) {
-      Expr *BitWidth = FD->getBitWidth();
+    if (Field->isBitField()) {
+      Expr *BitWidth = Field->getBitWidth();
       llvm::APSInt FieldSize(32);
       bool isBitField =
         BitWidth->isIntegerConstantExpr(FieldSize, CGT.getContext());
@@ -498,8 +499,8 @@
       // Bitfield field info is different from other field info;
       // it actually ignores the underlying LLVM struct because
       // there isn't any convenient mapping.
-      CGT.addFieldInfo(FD, offset / size);
-      CGT.addBitFieldInfo(FD, offset % size, BitFieldSize);
+      CGT.addFieldInfo(*Field, offset / size);
+      CGT.addBitFieldInfo(*Field, offset % size, BitFieldSize);
     } else {
       // Put the element into the struct. This would be simpler
       // if we didn't bother, but it seems a bit too strange to
@@ -510,9 +511,10 @@
       }
 
       llvmSize += size;
-      CGT.addFieldInfo(FD, LLVMFields.size());
+      CGT.addFieldInfo(*Field, LLVMFields.size());
       LLVMFields.push_back(Ty);
     }
+    ++curField;
   }
 
   while (llvmSize < RL.getSize()) {
@@ -528,21 +530,24 @@
 /// corresponding llvm struct type.  This should be invoked only after
 /// all fields are added.
 void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) {
-  for (int curField = 0; curField < RD.getNumMembers(); curField++) {
-    const FieldDecl *FD = RD.getMember(curField);
+  unsigned curField = 0;
+  for (RecordDecl::field_iterator Field = RD.field_begin(),
+                               FieldEnd = RD.field_end();
+       Field != FieldEnd; ++Field) {
     // The offset should usually be zero, but bitfields could be strange
     uint64_t offset = RL.getFieldOffset(curField);
 
-    if (FD->isBitField()) {
-      Expr *BitWidth = FD->getBitWidth();
+    if (Field->isBitField()) {
+      Expr *BitWidth = Field->getBitWidth();
       uint64_t BitFieldSize =  
         BitWidth->getIntegerConstantExprValue(CGT.getContext()).getZExtValue();
 
-      CGT.addFieldInfo(FD, 0);
-      CGT.addBitFieldInfo(FD, offset, BitFieldSize);
+      CGT.addFieldInfo(*Field, 0);
+      CGT.addBitFieldInfo(*Field, offset, BitFieldSize);
     } else {
-      CGT.addFieldInfo(FD, 0);
+      CGT.addFieldInfo(*Field, 0);
     }
+    ++curField;
   }
 
   // This looks stupid, but it is correct in the sense that

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Dec 11 10:49:14 2008
@@ -914,7 +914,7 @@
       for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
         FieldDeclarator &FD = FieldDeclarators[i];
         // Install the declarator into the current TagDecl.
-        DeclTy *Field = Actions.ActOnField(CurScope,
+        DeclTy *Field = Actions.ActOnField(CurScope, TagDecl,
                                            DS.getSourceRange().getBegin(),
                                            FD.D, FD.BitfieldSize);
         FieldDecls.push_back(Field);
@@ -934,8 +934,8 @@
         continue;
       }
       llvm::SmallVector<DeclTy*, 16> Fields;
-      Actions.ActOnDefs(CurScope, Tok.getLocation(), Tok.getIdentifierInfo(),
-          Fields);
+      Actions.ActOnDefs(CurScope, TagDecl, Tok.getLocation(), 
+                        Tok.getIdentifierInfo(), Fields);
       FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
       ConsumeToken();
       ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);

Modified: cfe/trunk/lib/Sema/CXXFieldCollector.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CXXFieldCollector.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/CXXFieldCollector.h (original)
+++ cfe/trunk/lib/Sema/CXXFieldCollector.h Thu Dec 11 10:49:14 2008
@@ -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() {

Modified: cfe/trunk/lib/Sema/IdentifierResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/IdentifierResolver.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.cpp Thu Dec 11 10:49:14 2008
@@ -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.

Modified: cfe/trunk/lib/Sema/IdentifierResolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/IdentifierResolver.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.h (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.h Thu Dec 11 10:49:14 2008
@@ -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);

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Dec 11 10:49:14 2008
@@ -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;"

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Dec 11 10:49:14 2008
@@ -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);

Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Thu Dec 11 10:49:14 2008
@@ -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)) {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec 11 10:49:14 2008
@@ -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.
-
-      IdResolver.AddShadowedDecl(TD, *I);
-      return;
+    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);
+
+       // 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);
-
-    // Chain this decl to the containing DeclContext.
-    D->setNext(CurContext->getDeclChain());
-    CurContext->setDeclChain(D);
+    if (!D->getDeclName()) continue;
+
+    // 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);
 }
 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Dec 11 10:49:14 2008
@@ -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;
     }

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Dec 11 10:49:14 2008
@@ -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);
-
-    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.
+      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());
+
+      // 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;
 }
 

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Dec 11 10:49:14 2008
@@ -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.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Dec 11 10:49:14 2008
@@ -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) {

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Dec 11 10:49:14 2008
@@ -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))

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Dec 11 10:49:14 2008
@@ -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!)

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Dec 11 10:49:14 2008
@@ -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);

Modified: cfe/trunk/test/SemaCXX/namespace.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/namespace.cpp?rev=60878&r1=60877&r2=60878&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/namespace.cpp (original)
+++ cfe/trunk/test/SemaCXX/namespace.cpp Thu Dec 11 10:49:14 2008
@@ -9,7 +9,6 @@
 class A; // expected-error {{redefinition of 'A' as different kind of symbol}}
 
 class B {}; // expected-note {{previous definition is here}}
-namespace B {} // expected-error {{redefinition of 'B' as different kind of symbol}}
 
 void C(); // expected-note {{previous definition is here}}
 namespace C {} // expected-error {{redefinition of 'C' as different kind of symbol}}
@@ -55,3 +54,5 @@
     }
   }
 }
+
+namespace B {} // expected-error {{redefinition of 'B' as different kind of symbol}}

Added: cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp?rev=60878&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp (added)
+++ cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp Thu Dec 11 10:49:14 2008
@@ -0,0 +1,53 @@
+// RUN: clang -fsyntax-only -verify %s 
+
+namespace Ns {
+  int f(); // expected-note{{previous declaration is here}}
+}
+namespace Ns {
+  double f(); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+}
+
+namespace Ns2 {
+  float f();
+}
+
+namespace Ns2 {
+  float f(int); // expected-note{{previous declaration is here}}
+}
+
+namespace Ns2 {
+  double f(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+}
+
+namespace N {
+  int& f1();
+}
+
+namespace N {
+  struct f1 {
+    static int member;
+  };
+
+  void test_f1() {
+    int &i1 = f1();
+  }
+}
+
+namespace N {
+  float& f1(int);
+
+  struct f2 {
+    static int member;
+  };
+  void f2();
+}
+
+int i1 = N::f1::member;
+typedef struct N::f1 type1;
+int i2 = N::f2::member;
+typedef struct N::f2 type2;
+
+void test_f1(int i) {
+  int &v1 = N::f1();
+  float &v2 = N::f1(i);
+}





More information about the cfe-commits mailing list