/*******************************************************************************
* Copyright (c) 2004, 2014 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
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
* Nathan Ridge
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
public class CPPBaseClause implements ICPPBase, ICPPInternalBase {
private final ICPPASTBaseSpecifier base;
private IType baseClass;
private boolean inheritedConstructorsSource;
public CPPBaseClause(ICPPASTBaseSpecifier base) {
this.base = base;
}
@Override
public IBinding getBaseClass() {
IType type= getBaseClassType();
type = getNestedType(type, TDEF);
if (type instanceof IBinding)
return (IBinding) type;
return null;
}
@Override
public IType getBaseClassType() {
if (baseClass == null) {
ICPPASTNameSpecifier nameSpec = base.getNameSpecifier();
IBinding b = nameSpec.resolveBinding();
if (b instanceof IProblemBinding) {
baseClass = new CPPClassType.CPPClassTypeProblem(nameSpec, ((IProblemBinding) b).getID());
} else if (!(b instanceof IType)) {
baseClass = new CPPClassType.CPPClassTypeProblem(nameSpec, ISemanticProblem.BINDING_NO_CLASS);
} else {
baseClass= (IType) b;
IType check= getNestedType(baseClass, TDEF);
if (!(check instanceof ICPPClassType || check instanceof ICPPUnknownType)) {
baseClass = new CPPClassType.CPPClassTypeProblem(nameSpec, ISemanticProblem.BINDING_NO_CLASS);
}
}
if (base.isPackExpansion()) {
baseClass = new CPPParameterPackType(baseClass);
}
}
return baseClass;
}
@Override
public int getVisibility() {
int vis = base.getVisibility();
if (vis == 0) {
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) base.getParent();
vis = compSpec.getKey() == ICPPClassType.k_class ? ICPPBase.v_private : ICPPBase.v_public;
}
return vis;
}
@Override
public boolean isVirtual() {
return base.isVirtual();
}
@Override
public boolean isInheritedConstructorsSource() {
return inheritedConstructorsSource;
}
@Override
public IName getClassDefinitionName() {
IASTNode parent = base.getParent();
if (parent instanceof ICPPASTCompositeTypeSpecifier) {
return ((ICPPASTCompositeTypeSpecifier) parent).getName();
}
return null;
}
@Override
public ICPPBase clone() {
ICPPBase t = null;
try {
t = (ICPPBase) super.clone();
} catch (CloneNotSupportedException e) {
// Not going to happen.
}
return t;
}
@Override
public void setBaseClass(IBinding cls) {
if (cls instanceof IType)
baseClass = (IType) cls;
}
@Override
public void setBaseClass(IType cls) {
baseClass = cls;
}
public void setInheritedConstructorsSource(boolean value) {
inheritedConstructorsSource = value;
}
}