OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / libs / cplusplus / DeprecatedGenTemplateInstance.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "DeprecatedGenTemplateInstance.h"
35 #include "Overview.h"
36
37 #include <Control.h>
38 #include <Scope.h>
39 #include <Names.h>
40 #include <Symbols.h>
41 #include <CoreTypes.h>
42 #include <Literals.h>
43
44 #include <QtCore/QVarLengthArray>
45 #include <QtCore/QDebug>
46
47 using namespace CPlusPlus;
48
49 namespace {
50
51 class ApplySubstitution
52 {
53 public:
54     ApplySubstitution(Control *control, Symbol *symbol, const DeprecatedGenTemplateInstance::Substitution &substitution);
55     ~ApplySubstitution();
56
57     inline Control *control() const { return _control; }
58
59     FullySpecifiedType apply(const Name *name);
60     FullySpecifiedType apply(const FullySpecifiedType &type);
61
62     int findSubstitution(const Identifier *id) const;
63     FullySpecifiedType applySubstitution(int index) const;
64
65 private:
66     class ApplyToType: protected TypeVisitor
67     {
68     public:
69         ApplyToType(ApplySubstitution *q)
70             : q(q) {}
71
72         FullySpecifiedType operator()(const FullySpecifiedType &ty)
73         {
74             FullySpecifiedType previousType = switchType(ty);
75             accept(ty.type());
76             return switchType(previousType);
77         }
78
79     protected:
80         using TypeVisitor::visit;
81
82         Control *control() const
83         { return q->control(); }
84
85         FullySpecifiedType switchType(const FullySpecifiedType &type)
86         {
87             FullySpecifiedType previousType = _type;
88             _type = type;
89             return previousType;
90         }
91
92         virtual void visit(VoidType *)
93         {
94             // nothing to do
95         }
96
97         virtual void visit(IntegerType *)
98         {
99             // nothing to do
100         }
101
102         virtual void visit(FloatType *)
103         {
104             // nothing to do
105         }
106
107         virtual void visit(PointerToMemberType *)
108         {
109             qDebug() << Q_FUNC_INFO; // ### TODO
110         }
111
112         virtual void visit(PointerType *ptrTy)
113         {
114             _type.setType(control()->pointerType(q->apply(ptrTy->elementType())));
115         }
116
117         virtual void visit(ReferenceType *refTy)
118         {
119             _type.setType(control()->referenceType(q->apply(refTy->elementType())));
120         }
121
122         virtual void visit(ArrayType *arrayTy)
123         {
124             _type.setType(control()->arrayType(q->apply(arrayTy->elementType()), arrayTy->size()));
125         }
126
127         virtual void visit(NamedType *ty)
128         {
129             FullySpecifiedType n = q->apply(ty->name());
130             _type.setType(n.type());
131         }
132
133         virtual void visit(Function *funTy)
134         {
135             Function *fun = control()->newFunction(/*sourceLocation=*/ 0, funTy->name());
136             fun->setScope(funTy->enclosingScope());
137             fun->setConst(funTy->isConst());
138             fun->setVolatile(funTy->isVolatile());
139             fun->setVirtual(funTy->isVirtual());
140             fun->setAmbiguous(funTy->isAmbiguous());
141             fun->setVariadic(funTy->isVariadic());
142
143             fun->setReturnType(q->apply(funTy->returnType()));
144
145             for (unsigned i = 0; i < funTy->argumentCount(); ++i) {
146                 Argument *originalArgument = funTy->argumentAt(i)->asArgument();
147                 Argument *arg = control()->newArgument(/*sourceLocation*/ 0,
148                                                        originalArgument->name());
149
150                 arg->setType(q->apply(originalArgument->type()));
151                 arg->setInitializer(originalArgument->initializer());
152                 fun->addMember(arg);
153             }
154
155             _type.setType(fun);
156         }
157
158         virtual void visit(Namespace *)
159         {
160             qDebug() << Q_FUNC_INFO;
161         }
162
163         virtual void visit(Class *)
164         {
165             qDebug() << Q_FUNC_INFO;
166         }
167
168         virtual void visit(Enum *)
169         {
170             qDebug() << Q_FUNC_INFO;
171         }
172
173         virtual void visit(ForwardClassDeclaration *)
174         {
175             qDebug() << Q_FUNC_INFO;
176         }
177
178         virtual void visit(ObjCClass *)
179         {
180             qDebug() << Q_FUNC_INFO;
181         }
182
183         virtual void visit(ObjCProtocol *)
184         {
185             qDebug() << Q_FUNC_INFO;
186         }
187
188         virtual void visit(ObjCMethod *)
189         {
190             qDebug() << Q_FUNC_INFO;
191         }
192
193         virtual void visit(ObjCForwardClassDeclaration *)
194         {
195             qDebug() << Q_FUNC_INFO;
196         }
197
198         virtual void visit(ObjCForwardProtocolDeclaration *)
199         {
200             qDebug() << Q_FUNC_INFO;
201         }
202
203     private:
204         ApplySubstitution *q;
205         FullySpecifiedType _type;
206         QHash<Symbol *, FullySpecifiedType> _processed;
207     };
208
209     class ApplyToName: protected NameVisitor
210     {
211     public:
212         ApplyToName(ApplySubstitution *q): q(q) {}
213
214         FullySpecifiedType operator()(const Name *name)
215         {
216             FullySpecifiedType previousType = switchType(FullySpecifiedType());
217             accept(name);
218             return switchType(previousType);
219         }
220
221     protected:
222         Control *control() const
223         { return q->control(); }
224
225         int findSubstitution(const Identifier *id) const
226         { return q->findSubstitution(id); }
227
228         FullySpecifiedType applySubstitution(int index) const
229         { return q->applySubstitution(index); }
230
231         FullySpecifiedType switchType(const FullySpecifiedType &type)
232         {
233             FullySpecifiedType previousType = _type;
234             _type = type;
235             return previousType;
236         }
237
238         virtual void visit(const Identifier *name)
239         {
240             int index = findSubstitution(name->identifier());
241
242             if (index != -1)
243                 _type = applySubstitution(index);
244
245             else
246                 _type = control()->namedType(name);
247         }
248
249         virtual void visit(const TemplateNameId *name)
250         {
251             QVarLengthArray<FullySpecifiedType, 8> arguments(name->templateArgumentCount());
252             for (unsigned i = 0; i < name->templateArgumentCount(); ++i) {
253                 FullySpecifiedType argTy = name->templateArgumentAt(i);
254                 arguments[i] = q->apply(argTy);
255             }
256
257             const TemplateNameId *templId = control()->templateNameId(name->identifier(),
258                                                                       arguments.data(),
259                                                                       arguments.size());
260             _type = control()->namedType(templId);
261         }
262
263         const Name *instantiate(const Name *name)
264         {
265             if (! name)
266                 return name;
267
268             else if (const Identifier *nameId = name->asNameId()) {
269                 const Identifier *id = control()->identifier(nameId->chars(), nameId->size());
270                 return id;
271
272             } else if (const TemplateNameId *templId = name->asTemplateNameId()) {
273                 QVarLengthArray<FullySpecifiedType, 8> arguments(templId->templateArgumentCount());
274                 for (unsigned templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount(); ++templateArgIndex) {
275                     FullySpecifiedType argTy = templId->templateArgumentAt(templateArgIndex);
276                     arguments[templateArgIndex] = q->apply(argTy);
277                 }
278                 const Identifier *id = control()->identifier(templId->identifier()->chars(),
279                                                                          templId->identifier()->size());
280                 return control()->templateNameId(id, arguments.data(), arguments.size());
281
282             } else if (const QualifiedNameId *qq = name->asQualifiedNameId()) {
283                 const Name *base = instantiate(qq->base());
284                 const Name *name = instantiate(qq->name());
285
286                 return control()->qualifiedNameId(base, name);
287
288             } else if (const OperatorNameId *op = name->asOperatorNameId()) {
289                 return control()->operatorNameId(op->kind());
290
291             } else if (const ConversionNameId *c = name->asConversionNameId()) {
292                 FullySpecifiedType ty = q->apply(c->type());
293                 return control()->conversionNameId(ty);
294
295             }
296
297             return 0;
298         }
299
300         virtual void visit(const QualifiedNameId *name)
301         {
302             if (const Name *n = instantiate(name))
303                 _type = control()->namedType(n);
304         }
305
306         virtual void visit(const DestructorNameId *name)
307         {
308             Overview oo;
309             qWarning() << "ignored name:" << oo(name);
310         }
311
312         virtual void visit(const OperatorNameId *name)
313         {
314             Overview oo;
315             qWarning() << "ignored name:" << oo(name);
316         }
317
318         virtual void visit(const ConversionNameId *name)
319         {
320             Overview oo;
321             qWarning() << "ignored name:" << oo(name);
322         }
323
324         virtual void visit(const SelectorNameId *name)
325         {
326             Overview oo;
327             qWarning() << "ignored name:" << oo(name);
328         }
329
330     private:
331         ApplySubstitution *q;
332         FullySpecifiedType _type;
333     };
334
335 public: // attributes
336     Control *_control;
337     Symbol *symbol;
338     DeprecatedGenTemplateInstance::Substitution substitution;
339     ApplyToType applyToType;
340     ApplyToName applyToName;
341 };
342
343 ApplySubstitution::ApplySubstitution(Control *control, Symbol *symbol,
344                                      const DeprecatedGenTemplateInstance::Substitution &substitution)
345     : _control(control), symbol(symbol),
346       substitution(substitution),
347       applyToType(this), applyToName(this)
348 { }
349
350 ApplySubstitution::~ApplySubstitution()
351 {
352 }
353
354 FullySpecifiedType ApplySubstitution::apply(const Name *name)
355 {
356     FullySpecifiedType ty = applyToName(name);
357     return ty;
358 }
359
360 FullySpecifiedType ApplySubstitution::apply(const FullySpecifiedType &type)
361 {
362     FullySpecifiedType ty = applyToType(type);
363     return ty;
364 }
365
366 int ApplySubstitution::findSubstitution(const Identifier *id) const
367 {
368     Q_ASSERT(id != 0);
369
370     for (int index = 0; index < substitution.size(); ++index) {
371         QPair<const Identifier *, FullySpecifiedType> s = substitution.at(index);
372
373         if (id->isEqualTo(s.first))
374             return index;
375     }
376
377     return -1;
378 }
379
380 FullySpecifiedType ApplySubstitution::applySubstitution(int index) const
381 {
382     Q_ASSERT(index != -1);
383     Q_ASSERT(index < substitution.size());
384
385     return substitution.at(index).second;
386 }
387
388 } // end of anonymous namespace
389
390 DeprecatedGenTemplateInstance::DeprecatedGenTemplateInstance(QSharedPointer<Control> control, const Substitution &substitution)
391     : _symbol(0),
392       _control(control),
393       _substitution(substitution)
394 { }
395
396 FullySpecifiedType DeprecatedGenTemplateInstance::gen(Symbol *symbol)
397 {
398     ApplySubstitution o(_control.data(), symbol, _substitution);
399     return o.apply(symbol->type());
400 }
401
402 FullySpecifiedType DeprecatedGenTemplateInstance::instantiate(const Name *className, Symbol *candidate,
403                                                               QSharedPointer<Control> control)
404 {
405     if (className) {
406         if (const TemplateNameId *templId = className->asTemplateNameId()) {
407             if (Template *templ = candidate->enclosingTemplate()) {
408                 DeprecatedGenTemplateInstance::Substitution subst;
409
410                 for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
411                     FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
412
413                     if (i < templ->templateParameterCount()) {
414                         const Name *templArgName = templ->templateParameterAt(i)->name();
415
416                         if (templArgName && templArgName->identifier()) {
417                             const Identifier *templArgId = templArgName->identifier();
418                             subst.append(qMakePair(templArgId, templArgTy));
419                         }
420                     }
421                 }
422
423                 DeprecatedGenTemplateInstance inst(control, subst);
424                 return inst.gen(candidate);
425             }
426         }
427     }
428     return candidate->type();
429 }