Skip to main content
summaryrefslogtreecommitdiffstats
blob: 591c9f1f903ee98cb4ef58c8380bc10d5117bc00 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*******************************************************************************
 * Copyright (c) 2003, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v0.5 
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *     IBM Corp. - Rational Software - initial implementation
 ******************************************************************************/
/*
 * Created on Nov 6, 2003
 */
package org.eclipse.cdt.internal.core.parser.pst;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author aniefe
 */

public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSymbol {
	protected SpecializedSymbol( ParserSymbolTable table, String name ){
		super( table, name );
	}
	
	protected SpecializedSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
		super( table, name, obj );
	}
	
	public Object clone(){
		SpecializedSymbol copy = (SpecializedSymbol)super.clone();
		
		copy._argumentList	  = ( _argumentList != Collections.EMPTY_LIST ) ? (List)((ArrayList) _argumentList).clone() : _argumentList;
		
		return copy;	
	}
	
	
	public ITemplateSymbol getPrimaryTemplate(){
		return _primaryTemplate;
	}
	
	public void setPrimaryTemplate( ITemplateSymbol templateSymbol ){
		_primaryTemplate = templateSymbol;
	}
	
	public ISymbol instantiate( List arguments ) throws ParserSymbolTableException{
		Map argMap = new HashMap();
		
		List specArgs = getArgumentList();
		if( specArgs.size() != arguments.size() ){
			return null;
		}
		
		List actualArgs = new ArrayList( specArgs.size() );
		
		Iterator iter1 = specArgs.iterator();
		Iterator iter2 = arguments.iterator();
		
		ISymbol templatedSymbol = getTemplatedSymbol();
		while( templatedSymbol.isTemplateInstance() ){
			templatedSymbol = templatedSymbol.getInstantiatedSymbol();
		}
		
		while( iter1.hasNext() ){
			TypeInfo info = (TypeInfo) iter1.next();
			TypeInfo mappedInfo = (TypeInfo) iter2.next();
			
			//If the argument is a template parameter, we can't instantiate yet, defer for later
			if( mappedInfo.isType( TypeInfo.t_type ) && mappedInfo.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
				return deferredInstance( arguments );
			}
			
			actualArgs.add( mappedInfo );
			if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol().isType( TypeInfo.t_templateParameter )){
				ISymbol param = info.getTypeSymbol();
				
				param = TemplateEngine.translateParameterForDefinition ( templatedSymbol, param, getDefinitionParameterMap() );
				
				if( !argMap.containsKey( param ) ){
					argMap.put( param, mappedInfo );
				}
			}
		}
		
		//sanity check
		if( getParameterList().size() != argMap.size() )
			return null;
		
		Iterator params = getParameterList().iterator();
		while( params.hasNext() ){
			if( !argMap.containsKey( params.next() ) )
				return null;
		}
		
		IContainerSymbol instance = findInstantiation( actualArgs );
		if( instance != null ){
			return instance;
		} 
		IContainerSymbol symbol = null;
			
		if( getContainedSymbols().size() == 1 ){
			Iterator iter = getContainedSymbols().keySet().iterator();
			symbol = (IContainerSymbol)getContainedSymbols().get( iter.next() );
		}
			
		instance = (IContainerSymbol) symbol.instantiate( this, argMap );
		addInstantiation( instance, actualArgs );
		processDeferredInstantiations();
			
		return instance;
		
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList()
	 */
	public List getArgumentList(){
		return _argumentList;
	}
	
	public void prepareArguments( int size ){
		if( _argumentList == Collections.EMPTY_LIST )
			_argumentList = new ArrayList( size );
		else
			((ArrayList)_argumentList).ensureCapacity( size );
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
	 */
	public void addArgument(TypeInfo arg) {
		if( _argumentList == Collections.EMPTY_LIST )
			_argumentList = new ArrayList(4);
		
		_argumentList.add( arg );
		
		//arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
		
//		Command command = new AddArgumentCommand( this, arg );
//		getSymbolTable().pushCommand( command );
	}
	
//	static private class AddArgumentCommand extends Command{
//		public AddArgumentCommand( ISpecializedSymbol container, TypeInfo arg ){
//			_decl = container;
//			_arg = arg;
//		}
//		public void undoIt(){
//			_decl.getArgumentList().remove( _arg );
//		}
//
//		private ISpecializedSymbol _decl;
//		private TypeInfo _arg;
//	}
	
	private List      _argumentList = Collections.EMPTY_LIST;	  //template specialization arguments
	private ITemplateSymbol _primaryTemplate; //our primary template
}

Back to the top