/******************************************************************************* * Copyright (c) 2008, 2013 Symbian Software Systems 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 Ferguson (Symbian) - Initial Implementation * Markus Schorn (Wind River Systems) * IBM Corporation * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.core.runtime.Assert; /** * Ambiguity node for deciding between type-id and expression in a template argument. */ public class CPPASTAmbiguousTemplateArgument extends ASTAmbiguousNode implements ICPPASTAmbiguousTemplateArgument { private List<IASTNode> fNodes; /** * @param nodes nodes of type {@link IASTTypeId}, {@link IASTIdExpression} * or {@link ICPPASTPackExpansionExpression}. */ public CPPASTAmbiguousTemplateArgument(IASTNode... nodes) { fNodes= new ArrayList<IASTNode>(2); for (IASTNode node : nodes) { if (node instanceof IASTTypeId || node instanceof IASTExpression) { fNodes.add(node); } else { Assert.isLegal(false, node == null ? "null" : node.getClass().getName()); //$NON-NLS-1$ } } } @Override protected void beforeAlternative(IASTNode node) { // If the expression is an id-expression, the name may be shared // between the alternatives (see bug 316704), so make sure its parent // is set correctly. if (node instanceof IASTTypeId) { IASTDeclSpecifier declSpec = ((IASTTypeId) node).getDeclSpecifier(); if (declSpec instanceof IASTNamedTypeSpecifier) { IASTNamedTypeSpecifier namedTypeSpec= (IASTNamedTypeSpecifier) declSpec; final IASTName name = namedTypeSpec.getName(); name.setBinding(null); namedTypeSpec.setName(name); } } else { // Unwrap variadic pack expansion if necessary. if (node instanceof ICPPASTPackExpansionExpression) node= ((ICPPASTPackExpansionExpression) node).getPattern(); if (node instanceof IASTIdExpression) { IASTIdExpression id= (IASTIdExpression) node; final IASTName name = id.getName(); name.setBinding(null); id.setName(name); } } } @Override protected void afterResolution(ASTVisitor resolver, IASTNode best) { beforeAlternative(best); } @Override public IASTNode copy() { return copy(CopyStyle.withoutLocations); } @Override public IASTNode copy(CopyStyle style) { int sizeOfNodes = fNodes.size(); IASTNode[] copyNodes = new IASTNode[sizeOfNodes]; int arrayIndex = 0; for (IASTNode node : fNodes) { if (node != null) { copyNodes[arrayIndex] = node.copy(style); } else { copyNodes[arrayIndex] = null; } arrayIndex++; } ICPPASTAmbiguousTemplateArgument ambiguityNode = new CPPASTAmbiguousTemplateArgument(copyNodes); return ambiguityNode; } @Override public IASTNode[] getNodes() { return fNodes.toArray(new IASTNode[fNodes.size()]); } @Override public void addTypeId(IASTTypeId typeId) { assertNotFrozen(); addNode(typeId); } @Override public void addExpression(IASTExpression expression) { assertNotFrozen(); addNode(expression); } @Override public void addIdExpression(IASTIdExpression idExpression) { addExpression(idExpression); } @Deprecated @Override public void addIdExpression(IASTExpression idExpression) { addExpression(idExpression); } private void addNode(IASTNode node) { fNodes.add(node); node.setParent(this); node.setPropertyInParent(ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT); } }