1
/*******************************************************************************
2
* Copyright (c) 2005, 2011 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
* Andrew Niefer (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.ILinkage;
15
import org.eclipse.cdt.core.dom.ast.IASTName;
16
import org.eclipse.cdt.core.dom.ast.IASTNode;
17
import org.eclipse.cdt.core.dom.ast.IBinding;
18
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
19
import org.eclipse.cdt.core.dom.ast.IScope;
20
import org.eclipse.cdt.core.dom.ast.IType;
21
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
22
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
23
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
24
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
25
import org.eclipse.cdt.core.parser.util.ArrayUtil;
26
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
27
import org.eclipse.cdt.internal.core.dom.Linkage;
28
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
29
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
30
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
31
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
32
import org.eclipse.core.runtime.PlatformObject;
35
* Base implementation for template parameter bindings in the AST.
37
public abstract class CPPTemplateParameter extends PlatformObject
38
implements ICPPTemplateParameter, ICPPInternalBinding, ICPPTwoPhaseBinding {
39
private IASTName[] declarations;
40
private final int fParameterID;
42
public CPPTemplateParameter(IASTName name) {
43
declarations = new IASTName[] {name};
44
fParameterID= computeParameterID(name);
47
private int computeParameterID(IASTName name) {
49
ICPPASTTemplateParameter tp= null;
50
ICPPASTTemplateParameter[] tps= null;
51
for (IASTNode node= name.getParent(); node != null; node= node.getParent()) {
52
if (tp == null && node instanceof ICPPASTTemplateParameter) {
53
tp= (ICPPASTTemplateParameter) node;
54
} else if (node instanceof ICPPASTInternalTemplateDeclaration) {
55
final ICPPASTInternalTemplateDeclaration tdecl= (ICPPASTInternalTemplateDeclaration) node;
56
nesting+= tdecl.getNestingLevel();
58
tps= tdecl.getTemplateParameters();
61
} else if (node instanceof ICPPASTTemplatedTypeTemplateParameter) {
64
tps= ((ICPPASTTemplatedTypeTemplateParameter) node).getTemplateParameters();
69
if (tps != null && tp != null) {
70
for (int i = 0; i < tps.length; i++) {
78
return (nesting << 16) + (pos & 0xffff);
82
public Object clone() {
85
t = (IType) super.clone();
86
} catch (CloneNotSupportedException e) {
93
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
95
public final String getName() {
96
return new String(getNameCharArray());
100
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
102
public final char[] getNameCharArray() {
103
// Search for the first declaration that has a name.
104
for (IASTName decl : declarations) {
108
final char[] result= decl.getSimpleID();
109
if (result.length > 0)
112
return CharArrayUtils.EMPTY;
115
public int getParameterID() {
119
public short getParameterPosition() {
120
return (short) fParameterID;
123
public short getTemplateNestingLevel() {
124
return (short) (fParameterID >> 16);
127
public IASTName getPrimaryDeclaration () {
128
return declarations[0];
131
private ICPPASTTemplateParameter getASTTemplateParameter() {
132
IASTNode node= declarations[0];
133
while (node != null && !(node instanceof ICPPASTTemplateParameter))
134
node= node.getParent();
136
return (ICPPASTTemplateParameter) node;
140
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
142
public IScope getScope() {
143
return CPPVisitor.getContainingScope(getPrimaryDeclaration());
147
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedName()
149
public String[] getQualifiedName() {
150
return new String[] { getName() };
154
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedNameCharArray()
156
public char[][] getQualifiedNameCharArray() {
157
return new char[][] {getNameCharArray() };
161
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#isGloballyQualified()
163
public boolean isGloballyQualified() {
168
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDeclarations()
170
public IASTName[] getDeclarations() {
175
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDefinition()
177
public IASTNode getDefinition() {
178
if (declarations != null && declarations.length > 0)
179
return declarations[0];
184
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
186
public void addDefinition(IASTNode node) {
187
addDeclaration(node);
191
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode)
193
public void addDeclaration(IASTNode node) {
194
if (!(node instanceof IASTName))
196
IASTName name = (IASTName) node;
197
if (declarations == null) {
198
declarations = new IASTName[] { name };
200
if (declarations.length > 0 && declarations[0] == node)
202
// keep the lowest offset declaration in [0]
203
if (declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset()) {
204
declarations = (IASTName[]) ArrayUtil.prepend(IASTName.class, declarations, name);
206
declarations = (IASTName[]) ArrayUtil.append(IASTName.class, declarations, name);
211
public ILinkage getLinkage() {
212
return Linkage.CPP_LINKAGE;
216
public String toString() {
220
public IBinding getOwner() {
221
if (declarations == null || declarations.length == 0)
224
IASTNode node= declarations[0];
225
while (!(node instanceof ICPPASTTemplateParameter)) {
229
node= node.getParent();
232
return CPPTemplates.getContainingTemplate((ICPPASTTemplateParameter) node);
235
public IBinding resolveFinalBinding(CPPASTNameBase name) {
236
// check if the binding has been updated.
237
IBinding current= name.getPreBinding();
241
ICPPTemplateDefinition template= CPPTemplates.getContainingTemplate(getASTTemplateParameter());
242
if (template instanceof ICPPInternalTemplate) {
243
return ((ICPPInternalTemplate) template).resolveTemplateParameter(this);
246
// problem finding the containing template
247
if (template == null) {
251
ICPPTemplateParameter[] params = template.getTemplateParameters();
252
final int pos= getParameterPosition();
253
if (pos < params.length)
255
return new ProblemBinding(getPrimaryDeclaration(), IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND);