Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 332883 - Parser cannot resolve type of auto variable in range-based for loop
Summary: Parser cannot resolve type of auto variable in range-based for loop
Status: RESOLVED FIXED
Alias: None
Product: CDT
Classification: Tools
Component: cdt-indexer (show other bugs)
Version: 8.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 8.0.2   Edit
Assignee: Markus Schorn CLA
QA Contact: Markus Schorn CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-18 02:29 EST by Nathan Ridge CLA
Modified: 2011-12-21 12:23 EST (History)
2 users (show)

See Also:


Attachments
testcase + fix (3.48 KB, patch)
2010-12-23 08:32 EST, Markus Schorn CLA
mschorn.eclipse: iplog-
Details | Diff
testcase + fix for the case where the initializer is not an array (3.48 KB, patch)
2011-03-02 09:49 EST, Markus Schorn CLA
mschorn.eclipse: iplog-
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nathan Ridge CLA 2010-12-18 02:29:51 EST
Given the following code:

struct S
{
    void f();
};
void g()
{
    S array[5];
    for (auto& s : array)
        s.f();  // ERROR HERE
}

the parser gives an error: 

f: method could not be resolved

It works fine if I write in the type explicitly, as in:

for (S& s : array)
    s.f();

I wasn't sure whether this belongs under Codan or Indexer - please reassign as appropriate.
Comment 1 Markus Schorn CLA 2010-12-23 08:32:47 EST
Created attachment 185768 [details]
testcase + fix

The patch fixes the issue for array-types. However, there is also a mechanism for non-array types that needs to be implemented.

-> Fixed for array-types in 8.0 > 20101223.
Comment 3 Markus Schorn CLA 2011-03-02 09:49:21 EST
Created attachment 190148 [details]
testcase + fix for the case where the initializer is not an array
Comment 4 Markus Schorn CLA 2011-03-02 10:12:32 EST
Fixed in 8.0 > 20110302
Comment 6 Nathan Ridge CLA 2011-03-03 22:28:42 EST
While it now works correctly for the testcase you added in AST2CPPTests.java, I still get an error for the following:

#include <vector>
struct S
{
    void f();
};
void g()
{
    std::vector<S> vec[5];
    for (auto s : vec)
        s.f();  // ERROR HERE: Method 'f' could not be resolved
}
Comment 7 Nathan Ridge CLA 2011-03-03 22:29:38 EST
Sorry, there should be be no "[5]" in that last example. (It gaves the same error without the "[5]".)
Comment 8 Nathan Ridge CLA 2011-03-03 23:13:07 EST
Update: it seems to be a preprocessing issue since it works fine if I replace "#include <vector>" with the preprocessed source code of <vector>.

There is one other small issue: in the code below, if I use "auto" as the type of "s", the "f()" in "s.f()" is syntax-highlighted differently and I cannot jump to f()'s declaration using "Open Declaration". If I replace the "auto" with "S", I can now jump to the declaration using "Open Declaration".

#include <vector>
struct S
{
    void f();
};
void g()
{
    std::vector<S> vec;
    for (auto s : vec)
        s.f();
}
Comment 9 Nathan Ridge CLA 2011-03-03 23:28:36 EST
With regards to the "preprocessing issue": it appears to be due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=338611, since std::begin uses decltype to declare its return type. Just as that issue goes away if I inline the contents of the header file where the function is declared into the file where it's used, so the issue here goes away if I inline the contents of <vector> into my source file.

I am still *very* curious to know why there is this difference in behaviour between using a header file and copy-pasting its contents into the source file directly.
Comment 10 Markus Schorn CLA 2011-03-09 08:08:45 EST
(In reply to comment #9)
> With regards to the "preprocessing issue": it appears to be due to
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=338611, since std::begin uses
> decltype to declare its return type. Just as that issue goes away if I inline
> the contents of the header file where the function is declared into the file
> where it's used, so the issue here goes away if I inline the contents of
> <vector> into my source file.
There may be many reasons, why we cannot correctly index <vector> when the header is using c++0x. Nevertheless, the range-based for loop is implemented
correctly.

> I am still *very* curious to know why there is this difference in behaviour
> between using a header file and copy-pasting its contents into the source file
> directly.
Declarations that are found in the header are stored in the index and can subsequently be used by the parser (without looking at the header again). Especially in the area of dependent names, types and expressions the reperesentation in the index is less complete than the representation directly built by the parser.
Comment 11 Nathan Ridge CLA 2011-12-07 23:58:30 EST
This still does not seem to be working properly in some cases. For example:

test.hpp:

namespace std
{
    template <class T1, class T2>
    struct pair
    {
        T1 first; 
        T2 second;
    };

    template <typename T, typename U>
    T begin(const pair<T, U>& p)
    {
        return p.first;
    }
    
    template <typename T, typename U>
    U end(const pair<T, U>& p)
    {
        return p.second;
    }
}

test.cpp:

#include "test.hpp"

struct S
{
    int x;
};

int main()
{
    S arr[5];
    std::pair<S*, S*> p{arr, arr + 5};
    for (const auto& r : p)
        r.x;  // ERROR HERE: Field 'x' could not be resolved
}


Interestingly, if I try this with a type in some namespace other than std, it works. Does the parser/indexer somehow treat namespace std specially?
Comment 12 Markus Schorn CLA 2011-12-21 12:06:33 EST
Thanks for the example!
Added testcase and fix.
Comment 13 CDT Genie CLA 2011-12-21 12:23:02 EST
*** cdt git genie on behalf of Markus Schorn ***

    Bug 332883: Auto type for range based for loop.

[*] http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=35a66ea7636bcf66e8c64c304ad0733e6b565172
Comment 14 CDT Genie CLA 2011-12-21 12:23:04 EST
*** cdt git genie on behalf of Markus Schorn ***

    Bug 332883: Auto type for range based for loop.

[*] http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=f492f351361ec3ad62cb9691fde2532a0dca5c47