1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 14:12:10 +02:00

Bug 540450 - Parsing dependent template name

Parse dependent template names as type.

Change-Id: I35461b2e4a615f34749e6ff17b2a85406ec2cf12
Signed-off-by: Hannes Vogt <hannes@havogt.de>
This commit is contained in:
Hannes Vogt 2018-10-14 00:38:11 +02:00 committed by Nathan Ridge
parent 652602febd
commit b33ebe2ee6
6 changed files with 97 additions and 5 deletions

View file

@ -10968,4 +10968,20 @@ public class AST2TemplateTests extends AST2CPPTestBase {
public void testNonTypePackExpansion_540538() throws Exception { public void testNonTypePackExpansion_540538() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template<class>
// struct foo{
// template<class>
// struct apply{
// };
// };
// template <template <class> class F> struct capture {};
// template <class F> using forward = capture<foo<F>::template apply>;
// struct dummy1 {};
// using bar = forward<dummy1>;
// template <class> struct dummy2 {};
// using trigger = dummy2<bar>;
public void testDependentTemplateTemplateArgument_540450() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2018
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
/**
* This interface represents template names which use the template disambiguator
* keyword.
*
* @noimplement This interface is not intended to be implemented by clients.
* @noextend This interface is not intended to be extended by clients.
* @since 9.6
*/
public interface ICPPASTTemplateName extends ICPPASTName {
}

View file

@ -304,6 +304,11 @@ public interface ICPPNodeFactory extends INodeFactory {
@Override @Override
public ICPPASTName newName(String name); public ICPPASTName newName(String name);
/**
* @since 9.6
*/
public ICPPASTTemplateName newTemplateName(char[] templateName);
/** /**
* @since 5.11 * @since 5.11
*/ */

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2018
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateName;
/**
* Represents a template name.
*/
public class CPPASTTemplateName extends CPPASTName implements ICPPASTTemplateName {
public CPPASTTemplateName(char[] name) {
super(name);
}
public CPPASTTemplateName() {
super();
}
@Override
public CPPASTTemplateName copy() {
return copy(CopyStyle.withoutLocations);
}
@Override
public CPPASTTemplateName copy(CopyStyle style) {
CPPASTTemplateName copy = new CPPASTTemplateName(
toCharArray() == null ? null : toCharArray().clone());
return copy(copy, style);
}
}

View file

@ -65,6 +65,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
@ -583,6 +584,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
return newName(name.toCharArray()); return newName(name.toCharArray());
} }
@Override
public ICPPASTTemplateName newTemplateName(char[] templateName) {
return new CPPASTTemplateName(templateName);
}
@Override @Override
public ICPPASTNamedTypeSpecifier newNamedTypeSpecifier(IASTName name) { public ICPPASTNamedTypeSpecifier newNamedTypeSpecifier(IASTName name) {
return new CPPASTNamedTypeSpecifier(name); return new CPPASTNamedTypeSpecifier(name);

View file

@ -81,6 +81,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAttributeList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
@ -269,7 +270,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tIDENTIFIER: case IToken.tIDENTIFIER:
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
case IToken.tEOC: case IToken.tEOC:
return buildName(-1, consume()); return buildName(-1, consume(), false);
} }
throw backtrack; throw backtrack;
@ -335,7 +336,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
case IToken.tEOC: case IToken.tEOC:
IToken nt= consume(); IToken nt= consume();
nameSpec = (ICPPASTName) buildName(destructorOffset, nt); nameSpec = (ICPPASTName) buildName(destructorOffset, nt, keywordTemplate);
break; break;
case IToken.t_operator: case IToken.t_operator:
@ -436,10 +437,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
qname.addNameSpecifier(nameSpec); qname.addNameSpecifier(nameSpec);
} }
private IASTName buildName(int destructorOffset, IToken nt) { private IASTName buildName(int destructorOffset, IToken nt, boolean keywordTemplate) {
IASTName name; IASTName name;
if (destructorOffset < 0) { if (destructorOffset < 0) {
if (keywordTemplate) {
name= getNodeFactory().newTemplateName(nt.getCharImage());
} else {
name= getNodeFactory().newName(nt.getCharImage()); name= getNodeFactory().newName(nt.getCharImage());
}
setRange(name, nt.getOffset(), nt.getEndOffset()); setRange(name, nt.getOffset(), nt.getEndOffset());
} else { } else {
char[] nchars= nt.getCharImage(); char[] nchars= nt.getCharImage();
@ -2266,7 +2271,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private IASTDeclaration aliasDeclaration(final int offset) throws EndOfFileException, private IASTDeclaration aliasDeclaration(final int offset) throws EndOfFileException,
BacktrackException { BacktrackException {
IToken identifierToken = consume(); IToken identifierToken = consume();
IASTName aliasName = buildName(-1, identifierToken); IASTName aliasName = buildName(-1, identifierToken, false);
List<IASTAttributeSpecifier> attributes = attributeSpecifierSeq(); List<IASTAttributeSpecifier> attributes = attributeSpecifierSeq();
@ -3439,6 +3444,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (identifier.getLookupKey().length == 0 && LT(1) != IToken.tEOC) if (identifier.getLookupKey().length == 0 && LT(1) != IToken.tEOC)
throwBacktrack(LA(1)); throwBacktrack(LA(1));
if (identifier.getLastName() instanceof ICPPASTTemplateName) {
isTypename = true;
}
endOffset= calculateEndOffset(identifier); endOffset= calculateEndOffset(identifier);
encounteredTypename= true; encounteredTypename= true;
break; break;