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

229942: apply fix

This commit is contained in:
Andrew Ferguson 2008-05-21 17:02:08 +00:00
parent d3fce200ee
commit 7a7891d1b4
8 changed files with 235 additions and 63 deletions

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
@ -2478,7 +2479,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// //
// const int i= 1; // const int i= 1;
// A<i> a1; // A<i> a1;
public void _testNonTypeArgumentIsIDExpression_229942_a() throws Exception { public void testNonTypeArgumentIsIDExpression_229942_a() throws Exception {
IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true); IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true);
CPPNameCollector col = new CPPNameCollector(); CPPNameCollector col = new CPPNameCollector();
tu.accept(col); tu.accept(col);
@ -2497,7 +2498,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// //
// const int i= 1; // const int i= 1;
// }; // };
public void _testNonTypeArgumentIsIDExpression_229942_b() throws Exception { public void testNonTypeArgumentIsIDExpression_229942_b() throws Exception {
IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true); IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true);
CPPNameCollector col = new CPPNameCollector(); CPPNameCollector col = new CPPNameCollector();
tu.accept(col); tu.accept(col);
@ -2592,7 +2593,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// template <class T> // template <class T>
// inline const void foo(void (*f)(A<i>), T* t) { // disallowed, but we're testing the AST // inline const void foo(void (*f)(A<i>), T* t) { // disallowed, but we're testing the AST
// } // }
public void _testTypeIdAsTemplateArgumentIsTypeId_229942_g() throws Exception { public void testTypeIdAsTemplateArgumentIsTypeId_229942_g() throws Exception {
IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true); IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true);
CPPNameCollector col = new CPPNameCollector(); CPPNameCollector col = new CPPNameCollector();
tu.accept(col); tu.accept(col);
@ -2605,6 +2606,21 @@ public class AST2TemplateTests extends AST2BaseTest {
assertInstance(col.getName(17).getParent(), IASTIdExpression.class); assertInstance(col.getName(17).getParent(), IASTIdExpression.class);
} }
// typedef int td;
// template<> class Alias<td const *> {
// };
public void testNonAmbiguityCase_229942_h() throws Exception {
IASTTranslationUnit tu= parse(getAboveComment(), ParserLanguage.CPP);
CPPNameCollector col= new CPPNameCollector();
tu.accept(col);
// 2 is Alias
ICPPASTTemplateId tid= assertInstance(col.getName(2).getParent(), ICPPASTTemplateId.class);
IASTNode[] args= tid.getTemplateArguments();
assertEquals(1, args.length);
assertInstance(args[0], IASTTypeId.class);
}
// // From discussion in 207840. See 14.3.4. // // From discussion in 207840. See 14.3.4.
// class A {}; // class A {};
// //

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2008 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
/**
* Place-holder in the AST for template arguments that are not yet
* understood.
*/
public interface ICPPASTAmbiguousTemplateArgument extends IASTNode {
/**
* Add an partial parse tree that could be a suitable subtree representing
* the template argument
* @param idExpression a non-null id-expression
*/
public void addIdExpression(IASTIdExpression idExpression);
/**
* Add an partial parse tree that could be a suitable subtree representing
* the template argument
* @param typeId a non-null type-id
*/
public void addTypeId(IASTTypeId typeId);
}

View file

@ -1,12 +1,13 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others. * Copyright (c) 2004, 2008 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 * IBM - Initial API and implementation
* Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
@ -57,19 +58,24 @@ public interface ICPPASTTemplateId extends IASTName, IASTNameOwner {
/** /**
* Add template argument. * Add template argument.
* *
* @param typeId * @param typeId <code>IASTTypeId</code>
* <code>IASTTypeId</code>
*/ */
public void addTemplateArgument(IASTTypeId typeId); public void addTemplateArgument(IASTTypeId typeId);
/** /**
* Add template argument. * Add template argument.
* *
* @param expression * @param expression <code>IASTExpression</code>
* <code>IASTExpression</code>
*/ */
public void addTemplateArgument(IASTExpression expression); public void addTemplateArgument(IASTExpression expression);
/**
* Add an ambiguity node for later resolution.
*
* @param ambiguity
*/
public void addTemplateArgument(ICPPASTAmbiguousTemplateArgument ambiguity);
/** /**
* Get all template arguments. (as nodes) * Get all template arguments. (as nodes)
* *

View file

@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2008 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument;
import org.eclipse.cdt.internal.core.parser.ParserMessages;
/**
* Ambiguity node for deciding between type-id and id-expression in a template argument.
*/
public class CPPASTAmbiguousTemplateArgument extends CPPASTAmbiguity implements ICPPASTAmbiguousTemplateArgument {
private List<IASTNode> fNodes;
/**
* @param nodes nodes of type {@link IASTTypeId} or {@link IASTIdExpression}
*/
/*
* We can replace this with a version taking ICPPASTTemplateArgument...
* in the future
*/
public CPPASTAmbiguousTemplateArgument(IASTNode... nodes) {
fNodes= new ArrayList<IASTNode>();
for(IASTNode node : nodes) {
if(node instanceof IASTTypeId || node instanceof IASTIdExpression) {
fNodes.add(node);
} else {
String ns= node == null ? "null" : node.getClass().getName(); //$NON-NLS-1$
String msg= MessageFormat.format(ParserMessages.getString("CPPASTAmbiguousTemplateArgument_InvalidConstruction"), ns); //$NON-NLS-1$
throw new IllegalArgumentException(msg);
}
}
}
@Override
protected IASTNode[] getNodes() {
return fNodes.toArray(new IASTNode[fNodes.size()]);
}
public void addTypeId(IASTTypeId typeId) {
addNode(typeId);
}
public void addIdExpression(IASTIdExpression idExpression) {
addNode(idExpression);
}
private void addNode(IASTNode node) {
fNodes.add(node);
node.setParent(this);
node.setPropertyInParent(CPPASTTemplateId.TEMPLATE_ID_ARGUMENT);
}
}

View file

@ -8,6 +8,7 @@
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -20,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
@ -70,6 +72,14 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId, I
} }
} }
public void addTemplateArgument(ICPPASTAmbiguousTemplateArgument ata) {
templateArguments = (IASTNode[]) ArrayUtil.append(IASTNode.class, templateArguments, ata);
if (ata != null) {
ata.setParent(this);
ata.setPropertyInParent(TEMPLATE_ID_ARGUMENT);
}
}
public IASTNode[] getTemplateArguments() { public IASTNode[] getTemplateArguments() {
if (templateArguments == null) return ICPPASTTemplateId.EMPTY_ARG_ARRAY; if (templateArguments == null) return ICPPASTTemplateId.EMPTY_ARG_ARRAY;
return (IASTNode[]) ArrayUtil.trim(IASTNode.class, templateArguments); return (IASTNode[]) ArrayUtil.trim(IASTNode.class, templateArguments);

View file

@ -11,6 +11,7 @@
* Bryan Wilkinson (QNX) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=151207 * Bryan Wilkinson (QNX) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=151207
* Ed Swartz (Nokia) * Ed Swartz (Nokia)
* Mike Kucera (IBM) * Mike Kucera (IBM)
* Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -77,6 +78,7 @@ import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
@ -271,63 +273,86 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return last; return last;
} }
protected List<IASTNode> templateArgumentList() throws EndOfFileException, BacktrackException { protected List<IASTNode> templateArgumentList() throws EndOfFileException, BacktrackException {
IToken start = LA(1); IToken start = LA(1);
int startingOffset = start.getOffset(); int startingOffset = start.getOffset();
int endOffset = 0; int endOffset = 0;
start = null; start = null;
List<IASTNode> list = new ArrayList<IASTNode>(); List<IASTNode> list = new ArrayList<IASTNode>();
boolean completedArg = false; boolean failed = false;
boolean failed = false;
final int initialTemplateIdScopesSize= templateIdScopes.size(); final int initialTemplateIdScopesSize= templateIdScopes.size();
templateIdScopes.push(IToken.tLT); templateIdScopes.push(IToken.tLT);
try { try {
while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) { while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
completedArg = false; IToken argStart = mark();
IASTTypeId typeId = typeId(false);
IToken mark = mark(); if(typeId != null && (LT(1)==IToken.tCOMMA || LT(1)==IToken.tGT || LT(1)==IToken.tEOC)) {
IASTTypeId typeId = typeId(false); // potentially a type-id - check for id-expression ambiguity
if (typeId == null) { IToken typeIdEnd= mark();
backup(mark);
} else if (LT(1) != IToken.tCOMMA && LT(1) != IToken.tGT && LT(1) != IToken.tEOC){
//didn't consume the whole argument, probably confused typeId with idExpression
//backup and try the assignmentExpression
backup(mark);
} else {
list.add(typeId);
completedArg = true;
}
if (!completedArg) {
try {
IASTExpression expression = assignmentExpression();
list.add(expression);
completedArg = true;
} catch (BacktrackException e) {
backup(mark);
}
}
if (LT(1) == IToken.tCOMMA) { backup(argStart);
consume(); try {
} else if (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) { IASTExpression expression = assignmentExpression();
failed = true; if(expression instanceof IASTIdExpression) {
endOffset = LA(1).getEndOffset(); IASTIdExpression idExpression= (IASTIdExpression) expression;
break; if(idExpression.getName() instanceof ICPPASTTemplateId) {
} /*
} * A template-id cannot be used in an id-expression as a template argument.
} *
finally { * 5.1-11 A template-id shall be used as an unqualified-id only as specified in
do { * 14.7.2, 14.7, and 14.5.4.
templateIdScopes.pop(); */
} while (templateIdScopes.size() > initialTemplateIdScopesSize); throw backtrack;
} }
if (failed)
throwBacktrack(startingOffset, endOffset - startingOffset);
return list; if (mark() != typeIdEnd)
throw backtrack;
ICPPASTAmbiguousTemplateArgument ambiguity= createAmbiguousTemplateArgument();
ambiguity.addTypeId(typeId);
ambiguity.addIdExpression(idExpression);
list.add(ambiguity);
} else {
// prefer the typeId at this stage
throw backtrack;
}
} catch (BacktrackException e) {
// no ambiguity - its a type-id
list.add(typeId);
backup(typeIdEnd);
}
} else {
// not a type-id - try as expression
backup(argStart);
try {
IASTExpression expression = assignmentExpression();
list.add(expression);
} catch (BacktrackException e) {
backup(argStart);
}
}
if (LT(1) == IToken.tCOMMA) {
consume();
} else if (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
failed = true;
endOffset = LA(1).getEndOffset();
break;
}
}
}
finally {
do {
templateIdScopes.pop();
} while (templateIdScopes.size() > initialTemplateIdScopesSize);
}
if (failed)
throwBacktrack(startingOffset, endOffset - startingOffset);
return list;
} }
/** /**
@ -1611,6 +1636,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTAmbiguousExpression(); return new CPPASTAmbiguousExpression();
} }
protected ICPPASTAmbiguousTemplateArgument createAmbiguousTemplateArgument() {
return new CPPASTAmbiguousTemplateArgument();
}
protected IASTArraySubscriptExpression createArraySubscriptExpression() { protected IASTArraySubscriptExpression createArraySubscriptExpression() {
return new CPPASTArraySubscriptExpression(); return new CPPASTArraySubscriptExpression();
} }
@ -2540,10 +2569,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (args != null) if (args != null)
for (int i = 0; i < args.size(); ++i) { for (int i = 0; i < args.size(); ++i) {
IASTNode n = args.get(i); IASTNode n = args.get(i);
if (n instanceof IASTTypeId) if (n instanceof IASTTypeId) {
result.addTemplateArgument((IASTTypeId) n); result.addTemplateArgument((IASTTypeId) n);
else if(n instanceof IASTExpression) } else if(n instanceof IASTExpression) {
result.addTemplateArgument((IASTExpression) n); result.addTemplateArgument((IASTExpression) n);
} else if(n instanceof ICPPASTAmbiguousTemplateArgument) {
result.addTemplateArgument((ICPPASTAmbiguousTemplateArgument) n);
}
} }
} }
return result; return result;

View file

@ -349,7 +349,11 @@ public class CPPSemantics {
if (name.getPropertyInParent() == IASTNamedTypeSpecifier.NAME && !(binding instanceof IType || binding instanceof ICPPConstructor)) { if (name.getPropertyInParent() == IASTNamedTypeSpecifier.NAME && !(binding instanceof IType || binding instanceof ICPPConstructor)) {
IASTNode parent = name.getParent().getParent(); IASTNode parent = name.getParent().getParent();
if (parent instanceof IASTTypeId && parent.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) { if (parent instanceof IASTTypeId && parent.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) {
//don't do a problem here if(!(binding instanceof IType)) {
// a type id needs to hold a type
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.name());
}
// don't create a problem here
} else { } else {
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.name()); binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.name());
} }

View file

@ -88,3 +88,4 @@ ASTProblemFactory.error.semantic.dom.invalidRedeclaration=Invalid redeclaration
ASTProblemFactory.error.semantic.dom.recursionInResolution=Recursion while looking up ''{0}'' ASTProblemFactory.error.semantic.dom.recursionInResolution=Recursion while looking up ''{0}''
ASTProblemFactory.error.semantic.dom.badScope=A scope could not be created to represent the name {0} ASTProblemFactory.error.semantic.dom.badScope=A scope could not be created to represent the name {0}
ASTProblemFactory.error.semantic.dom.memberDeclNotFound=A declaration could not be found for this member definition: {0} ASTProblemFactory.error.semantic.dom.memberDeclNotFound=A declaration could not be found for this member definition: {0}
CPPASTAmbiguousTemplateArgument_InvalidConstruction=Internal parser error: Template argument ambiguity constructed with {0}