Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2019-11-03 00:54:28 -0400
committerMarc-André Laperle2019-11-08 22:22:25 -0500
commitfac1ba39e6176beb4d38f9fc3a34744ec2b5e18d (patch)
treebfc2c336c96e086331316df755b1d15b73f0cad9
parentc29769823c4ed5e192ec9b203f34210b3b2c184c (diff)
downloadorg.eclipse.cdt-fac1ba39e6176beb4d38f9fc3a34744ec2b5e18d.tar.gz
org.eclipse.cdt-fac1ba39e6176beb4d38f9fc3a34744ec2b5e18d.tar.xz
org.eclipse.cdt-fac1ba39e6176beb4d38f9fc3a34744ec2b5e18d.zip
Bug 536986 - Add support for string literal operator templates
This was proposed for standardization in N3599. The proposal was not accepted, but it's supported by gcc and clang as an extension. Change-Id: I0c4a6e532f3a9172a8cb26218f0a608a1ca6be7d
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java45
2 files changed, 52 insertions, 5 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 242b5ed5eb..bada355b7d 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
@@ -11373,4 +11373,16 @@ public class AST2TemplateTests extends AST2CPPTestBase {
public void testGlobalConstWorksAsConstExpression_545756() throws Exception {
parseAndCheckBindings();
}
+
+ // template <class C, C... Chars>
+ // unsigned int operator""_test() {
+ // return sizeof...(Chars);
+ // }
+ //
+ // void foo() {
+ // auto len = "test"_test;
+ // }
+ public void testStringLiteralOperatorTemplate_536986() throws Exception {
+ parseAndCheckImplicitNameBindings();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index bcb87fc8d9..02046bca74 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -231,6 +231,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownField;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMemberClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMethod;
@@ -3453,11 +3454,10 @@ public class CPPSemantics {
data.setFunctionArguments(false, createArgForType(exp, charArray));
ret = resolveFunction(data, funcs, true, false);
- //
char[] stringLiteral = exp.getValue(); // The string literal that was passed to the operator
// The string literal is passed to the operator as chars:
- // "literal"_op -> operator "" _op<'l', 'i', 't', 'e', 'r', 'a', 'l'>();
+ // 12345_op -> operator "" _op<'1', '2', '3', '4', '5'>();
ICPPTemplateArgument args[] = new ICPPTemplateArgument[stringLiteral.length];
for (int k = 0; k < stringLiteral.length; k++) {
args[k] = new CPPTemplateNonTypeArgument(
@@ -3492,13 +3492,48 @@ public class CPPSemantics {
* str (i.e., its length excluding the terminating null character).
* L is treated as operator "" X(str, len)
*/
- CPPPointerType strType = new CPPPointerType(
- new CPPBasicType(((CPPASTLiteralExpression) exp).getBasicCharKind(), 0, null), true, false,
- false);
+ IType charType = new CPPBasicType(((CPPASTLiteralExpression) exp).getBasicCharKind(), 0, null);
+ CPPPointerType strType = new CPPPointerType(charType, true, false, false);
IASTInitializerClause[] initializer = new IASTInitializerClause[] { createArgForType(exp, strType),
createArgForType(null, CPPBasicType.UNSIGNED_INT) };
data.setFunctionArguments(false, initializer);
ret = resolveFunction(data, funcs, true, false);
+
+ // GNU extension: allow literal operator templates for string literals.
+ // The implementation follows the proposed spec in
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3599.html.
+ char[] stringLiteral = exp.getValue(); // The string literal that was passed to the operator
+
+ // The operator template is expected to take the character type as its first argument,
+ // followed by the characters as non-type arguments.
+ // "literal"_op -> operator "" _op<char, 'l', 'i', 't', 'e', 'r', 'a', 'l'>();
+ ICPPTemplateArgument args[] = new ICPPTemplateArgument[stringLiteral.length + 1];
+ args[0] = new CPPTemplateTypeArgument(charType);
+ for (int k = 0; k < stringLiteral.length; k++) {
+ args[k + 1] = new CPPTemplateNonTypeArgument(
+ new EvalFixed(CPPBasicType.CHAR, PRVALUE, IntegralValue.create(stringLiteral[k])));
+ }
+
+ data = new LookupData(((CPPASTLiteralExpression) exp).getOperatorName(), args, exp);
+ IBinding litTpl = resolveFunction(data, tplFunctions, true, false);
+
+ // Do we have valid template and non-template bindings?
+ if (ret != null && !(ret instanceof IProblemBinding)) {
+ // Do we have valid template and non-template bindings?
+ if (litTpl instanceof ICPPFunctionInstance) {
+ // Ambiguity? It has two valid options, and the spec says it shouldn't
+ return new ProblemBinding(data.getLookupName(), exp, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
+ tplFunctions);
+ }
+ } else {
+ if (litTpl instanceof ICPPFunctionInstance) {
+ // Only the template binding is valid
+ ret = litTpl;
+ } else {
+ // Couldn't find a valid operator
+ return ret;
+ }
+ }
} else if (kind == IASTLiteralExpression.lk_char_constant) {
/*
* 2.14.8.6

Back to the top