1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 10:46:02 +02:00

Follow up on ambiguity between template args and binary expression, bug 104706.

This commit is contained in:
Markus Schorn 2008-03-17 21:49:40 +00:00
parent 93003bf673
commit 366bb49c07

View file

@ -139,9 +139,7 @@ import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.util.ASTPrinter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.DebugUtil;
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.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser; import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
@ -171,6 +169,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private ScopeStack templateIdScopes = new ScopeStack(); private ScopeStack templateIdScopes = new ScopeStack();
private int templateCount = 0; private int templateCount = 0;
private int functionBodyCount= 0;
private int templateArgListCount= 0;
protected CPPASTTranslationUnit translationUnit; protected CPPASTTranslationUnit translationUnit;
@ -358,12 +358,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
case IToken.tEOC: case IToken.tEOC:
last = consume(); last = consume();
if (!fNoTemplateArguments) { IToken templateLast = consumeTemplateArguments(last, argumentList);
IToken templateLast = consumeTemplateArguments(last, argumentList); if (last != templateLast) {
if (last != templateLast) { last = templateLast;
last = templateLast; hasTemplateId = true;
hasTemplateId = true;
}
} }
break; break;
@ -375,11 +373,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} }
while (LT(1) == IToken.tCOLONCOLON) { while (LT(1) == IToken.tCOLONCOLON) {
boolean checkTemplateArgs= !fNoTemplateArguments;
last = consume(); last = consume();
if (LT(1) == IToken.t_template) { if (LT(1) == IToken.t_template) {
checkTemplateArgs= true;
consume(); consume();
} }
@ -395,9 +391,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
case IToken.tEOC: case IToken.tEOC:
last = consume(); last = consume();
if (checkTemplateArgs) { last = consumeTemplateArguments(last, argumentList);
last = consumeTemplateArguments(last, argumentList);
}
if (last.getType() == IToken.tGT || last.getType() == IToken.tEOC) if (last.getType() == IToken.tGT || last.getType() == IToken.tEOC)
hasTemplateId = true; hasTemplateId = true;
} }
@ -413,12 +407,29 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} }
/** protected IASTExpression conditionalExpression() throws BacktrackException, EndOfFileException {
*/ final IASTExpression expr= super.conditionalExpression();
protected IToken consumeTemplateArguments(IToken last, TemplateParameterManager argumentList) throws EndOfFileException, BacktrackException { if (templateArgListCount > 0) {
// bug 104706, don't allow usage of logical operators in template argument lists.
if (expr instanceof IASTConditionalExpression)
throw new BacktrackException();
if (expr instanceof IASTBinaryExpression) {
IASTBinaryExpression bexpr= (IASTBinaryExpression) expr;
switch (bexpr.getOperator()) {
case IASTBinaryExpression.op_logicalAnd:
case IASTBinaryExpression.op_logicalOr:
throw new BacktrackException();
}
}
}
return expr;
}
protected IToken consumeTemplateArguments(IToken last, TemplateParameterManager argumentList) throws EndOfFileException, BacktrackException {
if (LT(1) == IToken.tLT) { if (LT(1) == IToken.tLT) {
IToken secondMark = mark(); IToken secondMark = mark();
consume(); consume();
templateArgListCount++;
try { try {
List<IASTNode> list = templateArgumentList(); List<IASTNode> list = templateArgumentList();
argumentList.addSegment(list); argumentList.addSegment(list);
@ -437,6 +448,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} catch (BacktrackException bt) { } catch (BacktrackException bt) {
argumentList.addSegment(null); argumentList.addSegment(null);
backup(secondMark); backup(secondMark);
} finally {
templateArgListCount--;
} }
} else { } else {
argumentList.addSegment(null); argumentList.addSegment(null);
@ -1862,8 +1875,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private final IIndex index; private final IIndex index;
private boolean fNoTemplateArguments;
private static final int DEFAULT_PARM_LIST_SIZE = 4; private static final int DEFAULT_PARM_LIST_SIZE = 4;
private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4; private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4;
@ -4696,22 +4707,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (lt1 == expectToken || lt1 == IToken.tEOC) { if (lt1 == expectToken || lt1 == IToken.tEOC) {
return e; return e;
} }
if (!fNoTemplateArguments) {
// bug 104706, ambiguity between template arguments and conditional expression,
// try without template args
backup(mark);
try {
fNoTemplateArguments= true;
e= expression();
final int lt11= LT(1);
if (lt11 == expectToken || lt11 == IToken.tEOC) {
return e;
}
}
finally {
fNoTemplateArguments= false;
}
}
throwBacktrack(LA(1)); throwBacktrack(LA(1));
} catch (BacktrackException bt) { } catch (BacktrackException bt) {
backup(mark); backup(mark);
@ -4733,8 +4728,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private static final EmptyVisitor EMPTY_VISITOR = new EmptyVisitor(); private static final EmptyVisitor EMPTY_VISITOR = new EmptyVisitor();
private int functionBodyCount;
@Override @Override
protected ASTVisitor createVisitor() { protected ASTVisitor createVisitor() {
return EMPTY_VISITOR; return EMPTY_VISITOR;