Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Schorn2012-01-12 05:16:26 -0500
committerMarkus Schorn2012-01-12 05:16:26 -0500
commit9e5ceb1a49c557b9175cefac25bd61ba7b7c1bb6 (patch)
tree6249a1ff4404bf635675b1cdb0e4c44a8905ab29
parent8aef9f4f9d9cf3ddd82daacd6d900d6e853d7930 (diff)
downloadorg.eclipse.cdt-9e5ceb1a49c557b9175cefac25bd61ba7b7c1bb6.tar.gz
org.eclipse.cdt-9e5ceb1a49c557b9175cefac25bd61ba7b7c1bb6.tar.xz
org.eclipse.cdt-9e5ceb1a49c557b9175cefac25bd61ba7b7c1bb6.zip
Bug 368311: Specialization of nested class used as argument for class instance.
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java28
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java54
2 files changed, 75 insertions, 7 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 7cd2e58936..e64d924e81 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
@@ -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();
+ }
}
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 eb17e32224..dea3993383 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
@@ -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) {

Back to the top