1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Scalability of parsing nested template ids, bug 246079.

This commit is contained in:
Markus Schorn 2008-11-12 10:01:07 +00:00
parent ab6e2bd18c
commit d9c2afbec2
2 changed files with 53 additions and 15 deletions

View file

@ -3212,4 +3212,39 @@ public class AST2TemplateTests extends AST2BaseTest {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
ba.assertNonProblem("x))", 1, ICPPVariable.class); ba.assertNonProblem("x))", 1, ICPPVariable.class);
} }
// template<typename T, typename U> class TL {};
// typedef int T;
// typedef
// TL<T, TL< T, TL< T, TL< T, TL<T,
// TL<T, TL< T, TL< T, TL< T, TL<T,
// TL<T, TL< T, TL< T, TL< T, TL<T,
// TL<T, TL< T, TL< T, TL< T, TL<T,
// TL<T, TL< T, TL< T, TL< T, TL<T,
// T
// > > > > >
// > > > > >
// > > > > >
// > > > > >
// > > > > >
// 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];
}
} }

View file

@ -304,28 +304,31 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if(typeId != null && (LT(1)==IToken.tCOMMA || LT(1)==IToken.tGT || LT(1)==IToken.tEOC)) { if(typeId != null && (LT(1)==IToken.tCOMMA || LT(1)==IToken.tGT || LT(1)==IToken.tEOC)) {
// potentially a type-id - check for id-expression ambiguity // potentially a type-id - check for id-expression ambiguity
IToken typeIdEnd= mark(); IToken typeIdEnd= mark();
backup(argStart);
try { try {
IASTExpression expression = assignmentExpression(); // consider ambiguity with id-expressions, only:
if(expression instanceof IASTIdExpression) { IASTDeclSpecifier declspec= typeId.getDeclSpecifier();
IASTIdExpression idExpression= (IASTIdExpression) expression; if (!(declspec instanceof IASTNamedTypeSpecifier))
if(idExpression.getName() instanceof ICPPASTTemplateId) { throw backtrack;
/* IASTName name= ((IASTNamedTypeSpecifier) declspec).getName();
* A template-id cannot be used in an id-expression as a template argument. if (!name.contains(typeId))
* throw backtrack;
* 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. // 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
throw backtrack; // 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) if (mark() != typeIdEnd)
throw backtrack; throw backtrack;
ICPPASTAmbiguousTemplateArgument ambiguity= createAmbiguousTemplateArgument(); ICPPASTAmbiguousTemplateArgument ambiguity= createAmbiguousTemplateArgument();
ambiguity.addTypeId(typeId); ambiguity.addTypeId(typeId);
ambiguity.addIdExpression(idExpression); ambiguity.addIdExpression((IASTIdExpression) expression);
list.add(ambiguity); list.add(ambiguity);
} else { } else {
// prefer the typeId at this stage // prefer the typeId at this stage