I've played with the Clang bits of this. The biggest problem I've
found is that Clang uses LLVM's type resolution not just for
forward-declared structs/classes/unions, which convert
straightforwardly to the new system, but also for forward-declared
enums, which don't.
In case anyone's interested, here's my work-in-progress patch for
clang. (Note that it's against a slightly old clang tree, because the
llvm type-system-rewrite branch hasn't had a merge from trunk
recently; and you also need the attached llvm patchlet to make it all
build.)
I'm not 100% satisfied with it but it is good enough to build sqlite3
from the test suite.
I haven't started looking at this at all yet, but it seems that we could use a similar example for forward declared structs whose bodies are needed. Clang currently codegen's this:
struct S;
struct S f(void);
struct T { struct S (*f)(void); };
struct T t = {f};
into:
%0 = type opaque
%struct.T = type { %0* }
@t = global %struct.T { %0* bitcast (void ()* @f to %0*) }, align 8
for example. Instead of doing that, we can/should just codegen it to:
%struct.T = type { void ()* }
@t = global %struct.T { void ()* @f }, align 8
directly.
I now get:
%struct.T = type { i8* }
@t = global %struct.T { i8* bitcast (void ()* @f to i8*) }, align 8
declare void @f()
(I lowered the incomplete function type all the way to void, instead
of to void(), only because that made it simpler for
CodeGenModule::GetOrCreateLLVMFunction() to tell the difference
between a proper function type and a placeholder type. There's
probably a better way of doing this.)
Basically, if we "need" a type and don't have it, just lower it directly to void instead of 'opaque'.
I'm doing this for:
- incomplete non-fixed enum types
- functions types whose argument or return types are incomplete
(because in that case the ABI stuff can't work out how parameters are
going to be passed/returned, so you can't get a proper LLVM type for
the function)
This will lead to some more bitcasts downstream, but we already have that, they get resolved if f is ever implemented.
I don't have a good understanding of which bits of Clang's codegen are
prepared to insert bitcasts like this; but it seems to work well
enough to build sqlite3!
Jay.
clang-type-system-rewrite.diff (89.4 KB)
llvm-constantarray-get-arrayref.diff (702 Bytes)