Redefinitions of a struct in different modules

[resending to correct cfe-dev]

Hi, Richard. One of our Swift tests recently hit an interesting edge case involving modules and redefinitions. Take the following code:

// Module A

struct Foo {
int x;

// Module B
struct Foo {
int x;

// Module C
typedef struct Foo *FooPtr;

// main.m
@import A;
@import B;
@import C;

If all of this was in one file, we’d have an invalid redefinition of Foo, but because A and B are separate modules (and supposedly self-contained) Clang just cheats and treat one of them as a mere declaration. Because Clang modules don’t affect lookup, that’s fine. In Swift, however, I can ask for “A.Foo” or “B.Foo”, and ideally both would resolve to some declaration of Foo. “C.Foo”, on the other hand, should say “there’s no ‘Foo’ in C” (because Swift doesn’t have forward declarations).

I tried using isCompleteDefinition to distinguish the B case from the C case, but of course Clang doesn’t consider the second definition to be a definition. Do you have any ideas?