/******************************************************************************* * Copyright (c) 2005, 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) - 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.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; 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.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; 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; /** * A template for a method. */ public class CPPMethodTemplate extends CPPFunctionTemplate implements ICPPMethod { public CPPMethodTemplate(IASTName name) { super(name); } public IASTDeclaration getPrimaryDeclaration() { //first check if we already know it if (declarations != null) { for (IASTName declaration : declarations) { IASTNode parent = declaration.getParent(); while (!(parent instanceof IASTDeclaration) && parent != null) parent = parent.getParent(); IASTDeclaration decl = (IASTDeclaration) parent; if (decl != null && decl.getParent() instanceof ICPPASTCompositeTypeSpecifier) return decl; } } if (definition != null) { IASTNode parent = definition.getParent(); while (!(parent instanceof IASTDeclaration) && parent != null) parent = parent.getParent(); IASTDeclaration decl = (IASTDeclaration) parent; if (decl != null && decl.getParent() instanceof ICPPASTCompositeTypeSpecifier) return decl; } final char[] myName = getTemplateName().getLookupKey(); IScope scope = getScope(); if (scope instanceof ICPPTemplateScope) { try { scope = scope.getParent(); } catch (DOMException e) { return null; } } ICPPClassScope clsScope = (ICPPClassScope) scope; ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) ASTInternal.getPhysicalNodeOfScope(clsScope); IASTDeclaration[] members = compSpec.getMembers(); for (IASTDeclaration member : members) { if (member instanceof ICPPASTTemplateDeclaration) { IASTDeclaration decl = ((ICPPASTTemplateDeclaration) member).getDeclaration(); if (decl instanceof IASTSimpleDeclaration) { IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators(); for (IASTDeclarator dtor : dtors) { IASTName name = ASTQueries.findInnermostDeclarator(dtor).getName(); if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) { return member; } } } else if (decl instanceof IASTFunctionDefinition) { IASTName name = ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) decl).getDeclarator()).getName(); if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) { return member; } } } } return null; } public int getVisibility() { IASTDeclaration decl = getPrimaryDeclaration(); if( decl == null ){ ICPPClassType cls = getClassOwner(); if (cls != null) { return ( cls.getKey() == ICPPClassType.k_class ) ? ICPPASTVisibilityLabel.v_private : ICPPASTVisibilityLabel.v_public; } return ICPPASTVisibilityLabel.v_private; } 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() { IScope scope= getScope(); if (scope instanceof ICPPTemplateScope) { try { scope= scope.getParent(); } catch (DOMException e) { return null; } } if( scope instanceof ICPPClassScope ){ return ((ICPPClassScope)scope).getClassType(); } return null; } public boolean isVirtual() { IASTDeclaration decl = getPrimaryDeclaration(); if (decl instanceof ICPPASTTemplateDeclaration) { ICPPASTDeclSpecifier declSpec= getDeclSpecifier(((ICPPASTTemplateDeclaration) decl).getDeclaration()); if (declSpec != null) { return declSpec.isVirtual(); } } return false; } @Override public boolean isStatic(boolean resolveAll) { IASTDeclaration decl = getPrimaryDeclaration(); if (decl instanceof ICPPASTTemplateDeclaration) { ICPPASTDeclSpecifier declSpec= getDeclSpecifier(((ICPPASTTemplateDeclaration) decl).getDeclaration()); if (declSpec != null) { return declSpec.getStorageClass() == IASTDeclSpecifier.sc_static; } } return false; } @Override public boolean isInline() { IASTDeclaration decl = getPrimaryDeclaration(); if (decl instanceof ICPPASTTemplateDeclaration && ((ICPPASTTemplateDeclaration) decl).getDeclaration() instanceof IASTFunctionDefinition) return true; return super.isInline(); } public boolean isDestructor() { char[] name = getNameCharArray(); if (name.length > 1 && name[0] == '~') return true; return false; } public boolean isImplicit() { return false; } public boolean isExplicit() { IASTDeclaration decl = getPrimaryDeclaration(); if (decl instanceof ICPPASTTemplateDeclaration) { ICPPASTDeclSpecifier declSpec= getDeclSpecifier(((ICPPASTTemplateDeclaration) decl).getDeclaration()); if (declSpec != null) { return declSpec.isExplicit(); } } return false; } public boolean isPureVirtual() { if (declarations != null && declarations.length > 0) { IASTName decl= declarations[0]; if (decl != null) { IASTNode parent = decl.getParent(); while (!(parent instanceof IASTDeclarator) && parent != null) parent = parent.getParent(); if (parent instanceof IASTDeclarator) { IASTDeclarator dtor= ASTQueries.findTypeRelevantDeclarator((IASTDeclarator) parent); if (dtor instanceof ICPPASTFunctionDeclarator) { return ((ICPPASTFunctionDeclarator) dtor).isPureVirtual(); } } } } return false; } }