1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-06 15:55:47 +02:00

Bug 333285: Non-type template parameter with leading typename keyword.

This commit is contained in:
Markus Schorn 2011-01-07 11:16:33 +00:00
parent 3a300ec622
commit c3d083bf06
2 changed files with 119 additions and 88 deletions

View file

@ -5173,4 +5173,17 @@ public class AST2TemplateTests extends AST2BaseTest {
public void testSpecializationViaNotDirectlyEnclosingTemplate_Bug333186() throws Exception { public void testSpecializationViaNotDirectlyEnclosingTemplate_Bug333186() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename T> struct A {
// typedef T type;
// };
// template <typename T> struct X {
// template <typename A<T>::type x> struct Y {};
// };
//
// struct C {};
// template <class C& c> class Z{};
public void testNonTypeTemplateParameterWithTypenameKeyword_Bug333186() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -1756,17 +1756,29 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* request for a backtrack * request for a backtrack
*/ */
protected List<ICPPASTTemplateParameter> templateParameterList() throws BacktrackException, EndOfFileException { protected List<ICPPASTTemplateParameter> templateParameterList() throws BacktrackException, EndOfFileException {
// if we have gotten this far then we have a true template-declaration List<ICPPASTTemplateParameter> result = new ArrayList<ICPPASTTemplateParameter>(DEFAULT_PARM_LIST_SIZE);
// iterate through the template parameter list boolean needComma= false;
List<ICPPASTTemplateParameter> returnValue = new ArrayList<ICPPASTTemplateParameter>(DEFAULT_PARM_LIST_SIZE);
for (;;) { for (;;) {
final int lt1= LT(1); final int lt1= LT(1);
if (lt1 == IToken.tGT || lt1 == IToken.tEOC || lt1 == IToken.tGT_in_SHIFTR) if (lt1 == IToken.tGT || lt1 == IToken.tEOC || lt1 == IToken.tGT_in_SHIFTR)
return returnValue; return result;
final int offset = LA(1).getOffset(); if (needComma) {
consume(IToken.tCOMMA);
} else {
needComma= true;
}
ICPPASTTemplateParameter tpar= templateParameter();
result.add(tpar);
}
}
private ICPPASTTemplateParameter templateParameter() throws EndOfFileException, BacktrackException {
final int lt1= LT(1);
final IToken start= mark();
if (lt1 == IToken.t_class || lt1 == IToken.t_typename) { if (lt1 == IToken.t_class || lt1 == IToken.t_typename) {
try {
int type = (lt1 == IToken.t_class ? ICPPASTSimpleTypeTemplateParameter.st_class int type = (lt1 == IToken.t_class ? ICPPASTSimpleTypeTemplateParameter.st_class
: ICPPASTSimpleTypeTemplateParameter.st_typename); : ICPPASTSimpleTypeTemplateParameter.st_typename);
boolean parameterPack= false; boolean parameterPack= false;
@ -1792,11 +1804,21 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
identifierName = nodeFactory.newName(); identifierName = nodeFactory.newName();
} }
// Check if followed by comma
switch (LT(1)) {
case IToken.tGT:
case IToken.tEOC:
case IToken.tGT_in_SHIFTR:
case IToken.tCOMMA:
ICPPASTSimpleTypeTemplateParameter tpar = nodeFactory.newSimpleTypeTemplateParameter(type, identifierName, defaultValue); ICPPASTSimpleTypeTemplateParameter tpar = nodeFactory.newSimpleTypeTemplateParameter(type, identifierName, defaultValue);
tpar.setIsParameterPack(parameterPack); tpar.setIsParameterPack(parameterPack);
setRange(tpar, offset, endOffset); setRange(tpar, start.getOffset(), endOffset);
returnValue.add(tpar); return tpar;
}
} catch (BacktrackException bt) {
}
// Can be a non-type template parameter, see bug 333285
backup(start);
} else if (lt1 == IToken.t_template) { } else if (lt1 == IToken.t_template) {
boolean parameterPack= false; boolean parameterPack= false;
IASTName identifierName = null; IASTName identifierName = null;
@ -1830,28 +1852,24 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
ICPPASTTemplatedTypeTemplateParameter tpar = nodeFactory.newTemplatedTypeTemplateParameter(identifierName, defaultValue); ICPPASTTemplatedTypeTemplateParameter tpar = nodeFactory.newTemplatedTypeTemplateParameter(identifierName, defaultValue);
tpar.setIsParameterPack(parameterPack); tpar.setIsParameterPack(parameterPack);
setRange(tpar, offset, endOffset); setRange(tpar, start.getOffset(), endOffset);
for (int i = 0; i < tparList.size(); ++i) { for (int i = 0; i < tparList.size(); ++i) {
ICPPASTTemplateParameter p = tparList.get(i); ICPPASTTemplateParameter p = tparList.get(i);
tpar.addTemplateParameter(p); tpar.addTemplateParameter(p);
} }
returnValue.add(tpar); return tpar;
} else if (lt1 == IToken.tCOMMA) { }
consume();
continue; // Try non-type template parameter
} else {
boolean inTParList= fInTemplateParameterList; boolean inTParList= fInTemplateParameterList;
try { try {
fInTemplateParameterList= true; fInTemplateParameterList= true;
ICPPASTParameterDeclaration parm = parameterDeclaration(); return parameterDeclaration();
returnValue.add(parm);
} finally { } finally {
fInTemplateParameterList= inTParList; fInTemplateParameterList= inTParList;
} }
} }
}
}
/** /**