From 95c12313366888fea38f77449ef4ba840f52ac1b Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Tue, 29 Jan 2013 16:22:40 -0800 Subject: [PATCH] Bug 399039 - Error involving variadic non-type template parameter Change-Id: I61b19e1fc5aac9372ad756c1e33e412f4bee86e2 Reviewed-on: https://git.eclipse.org/r/9943 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../parser/tests/ast2/AST2TemplateTests.java | 27 +++++++++++++++++++ .../core/dom/parser/cpp/ICPPEvaluation.java | 13 +++++++-- .../parser/cpp/semantics/CPPTemplates.java | 14 ++++++++++ .../core/dom/parser/cpp/semantics/EvalID.java | 9 +++++-- 4 files changed, 59 insertions(+), 4 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 f1ef857a7a3..f6f66498610 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 @@ -7069,6 +7069,33 @@ public class AST2TemplateTests extends AST2TestBase { parseAndCheckBindings(); } + // template + // struct ice_or { + // static const bool value = false; + // }; + // template + // struct is_foo { + // static const bool value = false; + // }; + // template + // struct contains_foo { + // static const bool value = ice_or::value...>::value; + // }; + // template + // struct meta; + // struct S { void bar(); }; + // template <> + // struct meta { + // typedef S type; + // }; + // int main() { + // meta::value>::type t; + // t.bar(); + // } + public void testVariadicNonTypeTemplateParameter_399039() throws Exception { + parseAndCheckBindings(); + } + // template // struct common_type; // template diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java index 0ed1f673f48..4bff763279a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2012, 2013 Wind River Systems, Inc. and others. * 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 @@ -8,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -84,8 +85,16 @@ public interface ICPPEvaluation extends ISerializableEvaluation { IASTNode point); /** - * Determines size of the template parameter pack. + * Searches the evaluation for a usage of a template parameter which is a parameter pack, + * and returns the number of arguments bound to that parameter pack in the given + * template parameter map. * + * Can also return one of the special values CPPTemplates.PACK_SIZE_DEFER, + * CPPTemplates.PACK_SIZE_FAIL, and CPPTemplates.PACK_SIZE_NOT_FOUND. See their + * declarations for their meanings. + * + * See also CPPTemplates.determinePackSize(). + * * @noreference This method is not intended to be referenced by clients. */ int determinePackSize(ICPPTemplateParameterMap tpMap); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 8d4f25cf045..9e4a6d0a356 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -162,9 +162,23 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMod * type instantiation. */ public class CPPTemplates { + // The three constants below are used as special return values for the various overloads + // of CPPTemplates.determinePackSize() and for ICPPEvaluation.determinePackSize(), which + // search a type, template argument, or value for a usage of a template parameter pack + // and return the number of arguments bound to that parameter pack in an + // ICPPTemplateParameterMap. + + // Used to indicate that the parameter pack is not bound to any arguments in the + // template parameter map. Computation of the pack size needs to be deferred until + // arguments for it become available. static final int PACK_SIZE_DEFER = -1; + + // Used to indicate that two different packs with different sizes were found. static final int PACK_SIZE_FAIL = -2; + + // Used to indicate that no template parameter packs were found. static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; + static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 74760703536..61c5c7883af 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -360,8 +360,13 @@ public class EvalID extends CPPEvaluation { @Override public int determinePackSize(ICPPTemplateParameterMap tpMap) { int r = fFieldOwner != null ? fFieldOwner.determinePackSize(tpMap) : CPPTemplates.PACK_SIZE_NOT_FOUND; - for (ICPPTemplateArgument arg : fTemplateArgs) { - r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap)); + if (fNameOwner instanceof ICPPUnknownBinding) { + r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize((ICPPUnknownBinding) fNameOwner, tpMap)); + } + if (fTemplateArgs != null) { + for (ICPPTemplateArgument arg : fTemplateArgs) { + r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap)); + } } return r; }