RFC: Name lookup overhaul

This patch is a follow-on to my qualified/unqualified name lookup patch. It unifies the name-lookup mechanisms used in various parts of the AST and separates lexical name lookup from qualified name lookup. In particular, the patch:

  * Makes 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).
  * Implements C++ qualified name lookup in terms of lookup into DeclContext
  * Implements C++ unqualified name lookup in terms of qualified+unqualified name lookup (since unqualified lookup is not purely lexical in C++!)
  * Limits the use of the chains of declarations stored in IdentifierInfo to those names declared lexically.
  * Eliminates CXXFieldDecl, collapsing its behavior into FieldDecl. (FieldDecl is now a ScopedDecl).
  * Makes RecordDecl into a DeclContext and eliminates its Members/NumMembers fields (since one can just iterate through the DeclContext to get the fields).

Here's a particularly fun example that illustrates why DeclContext is designed the way it is:

   namespace N {
     void f(); // #1

     void f() { } // #2

   namespace N {
     void f(); // #3
     void f(int); // #4

Each of those declarations of namespace N is represented by a NamespaceDecl, which is a DeclContext, so we have two DeclContexts. The first DeclContext contains declarations for #1 and #2, so if you walk the list decls_begin()/decls_end() you'll see just #1 and #2.

The second DeclContext contains declarations for #3 and #4, so if you walk the list decls_begin()/decls_end() you'll see just #3 and #4. So, walking decls_begin()/decls_end() gives you the syntactic view of the declarations in that context.

If you want all of the declarations in namespace N (regardless of which definition of 'N' they show up in), DeclContext provides access to the "primary" (first) DeclContext for a type and a way to retrieve the next DeclContext in the chain.

The lookup mechanism for DeclContext provides lookup results based on the semantics of name lookup. Lookup looks across all DeclContexts for a namespace. More importantly, the lookup structure is built such that redeclarations are filtered out. So if we look up N::f, we get an OverloadedFunctionDecl containing #3 and #4 (one can follow #3 back to #2 and #1).

Comments greatly appreciated! I plan to commit this some time tomorrow unless I hear howls of protest.

  - Doug

decl-context-overhaul-lazy.patch (124 KB)