mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-12 02:35:37 +02:00
Fix for a bogus c++-syntax-error and 2 exceptions, bug 223777.
This commit is contained in:
parent
064d4429ba
commit
9f5748de37
4 changed files with 165 additions and 117 deletions
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
templateIdScopes.push(IToken.tLPAREN);
|
if (initialSize > 0)
|
||||||
|
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:
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Add table
Reference in a new issue