diff options
Diffstat (limited to 'core/org.eclipse.cdt.core/parser')
5 files changed, 192 insertions, 34 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java index f36f2320c40..376fd1e1664 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java index 5ba6ff5bf4e..6d32a9be760 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java index 651dcf02f46..b7cae1fb471 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownClassTemplate.java new file mode 100644 index 00000000000..dbf6b647004 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownClassTemplate.java @@ -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; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java index c9bb10bbf96..f8cae4b1585 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java @@ -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; |