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

Fix pack expansion for array elements

When parameter pack contains array type the EvalCompositeAccess.getType() will
attempt to return type of array element.

Fix this by providing EvalPackAccess which returns pack elements as is.
This commit is contained in:
Igor V. Kovalenko 2023-01-06 00:32:35 +03:00 committed by Jonah Graham
parent 7911ac8a2b
commit 8fc812ee27
6 changed files with 77 additions and 3 deletions

View file

@ -18,6 +18,7 @@
* Nathan Ridge
* Danny Ferreira
* Marc-Andre Laperle (Ericsson)
* Igor V. Kovalenko
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
@ -11400,4 +11401,22 @@ public class AST2TemplateTests extends AST2CPPTestBase {
ITypedef type2 = helper.assertNonProblem("type2");
assertSameType(type1, type2);
}
// using size_t = decltype(sizeof(int));
//
// template<typename T> struct A {
// static constexpr size_t f(const T& arg) noexcept { return sizeof(arg); }
// };
//
// template<typename... Pack>
// constexpr size_t g(const Pack&... pack) { return A<Pack...>::f(pack...); }
//
// static constexpr auto val1 = g("123");
// static constexpr auto val2 = g((const char*)"123");
public void testParameterPackExpansions_array() throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableValue("val1", 4);
helper.assertVariableValue("val2", 8);
}
}

View file

@ -45,7 +45,7 @@ public interface ITypeMarshalBuffer {
EVAL_FUNCTION_SET = 0x09, EVAL_ID = 0x0A, EVAL_INIT_LIST = 0x0B, EVAL_MEMBER_ACCESS = 0x0C,
EVAL_PACK_EXPANSION = 0x0D, EVAL_TYPE_ID = 0x0E, EVAL_UNARY = 0x0F, EVAL_UNARY_TYPE_ID = 0x10,
EVAL_CONSTRUCTOR = 0x11, EVAL_REFERENCE = 0x12, EVAL_POINTER = 0x13, EVAL_COMPOSITE_ACCESS = 0x14,
EVAL_NARY_TYPE_ID = 0x15;
EVAL_NARY_TYPE_ID = 0x15, EVAL_PACK_ACCESS = 0x16;
// Can add more evaluations up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
final static byte EXEC_COMPOUND_STATEMENT = 0x01, EXEC_BREAK = 0x02, EXEC_CASE = 0x03, EXEC_CONTINUE = 0x04,

View file

@ -454,7 +454,7 @@ public class EvalBinding extends CPPDependentEvaluation {
newBindingEval = new EvalBinding(newBinding, newBinding.getType(), getTemplateDefinition());
}
if (context.hasPackOffset()) {
return new EvalCompositeAccess(newBindingEval, packOffset);
return new EvalPackAccess(newBindingEval, packOffset);
} else {
return newBindingEval;
}

View file

@ -39,7 +39,7 @@ import org.eclipse.core.runtime.CoreException;
* Represents an access to a sub-value of a composite value, identified by an index.
* Composite values can include arrays, structures, and parameter packs (see {@code CompositeValue}).
*/
public final class EvalCompositeAccess implements ICPPEvaluation {
public class EvalCompositeAccess implements ICPPEvaluation {
private final ICPPEvaluation parent; // The composite value being accessed
private final int elementId; // The index of the sub-value being accessed

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2016,2022 Institute for Software, HSR Hochschule fuer Technik and others
* Rapperswil, University of applied sciences and others
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Igor V. Kovalenko - factor out EvalPackAccess
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
public class EvalPackAccess extends EvalCompositeAccess {
public EvalPackAccess(ICPPEvaluation parent, int elementId) {
super(parent, elementId);
}
@Override
public IType getType() {
IType type = getParent().getType();
type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
return type;
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putShort(ITypeMarshalBuffer.EVAL_PACK_ACCESS);
buffer.marshalEvaluation(getParent(), includeValue);
buffer.putInt(getElementId());
}
public static ICPPEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
ICPPEvaluation parent = buffer.unmarshalEvaluation();
int elementId = buffer.getInt();
return new EvalPackAccess(parent, elementId);
}
}

View file

@ -136,6 +136,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalNaryTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackAccess;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackExpansion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPointer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalReference;
@ -1726,6 +1727,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return EvalCompositeAccess.unmarshal(firstBytes, buffer);
case ITypeMarshalBuffer.EVAL_NARY_TYPE_ID:
return EvalNaryTypeId.unmarshal(firstBytes, buffer);
case ITypeMarshalBuffer.EVAL_PACK_ACCESS:
return EvalPackAccess.unmarshal(firstBytes, buffer);
}
throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first bytes=" + firstBytes)); //$NON-NLS-1$
}