1
/*******************************************************************************
2
* Copyright (c) 2004, 2008 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
* Andrew Ferguson (Symbian)
12
*******************************************************************************/
13
package org.eclipse.cdt.internal.core.dom.parser.cpp;
15
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
16
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
17
import org.eclipse.cdt.core.dom.ast.IASTExpression;
18
import org.eclipse.cdt.core.dom.ast.IASTName;
19
import org.eclipse.cdt.core.dom.ast.IASTNode;
20
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
21
import org.eclipse.cdt.core.dom.ast.IBinding;
22
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
23
import org.eclipse.cdt.core.dom.ast.IType;
24
import org.eclipse.cdt.core.dom.ast.IValue;
25
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument;
26
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
27
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
28
import org.eclipse.cdt.core.parser.util.ArrayUtil;
29
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
30
import org.eclipse.cdt.internal.core.dom.parser.Value;
31
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
32
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
35
* Template ids consist of an unqualified name (or operator or conversion name)
36
* and an array of template arguments.
38
public class CPPASTTemplateId extends CPPASTNameBase implements ICPPASTTemplateId, IASTAmbiguityParent {
39
private IASTName templateName;
40
private IASTNode[] templateArguments = null;
42
public CPPASTTemplateId() {
45
public CPPASTTemplateId(IASTName templateName) {
46
setTemplateName(templateName);
49
public CPPASTTemplateId copy() {
50
CPPASTTemplateId copy = new CPPASTTemplateId(templateName == null ? null : templateName.copy());
51
for(IASTNode arg : getTemplateArguments())
52
copy.internalAddTemplateArgument(arg == null ? null : arg.copy());
53
copy.setOffsetAndLength(this);
57
public char[] getSimpleID() {
58
return templateName.getSimpleID();
61
public char[] getLookupKey() {
62
return templateName.getLookupKey();
65
public IASTName getTemplateName() {
69
public void setTemplateName(IASTName name) {
71
assert !(name instanceof ICPPASTQualifiedName) && !(name instanceof ICPPASTTemplateId);
75
name.setPropertyInParent(TEMPLATE_NAME);
79
private void internalAddTemplateArgument(IASTNode node) {
81
templateArguments = (IASTNode[]) ArrayUtil.append(IASTNode.class, templateArguments, node);
84
node.setPropertyInParent(TEMPLATE_ID_ARGUMENT);
88
public void addTemplateArgument(IASTTypeId typeId) {
89
internalAddTemplateArgument(typeId);
92
public void addTemplateArgument(IASTExpression expression) {
93
internalAddTemplateArgument(expression);
96
public void addTemplateArgument(ICPPASTAmbiguousTemplateArgument ata) {
97
internalAddTemplateArgument(ata);
100
public IASTNode[] getTemplateArguments() {
101
if (templateArguments == null) return ICPPASTTemplateId.EMPTY_ARG_ARRAY;
102
return (IASTNode[]) ArrayUtil.trim(IASTNode.class, templateArguments);
106
protected IBinding createIntermediateBinding() {
107
return CPPTemplates.createBinding(this);
110
public char[] toCharArray() {
111
assert sAllowNameComputation;
113
StringBuilder buf= new StringBuilder();
114
buf.append(getTemplateName().toCharArray());
116
boolean needComma= false;
117
boolean cleanupWhitespace= false;
118
final IASTNode[] args= getTemplateArguments();
119
for (IASTNode arg : args) {
121
buf.append(", "); //$NON-NLS-1$
123
if (arg instanceof IASTExpression) {
124
IValue value= Value.create((IASTExpression) arg, Value.MAX_RECURSION_DEPTH);
125
if (value != Value.UNKNOWN && !Value.isDependentValue(value)) {
126
buf.append(value.getSignature());
128
buf.append(arg.getRawSignature());
129
cleanupWhitespace= true;
132
IType type= CPPVisitor.createType(arg);
133
if (type == null || type instanceof IProblemBinding) {
134
buf.append(arg.getRawSignature());
136
buf.append(ASTTypeUtil.getType(type, false));
139
if (cleanupWhitespace)
140
WHITESPACE_SEQ.matcher(buf).replaceAll(" "); //$NON-NLS-1$
143
final int len= buf.length();
144
final char[] result= new char[len];
145
buf.getChars(0, len, result, 0);
150
public boolean accept(ASTVisitor action) {
151
if (action.shouldVisitNames) {
152
switch(action.visit(this)) {
153
case ASTVisitor.PROCESS_ABORT: return false;
154
case ASTVisitor.PROCESS_SKIP: return true;
158
if (templateName != null && !templateName.accept(action)) return false;
160
IASTNode[] nodes = getTemplateArguments();
161
for (int i = 0; i < nodes.length; i++) {
162
if (!nodes[i].accept(action)) return false;
164
if (action.shouldVisitNames) {
165
switch(action.leave(this)) {
166
case ASTVisitor.PROCESS_ABORT: return false;
167
case ASTVisitor.PROCESS_SKIP: return true;
175
public boolean isDeclaration() {
176
return false; //for now this seems to be true
180
public boolean isReference() {
181
return true; //for now this seems to be true
184
public int getRoleForName(IASTName n) {
185
if (n == templateName)
190
public void replace(IASTNode child, IASTNode other) {
191
if (templateArguments == null) return;
192
for (int i = 0; i < templateArguments.length; ++i) {
193
if (child == templateArguments[i]) {
194
other.setPropertyInParent(child.getPropertyInParent());
195
other.setParent(child.getParent());
196
templateArguments[i] = other;