1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 13:25:45 +02:00

Bug 368311: Specialization of nested class used as argument for class instance.

This commit is contained in:
Markus Schorn 2012-01-12 11:16:26 +01:00
parent 8aef9f4f9d
commit 9e5ceb1a49
2 changed files with 75 additions and 7 deletions

View file

@ -5723,4 +5723,32 @@ public class AST2TemplateTests extends AST2BaseTest {
public void testValueForSizeofExpression_368309() throws Exception {
parseAndCheckBindings();
}
// template <class Value> struct iterator {
// Value operator*();
// };
// template <typename Iterator> struct range {
// Iterator begin();
// };
// template <typename T> struct A {
// struct iterator_t : public iterator<T> {};
// typedef range<iterator_t> range_t;
// };
// struct S {
// int x;
// };
//
// void test() {
// A<S>::range_t r;
// auto cur = r.begin(); // A<S>::iterator_t
// A<S>::iterator_t cur;
// auto e = *cur;
// e.x; // ERROR HERE: "Field 'x' could not be resolved"
// }
public void testAutoTypeWithTypedef_368311() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
IVariable v= bh.assertNonProblem("cur = r.begin()", 3);
assertEquals("A<S>::iterator_t", ASTTypeUtil.getType(v.getType(), true));
parseAndCheckBindings();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* Copyright (c) 2005, 2012 IBM Corporation 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
@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import java.util.ArrayList;
import java.util.Collections;
@ -1056,6 +1057,28 @@ public class CPPTemplates {
return arg;
return new CPPTemplateArgument(inst);
}
private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPClassSpecialization within) {
final Integer[] positions = orig.getAllParameterPositions();
CPPTemplateParameterMap newMap= new CPPTemplateParameterMap(positions.length);
for (Integer key : positions) {
ICPPTemplateArgument arg = orig.getArgument(key);
if (arg != null) {
newMap.put(key, instantiateArgument(arg, tpMap, packOffset, within));
} else {
ICPPTemplateArgument[] args = orig.getPackExpansion(key);
if (args != null) {
try {
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within));
} catch (DOMException e) {
newMap.put(key, args);
}
}
}
}
return newMap;
}
/**
* This method propagates the specialization of a member to the types used by the member.
@ -1121,11 +1144,15 @@ public class CPPTemplates {
return type;
}
if (within != null && type instanceof IBinding &&
(type instanceof ITypedef || type instanceof ICPPClassType)) {
ICPPClassType originalClass= within.getSpecializedBinding();
if (originalClass.isSameType(type))
return within;
if (within != null && type instanceof IBinding) {
IType unwound= getNestedType(type, TDEF);
if (unwound instanceof ICPPClassType) {
// Convert (partial) class-templates (specializations) or typedefs to such to
// the actual instance.
ICPPClassType originalClass= within.getSpecializedBinding();
if (originalClass.isSameType(unwound))
return within;
}
IBinding typeAsBinding= (IBinding) type;
IBinding typeOwner= typeAsBinding.getOwner();
@ -1134,8 +1161,21 @@ public class CPPTemplates {
if (newOwner != typeOwner && newOwner instanceof ICPPClassSpecialization) {
return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding);
}
return type;
}
if (unwound instanceof ICPPTemplateInstance && !(unwound instanceof ICPPDeferredClassInstance)) {
// Argument of a class specialization can be a nested class subject to specialization.
final ICPPTemplateInstance classInstance = (ICPPTemplateInstance) unwound;
final IBinding origClass = classInstance.getSpecializedBinding();
if (origClass instanceof ICPPClassType) {
ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within);
if (newArgs != args) {
CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within);
return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args);
}
}
}
}
if (type instanceof ITypeContainer) {