/*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation 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:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* Binding for implicit methods, base class for implicit constructors.
*/
public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod {
public CPPImplicitMethod(ICPPClassScope scope, char[] name, ICPPFunctionType type, ICPPParameter[] params) {
super(name, scope, type, params, false);
}
public int getVisibility() {
IASTDeclaration decl= getPrimaryDeclaration();
if (decl == null) {
// 12.1-5, 12.8-10 Implicit constructors and assignment operators are public
return ICPPASTVisibilityLabel.v_public;
}
IASTNode parent= decl.getParent();
while (parent instanceof ICPPASTTemplateDeclaration) {
decl= (ICPPASTTemplateDeclaration) parent;
parent= parent.getParent();
}
if (parent instanceof IASTCompositeTypeSpecifier) {
IASTCompositeTypeSpecifier cls = (IASTCompositeTypeSpecifier) decl.getParent();
IASTDeclaration [] members = cls.getMembers();
ICPPASTVisibilityLabel vis = null;
for (IASTDeclaration member : members) {
if( member instanceof ICPPASTVisibilityLabel )
vis = (ICPPASTVisibilityLabel) member;
else if( member == decl )
break;
}
if( vis != null ){
return vis.getVisibility();
} else if( cls.getKey() == ICPPASTCompositeTypeSpecifier.k_class ){
return ICPPASTVisibilityLabel.v_private;
}
}
return ICPPASTVisibilityLabel.v_public;
}
public ICPPClassType getClassOwner() {
ICPPClassScope scope = (ICPPClassScope)getScope();
return scope.getClassType();
}
public IASTDeclaration getPrimaryDeclaration() {
// first check if we already know it
if (declarations != null) {
for (IASTDeclarator dtor : declarations) {
if (dtor == null)
break;
IASTDeclaration decl = (IASTDeclaration) ASTQueries.findOutermostDeclarator(dtor).getParent();
IASTNode parent= decl.getParent();
while (parent instanceof ICPPASTTemplateDeclaration)
parent= parent.getParent();
if (parent instanceof ICPPASTCompositeTypeSpecifier)
return decl;
}
}
IFunctionType ftype = getType();
IType[] params = ftype.getParameterTypes();
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) ASTInternal
.getPhysicalNodeOfScope(getScope());
if (compSpec == null) {
return null;
}
IASTDeclaration[] members = compSpec.getMembers();
for (IASTDeclaration member : members) {
IASTDeclarator[] ds = null;
while (member instanceof ICPPASTTemplateDeclaration)
member = ((ICPPASTTemplateDeclaration) member).getDeclaration();
if (member instanceof IASTSimpleDeclaration) {
ds = ((IASTSimpleDeclaration) member).getDeclarators();
} else if (member instanceof IASTFunctionDefinition) {
ds = new IASTDeclarator[] {((IASTFunctionDefinition) member).getDeclarator()};
} else {
continue;
}
for (IASTDeclarator dtor : ds) {
IASTName name = ASTQueries.findInnermostDeclarator(dtor).getName();
if (ASTQueries.findTypeRelevantDeclarator(dtor) instanceof ICPPASTFunctionDeclarator
&& CharArrayUtils.equals(name.getLookupKey(), getNameCharArray())) {
IType t0 = CPPVisitor.createType(dtor);
boolean ok = false;
if (t0 instanceof IFunctionType) {
IFunctionType t = (IFunctionType) t0;
IType[] ps = t.getParameterTypes();
if (ps.length == params.length) {
int idx = 0;
for (; idx < ps.length && ps[idx] != null; idx++) {
if (!ps[idx].isSameType(params[idx]))
break;
}
ok = idx == ps.length;
} else if (ps.length == 0) {
if (params.length == 1) {
ok = SemanticUtil.isVoidType(params[0]);
}
}
} else {
ok = false;
}
if (ok) {
name.setBinding(this);
if (member instanceof IASTSimpleDeclaration)
ASTInternal.addDeclaration(this, dtor);
else if (member instanceof IASTFunctionDefinition)
ASTInternal.addDefinition(this, dtor);
return member;
}
}
}
}
return null;
}
public boolean isVirtual() {
return false;
}
public boolean isDestructor() {
char [] n = getNameCharArray();
if( n != null && n.length > 0 )
return n[0] == '~';
return false;
}
public boolean isImplicit() {
return getPrimaryDeclaration() == null;
}
public boolean isExplicit() {
return false;
}
public boolean isPureVirtual() {
return false;
}
@Override
public IBinding getOwner() {
return getClassOwner();
}
@Override
public IType[] getExceptionSpecification() {
return ClassTypeHelper.getInheritedExceptionSpecification(this);
}
}