[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-dev] name resolution and index bindings
|
Hello,
After being away from CDT for a while, I am back and I hope to
resume working on C++ semantics problems.
Currently I am trying to fix a name resolution problem, and I
could use a little help.
Here is a code snippet that demonstrates the problem:
struct Cat { void meow(); };
struct Dog { void woof(); };
template <typename T>
Dog bar(T);
template <typename T>
auto foo(T t) -> decltype(bar(t));
Cat bar(int);
int main() {
auto x = foo(0); // type of x is deduced as Cat, not Dog...
x.woof(); // ... causing an error here
}
In the above code, the type of x should be Dog, due to the way
C++'s two-phase name lookup works:
1) At the point of definition of 'foo', an unqualified lookup
should be performed, which should find the 'bar' template (only),
which returns Dog. The non-template 'bar', which returns Cat,
should not be found because it is declared after the point
of definition of 'foo'.
2) When instantiating 'foo', a second, argument-dependent lookup
should be performed at the point of instantiation. Here, the
non-template 'bar' is now visible, but it is still not matched
because it is not in any of the argument type's associated
namespaces.
CDT messes up step (1) in cases where the translation unit has an
index.
This is what happens in the CPPSemantics.resolveBinding() call
that performs the unqualified lookup of 'bar' in the definition
of 'foo':
If there is no index:
- lookup() finds two bindings:
1. a CPPFunctionTemplate representing the template overload of 'bar'
2. a CPPFunction representing the non-template overload of 'bar'
- resolveAmbiguities() then filters out bindings for which
declaredBefore(<binding>, <point of definition>) returns
false. The CPPFunction gets filtered out this way.
- The resulting binding is thus the CPPFunctionTemplate, which is correct.
So far, so good. But, if there is an index:
- lookup() finds four bindings:
1. a CPPFunctionTemplate representing the template overload of 'bar'
2. a CPPFunction representing the non-template overload of 'bar'
3. a CompositeCPPFunctionTemplate representing the template overload of 'bar'
4. a CompositeCPPFunction representing the non-template overload of 'bar'
- resolveAmbiguities() filters out the CPPFunction, but not the
CompositeCPPFunction, because declaredBefore() cannot determine
the point of declaration for the CompositeCPPFunction.
- Overload resolution then chooses the CompositeCPPFunction over the
templates, and the result if the CompositeCPPFunction, which is incorrect.
I don't understand composite bindings well enough to determine how this
should be resolved.
- Should lookup() even be returning the composite binding for the
non-template function?
- If so, should resolveAmbiguities() be filtering it out with
declaredBefore()? If yes, how should declaredBefore() determine where
the composite binding for the non-template function was declared?
Any help is appreciated.
Thanks,
Nate