1
/*******************************************************************************
2
* Copyright (c) 2004, 2009 IBM Corporation and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* John Camelon (IBM) - Initial API and implementation
10
* Markus Schorn (Wind River Systems)
11
*******************************************************************************/
12
package org.eclipse.cdt.internal.core.dom.parser.cpp;
14
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
15
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
16
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
17
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
18
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
19
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
20
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
21
import org.eclipse.cdt.core.dom.ast.IASTName;
22
import org.eclipse.cdt.core.dom.ast.IASTNode;
23
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
24
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
25
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
26
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
27
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
28
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
29
import org.eclipse.cdt.core.parser.util.ArrayUtil;
30
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
31
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
32
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
35
* C++ specific declarator.
37
public class CPPASTDeclarator extends ASTNode implements IASTDeclarator {
38
private IASTInitializer initializer;
39
private IASTName name;
40
private IASTDeclarator nested;
41
private IASTPointerOperator[] pointerOps = null;
42
private int pointerOpsPos= -1;
44
public CPPASTDeclarator() {
47
public CPPASTDeclarator(IASTName name) {
51
public CPPASTDeclarator(IASTName name, IASTInitializer initializer) {
53
setInitializer(initializer);
57
public CPPASTDeclarator copy() {
58
CPPASTDeclarator copy = new CPPASTDeclarator();
59
copyBaseDeclarator(copy);
63
protected void copyBaseDeclarator(CPPASTDeclarator copy) {
64
copy.setName(name == null ? null : name.copy());
65
copy.setInitializer(initializer == null ? null : initializer.copy());
66
copy.setNestedDeclarator(nested == null ? null : nested.copy());
67
for(IASTPointerOperator pointer : getPointerOperators())
68
copy.addPointerOperator(pointer == null ? null : pointer.copy());
69
copy.setOffsetAndLength(this);
72
public IASTPointerOperator[] getPointerOperators() {
73
if (pointerOps == null) return IASTPointerOperator.EMPTY_ARRAY;
74
pointerOps = (IASTPointerOperator[]) ArrayUtil.removeNullsAfter(IASTPointerOperator.class, pointerOps, pointerOpsPos);
78
public IASTDeclarator getNestedDeclarator() {
82
public IASTName getName() {
86
public IASTInitializer getInitializer() {
90
public void setInitializer(IASTInitializer initializer) {
92
this.initializer = initializer;
93
if (initializer != null) {
94
initializer.setParent(this);
95
initializer.setPropertyInParent(INITIALIZER);
99
public void addPointerOperator(IASTPointerOperator operator) {
101
if (operator != null) {
102
operator.setParent(this);
103
operator.setPropertyInParent(POINTER_OPERATOR);
104
pointerOps = (IASTPointerOperator[]) ArrayUtil.append(IASTPointerOperator.class, pointerOps, ++pointerOpsPos, operator);
108
public void setNestedDeclarator(IASTDeclarator nested) {
110
this.nested = nested;
111
if (nested != null) {
112
nested.setParent(this);
113
nested.setPropertyInParent(NESTED_DECLARATOR);
117
public void setName(IASTName name) {
121
name.setParent(this);
122
name.setPropertyInParent(DECLARATOR_NAME);
127
public boolean accept(ASTVisitor action) {
128
if (action.shouldVisitDeclarators) {
129
switch(action.visit(this)) {
130
case ASTVisitor.PROCESS_ABORT: return false;
131
case ASTVisitor.PROCESS_SKIP: return true;
136
for (int i = 0; i <= pointerOpsPos; i++) {
137
if (!pointerOps[i].accept(action))
141
if (nested == null && name != null) {
142
IASTDeclarator outermost= ASTQueries.findOutermostDeclarator(this);
143
if (outermost.getPropertyInParent() != IASTTypeId.ABSTRACT_DECLARATOR) {
144
if (!name.accept(action)) return false;
148
if (nested != null) {
149
if (!nested.accept(action)) return false;
152
if (!postAccept(action))
155
if (action.shouldVisitDeclarators && action.leave(this) == ASTVisitor.PROCESS_ABORT)
161
protected boolean postAccept(ASTVisitor action) {
162
if (initializer != null && !initializer.accept(action))
169
public int getRoleForName(IASTName n) {
171
IASTNode parent = ASTQueries.findOutermostDeclarator(this).getParent();
172
if (parent instanceof IASTDeclaration) {
173
// a declaration is a definition unless ...
174
if (parent instanceof IASTFunctionDefinition)
177
if (parent instanceof IASTSimpleDeclaration) {
178
final IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) parent;
180
// unless it declares a function without body
181
if (this instanceof IASTFunctionDeclarator) {
182
return r_declaration;
185
final int storage = sdecl.getDeclSpecifier().getStorageClass();
186
// unless it contains the extern specifier or a linkage-specification and neither initializer nor function-body
187
if (getInitializer() == null && (storage == IASTDeclSpecifier.sc_extern || isSimpleLinkageSpec(sdecl))) {
188
return r_declaration;
190
// unless it declares a static data member in a class declaration
191
if (storage == IASTDeclSpecifier.sc_static && CPPVisitor.getContainingScope(parent) instanceof ICPPClassScope) {
192
return r_declaration;
194
// unless it is a class name declaration: no declarator in this case
195
// unless it is a typedef declaration
196
if (storage == IASTDeclSpecifier.sc_typedef)
197
return r_definition; // should actually be a declaration
199
// unless it is a using-declaration or using-directive: no declarator in this case
206
if (parent instanceof IASTTypeId)
209
if (parent instanceof IASTParameterDeclaration)
210
return (n.getLookupKey().length > 0) ? r_definition : r_declaration;
215
private boolean isSimpleLinkageSpec(IASTSimpleDeclaration sdecl) {
216
IASTNode parent= sdecl.getParent();
217
if (parent instanceof ICPPASTLinkageSpecification) {
218
ICPPASTLinkageSpecification spec= (ICPPASTLinkageSpecification) parent;
219
// todo distinction between braced enclose and simple linkage specification
220
if (spec.getDeclarations().length == 1) {