blob: 0b9b780f3e9ef7f5e944b70d10e4e5509e629c07 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2014 IBM Wind River Systems, Inc. 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:
* Markus Schorn - Initial API and implementation
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTAttribute;
import org.eclipse.cdt.core.dom.ast.IASTAttributeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
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.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousSimpleDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* Handles ambiguities for simple declarations.
* <pre>
* class C {
* C(D); // If D a type we have a constructor, otherwise this declares the field D.
* };
* </pre>
*/
public class CPPASTAmbiguousSimpleDeclaration extends ASTAmbiguousNode implements IASTAmbiguousSimpleDeclaration {
private IASTSimpleDeclaration fSimpleDecl;
private IASTDeclSpecifier fAltDeclSpec;
private IASTDeclarator fAltDtor;
public CPPASTAmbiguousSimpleDeclaration(IASTSimpleDeclaration decl, IASTDeclSpecifier declSpec, IASTDeclarator dtor) {
fSimpleDecl= decl;
fAltDeclSpec= declSpec;
fAltDtor= dtor;
}
@Override
protected void beforeResolution() {
// Populate containing scope, so that it will not be affected by the alternative branches.
IScope scope= CPPVisitor.getContainingScope(this);
if (scope instanceof IASTInternalScope) {
((IASTInternalScope) scope).populateCache();
}
}
@Override
public IASTNode[] getNodes() {
return new IASTNode[] { fSimpleDecl, fAltDeclSpec, fAltDtor };
}
@Override
public IASTSimpleDeclaration copy() {
throw new UnsupportedOperationException();
}
@Override
public IASTSimpleDeclaration copy(CopyStyle style) {
throw new UnsupportedOperationException();
}
@Override
public void addDeclarator(IASTDeclarator declarator) {
fSimpleDecl.addDeclarator(declarator);
}
@Override
public IASTDeclSpecifier getDeclSpecifier() {
return fSimpleDecl.getDeclSpecifier();
}
@Override
public IASTDeclarator[] getDeclarators() {
return fSimpleDecl.getDeclarators();
}
@Override
public void setDeclSpecifier(IASTDeclSpecifier declSpec) {
fSimpleDecl.setDeclSpecifier(declSpec);
}
@Override
protected final IASTNode doResolveAmbiguity(ASTVisitor resolver) {
final IASTAmbiguityParent owner= (IASTAmbiguityParent) getParent();
IASTNode nodeToReplace= this;
// Handle nested ambiguities first.
owner.replace(nodeToReplace, fSimpleDecl);
IASTDeclarator dtor= fSimpleDecl.getDeclarators()[0];
dtor.accept(resolver);
// Find nested names.
final NameCollector nameCollector= new NameCollector();
dtor.accept(nameCollector);
final IASTName[] names= nameCollector.getNames();
// Resolve names.
boolean hasIssue= false;
for (IASTName name : names) {
try {
IBinding b = name.resolveBinding();
if (b instanceof IProblemBinding) {
hasIssue= true;
break;
}
} catch (Exception t) {
hasIssue= true;
break;
}
}
if (hasIssue) {
// Use the alternate version.
final IASTAmbiguityParent parent = (IASTAmbiguityParent) fSimpleDecl;
parent.replace(fSimpleDecl.getDeclSpecifier(), fAltDeclSpec);
parent.replace(dtor, fAltDtor);
}
// Resolve further nested ambiguities.
fSimpleDecl.accept(resolver);
return fSimpleDecl;
}
@Override
public IASTAttribute[] getAttributes() {
return fSimpleDecl.getAttributes();
}
@Override
@Deprecated
public void addAttribute(IASTAttribute attribute) {
fSimpleDecl.addAttribute(attribute);
}
@Override
public IASTAttributeSpecifier[] getAttributeSpecifiers() {
return fSimpleDecl.getAttributeSpecifiers();
}
@Override
public void addAttributeSpecifier(IASTAttributeSpecifier attributeSpecifier) {
fSimpleDecl.addAttributeSpecifier(attributeSpecifier);
}
}