mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Array size determined by initializer expression, bug 294144.
This commit is contained in:
parent
fa2c3fcdd0
commit
8120ebe44f
7 changed files with 115 additions and 73 deletions
|
@ -7673,5 +7673,20 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
final String code = getAboveComment();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <typename T, int N> char (&func(T (&array)[N]))[N];
|
||||||
|
// void f(const int (&a)[1]) {}
|
||||||
|
// typedef int TA[];
|
||||||
|
// TA a = { 0 };
|
||||||
|
// int b[1];
|
||||||
|
//
|
||||||
|
// void test() {
|
||||||
|
// f(a); func(a);
|
||||||
|
// f(b); func(b);
|
||||||
|
// }
|
||||||
|
public void testArrayTypeSizeFromInitializer_294144() throws Exception {
|
||||||
|
final String code = getAboveComment();
|
||||||
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ package org.eclipse.cdt.core.dom.ast;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an an initializer that is a list of initializers.
|
* This is an an initializer that is a list of initializers.
|
||||||
|
* For example as in:
|
||||||
|
* <pre> int a[]= {1,2,3}; </pre>
|
||||||
*
|
*
|
||||||
* @noextend This interface is not intended to be extended by clients.
|
* @noextend This interface is not intended to be extended by clients.
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
|
@ -26,17 +28,22 @@ public interface IASTInitializerList extends IASTInitializer {
|
||||||
"IASTInitializerList.NESTED_INITIALIZER - sub-IASTInitializer for IASTInitializerList"); //$NON-NLS-1$
|
"IASTInitializerList.NESTED_INITIALIZER - sub-IASTInitializer for IASTInitializerList"); //$NON-NLS-1$
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of initializers.
|
* Returns the size of the initializer list, including trivial initializers. This size may
|
||||||
*
|
* be larger than the length of the array returned by {@link #getInitializers()}.
|
||||||
* @return <code>IASTInitializer[]</code> array of initializers
|
* @since 5.2
|
||||||
|
*/
|
||||||
|
public int getSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of initializers. Depending on how the ast was created, this may omit
|
||||||
|
* trivial initializers in order to save memory.
|
||||||
*/
|
*/
|
||||||
public IASTInitializer[] getInitializers();
|
public IASTInitializer[] getInitializers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an initializer to the initializer list.
|
* Add an initializer to the initializer list. Depending on how the AST is created the
|
||||||
*
|
* initializer may be <code>null</code>. A <code>null</code> initializer will not be returned
|
||||||
* @param initializer
|
* by {@link #getInitializers()}, however it contributes to the actual element count (#getSize()).
|
||||||
* <code>IASTInitializer</code>
|
|
||||||
*/
|
*/
|
||||||
public void addInitializer(IASTInitializer initializer);
|
public void addInitializer(IASTInitializer initializer);
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2005, 2008 IBM Corporation and others.
|
* Copyright (c) 2005, 2009 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Rational Software - Initial API and implementation
|
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.c;
|
package org.eclipse.cdt.internal.core.dom.parser.c;
|
||||||
|
|
||||||
|
@ -19,23 +19,34 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* e.g.: int a[]= {1,2,3};
|
||||||
*/
|
*/
|
||||||
public class CASTInitializerList extends ASTNode implements IASTInitializerList {
|
public class CASTInitializerList extends ASTNode implements IASTInitializerList {
|
||||||
|
|
||||||
|
private IASTInitializer [] initializers = null;
|
||||||
|
private int initializersPos=-1;
|
||||||
|
private int actualSize;
|
||||||
|
|
||||||
public CASTInitializerList copy() {
|
public CASTInitializerList copy() {
|
||||||
CASTInitializerList copy = new CASTInitializerList();
|
CASTInitializerList copy = new CASTInitializerList();
|
||||||
for(IASTInitializer initializer : getInitializers())
|
for(IASTInitializer initializer : getInitializers())
|
||||||
copy.addInitializer(initializer == null ? null : initializer.copy());
|
copy.addInitializer(initializer == null ? null : initializer.copy());
|
||||||
copy.setOffsetAndLength(this);
|
copy.setOffsetAndLength(this);
|
||||||
|
copy.actualSize= getSize();
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTInitializer[] getInitializers() {
|
|
||||||
if( initializers == null ) return IASTInitializer.EMPTY_INITIALIZER_ARRAY;
|
public int getSize() {
|
||||||
initializers = (IASTInitializer[]) ArrayUtil.removeNullsAfter( IASTInitializer.class, initializers, initializersPos );
|
return actualSize;
|
||||||
return initializers;
|
}
|
||||||
}
|
|
||||||
|
public IASTInitializer[] getInitializers() {
|
||||||
|
if (initializers == null)
|
||||||
|
return IASTInitializer.EMPTY_INITIALIZER_ARRAY;
|
||||||
|
initializers = ArrayUtil.trimAt(IASTInitializer.class, initializers, initializersPos);
|
||||||
|
return initializers;
|
||||||
|
}
|
||||||
|
|
||||||
public void addInitializer( IASTInitializer d ) {
|
public void addInitializer( IASTInitializer d ) {
|
||||||
assertNotFrozen();
|
assertNotFrozen();
|
||||||
|
@ -44,10 +55,9 @@ public class CASTInitializerList extends ASTNode implements IASTInitializerList
|
||||||
d.setParent(this);
|
d.setParent(this);
|
||||||
d.setPropertyInParent(NESTED_INITIALIZER);
|
d.setPropertyInParent(NESTED_INITIALIZER);
|
||||||
}
|
}
|
||||||
|
actualSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTInitializer [] initializers = null;
|
|
||||||
private int initializersPos=-1;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
|
|
|
@ -175,9 +175,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
if (designator == null) {
|
if (designator == null) {
|
||||||
IASTInitializer initializer= cInitializerClause(true);
|
IASTInitializer initializer= cInitializerClause(true);
|
||||||
// depending on value of skipTrivialItemsInCompoundInitializers initializer may be null
|
// depending on value of skipTrivialItemsInCompoundInitializers initializer may be null
|
||||||
if (initializer != null) {
|
// in any way add the initializer such that the actual size can be tracked.
|
||||||
result.addInitializer(initializer);
|
result.addInitializer(initializer);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (LT(1) == IToken.tASSIGN)
|
if (LT(1) == IToken.tASSIGN)
|
||||||
consume();
|
consume();
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
@ -17,36 +18,44 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* e.g.: int a[]= {1,2,3};
|
||||||
*/
|
*/
|
||||||
public class CPPASTInitializerList extends ASTNode implements IASTInitializerList {
|
public class CPPASTInitializerList extends ASTNode implements IASTInitializerList {
|
||||||
|
private IASTInitializer [] initializers = null;
|
||||||
|
private int initializersPos=-1;
|
||||||
|
private int actualLength;
|
||||||
|
|
||||||
public CPPASTInitializerList copy() {
|
public CPPASTInitializerList copy() {
|
||||||
CPPASTInitializerList copy = new CPPASTInitializerList();
|
CPPASTInitializerList copy = new CPPASTInitializerList();
|
||||||
for(IASTInitializer initializer : getInitializers())
|
for(IASTInitializer initializer : getInitializers())
|
||||||
copy.addInitializer(initializer == null ? null : initializer.copy());
|
copy.addInitializer(initializer == null ? null : initializer.copy());
|
||||||
copy.setOffsetAndLength(this);
|
copy.setOffsetAndLength(this);
|
||||||
|
copy.actualLength= getSize();
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTInitializer [] getInitializers() {
|
public int getSize() {
|
||||||
if( initializers == null ) return IASTInitializer.EMPTY_INITIALIZER_ARRAY;
|
return actualLength;
|
||||||
initializers = (IASTInitializer[]) ArrayUtil.removeNullsAfter( IASTInitializer.class, initializers, initializersPos );
|
}
|
||||||
return initializers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addInitializer( IASTInitializer d ) {
|
public IASTInitializer[] getInitializers() {
|
||||||
assertNotFrozen();
|
if (initializers == null)
|
||||||
if (d != null) {
|
return IASTInitializer.EMPTY_INITIALIZER_ARRAY;
|
||||||
initializers = (IASTInitializer[]) ArrayUtil.append( IASTInitializer.class, initializers, ++initializersPos, d );
|
|
||||||
d.setParent(this);
|
initializers = ArrayUtil.trimAt(IASTInitializer.class, initializers, initializersPos);
|
||||||
|
return initializers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInitializer(IASTInitializer d) {
|
||||||
|
assertNotFrozen();
|
||||||
|
if (d != null) {
|
||||||
|
initializers = (IASTInitializer[]) ArrayUtil.append(IASTInitializer.class, initializers,
|
||||||
|
++initializersPos, d);
|
||||||
|
d.setParent(this);
|
||||||
d.setPropertyInParent(NESTED_INITIALIZER);
|
d.setPropertyInParent(NESTED_INITIALIZER);
|
||||||
}
|
}
|
||||||
}
|
actualLength++;
|
||||||
|
}
|
||||||
|
|
||||||
private IASTInitializer [] initializers = null;
|
|
||||||
private int initializersPos=-1;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
|
|
|
@ -603,17 +603,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
return throwExpression();
|
return throwExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tLBRACE
|
// if this is a conditional expression, return right away.
|
||||||
// && supportStatementsInExpressions) {
|
|
||||||
// IASTExpression resultExpression = compoundStatementExpression();
|
|
||||||
// if (resultExpression != null)
|
|
||||||
// return resultExpression;
|
|
||||||
// }
|
|
||||||
|
|
||||||
IASTExpression conditionalExpression = conditionalExpression();
|
IASTExpression conditionalExpression = conditionalExpression();
|
||||||
// if the condition not taken, try assignment operators
|
if (conditionalExpression instanceof IASTConditionalExpression)
|
||||||
if (conditionalExpression != null
|
|
||||||
&& conditionalExpression instanceof IASTConditionalExpression) // &&
|
|
||||||
return conditionalExpression;
|
return conditionalExpression;
|
||||||
|
|
||||||
switch (LT(1)) {
|
switch (LT(1)) {
|
||||||
|
@ -2609,10 +2601,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
if (LT(1) == IToken.tRBRACE)
|
if (LT(1) == IToken.tRBRACE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// clause may be null, add to initializer anyways, such that the
|
||||||
|
// actual size can be computed.
|
||||||
IASTInitializer clause = initializerClause(true);
|
IASTInitializer clause = initializerClause(true);
|
||||||
if (clause != null) {
|
result.addInitializer(clause);
|
||||||
result.addInitializer(clause);
|
|
||||||
}
|
|
||||||
if (LT(1) == IToken.tRBRACE || LT(1) == IToken.tEOC)
|
if (LT(1) == IToken.tRBRACE || LT(1) == IToken.tEOC)
|
||||||
break;
|
break;
|
||||||
consume(IToken.tCOMMA);
|
consume(IToken.tCOMMA);
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
@ -137,6 +138,7 @@ 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.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.Value;
|
||||||
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.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;
|
||||||
|
@ -1638,26 +1640,34 @@ public class CPPVisitor extends ASTQueries {
|
||||||
if (declarator == null)
|
if (declarator == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
declarator= findOutermostDeclarator(declarator);
|
||||||
|
IASTNode parent = declarator.getParent();
|
||||||
|
|
||||||
IASTDeclSpecifier declSpec = null;
|
IASTDeclSpecifier declSpec = null;
|
||||||
|
if (parent instanceof IASTParameterDeclaration) {
|
||||||
IASTNode node = declarator.getParent();
|
declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||||
while (node instanceof IASTDeclarator) {
|
} else if (parent instanceof IASTSimpleDeclaration) {
|
||||||
declarator = (IASTDeclarator) node;
|
declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier();
|
||||||
node = node.getParent();
|
} else if (parent instanceof IASTFunctionDefinition) {
|
||||||
}
|
declSpec = ((IASTFunctionDefinition)parent).getDeclSpecifier();
|
||||||
|
} else if (parent instanceof IASTTypeId) {
|
||||||
if (node instanceof IASTParameterDeclaration) {
|
declSpec = ((IASTTypeId)parent).getDeclSpecifier();
|
||||||
declSpec = ((IASTParameterDeclaration) node).getDeclSpecifier();
|
|
||||||
} else if (node instanceof IASTSimpleDeclaration) {
|
|
||||||
declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier();
|
|
||||||
} else if (node instanceof IASTFunctionDefinition) {
|
|
||||||
declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier();
|
|
||||||
} else if (node instanceof IASTTypeId) {
|
|
||||||
declSpec = ((IASTTypeId)node).getDeclSpecifier();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
IASTInitializer initializer= declarator.getInitializer();
|
||||||
|
if (initializer instanceof IASTInitializerList) {
|
||||||
|
IType t= SemanticUtil.getNestedType(type, TDEF);
|
||||||
|
if (t instanceof IArrayType) {
|
||||||
|
IArrayType at= (IArrayType) t;
|
||||||
|
if (at.getSize() == null) {
|
||||||
|
type= new CPPArrayType(at.getType(), Value.create(((IASTInitializerList) initializer).getSize()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue