blob: 185907c83458b18b4537ade15769f23ac4d5a5ba [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2012 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)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
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.IASTElaboratedTypeSpecifier;
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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
/**
* Utility class to populate scope with friend declarations hidden in nested classes
*/
class NamespaceTypeCollector extends ASTVisitor {
private final ICPPASTInternalScope fScope;
public NamespaceTypeCollector(ICPPASTInternalScope scope) {
fScope= scope;
shouldVisitDeclarations= true;
shouldVisitStatements= true;
shouldVisitParameterDeclarations= true;
}
@Override
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) simpleDeclaration.getDeclSpecifier();
if (declSpec.isFriend()) {
IASTDeclarator[] declarators= simpleDeclaration.getDeclarators();
for (IASTDeclarator declarator : declarators) {
IASTDeclarator innermost= null;
while (declarator != null) {
if (declarator instanceof IASTAmbiguousDeclarator) {
innermost= null;
break;
}
innermost= declarator;
declarator= declarator.getNestedDeclarator();
}
if (innermost != null) {
IASTName declaratorName = innermost.getName();
ASTInternal.addName(fScope, declaratorName);
}
}
} else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier) {
// 3.3.1.5 Point of declaration
if (simpleDeclaration.getDeclarators().length != 0) {
addNonSimpleElabSpec((ICPPASTElaboratedTypeSpecifier) declSpec);
}
}
// Visit nested class definitions and parameter declarations
return PROCESS_CONTINUE;
} else if (declaration instanceof IASTFunctionDefinition) {
IASTFunctionDefinition funcDefinition = (IASTFunctionDefinition) declaration;
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) funcDefinition.getDeclSpecifier();
if (declSpec.isFriend()) {
IASTFunctionDeclarator declarator = funcDefinition.getDeclarator();
ASTInternal.addName(fScope, declarator.getName());
} else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier) {
addNonSimpleElabSpec((ICPPASTElaboratedTypeSpecifier) declSpec);
}
// Visit parameter declarations
return PROCESS_CONTINUE;
}
return PROCESS_SKIP;
}
@Override
public int visit(IASTParameterDeclaration declaration) {
IASTDeclSpecifier declSpec = declaration.getDeclSpecifier();
if (declSpec instanceof ICPPASTElaboratedTypeSpecifier) {
addNonSimpleElabSpec((ICPPASTElaboratedTypeSpecifier) declSpec);
}
return PROCESS_SKIP;
}
private void addNonSimpleElabSpec(final ICPPASTElaboratedTypeSpecifier elabSpec) {
if (elabSpec.getKind() != IASTElaboratedTypeSpecifier.k_enum) {
final IASTName name = elabSpec.getName();
if (!(name instanceof ICPPASTQualifiedName)) {
ASTInternal.addName(fScope, name);
}
}
}
@Override
public int visit(IASTStatement statement) {
// Don't visit function bodies
return PROCESS_SKIP;
}
}