/******************************************************************************* * Copyright (c) 2005, 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: * IBM - Initial API and implementation * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) * Andrew Ferguson (Symbian) * Thomas Corbat (IFS) * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.IASTNode; 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.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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.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.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; /** * Represents a class template. */ public class CPPClassTemplate extends CPPTemplateDefinition implements ICPPClassTemplate, ICPPInternalClassTemplate, ICPPInternalClassTypeMixinHost { private ICPPClassTemplatePartialSpecialization[] partialSpecializations; private ICPPDeferredClassInstance fDeferredInstance; private boolean addedPartialSpecializationsOfIndex; private ICPPBase[] bases; public CPPClassTemplate(IASTName name) { super(name); } @Override public void checkForDefinition() { // Ambiguity resolution ensures that definitions are resolved. } @Override public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) { partialSpecializations = ArrayUtil.append( ICPPClassTemplatePartialSpecialization.class, partialSpecializations, spec); } @Override public ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier() { if (definition != null) { IASTNode node = definition.getParent(); if (node instanceof ICPPASTQualifiedName) node = node.getParent(); if (node instanceof ICPPASTCompositeTypeSpecifier) return (ICPPASTCompositeTypeSpecifier) node; } return null; } @Override public ICPPClassScope getCompositeScope() { if (definition == null) { 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(); } } // Forward declarations must be backed up from the index. ICPPClassTemplate ib = getIndexBinding(); if (ib != null) { IScope scope = ib.getCompositeScope(); if (scope instanceof ICPPClassScope) return (ICPPClassScope) scope; } return null; } @Override public int getKey() { if (definition != null) { ICPPASTCompositeTypeSpecifier cts= getCompositeTypeSpecifier(); if (cts != null) { return cts.getKey(); } IASTNode n= definition.getParent(); if (n instanceof ICPPASTElaboratedTypeSpecifier) { return ((ICPPASTElaboratedTypeSpecifier) n).getKind(); } } if (declarations != null && declarations.length > 0) { IASTNode n = declarations[0].getParent(); if (n instanceof ICPPASTElaboratedTypeSpecifier) { return ((ICPPASTElaboratedTypeSpecifier) n).getKind(); } } return ICPPASTElaboratedTypeSpecifier.k_class; } @Override public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { if (!addedPartialSpecializationsOfIndex) { addedPartialSpecializationsOfIndex= true; ICPPClassTemplate ib = getIndexBinding(); if (ib != null) { IIndexFileSet fs = getTemplateName().getTranslationUnit().getIndexFileSet(); for (ICPPClassTemplatePartialSpecialization spec : ib.getPartialSpecializations()) { if (spec instanceof IIndexBinding && fs.containsDeclaration((IIndexBinding) spec)) { addPartialSpecialization(spec); } } } } partialSpecializations = ArrayUtil.trim(ICPPClassTemplatePartialSpecialization.class, partialSpecializations); return partialSpecializations; } @Override public boolean isSameType(IType type) { if (type == this) return true; if (type instanceof ITypedef || type instanceof IIndexBinding) return type.isSameType(this); return false; } @Override public ICPPBase[] getBases() { if (bases == null) { bases = ClassTypeHelper.getBases(this); } return bases; } @Override public IField[] getFields() { return ClassTypeHelper.getFields(this, null); } @Override public ICPPField[] getDeclaredFields() { return ClassTypeHelper.getDeclaredFields(this); } @Override public ICPPMethod[] getMethods() { return ClassTypeHelper.getMethods(this, null); } @Override public ICPPMethod[] getAllDeclaredMethods() { return ClassTypeHelper.getAllDeclaredMethods(this, null); } @Override public ICPPMethod[] getDeclaredMethods() { return ClassTypeHelper.getDeclaredMethods(this); } @Override public ICPPConstructor[] getConstructors() { return ClassTypeHelper.getConstructors(this); } @Override public IBinding[] getFriends() { return ClassTypeHelper.getFriends(this); } @Override public ICPPClassType[] getNestedClasses() { return ClassTypeHelper.getNestedClasses(this); } @Override public IField findField(String name) { return ClassTypeHelper.findField(this, name); } @Override public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { } return null; } /* For debug purposes only */ @Override public String toString() { return ASTTypeUtil.getType(this); } @Override public boolean isAnonymous() { return false; } @Override public final ICPPDeferredClassInstance asDeferredInstance() { if (fDeferredInstance == null) { fDeferredInstance= CPPTemplates.createDeferredInstance(this); } return fDeferredInstance; } @Override public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException { ICPPClassTemplate ib = getIndexBinding(); if (ib != null) { ICPPTemplateParameter[] params = ib.getTemplateParameters(); if (paramPos < params.length) { ICPPTemplateParameter param = params[paramPos]; return param.getDefaultValue(); } } return null; } @Override public boolean isFinal() { ICPPASTCompositeTypeSpecifier typeSpecifier = getCompositeTypeSpecifier(); if (typeSpecifier != null) { return typeSpecifier.isFinal(); } return false; } @Override public int getVisibility(IBinding member) { return ClassTypeHelper.getVisibility(this, member); } }