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

Declarator ambiguity with initializer, bug 267184.

This commit is contained in:
Markus Schorn 2009-03-05 15:29:44 +00:00
parent e0124cd03d
commit 935de12ddc
8 changed files with 111 additions and 32 deletions

View file

@ -102,6 +102,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
@ -6943,4 +6944,44 @@ public class AST2CPPTests extends AST2BaseTest {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// void f(char *(names[2])= 0);
// void f2(const char *(n[])) {
// if (n && 1){}
// }
public void testPointerToArrayWithDefaultVal_267184() throws Exception {
final String code = getAboveComment();
BindingAssertionHelper ba= new BindingAssertionHelper(code, true);
ICPPParameter p= ba.assertNonProblem("names", 5);
assertTrue(p.hasDefaultValue());
IType t= p.getType();
assertInstance(t, IPointerType.class); // parameter of type array is converted to pointer
t= ((IPointerType) t).getType();
assertInstance(t, IPointerType.class);
t= ((IPointerType) t).getType();
assertInstance(t, IBasicType.class);
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// class X {
// virtual void pv() = 0;
// void (*ptrToFunc) ()= 0;
// };
public void testPureVirtualVsInitDeclarator_267184() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP);
ICPPASTCompositeTypeSpecifier ct= getCompositeType(tu, 0);
IASTSimpleDeclaration sdecl= getDeclaration(ct, 0);
ICPPASTFunctionDeclarator dtor= (ICPPASTFunctionDeclarator) sdecl.getDeclarators()[0];
assertTrue(dtor.isPureVirtual());
assertNull(dtor.getInitializer());
sdecl= getDeclaration(ct, 1);
dtor= (ICPPASTFunctionDeclarator) sdecl.getDeclarators()[0];
assertFalse(dtor.isPureVirtual());
assertNotNull(dtor.getInitializer());
parseAndCheckBindings(code, ParserLanguage.CPP);
}
}

View file

@ -65,6 +65,9 @@ public abstract class ASTAmbiguousNode extends ASTNode {
protected void beforeResolution() {
}
protected void afterResolution(ASTVisitor resolver, IASTNode best) {
}
public IASTNode resolveAmbiguity(ASTVisitor resolver) {
beforeResolution();
final IASTAmbiguityParent owner= (IASTAmbiguityParent) getParent();
@ -127,6 +130,7 @@ public abstract class ASTAmbiguousNode extends ASTNode {
if (nodeToReplace != bestAlternative) {
owner.replace(nodeToReplace, bestAlternative);
}
afterResolution(resolver, bestAlternative);
return bestAlternative;
}
}

View file

@ -488,10 +488,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected final void adjustLength(IASTNode n, IASTNode endNode) {
final int endOffset= calculateEndOffset(endNode);
final ASTNode node = (ASTNode) n;
node.setLength(endOffset-node.getOffset());
adjustEndOffset(n, endOffset);
}
protected final void adjustEndOffset(IASTNode n, final int endOffset) {
final ASTNode node = (ASTNode) n;
node.setLength(endOffset-node.getOffset());
}
protected final int getEndOffset() {
if (lastTokenFromScanner == null)
return 0;
@ -1628,7 +1632,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} catch (FoundAggregateInitializer lie) {
if (declSpec == null)
declSpec= lie.fDeclSpec;
dtor= addInitializer(lie);
dtor= addInitializer(lie, DeclarationOptions.FUNCTION_STYLE_ASM);
}
if (LT(1) != IToken.tLBRACE)
@ -1649,7 +1653,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return funcDefinition;
}
protected abstract IASTDeclarator addInitializer(FoundAggregateInitializer lie) throws EndOfFileException;
protected abstract IASTDeclarator addInitializer(FoundAggregateInitializer lie, DeclarationOptions option) throws EndOfFileException;
protected IToken asmExpression(StringBuilder content) throws EndOfFileException, BacktrackException {
IToken t= consume(IToken.tLPAREN);

View file

@ -29,7 +29,7 @@ public class DeclarationOptions {
GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_CONSTRUCTOR_INITIALIZER),
FUNCTION_STYLE_ASM= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | NO_INITIALIZER),
C_MEMBER= new DeclarationOptions(ALLOW_BITFIELD | ALLOW_ABSTRACT),
CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | ALLOW_CONSTRUCTOR_INITIALIZER),
CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD),
LOCAL= new DeclarationOptions(ALLOW_CONSTRUCTOR_INITIALIZER),
PARAMETER= new DeclarationOptions(ALLOW_ABSTRACT),
TYPEID= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER),

View file

@ -338,7 +338,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// scalability: don't keep references to tokens, initializer may be large
declarationMark= null;
markBeforDtor= null;
dtor= addInitializer(lie);
dtor= addInitializer(lie, declOption);
} catch (FoundDeclaratorException e) {
if (e.altSpec != null) {
declSpec= e.altSpec;
@ -371,7 +371,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// scalability: don't keep references to tokens, initializer may be large
declarationMark= null;
markBeforDtor= null;
dtor= addInitializer(e);
dtor= addInitializer(e, declOption);
}
declarators= (IASTDeclarator[]) ArrayUtil.append( IASTDeclarator.class, declarators, dtor);
}
@ -1274,7 +1274,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
@Override
protected IASTDeclarator addInitializer(FoundAggregateInitializer e) throws EndOfFileException {
protected IASTDeclarator addInitializer(FoundAggregateInitializer e, DeclarationOptions options) throws EndOfFileException {
final IASTDeclarator d = e.fDeclarator;
try {
IASTInitializer i = optionalCInitializer();

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
@ -70,6 +71,10 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
fRepopulate.add((IASTDeclaration) node);
break;
}
if (node instanceof IASTParameterDeclaration) {
repopulateScope((IASTParameterDeclaration) node);
break;
}
if (node instanceof IASTExpression) {
break;
}
@ -172,6 +177,12 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration);
}
}
private void repopulateScope(IASTParameterDeclaration declaration) {
IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration);
if (scope instanceof ICPPASTInternalScope) {
CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration);
}
}
@Override
public int visit(IASTInitializer initializer) {

View file

@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -31,6 +32,7 @@ public class CPPASTAmbiguousDeclarator extends ASTAmbiguousNode implements IASTA
private IASTDeclarator[] dtors = new IASTDeclarator[2];
private int dtorPos=-1;
private IASTInitializer fInitializer;
public CPPASTAmbiguousDeclarator(IASTDeclarator... decls) {
@ -49,8 +51,18 @@ public class CPPASTAmbiguousDeclarator extends ASTAmbiguousNode implements IASTA
((ICPPASTInternalScope) scope).populateCache();
}
}
@Override
protected void afterResolution(ASTVisitor resolver, IASTNode best) {
// if we have an initializer it needs to be added to the chosen alternative.
// we also need to resolve ambiguities in the initializer.
if (fInitializer != null) {
((IASTDeclarator) best).setInitializer(fInitializer);
fInitializer.accept(resolver);
}
}
public IASTDeclarator copy() {
public IASTDeclarator copy() {
throw new UnsupportedOperationException();
}
@ -74,7 +86,7 @@ public class CPPASTAmbiguousDeclarator extends ASTAmbiguousNode implements IASTA
}
public IASTInitializer getInitializer() {
return dtors[0].getInitializer();
return fInitializer;
}
public IASTName getName() {
@ -99,8 +111,8 @@ public class CPPASTAmbiguousDeclarator extends ASTAmbiguousNode implements IASTA
}
public void setInitializer(IASTInitializer initializer) {
assertNotFrozen();
Assert.isLegal(false);
// store the initializer until the ambiguity is resolved
fInitializer= initializer;
}
public void setName(IASTName name) {

View file

@ -1717,7 +1717,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// scalability: don't keep references to tokens, initializer may be large
declarationMark= null;
markBeforDtor= null;
dtor= addInitializer(lie);
dtor= addInitializer(lie, declOption);
} catch (FoundDeclaratorException e) {
declSpec= (ICPPASTDeclSpecifier) e.declSpec;
dtor= e.declarator;
@ -1743,7 +1743,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// scalability: don't keep references to tokens, initializer may be large
declarationMark= null;
markBeforDtor= null;
dtor= addInitializer(e);
dtor= addInitializer(e, declOption);
}
declarators = (IASTDeclarator[]) ArrayUtil.append(IASTDeclarator.class, declarators, dtor);
}
@ -1944,7 +1944,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} catch (FoundAggregateInitializer lie) {
if (declSpec == null)
declSpec= lie.fDeclSpec;
declarator= addInitializer(lie);
declarator= addInitializer(lie, DeclarationOptions.PARAMETER);
}
final ICPPASTParameterDeclaration parm = nodeFactory.newParameterDeclaration(declSpec, declarator);
@ -2555,7 +2555,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LTcatchEOF(1) == IToken.tASSIGN && LTcatchEOF(2) == IToken.tLBRACE)
throw new FoundAggregateInitializer(dtor);
IASTInitializer initializer= optionalCPPInitializer(dtor);
IASTInitializer initializer= optionalCPPInitializer(dtor, option);
if (initializer != null) {
dtor.setInitializer(initializer);
adjustLength(dtor, initializer);
@ -2565,10 +2565,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
@Override
protected IASTDeclarator addInitializer(FoundAggregateInitializer e) throws EndOfFileException {
protected IASTDeclarator addInitializer(FoundAggregateInitializer e, DeclarationOptions option) throws EndOfFileException {
final IASTDeclarator d = e.fDeclarator;
try {
IASTInitializer i = optionalCPPInitializer(e.fDeclarator);
IASTInitializer i = optionalCPPInitializer(e.fDeclarator, option);
if (i != null) {
d.setInitializer(i);
((ASTNode) d).setLength(calculateEndOffset(i) - ((ASTNode) d).getOffset());
@ -2579,18 +2579,35 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return d;
}
protected IASTInitializer optionalCPPInitializer(IASTDeclarator d) throws EndOfFileException, BacktrackException {
protected IASTInitializer optionalCPPInitializer(IASTDeclarator d, DeclarationOptions option) throws EndOfFileException, BacktrackException {
// handle initializer
final int lt1= LTcatchEOF(1);
if (lt1 == IToken.tASSIGN) {
consume();
// for member functions we need to consider pure-virtual syntax
if (option == DeclarationOptions.CPP_MEMBER && LTcatchEOF(1) == IToken.tINTEGER) {
IASTDeclarator relDtor = ASTQueries.findTypeRelevantDeclarator(d);
// note the declarator for a member function cannot be ambiguous because it cannot be abstract
if (relDtor instanceof ICPPASTFunctionDeclarator) {
// check for pure virtual
IToken t = consume();
char[] image = t.getCharImage();
if (image.length != 1 || image[0] != '0') {
throwBacktrack(t);
}
((ICPPASTFunctionDeclarator) relDtor).setPureVirtual(true);
adjustEndOffset(d, t.getEndOffset()); // we can only adjust the offset of the outermost dtor.
return null;
}
}
try {
return initializerClause(false);
} catch (EndOfFileException eof) {
failParse();
throw eof;
}
} else if (lt1 == IToken.tLPAREN) {
} else if (option.fAllowConstructorInitializer && lt1 == IToken.tLPAREN) {
if (d instanceof IASTFunctionDeclarator && d.getNestedDeclarator() == null) {
// constructor initializer doesn't make sense for a function
// declarator,
@ -3080,17 +3097,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
__attribute_decl_seq(supportAttributeSpecifiers, false);
}
// pure virtual
if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER) {
char[] image = LA(2).getCharImage();
if (image.length == 1 && image[0] == '0') {
consume(); // tASSIGN
endOffset= consume().getEndOffset(); // tINTEGER
fc.setPureVirtual(true);
}
}
((ASTNode) fc).setOffsetAndLength(startOffset, endOffset-startOffset);
setRange(fc, startOffset, endOffset);
return fc;
}
@ -3345,7 +3352,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} catch (FoundAggregateInitializer lie) {
if (declSpec == null)
declSpec= lie.fDeclSpec;
declarator= addInitializer(lie);
declarator= addInitializer(lie, options);
}
final int endOffset = figureEndOffset(declSpec, declarator);