1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-04 23:55:26 +02:00

Bug 359653: Range based for loop with auto type.

This commit is contained in:
Markus Schorn 2011-10-06 15:50:45 +02:00
parent 8433a8acd9
commit 682b3bbf7b
2 changed files with 30 additions and 2 deletions

View file

@ -9351,6 +9351,22 @@ public class AST2CPPTests extends AST2BaseTest {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// struct S {
// void f();
// };
// struct Vector {
// S* begin();
// };
// void test() {
// Vector v;
// for (auto e : v) {
// e.f();
// }
// }
public void testAutoTypeInRangeBasedFor_359653() throws Exception {
parseAndCheckBindings();
}
// typedef int T; // typedef int T;
// struct B { // struct B {
// int a, b; // int a, b;

View file

@ -156,6 +156,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
@ -200,12 +201,14 @@ public class CPPVisitor extends ASTQueries {
private static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED); private static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
private static final CPPBasicType INT_TYPE = new CPPBasicType(Kind.eInt, 0); private static final CPPBasicType INT_TYPE = new CPPBasicType(Kind.eInt, 0);
static final char[] BEGIN = "begin".toCharArray(); //$NON-NLS-1$ private static final String BEGIN_STR = "begin"; //$NON-NLS-1$
static final char[] BEGIN = BEGIN_STR.toCharArray();
static final String STD = "std"; //$NON-NLS-1$ static final String STD = "std"; //$NON-NLS-1$
private static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$ private static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$
private static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$ private static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$
private static final char[] TYPE_INFO= "type_info".toCharArray(); //$NON-NLS-1$ private static final char[] TYPE_INFO= "type_info".toCharArray(); //$NON-NLS-1$
private static final char[] INITIALIZER_LIST = "initializer_list".toCharArray(); //$NON-NLS-1$ private static final char[] INITIALIZER_LIST = "initializer_list".toCharArray(); //$NON-NLS-1$
private static final IASTInitializerClause[] NO_ARGS = {};
// Thread-local set of DeclSpecifiers for which auto types are being created. // Thread-local set of DeclSpecifiers for which auto types are being created.
// Used to prevent infinite recursion while processing invalid self-referencing // Used to prevent infinite recursion while processing invalid self-referencing
@ -1845,14 +1848,23 @@ public class CPPVisitor extends ASTQueries {
} }
} }
} else if (parent instanceof ICPPASTRangeBasedForStatement) { } else if (parent instanceof ICPPASTRangeBasedForStatement) {
// See 6.5.4 The range-based for statement [stmt.ranged]
ICPPASTRangeBasedForStatement forStmt= (ICPPASTRangeBasedForStatement) parent; ICPPASTRangeBasedForStatement forStmt= (ICPPASTRangeBasedForStatement) parent;
IASTInitializerClause forInit = forStmt.getInitializerClause(); IASTInitializerClause forInit = forStmt.getInitializerClause();
IASTExpression beginExpr= null; IASTExpression beginExpr= null;
if (forInit instanceof IASTExpression) { if (forInit instanceof IASTExpression) {
final IASTExpression expr = (IASTExpression) forInit; final IASTExpression expr = (IASTExpression) forInit;
IType type= expr.getExpressionType(); IType type= SemanticUtil.getNestedType(expr.getExpressionType(), TDEF|CVTYPE);
if (type instanceof IArrayType) { if (type instanceof IArrayType) {
beginExpr= expr.copy(); beginExpr= expr.copy();
} else if (type instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) type;
if (ct.getCompositeScope().find(BEGIN_STR).length > 0) {
final CPPASTName name = new CPPASTName(BEGIN);
name.setOffset(((ASTNode) forInit).getOffset());
beginExpr= new CPPASTFunctionCallExpression(
new CPPASTFieldReference(name, expr.copy()), NO_ARGS);
}
} }
} }
if (beginExpr == null) { if (beginExpr == null) {