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.IASTIdExpression;
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.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBasicType;
@ -2478,7 +2479,7 @@ public class AST2TemplateTests extends AST2BaseTest {
//
// const int i= 1;
// 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);
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
@ -2497,7 +2498,7 @@ public class AST2TemplateTests extends AST2BaseTest {
//
// 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);
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
@ -2592,7 +2593,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// template <class T>
// 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);
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
@ -2605,6 +2606,21 @@ public class AST2TemplateTests extends AST2BaseTest {
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.
// 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
* 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:
* IBM - Initial API and implementation
* IBM - Initial API and implementation
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -57,19 +58,24 @@ public interface ICPPASTTemplateId extends IASTName, IASTNameOwner {
/**
* Add template argument.
*
* @param typeId
* <code>IASTTypeId</code>
* @param typeId <code>IASTTypeId</code>
*/
public void addTemplateArgument(IASTTypeId typeId);
/**
* Add template argument.
*
* @param expression
* <code>IASTExpression</code>
* @param expression <code>IASTExpression</code>
*/
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)
*

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:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
*******************************************************************************/
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.IASTTypeId;
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.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage;
@ -69,6 +71,14 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId, I
expression.setPropertyInParent(TEMPLATE_ID_ARGUMENT);
}
}
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() {
if (templateArguments == null) return ICPPASTTemplateId.EMPTY_ARG_ARRAY;

View file

@ -11,6 +11,7 @@
* Bryan Wilkinson (QNX) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=151207
* Ed Swartz (Nokia)
* Mike Kucera (IBM)
* Andrew Ferguson (Symbian)
*******************************************************************************/
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.IScope;
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.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
@ -270,64 +272,87 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
return last;
}
protected List<IASTNode> templateArgumentList() throws EndOfFileException, BacktrackException {
IToken start = LA(1);
int startingOffset = start.getOffset();
int endOffset = 0;
start = null;
List<IASTNode> list = new ArrayList<IASTNode>();
IToken start = LA(1);
int startingOffset = start.getOffset();
int endOffset = 0;
start = null;
List<IASTNode> list = new ArrayList<IASTNode>();
boolean completedArg = false;
boolean failed = false;
boolean failed = false;
final int initialTemplateIdScopesSize= templateIdScopes.size();
templateIdScopes.push(IToken.tLT);
try {
while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
completedArg = false;
final int initialTemplateIdScopesSize= templateIdScopes.size();
templateIdScopes.push(IToken.tLT);
try {
while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
IToken argStart = mark();
IASTTypeId typeId = typeId(false);
IToken mark = mark();
IASTTypeId typeId = typeId(false);
if (typeId == null) {
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(typeId != null && (LT(1)==IToken.tCOMMA || LT(1)==IToken.tGT || LT(1)==IToken.tEOC)) {
// potentially a type-id - check for id-expression ambiguity
IToken typeIdEnd= mark();
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);
backup(argStart);
try {
IASTExpression expression = assignmentExpression();
if(expression instanceof IASTIdExpression) {
IASTIdExpression idExpression= (IASTIdExpression) expression;
if(idExpression.getName() instanceof ICPPASTTemplateId) {
/*
* A template-id cannot be used in an id-expression as a template argument.
*
* 5.1-11 A template-id shall be used as an unqualified-id only as specified in
* 14.7.2, 14.7, and 14.5.4.
*/
throw backtrack;
}
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;
}
/**
@ -1610,6 +1635,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
protected IASTAmbiguousExpression createAmbiguousExpression() {
return new CPPASTAmbiguousExpression();
}
protected ICPPASTAmbiguousTemplateArgument createAmbiguousTemplateArgument() {
return new CPPASTAmbiguousTemplateArgument();
}
protected IASTArraySubscriptExpression createArraySubscriptExpression() {
return new CPPASTArraySubscriptExpression();
@ -2540,10 +2569,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (args != null)
for (int i = 0; i < args.size(); ++i) {
IASTNode n = args.get(i);
if (n instanceof IASTTypeId)
if (n instanceof IASTTypeId) {
result.addTemplateArgument((IASTTypeId) n);
else if(n instanceof IASTExpression)
} else if(n instanceof IASTExpression) {
result.addTemplateArgument((IASTExpression) n);
} else if(n instanceof ICPPASTAmbiguousTemplateArgument) {
result.addTemplateArgument((ICPPASTAmbiguousTemplateArgument) n);
}
}
}
return result;

View file

@ -349,7 +349,11 @@ public class CPPSemantics {
if (name.getPropertyInParent() == IASTNamedTypeSpecifier.NAME && !(binding instanceof IType || binding instanceof ICPPConstructor)) {
IASTNode parent = name.getParent().getParent();
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 {
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.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}
CPPASTAmbiguousTemplateArgument_InvalidConstruction=Internal parser error: Template argument ambiguity constructed with {0}