Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java265
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java5
4 files changed, 167 insertions, 119 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index b5ac586d43a..1c45cada70c 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -5838,4 +5838,15 @@ public class AST2CPPTests extends AST2BaseTest {
assertTrue(td instanceof ITypedef);
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);
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java
index d7a13d4d5c6..f4aed3c18e0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java
@@ -835,13 +835,16 @@ public class CPPVisitor {
IScope scope= getContainingScopeOrNull(name);
if (scope == null) {
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE,
- name.toCharArray());
+ name == null ? CharArrayUtils.EMPTY : name.toCharArray());
}
return scope;
}
private static IScope getContainingScopeOrNull(IASTName name) {
+ if (name == null) {
+ return null;
+ }
IASTNode parent = name.getParent();
try {
if (parent instanceof ICPPASTTemplateId) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index 72aaf4afc23..fd2149b56a4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -282,45 +282,49 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
boolean completedArg = 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;
+
+ 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);
+ }
+ }
- while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
- 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);
- }
- }
-
- if (LT(1) == IToken.tCOMMA) {
- consume();
- } else if (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
- failed = true;
- endOffset = LA(1).getEndOffset();
- break;
- }
+ 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);
}
-
- templateIdScopes.pop();
-
if (failed)
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();
if (templateArgListCount > 0) {
// 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();
consume();
- if (templateIdScopes.size() > 0)
- templateIdScopes.push(IToken.tLPAREN);
-
- boolean popped = false;
- IASTTypeId typeId = null;
- IToken startCastExpression=null;
+ final int initialSize= templateIdScopes.size();
+ if (initialSize > 0)
+ templateIdScopes.push(IToken.tLPAREN);
- // If this isn't a type name, then we shouldn't be here
- if (!avoidCastExpressionByHeuristics()) {
- typeId = typeId(false);
+ try {
+ IASTTypeId typeId = null;
+ IToken startCastExpression=null;
+
+ // If this isn't a type name, then we shouldn't be here
+ if (!avoidCastExpressionByHeuristics()) {
+ 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();
@@ -1395,13 +1405,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IASTName name = createName(nestedName);
consume(IToken.tLPAREN);
+ int lastOffset;
+ IASTExpression expressionList;
if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN);
}
- IASTExpression expressionList = expression();
- int lastOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
+ try {
+ expressionList = expression();
+ lastOffset = consume(IToken.tRPAREN).getEndOffset();
+ }
+ finally {
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
}
ICPPASTTypenameExpression result = createTypenameExpression();
@@ -1460,10 +1476,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN);
}
- IASTNode[] n = parseTypeIdOrUnaryExpression(false);
- lastOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
+ IASTNode[] n;
+ try {
+ n= parseTypeIdOrUnaryExpression(false);
+ lastOffset = consume(IToken.tRPAREN).getEndOffset();
+ }
+ finally {
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
}
switch (n.length) {
@@ -1509,18 +1530,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLBRACKET);
}
- secondExpression = expression();
int lastOffset;
- switch (LT(1)) {
- case IToken.tRBRACKET:
- case IToken.tEOC:
- lastOffset = consume().getEndOffset();
- break;
- default:
- throw backtrack;
+ try {
+ secondExpression = expression();
+ switch (LT(1)) {
+ case IToken.tRBRACKET:
+ case IToken.tEOC:
+ lastOffset = consume().getEndOffset();
+ break;
+ default:
+ throw backtrack;
+ }
}
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
+ finally {
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
}
IASTArraySubscriptExpression s = createArraySubscriptExpression();
@@ -1537,21 +1562,24 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN);
}
- if (LT(1) != IToken.tRPAREN)
- secondExpression = expression();
- else
- secondExpression = null;
- switch (LT(1)) {
- case IToken.tRPAREN:
- case IToken.tEOC:
- lastOffset = consume().getEndOffset();
- break;
- default:
- throw backtrack;
+ try {
+ if (LT(1) != IToken.tRPAREN)
+ secondExpression = expression();
+ else
+ secondExpression = null;
+ switch (LT(1)) {
+ case IToken.tRPAREN:
+ case IToken.tEOC:
+ lastOffset = consume().getEndOffset();
+ break;
+ default:
+ throw backtrack;
+ }
}
-
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
+ finally {
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
}
IASTFunctionCallExpression fce = createFunctionCallExpression();
@@ -1743,16 +1771,21 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN);
}
- IASTExpression lhs = expression();
int finalOffset= 0;
- if (LT(1) == IToken.tRPAREN) {
- finalOffset = consume().getEndOffset();
- } else {
- // missing parenthesis, assume it's there and keep going.
- finalOffset = LA(1).getOffset();
+ IASTExpression lhs;
+ try {
+ lhs = expression();
+ if (LT(1) == IToken.tRPAREN) {
+ finalOffset = consume().getEndOffset();
+ } else {
+ // missing parenthesis, assume it's there and keep going.
+ finalOffset = LA(1).getOffset();
+ }
}
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
+ finally {
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
}
return buildUnaryExpression(IASTUnaryExpression.op_bracketedPrimary, lhs, t.getOffset(), finalOffset);
case IToken.tIDENTIFIER:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java
index 0aec19b659c..de07d2332eb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java
@@ -89,12 +89,13 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization implements ICP
IParameter[] sParams= sFunc.getParameters();
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);
for (int i=0; i<length; ++i) {
int typeRecord= i<paramTypes.length && paramTypes[i]!=null ? ((PDOMNode)paramTypes[i]).getRecord() : 0;
//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));
}
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function));

Back to the top