1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-12 10:45:37 +02:00

Fix for a bogus c++-syntax-error and 2 exceptions, bug 223777.

This commit is contained in:
Markus Schorn 2008-03-26 11:35:43 +00:00
parent 064d4429ba
commit 9f5748de37
4 changed files with 165 additions and 117 deletions

View file

@ -5838,4 +5838,15 @@ public class AST2CPPTests extends AST2BaseTest {
assertTrue(td instanceof ITypedef); assertTrue(td instanceof ITypedef);
assertTrue(((ITypedef) td).getType() instanceof ICPPBasicType); assertTrue(((ITypedef) td).getType() instanceof ICPPBasicType);
} }
// void func() {
// int a, b;
// a < b || (a==b && a < b);
// if (a > b) {
// }
// }
public void testResettingTemplateIdScopesStack_Bug223777() throws Exception{
final String code = getContents(1)[0].toString();
parseAndCheckBindings(code);
}
} }

View file

@ -835,13 +835,16 @@ public class CPPVisitor {
IScope scope= getContainingScopeOrNull(name); IScope scope= getContainingScopeOrNull(name);
if (scope == null) { if (scope == null) {
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE, return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE,
name.toCharArray()); name == null ? CharArrayUtils.EMPTY : name.toCharArray());
} }
return scope; return scope;
} }
private static IScope getContainingScopeOrNull(IASTName name) { private static IScope getContainingScopeOrNull(IASTName name) {
if (name == null) {
return null;
}
IASTNode parent = name.getParent(); IASTNode parent = name.getParent();
try { try {
if (parent instanceof ICPPASTTemplateId) { if (parent instanceof ICPPASTTemplateId) {

View file

@ -282,45 +282,49 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
boolean completedArg = false; boolean completedArg = false;
boolean failed = false; boolean failed = false;
final int initialTemplateIdScopesSize= templateIdScopes.size();
templateIdScopes.push(IToken.tLT); templateIdScopes.push(IToken.tLT);
try {
while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
completedArg = false;
while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) { IToken mark = mark();
completedArg = 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);
}
}
IASTTypeId typeId = typeId(false); if (LT(1) == IToken.tCOMMA) {
if (typeId == null) { consume();
backup(mark); } else if (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
} else if (LT(1) != IToken.tCOMMA && LT(1) != IToken.tGT && LT(1) != IToken.tEOC){ failed = true;
//didn't consume the whole argument, probably confused typeId with idExpression endOffset = LA(1).getEndOffset();
//backup and try the assignmentExpression break;
backup(mark); }
} else { }
list.add(typeId); }
completedArg = true; finally {
} do {
if (!completedArg) { templateIdScopes.pop();
try { } while (templateIdScopes.size() > initialTemplateIdScopesSize);
IASTExpression expression = assignmentExpression();
list.add(expression);
completedArg = true;
} catch (BacktrackException e) {
backup(mark);
}
}
if (LT(1) == IToken.tCOMMA) {
consume();
} else if (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
failed = true;
endOffset = LA(1).getEndOffset();
break;
}
} }
templateIdScopes.pop();
if (failed) if (failed)
throwBacktrack(startingOffset, endOffset - startingOffset); throwBacktrack(startingOffset, endOffset - startingOffset);
@ -407,7 +411,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} }
protected IASTExpression conditionalExpression() throws BacktrackException, EndOfFileException { @Override
protected IASTExpression conditionalExpression() throws BacktrackException, EndOfFileException {
final IASTExpression expr= super.conditionalExpression(); final IASTExpression expr= super.conditionalExpression();
if (templateArgListCount > 0) { if (templateArgListCount > 0) {
// bug 104706, don't allow usage of logical operators in template argument lists. // bug 104706, don't allow usage of logical operators in template argument lists.
@ -912,47 +917,52 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IToken mark = mark(); IToken mark = mark();
consume(); consume();
if (templateIdScopes.size() > 0) final int initialSize= templateIdScopes.size();
if (initialSize > 0)
templateIdScopes.push(IToken.tLPAREN); templateIdScopes.push(IToken.tLPAREN);
boolean popped = false; try {
IASTTypeId typeId = null; IASTTypeId typeId = null;
IToken startCastExpression=null; IToken startCastExpression=null;
// If this isn't a type name, then we shouldn't be here // If this isn't a type name, then we shouldn't be here
if (!avoidCastExpressionByHeuristics()) { if (!avoidCastExpressionByHeuristics()) {
typeId = typeId(false); typeId = typeId(false);
}
if (typeId != null && LT(1) == IToken.tRPAREN) {
consume();
startCastExpression=mark();
if (initialSize > 0) {
templateIdScopes.pop();
}
try {
IASTExpression castExpression = castExpression();
mark = null; // clean up mark so that we can garbage collect
return buildTypeIdUnaryExpression(IASTCastExpression.op_cast,
typeId, castExpression, startingOffset,
calculateEndOffset(castExpression));
} catch (BacktrackException b) {
try {
// try a compoundStatementExpression
backup(startCastExpression);
if (LT(1) == IToken.tLPAREN) {
IASTExpression castExpression = compoundStatementExpression();
mark = null; // clean up mark so that we can garbage collect
return buildTypeIdUnaryExpression(IASTCastExpression.op_cast,
typeId, castExpression, startingOffset,
calculateEndOffset(castExpression));
}
} catch (BacktrackException bte2) {}
}
}
backup(mark);
}
finally {
while (templateIdScopes.size() > initialSize) {
templateIdScopes.pop();
}
} }
if (typeId != null && LT(1) == IToken.tRPAREN) {
consume();
startCastExpression=mark();
if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
popped = true;
}
try {
IASTExpression castExpression = castExpression();
mark = null; // clean up mark so that we can garbage collect
return buildTypeIdUnaryExpression(IASTCastExpression.op_cast,
typeId, castExpression, startingOffset,
calculateEndOffset(castExpression));
} catch (BacktrackException b) {
try {
// try a compoundStatementExpression
backup(startCastExpression);
if (LT(1) == IToken.tLPAREN) {
IASTExpression castExpression = compoundStatementExpression();
mark = null; // clean up mark so that we can garbage collect
return buildTypeIdUnaryExpression(IASTCastExpression.op_cast,
typeId, castExpression, startingOffset,
calculateEndOffset(castExpression));
}
} catch (BacktrackException bte2) {}
}
}
backup(mark);
if (templateIdScopes.size() > 0 && !popped) { templateIdScopes.pop(); }
} }
return unaryExpression(); return unaryExpression();
@ -1395,13 +1405,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IASTName name = createName(nestedName); IASTName name = createName(nestedName);
consume(IToken.tLPAREN); consume(IToken.tLPAREN);
int lastOffset;
IASTExpression expressionList;
if (templateIdScopes.size() > 0) { if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN); templateIdScopes.push(IToken.tLPAREN);
} }
IASTExpression expressionList = expression(); try {
int lastOffset = consume(IToken.tRPAREN).getEndOffset(); expressionList = expression();
if (templateIdScopes.size() > 0) { lastOffset = consume(IToken.tRPAREN).getEndOffset();
templateIdScopes.pop(); }
finally {
if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
}
} }
ICPPASTTypenameExpression result = createTypenameExpression(); ICPPASTTypenameExpression result = createTypenameExpression();
@ -1460,10 +1476,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) { if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN); templateIdScopes.push(IToken.tLPAREN);
} }
IASTNode[] n = parseTypeIdOrUnaryExpression(false); IASTNode[] n;
lastOffset = consume(IToken.tRPAREN).getEndOffset(); try {
if (templateIdScopes.size() > 0) { n= parseTypeIdOrUnaryExpression(false);
templateIdScopes.pop(); lastOffset = consume(IToken.tRPAREN).getEndOffset();
}
finally {
if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
}
} }
switch (n.length) { switch (n.length) {
@ -1509,18 +1530,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) { if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLBRACKET); templateIdScopes.push(IToken.tLBRACKET);
} }
secondExpression = expression();
int lastOffset; int lastOffset;
switch (LT(1)) { try {
case IToken.tRBRACKET: secondExpression = expression();
case IToken.tEOC: switch (LT(1)) {
lastOffset = consume().getEndOffset(); case IToken.tRBRACKET:
break; case IToken.tEOC:
default: lastOffset = consume().getEndOffset();
throw backtrack; break;
default:
throw backtrack;
}
} }
if (templateIdScopes.size() > 0) { finally {
templateIdScopes.pop(); if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
}
} }
IASTArraySubscriptExpression s = createArraySubscriptExpression(); IASTArraySubscriptExpression s = createArraySubscriptExpression();
@ -1537,21 +1562,24 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) { if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN); templateIdScopes.push(IToken.tLPAREN);
} }
if (LT(1) != IToken.tRPAREN) try {
secondExpression = expression(); if (LT(1) != IToken.tRPAREN)
else secondExpression = expression();
secondExpression = null; else
switch (LT(1)) { secondExpression = null;
case IToken.tRPAREN: switch (LT(1)) {
case IToken.tEOC: case IToken.tRPAREN:
lastOffset = consume().getEndOffset(); case IToken.tEOC:
break; lastOffset = consume().getEndOffset();
default: break;
throw backtrack; default:
throw backtrack;
}
} }
finally {
if (templateIdScopes.size() > 0) { if (templateIdScopes.size() > 0) {
templateIdScopes.pop(); templateIdScopes.pop();
}
} }
IASTFunctionCallExpression fce = createFunctionCallExpression(); IASTFunctionCallExpression fce = createFunctionCallExpression();
@ -1743,16 +1771,21 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) { if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN); templateIdScopes.push(IToken.tLPAREN);
} }
IASTExpression lhs = expression();
int finalOffset= 0; int finalOffset= 0;
if (LT(1) == IToken.tRPAREN) { IASTExpression lhs;
finalOffset = consume().getEndOffset(); try {
} else { lhs = expression();
// missing parenthesis, assume it's there and keep going. if (LT(1) == IToken.tRPAREN) {
finalOffset = LA(1).getOffset(); finalOffset = consume().getEndOffset();
} else {
// missing parenthesis, assume it's there and keep going.
finalOffset = LA(1).getOffset();
}
} }
if (templateIdScopes.size() > 0) { finally {
templateIdScopes.pop(); if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
}
} }
return buildUnaryExpression(IASTUnaryExpression.op_bracketedPrimary, lhs, t.getOffset(), finalOffset); return buildUnaryExpression(IASTUnaryExpression.op_bracketedPrimary, lhs, t.getOffset(), finalOffset);
case IToken.tIDENTIFIER: case IToken.tIDENTIFIER:

View file

@ -89,12 +89,13 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICP
IParameter[] sParams= sFunc.getParameters(); IParameter[] sParams= sFunc.getParameters();
IType[] sParamTypes= sFunc.getType().getParameterTypes(); IType[] sParamTypes= sFunc.getType().getParameterTypes();
final int length= Math.min(sParamTypes.length, params.length); final int length= Math.min(sParams.length, params.length);
db.putInt(record + NUM_PARAMS, length); db.putInt(record + NUM_PARAMS, length);
for (int i=0; i<length; ++i) { for (int i=0; i<length; ++i) {
int typeRecord= i<paramTypes.length && paramTypes[i]!=null ? ((PDOMNode)paramTypes[i]).getRecord() : 0; int typeRecord= i<paramTypes.length && paramTypes[i]!=null ? ((PDOMNode)paramTypes[i]).getRecord() : 0;
//TODO shouldn't need to make new parameter (find old one) //TODO shouldn't need to make new parameter (find old one)
PDOMCPPParameter sParam = new PDOMCPPParameter(pdom, this, sParams[i], sParamTypes[i]); final IType type= i<sParamTypes.length ? sParamTypes[i] : null;
PDOMCPPParameter sParam = new PDOMCPPParameter(pdom, this, sParams[i], type);
setFirstParameter(new PDOMCPPParameterSpecialization(pdom, this, (ICPPParameter) params[i], sParam, typeRecord)); setFirstParameter(new PDOMCPPParameterSpecialization(pdom, this, (ICPPParameter) params[i], sParam, typeRecord));
} }
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function)); db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function));