[cfe-dev] PATCH: Cleanup function redeclaration representations

Doug Gregor doug.gregor at gmail.com
Sun Apr 20 09:15:00 PDT 2008


While working on some of the preliminaries for overloading, I stumbled
across an issue with the way Clang represents redeclarations of
functions. The basic problem is that, although Clang recognizes
redeclarations, it does not represent them as such. Here's a simple
little example that can be used to illustrate the problem:

    int f(int x) { return x; } // #1
    int f(int x); // #2
    int f(int x) { return x; } // #3

That's an error (f is defined twice), but Clang doesn't diagnose it.
If you swap the first two f's, or the last two f's, Clang does
diagnose it properly.

Why the ordering dependency? Well, when we see the 2nd declaration of
f, Clang notices that there is a previous declaration of 'f'. It then
merges the declarations (as it should) and considers the second
declaration valid... so it pushes the second declaration on shadowed
stack. Now we have two f's in scope, although both refer to the same
function.

When we get around to the third declaration (which is also a
definition, of course), we look for a previous declaration... and find
the second declaration. Since that declaration has no body, Clang
parses the body of f again and attaches it to the third declaration of
f (which has also been pushed onto the stack of shadowed variables and
put into the scope). So we end up with three FunctionDecls on the
stack of shadowed decls for the identifier "f", all of which
conceptually represent the same function.

In this patch, when  we notice that we're redeclaring an existing
function, we merge the declarations together but *do not* introduce
the new declaration into the scope (Argiris is doing the same thing
with namespaces in his patch). That way, everyone who refers to a
function "f" will refer to the same FunctionDecl, which will always be
updated with all of the information we have about that function.

Some notes:
  - FunctionDecl::RedeclaredBy is used to update the main FunctionDecl
with information from the newest FunctionDecl, and update the chain of
previous declarations.

  - FunctionDecl::getBody actually traverses the list of
redeclarations to find the function definition. That way, we know
*which* declaration is also a definition.

  - This change breaks CodeGen for the case where one sees the
prototype of a function, generates a call to that function, and later
sees the definition; see test/CodeGen/functions.c.
CodeGenModule::GetAddrOfFunctionDecl currently relies on the later
definition having a different FunctionDecl node (which used to be the
case, but isn't with this patch). I can provide a follow-up patch to
fix this issue, unless someone more familiar with the CodeGen module
wants to deal with it.

  - Doug
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clang-redecl.patch
Type: text/x-patch
Size: 12338 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20080420/7d98786f/attachment.bin>


More information about the cfe-dev mailing list