Is there some reason that RefineAbstractType doesn't recurse down
DerivedTypes
and further resolve abstract types?
In Fortran it is possible to have a routine that takes a function pointer to a
routine with the same signature. This is not possible to express in C/C++.
I'm not sure it's possible to express in LLVM either without using
varargs
(opinions welcome).
In a simpler C++ example, we end upcreating a function pointer type:
void (...) * (opaque *)
We want to resolve "opaque" to be
void (...)
Note that this isn't the same issue as in Fortran (it's not a recursive
type)
but it serves the purpose for this question.
Unfortunately, calling FunctionType::refineAbstractType(opaque, void (...))
doesn't work because RefineAbstractType doesn't recurse down into the
pointee types. It ends up giving back
void (...) * (opaque *)
so it didn't resolve anything.
It's not clear how to fix this without a core LLVM change because the
pointee
depth could be arbitrary (pointer to pointer to pointer...).
Thoughts?
-Dave
On Nov 12, 2008, at 2:59 PM, David Greene wrote:> Is there some reason that RefineAbstractType doesn't recurse down > DerivedTypes > and further resolve abstract types?Because that would resolve two different types. RefineAbstractType just refines the one type you request, and further uniques types based on it. In fact, I strongly suspect that RefineAbstractType doesn't work if you give it something that isn't Opaque. I'd recommend only using it on Opaque, not random abstract types.> In Fortran it is possible to have a routine that takes a function > pointer to a > routine with the same signature. This is not possible to express in > C/C++. > I'm not sure it's possible to express in LLVM either without using > varargs > (opinions welcome).Sure, LLVM is more general than C. In LLVM, you can have a pointer that points to itself, for example: %t = type %t* which is "\1*" if you like up references. I'm not sure what a function pointer that takes a pointer to itself has to do with opaque types, but you'd write it like this: %t = type void (%t)* or if you want the function: %t = type void (%t*)> Unfortunately, calling FunctionType::refineAbstractType(opaque, void > (...)) > doesn't work because RefineAbstractType doesn't recurse down into the > pointee types.What types are you starting out with? If you had the equivalent of: %t1 = type opaque %t2 = type void(%t1*) and you refine t1 -> t2, it should work. -Chris
On Wednesday 12 November 2008 17:29, Chris Lattner wrote:> In fact, I strongly suspect that RefineAbstractType doesn't work if > you give it something that isn't Opaque. I'd recommend only using it > on Opaque, not random abstract types.Ok.> Sure, LLVM is more general than C. In LLVM, you can have a pointer > that points to itself, for example: > > %t = type %t* > > which is "\1*" if you like up references. > > I'm not sure what a function pointer that takes a pointer to itself > has to do with opaque types, but you'd write it like this:It has to do with the way we're processing things right now. We have to break the processing recursion so we create an Opaque type as a stand-in for the (yet-to-be-completed) FunctionType when we encounter an argument referencing the (yet-to-be-completed) FunctionType. We want to resolve those OpaqueTypes once we have the FunctionType constructed.> > %t = type void (%t)* > > or if you want the function: > > %t = type void (%t*)Cool.> > Unfortunately, calling FunctionType::refineAbstractType(opaque, void > > (...)) > > doesn't work because RefineAbstractType doesn't recurse down into the > > pointee types. > > What types are you starting out with? If you had the equivalent of: > > %t1 = type opaque > %t2 = type void(%t1*) > > and you refine t1 -> t2, it should work.I'm not sure it will. %t1* is the "contained" type inside the FunctionType. RefineAbstractTypes expects the OldType (%t1 in this case) to be in the contained type set. Since a _pointer_ to %t1 is in the contained set, it doesn't see it. -Dave