From d9c2afbec28068ba8716df7d403e2f753879ecb4 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 12 Nov 2008 10:01:07 +0000 Subject: [PATCH] Scalability of parsing nested template ids, bug 246079. --- .../parser/tests/ast2/AST2TemplateTests.java | 35 +++++++++++++++++++ .../dom/parser/cpp/GNUCPPSourceParser.java | 33 +++++++++-------- 2 files changed, 53 insertions(+), 15 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 b8bf471b44d..fba3c3ef9f8 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 @@ -3212,4 +3212,39 @@ public class AST2TemplateTests extends AST2BaseTest { BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); ba.assertNonProblem("x))", 1, ICPPVariable.class); } + + // template class TL {}; + // typedef int T; + // typedef + // TL > > > > + // > > > > > + // > > > > > + // > > > > > + // > > > > > + // type; + public void testNestedArguments_246079() throws Throwable { + final Throwable[] th= {null}; + Thread t= new Thread(){ + @Override + public void run() { + try { + parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); + } catch (Throwable e) { + th[0]= e; + } + } + }; + + t.start(); + t.join(4000); + assertFalse(t.isAlive()); + if (th[0] != null) + throw th[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 a17b614e5b3..6b83d220773 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 @@ -304,28 +304,31 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if(typeId != null && (LT(1)==IToken.tCOMMA || LT(1)==IToken.tGT || LT(1)==IToken.tEOC)) { // potentially a type-id - check for id-expression ambiguity IToken typeIdEnd= mark(); - - backup(argStart); try { - IASTExpression expression = assignmentExpression(); - if(expression instanceof IASTIdExpression) { - IASTIdExpression idExpression= (IASTIdExpression) expression; - if(idExpression.getName() instanceof ICPPASTTemplateId) { - /* - * A template-id cannot be used in an id-expression as a template argument. - * - * 5.1-11 A template-id shall be used as an unqualified-id only as specified in - * 14.7.2, 14.7, and 14.5.4. - */ - throw backtrack; - } + // consider ambiguity with id-expressions, only: + IASTDeclSpecifier declspec= typeId.getDeclSpecifier(); + if (!(declspec instanceof IASTNamedTypeSpecifier)) + throw backtrack; + IASTName name= ((IASTNamedTypeSpecifier) declspec).getName(); + if (!name.contains(typeId)) + throw backtrack; + + // A template-id cannot be used in an id-expression as a template argument + // 5.1-11 A template-id shall be used as an unqualified-id only as specified in + // 14.7.2, 14.7, and 14.5.4. + name= name.getLastName(); + if (name instanceof ICPPASTTemplateId) + throw backtrack; + backup(argStart); + IASTExpression expression = assignmentExpression(); + if (expression instanceof IASTIdExpression) { if (mark() != typeIdEnd) throw backtrack; ICPPASTAmbiguousTemplateArgument ambiguity= createAmbiguousTemplateArgument(); ambiguity.addTypeId(typeId); - ambiguity.addIdExpression(idExpression); + ambiguity.addIdExpression((IASTIdExpression) expression); list.add(ambiguity); } else { // prefer the typeId at this stage