[cfe-dev] RFC: Name lookup overhaul

Douglas Gregor dgregor at apple.com
Wed Dec 10 11:21:04 PST 2008


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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: decl-context-overhaul-lazy.patch
Type: application/octet-stream
Size: 127048 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20081210/67938e3c/attachment.obj>


More information about the cfe-dev mailing list