diff options
author | Markus Schorn | 2009-03-05 15:29:44 +0000 |
---|---|---|
committer | Markus Schorn | 2009-03-05 15:29:44 +0000 |
commit | 935de12ddc6750c837b0e534d6c2e748e2df780c (patch) | |
tree | df8f35d5732af2c4f478febac06713e6514fd8f4 /core | |
parent | e0124cd03d9070523e98498bc89786c1505fa9e2 (diff) | |
download | org.eclipse.cdt-935de12ddc6750c837b0e534d6c2e748e2df780c.tar.gz org.eclipse.cdt-935de12ddc6750c837b0e534d6c2e748e2df780c.tar.xz org.eclipse.cdt-935de12ddc6750c837b0e534d6c2e748e2df780c.zip |
Declarator ambiguity with initializer, bug 267184.
Diffstat (limited to 'core')
8 files changed, 111 insertions, 32 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 2f1ae56dbbc..4451c6238a3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -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); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java index c88be892de0..33dc8795757 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 5756999c4e0..2c1f63d2051 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java index d931db2fcc1..908ac9fc722 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java @@ -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), diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index f2554f2b3f9..a2d5a53cba4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -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(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java index 6344a1c00f0..40b4192bc8f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java index 458d3d13d16..cc765d57694 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 1559cf97fdd..dd8b382a2d8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -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); |