mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
Fix for bug 214447.
This commit is contained in:
parent
e1c98f2c02
commit
d245dc8fca
6 changed files with 208 additions and 45 deletions
|
@ -6,10 +6,11 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
* Andrew Ferguson (Symbian)
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
|
@ -298,8 +299,11 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
assertSame( foo1, foo2 );
|
||||
|
||||
ITypedef TYPE = (ITypedef) col.getName(2).resolveBinding();
|
||||
assertSame( TYPE, col.getName(8).resolveBinding() );
|
||||
assertSame( TYPE, col.getName(17).resolveBinding() );
|
||||
IBinding b0 = col.getName(8).resolveBinding();
|
||||
assertInstance(b0, ICPPSpecialization.class);
|
||||
assertSame(TYPE, ((ICPPSpecialization) b0).getSpecializedBinding());
|
||||
IBinding b1 = col.getName(17).resolveBinding();
|
||||
assertSame(TYPE, ((ICPPSpecialization) b1).getSpecializedBinding());
|
||||
|
||||
assertInstances( col, T1, 6 );
|
||||
}
|
||||
|
@ -1610,7 +1614,8 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
tu.accept( col );
|
||||
|
||||
ICPPMethod init = (ICPPMethod) col.getName(4).resolveBinding();
|
||||
assertSame( init, col.getName(19).resolveBinding() );
|
||||
ICPPSpecialization b0 = (ICPPSpecialization) col.getName(19).resolveBinding();
|
||||
assertSame(init, b0.getSpecializedBinding());
|
||||
}
|
||||
|
||||
public void testBug91707() throws Exception {
|
||||
|
@ -2110,7 +2115,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
// };
|
||||
//
|
||||
// void f(B<int>::tb r) {}
|
||||
public void _testTemplateTypedef_214447() throws Exception {
|
||||
public void testTemplateTypedef_214447() throws Exception {
|
||||
StringBuffer buffer = getContents(1)[0];
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, true, true);
|
||||
|
||||
|
@ -2144,7 +2149,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
// };
|
||||
//
|
||||
// void f(Vec<int>::reference r) {}
|
||||
public void _testRebindPattern_214447_1() throws Exception {
|
||||
public void testRebindPattern_214447_1() throws Exception {
|
||||
StringBuffer buffer = getContents(1)[0];
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, true, true);
|
||||
|
||||
|
@ -2184,7 +2189,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
// };
|
||||
//
|
||||
// void f(Vec<int>::reference r) {}
|
||||
public void _testRebindPattern_214017_2() throws Exception {
|
||||
public void testRebindPattern_214447_2() throws Exception {
|
||||
StringBuffer buffer = getContents(1)[0];
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, true, true);
|
||||
|
||||
|
@ -2200,7 +2205,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// template<typename _Tp>
|
||||
// class A {
|
||||
// public:
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX)
|
||||
* Andrew Ferguson (Symbian)
|
||||
* IBM - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX)
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
@ -23,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
|
||||
/**
|
||||
|
@ -32,7 +34,7 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
ICPPClassType, ICPPDeferredTemplateInstance, ICPPInternalDeferredClassInstance {
|
||||
|
||||
public CPPDeferredClassInstance(ICPPClassTemplate orig, IType[] arguments) {
|
||||
super(null, orig, null, arguments);
|
||||
super(null, orig, buildArgumentMap(orig, arguments), arguments);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -46,7 +48,6 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getFields()
|
||||
*/
|
||||
public IField[] getFields() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -54,7 +55,6 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(java.lang.String)
|
||||
*/
|
||||
public IField findField(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,6 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredFields()
|
||||
*/
|
||||
public ICPPField[] getDeclaredFields() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -70,7 +69,6 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getMethods()
|
||||
*/
|
||||
public ICPPMethod[] getMethods() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -78,7 +76,6 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getAllDeclaredMethods()
|
||||
*/
|
||||
public ICPPMethod[] getAllDeclaredMethods() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -86,7 +83,6 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods()
|
||||
*/
|
||||
public ICPPMethod[] getDeclaredMethods() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -101,7 +97,6 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getFriends()
|
||||
*/
|
||||
public IBinding[] getFriends() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -116,6 +111,9 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope()
|
||||
*/
|
||||
public IScope getCompositeScope() throws DOMException {
|
||||
if (getArgumentMap() != null) {
|
||||
return new CPPClassSpecializationScope(this);
|
||||
}
|
||||
return ((ICPPClassType) getClassTemplate()).getCompositeScope();
|
||||
}
|
||||
|
||||
|
@ -144,7 +142,7 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
classTemplate = (ICPPClassTemplate) argMap.get(classTemplate);
|
||||
}
|
||||
|
||||
return (IType) ((ICPPInternalTemplateInstantiator)classTemplate).instantiate(newArgs);
|
||||
return (IType) ((ICPPInternalTemplateInstantiator) classTemplate).instantiate(newArgs);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -163,18 +161,47 @@ public class CPPDeferredClassInstance extends CPPInstance implements
|
|||
} else if (type instanceof ICPPClassTemplate && classTemplate == type) {
|
||||
return true;
|
||||
} else if (type instanceof ICPPTemplateInstance &&
|
||||
((ICPPTemplateInstance)type).getTemplateDefinition() == classTemplate) {
|
||||
((ICPPTemplateInstance) type).getTemplateDefinition() == classTemplate) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ICPPClassType[] getNestedClasses() throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
private ICPPClassTemplate getClassTemplate() {
|
||||
return (ICPPClassTemplate) getSpecializedBinding();
|
||||
}
|
||||
|
||||
private static ObjectMap buildArgumentMap(ICPPClassTemplate template, IType[] arguments) {
|
||||
ICPPTemplateParameter[] parameters = null;
|
||||
try {
|
||||
parameters = template.getTemplateParameters();
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
|
||||
if (parameters == null || parameters.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int numParams = parameters.length;
|
||||
ObjectMap map = new ObjectMap(numParams);
|
||||
int numArgs = arguments.length;
|
||||
boolean trivial = true;
|
||||
for (int i = 0; i < numParams && i < numArgs; i++) {
|
||||
ICPPTemplateParameter param = parameters[i];
|
||||
IType arg = arguments[i];
|
||||
|
||||
if (!CPPTemplates.matchTemplateParameterAndArgument(param, arg, map)) {
|
||||
return null;
|
||||
}
|
||||
map.put(param, arg);
|
||||
if (!arg.equals(param)) {
|
||||
trivial = false;
|
||||
}
|
||||
}
|
||||
return trivial ? null : map;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
@ -32,7 +33,7 @@ public class CPPUnknownBinding extends PlatformObject implements ICPPInternalUnk
|
|||
private ICPPScope unknownScope = null;
|
||||
private IBinding scopeBinding = null;
|
||||
private ICPPScope scope = null;
|
||||
private IASTName name = null;
|
||||
protected IASTName name = null;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -132,20 +133,21 @@ public class CPPUnknownBinding extends PlatformObject implements ICPPInternalUnk
|
|||
*/
|
||||
public IBinding resolveUnknown(ObjectMap argMap) throws DOMException {
|
||||
IBinding result = this;
|
||||
if (argMap.containsKey(scopeBinding)) {
|
||||
IType t = (IType) argMap.get(scopeBinding);
|
||||
t = CPPSemantics.getUltimateType(t, false);
|
||||
if (t instanceof ICPPClassType) {
|
||||
IScope s = ((ICPPClassType)t).getCompositeScope();
|
||||
|
||||
if (s != null && ASTInternal.isFullyCached(s))
|
||||
result = s.getBinding(name, true);
|
||||
// CPPSemantics.LookupData data = CPPSemantics.createLookupData(name, false);
|
||||
// CPPSemantics.lookup(data, s);
|
||||
// IBinding result = CPPSemantics.resolveAmbiguities(data, name);
|
||||
return result;
|
||||
IType t = (IType) argMap.get(scopeBinding);
|
||||
if (t == null && scopeBinding instanceof CPPUnknownBinding) {
|
||||
IBinding binding = ((CPPUnknownBinding) scopeBinding).resolveUnknown(argMap);
|
||||
if (binding instanceof IType) {
|
||||
t = (IType) binding;
|
||||
}
|
||||
}
|
||||
if (t != null) {
|
||||
t = CPPSemantics.getUltimateType(t, false);
|
||||
if (t instanceof ICPPClassType) {
|
||||
IScope s = ((ICPPClassType) t).getCompositeScope();
|
||||
if (s != null && ASTInternal.isFullyCached(s))
|
||||
result = s.getBinding(name, true);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Google, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
|
||||
/*
|
||||
* Represents a C++ class template for which we don't yet have a complete declaration.
|
||||
*
|
||||
* @author Sergey Prigogin
|
||||
*/
|
||||
public class CPPUnknownClassTemplate extends CPPUnknownClass
|
||||
implements ICPPClassTemplate, ICPPInternalClassTemplate {
|
||||
private ICPPClassTemplatePartialSpecialization[] partialSpecializations;
|
||||
private ObjectMap instances;
|
||||
|
||||
public CPPUnknownClassTemplate(ICPPScope scope, IBinding scopeBinding, IASTName name) {
|
||||
super(scope, scopeBinding, name);
|
||||
}
|
||||
|
||||
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations()
|
||||
throws DOMException {
|
||||
return partialSpecializations;
|
||||
}
|
||||
|
||||
public ICPPTemplateParameter[] getTemplateParameters() throws DOMException {
|
||||
return ICPPTemplateParameter.EMPTY_TEMPLATE_PARAMETER_ARRAY;
|
||||
}
|
||||
|
||||
public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) {
|
||||
partialSpecializations = (ICPPClassTemplatePartialSpecialization[]) ArrayUtil.append(
|
||||
ICPPClassTemplatePartialSpecialization.class, partialSpecializations, spec);
|
||||
}
|
||||
|
||||
public void addSpecialization(IType[] arguments, ICPPSpecialization specialization) {
|
||||
if (arguments == null)
|
||||
return;
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
if (arguments[i] == null)
|
||||
return;
|
||||
}
|
||||
if (instances == null)
|
||||
instances = new ObjectMap(2);
|
||||
instances.put(arguments, specialization);
|
||||
}
|
||||
|
||||
public ICPPSpecialization deferredInstance(IType[] arguments) {
|
||||
ICPPSpecialization instance = getInstance(arguments);
|
||||
if (instance == null) {
|
||||
instance = new CPPDeferredClassInstance(this, arguments);
|
||||
addSpecialization(arguments, instance);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ICPPSpecialization getInstance(IType[] arguments) {
|
||||
if (instances == null)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < instances.size(); i++) {
|
||||
IType[] args = (IType[]) instances.keyAt(i);
|
||||
if (args.length == arguments.length) {
|
||||
int j = 0;
|
||||
for (; j < args.length; j++) {
|
||||
if (!args[j].isSameType(arguments[j]))
|
||||
break;
|
||||
}
|
||||
if (j == args.length) {
|
||||
return (ICPPSpecialization) instances.getAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IBinding instantiate(IType[] arguments) {
|
||||
return deferredInstance(arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding resolveUnknown(ObjectMap argMap) throws DOMException {
|
||||
IBinding result = super.resolveUnknown(argMap);
|
||||
if (result instanceof ICPPSpecialization) {
|
||||
ICPPSpecialization specialization = (ICPPSpecialization) result;
|
||||
IASTNode parent = name.getParent();
|
||||
if (parent instanceof ICPPASTTemplateId) {
|
||||
IBinding binding = ((ICPPASTTemplateId) parent).resolveBinding();
|
||||
if (binding instanceof ICPPInternalDeferredClassInstance) {
|
||||
// This is a hack to get proper arguments for the template instantiation.
|
||||
// A proper solution should probably be implemented inside
|
||||
// CPPTemplates.instantiateTemplate, but I don't know how to do it.
|
||||
// When making any changes to this code please make sure to run
|
||||
// AST2TemplateTests.testRebindPattern_214447* tests.
|
||||
IType type = ((ICPPInternalDeferredClassInstance) binding).instantiate(argMap);
|
||||
IType[] arguments = ((ICPPTemplateInstance) type).getArguments();
|
||||
ICPPTemplateDefinition template =
|
||||
(ICPPTemplateDefinition) specialization.getSpecializedBinding();
|
||||
result = CPPTemplates.instantiateTemplate(template, arguments, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
* IBM Corporation - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -22,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
|
@ -33,12 +35,10 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
|
|||
* @author aniefer
|
||||
*/
|
||||
public class CPPUnknownScope implements ICPPScope, IASTInternalScope {
|
||||
private IBinding binding = null;
|
||||
private IASTName scopeName = null;
|
||||
private CharArrayObjectMap map = null;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private IBinding binding;
|
||||
private IASTName scopeName;
|
||||
private CharArrayObjectMap map;
|
||||
|
||||
public CPPUnknownScope(IBinding binding, IASTName name) {
|
||||
super();
|
||||
this.scopeName = name;
|
||||
|
@ -105,7 +105,9 @@ public class CPPUnknownScope implements ICPPScope, IASTInternalScope {
|
|||
return (IBinding) map.get(c);
|
||||
}
|
||||
|
||||
IBinding b = new CPPUnknownClass(this, binding, name);
|
||||
IBinding b = name.getParent() instanceof ICPPASTTemplateId ?
|
||||
new CPPUnknownClassTemplate(this, binding, name) :
|
||||
new CPPUnknownClass(this, binding, name);
|
||||
name.setBinding(b);
|
||||
map.put(c, b);
|
||||
return b;
|
||||
|
|
Loading…
Add table
Reference in a new issue