mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 00:45:28 +02:00
Bug 367611: Implicit names for begin() and end() in range based for loop.
This commit is contained in:
parent
5b0b6666ea
commit
545ae7e7f9
4 changed files with 135 additions and 41 deletions
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
|
@ -24,7 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
|
|||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* @since 5.3
|
||||
*/
|
||||
public interface ICPPASTRangeBasedForStatement extends IASTStatement {
|
||||
public interface ICPPASTRangeBasedForStatement extends IASTStatement, IASTImplicitNameOwner {
|
||||
public static final ASTNodeProperty DECLARATION = new ASTNodeProperty(
|
||||
"ICPPASTRangeBasedForStatement.DECLARATION [IASTDeclaration]"); //$NON-NLS-1$
|
||||
public static final ASTNodeProperty INITIALIZER = new ASTNodeProperty(
|
||||
|
@ -53,8 +54,10 @@ public interface ICPPASTRangeBasedForStatement extends IASTStatement {
|
|||
*/
|
||||
public IScope getScope();
|
||||
|
||||
@Override
|
||||
public ICPPASTRangeBasedForStatement copy();
|
||||
|
||||
@Override
|
||||
public ICPPASTRangeBasedForStatement copy(CopyStyle style);
|
||||
|
||||
|
||||
|
|
|
@ -10,15 +10,26 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
|
||||
/**
|
||||
* Range based for loop in c++.
|
||||
|
@ -28,14 +39,17 @@ public class CPPASTRangeBasedForStatement extends ASTNode implements ICPPASTRang
|
|||
private IASTDeclaration fDeclaration;
|
||||
private IASTInitializerClause fInitClause;
|
||||
private IASTStatement fBody;
|
||||
private IASTImplicitName[] fImplicitNames;
|
||||
|
||||
public CPPASTRangeBasedForStatement() {
|
||||
}
|
||||
|
||||
public CPPASTRangeBasedForStatement copy() {
|
||||
@Override
|
||||
public CPPASTRangeBasedForStatement copy() {
|
||||
return copy(CopyStyle.withoutLocations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPPASTRangeBasedForStatement copy(CopyStyle style) {
|
||||
CPPASTRangeBasedForStatement copy = new CPPASTRangeBasedForStatement();
|
||||
copy.setDeclaration(fDeclaration == null ? null : fDeclaration.copy(style));
|
||||
|
@ -48,11 +62,13 @@ public class CPPASTRangeBasedForStatement extends ASTNode implements ICPPASTRang
|
|||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTDeclaration getDeclaration() {
|
||||
return fDeclaration;
|
||||
}
|
||||
|
||||
public void setDeclaration(IASTDeclaration declaration) {
|
||||
@Override
|
||||
public void setDeclaration(IASTDeclaration declaration) {
|
||||
assertNotFrozen();
|
||||
this.fDeclaration = declaration;
|
||||
if (declaration != null) {
|
||||
|
@ -61,11 +77,13 @@ public class CPPASTRangeBasedForStatement extends ASTNode implements ICPPASTRang
|
|||
}
|
||||
}
|
||||
|
||||
public IASTInitializerClause getInitializerClause() {
|
||||
@Override
|
||||
public IASTInitializerClause getInitializerClause() {
|
||||
return fInitClause;
|
||||
}
|
||||
|
||||
public void setInitializerClause(IASTInitializerClause initClause) {
|
||||
@Override
|
||||
public void setInitializerClause(IASTInitializerClause initClause) {
|
||||
assertNotFrozen();
|
||||
fInitClause = initClause;
|
||||
if (initClause != null) {
|
||||
|
@ -74,10 +92,12 @@ public class CPPASTRangeBasedForStatement extends ASTNode implements ICPPASTRang
|
|||
}
|
||||
}
|
||||
|
||||
public IASTStatement getBody() {
|
||||
@Override
|
||||
public IASTStatement getBody() {
|
||||
return fBody;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBody(IASTStatement statement) {
|
||||
assertNotFrozen();
|
||||
fBody = statement;
|
||||
|
@ -87,12 +107,72 @@ public class CPPASTRangeBasedForStatement extends ASTNode implements ICPPASTRang
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScope getScope() {
|
||||
if (fScope == null)
|
||||
fScope = new CPPBlockScope(this);
|
||||
return fScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (fImplicitNames == null) {
|
||||
IASTInitializerClause forInit = getInitializerClause();
|
||||
final ASTNode position = (ASTNode) forInit;
|
||||
if (forInit instanceof IASTExpression) {
|
||||
final IASTExpression forInitExpr = (IASTExpression) forInit;
|
||||
IType type= SemanticUtil.getNestedType(forInitExpr.getExpressionType(), TDEF|CVTYPE);
|
||||
if (type instanceof IArrayType) {
|
||||
fImplicitNames= IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
} else if (type instanceof ICPPClassType) {
|
||||
ICPPClassType ct= (ICPPClassType) type;
|
||||
if (CPPSemantics.findBindings(ct.getCompositeScope(), CPPVisitor.BEGIN_STR, true).length > 0) {
|
||||
CPPASTName name = new CPPASTName(CPPVisitor.BEGIN);
|
||||
name.setOffset(position.getOffset());
|
||||
CPPASTFieldReference fieldRef = new CPPASTFieldReference(name, forInitExpr.copy());
|
||||
IASTExpression expr= new CPPASTFunctionCallExpression(fieldRef, CPPVisitor.NO_ARGS);
|
||||
expr.setParent(this);
|
||||
expr.setPropertyInParent(ICPPASTRangeBasedForStatement.INITIALIZER);
|
||||
CPPASTImplicitName begin= new CPPASTImplicitName(name.toCharArray(), this);
|
||||
begin.setBinding(name.resolveBinding());
|
||||
begin.setOffsetAndLength(position);
|
||||
|
||||
name = new CPPASTName(CPPVisitor.END);
|
||||
name.setOffset(position.getOffset());
|
||||
fieldRef.setFieldName(name);
|
||||
CPPASTImplicitName end= new CPPASTImplicitName(name.toCharArray(), this);
|
||||
end.setBinding(name.resolveBinding());
|
||||
end.setOffsetAndLength(position);
|
||||
|
||||
fImplicitNames= new IASTImplicitName[] {begin, end};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fImplicitNames == null) {
|
||||
CPPASTName name = new CPPASTName(CPPVisitor.BEGIN);
|
||||
name.setOffset(position.getOffset());
|
||||
CPPASTIdExpression fname = new CPPASTIdExpression(name);
|
||||
IASTExpression expr= new CPPASTFunctionCallExpression(fname, new IASTInitializerClause[] {forInit.copy()});
|
||||
expr.setParent(this);
|
||||
expr.setPropertyInParent(ICPPASTRangeBasedForStatement.INITIALIZER);
|
||||
|
||||
CPPASTImplicitName begin= new CPPASTImplicitName(name.toCharArray(), this);
|
||||
begin.setBinding(name.resolveBinding());
|
||||
begin.setOffsetAndLength(position);
|
||||
|
||||
name = new CPPASTName(CPPVisitor.END);
|
||||
name.setOffset(position.getOffset());
|
||||
fname.setName(name);
|
||||
CPPASTImplicitName end= new CPPASTImplicitName(name.toCharArray(), this);
|
||||
end.setBinding(name.resolveBinding());
|
||||
end.setOffsetAndLength(position);
|
||||
|
||||
fImplicitNames= new IASTImplicitName[] {begin, end};
|
||||
}
|
||||
}
|
||||
return fImplicitNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if (action.shouldVisitStatements) {
|
||||
|
@ -106,6 +186,14 @@ public class CPPASTRangeBasedForStatement extends ASTNode implements ICPPASTRang
|
|||
return false;
|
||||
if (fInitClause != null && !fInitClause.accept(action))
|
||||
return false;
|
||||
IASTImplicitName[] implicits = action.shouldVisitImplicitNames ? getImplicitNames() : null;
|
||||
if (implicits != null) {
|
||||
for (IASTImplicitName implicit : implicits) {
|
||||
if (!implicit.accept(action))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fBody != null && !fBody.accept(action))
|
||||
return false;
|
||||
|
||||
|
@ -114,6 +202,7 @@ public class CPPASTRangeBasedForStatement extends ASTNode implements ICPPASTRang
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replace(IASTNode child, IASTNode other) {
|
||||
if (child == fDeclaration) {
|
||||
setDeclaration((IASTDeclaration) other);
|
||||
|
|
|
@ -649,23 +649,23 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.astName != null) {
|
||||
final char[] simpleID = data.astName.getSimpleID();
|
||||
if (CharArrayUtils.equals(CPPVisitor.BEGIN, simpleID) || CharArrayUtils.equals(CPPVisitor.END, simpleID)) {
|
||||
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 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;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||
|
@ -151,7 +152,6 @@ import org.eclipse.cdt.core.index.IIndexBinding;
|
|||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
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.ASTNode;
|
||||
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.ProblemType;
|
||||
|
@ -201,14 +201,15 @@ 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 INT_TYPE = new CPPBasicType(Kind.eInt, 0);
|
||||
|
||||
private static final String BEGIN_STR = "begin"; //$NON-NLS-1$
|
||||
static final char[] BEGIN = BEGIN_STR.toCharArray();
|
||||
public static final String BEGIN_STR = "begin"; //$NON-NLS-1$
|
||||
public static final char[] BEGIN = BEGIN_STR.toCharArray();
|
||||
public static final char[] END = "end".toCharArray(); //$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[] PTRDIFF_T = "ptrdiff_t".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 IASTInitializerClause[] NO_ARGS = {};
|
||||
public static final IASTInitializerClause[] NO_ARGS = {};
|
||||
|
||||
// Thread-local set of DeclSpecifiers for which auto types are being created.
|
||||
// Used to prevent infinite recursion while processing invalid self-referencing
|
||||
|
@ -1925,22 +1926,23 @@ public class CPPVisitor extends ASTQueries {
|
|||
IType type= SemanticUtil.getNestedType(expr.getExpressionType(), TDEF|CVTYPE);
|
||||
if (type instanceof IArrayType) {
|
||||
beginExpr= expr.copy();
|
||||
} else if (type instanceof ICPPClassType) {
|
||||
ICPPClassType ct= (ICPPClassType) type;
|
||||
if (CPPSemantics.findBindings(ct.getCompositeScope(), BEGIN_STR, true).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) {
|
||||
final CPPASTName name = new CPPASTName(BEGIN);
|
||||
name.setOffset(((ASTNode) forInit).getOffset());
|
||||
beginExpr= new CPPASTFunctionCallExpression(
|
||||
new CPPASTIdExpression(name),
|
||||
new IASTInitializerClause[] { forInit.copy() });
|
||||
IASTImplicitName[] implicits= forStmt.getImplicitNames();
|
||||
if (implicits.length > 0) {
|
||||
IBinding b= implicits[0].getBinding();
|
||||
CPPASTName name= new CPPASTName();
|
||||
name.setBinding(b);
|
||||
if (b instanceof ICPPMethod) {
|
||||
beginExpr= new CPPASTFunctionCallExpression(
|
||||
new CPPASTFieldReference(name, null), NO_ARGS);
|
||||
} else {
|
||||
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
|
||||
}
|
||||
} else {
|
||||
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
|
||||
}
|
||||
}
|
||||
autoInitClause= new CPPASTUnaryExpression(IASTUnaryExpression.op_star, beginExpr);
|
||||
autoInitClause.setParent(forStmt);
|
||||
|
|
Loading…
Add table
Reference in a new issue