1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Patch for Bryan Wilkinson as part of 167098, adding support for templates in the PDOM.

This commit is contained in:
Doug Schaefer 2007-03-19 21:05:46 +00:00
parent 71d2d09866
commit 00987cb6b2
48 changed files with 3588 additions and 221 deletions

View file

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

View file

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

View file

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

View file

@ -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 ){

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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()
*/

View file

@ -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 )) {

View file

@ -111,4 +111,7 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE;
}
public ObjectMap getArgumentMap() {
return argumentMap;
}
}

View file

@ -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() {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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
* </ul>
* @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;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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; i<params.length; ++i) {
IType pt= i<paramTypes.length ? paramTypes[i] : null;
setFirstParameter(new PDOMCPPParameter(pdom, this, params[i], pt));
}
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(binding));
IFunctionType ftype = function.getType();
db.putInt(record + SIGNATURE_MEMENTO, getSignatureMemento(ftype.getParameterTypes()));
Integer memento = PDOMCPPOverloaderUtil.getSignatureMemento(binding);
pdom.getDB().putInt(record + SIGNATURE_MEMENTO, memento != null ? memento.intValue() : 0);
if (setTypes) {
IType rt= ft.getReturnType();
if (rt != null) {
setReturnType(rt);
}
for (int i=0; i<params.length; ++i) {
IType pt= i<paramTypes.length ? paramTypes[i] : null;
setFirstParameter(new PDOMCPPParameter(pdom, this, params[i], pt));
}
}
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
@ -220,6 +220,13 @@ class PDOMCPPFunction extends PDOMCPPBinding implements IIndexType, ICPPFunction
return null;
}
public void setReturnType(IType type) throws CoreException {
PDOMNode typeNode = getLinkageImpl().addType(this, type);
if (typeNode != null) {
pdom.getDB().putInt(record + RETURN_TYPE, typeNode.getRecord());
}
}
public boolean isConst() {
// ISO/IEC 14882:2003 9.3.1.3
// Only applicable to member functions
@ -279,32 +286,7 @@ class PDOMCPPFunction extends PDOMCPPBinding implements IIndexType, ICPPFunction
public Object clone() {
throw new PDOMNotImplementedError();
}
public static int getSignatureMemento(IType[] types) throws DOMException {
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; i<types.length; i++) {
if (i>0) {
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) {

View file

@ -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<params.length; ++i) {
IType pt= i<paramTypes.length ? paramTypes[i] : null;
//TODO shouldn't need to make new parameter (find old one)
PDOMCPPParameter sParam = new PDOMCPPParameter(pdom, this, sParams[i], sParamTypes[i]);
setFirstParameter(new PDOMCPPParameterSpecialization(pdom, this, (ICPPParameter) params[i], sParam, pt));
}
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
}
public PDOMCPPFunctionInstance(PDOM pdom, int bindingRecord) {
super(pdom, bindingRecord);
}
protected int getRecordSize() {
return RECORD_SIZE;
}
public int getNodeType() {
return PDOMCPPLinkage.CPP_FUNCTION_INSTANCE;
}
public PDOMCPPParameterSpecialization getFirstParameter() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRST_PARAM);
return rec != 0 ? new PDOMCPPParameterSpecialization(pdom, rec) : null;
}
public void setFirstParameter(PDOMCPPParameterSpecialization param) throws CoreException {
if (param != null)
param.setNextParameter(getFirstParameter());
int rec = param != null ? param.getRecord() : 0;
pdom.getDB().putInt(record + FIRST_PARAM, rec);
}
public IParameter[] getParameters() throws DOMException {
try {
int n = pdom.getDB().getInt(record + NUM_PARAMS);
IParameter[] params = new IParameter[n];
PDOMCPPParameterSpecialization param = getFirstParameter();
while (param != null) {
params[--n] = param;
param = param.getNextParameter();
}
return params;
} catch (CoreException e) {
CCorePlugin.log(e);
return new IParameter[0];
}
}
public IFunctionType getType() throws DOMException {
return this;
}
public boolean isInline() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).isInline();
}
public boolean isMutable() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).isMutable();
}
public boolean isAuto() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).isAuto();
}
public boolean isExtern() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).isExtern();
}
public boolean isRegister() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).isRegister();
}
public boolean isStatic() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).isStatic();
}
public boolean takesVarArgs() throws DOMException {
return ((ICPPFunction)getTemplateDefinition()).takesVarArgs();
}
public IScope getFunctionScope() throws DOMException { fail(); return null; }
public boolean isSameType(IType type) {
if (type instanceof ITypedef) {
return type.isSameType(this);
}
try {
if (type instanceof ICPPFunctionType) {
ICPPFunctionType ft = (ICPPFunctionType) type;
IType rt1= getReturnType();
IType rt2= ft.getReturnType();
if (rt1 != rt2) {
if (rt1 == null || !rt1.isSameType(rt2)) {
return false;
}
}
IType[] params1= getParameterTypes();
IType[] params2= ft.getParameterTypes();
if( params1.length == 1 && params2.length == 0 ){
if( !(params1[0] instanceof IBasicType) || ((IBasicType)params1[0]).getType() != IBasicType.t_void )
return false;
} else if( params2.length == 1 && params1.length == 0 ){
if( !(params2[0] instanceof IBasicType) || ((IBasicType)params2[0]).getType() != IBasicType.t_void )
return false;
} else if( params1.length != params2.length ){
return false;
} else {
for( int i = 0; i < params1.length; i++ ){
if (params1[i] == null || ! params1[i].isSameType( params2[i] ) )
return false;
}
}
if( isConst() != ft.isConst() || isVolatile() != ft.isVolatile() )
return false;
return true;
}
return false;
} catch (DOMException e) {
}
return false;
}
public boolean isConst() {
// ISO/IEC 14882:2003 9.3.1.3
// Only applicable to member functions
return false;
}
public boolean isVolatile() {
// ISO/IEC 14882:2003 9.3.1.3
// Only applicable to member functions
return false;
}
public IType[] getParameterTypes() throws DOMException {
try {
int n = pdom.getDB().getInt(record + NUM_PARAMS);
IType[] types = new IType[n];
PDOMCPPParameterSpecialization param = getFirstParameter();
while (param != null) {
types[--n] = param.getType();
param = param.getNextParameter();
}
return types;
} catch (CoreException e) {
CCorePlugin.log(e);
return new IType[0];
}
}
public IType getReturnType() throws DOMException {
try {
PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + RETURN_TYPE));
if (node instanceof IType) {
return (IType) node;
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
return null;
}
public Object clone() {fail();return null;}
}

View file

@ -0,0 +1,271 @@
/*******************************************************************************
* 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.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.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
import org.eclipse.core.runtime.CoreException;
/**
* @author Bryan Wilkinson
*
*/
class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization
implements IIndexType, ICPPFunction, ICPPFunctionType {
/**
* Offset of total number of function parameters (relative to the
* beginning of the record).
*/
private static final int NUM_PARAMS = PDOMCPPSpecialization.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 = PDOMCPPSpecialization.RECORD_SIZE + 4;
/**
* Offset for return type of this function (relative to
* the beginning of the record).
*/
private static final int RETURN_TYPE = PDOMCPPSpecialization.RECORD_SIZE + 8;
/**
* Offset of annotation information (relative to the beginning of the
* record).
*/
protected static final int ANNOTATION = PDOMCPPSpecialization.RECORD_SIZE + 12; // byte
/**
* The size in bytes of a PDOMCPPFunction record in the database.
*/
protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 13;
public PDOMCPPFunctionSpecialization(PDOM pdom, PDOMNode parent, ICPPFunction function, PDOMBinding specialized) throws CoreException {
super(pdom, parent, (ICPPSpecialization) function, specialized);
if (specialized instanceof PDOMCPPFunctionTemplate) {
((PDOMCPPFunctionTemplate)specialized).addMember(this);
}
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<params.length; ++i) {
IType pt= i<paramTypes.length ? paramTypes[i] : null;
//TODO shouldn't need to make new parameter (find old one)
PDOMCPPParameter sParam = new PDOMCPPParameter(pdom, this, sParams[i], sParamTypes[i]);
setFirstParameter(new PDOMCPPParameterSpecialization(pdom, this, (ICPPParameter) params[i], sParam, pt));
}
db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function));
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
}
public PDOMCPPFunctionSpecialization(PDOM pdom, int bindingRecord) {
super(pdom, bindingRecord);
}
protected int getRecordSize() {
return RECORD_SIZE;
}
public int getNodeType() {
return PDOMCPPLinkage.CPP_FUNCTION_SPECIALIZATION;
}
public PDOMCPPParameterSpecialization getFirstParameter() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRST_PARAM);
return rec != 0 ? new PDOMCPPParameterSpecialization(pdom, rec) : null;
}
public void setFirstParameter(PDOMCPPParameterSpecialization param) throws CoreException {
if (param != null)
param.setNextParameter(getFirstParameter());
int rec = param != null ? param.getRecord() : 0;
pdom.getDB().putInt(record + FIRST_PARAM, rec);
}
public boolean isInline() throws DOMException {
return getBit(getByte(record + ANNOTATION), PDOMCAnnotation.INLINE_OFFSET);
}
public boolean isMutable() throws DOMException {
throw new PDOMNotImplementedError();
}
public IScope getFunctionScope() throws DOMException {
throw new PDOMNotImplementedError();
}
public IParameter[] getParameters() throws DOMException {
try {
int n = pdom.getDB().getInt(record + NUM_PARAMS);
IParameter[] params = new IParameter[n];
PDOMCPPParameterSpecialization param = getFirstParameter();
while (param != null) {
params[--n] = param;
param = param.getNextParameter();
}
return params;
} catch (CoreException e) {
CCorePlugin.log(e);
return new IParameter[0];
}
}
public IFunctionType getType() throws DOMException {
return this;
}
public boolean isAuto() throws DOMException {
// ISO/IEC 14882:2003 7.1.1.2
return false;
}
public boolean isExtern() throws DOMException {
return getBit(getByte(record + ANNOTATION), PDOMCAnnotation.EXTERN_OFFSET);
}
public boolean isRegister() throws DOMException {
// ISO/IEC 14882:2003 7.1.1.2
return false;
}
public boolean isStatic() throws DOMException {
return getBit(getByte(record + ANNOTATION), PDOMCAnnotation.STATIC_OFFSET);
}
public boolean takesVarArgs() throws DOMException {
return getBit(getByte(record + ANNOTATION), PDOMCAnnotation.VARARGS_OFFSET);
}
public boolean isSameType(IType type) {
if (type instanceof ITypedef) {
return type.isSameType(this);
}
try {
if (type instanceof ICPPFunctionType) {
ICPPFunctionType ft = (ICPPFunctionType) type;
IType rt1= getReturnType();
IType rt2= ft.getReturnType();
if (rt1 != rt2) {
if (rt1 == null || !rt1.isSameType(rt2)) {
return false;
}
}
IType[] params1= getParameterTypes();
IType[] params2= ft.getParameterTypes();
if( params1.length == 1 && params2.length == 0 ){
if( !(params1[0] instanceof IBasicType) || ((IBasicType)params1[0]).getType() != IBasicType.t_void )
return false;
} else if( params2.length == 1 && params1.length == 0 ){
if( !(params2[0] instanceof IBasicType) || ((IBasicType)params2[0]).getType() != IBasicType.t_void )
return false;
} else if( params1.length != params2.length ){
return false;
} else {
for( int i = 0; i < params1.length; i++ ){
if (params1[i] == null || ! params1[i].isSameType( params2[i] ) )
return false;
}
}
if( isConst() != ft.isConst() || isVolatile() != ft.isVolatile() )
return false;
return true;
}
return false;
} catch (DOMException e) {
}
return false;
}
public boolean isConst() {
// ISO/IEC 14882:2003 9.3.1.3
// Only applicable to member functions
return false;
}
public boolean isVolatile() {
// ISO/IEC 14882:2003 9.3.1.3
// Only applicable to member functions
return false;
}
public IType[] getParameterTypes() throws DOMException {
try {
int n = pdom.getDB().getInt(record + NUM_PARAMS);
IType[] types = new IType[n];
PDOMCPPParameterSpecialization param = getFirstParameter();
while (param != null) {
types[--n] = param.getType();
param = param.getNextParameter();
}
return types;
} catch (CoreException e) {
CCorePlugin.log(e);
return new IType[0];
}
}
public IType getReturnType() throws DOMException {
try {
PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + RETURN_TYPE));
if (node instanceof IType) {
return (IType) node;
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
return null;
}
public Object clone() {fail();return null;}
}

View file

@ -0,0 +1,170 @@
/*******************************************************************************
* 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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
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.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.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
/**
* @author Bryan Wilkinson
*
*/
public class PDOMCPPFunctionTemplate extends PDOMCPPFunction implements
ICPPFunctionTemplate, ICPPInternalTemplateInstantiator,
IPDOMMemberOwner {
private static final int TEMPLATE_PARAMS = PDOMCPPFunction.RECORD_SIZE + 0;
private static final int INSTANCES = PDOMCPPFunction.RECORD_SIZE + 4;
private static final int SPECIALIZATIONS = PDOMCPPFunction.RECORD_SIZE + 8;
/**
* The size in bytes of a PDOMCPPFunctionTemplate record in the database.
*/
protected static final int RECORD_SIZE = PDOMCPPFunction.RECORD_SIZE + 12;
public PDOMCPPFunctionTemplate(PDOM pdom, PDOMNode parent,
ICPPFunctionTemplate template) throws CoreException {
super(pdom, parent, (ICPPFunction) template, false);
}
public PDOMCPPFunctionTemplate(PDOM pdom, int bindingRecord) {
super(pdom, bindingRecord);
}
protected int getRecordSize() {
return RECORD_SIZE;
}
public int getNodeType() {
return PDOMCPPLinkage.CPP_FUNCTION_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 + TEMPLATE_PARAMS, getLinkageImpl());
TemplateParameterCollector visitor = new TemplateParameterCollector();
list.accept(visitor);
return visitor.getTemplateParameters();
} catch (CoreException e) {
CCorePlugin.log(e);
return new ICPPTemplateParameter[0];
}
}
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) {
return getInstance(arguments);
}
public void addChild(PDOMNode child) throws CoreException {
addMember(child);
}
public void addMember(PDOMNode member) throws CoreException {
if (member instanceof ICPPTemplateParameter) {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + TEMPLATE_PARAMS, 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) {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + SPECIALIZATIONS, getLinkageImpl());
list.addMember(member);
}
}
public void accept(IPDOMVisitor visitor) throws CoreException {
super.accept(visitor);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + TEMPLATE_PARAMS, getLinkageImpl());
list.accept(visitor);
list = new PDOMNodeLinkedList(pdom, record + INSTANCES, getLinkageImpl());
list.accept(visitor);
}
}

View file

@ -0,0 +1,101 @@
/*******************************************************************************
* 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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
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
*
*/
abstract class PDOMCPPInstance extends PDOMCPPSpecialization implements
ICPPTemplateInstance {
private static final int ARGUMENTS = PDOMCPPSpecialization.RECORD_SIZE + 0;
/**
* The size in bytes of a PDOMCPPInstance record in the database.
*/
protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 4;
public PDOMCPPInstance(PDOM pdom, PDOMNode parent, ICPPTemplateInstance inst, PDOMBinding instantiated)
throws CoreException {
super(pdom, parent, inst, instantiated);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + ARGUMENTS, getLinkageImpl());
IType[] args = inst.getArguments();
for (int i = 0; i < args.length; i++) {
PDOMNode typeNode = getLinkageImpl().addType(this, args[i]);
list.addMember(typeNode);
}
}
public PDOMCPPInstance(PDOM pdom, int bindingRecord) {
super(pdom, bindingRecord);
}
public ICPPTemplateDefinition getTemplateDefinition() {
return (ICPPTemplateDefinition) getSpecializedBinding();
}
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 boolean matchesArguments(IType[] arguments) {
IType [] args = getArguments();
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;
}
}

View file

@ -13,6 +13,9 @@
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.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -20,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -28,20 +32,29 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
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.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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBlockScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstanceScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
@ -94,7 +107,79 @@ class PDOMCPPLinkage extends PDOMLinkage {
public static final int CPP_POINTER_TO_MEMBER_TYPE= PDOMLinkage.LAST_NODE_TYPE + 13;
public static final int CPP_CONSTRUCTOR= PDOMLinkage.LAST_NODE_TYPE + 14;
public static final int CPP_REFERENCE_TYPE= PDOMLinkage.LAST_NODE_TYPE + 15;
public static final int CPP_FUNCTION_TEMPLATE= PDOMLinkage.LAST_NODE_TYPE + 16;
public static final int CPP_CLASS_TEMPLATE= PDOMLinkage.LAST_NODE_TYPE + 17;
public static final int CPP_CLASS_TEMPLATE_PARTIAL_SPEC= PDOMLinkage.LAST_NODE_TYPE + 18;
public static final int CPP_FUNCTION_INSTANCE= PDOMLinkage.LAST_NODE_TYPE + 19;
public static final int CPP_DEFERRED_FUNCTION_INSTANCE= PDOMLinkage.LAST_NODE_TYPE + 20;
public static final int CPP_CLASS_INSTANCE= PDOMLinkage.LAST_NODE_TYPE + 21;
public static final int CPP_DEFERRED_CLASS_INSTANCE= PDOMCPPLinkage.LAST_NODE_TYPE + 22;
public static final int CPP_TEMPLATE_TYPE_PARAMETER= PDOMLinkage.LAST_NODE_TYPE + 23;
public static final int CPP_TEMPLATE_NON_TYPE_PARAMETER= PDOMLinkage.LAST_NODE_TYPE + 24;
public static final int CPP_PARAMETER_SPECIALIZATION= PDOMLinkage.LAST_NODE_TYPE + 25;
public static final int CPP_FIELD_SPECIALIZATION= PDOMLinkage.LAST_NODE_TYPE + 26;
public static final int CPP_FUNCTION_SPECIALIZATION= PDOMLinkage.LAST_NODE_TYPE + 27;
public static final int CPP_METHOD_SPECIALIZATION= PDOMLinkage.LAST_NODE_TYPE + 28;
public static final int CPP_CONSTRUCTOR_SPECIALIZATION= PDOMLinkage.LAST_NODE_TYPE + 29;
public static final int CPP_CLASS_SPECIALIZATION= PDOMLinkage.LAST_NODE_TYPE + 30;
public static final int CPP_CLASS_TEMPLATE_SPECIALIZATION= PDOMLinkage.LAST_NODE_TYPE + 31;
private class ConfigurePartialSpecialization implements Runnable {
PDOMCPPClassTemplatePartialSpecialization partial;
ICPPClassTemplatePartialSpecialization binding;
public ConfigurePartialSpecialization(PDOMCPPClassTemplatePartialSpecialization partial, ICPPClassTemplatePartialSpecialization binding) {
this.partial = partial;
this.binding = binding;
}
public void run() {
try {
IType[] args = binding.getArguments();
for (int i = 0; i < args.length; i++) {
partial.addArgument(args[i]);
}
} catch (CoreException e) {
} catch (DOMException e) {
} finally {
partial = null;
binding = null;
}
}
}
private class ConfigureFunctionTemplate implements Runnable {
PDOMCPPFunctionTemplate template;
ICPPFunction binding;
public ConfigureFunctionTemplate(PDOMCPPFunctionTemplate template, ICPPFunction binding) {
this.template = template;
this.binding = binding;
}
public void run() {
try {
IFunctionType ft = binding.getType();
template.setReturnType(ft.getReturnType());
IParameter[] params= binding.getParameters();
IType[] paramTypes= ft.getParameterTypes();
for (int i=0; i<params.length; ++i) {
IType pt= i<paramTypes.length ? paramTypes[i] : null;
template.setFirstParameter(new PDOMCPPParameter(pdom, PDOMCPPLinkage.this, params[i], pt));
}
} catch (CoreException e) {
} catch (DOMException e) {
} finally {
template = null;
binding = null;
}
}
}
List postProcesses = new ArrayList();
public PDOMBinding addBinding(IASTName name) throws CoreException {
if (name == null || name instanceof ICPPASTQualifiedName)
return null;
@ -116,16 +201,18 @@ class PDOMCPPLinkage extends PDOMLinkage {
return null;
PDOMBinding pdomBinding = addBinding(binding);
if (pdomBinding instanceof PDOMCPPClassType) {
PDOMCPPClassType pdomClassType= (PDOMCPPClassType) pdomBinding;
if (pdomBinding instanceof PDOMCPPClassType || pdomBinding instanceof PDOMCPPClassSpecialization) {
if (binding instanceof ICPPClassType && name.isDefinition()) {
addImplicitMethods(pdomClassType, (ICPPClassType) binding);
addImplicitMethods(pdomBinding, (ICPPClassType) binding);
}
}
handlePostProcesses();
return pdomBinding;
}
private PDOMBinding addBinding(IBinding binding) throws CoreException {
public PDOMBinding addBinding(IBinding binding) throws CoreException {
// assign names to anonymous types.
binding= PDOMASTAdapter.getAdapterIfAnonymous(binding);
if (binding == null) {
@ -135,7 +222,8 @@ class PDOMCPPLinkage extends PDOMLinkage {
PDOMBinding pdomBinding = adaptBinding(binding);
try {
if (pdomBinding == null) {
PDOMNode parent = getAdaptedParent(binding, true);
boolean addParent = shouldAddParent(binding);
PDOMNode parent = getAdaptedParent(binding, true, addParent);
if (parent == null)
return null;
pdomBinding = addBinding(parent, binding);
@ -147,28 +235,104 @@ class PDOMCPPLinkage extends PDOMLinkage {
return pdomBinding;
}
private boolean shouldAddParent(IBinding binding) throws CoreException {
if (binding instanceof ICPPTemplateParameter) {
return true;
} else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
return true;
} else if (binding instanceof ICPPSpecialization) {
try {
IScope scope = binding.getScope();
if (scope instanceof CPPClassInstanceScope)
return true;
} catch (DOMException e) {
}
}
return false;
}
private PDOMBinding addBinding(PDOMNode parent, IBinding binding) throws CoreException, DOMException {
PDOMBinding pdomBinding= null;
if (binding instanceof ICPPField ) {
if (parent instanceof PDOMCPPClassType) {
pdomBinding = new PDOMCPPField(pdom, (PDOMCPPClassType)parent, (ICPPField) binding);
if (binding instanceof ICPPSpecialization) {
IBinding specialized = ((ICPPSpecialization)binding).getSpecializedBinding();
PDOMBinding pdomSpecialized = addBinding(specialized);
if (binding instanceof ICPPDeferredTemplateInstance) {
if (binding instanceof ICPPFunction && pdomSpecialized instanceof ICPPFunctionTemplate) {
pdomBinding = new PDOMCPPDeferredFunctionInstance(pdom,
parent, (ICPPFunction) binding,
(PDOMCPPFunctionTemplate) pdomSpecialized);
} else if (binding instanceof ICPPClassType && pdomSpecialized instanceof ICPPClassTemplate) {
pdomBinding = new PDOMCPPDeferredClassInstance(pdom,
parent, (ICPPClassType) binding,
(PDOMCPPClassTemplate) pdomSpecialized);
}
} else if (binding instanceof ICPPTemplateInstance) {
if (binding instanceof ICPPFunction && pdomSpecialized instanceof PDOMCPPFunctionTemplate) {
pdomBinding = new PDOMCPPFunctionInstance(pdom, parent,
(ICPPFunction) binding,
(PDOMCPPFunctionTemplate) pdomSpecialized);
} else if (binding instanceof ICPPClassType && pdomSpecialized instanceof PDOMCPPClassTemplate) {
pdomBinding = new PDOMCPPClassInstance(pdom, parent,
(ICPPClassType) binding, pdomSpecialized);
} else if (binding instanceof ICPPClassType && pdomSpecialized instanceof PDOMCPPClassTemplateSpecialization) {
pdomBinding = new PDOMCPPClassInstance(pdom, parent,
(ICPPClassType) binding, pdomSpecialized);
}
} else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
pdomBinding = new PDOMCPPClassTemplatePartialSpecialization(
pdom, parent,
(ICPPClassTemplatePartialSpecialization) binding,
(PDOMCPPClassTemplate) pdomSpecialized);
} else if (binding instanceof ICPPField && pdomSpecialized instanceof PDOMCPPField) {
pdomBinding = new PDOMCPPFieldSpecialization(pdom, parent,
(ICPPField) binding, (PDOMCPPField) pdomSpecialized);
} else if (binding instanceof ICPPConstructor) {
pdomBinding = new PDOMCPPConstructorSpecialization(pdom, parent,
(ICPPConstructor) binding, pdomSpecialized);
} else if (binding instanceof ICPPMethod) {
pdomBinding = new PDOMCPPMethodSpecialization(pdom, parent,
(ICPPMethod) binding, pdomSpecialized);
} else if (binding instanceof ICPPFunction) {
pdomBinding = new PDOMCPPFunctionSpecialization(pdom, parent,
(ICPPFunction) binding, pdomSpecialized);
} else if (binding instanceof ICPPClassTemplate) {
pdomBinding = new PDOMCPPClassTemplateSpecialization(pdom, parent,
(ICPPClassTemplate) binding, pdomSpecialized);
} else if (binding instanceof ICPPClassType) {
pdomBinding = new PDOMCPPClassSpecialization(pdom, parent,
(ICPPClassType) binding, pdomSpecialized);
}
} else if (binding instanceof ICPPField ) {
if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) {
pdomBinding = new PDOMCPPField(pdom, parent, (ICPPField) binding);
}
} else if (binding instanceof ICPPVariable) {
if (!(binding.getScope() instanceof CPPBlockScope)) {
ICPPVariable var= (ICPPVariable) binding;
pdomBinding = new PDOMCPPVariable(pdom, parent, var);
}
} else if (binding instanceof ICPPFunctionTemplate) {
if (binding instanceof ICPPConstructor) {
//TODO
} else if (binding instanceof ICPPMethod) {
//TODO
} else if (binding instanceof ICPPFunction) {
pdomBinding= new PDOMCPPFunctionTemplate(pdom, parent, (ICPPFunctionTemplate) binding);
}
} else if (binding instanceof ICPPConstructor) {
if (parent instanceof PDOMCPPClassType) {
if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) {
pdomBinding = new PDOMCPPConstructor(pdom, parent, (ICPPConstructor)binding);
}
} else if (binding instanceof ICPPMethod) {
if (parent instanceof PDOMCPPClassType) {
if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) {
pdomBinding = new PDOMCPPMethod(pdom, parent, (ICPPMethod)binding);
}
} else if (binding instanceof ICPPFunction) {
pdomBinding = new PDOMCPPFunction(pdom, parent, (ICPPFunction) binding);
pdomBinding = new PDOMCPPFunction(pdom, parent, (ICPPFunction) binding, true);
} else if (binding instanceof ICPPClassTemplate) {
pdomBinding= new PDOMCPPClassTemplate(pdom, parent, (ICPPClassTemplate) binding);
} else if (binding instanceof ICPPClassType) {
pdomBinding= new PDOMCPPClassType(pdom, parent, (ICPPClassType) binding);
} else if (binding instanceof ICPPNamespaceAlias) {
@ -185,15 +349,33 @@ class PDOMCPPLinkage extends PDOMLinkage {
(PDOMCPPEnumeration)pdomEnumeration);
} else if (binding instanceof ITypedef) {
pdomBinding = new PDOMCPPTypedef(pdom, parent, (ITypedef)binding);
} else if (binding instanceof ICPPTemplateTypeParameter) {
pdomBinding = new PDOMCPPTemplateTypeParameter(pdom, parent, (ICPPTemplateTypeParameter)binding);
}
if(pdomBinding!=null) {
parent.addChild(pdomBinding);
}
pushPostProcess(pdomBinding, binding);
return pdomBinding;
}
private void addImplicitMethods(PDOMCPPClassType type, ICPPClassType binding) throws CoreException {
private void pushPostProcess(PDOMBinding pdomBinding, IBinding binding) throws CoreException, DOMException {
if (pdomBinding instanceof PDOMCPPClassTemplatePartialSpecialization &&
binding instanceof ICPPClassTemplatePartialSpecialization) {
PDOMCPPClassTemplatePartialSpecialization pdomSpec = (PDOMCPPClassTemplatePartialSpecialization) pdomBinding;
ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) binding;
postProcesses.add(postProcesses.size(), new ConfigurePartialSpecialization(pdomSpec, spec));
} else if (pdomBinding instanceof PDOMCPPFunctionTemplate && binding instanceof ICPPFunction) {
PDOMCPPFunctionTemplate pdomTemplate = (PDOMCPPFunctionTemplate) pdomBinding;
ICPPFunction function = (ICPPFunction) binding;
postProcesses.add(postProcesses.size(), new ConfigureFunctionTemplate(pdomTemplate, function));
}
}
private void addImplicitMethods(PDOMBinding type, ICPPClassType binding) throws CoreException {
try {
IScope scope = binding.getCompositeScope();
if (scope instanceof ICPPClassScope) {
@ -211,15 +393,46 @@ class PDOMCPPLinkage extends PDOMLinkage {
}
public int getBindingType(IBinding binding) {
if (binding instanceof ICPPTemplateDefinition)
// this must be before class type
return 0;
else if (binding instanceof ICPPField)
if (binding instanceof ICPPSpecialization) {
if (binding instanceof ICPPDeferredTemplateInstance) {
if (binding instanceof ICPPFunction)
return CPP_DEFERRED_FUNCTION_INSTANCE;
if (binding instanceof ICPPClassType)
return CPP_DEFERRED_CLASS_INSTANCE;
} else if (binding instanceof ICPPTemplateInstance) {
if (binding instanceof ICPPFunction)
return CPP_FUNCTION_INSTANCE;
else if (binding instanceof ICPPClassType)
return CPP_CLASS_INSTANCE;
} else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
return CPP_CLASS_TEMPLATE_PARTIAL_SPEC;
} else if (binding instanceof ICPPField)
return CPP_FIELD_SPECIALIZATION;
else if (binding instanceof ICPPConstructor)
return CPP_CONSTRUCTOR_SPECIALIZATION;
else if (binding instanceof ICPPMethod)
return CPP_METHOD_SPECIALIZATION;
else if (binding instanceof ICPPFunction)
return CPP_FUNCTION_SPECIALIZATION;
else if (binding instanceof ICPPClassTemplate)
return CPP_CLASS_TEMPLATE_SPECIALIZATION;
else if (binding instanceof ICPPClassType)
return CPP_CLASS_SPECIALIZATION;
} else if (binding instanceof ICPPField)
// this must be before variables
return CPPFIELD;
else if (binding instanceof ICPPVariable)
return CPPVARIABLE;
else if (binding instanceof ICPPConstructor)
else if (binding instanceof ICPPFunctionTemplate) {
// this must be before functions
if (binding instanceof ICPPConstructor) {
//TODO
} else if (binding instanceof ICPPMethod) {
//TODO
} else if (binding instanceof ICPPFunction) {
return CPP_FUNCTION_TEMPLATE;
}
} else if (binding instanceof ICPPConstructor)
// before methods
return CPP_CONSTRUCTOR;
else if (binding instanceof ICPPMethod)
@ -227,6 +440,9 @@ class PDOMCPPLinkage extends PDOMLinkage {
return CPPMETHOD;
else if (binding instanceof ICPPFunction)
return CPPFUNCTION;
else if (binding instanceof ICPPClassTemplate)
// this must be before class type
return CPP_CLASS_TEMPLATE;
else if (binding instanceof ICPPClassType)
return CPPCLASSTYPE;
else if (binding instanceof ICPPNamespaceAlias)
@ -239,8 +455,12 @@ class PDOMCPPLinkage extends PDOMLinkage {
return CPPENUMERATOR;
else if (binding instanceof ITypedef)
return CPPTYPEDEF;
else
return 0;
else if (binding instanceof ICPPTemplateTypeParameter)
return CPP_TEMPLATE_TYPE_PARAMETER;
else if (binding instanceof ICPPTemplateNonTypeParameter)
return CPP_TEMPLATE_NON_TYPE_PARAMETER;
return 0;
}
/**
@ -266,7 +486,7 @@ class PDOMCPPLinkage extends PDOMLinkage {
}
}
PDOMNode parent = getAdaptedParent(binding, false);
PDOMNode parent = getAdaptedParent(binding, false, false);
if (parent == this) {
return CPPFindBinding.findBinding(getIndex(), this, binding);
@ -288,31 +508,48 @@ class PDOMCPPLinkage extends PDOMLinkage {
}
public PDOMNode addType(PDOMNode parent, IType type) throws CoreException {
if (type instanceof IProblemBinding) {
return null;
try {
if (type instanceof IProblemBinding) {
return null;
}
if (type instanceof ICPPBasicType) {
return new PDOMCPPBasicType(pdom, parent, (ICPPBasicType)type);
}
if (type instanceof ICPPClassType) {
return addBinding((ICPPClassType) type);
}
if (type instanceof IEnumeration) {
return addBinding((IEnumeration) type);
}
if (type instanceof ITypedef) {
return addBinding((ITypedef) type);
}
if (type instanceof ICPPReferenceType) {
return new PDOMCPPReferenceType(pdom, parent, (ICPPReferenceType)type);
}
if (type instanceof ICPPPointerToMemberType) {
return new PDOMCPPPointerToMemberType(pdom, parent, (ICPPPointerToMemberType)type);
}
if (type instanceof ICPPTemplateTypeParameter) {
return addBinding((ICPPTemplateTypeParameter) type);
}
return super.addType(parent, type);
} finally {
handlePostProcesses();
}
if (type instanceof ICPPBasicType) {
return new PDOMCPPBasicType(pdom, parent, (ICPPBasicType)type);
}
if (type instanceof ICPPClassType) {
return addBinding((ICPPClassType) type);
}
if (type instanceof IEnumeration) {
return addBinding((IEnumeration) type);
}
if (type instanceof ITypedef) {
return addBinding((ITypedef) type);
}
if (type instanceof ICPPReferenceType) {
return new PDOMCPPReferenceType(pdom, parent, (ICPPReferenceType)type);
}
if (type instanceof ICPPPointerToMemberType) {
return new PDOMCPPPointerToMemberType(pdom, parent, (ICPPPointerToMemberType)type);
}
return super.addType(parent, type);
}
private void handlePostProcesses() {
while (!postProcesses.isEmpty()) {
popPostProcess().run();
}
}
private Runnable popPostProcess() {
return (Runnable) postProcesses.remove(postProcesses.size() - 1);
}
public PDOMNode getNode(int record) throws CoreException {
if (record == 0)
return null;
@ -346,7 +583,34 @@ class PDOMCPPLinkage extends PDOMLinkage {
return new PDOMCPPPointerToMemberType(pdom, record);
case CPP_REFERENCE_TYPE:
return new PDOMCPPReferenceType(pdom, record);
case CPP_FUNCTION_TEMPLATE:
return new PDOMCPPFunctionTemplate(pdom, record);
case CPP_CLASS_TEMPLATE:
return new PDOMCPPClassTemplate(pdom, record);
case CPP_CLASS_TEMPLATE_PARTIAL_SPEC:
return new PDOMCPPClassTemplatePartialSpecialization(pdom, record);
case CPP_FUNCTION_INSTANCE:
return new PDOMCPPFunctionInstance(pdom, record);
case CPP_DEFERRED_FUNCTION_INSTANCE:
return new PDOMCPPDeferredFunctionInstance(pdom, record);
case CPP_CLASS_INSTANCE:
return new PDOMCPPClassInstance(pdom, record);
case CPP_DEFERRED_CLASS_INSTANCE:
return new PDOMCPPDeferredClassInstance(pdom, record);
case CPP_TEMPLATE_TYPE_PARAMETER:
return new PDOMCPPTemplateTypeParameter(pdom, record);
case CPP_FIELD_SPECIALIZATION:
return new PDOMCPPFieldSpecialization(pdom, record);
case CPP_FUNCTION_SPECIALIZATION:
return new PDOMCPPFunctionSpecialization(pdom, record);
case CPP_METHOD_SPECIALIZATION:
return new PDOMCPPMethodSpecialization(pdom, record);
case CPP_CONSTRUCTOR_SPECIALIZATION:
return new PDOMCPPConstructorSpecialization(pdom, record);
case CPP_CLASS_SPECIALIZATION:
return new PDOMCPPClassSpecialization(pdom, record);
case CPP_CLASS_TEMPLATE_SPECIALIZATION:
return new PDOMCPPClassTemplateSpecialization(pdom, record);
default:
return super.getNode(record);
}

View file

@ -54,7 +54,7 @@ class PDOMCPPMethod extends PDOMCPPFunction implements IIndexType, ICPPMethod, I
private static final int CV_OFFSET = PDOMCPPAnnotation.MAX_EXTRA_OFFSET + 1;
public PDOMCPPMethod(PDOM pdom, PDOMNode parent, ICPPMethod method) throws CoreException {
super(pdom, parent, method);
super(pdom, parent, method, true);
Database db = pdom.getDB();

View file

@ -0,0 +1,110 @@
/*******************************************************************************
* 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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
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.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
import org.eclipse.core.runtime.CoreException;
/**
* @author Bryan Wilkinson
*
*/
class PDOMCPPMethodSpecialization extends PDOMCPPFunctionSpecialization
implements ICPPMethod {
/**
* Offset of remaining annotation information (relative to the beginning of
* the record).
*/
protected static final int ANNOTATION1 = PDOMCPPFunctionSpecialization.RECORD_SIZE; // byte
/**
* The size in bytes of a PDOMCPPMethodSpecialization record in the database.
*/
protected static final int RECORD_SIZE = PDOMCPPFunctionSpecialization.RECORD_SIZE + 1;
/**
* The bit offset of CV qualifier flags within ANNOTATION1.
*/
private static final int CV_OFFSET = PDOMCPPAnnotation.MAX_EXTRA_OFFSET + 1;
public PDOMCPPMethodSpecialization(PDOM pdom, PDOMNode parent, ICPPMethod method, PDOMBinding specialized) throws CoreException {
super(pdom, parent, method, specialized);
Database db = pdom.getDB();
try {
ICPPFunctionType type = (ICPPFunctionType) method.getType();
byte annotation = 0;
annotation |= PDOMCAnnotation.encodeCVQualifiers(type) << CV_OFFSET;
annotation |= PDOMCPPAnnotation.encodeExtraAnnotation(method);
db.putByte(record + ANNOTATION1, annotation);
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
}
public PDOMCPPMethodSpecialization(PDOM pdom, int bindingRecord) {
super(pdom, bindingRecord);
}
protected int getRecordSize() {
return RECORD_SIZE;
}
public int getNodeType() {
return PDOMCPPLinkage.CPP_METHOD_SPECIALIZATION;
}
public boolean isDestructor() throws DOMException {
return getBit(getByte(record + ANNOTATION1), PDOMCPPAnnotation.DESTRUCTOR_OFFSET);
}
public boolean isImplicit() {
return getBit(getByte(record + ANNOTATION1), PDOMCPPAnnotation.IMPLICIT_METHOD_OFFSET);
}
public boolean isVirtual() throws DOMException {
return getBit(getByte(record + ANNOTATION1), PDOMCPPAnnotation.VIRTUAL_OFFSET);
}
public boolean isExtern() throws DOMException {
// ISO/IEC 14882:2003 9.2.6
return false;
}
public ICPPClassType getClassOwner() throws DOMException {
ICPPMethod f = (ICPPMethod) getSpecializedBinding();
if( f != null )
return f.getClassOwner();
return null;
}
public int getVisibility() throws DOMException {
return PDOMCPPAnnotation.getVisibility(getByte(record + ANNOTATION));
}
public boolean isConst() {
return getBit(getByte(record + ANNOTATION1), PDOMCAnnotation.CONST_OFFSET + CV_OFFSET);
}
public boolean isVolatile() {
return getBit(getByte(record + ANNOTATION1), PDOMCAnnotation.VOLATILE_OFFSET + CV_OFFSET);
}
}

View file

@ -0,0 +1,160 @@
/*******************************************************************************
* 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.IName;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBasicType;
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.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
/**
* Determines the signatures and signature mementos for bindings that can have
* siblings with the same name.
*
* @author Bryan Wilkinson
*/
public class PDOMCPPOverloaderUtil {
/**
* Returns the signature for the binding. Returns an empty string if a
* signature is not required for the binding.
*
* @param binding
* @return the signature or an empty string
* @throws CoreException
* @throws DOMException
*/
public static String getSignature(IBinding binding) throws CoreException, DOMException {
StringBuffer buffer = new StringBuffer();
if (binding instanceof ICPPTemplateInstance) {
ICPPTemplateInstance inst = (ICPPTemplateInstance) binding;
buffer.append(getTemplateArgString(inst.getArguments(), true));
} else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
ICPPClassTemplatePartialSpecialization partial = (ICPPClassTemplatePartialSpecialization) binding;
buffer.append(getTemplateArgString(partial.getArguments(), false));
} else if (binding instanceof ICPPSpecialization) {
ICPPSpecialization spec = (ICPPSpecialization) binding;
ObjectMap argMap = spec.getArgumentMap();
IType[] args = new IType[argMap.size()];
for (int i = 0; i < argMap.size(); i++) {
args[i] = (IType) argMap.getAt(i);
}
buffer.append(getTemplateArgString(args, false));
}
if (binding instanceof IFunction) {
IFunction function = (IFunction) binding;
buffer.append(getFunctionParameterString((function.getType())));
}
return buffer.toString();
}
/**
* Constructs a string in the format:
* <typeName1,typeName2,...>
*
* @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; i<types.length; i++) {
if (i>0) {
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());
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -70,7 +70,7 @@ public class ParameterHintTests extends AbstractContentAssistTest {
////TODO move function into header once indexer supports templates
//template<class T>void 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"
});

View file

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