diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPDeferredTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPDeferredTemplateInstance.java new file mode 100644 index 00000000000..efd7153bb06 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPDeferredTemplateInstance.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * @author Bryan Wilkinson + * + */ +public interface ICPPDeferredTemplateInstance extends ICPPTemplateInstance { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPSpecialization.java index 580859898a6..022bb4fcf77 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPSpecialization.java @@ -15,6 +15,7 @@ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer @@ -36,4 +37,11 @@ public interface ICPPSpecialization extends ICPPBinding { * @return */ public IBinding getSpecializedBinding(); + + /** + * return a map which maps from template parameter to the corresponding + * template argument + * @return + */ + public ObjectMap getArgumentMap(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java index 1492424f812..eaa113cb942 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java @@ -14,7 +14,6 @@ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer @@ -43,11 +42,4 @@ public interface ICPPTemplateInstance extends ICPPSpecialization { * @return */ public IType [] getArguments(); - - /** - * return a map which maps from template parameter to the corresponding - * template argument - * @return - */ - public ObjectMap getArgumentMap(); } 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 68e92c43f3c..d98e42d81a6 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 @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; @@ -172,7 +173,7 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP return true; if( type instanceof ITypedef ) return ((ITypedef)type).isSameType( this ); - if( type instanceof CPPDeferredClassInstance ) + if( type instanceof ICPPDeferredTemplateInstance && type instanceof ICPPClassType ) return type.isSameType( this ); //the CPPDeferredClassInstance has some fuzziness if( type instanceof ICPPTemplateInstance ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index 2c9655d4498..f40a2959ec1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -450,6 +450,8 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements checkForDefinition(); if( definition != null ) { IASTNode parent = definition.getParent(); + while (parent instanceof IASTName) + parent = parent.getParent(); if (parent instanceof ICPPASTCompositeTypeSpecifier) { ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier)parent; return compSpec.getScope(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java index 0ba5fb7c6ca..51aa6eaa101 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java @@ -65,7 +65,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate impl } IType [] specArgs = getArguments(); - if( specArgs.length != arguments.length ){ + if( specArgs.length != args.length ){ return null; } @@ -103,4 +103,8 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate impl public IBinding getSpecializedBinding() { return getPrimaryClassTemplate(); } + + public ObjectMap getArgumentMap() { + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java index 297a5790d3b..fadf9736017 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java @@ -16,11 +16,13 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPTemplateParameter; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ObjectMap; @@ -94,7 +96,20 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization } public IBinding instantiate(IType[] arguments) { - // TODO Auto-generated method stub + ICPPTemplateDefinition template = null; + + try { + template = CPPTemplates.matchTemplatePartialSpecialization( (ICPPClassTemplate) this, arguments ); + } catch (DOMException e) { + return e.getProblem(); + } + + if( template instanceof IProblemBinding ) + return template; + if( template != null && template instanceof ICPPClassTemplatePartialSpecialization ){ + return ((CPPTemplateDefinition)template).instantiate( arguments ); + } + return CPPTemplates.instantiateTemplate( this, arguments, argumentMap ); } 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 6e6b1c52079..0f929f1080b 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 @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; @@ -32,7 +33,8 @@ import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer */ -public class CPPDeferredClassInstance extends CPPInstance implements ICPPClassType { +public class CPPDeferredClassInstance extends CPPInstance implements + ICPPClassType, ICPPDeferredTemplateInstance { public IType [] arguments = null; public ICPPClassTemplate classTemplate = null; @@ -169,8 +171,8 @@ public class CPPDeferredClassInstance extends CPPInstance implements ICPPClassTy return true; //allow some fuzziness here. - if( type instanceof CPPDeferredClassInstance ){ - ICPPClassTemplate typeClass = (ICPPClassTemplate) ((CPPDeferredClassInstance)type).getSpecializedBinding(); + if( type instanceof ICPPDeferredTemplateInstance && type instanceof ICPPClassType ){ + ICPPClassTemplate typeClass = (ICPPClassTemplate) ((ICPPDeferredTemplateInstance)type).getSpecializedBinding(); return (typeClass == classTemplate ); } else if( type instanceof ICPPClassTemplate && classTemplate == type ){ return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java index af6e04166b9..8496e7d7f20 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; @@ -32,7 +33,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer */ -public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunction, ICPPInternalFunction { +public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunction, ICPPInternalFunction, ICPPDeferredTemplateInstance { private IParameter [] parameters; private IType[] arguments; private IFunctionType functionType; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java index 3e3b40afdf0..2472813e382 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java @@ -38,13 +38,6 @@ public abstract class CPPInstance extends CPPSpecialization implements ICPPTempl return (ICPPTemplateDefinition) getSpecializedBinding(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPInstance#getArgumentMap() - */ - public ObjectMap getArgumentMap() { - return argumentMap; - } - /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance#getArguments() */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 56042825b1d..9c3063dc782 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -680,7 +680,8 @@ public class CPPSemantics { } if( binding instanceof ICPPClassTemplate ){ ASTNodeProperty prop = data.astName.getPropertyInParent(); - if( prop != ICPPASTQualifiedName.SEGMENT_NAME && prop != ICPPASTTemplateId.TEMPLATE_NAME ){ + if( prop != ICPPASTQualifiedName.SEGMENT_NAME && prop != ICPPASTTemplateId.TEMPLATE_NAME && + binding instanceof ICPPInternalBinding){ try { IASTNode def = ((ICPPInternalBinding)binding).getDefinition(); if( def != null ){ @@ -2034,7 +2035,7 @@ public class CPPSemantics { { //ok, delegates are synonyms } else if( type instanceof ICPPClassTemplate && temp instanceof ICPPSpecialization && - ((ICPPSpecialization)temp).getSpecializedBinding() == type ) + ((IType) type).isSameType((IType) ((ICPPSpecialization)temp).getSpecializedBinding())) { //ok, stay with the template, the specialization, if applicable, will come out during instantiation } else if( type != temp && !((IType)type).isSameType( (IType) temp )) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java index df071c887b5..06edb13b7d7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java @@ -111,4 +111,7 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp public ILinkage getLinkage() { return Linkage.CPP_LINKAGE; } + public ObjectMap getArgumentMap() { + return argumentMap; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java index 8906dc8d222..70a6d6bcaef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java @@ -60,8 +60,8 @@ public class CPPTemplateScope extends CPPScope implements ICPPTemplateScope { * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getScopeName() */ public IName getScopeName() { - // TODO Auto-generated method stub - return null; + ICPPASTTemplateDeclaration template = (ICPPASTTemplateDeclaration) getPhysicalNode(); + return CPPTemplates.getTemplateName(template); } public IScope getParent() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java index 4b37af08247..6b52e54ce60 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.index.IIndexType; /** * @author aniefer @@ -72,8 +73,8 @@ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements public boolean isSameType( IType type ) { if( type == this ) return true; - if( type instanceof ITypedef ) - return ((ITypedef)type).isSameType( this ); + if( type instanceof ITypedef || type instanceof IIndexType ) + return type.isSameType( this ); return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java index d133f515765..66f18a6cd0d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java @@ -176,10 +176,33 @@ public class CPPTemplates { ICPPTemplateDefinition template = getContainingTemplate( templateParameter ); IBinding binding = null; - if( template instanceof CPPTemplateDefinition ){ - binding = ((CPPTemplateDefinition)template).resolveTemplateParameter( templateParameter ); - } else if( template instanceof CPPTemplateTemplateParameter ){ + if( template instanceof CPPTemplateTemplateParameter ){ binding = ((CPPTemplateTemplateParameter)template).resolveTemplateParameter( templateParameter ); + } else if (template instanceof CPPTemplateDefinition) { + binding = ((CPPTemplateDefinition) template).resolveTemplateParameter(templateParameter); + } else if (template != null) { + IASTName name = CPPTemplates.getTemplateParameterName(templateParameter); + binding = name.getBinding(); + + if (binding == null) { + ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) templateParameter.getParent(); + ICPPASTTemplateParameter[] ps = templateDecl.getTemplateParameters(); + + int i = 0; + for (; i < ps.length; i++) { + if (templateParameter == ps[i]) + break; + } + + try { + ICPPTemplateParameter[] params = template.getTemplateParameters(); + if (i < params.length) { + binding = params[i]; + name.setBinding(binding); + } + } catch (DOMException e) { + } + } } return binding; @@ -249,10 +272,10 @@ public class CPPTemplates { template = ((ICPPSpecialization)template).getSpecializedBinding(); } - if( template != null && template instanceof ICPPInternalTemplate ){ + if( template != null && template instanceof ICPPInternalTemplateInstantiator){ IASTNode [] args = id.getTemplateArguments(); IType [] types = CPPTemplates.createTypeArray( args ); - return ((ICPPInternalTemplate)template).instantiate( types ); + return ((ICPPInternalTemplateInstantiator) template).instantiate(types); } } else { //functions are instatiated as part of the resolution process @@ -279,8 +302,8 @@ public class CPPTemplates { ICPPClassTemplate classTemplate = (ICPPClassTemplate) template; IType [] args = createTypeArray( id.getTemplateArguments() ); - if( classTemplate instanceof ICPPInternalTemplate ){ - IBinding binding = ((ICPPInternalTemplate)classTemplate).instantiate( args ); + if( classTemplate instanceof ICPPInternalTemplateInstantiator ){ + IBinding binding = ((ICPPInternalTemplateInstantiator)classTemplate).instantiate( args ); return binding; } return null; @@ -330,7 +353,9 @@ public class CPPTemplates { if( spec == null ) { ICPPScope scope = (ICPPScope) CPPVisitor.getContainingScope( id ); spec = new CPPClassSpecialization(binding, scope, argMap ); - ((ICPPInternalTemplate)template).addSpecialization( args, (ICPPSpecialization) spec ); + if (template instanceof ICPPInternalTemplate) { + ((ICPPInternalTemplate)template).addSpecialization( args, (ICPPSpecialization) spec ); + } } IASTNode parent = id.getParent(); while( !(parent instanceof IASTDeclSpecifier ) ) @@ -727,6 +752,9 @@ public class CPPTemplates { } } } else { + while (templateDecl.getDeclaration() instanceof ICPPASTTemplateDeclaration) { + templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getDeclaration(); + } return templateDecl; } } @@ -845,7 +873,8 @@ public class CPPTemplates { if( bindingsToClear == null ) bindingsToClear = new ObjectSet( templateParams.length ); tn.setBinding( defParams[i] ); - ((ICPPInternalBinding)defParams[i]).addDeclaration( tn ); + if (defParams[i] instanceof ICPPInternalBinding) + ((ICPPInternalBinding)defParams[i]).addDeclaration( tn ); bindingsToClear.put( defParams[i] ); } @@ -1002,7 +1031,7 @@ public class CPPTemplates { instanceArgs = (IType[]) ArrayUtil.append( IType.class, instanceArgs, (arg != null) ? arg : mapped ); } instanceArgs = (IType[]) ArrayUtil.trim( IType.class, instanceArgs ); - ICPPSpecialization temp = (ICPPSpecialization) ((ICPPInternalTemplate)template).instantiate( instanceArgs ); + ICPPSpecialization temp = (ICPPSpecialization) ((ICPPInternalTemplateInstantiator)template).instantiate( instanceArgs ); if( temp != null ) instances = (IFunction[]) ArrayUtil.append( IFunction.class, instances, temp ); } @@ -1274,7 +1303,7 @@ public class CPPTemplates { return -1; } - static protected ICPPTemplateDefinition matchTemplatePartialSpecialization( ICPPClassTemplate template, IType[] args ) throws DOMException{ + static public ICPPTemplateDefinition matchTemplatePartialSpecialization( ICPPClassTemplate template, IType[] args ) throws DOMException{ if( template == null ){ return null; } @@ -1532,7 +1561,7 @@ public class CPPTemplates { arg = arguments[i]; //If the argument is a template parameter, we can't instantiate yet, defer for later if( typeContainsTemplateParameter( arg ) ){ - return ((ICPPInternalTemplate)template).deferredInstance( arguments ); + return ((ICPPInternalTemplateInstantiator)template).deferredInstance(arguments); } } else { IType defaultType = null; @@ -1569,7 +1598,7 @@ public class CPPTemplates { } } - ICPPSpecialization instance = ((ICPPInternalTemplate)template).getInstance( actualArgs ); + ICPPSpecialization instance = ((ICPPInternalTemplateInstantiator)template).getInstance( actualArgs ); if( instance != null ){ return instance; } @@ -1587,7 +1616,8 @@ public class CPPTemplates { return e.getProblem(); } instance = (ICPPTemplateInstance) CPPTemplates.createInstance( scope, template, map, arguments ); - ((ICPPInternalTemplate)template).addSpecialization( arguments, instance ); + if (template instanceof ICPPInternalTemplate) + ((ICPPInternalTemplate)template).addSpecialization( arguments, instance ); return instance; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java index fc65f11746b..69215e9a344 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java @@ -14,7 +14,6 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; @@ -22,13 +21,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; * @author aniefer * */ -public interface ICPPInternalTemplate extends ICPPInternalBinding { - +public interface ICPPInternalTemplate extends ICPPInternalBinding, ICPPInternalTemplateInstantiator { public void addSpecialization( IType [] arguments, ICPPSpecialization specialization ); - - public IBinding instantiate( IType [] arguments ); - - public ICPPSpecialization deferredInstance( IType [] arguments ); - - public ICPPSpecialization getInstance( IType [] arguments ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplateInstantiator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplateInstantiator.java new file mode 100644 index 00000000000..6131cbf6a67 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplateInstantiator.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; + +/** + * @author Bryan Wilkinson + * + */ +public interface ICPPInternalTemplateInstantiator { + + public IBinding instantiate( IType [] arguments ); + + public ICPPSpecialization deferredInstance( IType [] arguments ); + + public ICPPSpecialization getInstance( IType [] arguments ); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 3653a9d7b7a..760801715d8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -73,7 +73,7 @@ import org.eclipse.core.runtime.Status; public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { protected Database db; - public static final int VERSION = 26; + public static final int VERSION = 27; // 0 - the beginning of it all // 1 - first change to kick off upgrades // 2 - added file inclusions @@ -101,6 +101,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { // 24 - file local scopes (161216) // 25 - change ordering of bindings (175275) // 26 - add properties storage + // 27 - templates: classes, functions, limited nesting support, only template type parameters public static final int LINKAGES = Database.DATA_AREA; public static final int FILE_INDEX = Database.DATA_AREA + 4; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/IPDOMOverloader.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/IPDOMOverloader.java new file mode 100644 index 00000000000..ec23ed39eac --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/IPDOMOverloader.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom; + +import org.eclipse.core.runtime.CoreException; + +/** + * Interface for any element in the PDOM that can have the same name as a + * sibling, but differ in other ways (i.e. function parameters, template + * arguments). + * + * @author Bryan Wilkinson + */ +public interface IPDOMOverloader { + + /** + * Gets the signature memento for this PDOM element, which will be unique + * for all sibling IPDOMOverloaders with the same name. + * + * @return + * @throws CoreException + */ + public int getSignatureMemento() throws CoreException; +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index b1f5f3417c1..5e04791ab03 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -29,11 +29,17 @@ import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; +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.dom.ast.cpp.ICPPTemplateScope; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexLinkage; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstanceScope; import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.composite.CompositeScope; import org.eclipse.cdt.internal.core.pdom.PDOM; @@ -175,6 +181,8 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage public abstract PDOMBinding addBinding(IASTName name) throws CoreException; + public abstract PDOMBinding addBinding(IBinding binding) throws CoreException; + public abstract PDOMBinding adaptBinding(IBinding binding) throws CoreException; public abstract PDOMBinding resolveBinding(IASTName name) throws CoreException; @@ -190,7 +198,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage * * @throws CoreException */ - protected PDOMNode getAdaptedParent(IBinding binding, boolean createFileLocalScope) throws CoreException { + protected PDOMNode getAdaptedParent(IBinding binding, boolean createFileLocalScope, boolean addParent) throws CoreException { try { IScope scope = binding.getScope(); if (scope == null) { @@ -203,7 +211,14 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage // in an index the null scope represents global scope. return this; } - return null; + + if (binding instanceof ICPPDeferredTemplateInstance) { + ICPPDeferredTemplateInstance deferred = (ICPPDeferredTemplateInstance) binding; + ICPPTemplateDefinition template = deferred.getTemplateDefinition(); + scope = template.getScope(); + } else { + return null; + } } if(scope instanceof IIndexScope) { @@ -215,6 +230,10 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage } // the scope is from the ast + if (scope instanceof ICPPTemplateScope && !(binding instanceof ICPPTemplateParameter || binding instanceof ICPPTemplateInstance)) { + scope = scope.getParent(); + } + if (scope instanceof ICPPNamespaceScope) { IName name= scope.getScopeName(); if (name != null && name.toCharArray().length == 0) { @@ -234,10 +253,22 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage return this; } else { - IName scopeName = scope.getScopeName(); - if (scopeName instanceof IASTName) { - IBinding scopeBinding = ((IASTName) scopeName).resolveBinding(); - PDOMBinding scopePDOMBinding = adaptBinding(scopeBinding); + IBinding scopeBinding = null; + if (scope instanceof CPPClassInstanceScope) { + scopeBinding = ((CPPClassInstanceScope)scope).getClassType(); + } else { + IName scopeName = scope.getScopeName(); + if (scopeName instanceof IASTName) { + scopeBinding = ((IASTName) scopeName).resolveBinding(); + } + } + if (scopeBinding != null) { + PDOMBinding scopePDOMBinding = null; + if (addParent) { + scopePDOMBinding = addBinding(scopeBinding); + } else { + scopePDOMBinding = adaptBinding(scopeBinding); + } if (scopePDOMBinding != null) return scopePDOMBinding; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java index e17b57cddee..968c74a5f6b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java @@ -78,7 +78,7 @@ class PDOMCLinkage extends PDOMLinkage { public PDOMBinding addBinding(IBinding binding) throws CoreException { PDOMBinding pdomBinding = adaptBinding(binding); if (pdomBinding == null) { - PDOMNode parent = getAdaptedParent(binding, true); + PDOMNode parent = getAdaptedParent(binding, true, false); if (parent == null) return null; @@ -176,7 +176,7 @@ class PDOMCLinkage extends PDOMLinkage { return null; } } - PDOMNode parent = getAdaptedParent(binding, false); + PDOMNode parent = getAdaptedParent(binding, false, false); if (parent == this) { return FindBinding.findBinding(getIndex(), getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java index e9b442c03e7..c8f693695fb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java @@ -15,14 +15,12 @@ import org.eclipse.cdt.core.dom.IPDOMNode; import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IFunction; -import org.eclipse.cdt.core.dom.ast.IFunctionType; -import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.cdt.internal.core.pdom.db.IString; import org.eclipse.cdt.internal.core.pdom.dom.FindBinding; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMOverloader; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; @@ -33,57 +31,56 @@ import org.eclipse.core.runtime.Status; /** * Look up bindings in BTree objects and IPDOMNode objects. This additionally - * takes into account function/method parameters for overloading. + * takes into account function/method parameters as well as template + * specialization arguments for overloading, . */ public class CPPFindBinding extends FindBinding { - public static PDOMBinding findBinding(BTree btree, final PDOM pdom, final char[]name, final int c2, final IType[] types) throws CoreException { + public static PDOMBinding findBinding(BTree btree, final PDOM pdom, final char[]name, final int c2, final int ty2) throws CoreException { final PDOMBinding[] result = new PDOMBinding[1]; - try { - final int ty2 = PDOMCPPFunction.getSignatureMemento(types); - btree.accept(new IBTreeVisitor() { - public int compare(int record) throws CoreException { - IString nm1 = PDOMNamedNode.getDBName(pdom, record); - - int cmp= nm1.compare(name, false); - cmp= cmp==0 ? nm1.compare(name, true) : cmp; - - if(cmp==0) { - int c1 = PDOMNode.getNodeType(pdom, record); - cmp = c1 < c2 ? -1 : (c1 > c2 ? 1 : 0); - if(cmp==0) { - PDOMBinding binding = pdom.getBinding(record); - if(binding instanceof PDOMCPPFunction) { - int ty1 = ((PDOMCPPFunction)binding).getSignatureMemento(); - cmp = ty1 < ty2 ? -1 : (ty1 > ty2 ? 1 : 0); - } + + btree.accept(new IBTreeVisitor() { + public int compare(int record) throws CoreException { + IString nm1 = PDOMNamedNode.getDBName(pdom, record); + + int cmp = nm1.compare(name, false); + cmp = cmp == 0 ? nm1.compare(name, true) : cmp; + + if (cmp == 0) { + int c1 = PDOMNode.getNodeType(pdom, record); + cmp = c1 < c2 ? -1 : (c1 > c2 ? 1 : 0); + if (cmp == 0) { + PDOMBinding binding = pdom.getBinding(record); + if (binding instanceof IPDOMOverloader) { + int ty1 = ((IPDOMOverloader) binding) + .getSignatureMemento(); + cmp = ty1 < ty2 ? -1 : (ty1 > ty2 ? 1 : 0); } } - return cmp; } - public boolean visit(int record) throws CoreException { - result[0] = pdom.getBinding(record); - return false; - } - }); - } catch(DOMException de) { - CCorePlugin.log(de); - } + return cmp; + } + + public boolean visit(int record) throws CoreException { + result[0] = pdom.getBinding(record); + return false; + } + }); + return result[0]; } - public static PDOMBinding findBinding(PDOMNode node, final PDOM pdom, final char[]name, final int constant, final IType[] types) { + public static PDOMBinding findBinding(PDOMNode node, final PDOM pdom, final char[]name, final int constant, final int ty2) { final PDOMBinding[] result = new PDOMBinding[1]; try { - final int ty2 = PDOMCPPFunction.getSignatureMemento(types); node.accept(new IPDOMVisitor() { public boolean visit(IPDOMNode binding) throws CoreException { if(binding instanceof PDOMNamedNode) { PDOMNamedNode nnode = (PDOMNamedNode) binding; if(nnode.hasName(name)) { if(nnode.getNodeType() == constant) { - if(binding instanceof PDOMCPPFunction) { - int ty1 = ((PDOMCPPFunction)binding).getSignatureMemento(); + if(binding instanceof IPDOMOverloader) { + int ty1 = ((IPDOMOverloader)binding).getSignatureMemento(); if(ty1==ty2) { result[0] = (PDOMBinding) binding; throw new CoreException(Status.OK_STATUS); @@ -102,40 +99,35 @@ public class CPPFindBinding extends FindBinding { } else { CCorePlugin.log(ce); } - } catch(DOMException de) { - CCorePlugin.log(de); } return null; } - public static PDOMBinding findBinding(BTree btree, PDOMLinkage linkage, IBinding binding) throws CoreException { - if(binding instanceof IFunction) { - try { - IFunctionType type = ((IFunction) binding).getType(); - return findBinding(btree, linkage.getPDOM(), binding.getNameCharArray(), linkage.getBindingType(binding), type.getParameterTypes()); - } catch(DOMException de) { - CCorePlugin.log(de); - return null; - } + public static PDOMBinding findBinding(BTree btree, PDOMLinkage linkage, IBinding binding) throws CoreException { + Integer memento = null; + try { + memento = PDOMCPPOverloaderUtil.getSignatureMemento(binding); + } catch (DOMException e) { + } + if(memento != null) { + return findBinding(btree, linkage.getPDOM(), binding.getNameCharArray(), linkage.getBindingType(binding), memento.intValue()); } return findBinding(btree, linkage.getPDOM(), binding.getNameCharArray(), new int [] {linkage.getBindingType(binding)}); } - - public static PDOMBinding findBinding(PDOMNode node, PDOMLinkage linkage, IBinding binding) { - if(binding instanceof IFunction) { - try { - IFunctionType type = ((IFunction) binding).getType(); - return findBinding(node, linkage.getPDOM(), binding.getNameCharArray(), linkage.getBindingType(binding), type.getParameterTypes()); - } catch(DOMException de) { - CCorePlugin.log(de); - return null; - } + public static PDOMBinding findBinding(PDOMNode node, PDOMLinkage linkage, IBinding binding) throws CoreException { + Integer memento = null; + try { + memento = PDOMCPPOverloaderUtil.getSignatureMemento(binding); + } catch (DOMException e) { + } + if(memento != null) { + return findBinding(node, linkage.getPDOM(), binding.getNameCharArray(), linkage.getBindingType(binding), memento.intValue()); } return findBinding(node, linkage.getPDOM(), binding.getNameCharArray(), new int[] {linkage.getBindingType(binding)}); } - + public static class CPPBindingBTreeComparator extends FindBinding.DefaultBindingBTreeComparator { public CPPBindingBTreeComparator(PDOM pdom) { super(pdom); @@ -145,9 +137,9 @@ public class CPPFindBinding extends FindBinding { if(cmp==0) { PDOMBinding binding1 = pdom.getBinding(record1); PDOMBinding binding2 = pdom.getBinding(record2); - if(binding1 instanceof PDOMCPPFunction && binding2 instanceof PDOMCPPFunction) { - int ty1 = ((PDOMCPPFunction)binding1).getSignatureMemento(); - int ty2 = ((PDOMCPPFunction)binding2).getSignatureMemento(); + if(binding1 instanceof IPDOMOverloader && binding2 instanceof IPDOMOverloader) { + int ty1 = ((IPDOMOverloader)binding1).getSignatureMemento(); + int ty2 = ((IPDOMOverloader)binding2).getSignatureMemento(); cmp = ty1 < ty2 ? -1 : (ty1 > ty2 ? 1 : 0); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java new file mode 100644 index 00000000000..377580adc15 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +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.index.IIndexBinding; +import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics; +import org.eclipse.cdt.internal.core.index.IIndexScope; +import org.eclipse.cdt.internal.core.index.IIndexType; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPClassInstance extends PDOMCPPInstance implements + ICPPClassType, ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope { + + private static final int MEMBERLIST = PDOMCPPInstance.RECORD_SIZE + 0; + + /** + * The size in bytes of a PDOMCPPClassInstance record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPInstance.RECORD_SIZE + 4; + + public PDOMCPPClassInstance(PDOM pdom, PDOMNode parent, ICPPClassType classType, PDOMBinding instantiated) + throws CoreException { + super(pdom, parent, (ICPPTemplateInstance) classType, instantiated); + } + + public PDOMCPPClassInstance(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_CLASS_INSTANCE; + } + + public ICPPBase[] getBases() throws DOMException { + //TODO Get bases + return ICPPBase.EMPTY_BASE_ARRAY; + } + + private static class ConstructorCollector implements IPDOMVisitor { + private List fConstructors = new ArrayList(); + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof ICPPConstructor) + fConstructors.add(node); + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public ICPPConstructor[] getConstructors() { + return (ICPPConstructor[])fConstructors.toArray(new ICPPConstructor[fConstructors.size()]); + } + } + + public ICPPConstructor[] getConstructors() throws DOMException { + ConstructorCollector visitor= new ConstructorCollector(); + try { + accept(visitor); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return visitor.getConstructors(); + } + + public int getKey() throws DOMException { + return ((ICPPClassType)getSpecializedBinding()).getKey(); + } + + public IScope getCompositeScope() throws DOMException { + return this; + } + + public boolean isSameType(IType type) { + if( type instanceof PDOMNode ) { + PDOMNode node = (PDOMNode) type; + if (node.getPDOM() == getPDOM() && node.getRecord() == getRecord()) { + return true; + } + } + if( type instanceof ITypedef ) + return ((ITypedef)type).isSameType( this ); + if( type instanceof ICPPDeferredTemplateInstance && type instanceof ICPPClassType ) + return type.isSameType( this ); //the CPPDeferredClassInstance has some fuzziness + + if( type instanceof ICPPTemplateInstance ){ + if( getSpecializedBinding() != ((ICPPTemplateInstance)type).getTemplateDefinition() ) + return false; + + ObjectMap m1 = getArgumentMap(), m2 = ((ICPPTemplateInstance)type).getArgumentMap(); + if( m1 == null || m2 == null || m1.size() != m2.size()) + return false; + for( int i = 0; i < m1.size(); i++ ){ + IType t1 = (IType) m1.getAt( i ); + IType t2 = (IType) m2.getAt( i ); + if( t1 == null || ! t1.isSameType( t2 ) ) + return false; + } + return true; + } + + return false; + } + + //ICPPClassType unimplemented + public IField findField(String name) throws DOMException { fail(); return null; } + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { fail(); return null; } + public ICPPField[] getDeclaredFields() throws DOMException { fail(); return null; } + public ICPPMethod[] getDeclaredMethods() throws DOMException { fail(); return null; } + public IField[] getFields() throws DOMException { fail(); return null; } + public IBinding[] getFriends() throws DOMException { fail(); return null; } + public ICPPMethod[] getMethods() throws DOMException { fail(); return null; } + public ICPPClassType[] getNestedClasses() throws DOMException { fail(); return null; } + public Object clone() {fail();return null;} + + public ICPPClassType getClassType() { + return this; + } + + public IBinding[] find(String name) throws DOMException { + return find(name, false); + } + + public IBinding[] find(String name, boolean prefixLookup) + throws DOMException { + try { + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), null, prefixLookup, !prefixLookup); + accept(visitor); + return visitor.getBindings(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public IBinding getBinding(IASTName name, boolean resolve) + throws DOMException { + try { + if (getDBName().equals(name.toCharArray())) { + if (CPPClassScope.isConstructorReference(name)){ + return CPPSemantics.resolveAmbiguities(name, getConstructors()); + } + //9.2 ... The class-name is also inserted into the scope of the class itself + return this; + } + + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray()); + accept(visitor); + return CPPSemantics.resolveAmbiguities(name, visitor.getBindings()); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + //ICPPClassScope unimplemented + public ICPPMethod[] getImplicitMethods() { fail(); return null; } + + public IIndexBinding getScopeBinding() { + return this; + } + + public void addChild(PDOMNode member) throws CoreException { + addMember(member); + } + + public void addMember(PDOMNode member) throws CoreException { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl()); + list.addMember(member); + } + + public void accept(IPDOMVisitor visitor) throws CoreException { + super.accept(visitor); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl()); + list.accept(visitor); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java new file mode 100644 index 00000000000..e1f98eb58f4 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +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.ICPPSpecialization; +import org.eclipse.cdt.core.index.IIndexBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics; +import org.eclipse.cdt.internal.core.index.IIndexScope; +import org.eclipse.cdt.internal.core.index.IIndexType; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements + ICPPClassType, ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope { + + private static final int MEMBERLIST = PDOMCPPSpecialization.RECORD_SIZE + 0; + + /** + * The size in bytes of a PDOMCPPClassSpecialization record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 4; + + public PDOMCPPClassSpecialization(PDOM pdom, PDOMNode parent, ICPPClassType classType, PDOMBinding specialized) + throws CoreException { + super(pdom, parent, (ICPPSpecialization) classType, specialized); + if (specialized instanceof PDOMCPPClassTemplate) { + ((PDOMCPPClassTemplate)specialized).addMember(this); + } else if (specialized instanceof PDOMCPPClassTemplateSpecialization) { + ((PDOMCPPClassTemplateSpecialization)specialized).addMember(this); + } + } + + public PDOMCPPClassSpecialization(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_CLASS_SPECIALIZATION; + } + + public IField findField(String name) throws DOMException { fail(); return null; } + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { fail(); return null; } + + public ICPPBase[] getBases() throws DOMException { + //TODO Get bases + return ICPPBase.EMPTY_BASE_ARRAY; + } + + private static class ConstructorCollector implements IPDOMVisitor { + private List fConstructors = new ArrayList(); + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof ICPPConstructor) + fConstructors.add(node); + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public ICPPConstructor[] getConstructors() { + return (ICPPConstructor[])fConstructors.toArray(new ICPPConstructor[fConstructors.size()]); + } + } + + public ICPPConstructor[] getConstructors() throws DOMException { + try { + if (hasDefinition()) { + ConstructorCollector visitor= new ConstructorCollector(); + accept(visitor); + return visitor.getConstructors(); + } else { + return ((ICPPClassType)getSpecializedBinding()).getConstructors(); + } + } catch (CoreException e) { + CCorePlugin.log(e); + return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; + } + } + + //ICPPClassType unimplemented + public ICPPField[] getDeclaredFields() throws DOMException { fail(); return null; } + public ICPPMethod[] getDeclaredMethods() throws DOMException { fail(); return null; } + public IField[] getFields() throws DOMException { fail(); return null; } + public IBinding[] getFriends() throws DOMException { fail(); return null; } + public ICPPMethod[] getMethods() throws DOMException { fail(); return null; } + public ICPPClassType[] getNestedClasses() throws DOMException { fail(); return null; } + + public IScope getCompositeScope() throws DOMException { + try { + if (hasDefinition()) { + return this; + } else { + return ((ICPPClassType)getSpecializedBinding()).getCompositeScope(); + } + } catch (CoreException e) { + CCorePlugin.log(e); + return null; + } + } + + public int getKey() throws DOMException { + return ((ICPPClassType)getSpecializedBinding()).getKey(); + } + + public boolean isSameType(IType type) { + if( type instanceof PDOMNode ) { + PDOMNode node = (PDOMNode) type; + if (node.getPDOM() == getPDOM() && node.getRecord() == getRecord()) { + return true; + } + } + if( type instanceof ITypedef ) + return ((ITypedef)type).isSameType( this ); + + return false; + } + + public Object clone() {fail();return null;} + + public ICPPClassType getClassType() { + return this; + } + + public IBinding[] find(String name) throws DOMException { + return find(name, false); + } + + public IBinding[] find(String name, boolean prefixLookup) + throws DOMException { + try { + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), null, prefixLookup, !prefixLookup); + accept(visitor); + return visitor.getBindings(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public IBinding getBinding(IASTName name, boolean resolve) + throws DOMException { + try { + if (getDBName().equals(name.toCharArray())) { + if (CPPClassScope.isConstructorReference(name)){ + return CPPSemantics.resolveAmbiguities(name, getConstructors()); + } + //9.2 ... The class-name is also inserted into the scope of the class itself + return this; + } + + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray()); + accept(visitor); + return CPPSemantics.resolveAmbiguities(name, visitor.getBindings()); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + //ICPPClassScope unimplemented + public ICPPMethod[] getImplicitMethods() { fail(); return null; } + + public IIndexBinding getScopeBinding() { + return this; + } + + public void addChild(PDOMNode member) throws CoreException { + addMember(member); + } + + public void addMember(PDOMNode member) throws CoreException { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl()); + list.addMember(member); + } + + public void accept(IPDOMVisitor visitor) throws CoreException { + super.accept(visitor); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl()); + list.accept(visitor); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java new file mode 100644 index 00000000000..afbe997dacf --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java @@ -0,0 +1,347 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.IName; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +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.ICPPClassType; +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.dom.ast.cpp.ICPPTemplateScope; +import org.eclipse.cdt.core.index.IIndexBinding; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplates; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalTemplateInstantiator; +import org.eclipse.cdt.internal.core.index.IIndexScope; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPClassTemplate extends PDOMCPPClassType implements + ICPPClassTemplate, ICPPInternalTemplateInstantiator { + + private static final int PARAMETERS = PDOMCPPClassType.RECORD_SIZE + 0; + private static final int INSTANCES = PDOMCPPClassType.RECORD_SIZE + 4; + private static final int SPECIALIZATIONS = PDOMCPPClassType.RECORD_SIZE + 8; + private static final int FIRST_PARTIAL = PDOMCPPClassType.RECORD_SIZE + 12; + + /** + * The size in bytes of a PDOMCPPClassTemplate record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPClassType.RECORD_SIZE + 16; + + public PDOMCPPClassTemplate(PDOM pdom, PDOMNode parent, ICPPClassTemplate template) + throws CoreException { + super(pdom, parent, (ICPPClassType) template); + } + + public PDOMCPPClassTemplate(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_CLASS_TEMPLATE; + } + + private static class TemplateParameterCollector implements IPDOMVisitor { + private List params = new ArrayList(); + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof ICPPTemplateParameter) + params.add(node); + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public ICPPTemplateParameter[] getTemplateParameters() { + return (ICPPTemplateParameter[])params.toArray(new ICPPTemplateParameter[params.size()]); + } + } + + public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { + try { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl()); + TemplateParameterCollector visitor = new TemplateParameterCollector(); + list.accept(visitor); + + return visitor.getTemplateParameters(); + } catch (CoreException e) { + CCorePlugin.log(e); + return new ICPPTemplateParameter[0]; + } + } + + private PDOMCPPClassTemplatePartialSpecialization getFirstPartial() throws CoreException { + int value = pdom.getDB().getInt(record + FIRST_PARTIAL); + return value != 0 ? new PDOMCPPClassTemplatePartialSpecialization(pdom, value) : null; + } + + public void addPartial(PDOMCPPClassTemplatePartialSpecialization partial) throws CoreException { + PDOMCPPClassTemplatePartialSpecialization first = getFirstPartial(); + partial.setNextPartial(first); + pdom.getDB().putInt(record + FIRST_PARTIAL, partial.getRecord()); + } + + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { + try { + ArrayList partials = new ArrayList(); + for (PDOMCPPClassTemplatePartialSpecialization partial = getFirstPartial(); + partial != null; + partial = partial.getNextPartial()) { + partials.add(partial); + } + + return (ICPPClassTemplatePartialSpecialization[]) partials + .toArray(new ICPPClassTemplatePartialSpecialization[partials + .size()]); + } catch (CoreException e) { + CCorePlugin.log(e); + return new ICPPClassTemplatePartialSpecialization[0]; + } + } + + public ICPPTemplateDefinition getTemplateDefinition() throws DOMException { + return null; + } + + public IBinding getBinding(IASTName name, boolean resolve) throws DOMException { + try { + if (getDBName().equals(name.toCharArray())) { + if (CPPClassScope.isConstructorReference(name)){ + return CPPSemantics.resolveAmbiguities(name, getConstructors()); + } + //9.2 ... The class-name is also inserted into the scope of the class itself + return this; + } + + IndexFilter filter = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return !(binding instanceof ICPPTemplateParameter || binding instanceof ICPPSpecialization); + } + public boolean acceptImplicitMethods() { + return true; + } + public boolean acceptLinkage(ILinkage linkage) { + return linkage.getID() == ILinkage.CPP_LINKAGE_ID; + } + }; + + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), filter, false, true); + accept(visitor); + return CPPSemantics.resolveAmbiguities(name, visitor.getBindings()); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public IBinding[] find(String name, boolean prefixLookup) throws DOMException { + try { + IndexFilter filter = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return !(binding instanceof ICPPTemplateParameter || binding instanceof ICPPSpecialization); + } + public boolean acceptImplicitMethods() { + return true; + } + public boolean acceptLinkage(ILinkage linkage) { + return linkage.getID() == ILinkage.CPP_LINKAGE_ID; + } + }; + + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), filter, prefixLookup, !prefixLookup); + acceptInHierarchy(new HashSet(), visitor); + return visitor.getBindings(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + private class PDOMCPPTemplateScope implements ICPPTemplateScope, IIndexScope { + public IBinding[] find(String name) throws DOMException { + return find(name, false); + } + + public IBinding[] find(String name, boolean prefixLookup) + throws DOMException { + try { + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray(), null, prefixLookup, !prefixLookup); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl()); + list.accept(visitor); + + return visitor.getBindings(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public IBinding getBinding(IASTName name, boolean resolve) + throws DOMException { + try { + BindingCollector visitor = new BindingCollector(getLinkageImpl(), name.toCharArray()); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl()); + list.accept(visitor); + + return CPPSemantics.resolveAmbiguities(name, visitor.getBindings()); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public IScope getParent() throws DOMException { + return PDOMCPPClassTemplate.super.getParent(); + } + + public ICPPTemplateDefinition getTemplateDefinition() + throws DOMException { + return null; + } + + public IName getScopeName() throws DOMException { + return null; + } + + public IIndexBinding getScopeBinding() { + return PDOMCPPClassTemplate.this; + } + } + + private PDOMCPPTemplateScope scope; + + public IScope getParent() throws DOMException { + if (scope == null) { + scope = new PDOMCPPTemplateScope(); + } + return scope; + } + + public void accept(IPDOMVisitor visitor) throws CoreException { + super.accept(visitor); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl()); + list.accept(visitor); + list = new PDOMNodeLinkedList(pdom, record + INSTANCES, getLinkageImpl()); + list.accept(visitor); + } + + public void addMember(PDOMNode member) throws CoreException { + if (member instanceof ICPPTemplateParameter) { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl()); + list.addMember(member); + } else if (member instanceof ICPPTemplateInstance) { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + INSTANCES, getLinkageImpl()); + list.addMember(member); + } else if (member instanceof ICPPSpecialization) { + if (this.equals(((ICPPSpecialization)member).getSpecializedBinding())) { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + SPECIALIZATIONS, getLinkageImpl()); + list.addMember(member); + } else { + super.addMember(member); + } + } else { + super.addMember(member); + } + } + + public ICPPSpecialization deferredInstance(IType[] arguments) { + return getInstance( arguments ); + } + + private static class InstanceFinder implements IPDOMVisitor { + private ICPPSpecialization instance = null; + private IType[] arguments; + + public InstanceFinder(IType[] arguments) { + this.arguments = arguments; + } + + public boolean visit(IPDOMNode node) throws CoreException { + if (instance == null && node instanceof PDOMCPPSpecialization) { + PDOMCPPSpecialization spec = (PDOMCPPSpecialization) node; + if (spec.matchesArguments(arguments)) { + instance = spec; + } + } + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public ICPPSpecialization getInstance() { + return instance; + } + } + + public ICPPSpecialization getInstance(IType[] arguments) { + try { + InstanceFinder visitor = new InstanceFinder(arguments); + + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + INSTANCES, getLinkageImpl()); + list.accept(visitor); + + if (visitor.getInstance() == null) { + list = new PDOMNodeLinkedList(pdom, record + SPECIALIZATIONS, getLinkageImpl()); + list.accept(visitor); + } + + return visitor.getInstance(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public IBinding instantiate(IType[] arguments) { + ICPPTemplateDefinition template = null; + try { + template = CPPTemplates.matchTemplatePartialSpecialization(this, arguments); + } catch (DOMException e) { + return e.getProblem(); + } + + if( template instanceof IProblemBinding ) + return template; + if( template != null && template instanceof ICPPClassTemplatePartialSpecialization ){ + return ((PDOMCPPClassTemplate)template).instantiate( arguments ); + } + + return getInstance(arguments); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java new file mode 100644 index 00000000000..bb043a223d7 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +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.ICPPSpecialization; +import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.Util; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMOverloader; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPClassTemplatePartialSpecialization extends + PDOMCPPClassTemplate implements ICPPClassTemplatePartialSpecialization, ICPPSpecialization, IPDOMOverloader { + + private static final int ARGUMENTS = PDOMCPPClassTemplate.RECORD_SIZE + 0; + private static final int SIGNATURE_MEMENTO = PDOMCPPClassTemplate.RECORD_SIZE + 4; + private static final int PRIMARY = PDOMCPPClassTemplate.RECORD_SIZE + 8; + private static final int NEXT_PARTIAL = PDOMCPPClassTemplate.RECORD_SIZE + 12; + + /** + * The size in bytes of a PDOMCPPClassTemplatePartialSpecialization record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPClassTemplate.RECORD_SIZE + 16; + + public PDOMCPPClassTemplatePartialSpecialization(PDOM pdom, + PDOMNode parent, ICPPClassTemplatePartialSpecialization partial, PDOMBinding primary) throws CoreException { + super(pdom, parent, partial); + pdom.getDB().putInt(record + PRIMARY, primary.getRecord()); + if (primary instanceof PDOMCPPClassTemplate) { + ((PDOMCPPClassTemplate)primary).addPartial(this); + } else if (primary instanceof PDOMCPPClassTemplateSpecialization) { + ((PDOMCPPClassTemplateSpecialization)primary).addPartial(this); + } + + try { + Integer memento = PDOMCPPOverloaderUtil.getSignatureMemento(partial); + pdom.getDB().putInt(record + SIGNATURE_MEMENTO, memento != null ? memento.intValue() : 0); + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + } + + public PDOMCPPClassTemplatePartialSpecialization(PDOM pdom, + int bindingRecord) { + super(pdom, bindingRecord); + } + + public int getSignatureMemento() throws CoreException { + return pdom.getDB().getInt(record + SIGNATURE_MEMENTO); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_CLASS_TEMPLATE_PARTIAL_SPEC; + } + + public PDOMCPPClassTemplatePartialSpecialization getNextPartial() throws CoreException { + int value = pdom.getDB().getInt(record + NEXT_PARTIAL); + return value != 0 ? new PDOMCPPClassTemplatePartialSpecialization(pdom, value) : null; + } + + public void setNextPartial(PDOMCPPClassTemplatePartialSpecialization partial) throws CoreException { + int value = partial != null ? partial.getRecord() : 0; + pdom.getDB().putInt(record + NEXT_PARTIAL, value); + } + + public ICPPClassTemplate getPrimaryClassTemplate() { + try { + return new PDOMCPPClassTemplate(pdom, pdom.getDB().getInt(record + PRIMARY)); + } catch (CoreException e) { + CCorePlugin.log(e); + return null; + } + } + + public IBinding getSpecializedBinding() { + return getPrimaryClassTemplate(); + } + + public void addArgument(IType type) throws CoreException { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + ARGUMENTS, getLinkageImpl()); + PDOMNode typeNode = getLinkageImpl().addType(this, type); + list.addMember(typeNode); + } + + private static class TemplateArgumentCollector implements IPDOMVisitor { + private List args = new ArrayList(); + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof IType) + args.add(node); + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public IType[] getTemplateArguments() { + return (IType[])args.toArray(new IType[args.size()]); + } + } + + public IType[] getArguments() { + try { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + ARGUMENTS, getLinkageImpl()); + TemplateArgumentCollector visitor = new TemplateArgumentCollector(); + list.accept(visitor); + + return visitor.getTemplateArguments(); + } catch (CoreException e) { + CCorePlugin.log(e); + return new IType[0]; + } + } + + public int compareTo(Object other) { + int cmp = super.compareTo(other); + if(cmp==0) { + if(other instanceof PDOMCPPClassTemplatePartialSpecialization) { + try { + PDOMCPPClassTemplatePartialSpecialization otherSpec = (PDOMCPPClassTemplatePartialSpecialization) other; + int mySM = getSignatureMemento(); + int otherSM = otherSpec.getSignatureMemento(); + return mySM == otherSM ? 0 : mySM < otherSM ? -1 : 1; + } catch(CoreException ce) { + CCorePlugin.log(ce); + } + } else { + throw new PDOMNotImplementedError(); + } + } + return cmp; + } + + public IBinding instantiate(IType[] args) { + return getInstance( args ); + } + + public ObjectMap getArgumentMap() { + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java new file mode 100644 index 00000000000..27ef07802eb --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IType; +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.ICPPClassType; +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.internal.core.dom.parser.cpp.CPPTemplates; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalTemplateInstantiator; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +public class PDOMCPPClassTemplateSpecialization extends + PDOMCPPClassSpecialization implements ICPPClassTemplate, ICPPInternalTemplateInstantiator { + + private static final int INSTANCES = PDOMCPPClassSpecialization.RECORD_SIZE + 0; + private static final int SPECIALIZATIONS = PDOMCPPClassSpecialization.RECORD_SIZE + 4; + private static final int FIRST_PARTIAL = PDOMCPPClassSpecialization.RECORD_SIZE + 8; + + /** + * The size in bytes of a PDOMCPPClassTemplateSpecialization record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPClassSpecialization.RECORD_SIZE + 12; + + public PDOMCPPClassTemplateSpecialization(PDOM pdom, PDOMNode parent, ICPPClassTemplate template, PDOMBinding specialized) + throws CoreException { + super(pdom, parent, (ICPPClassType) template, specialized); + } + + public PDOMCPPClassTemplateSpecialization(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_CLASS_TEMPLATE_SPECIALIZATION; + } + + private PDOMCPPClassTemplatePartialSpecialization getFirstPartial() throws CoreException { + int value = pdom.getDB().getInt(record + FIRST_PARTIAL); + return value != 0 ? new PDOMCPPClassTemplatePartialSpecialization(pdom, value) : null; + } + + public void addPartial(PDOMCPPClassTemplatePartialSpecialization partial) throws CoreException { + PDOMCPPClassTemplatePartialSpecialization first = getFirstPartial(); + partial.setNextPartial(first); + pdom.getDB().putInt(record + FIRST_PARTIAL, partial.getRecord()); + } + + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { + try { + ArrayList partials = new ArrayList(); + for (PDOMCPPClassTemplatePartialSpecialization partial = getFirstPartial(); + partial != null; + partial = partial.getNextPartial()) { + partials.add(partial); + } + + return (ICPPClassTemplatePartialSpecialization[]) partials + .toArray(new ICPPClassTemplatePartialSpecialization[partials + .size()]); + } catch (CoreException e) { + CCorePlugin.log(e); + return new ICPPClassTemplatePartialSpecialization[0]; + } + } + + public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { + ICPPClassTemplate template = (ICPPClassTemplate) getSpecializedBinding(); + return template.getTemplateParameters(); + } + + public ICPPSpecialization deferredInstance(IType[] arguments) { + return getInstance( arguments ); + } + + private static class InstanceFinder implements IPDOMVisitor { + private ICPPSpecialization instance = null; + private IType[] arguments; + + public InstanceFinder(IType[] arguments) { + this.arguments = arguments; + } + + public boolean visit(IPDOMNode node) throws CoreException { + if (instance == null && node instanceof PDOMCPPSpecialization) { + PDOMCPPSpecialization spec = (PDOMCPPSpecialization) node; + if (spec.matchesArguments(arguments)) { + instance = spec; + } + } + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public ICPPSpecialization getInstance() { + return instance; + } + } + + public ICPPSpecialization getInstance(IType[] arguments) { + try { + InstanceFinder visitor = new InstanceFinder(arguments); + + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + INSTANCES, getLinkageImpl()); + list.accept(visitor); + + if (visitor.getInstance() == null) { + list = new PDOMNodeLinkedList(pdom, record + SPECIALIZATIONS, getLinkageImpl()); + list.accept(visitor); + } + + return visitor.getInstance(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public IBinding instantiate(IType[] arguments) { + ICPPTemplateDefinition template = null; + try { + template = CPPTemplates.matchTemplatePartialSpecialization(this, arguments); + } catch (DOMException e) { + return e.getProblem(); + } + + if( template instanceof IProblemBinding ) + return template; + if( template != null && template instanceof ICPPClassTemplatePartialSpecialization ){ + return ((PDOMCPPClassTemplate)template).instantiate( arguments ); + } + + return getInstance(arguments); + } + + public void addMember(PDOMNode member) throws CoreException { + if (member instanceof ICPPTemplateInstance) { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + INSTANCES, getLinkageImpl()); + list.addMember(member); + } else if (member instanceof ICPPSpecialization + && !(member instanceof ICPPClassTemplatePartialSpecialization)) { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + SPECIALIZATIONS, getLinkageImpl()); + list.addMember(member); + } else { + super.addMember(member); + } + } + + public void accept(IPDOMVisitor visitor) throws CoreException { + super.accept(visitor); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + INSTANCES, getLinkageImpl()); + list.accept(visitor); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index b60912c5f2f..97c3f00ae12 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -187,7 +187,7 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope { } } - private void acceptInHierarchy(Set visited, IPDOMVisitor visitor) throws CoreException { + protected void acceptInHierarchy(Set visited, IPDOMVisitor visitor) throws CoreException { if (visited.contains(this)) return; visited.add(this); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorSpecialization.java new file mode 100644 index 00000000000..2bafed4836d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorSpecialization.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPConstructorSpecialization extends + PDOMCPPMethodSpecialization implements ICPPConstructor { + + /** + * The size in bytes of a PDOMCPPConstructorSpecialization record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPMethodSpecialization.RECORD_SIZE + 0; + + public PDOMCPPConstructorSpecialization(PDOM pdom, PDOMNode parent, ICPPConstructor constructor, PDOMBinding specialized) throws CoreException { + super(pdom, parent, constructor, specialized); + } + + public PDOMCPPConstructorSpecialization(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_CONSTRUCTOR_SPECIALIZATION; + } + + public boolean isExplicit() throws DOMException { + return getBit(getByte(record + ANNOTATION1), PDOMCPPAnnotation.EXPLICIT_CONSTRUCTOR_OFFSET); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java new file mode 100644 index 00000000000..8456a5e88b5 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +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.internal.core.index.IIndexType; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPDeferredClassInstance extends PDOMCPPInstance implements + ICPPClassType, IIndexType, ICPPDeferredTemplateInstance { + + /** + * The size in bytes of a PDOMCPPDeferredClassInstance record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPInstance.RECORD_SIZE + 0; + + public PDOMCPPDeferredClassInstance(PDOM pdom, PDOMNode parent, ICPPClassType classType, PDOMCPPClassTemplate instantiated) + throws CoreException { + super(pdom, parent, (ICPPTemplateInstance) classType, instantiated); + } + + public PDOMCPPDeferredClassInstance(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_DEFERRED_CLASS_INSTANCE; + } + + public ICPPBase[] getBases() throws DOMException { + return ((ICPPClassType) getSpecializedBinding()).getBases(); + } + + public IScope getCompositeScope() throws DOMException { + return ((ICPPClassType) getSpecializedBinding()).getCompositeScope(); + } + + public int getKey() throws DOMException { + return ((ICPPClassType) getSpecializedBinding()).getKey(); + } + + public boolean isSameType(IType type) { + if( type instanceof PDOMNode ) { + PDOMNode node = (PDOMNode) type; + if (node.getPDOM() == getPDOM() && node.getRecord() == getRecord()) { + return true; + } + } + + ICPPClassTemplate classTemplate = (ICPPClassTemplate) getTemplateDefinition(); + + //allow some fuzziness here. + if( type instanceof ICPPDeferredTemplateInstance && type instanceof ICPPClassType ){ + ICPPClassTemplate typeClass = (ICPPClassTemplate) ((ICPPDeferredTemplateInstance)type).getSpecializedBinding(); + return (typeClass == classTemplate ); + } else if( type instanceof ICPPClassTemplate && classTemplate == type ){ + return true; + } else if( type instanceof ICPPTemplateInstance && ((ICPPTemplateInstance)type).getTemplateDefinition() == classTemplate ){ + return true; + } + return false; + } + + public ICPPConstructor[] getConstructors() throws DOMException { + return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; + } + + //Unimplemented + public IField findField(String name) throws DOMException { fail(); return null; } + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { fail(); return null; } + public ICPPField[] getDeclaredFields() throws DOMException { fail(); return null; } + public ICPPMethod[] getDeclaredMethods() throws DOMException { fail(); return null; } + public IField[] getFields() throws DOMException { fail(); return null; } + public IBinding[] getFriends() throws DOMException { fail(); return null; } + public ICPPMethod[] getMethods() throws DOMException { fail(); return null; } + public ICPPClassType[] getNestedClasses() throws DOMException { fail(); return null; } + public Object clone() {fail();return null;} +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredFunctionInstance.java new file mode 100644 index 00000000000..5ae07524e0e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredFunctionInstance.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPDeferredFunctionInstance extends PDOMCPPFunctionInstance + implements ICPPDeferredTemplateInstance { + + /** + * The size in bytes of a PDOMCPPDeferredFunctionInstance record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPFunctionInstance.RECORD_SIZE + 0; + + public PDOMCPPDeferredFunctionInstance(PDOM pdom, PDOMNode parent, ICPPFunction function, PDOMCPPFunctionTemplate instantiated) + throws CoreException { + super(pdom, parent, function, instantiated); + } + + public PDOMCPPDeferredFunctionInstance(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_DEFERRED_FUNCTION_INSTANCE; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java index 320524fc95b..9aa04606408 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java @@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; /** @@ -25,7 +26,7 @@ import org.eclipse.core.runtime.CoreException; */ class PDOMCPPField extends PDOMCPPVariable implements ICPPField { - public PDOMCPPField(PDOM pdom, PDOMCPPClassType parent, ICPPField field) + public PDOMCPPField(PDOM pdom, PDOMNode parent, ICPPField field) throws CoreException { super(pdom, parent, field); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldSpecialization.java new file mode 100644 index 00000000000..699f8f012e0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldSpecialization.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.internal.core.Util; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPFieldSpecialization extends PDOMCPPSpecialization implements + ICPPField { + + private static final int TYPE = PDOMCPPSpecialization.RECORD_SIZE + 0; + + /** + * The size in bytes of a PDOMCPPFieldSpecialization record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 4; + + public PDOMCPPFieldSpecialization(PDOM pdom, PDOMNode parent, + ICPPField field, PDOMCPPField specialized) + throws CoreException { + super(pdom, parent, (ICPPSpecialization) field, specialized); + + try { + IType type = field.getType(); + PDOMNode typeNode = getLinkageImpl().addType(this, type); + if (typeNode != null) { + pdom.getDB().putInt(record + TYPE, typeNode.getRecord()); + } + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + } + + public PDOMCPPFieldSpecialization(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_FIELD_SPECIALIZATION; + } + + private ICPPField getField() { + return (ICPPField) getSpecializedBinding(); + } + + public ICompositeType getCompositeTypeOwner() throws DOMException { + return getClassOwner(); + } + + public IType getType() throws DOMException { + try { + PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + TYPE)); + if (node instanceof IType) { + return (IType) node; + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public boolean isAuto() throws DOMException { + return getField().isAuto(); + } + + public boolean isExtern() throws DOMException { + return getField().isExtern(); + } + + public boolean isRegister() throws DOMException { + return getField().isRegister(); + } + + public boolean isStatic() throws DOMException { + return getField().isStatic(); + } + + public ICPPClassType getClassOwner() throws DOMException { + return getField().getClassOwner(); + } + + public int getVisibility() throws DOMException { + return getField().getVisibility(); + } + + public boolean isMutable() throws DOMException { + return getField().isMutable(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java index e0f7eddce8d..2ff38472cd1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java @@ -29,7 +29,7 @@ import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.Database; -import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMOverloader; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation; @@ -39,68 +39,68 @@ import org.eclipse.core.runtime.CoreException; * @author Doug Schaefer * */ -class PDOMCPPFunction extends PDOMCPPBinding implements IIndexType, ICPPFunction, ICPPFunctionType { +class PDOMCPPFunction extends PDOMCPPBinding implements IIndexType, ICPPFunction, ICPPFunctionType, IPDOMOverloader { /** * Offset of total number of function parameters (relative to the * beginning of the record). */ - private static final int NUM_PARAMS = PDOMBinding.RECORD_SIZE + 0; + private static final int NUM_PARAMS = PDOMCPPBinding.RECORD_SIZE + 0; /** * Offset of pointer to the first parameter of this function (relative to * the beginning of the record). */ - private static final int FIRST_PARAM = PDOMBinding.RECORD_SIZE + 4; + private static final int FIRST_PARAM = PDOMCPPBinding.RECORD_SIZE + 4; /** * Offset of hash of parameter information to allow fast comparison */ - private static final int SIGNATURE_MEMENTO = PDOMBinding.RECORD_SIZE + 8; + private static final int SIGNATURE_MEMENTO = PDOMCPPBinding.RECORD_SIZE + 8; /** * Offset for return type of this function (relative to * the beginning of the record). */ - private static final int RETURN_TYPE = PDOMBinding.RECORD_SIZE + 12; + private static final int RETURN_TYPE = PDOMCPPBinding.RECORD_SIZE + 12; /** * Offset of annotation information (relative to the beginning of the * record). */ - protected static final int ANNOTATION = PDOMBinding.RECORD_SIZE + 16; // byte + protected static final int ANNOTATION = PDOMCPPBinding.RECORD_SIZE + 16; // byte /** * The size in bytes of a PDOMCPPFunction record in the database. */ - protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 17; + protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 17; - public PDOMCPPFunction(PDOM pdom, PDOMNode parent, ICPPFunction function) throws CoreException { + public PDOMCPPFunction(PDOM pdom, PDOMNode parent, ICPPFunction function, boolean setTypes) throws CoreException { super(pdom, parent, function.getNameCharArray()); Database db = pdom.getDB(); IBinding binding = function; try { IFunctionType ft= function.getType(); - IType rt= ft.getReturnType(); - if (rt != null) { - PDOMNode typeNode = getLinkageImpl().addType(this, rt); - if (typeNode != null) { - db.putInt(record + RETURN_TYPE, typeNode.getRecord()); - } - } - IParameter[] params= function.getParameters(); IType[] paramTypes= ft.getParameterTypes(); db.putInt(record + NUM_PARAMS, params.length); - for (int i=0; i0) { - result.append(','); - } - result.append(ASTTypeUtil.getType(types[i])); - } - result.append(')'); - return result.toString().hashCode(); - } - - public static int getSignatureMemento(IFunctionType type) throws DOMException { - IType[] params = type.getParameterTypes(); - return getSignatureMemento(params); - } - + public int compareTo(Object other) { int cmp = super.compareTo(other); if(cmp==0) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java new file mode 100644 index 00000000000..2ce81593c57 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.internal.core.Util; +import org.eclipse.cdt.internal.core.index.IIndexType; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPFunctionInstance extends PDOMCPPInstance implements IIndexType, + ICPPFunction, ICPPFunctionType { + + /** + * Offset of total number of function parameters (relative to the + * beginning of the record). + */ + private static final int NUM_PARAMS = PDOMCPPInstance.RECORD_SIZE + 0; + + /** + * Offset of pointer to the first parameter of this function (relative to + * the beginning of the record). + */ + private static final int FIRST_PARAM = PDOMCPPInstance.RECORD_SIZE + 4; + + /** + * Offset for return type of this function (relative to + * the beginning of the record). + */ + private static final int RETURN_TYPE = PDOMCPPInstance.RECORD_SIZE + 8; + + /** + * The size in bytes of a PDOMCPPFunctionInstance record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPInstance.RECORD_SIZE + 12; + + public PDOMCPPFunctionInstance(PDOM pdom, PDOMNode parent, ICPPFunction function, PDOMCPPFunctionTemplate instantiated) + throws CoreException { + super(pdom, parent, (ICPPTemplateInstance) function, instantiated); + + Database db = pdom.getDB(); + try { + IFunctionType ft= function.getType(); + IType rt= ft.getReturnType(); + if (rt != null) { + PDOMNode typeNode = getLinkageImpl().addType(this, rt); + if (typeNode != null) { + db.putInt(record + RETURN_TYPE, typeNode.getRecord()); + } + } + + IParameter[] params= function.getParameters(); + IType[] paramTypes= ft.getParameterTypes(); + db.putInt(record + NUM_PARAMS, params.length); + + ICPPFunction sFunc= (ICPPFunction) ((ICPPSpecialization)function).getSpecializedBinding(); + IParameter[] sParams= sFunc.getParameters(); + IType[] sParamTypes= sFunc.getType().getParameterTypes(); + + for (int i=0; i + * + * @param types + * @param qualifyTemplateParameters + * @return + * @throws CoreException + * @throws DOMException + */ + private static String getTemplateArgString(IType[] types, boolean qualifyTemplateParameters) throws CoreException, DOMException { + StringBuffer buffer = new StringBuffer(); + buffer.append('<'); + for (int i = 0; i < types.length; i++) { + if (i>0) { + buffer.append(','); + } + if (qualifyTemplateParameters && types[i] instanceof ICPPTemplateParameter) { + ICPPBinding parent = null; + if (types[i] instanceof PDOMNode) { + parent = (ICPPBinding)((PDOMNode)types[i]).getParentNode(); + } else { + IName parentName = ((ICPPTemplateParameter)types[i]).getScope().getScopeName(); + if (parentName instanceof IASTName) { + parent = (ICPPBinding)((IASTName)parentName).resolveBinding(); + } + } + //identical template parameters from different templates must have unique signatures + if (parent != null) { + buffer.append(CPPVisitor.renderQualifiedName(parent.getQualifiedName())); + String sig = getSignature(parent); + if (sig != null) + buffer.append(sig); + buffer.append("::"); + } + buffer.append(((ICPPTemplateParameter)types[i]).getName()); + } else { + buffer.append(ASTTypeUtil.getType(types[i])); + } + } + buffer.append('>'); + return buffer.toString(); + } + + /** + * Constructs a string in the format: + * (paramName1,paramName2,...) + * + * @param fType + * @return + * @throws DOMException + */ + private static String getFunctionParameterString(IFunctionType fType) throws DOMException { + IType[] types = fType.getParameterTypes(); + if(types.length==1) { + if(types[0] instanceof IBasicType) { + if(((IBasicType)types[0]).getType()==IBasicType.t_void) { + types = new IType[0]; + } + } + } + StringBuffer result = new StringBuffer(); + result.append('('); + for(int i=0; i0) { + result.append(','); + } + result.append(ASTTypeUtil.getType(types[i])); + } + result.append(')'); + return result.toString(); + } + + /** + * Gets the signature memento for the passed binding. + * + * @param binding + * @return the hash code of the binding's signature string + * @throws CoreException + * @throws DOMException + */ + public static Integer getSignatureMemento(IBinding binding) throws CoreException, DOMException { + String sig = getSignature(binding); + return sig.length() == 0 ? null : new Integer(sig.hashCode()); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameterSpecialization.java new file mode 100644 index 00000000000..3ebdb70cbd2 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPParameterSpecialization.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.internal.core.Util; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPParameterSpecialization extends PDOMCPPSpecialization + implements ICPPParameter { + + /** + * Offset of pointer to the next parameter (relative to the + * beginning of the record). + */ + private static final int NEXT_PARAM = PDOMCPPSpecialization.RECORD_SIZE + 0; + + /** + * Offset of pointer to type information for this parameter + * (relative to the beginning of the record). + */ + private static final int TYPE = PDOMCPPSpecialization.RECORD_SIZE + 4; + + /** + * The size in bytes of a PDOMCPPParameterSpecialization record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 8; + + public PDOMCPPParameterSpecialization(PDOM pdom, PDOMNode parent, ICPPParameter param, PDOMCPPParameter specialized, IType type) + throws CoreException { + super(pdom, parent, (ICPPSpecialization) param, specialized); + + Database db = pdom.getDB(); + + db.putInt(record + NEXT_PARAM, 0); + + try { + if (type == null) + type= param.getType(); + if (type != null) { + PDOMNode typeNode = getLinkageImpl().addType(this, type); + db.putInt(record + TYPE, typeNode != null ? typeNode.getRecord() : 0); + } + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + } + + public PDOMCPPParameterSpecialization(PDOM pdom, int record) { + super(pdom, record); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_PARAMETER_SPECIALIZATION; + } + + public void setNextParameter(PDOMCPPParameterSpecialization nextParam) throws CoreException { + int rec = nextParam != null ? nextParam.getRecord() : 0; + pdom.getDB().putInt(record + NEXT_PARAM, rec); + } + + public PDOMCPPParameterSpecialization getNextParameter() throws CoreException { + int rec = pdom.getDB().getInt(record + NEXT_PARAM); + return rec != 0 ? new PDOMCPPParameterSpecialization(pdom, rec) : null; + } + + public IType getType() throws DOMException { + try { + PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + TYPE)); + return node instanceof IType ? (IType)node : null; + } catch (CoreException e) { + CCorePlugin.log(e); + return null; + } + } + + private ICPPParameter getParameter(){ + return (ICPPParameter) getSpecializedBinding(); + } + + public boolean hasDefaultValue() { + return getParameter().hasDefaultValue(); + } + + public boolean isAuto() throws DOMException { + return getParameter().isAuto(); + } + + public boolean isRegister() throws DOMException { + return getParameter().isRegister(); + } + + public boolean isExtern() throws DOMException { + return false; + } + + public boolean isStatic() throws DOMException { + return false; + } + + public boolean isMutable() throws DOMException { + return false; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPSpecialization.java new file mode 100644 index 00000000000..b3220367371 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPSpecialization.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMOverloader; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +abstract class PDOMCPPSpecialization extends PDOMCPPBinding implements + ICPPSpecialization, IPDOMOverloader { + + private static final int ARGMAP_PARAMS = PDOMCPPBinding.RECORD_SIZE + 0; + private static final int ARGMAP_ARGS = PDOMCPPBinding.RECORD_SIZE + 4; + private static final int SIGNATURE_MEMENTO = PDOMCPPBinding.RECORD_SIZE + 8; + private static final int SPECIALIZED = PDOMCPPBinding.RECORD_SIZE + 12; + + /** + * The size in bytes of a PDOMCPPSpecialization record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 16; + + public PDOMCPPSpecialization(PDOM pdom, PDOMNode parent, ICPPSpecialization spec, PDOMNamedNode specialized) + throws CoreException { + super(pdom, parent, spec.getName().toCharArray()); + pdom.getDB().putInt(record + SPECIALIZED, specialized.getRecord()); + + PDOMNodeLinkedList paramList = new PDOMNodeLinkedList(pdom, record + ARGMAP_PARAMS, getLinkageImpl()); + PDOMNodeLinkedList argList = new PDOMNodeLinkedList(pdom, record + ARGMAP_ARGS, getLinkageImpl()); + ObjectMap argMap = ((ICPPSpecialization)spec).getArgumentMap(); + if (argMap != null) { + for (int i = 0; i < argMap.size(); i++) { + PDOMNode paramNode = getLinkageImpl().addType(this, (IType) argMap.keyAt(i)); + paramList.addMember(paramNode); + PDOMNode argNode = getLinkageImpl().addType(this, (IType) argMap.getAt(i)); + argList.addMember(argNode); + } + } + try { + Integer memento = PDOMCPPOverloaderUtil.getSignatureMemento(spec); + pdom.getDB().putInt(record + SIGNATURE_MEMENTO, memento != null ? memento.intValue() : 0); + } catch (DOMException e) { + } + } + + public PDOMCPPSpecialization(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + public IBinding getSpecializedBinding() { + try { + int specializedRec = pdom.getDB().getInt(record + SPECIALIZED); + PDOMNode node = specializedRec != 0 ? + getLinkageImpl().getNode(specializedRec) : null; + if (node instanceof IBinding) { + return (IBinding) node; + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + private static class NodeCollector implements IPDOMVisitor { + private List nodes = new ArrayList(); + public boolean visit(IPDOMNode node) throws CoreException { + nodes.add(node); + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public IPDOMNode[] getNodes() { + return (IPDOMNode[])nodes.toArray(new IPDOMNode[nodes.size()]); + } + } + + public ObjectMap getArgumentMap() { + try { + PDOMNodeLinkedList paramList = new PDOMNodeLinkedList(pdom, record + ARGMAP_PARAMS, getLinkageImpl()); + PDOMNodeLinkedList argList = new PDOMNodeLinkedList(pdom, record + ARGMAP_ARGS, getLinkageImpl()); + NodeCollector paramVisitor = new NodeCollector(); + paramList.accept(paramVisitor); + IPDOMNode[] paramNodes = paramVisitor.getNodes(); + NodeCollector argVisitor = new NodeCollector(); + argList.accept(argVisitor); + IPDOMNode[] argNodes = argVisitor.getNodes(); + + ObjectMap map = new ObjectMap(paramNodes.length); + for (int i = 0; i < paramNodes.length; i++) { + map.put(paramNodes[i], argNodes[i]); + } + + return map; + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public int getSignatureMemento() throws CoreException { + return pdom.getDB().getInt(record + SIGNATURE_MEMENTO); + } + + private static IType[] getArguments(ObjectMap argMap) { + IType[] args = new IType[argMap.size()]; + for (int i = 0; i < argMap.size(); i++) { + args[i] = (IType) argMap.getAt(i); + } + return args; + } + + public boolean matchesArguments(IType[] arguments) { + IType [] args = getArguments(getArgumentMap()); + if( args.length == arguments.length ){ + int i = 0; + for(; i < args.length; i++) { + if( !( args[i].isSameType( arguments[i] ) ) ) + break; + } + return i == args.length; + } + return false; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTypeParameter.java new file mode 100644 index 00000000000..9cd6f6f38ef --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTypeParameter.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.internal.core.Util; +import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Bryan Wilkinson + * + */ +class PDOMCPPTemplateTypeParameter extends PDOMCPPBinding implements + ICPPTemplateTypeParameter, IType { + + private static final int DEFAULT_TYPE = PDOMCPPBinding.RECORD_SIZE + 0; + + /** + * The size in bytes of a PDOMCPPTemplateTypeParameter record in the database. + */ + protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 4; + + public PDOMCPPTemplateTypeParameter(PDOM pdom, PDOMNode parent, + ICPPTemplateTypeParameter param) throws CoreException { + super(pdom, parent, param.getName().toCharArray()); + + try { + IType dflt = param.getDefault(); + if (dflt != null) { + PDOMNode typeNode = getLinkageImpl().addType(this, dflt); + if (typeNode != null) { + pdom.getDB().putInt(record + DEFAULT_TYPE, typeNode.getRecord()); + } + } + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + } + + public PDOMCPPTemplateTypeParameter(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + protected int getRecordSize() { + return RECORD_SIZE; + } + + public int getNodeType() { + return PDOMCPPLinkage.CPP_TEMPLATE_TYPE_PARAMETER; + } + + public boolean isSameType(IType type) { + if (type instanceof ITypedef) { + return type.isSameType(this); + } + + if (type instanceof PDOMNode) { + PDOMNode node= (PDOMNode) type; + if (node.getPDOM() == getPDOM()) { + return node.getRecord() == getRecord(); + } + } + + if (type instanceof ICPPTemplateTypeParameter && !(type instanceof ProblemBinding)) { + ICPPTemplateTypeParameter ttp= (ICPPTemplateTypeParameter) type; + try { + char[][] ttpName= ttp.getQualifiedNameCharArray(); + return hasQualifiedName(ttpName, ttpName.length-1); + } catch (DOMException e) { + CCorePlugin.log(e); + } + } + return false; + } + + public IType getDefault() throws DOMException { + try { + PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + DEFAULT_TYPE)); + if (node instanceof IType) { + return (IType) node; + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + public Object clone() { fail();return null; } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index ec7fe5f972d..de89166626e 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -303,7 +303,7 @@ public class CompletionTests extends AbstractContentAssistTest { //void C2::f() {T/*cursor*/ public void testTypes_MethodScope() throws Exception { final String[] expected= { - "T1", "T2", "T3" + "T1", "T2", "T3", "TClass" }; assertCompletionResults(fCursorOffset, expected, true); } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ParameterHintTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ParameterHintTests.java index 508334b87e6..2023ac86839 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ParameterHintTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ParameterHintTests.java @@ -70,7 +70,7 @@ public class ParameterHintTests extends AbstractContentAssistTest { ////TODO move function into header once indexer supports templates //templatevoid tFunc(T x, T y); //void foo(){tFunc( - public void _testTemplateFunction() throws Exception { + public void testTemplateFunction() throws Exception { assertParameterHints(new String[] { "tFunc(T x,T y) void" }); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/IndexLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/IndexLabelProvider.java index 9c9213aa095..bd319c90542 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/IndexLabelProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/IndexLabelProvider.java @@ -27,13 +27,19 @@ import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.model.ICContainer; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; @@ -54,6 +60,62 @@ public class IndexLabelProvider extends LabelProvider { } else if (element instanceof PDOMNode) { try { String result = ((PDOMNamedNode)element).getDBName().getString(); + + if (element instanceof ICPPTemplateInstance) { + StringBuffer buffer = null; + if (element instanceof ICPPDeferredTemplateInstance) { + buffer = new StringBuffer("Dfrd: "); //$NON-NLS-1$ + } else { + buffer = new StringBuffer("Inst: "); //$NON-NLS-1$ + } + buffer.append(result); + buffer.append('<'); + IType[] types = ((ICPPTemplateInstance) element).getArguments(); + for (int i = 0; i < types.length; i++) { + if (i > 0) + buffer.append(','); + buffer.append(ASTTypeUtil.getType(types[i])); + } + buffer.append('>'); + result = buffer.toString(); + } else if (element instanceof ICPPClassTemplatePartialSpecialization) { + StringBuffer buffer = new StringBuffer("Part: "); //$NON-NLS-1$ + buffer.append(result); + buffer.append('<'); + try { + IType[] types = ((ICPPClassTemplatePartialSpecialization) element).getArguments(); + for (int i = 0; i < types.length; i++) { + if (i > 0) + buffer.append(','); + buffer.append(ASTTypeUtil.getType(types[i])); + } + } catch (DOMException e) { + } + buffer.append('>'); + result = buffer.toString(); + } else if (element instanceof ICPPSpecialization) { + PDOMNode parentOfSpec = ((PDOMNode)((ICPPSpecialization)element).getSpecializedBinding()).getParentNode(); + PDOMNode parent = ((PDOMNode)element).getParentNode(); + PDOMNode grandParent = parent != null ? parent.getParentNode() : null; + boolean showArgs = parentOfSpec == null || grandParent == null || !parentOfSpec.equals(grandParent); + + StringBuffer buffer = null; + buffer = new StringBuffer("Spec: "); //$NON-NLS-1$ + buffer.append(result); + + if (showArgs) { + buffer.append('<'); + ObjectMap argMap = ((ICPPSpecialization) element).getArgumentMap(); + for (int i = 0; i < argMap.size(); i++) { + if (i > 0) + buffer.append(','); + buffer.append(ASTTypeUtil.getType((IType) argMap.getAt(i))); + } + buffer.append('>'); + } + + result = buffer.toString(); + } /* * aftodo - Ideally here we'd call ASTTypeUtil.getType but