1
0
Fork 0
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:
Sergey Prigogin 2008-03-17 02:34:13 +00:00
parent e1c98f2c02
commit d245dc8fca
6 changed files with 208 additions and 45 deletions

View file

@ -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:

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;