/******************************************************************************* * Copyright (c) 2004, 2013 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) * Thomas Corbat (IFS) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; 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.ICPPASTQualifiedName; 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.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; /** * The binding for a method. */ public class CPPMethod extends CPPFunction implements ICPPMethod { public CPPMethod(IASTDeclarator declarator) { super(declarator); } public IASTDeclaration getPrimaryDeclaration() { //first check if we already know it if (declarations != null) { for (IASTDeclarator dtor : declarations) { if (dtor == null) { break; } dtor = ASTQueries.findOutermostDeclarator(dtor); IASTDeclaration decl = (IASTDeclaration) dtor.getParent(); if (decl.getParent() instanceof ICPPASTCompositeTypeSpecifier) return decl; } } if (definition != null) { IASTDeclarator dtor = ASTQueries.findOutermostDeclarator(definition); IASTDeclaration decl = (IASTDeclaration) dtor.getParent(); if (decl.getParent() instanceof ICPPASTCompositeTypeSpecifier) return decl; } final char[] myName = getASTName().getLookupKey(); ICPPClassScope scope = (ICPPClassScope) getScope(); ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) ASTInternal.getPhysicalNodeOfScope(scope); if (compSpec != null) { IASTDeclaration [] members = compSpec.getMembers(); for (IASTDeclaration member : members) { if (member instanceof IASTSimpleDeclaration) { IASTDeclarator[] dtors = ((IASTSimpleDeclaration) member).getDeclarators(); for (IASTDeclarator dtor : dtors) { IASTName name = ASTQueries.findInnermostDeclarator(dtor).getName(); if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) { return member; } } } else if (member instanceof IASTFunctionDefinition) { final IASTFunctionDeclarator declarator = ((IASTFunctionDefinition) member).getDeclarator(); IASTName name = ASTQueries.findInnermostDeclarator(declarator).getName(); if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) { return member; } } } } return null; } @Override public int getVisibility() { IASTDeclaration decl = getPrimaryDeclaration(); if (decl == null) { IScope scope = getScope(); if (scope instanceof ICPPClassScope) { ICPPClassType cls = ((ICPPClassScope) scope).getClassType(); 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; } @Override public ICPPClassType getClassOwner() { ICPPClassScope scope = (ICPPClassScope) getScope(); return scope.getClassType(); } @Override protected IASTName getASTName() { IASTDeclarator dtor= (declarations != null && declarations.length > 0) ? declarations[0] : definition; dtor= ASTQueries.findInnermostDeclarator(dtor); IASTName name= dtor.getName(); if (name instanceof ICPPASTQualifiedName) { name = name.getLastName(); } return name; } @Override public IScope getScope() { return CPPVisitor.getContainingScope(getASTName()); } @Override public boolean isVirtual() { IASTDeclaration decl = getPrimaryDeclaration(); if (decl != null) { ICPPASTDeclSpecifier declSpec = getDeclSpec(decl); if (declSpec != null) { return declSpec.isVirtual(); } } return false; } protected ICPPASTDeclSpecifier getDeclSpec(IASTDeclaration decl) { ICPPASTDeclSpecifier declSpec = null; if (decl instanceof IASTSimpleDeclaration) { declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration) decl).getDeclSpecifier(); } else if (decl instanceof IASTFunctionDefinition) { declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition) decl).getDeclSpecifier(); } return declSpec; } @Override public boolean isInline() { IASTDeclaration decl = getPrimaryDeclaration(); if (decl instanceof IASTFunctionDefinition) return true; if (decl == null) return false; IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier(); return declSpec.isInline(); } @Override public boolean isMutable() { return hasStorageClass(this, IASTDeclSpecifier.sc_mutable); } @Override public boolean isStatic(boolean resolveAll) { IASTDeclaration decl = getPrimaryDeclaration(); if (decl != null) { ICPPASTDeclSpecifier declSpec = getDeclSpec(decl); if (declSpec != null) { return declSpec.getStorageClass() == IASTDeclSpecifier.sc_static; } } return false; } @Override public boolean isDestructor() { char[] name = getNameCharArray(); if (name.length > 1 && name[0] == '~') return true; return false; } @Override public boolean isImplicit() { return false; } @Override public boolean isPureVirtual() { ICPPASTFunctionDeclarator declarator = findFunctionDeclarator(); if (declarator != null) { return declarator.isPureVirtual(); } return false; } @Override public boolean isFinal() { ICPPASTFunctionDeclarator declarator = findFunctionDeclarator(); if (declarator != null) { return declarator.isFinal(); } return false; } @Override public boolean isOverride() { ICPPASTFunctionDeclarator declarator = findFunctionDeclarator(); if (declarator != null) { return declarator.isOverride(); } return false; } private ICPPASTFunctionDeclarator findFunctionDeclarator() { if (declarations != null) { for (IASTDeclarator dtor : declarations) { if (dtor == null) break; dtor = ASTQueries.findOutermostDeclarator(dtor); IASTDeclaration decl = (IASTDeclaration) dtor.getParent(); if (decl.getParent() instanceof ICPPASTCompositeTypeSpecifier) { dtor= ASTQueries.findTypeRelevantDeclarator(dtor); if (dtor instanceof ICPPASTFunctionDeclarator) { return (ICPPASTFunctionDeclarator) dtor; } } } } return definition; } @Override public boolean isExplicit() { IASTDeclaration decl= getPrimaryDeclaration(); if (decl != null) { ICPPASTDeclSpecifier declspec= getDeclSpec(decl); if (declspec != null) { return declspec.isExplicit(); } } return false; } }