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

Bug 541549 - Pack expansion expression in type of alias template

Alias templates can be instantiated with dependent arguments, which
can themselves contain a pack expansion, so we need to take care
that pack expansion expressions are instantiated correctly.

This was previously fixed for pack expansions of types and template
arguments in bug 486971.

The patch also fixes a bug in CPPTypedef.getType() where alias
declarations weren't handled correctly. (This bug would only occur
during debugging as normally the type would be computed via setType().

Change-Id: Ie70a923fc9dd0f177b7bfb429b8f1387966b416d
This commit is contained in:
Nathan Ridge 2018-11-27 02:00:10 -05:00
parent 3ee513f324
commit 089d7e1d61
4 changed files with 38 additions and 3 deletions

View file

@ -11123,6 +11123,23 @@ public class AST2TemplateTests extends AST2CPPTestBase {
parseAndCheckBindings();
}
// void foo(int);
//
// template <typename... T>
// using Res = decltype(foo(T()...));
//
// template <typename... T>
// struct Bind {
// using Type = Res<T...>;
// };
//
// using Waldo = Bind<int>::Type;
public void testPackExpansionExprInAliasTemplate_541549() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
IType waldo = helper.assertNonProblem("Waldo");
assertSameType(waldo, CommonCPPTypes.void_);
}
// template <class T>
// void foo(T = {});
//

View file

@ -24,12 +24,14 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAliasDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.PlatformObject;
@ -77,7 +79,15 @@ public class CPPTypedef extends PlatformObject implements ITypedef, ITypeContain
@Override
public IType getType() {
if (type == null) {
type = CPPVisitor.createType((IASTDeclarator) declarations[0].getParent());
IASTNode declParent = declarations[0].getParent();
if (declParent instanceof IASTDeclarator) {
type = CPPVisitor.createType((IASTDeclarator) declParent);
} else if (declParent instanceof ICPPASTAliasDeclaration) {
type = CPPVisitor.createType(((ICPPASTAliasDeclaration) declParent).getMappingTypeId());
} else {
assert false;
type = new ProblemType(ProblemType.TYPE_UNRESOLVED_NAME);
}
}
return type;
}

View file

@ -131,13 +131,19 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
int shift = packSize - 1;
ICPPEvaluation[] newResult = new ICPPEvaluation[expressions.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i + resultShift);
context.setExpandPack(true);
int oldPackOffset = context.getPackOffset();
for (int j = 0; j < packSize; ++j) {
context.setPackOffset(j);
newEval = pattern.instantiate(context, maxDepth);
if (context.isPackExpanded()) {
newEval = new EvalPackExpansion(newEval, newEval.getTemplateDefinition());
context.setPackExpanded(false);
}
newResult[i + resultShift + j] = newEval;
}
context.setPackOffset(oldPackOffset);
context.setExpandPack(false);
result = newResult;
resultShift += shift;
continue;

View file

@ -318,7 +318,7 @@ public class CPPTemplates {
}
IType aliasedType = aliasTemplate.getType();
IBinding owner = aliasTemplate.getOwner();
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner);
return createAliasTemplateInstance(aliasTemplate, args, parameterMap, aliasedType, owner);
} catch (DOMException e) {
return e.getProblem();
}
@ -867,7 +867,7 @@ public class CPPTemplates {
}
}
private static IBinding createAliasTemplaceInstance(ICPPAliasTemplate aliasTemplate, ICPPTemplateArgument[] args,
private static IBinding createAliasTemplateInstance(ICPPAliasTemplate aliasTemplate, ICPPTemplateArgument[] args,
ICPPTemplateParameterMap parameterMap, IType aliasedType, IBinding owner) {
InstantiationContext context = createInstantiationContext(parameterMap, owner);
IType instantiatedType = instantiateType(aliasedType, context);
@ -1350,6 +1350,8 @@ public class CPPTemplates {
if (instantiated != null) {
instantiated = new CPPParameterPackType(instantiated);
}
// TODO: instantiateArguments() calls context.setPackExpanded(false) here
// Do we need to do the same here?
}
result[j++] = instantiated;