Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorFelix Morgner2018-07-20 07:17:53 -0400
committerNathan Ridge2018-07-24 02:10:59 -0400
commit2dd5e7193de176ac044edbb1126c6d6ed9735478 (patch)
tree0f4e5ee19e844658e00f56f328950d330e21163a /core
parent1f89361032478066095609e729ac87bee9df4824 (diff)
downloadorg.eclipse.cdt-2dd5e7193de176ac044edbb1126c6d6ed9735478.tar.gz
org.eclipse.cdt-2dd5e7193de176ac044edbb1126c6d6ed9735478.tar.xz
org.eclipse.cdt-2dd5e7193de176ac044edbb1126c6d6ed9735478.zip
537217: [C++17] Add support for typename keyword for template template parameters
This patch allows for the 'typename' keyword to be used in template-template template parameter declarations. Additionally, this patch also fixes an issue in the writer, which caused the ellipsis in variadic template-template template parameter declaration to be dropped. Change-Id: I8f68e6053b2b8848b35d1cf6d25d7f4b5b9d396d Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=537217 Signed-off-by: Felix Morgner <fmorgner@hsr.ch>
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateTemplateTypenameTests.java37
-rw-r--r--core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts58
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSimpleTypeTemplateParameter.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java25
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java9
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/TemplateParameterWriter.java47
9 files changed, 178 insertions, 32 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateTemplateTypenameTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateTemplateTypenameTests.java
new file mode 100644
index 0000000000..d644d4f7d2
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateTemplateTypenameTests.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Felix Morgner
+ * 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
+ *
+ * Contributors:
+ * Felix Morgner (IFS Institute for Software) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.parser.tests.ast2.cxx17;
+
+import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
+
+import junit.framework.TestSuite;
+
+public class TemplateTemplateTypenameTests extends AST2CPPTestBase {
+
+ public static TestSuite suite() {
+ return suite(TemplateTemplateTypenameTests.class);
+ }
+
+ // template<template<typename> typename T>
+ // void f(T<int> param) {
+ // }
+ public void testFunctionTemplateWithTemplateTemplateParameterWithTypenameInsteadOfClass_537217() throws Exception {
+ parseAndCheckBindings();
+ }
+
+ // template<template<typename> typename U>
+ // class C {
+ // U<int> mem;
+ // };
+ public void testClassTemplateWithTemplateTemplateParameterWithTypenameInsteadOfClass_537217() throws Exception {
+ parseAndCheckBindings();
+ }
+}
diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts
index 494f57bf37..54c82cc9a2 100644
--- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts
+++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts
@@ -64,4 +64,60 @@ template<typename T> struct S
int f()
{
return S<int>::template c<100>;
-} \ No newline at end of file
+}
+
+//!Type Template Parameter with class
+//%CPP
+template<class >
+void f()
+{
+}
+
+//!Type Template Parameter with typename
+//%CPP
+template<typename >
+void f()
+{
+}
+
+//!Variadic Type Template Parameter with class
+//%CPP
+template<class... >
+void f()
+{
+}
+
+//!Variadic Type Template Parameter with typename
+//%CPP
+template<typename... >
+void f()
+{
+}
+
+//!Template-template Template Parameter with class
+//%CPP
+template<template <typename > class >
+void f()
+{
+}
+
+//!Template-template Template Parameter with typename
+//%CPP
+template<template <typename > typename >
+void f()
+{
+}
+
+//!Variadic Template-template Template Parameter with class
+//%CPP
+template<template <typename > class... >
+void f()
+{
+}
+
+//!Variadic Template-template Template Parameter with typename
+//%CPP
+template<template <typename > typename... >
+void f()
+{
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSimpleTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSimpleTypeTemplateParameter.java
index 0b6373bef3..73d74ba510 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSimpleTypeTemplateParameter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSimpleTypeTemplateParameter.java
@@ -47,7 +47,7 @@ public interface ICPPASTSimpleTypeTemplateParameter extends ICPPASTTemplateParam
/**
- * Get the parameter type.
+ * Get the type of the type parameter (either {@link #st_class} or {@link #st_typename}).
*/
public int getParameterType();
@@ -62,7 +62,9 @@ public interface ICPPASTSimpleTypeTemplateParameter extends ICPPASTTemplateParam
public IASTTypeId getDefaultType();
/**
- * Set the parameter type.
+ * Set the type of the type parameter.
+ *
+ * @param value The type of the type parameter (either {@link #st_class} or {@link #st_typename})
*/
public void setParameterType(int value);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java
index b6901bae13..8948533e47 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java
@@ -44,11 +44,29 @@ public interface ICPPASTTemplatedTypeTemplateParameter extends ICPPASTTemplatePa
"ICPPASTTemplateTypeTemplateParameter.DEFAULT_VALUE [IASTExpression]"); //$NON-NLS-1$
/**
+ * <code>tt_class</code> represents a class.
+ * @since 6.6
+ */
+ public static final int tt_class = 1;
+
+ /**
+ * <code>tt_typename</code> represents a typename.
+ * @since 6.6
+ */
+ public static final int tt_typename = 2;
+
+ /**
* Get the nested template parameters.
*/
public ICPPASTTemplateParameter[] getTemplateParameters();
/**
+ * Get the type of the template-template parameter (either {@link #tt_class} or {@link #tt_typename}).
+ * @since 6.6
+ */
+ public int getParameterType();
+
+ /**
* Get the (optional) name of this template template parameter. In case there is no name an
* empty name is returned.
*/
@@ -85,6 +103,13 @@ public interface ICPPASTTemplatedTypeTemplateParameter extends ICPPASTTemplatePa
public void setIsParameterPack(boolean val);
/**
+ * Set the type of the template-template parameter.
+ * @param type The type of the template-template parameter (either {@link #tt_class} or {@link #tt_typename})
+ * @since 6.6
+ */
+ public void setParameterType(int type);
+
+ /**
* Set the name of this template template parameter.
*/
public void setName(IASTName name);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
index b33183bd74..d2dae11d32 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
@@ -358,6 +358,11 @@ public interface ICPPNodeFactory extends INodeFactory {
public ICPPASTTemplatedTypeTemplateParameter newTemplatedTypeTemplateParameter(IASTName name, IASTExpression defaultValue);
+ /**
+ * @since 6.6
+ */
+ public ICPPASTTemplatedTypeTemplateParameter newTemplatedTypeTemplateParameter(int type, IASTName name, IASTExpression defaultValue);
+
public ICPPASTTemplateId newTemplateId(IASTName templateName);
public ICPPASTTemplateSpecialization newTemplateSpecialization(IASTDeclaration declaration);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java
index 5741604b23..4ba508de06 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java
@@ -30,6 +30,7 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements
private ICPPASTTemplateParameter [] fNestedParameters = null;
private boolean fIsParameterPack;
+ private boolean fUsesKeywordClass;
private IASTName fName;
private IASTExpression fDefaultValue;
private CPPTemplateTemplateParameterScope fScope;
@@ -38,6 +39,11 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements
}
public CPPASTTemplatedTypeTemplateParameter(IASTName name, IASTExpression defaultValue) {
+ this(tt_class, name, defaultValue);
+ }
+
+ public CPPASTTemplatedTypeTemplateParameter(int type, IASTName name, IASTExpression defaultValue) {
+ fUsesKeywordClass = type == tt_class;
setName(name);
setDefaultValue(defaultValue);
}
@@ -52,6 +58,7 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements
CPPASTTemplatedTypeTemplateParameter copy = new CPPASTTemplatedTypeTemplateParameter();
copy.setName(fName == null ? null : fName.copy(style));
copy.setDefaultValue(fDefaultValue == null ? null : fDefaultValue.copy(style));
+ copy.fUsesKeywordClass = fUsesKeywordClass;
copy.fIsParameterPack = fIsParameterPack;
for (ICPPASTTemplateParameter param : getTemplateParameters())
copy.addTemplateParameter(param == null ? null : param.copy(style));
@@ -96,6 +103,17 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements
}
@Override
+ public int getParameterType() {
+ return fUsesKeywordClass ? tt_class : tt_typename;
+ }
+
+ @Override
+ public void setParameterType(int type) {
+ assertNotFrozen();
+ fUsesKeywordClass = type == tt_class;
+ }
+
+ @Override
public IASTName getName() {
return fName;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
index a00303b074..834f34a25c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
@@ -775,6 +775,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
}
@Override
+ public ICPPASTTemplatedTypeTemplateParameter newTemplatedTypeTemplateParameter(int type, IASTName name, IASTExpression defaultValue) {
+ return new CPPASTTemplatedTypeTemplateParameter(type, name, defaultValue);
+ }
+
+ @Override
public ICPPASTTemplateId newTemplateId(IASTName templateName) {
return new CPPASTTemplateId(templateName);
}
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 8ba5be4d04..b47dba36e5 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
@@ -2540,7 +2540,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.tLT);
List<ICPPASTTemplateParameter> tparList = templateParameterList(new ArrayList<>());
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
- int endOffset = consume(IToken.t_class).getEndOffset();
+
+ int kind = LT(1);
+ if(kind != IToken.t_class && kind != IToken.t_typename) {
+ throw backtrack;
+ }
+
+ int endOffset = consume(kind).getEndOffset();
if (LT(1) == IToken.tELLIPSIS) {
parameterPack= true;
@@ -2564,6 +2570,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
ICPPASTTemplatedTypeTemplateParameter tpar = getNodeFactory().newTemplatedTypeTemplateParameter(identifierName, defaultValue);
tpar.setIsParameterPack(parameterPack);
+ tpar.setParameterType(kind == IToken.t_class ? ICPPASTTemplatedTypeTemplateParameter.tt_class : ICPPASTTemplatedTypeTemplateParameter.tt_typename);
setRange(tpar, start.getOffset(), endOffset);
for (int i = 0; i < tparList.size(); ++i) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/TemplateParameterWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/TemplateParameterWriter.java
index 26de0d2740..34ac4ed0b0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/TemplateParameterWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/TemplateParameterWriter.java
@@ -11,6 +11,8 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
@@ -28,7 +30,7 @@ import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
* @author Emanuel Graf IFS
*/
public class TemplateParameterWriter extends NodeWriter {
- private static final String GREATER_THAN_CLASS = "> class"; //$NON-NLS-1$
+ private static final String GREATER_THAN = ">"; //$NON-NLS-1$
private static final String TEMPLATE_LESS_THAN = "template <"; //$NON-NLS-1$
/**
@@ -43,7 +45,9 @@ public class TemplateParameterWriter extends NodeWriter {
if (parameter instanceof ICPPASTParameterDeclaration) {
((IASTParameterDeclaration)((ICPPASTParameterDeclaration) parameter)).accept(visitor);
} else if (parameter instanceof ICPPASTSimpleTypeTemplateParameter) {
- writeSimpleTypeTemplateParameter((ICPPASTSimpleTypeTemplateParameter) parameter);
+ ICPPASTSimpleTypeTemplateParameter simple = (ICPPASTSimpleTypeTemplateParameter) parameter;
+ writeTemplateParameter(simple.getParameterType() == ICPPASTSimpleTypeTemplateParameter.st_class,
+ simple.isParameterPack(), simple.getName(), simple.getDefaultType());
} else if (parameter instanceof ICPPASTTemplatedTypeTemplateParameter) {
writeTemplatedTypeTemplateParameter((ICPPASTTemplatedTypeTemplateParameter) parameter);
}
@@ -53,38 +57,25 @@ public class TemplateParameterWriter extends NodeWriter {
scribe.print(TEMPLATE_LESS_THAN);
ICPPASTTemplateParameter[] params = templated.getTemplateParameters();
writeNodeList(params);
-
- scribe.print(GREATER_THAN_CLASS);
-
- if (templated.getName()!=null){
- scribe.printSpace();
- templated.getName().accept(visitor);
- }
-
- if (templated.getDefaultValue() != null){
- scribe.print(EQUALS);
- templated.getDefaultValue().accept(visitor);
- }
+ scribe.print(GREATER_THAN);
+ scribe.printSpace();
+
+ writeTemplateParameter(templated.getParameterType() == ICPPASTTemplatedTypeTemplateParameter.tt_class,
+ templated.isParameterPack(), templated.getName(), templated.getDefaultValue());
}
- private void writeSimpleTypeTemplateParameter(ICPPASTSimpleTypeTemplateParameter simple) {
- switch (simple.getParameterType()) {
- case ICPPASTSimpleTypeTemplateParameter.st_class:
- scribe.print(Keywords.CLASS);
- break;
- case ICPPASTSimpleTypeTemplateParameter.st_typename:
- scribe.print(Keywords.TYPENAME);
- break;
- }
- if (simple.isParameterPack()) {
+ private void writeTemplateParameter(boolean usesClass, boolean isVariadic, IASTName name, IASTNode defaultArgument) {
+ scribe.print(usesClass ? Keywords.CLASS : Keywords.TYPENAME);
+ if (isVariadic) {
scribe.print(VAR_ARGS);
}
scribe.printSpace();
- visitNodeIfNotNull(simple.getName());
-
- if (simple.getDefaultType() != null){
+ visitNodeIfNotNull(name);
+
+ if (defaultArgument != null){
scribe.print(EQUALS);
- simple.getDefaultType().accept(visitor);
+ defaultArgument.accept(visitor);
}
}
+
}

Back to the top