Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorNathan Ridge2018-01-12 03:56:01 +0000
committerNathan Ridge2018-01-25 22:04:38 +0000
commit8d1afc2d77ceea7b7bb7a91892f4ff79fd7c6207 (patch)
tree8988adae75216354d782cb966b5a2014332afbf5 /core
parent7754023edaec9cde51fed6500c62f50ced621b92 (diff)
downloadorg.eclipse.cdt-8d1afc2d77ceea7b7bb7a91892f4ff79fd7c6207.tar.gz
org.eclipse.cdt-8d1afc2d77ceea7b7bb7a91892f4ff79fd7c6207.tar.xz
org.eclipse.cdt-8d1afc2d77ceea7b7bb7a91892f4ff79fd7c6207.zip
Bug 529696 - Propagate the template-id strategy into names contained within a type template argument
This avoids expontential complexity when type template arguments inside an ambiguous name specifier themselves contain ambiguous name specifiers. The patch also enhances TemplateIdStrategy to allow marking and backing up to a branch point, and uses this ability in templateArgument(). Change-Id: Ia03e9cd0bc026b02b85edc05ed327cce883d6a59
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java14
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java19
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java25
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/TemplateIdStrategy.java18
5 files changed, 66 insertions, 13 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index a6cff09c463..98223b1759e 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -10537,4 +10537,18 @@ public class AST2TemplateTests extends AST2CPPTestBase {
IType waldo = helper.assertNonProblem("Waldo");
assertSameType(CommonCPPTypes.void_, waldo);
}
+
+ // template <int, int, int, int, int, int, int, int> int constant8f();
+ //
+ // template <int i0, int i1, int i2, int i3>
+ // void foo() {
+ // constant8f<
+ // i0 < 0, i0 < 0,
+ // i1 < 0, i1 < 0,
+ // i2 < 0, i2 < 0,
+ // i3 < 0, i3 < 0>();
+ // }
+ public void testTemplateIdAmbiguity_529696() throws Exception {
+ parseAndCheckBindings();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
index 3ff0f8204f9..1a9ed31648a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
@@ -1631,19 +1631,32 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTDeclaration declaration(DeclarationOptions option) throws BacktrackException, EndOfFileException;
+ protected Decl declSpecifierSeq(DeclarationOptions option) throws BacktrackException, EndOfFileException {
+ return declSpecifierSeq(option, null);
+ }
+
/**
* Parses for two alternatives of a declspec sequence. If there is a second alternative the token after the second alternative
* is returned, such that the parser can continue after both variants.
*/
- protected abstract Decl declSpecifierSeq(DeclarationOptions option) throws BacktrackException, EndOfFileException;
+ protected abstract Decl declSpecifierSeq(DeclarationOptions option, ITemplateIdStrategy strat)
+ throws BacktrackException, EndOfFileException;
+ protected Decl declSpecifierSequence_initDeclarator(final DeclarationOptions option,
+ boolean acceptCompoundWithoutDtor)
+ throws EndOfFileException, FoundAggregateInitializer, BacktrackException {
+ return declSpecifierSequence_initDeclarator(option, acceptCompoundWithoutDtor, null);
+ }
+
/**
* Parses for two alternatives of a declspec sequence followed by a initDeclarator.
* A second alternative is accepted only, if it ends at the same point of the first alternative. Otherwise the
* longer alternative is selected.
*/
- protected Decl declSpecifierSequence_initDeclarator(final DeclarationOptions option, boolean acceptCompoundWithoutDtor) throws EndOfFileException, FoundAggregateInitializer, BacktrackException {
- Decl result= declSpecifierSeq(option);
+ protected Decl declSpecifierSequence_initDeclarator(final DeclarationOptions option,
+ boolean acceptCompoundWithoutDtor, ITemplateIdStrategy strat)
+ throws EndOfFileException, FoundAggregateInitializer, BacktrackException {
+ Decl result= declSpecifierSeq(option, strat);
final int lt1 = LTcatchEOF(1);
if (lt1 == IToken.tEOC)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
index b88e8c630e8..2622b978491 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
@@ -911,7 +911,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
SHORT=0x10, UNSIGNED= 0x20, SIGNED=0x40, COMPLEX=0x80, IMAGINARY=0x100;
@Override
- protected Decl declSpecifierSeq(final DeclarationOptions declOption) throws BacktrackException, EndOfFileException {
+ protected Decl declSpecifierSeq(final DeclarationOptions declOption, ITemplateIdStrategy strat)
+ throws BacktrackException, EndOfFileException {
int storageClass= IASTDeclSpecifier.sc_unspecified;
int simpleType= IASTSimpleDeclSpecifier.t_unspecified;
int options= 0;
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 cefa059c626..083e07dd0ab 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
@@ -751,10 +751,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private IASTNode templateArgument(ITemplateIdStrategy strat) throws EndOfFileException, BacktrackException {
IToken argStart = mark();
+ int markBranchPoint = ((TemplateIdStrategy) strat).getCurrentBranchPoint();
ICPPASTTypeId typeId= null;
int lt1= 0;
try {
- typeId= typeId(DeclarationOptions.TYPEID);
+ typeId= typeId(DeclarationOptions.TYPEID, strat);
lt1 = LT(1);
} catch (BacktrackException e) {
if (e.isFatal()) {
@@ -849,6 +850,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// Not a type-id, parse as expression.
backup(argStart);
+ ((TemplateIdStrategy) strat).backupToBranchPoint(markBranchPoint);
IASTExpression expr= expression(ExprKind.eAssignment, BinaryExprCtx.eInTemplateID, null, strat);
if (LT(1) == IToken.tELLIPSIS) {
expr= addPackExpansion(expr, consume());
@@ -3058,21 +3060,23 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* {"enum"} enumSpecifier
*/
@Override
- protected Decl declSpecifierSeq(final DeclarationOptions option) throws BacktrackException, EndOfFileException {
- return declSpecifierSeq(option, false);
+ protected Decl declSpecifierSeq(final DeclarationOptions option, ITemplateIdStrategy strat)
+ throws BacktrackException, EndOfFileException {
+ return declSpecifierSeq(option, false, strat);
}
private ICPPASTDeclSpecifier simpleTypeSpecifier() throws BacktrackException, EndOfFileException {
- Decl d= declSpecifierSeq(null, true);
+ Decl d= declSpecifierSeq(null, true, null);
return (ICPPASTDeclSpecifier) d.fDeclSpec1;
}
private ICPPASTDeclSpecifier simpleTypeSpecifierSequence() throws BacktrackException, EndOfFileException {
- Decl d= declSpecifierSeq(null, false);
+ Decl d= declSpecifierSeq(null, false, null);
return (ICPPASTDeclSpecifier) d.fDeclSpec1;
}
- private Decl declSpecifierSeq(final DeclarationOptions option, final boolean single) throws BacktrackException, EndOfFileException {
+ private Decl declSpecifierSeq(final DeclarationOptions option, final boolean single,
+ ITemplateIdStrategy strat) throws BacktrackException, EndOfFileException {
int storageClass = IASTDeclSpecifier.sc_unspecified;
int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
int options= 0;
@@ -3332,7 +3336,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
}
- identifier= qualifiedName();
+ identifier= qualifiedName(CastExprCtx.eNotInBExpr, strat);
if (identifier.getLookupKey().length == 0 && LT(1) != IToken.tEOC)
throwBacktrack(LA(1));
@@ -4169,6 +4173,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
@Override
protected ICPPASTTypeId typeId(DeclarationOptions option) throws EndOfFileException, BacktrackException {
+ return typeId(option, null);
+ }
+
+ protected ICPPASTTypeId typeId(DeclarationOptions option, ITemplateIdStrategy strat)
+ throws EndOfFileException, BacktrackException {
if (!canBeTypeSpecifier()) {
throwBacktrack(LA(1));
}
@@ -4177,7 +4186,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IASTDeclarator declarator = null;
try {
- Decl decl= declSpecifierSequence_initDeclarator(option, false);
+ Decl decl= declSpecifierSequence_initDeclarator(option, false, strat);
declSpecifier= decl.fDeclSpec1;
declarator= decl.fDtor1;
} catch (FoundAggregateInitializer lie) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/TemplateIdStrategy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/TemplateIdStrategy.java
index 0eec024fe6f..7e0a92a890e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/TemplateIdStrategy.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/TemplateIdStrategy.java
@@ -27,7 +27,7 @@ import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.ITem
* When parsing, we potentially need to consider both possibilities for each use of '<'.
*
* An instance of this class is used to track alternative parses in a segment of code that includes one or
- * more uses of '<' preceded by names. An alternative consists of a choices (template-id or not) for each
+ * more uses of '<' preceded by names. An alternative consists of a choice (template-id or not) for each
* name. At a given point in time, the instance has a notion of a current alternative, and a current
* position within that alternative.
*
@@ -145,4 +145,20 @@ final class TemplateIdStrategy implements ITemplateIdStrategy {
public IASTName[] getTemplateNames() {
return ArrayUtil.trim(fTemplateNames);
}
+
+ /**
+ * Sometimes, a BacktrackException can be thrown and handled during the processing
+ * of a single alternative (that is, the exception does not bubble up all the way
+ * to the point where setNextAlternative() would be called). In such a case, when
+ * backtracking we need to restore the branch point that was active at the point
+ * we're backing up to (otherwise, the current branch point could get out of sync
+ * with the parsing position). These methods facilitate marking and backing up to
+ * the current branch point for such situations.
+ */
+ public int getCurrentBranchPoint() {
+ return fCurrentBranchPoint;
+ }
+ public void backupToBranchPoint(int branchPoint) {
+ fCurrentBranchPoint = branchPoint;
+ }
} \ No newline at end of file

Back to the top