1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 332883: Range based for loop with non-array type.

This commit is contained in:
Markus Schorn 2011-03-02 14:52:44 +00:00
parent e03d0d8880
commit f6d62a31e8
4 changed files with 81 additions and 23 deletions

View file

@ -9314,7 +9314,24 @@ public class AST2CPPTests extends AST2BaseTest {
// for (auto& s : array) // for (auto& s : array)
// s.f(); // ERROR HERE // s.f(); // ERROR HERE
// } // }
public void testAutoTypeInRangeBasedFor_332883() throws Exception { public void testAutoTypeInRangeBasedFor_332883a() throws Exception {
parseAndCheckBindings();
}
// struct S {
// void f();
// };
// struct Range {};
// namespace std {
// S* begin(Range);
// }
//
// void g() {
// Range range;
// for (auto s : range)
// s.f(); // ERROR HERE
// }
public void testAutoTypeInRangeBasedFor_332883b() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }

View file

@ -5272,7 +5272,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// void g() { // void g() {
// S s; // S s;
// h(s); // h(s);
// h(s, 1); Variadicsd f // h(s, 1);
// h(s, 1, 2); // h(s, 1, 2);
// } // }
public void testVariadicFunctionTemplate_Bug333389() throws Exception { public void testVariadicFunctionTemplate_Bug333389() throws Exception {

View file

@ -666,6 +666,25 @@ public class CPPSemantics {
} catch (DOMException e) { } catch (DOMException e) {
} }
} }
if (data.astName != null
&& CharArrayUtils.equals(CPPVisitor.BEGIN, data.astName.getSimpleID())) {
IASTNode parent = data.astName.getParent(); // id-expression
if (parent != null)
parent= parent.getParent(); // function call
if (parent != null)
parent= parent.getParent(); // the loop
if (parent != null)
parent= parent.getParent(); // unary *
if (parent instanceof ICPPASTRangeBasedForStatement) {
IBinding[] std= parent.getTranslationUnit().getScope().find(CPPVisitor.STD);
for (IBinding binding : std) {
if (binding instanceof ICPPNamespace) {
namespaces.add(((ICPPNamespace) binding).getNamespaceScope());
}
}
}
}
return namespaces; return namespaces;
} }

View file

@ -149,11 +149,16 @@ import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; 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.CPPASTFunctionCallExpression;
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.CPPASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplate;
@ -192,9 +197,11 @@ import org.eclipse.cdt.internal.core.index.IIndexScope;
public class CPPVisitor extends ASTQueries { public class CPPVisitor extends ASTQueries {
public static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$ public static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$
public static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$ public static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$
static final char[] BEGIN = "begin".toCharArray(); //$NON-NLS-1$
public static final String STD = "std"; //$NON-NLS-1$ public static final String STD = "std"; //$NON-NLS-1$
public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$ public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$
private static final String INITIALIZER_LIST = "initializer_list"; //$NON-NLS-1$ private static final String INITIALIZER_LIST = "initializer_list"; //$NON-NLS-1$
// 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
// auto-type declarations. // auto-type declarations.
@ -1776,42 +1783,66 @@ public class CPPVisitor extends ASTQueries {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
IASTNode initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
initClause= ((IASTEqualsInitializer) initClause).getInitializerClause();
}
if (declSpec instanceof ICPPASTSimpleDeclSpecifier && if (declSpec instanceof ICPPASTSimpleDeclSpecifier &&
((ICPPASTSimpleDeclSpecifier) declSpec).getType() == IASTSimpleDeclSpecifier.t_auto) { ((ICPPASTSimpleDeclSpecifier) declSpec).getType() == IASTSimpleDeclSpecifier.t_auto) {
if (declarator instanceof ICPPASTFunctionDeclarator) { if (declarator instanceof ICPPASTFunctionDeclarator) {
return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator); return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator);
} }
boolean rangeBasedFor= false; IASTInitializerClause autoInitClause= null;
parent = parent.getParent(); parent = parent.getParent();
if (parent instanceof ICPPASTNewExpression) { if (parent instanceof ICPPASTNewExpression) {
IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer(); IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer();
if (initializer != null) { if (initializer != null) {
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments(); IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments();
if (arguments.length == 1) { if (arguments.length == 1) {
initClause = arguments[0]; autoInitClause = arguments[0];
} }
} }
} else if (parent instanceof ICPPASTRangeBasedForStatement) { } else if (parent instanceof ICPPASTRangeBasedForStatement) {
ICPPASTRangeBasedForStatement forStmt= (ICPPASTRangeBasedForStatement) parent; ICPPASTRangeBasedForStatement forStmt= (ICPPASTRangeBasedForStatement) parent;
initClause= forStmt.getInitializerClause(); IASTInitializerClause forInit = forStmt.getInitializerClause();
rangeBasedFor= true; IASTExpression beginExpr= null;
if (forInit instanceof IASTExpression) {
final IASTExpression expr = (IASTExpression) forInit;
IType type= expr.getExpressionType();
if (type instanceof IArrayType) {
beginExpr= expr.copy();
}
}
if (beginExpr == null) {
final CPPASTName name = new CPPASTName(BEGIN);
name.setOffset(((ASTNode) forInit).getOffset());
beginExpr= new CPPASTFunctionCallExpression(
new CPPASTIdExpression(name),
new IASTInitializerClause[] {forInit.copy()});
}
autoInitClause= new CPPASTUnaryExpression(IASTUnaryExpression.op_star, beginExpr);
autoInitClause.setParent(forStmt);
autoInitClause.setPropertyInParent(ICPPASTRangeBasedForStatement.INITIALIZER);
} else if (parent instanceof IASTCompositeTypeSpecifier && } else if (parent instanceof IASTCompositeTypeSpecifier &&
declSpec.getStorageClass() != IASTDeclSpecifier.sc_static) { declSpec.getStorageClass() != IASTDeclSpecifier.sc_static) {
// Non-static auto-typed class members are not allowed. // Non-static auto-typed class members are not allowed.
return new ProblemType(ISemanticProblem.TYPE_AUTO_FOR_NON_STATIC_FIELD); return new ProblemType(ISemanticProblem.TYPE_AUTO_FOR_NON_STATIC_FIELD);
} else {
IASTInitializer initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
autoInitClause= ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof IASTInitializerClause) {
autoInitClause= (IASTInitializerClause) initClause;
}
} }
return createAutoType(initClause, declSpec, declarator, rangeBasedFor); return createAutoType(autoInitClause, declSpec, declarator);
} }
IType type = createType(declSpec); IType type = createType(declSpec);
type = createType(type, declarator); type = createType(type, declarator);
// C++ specification 8.3.4.3 and 8.5.1.4 // C++ specification 8.3.4.3 and 8.5.1.4
IASTNode initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
initClause= ((IASTEqualsInitializer) initClause).getInitializerClause();
}
if (initClause instanceof IASTInitializerList) { if (initClause instanceof IASTInitializerList) {
IType t= SemanticUtil.getNestedType(type, TDEF); IType t= SemanticUtil.getNestedType(type, TDEF);
if (t instanceof IArrayType) { if (t instanceof IArrayType) {
@ -1828,10 +1859,9 @@ public class CPPVisitor extends ASTQueries {
return type; return type;
} }
private static IType createAutoType(IASTNode initClause, IASTDeclSpecifier declSpec, IASTDeclarator declarator, private static IType createAutoType(IASTInitializerClause initClause, IASTDeclSpecifier declSpec, IASTDeclarator declarator) {
boolean rangeBasedFor) {
// C++0x: 7.1.6.4 // C++0x: 7.1.6.4
if (!autoTypeDeclSpecs.get().add(declSpec)) { if (initClause == null || !autoTypeDeclSpecs.get().add(declSpec)) {
// Detected a self referring auto type, e.g.: auto x = x; // Detected a self referring auto type, e.g.: auto x = x;
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
@ -1880,14 +1910,6 @@ public class CPPVisitor extends ASTQueries {
type = (IType) CPPTemplates.instantiate(initializer_list_template, type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, true); new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, true);
} }
if (rangeBasedFor) {
if (type instanceof IArrayType) {
type= ((IArrayType) type).getType();
} else {
// todo: handle non-array types in for based range loops
// (c++-spec 6.5.4): 'typeof (* begin(type &&))'
}
}
return decorateType(type, declSpec, declarator); return decorateType(type, declSpec, declarator);
} }