1
/*******************************************************************************
2
* Copyright (c) 2005, 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
* 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.DOMException;
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.IScope;
19
import org.eclipse.cdt.core.dom.ast.IType;
20
import org.eclipse.cdt.core.dom.ast.IValue;
21
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
22
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
23
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
24
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
25
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
26
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
27
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
28
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
29
import org.eclipse.cdt.core.parser.util.ArrayUtil;
30
import org.eclipse.cdt.core.parser.util.ObjectMap;
31
import org.eclipse.cdt.internal.core.dom.Linkage;
32
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
33
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
34
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
35
import org.eclipse.core.runtime.PlatformObject;
38
* Base class for all specializations in the AST. Note the specialization may also be created on behalf
39
* of the index. The index may be concurrently be accessed (read-only) from different threads. So there
40
* is a need to synchronize non-final members.
42
public abstract class CPPSpecialization extends PlatformObject implements ICPPSpecialization, ICPPInternalBinding {
43
private IBinding owner;
44
private IBinding specialized;
45
private ICPPTemplateParameterMap argumentMap;
46
protected IASTNode definition;
47
private IASTNode[] declarations;
49
public CPPSpecialization(IBinding specialized, IBinding owner, ICPPTemplateParameterMap argumentMap) {
50
this.specialized = specialized;
52
this.argumentMap = argumentMap;
55
public IType specializeType(IType type) {
56
if (owner instanceof ICPPClassSpecialization) {
57
ICPPClassSpecialization within = getWithin((ICPPClassSpecialization) owner);
58
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, within);
60
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, null);
64
private ICPPClassSpecialization getWithin(ICPPClassSpecialization within) {
65
ICPPClassType orig = within.getSpecializedBinding();
67
IBinding o1 = within.getOwner();
68
IBinding o2 = orig.getOwner();
69
if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType))
71
ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1;
72
orig= (ICPPClassType) o2;
73
if (orig.isSameType(nextWithin))
79
public IType[] specializeTypePack(ICPPParameterPackType type) {
80
if (owner instanceof ICPPClassSpecialization) {
81
return CPPTemplates.instantiateTypes(new IType[]{type}, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner);
83
return CPPTemplates.instantiateTypes(new IType[]{type}, getTemplateParameterMap(), -1, null);
87
public IValue specializeValue(IValue value, int maxdepth) {
88
if (owner instanceof ICPPClassSpecialization) {
89
return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner, maxdepth);
91
return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), -1, null, maxdepth);
95
public IBinding getSpecializedBinding() {
99
public IASTNode[] getDeclarations() {
103
public IASTNode getDefinition() {
107
public void addDefinition(IASTNode node) {
111
public void addDeclaration(IASTNode node) {
112
if (declarations == null) {
113
declarations = new IASTNode[] { node };
115
// keep the lowest offset declaration in [0]
116
if (declarations.length > 0 &&
117
((ASTNode) node).getOffset() < ((ASTNode) declarations[0]).getOffset()) {
118
declarations = (IASTNode[]) ArrayUtil.prepend(IASTNode.class, declarations, node);
120
declarations = (IASTNode[]) ArrayUtil.append(IASTNode.class, declarations, node);
125
public String getName() {
126
return specialized.getName();
129
public char[] getNameCharArray() {
130
return specialized.getNameCharArray();
133
public IBinding getOwner() {
137
public IScope getScope() throws DOMException {
138
if (owner instanceof ICPPClassType) {
139
return ((ICPPClassType) owner).getCompositeScope();
140
} else if (owner instanceof ICPPNamespace) {
141
return ((ICPPNamespace) owner).getNamespaceScope();
142
} else if (owner instanceof ICPPFunction) {
143
return ((ICPPFunction) owner).getFunctionScope();
145
if (definition != null)
146
return CPPVisitor.getContainingScope(definition);
147
if (declarations != null && declarations.length > 0)
148
return CPPVisitor.getContainingScope(declarations[0]);
150
return specialized.getScope();
153
public String[] getQualifiedName() {
154
return CPPVisitor.getQualifiedName(this);
157
public char[][] getQualifiedNameCharArray() {
158
return CPPVisitor.getQualifiedNameCharArray(this);
161
public boolean isGloballyQualified() throws DOMException {
162
if (specialized instanceof ICPPBinding)
163
return ((ICPPBinding) specialized).isGloballyQualified();
167
public ILinkage getLinkage() {
168
return Linkage.CPP_LINKAGE;
172
public ObjectMap getArgumentMap() {
173
return CPPTemplates.getArgumentMap(this, getTemplateParameterMap());
176
public ICPPTemplateParameterMap getTemplateParameterMap() {
181
public String toString() {
182
StringBuilder result = new StringBuilder(getName());
183
if (argumentMap != null) {
184
result.append(" "); //$NON-NLS-1$
185
result.append(argumentMap.toString());
187
return result.toString();