1 /****************************************************************************
3 ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
5 ** This file is part of Qt Jambi.
7 ** ** This file may be used under the terms of the GNU General Public
8 ** License version 2.0 as published by the Free Software Foundation
9 ** and appearing in the file LICENSE.GPL included in the packaging of
10 ** this file. Please review the following information to ensure GNU
11 ** General Public Licensing requirements will be met:
12 ** http://www.trolltech.com/products/qt/opensource.html
14 ** If you are unsure which license is appropriate for your use, please
15 ** review the following information:
16 ** http://www.trolltech.com/products/qt/licensing.html or contact the
17 ** sales department at sales@trolltech.com.
20 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
21 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 ****************************************************************************/
25 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
27 /* This file is part of KDevelop
28 Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
29 Copyright (C) 2005 Trolltech AS
31 This library is free software; you can redistribute it and/or
32 modify it under the terms of the GNU Library General Public
33 License version 2 as published by the Free Software Foundation.
35 This library is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
38 Library General Public License for more details.
40 You should have received a copy of the GNU Library General Public License
41 along with this library; see the file COPYING.LIB. If not, write to
42 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
43 Boston, MA 02110-1301, USA.
50 #include "codemodel_finder.h"
51 #include "class_compiler.h"
52 #include "compiler_utils.h"
60 Binder::Binder(CodeModel
*__model
, LocationManager
&__location
, Control
*__control
)
62 _M_location(__location
),
63 _M_token_stream(&_M_location
.token_stream
),
64 _M_control(__control
),
65 _M_current_function_type(CodeModel::Normal
),
70 _M_qualified_types
["char"] = QString();
71 _M_qualified_types
["double"] = QString();
72 _M_qualified_types
["float"] = QString();
73 _M_qualified_types
["int"] = QString();
74 _M_qualified_types
["long"] = QString();
75 _M_qualified_types
["short"] = QString();
76 _M_qualified_types
["void"] = QString();
83 FileModelItem
Binder::run(AST
*node
)
85 FileModelItem old
= _M_current_file
;
86 _M_current_access
= CodeModel::Public
;
88 _M_current_file
= model()->create
<FileModelItem
>();
89 updateItemPosition (_M_current_file
->toItem(), node
);
91 FileModelItem result
= _M_current_file
;
93 _M_current_file
= old
; // restore
98 ScopeModelItem
Binder::currentScope()
100 if (_M_current_class
)
101 return model_static_cast
<ScopeModelItem
>(_M_current_class
);
102 else if (_M_current_namespace
)
103 return model_static_cast
<ScopeModelItem
>(_M_current_namespace
);
105 return model_static_cast
<ScopeModelItem
>(_M_current_file
);
108 TemplateParameterList
Binder::changeTemplateParameters(TemplateParameterList templateParameters
)
110 TemplateParameterList old
= _M_current_template_parameters
;
111 _M_current_template_parameters
= templateParameters
;
115 CodeModel::FunctionType
Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType
)
117 CodeModel::FunctionType old
= _M_current_function_type
;
118 _M_current_function_type
= functionType
;
122 CodeModel::AccessPolicy
Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy
)
124 CodeModel::AccessPolicy old
= _M_current_access
;
125 _M_current_access
= accessPolicy
;
129 NamespaceModelItem
Binder::changeCurrentNamespace(NamespaceModelItem item
)
131 NamespaceModelItem old
= _M_current_namespace
;
132 _M_current_namespace
= item
;
136 ClassModelItem
Binder::changeCurrentClass(ClassModelItem item
)
138 ClassModelItem old
= _M_current_class
;
139 _M_current_class
= item
;
143 FunctionDefinitionModelItem
Binder::changeCurrentFunction(FunctionDefinitionModelItem item
)
145 FunctionDefinitionModelItem old
= _M_current_function
;
146 _M_current_function
= item
;
150 int Binder::decode_token(std::size_t index
) const
152 return _M_token_stream
->kind(index
);
155 CodeModel::AccessPolicy
Binder::decode_access_policy(std::size_t index
) const
157 switch (decode_token(index
))
160 return CodeModel::Private
;
164 return CodeModel::Public
;
167 return CodeModel::Public
;
171 CodeModel::ClassType
Binder::decode_class_type(std::size_t index
) const
173 switch (decode_token(index
))
176 return CodeModel::Class
;
178 return CodeModel::Struct
;
180 return CodeModel::Union
;
182 std::cerr
<< "** WARNING unrecognized class type" << std::endl
;
184 return CodeModel::Class
;
187 const NameSymbol
*Binder::decode_symbol(std::size_t index
) const
189 return _M_token_stream
->symbol(index
);
192 void Binder::visitAccessSpecifier(AccessSpecifierAST
*node
)
194 const ListNode
<std::size_t> *it
= node
->specs
;
199 const ListNode
<std::size_t> *end
= it
;
203 switch (decode_token(it
->element
))
209 changeCurrentAccess(CodeModel::Public
);
210 changeCurrentFunctionType(CodeModel::Normal
);
212 case Token_protected
:
213 changeCurrentAccess(CodeModel::Protected
);
214 changeCurrentFunctionType(CodeModel::Normal
);
217 changeCurrentAccess(CodeModel::Private
);
218 changeCurrentFunctionType(CodeModel::Normal
);
221 changeCurrentAccess(CodeModel::Protected
);
222 changeCurrentFunctionType(CodeModel::Signal
);
225 changeCurrentFunctionType(CodeModel::Slot
);
233 void Binder::visitSimpleDeclaration(SimpleDeclarationAST
*node
)
235 visit(node
->type_specifier
);
237 if (const ListNode
<InitDeclaratorAST
*> *it
= node
->init_declarators
)
240 const ListNode
<InitDeclaratorAST
*> *end
= it
;
243 InitDeclaratorAST
*init_declarator
= it
->element
;
244 declare_symbol(node
, init_declarator
);
251 void Binder::declare_symbol(SimpleDeclarationAST
*node
, InitDeclaratorAST
*init_declarator
)
253 DeclaratorAST
*declarator
= init_declarator
->declarator
;
255 while (declarator
&& declarator
->sub_declarator
)
256 declarator
= declarator
->sub_declarator
;
258 NameAST
*id
= declarator
->id
;
259 if (! declarator
->id
)
261 std::cerr
<< "** WARNING expected a declarator id" << std::endl
;
265 CodeModelFinder
finder(model(), this);
266 ScopeModelItem symbolScope
= finder
.resolveScope(id
, currentScope());
270 std::cerr
<< "** WARNING scope not found for symbol:"
271 << qPrintable(name_cc
.name()) << std::endl
;
275 decl_cc
.run(declarator
);
277 if (decl_cc
.isFunction())
279 name_cc
.run(id
->unqualified_name
);
281 FunctionModelItem fun
= model()->create
<FunctionModelItem
>();
282 updateItemPosition (fun
->toItem(), node
);
283 fun
->setAccessPolicy(_M_current_access
);
284 fun
->setFunctionType(_M_current_function_type
);
285 fun
->setName(name_cc
.name());
286 fun
->setAbstract(init_declarator
->initializer
!= 0);
287 fun
->setConstant(declarator
->fun_cv
!= 0);
288 fun
->setTemplateParameters(_M_current_template_parameters
);
289 applyStorageSpecifiers(node
->storage_specifiers
, model_static_cast
<MemberModelItem
>(fun
));
290 applyFunctionSpecifiers(node
->function_specifiers
, fun
);
293 TypeInfo typeInfo
= CompilerUtils::typeDescription(node
->type_specifier
,
297 fun
->setType(qualifyType(typeInfo
, symbolScope
->qualifiedName()));
300 fun
->setVariadics (decl_cc
.isVariadics ());
302 // ... and the signature
303 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
305 ArgumentModelItem arg
= model()->create
<ArgumentModelItem
>();
306 arg
->setType(qualifyType(p
.type
, _M_context
));
307 arg
->setName(p
.name
);
308 arg
->setDefaultValue(p
.defaultValue
);
310 arg
->setDefaultValueExpression(p
.defaultValueExpression
);
311 fun
->addArgument(arg
);
314 fun
->setScope(symbolScope
->qualifiedName());
315 symbolScope
->addFunction(fun
);
319 VariableModelItem var
= model()->create
<VariableModelItem
>();
320 updateItemPosition (var
->toItem(), node
);
321 var
->setTemplateParameters(_M_current_template_parameters
);
322 var
->setAccessPolicy(_M_current_access
);
323 name_cc
.run(id
->unqualified_name
);
324 var
->setName(name_cc
.name());
325 TypeInfo typeInfo
= CompilerUtils::typeDescription(node
->type_specifier
,
328 if (declarator
!= init_declarator
->declarator
329 && init_declarator
->declarator
->parameter_declaration_clause
!= 0)
331 typeInfo
.setFunctionPointer (true);
332 decl_cc
.run (init_declarator
->declarator
);
333 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
334 typeInfo
.addArgument(p
.type
);
337 var
->setType(qualifyType(typeInfo
, _M_context
));
338 applyStorageSpecifiers(node
->storage_specifiers
, model_static_cast
<MemberModelItem
>(var
));
340 var
->setScope(symbolScope
->qualifiedName());
341 symbolScope
->addVariable(var
);
345 void Binder::visitFunctionDefinition(FunctionDefinitionAST
*node
)
347 Q_ASSERT(node
->init_declarator
!= 0);
349 ScopeModelItem scope
= currentScope();
351 InitDeclaratorAST
*init_declarator
= node
->init_declarator
;
352 DeclaratorAST
*declarator
= init_declarator
->declarator
;
354 CodeModelFinder
finder(model(), this);
356 ScopeModelItem functionScope
= finder
.resolveScope(declarator
->id
, scope
);
359 name_cc
.run(declarator
->id
);
360 std::cerr
<< "** WARNING scope not found for function definition:"
361 << qPrintable(name_cc
.name()) << std::endl
362 << "\tdefinition *ignored*"
367 decl_cc
.run(declarator
);
369 Q_ASSERT(! decl_cc
.id().isEmpty());
371 FunctionDefinitionModelItem
372 old
= changeCurrentFunction(_M_model
->create
<FunctionDefinitionModelItem
>());
373 _M_current_function
->setScope(functionScope
->qualifiedName());
374 updateItemPosition (_M_current_function
->toItem(), node
);
376 Q_ASSERT(declarator
->id
->unqualified_name
!= 0);
377 name_cc
.run(declarator
->id
->unqualified_name
);
378 QString unqualified_name
= name_cc
.name();
380 _M_current_function
->setName(unqualified_name
);
381 TypeInfo tmp_type
= CompilerUtils::typeDescription(node
->type_specifier
,
384 _M_current_function
->setType(qualifyType(tmp_type
, _M_context
));
385 _M_current_function
->setAccessPolicy(_M_current_access
);
386 _M_current_function
->setFunctionType(_M_current_function_type
);
387 _M_current_function
->setConstant(declarator
->fun_cv
!= 0);
388 _M_current_function
->setTemplateParameters(_M_current_template_parameters
);
390 applyStorageSpecifiers(node
->storage_specifiers
,
391 model_static_cast
<MemberModelItem
>(_M_current_function
));
392 applyFunctionSpecifiers(node
->function_specifiers
,
393 model_static_cast
<FunctionModelItem
>(_M_current_function
));
395 _M_current_function
->setVariadics (decl_cc
.isVariadics ());
397 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
399 ArgumentModelItem arg
= model()->create
<ArgumentModelItem
>();
400 arg
->setType(qualifyType(p
.type
, functionScope
->qualifiedName()));
401 arg
->setName(p
.name
);
402 arg
->setDefaultValue(p
.defaultValue
);
404 arg
->setDefaultValueExpression(p
.defaultValueExpression
);
405 _M_current_function
->addArgument(arg
);
408 functionScope
->addFunctionDefinition(_M_current_function
);
410 FunctionModelItem prototype
= model_static_cast
<FunctionModelItem
>(_M_current_function
);
411 FunctionModelItem declared
= functionScope
->declaredFunction(prototype
);
413 // try to find a function declaration for this definition..
416 functionScope
->addFunction(prototype
);
420 applyFunctionSpecifiers(node
->function_specifiers
, declared
);
422 // fix the function type and the access policy
423 _M_current_function
->setAccessPolicy(declared
->accessPolicy());
424 _M_current_function
->setFunctionType(declared
->functionType());
427 changeCurrentFunction(old
);
430 void Binder::visitTemplateDeclaration(TemplateDeclarationAST
*node
)
432 const ListNode
<TemplateParameterAST
*> *it
= node
->template_parameters
;
436 TemplateParameterList savedTemplateParameters
= changeTemplateParameters(TemplateParameterList());
439 const ListNode
<TemplateParameterAST
*> *end
= it
;
441 TemplateParameterList templateParameters
;
444 TemplateParameterAST
*parameter
= it
->element
;
445 TypeParameterAST
*type_parameter
= parameter
->type_parameter
;
446 if (! type_parameter
)
448 // std::cerr << "** WARNING template declaration not supported ``";
449 // Token const &tk = _M_token_stream->token ((int) node->start_token);
450 // Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
452 // std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
453 // << std::endl << std::endl;
455 changeTemplateParameters(savedTemplateParameters
);
458 assert(type_parameter
!= 0);
460 TemplateParameterModelItem p
= model()->create
<TemplateParameterModelItem
>();
461 int tk
= decode_token(type_parameter
->type
);
462 if (tk
!= Token_typename
&& tk
!= Token_class
)
464 // std::cerr << "** WARNING template declaration not supported ``";
465 // Token const &tk = _M_token_stream->token ((int) node->start_token);
466 // Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
468 // std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
469 // << std::endl << std::endl;
471 changeTemplateParameters(savedTemplateParameters
);
474 assert(tk
== Token_typename
|| tk
== Token_class
);
476 name_cc
.run(type_parameter
->name
);
477 p
->setName(name_cc
.name());
479 _M_current_template_parameters
.append(p
);
484 visit(node
->declaration
);
486 changeTemplateParameters(savedTemplateParameters
);
489 void Binder::visitTypedef(TypedefAST
*node
)
491 const ListNode
<InitDeclaratorAST
*> *it
= node
->init_declarators
;
496 const ListNode
<InitDeclaratorAST
*> *end
= it
;
500 InitDeclaratorAST
*init_declarator
= it
->element
;
503 Q_ASSERT(init_declarator
->declarator
!= 0);
506 decl_cc
.run (init_declarator
->declarator
);
507 QString alias_name
= decl_cc
.id ();
509 if (alias_name
.isEmpty ())
511 std::cerr
<< "** WARNING anonymous typedef not supported! ``";
512 Token
const &tk
= _M_token_stream
->token ((int) node
->start_token
);
513 Token
const &end_tk
= _M_token_stream
->token ((int) node
->end_token
);
515 std::cerr
<< std::string (&tk
.text
[tk
.position
], end_tk
.position
- tk
.position
) << "''"
516 << std::endl
<< std::endl
;
521 TypeInfo typeInfo
= CompilerUtils::typeDescription (node
->type_specifier
,
522 init_declarator
->declarator
,
524 DeclaratorAST
*decl
= init_declarator
->declarator
;
525 while (decl
&& decl
->sub_declarator
)
526 decl
= decl
->sub_declarator
;
528 if (decl
!= init_declarator
->declarator
529 && init_declarator
->declarator
->parameter_declaration_clause
!= 0)
531 typeInfo
.setFunctionPointer (true);
532 decl_cc
.run (init_declarator
->declarator
);
533 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
534 typeInfo
.addArgument(p
.type
);
537 ScopeModelItem scope
= currentScope();
538 DeclaratorAST
*declarator
= init_declarator
->declarator
;
539 CodeModelFinder
finder(model(), this);
540 ScopeModelItem typedefScope
= finder
.resolveScope(declarator
->id
, scope
);
542 TypeAliasModelItem typeAlias
= model ()->create
<TypeAliasModelItem
> ();
543 updateItemPosition (typeAlias
->toItem (), node
);
544 typeAlias
->setName (alias_name
);
545 typeAlias
->setType (qualifyType (typeInfo
, currentScope ()->qualifiedName ()));
546 typeAlias
->setScope (typedefScope
->qualifiedName());
547 _M_qualified_types
[typeAlias
->qualifiedName().join(".")] = QString();
548 currentScope ()->addTypeAlias (typeAlias
);
553 void Binder::visitNamespace(NamespaceAST
*node
)
555 bool anonymous
= (node
->namespace_name
== 0);
557 ScopeModelItem scope
= currentScope();
559 NamespaceModelItem old
;
562 QString name
= decode_symbol(node
->namespace_name
)->as_string();
564 QStringList qualified_name
= scope
->qualifiedName();
565 qualified_name
+= name
;
566 NamespaceModelItem ns
=
567 model_safe_cast
<NamespaceModelItem
>(_M_model
->findItem(qualified_name
,
568 _M_current_file
->toItem()));
571 ns
= _M_model
->create
<NamespaceModelItem
>();
572 updateItemPosition (ns
->toItem(), node
);
574 ns
->setScope(scope
->qualifiedName());
576 old
= changeCurrentNamespace(ns
);
578 _M_context
.append(name
);
581 DefaultVisitor::visitNamespace(node
);
585 Q_ASSERT(scope
->kind() == _CodeModelItem::Kind_Namespace
586 || scope
->kind() == _CodeModelItem::Kind_File
);
588 _M_context
.removeLast();
590 if (NamespaceModelItem ns
= model_static_cast
<NamespaceModelItem
>(scope
))
592 ns
->addNamespace(_M_current_namespace
);
595 changeCurrentNamespace(old
);
599 void Binder::visitClassSpecifier(ClassSpecifierAST
*node
)
601 ClassCompiler
class_cc(this);
604 if (class_cc
.name().isEmpty())
606 // anonymous not supported
610 Q_ASSERT(node
->name
!= 0 && node
->name
->unqualified_name
!= 0);
612 ScopeModelItem scope
= currentScope();
614 ClassModelItem old
= changeCurrentClass(_M_model
->create
<ClassModelItem
>());
615 updateItemPosition (_M_current_class
->toItem(), node
);
616 _M_current_class
->setName(class_cc
.name());
617 _M_current_class
->setBaseClasses(class_cc
.baseClasses());
618 _M_current_class
->setClassType(decode_class_type(node
->class_key
));
619 _M_current_class
->setTemplateParameters(_M_current_template_parameters
);
621 if (! _M_current_template_parameters
.isEmpty())
623 QString name
= _M_current_class
->name();
625 for (int i
= 0; i
<_M_current_template_parameters
.size(); ++i
)
630 name
+= _M_current_template_parameters
.at(i
)->name();
634 _M_current_class
->setName(name
);
637 CodeModel::AccessPolicy oldAccessPolicy
= changeCurrentAccess(decode_access_policy(node
->class_key
));
638 CodeModel::FunctionType oldFunctionType
= changeCurrentFunctionType(CodeModel::Normal
);
640 _M_current_class
->setScope(scope
->qualifiedName());
641 _M_qualified_types
[_M_current_class
->qualifiedName().join(".")] = QString();
642 scope
->addClass(_M_current_class
);
644 name_cc
.run(node
->name
->unqualified_name
);
645 _M_context
.append(name_cc
.name());
646 visitNodes(this, node
->member_specs
);
647 _M_context
.removeLast();
649 changeCurrentClass(old
);
650 changeCurrentAccess(oldAccessPolicy
);
651 changeCurrentFunctionType(oldFunctionType
);
654 void Binder::visitLinkageSpecification(LinkageSpecificationAST
*node
)
656 DefaultVisitor::visitLinkageSpecification(node
);
659 void Binder::visitUsing(UsingAST
*node
)
661 DefaultVisitor::visitUsing(node
);
664 void Binder::visitEnumSpecifier(EnumSpecifierAST
*node
)
666 CodeModelFinder
finder(model(), this);
667 ScopeModelItem scope
= currentScope();
668 ScopeModelItem enumScope
= finder
.resolveScope(node
->name
, scope
);
670 name_cc
.run(node
->name
);
671 QString name
= name_cc
.name();
676 QString key
= _M_context
.join("::");
677 int current
= ++_M_anonymous_enums
[key
];
678 name
+= QLatin1String("enum_");
679 name
+= QString::number(current
);
682 _M_current_enum
= model()->create
<EnumModelItem
>();
683 _M_current_enum
->setAccessPolicy(_M_current_access
);
684 updateItemPosition (_M_current_enum
->toItem(), node
);
685 _M_current_enum
->setName(name
);
686 _M_current_enum
->setScope(enumScope
->qualifiedName());
688 _M_qualified_types
[_M_current_enum
->qualifiedName().join(".")] = QString();
690 enumScope
->addEnum(_M_current_enum
);
692 DefaultVisitor::visitEnumSpecifier(node
);
697 void Binder::visitEnumerator(EnumeratorAST
*node
)
699 Q_ASSERT(_M_current_enum
!= 0);
700 EnumeratorModelItem e
= model()->create
<EnumeratorModelItem
>();
701 updateItemPosition (e
->toItem(), node
);
702 e
->setName(decode_symbol(node
->id
)->as_string());
704 if (ExpressionAST
*expr
= node
->expression
)
706 const Token
&start_token
= _M_token_stream
->token((int) expr
->start_token
);
707 const Token
&end_token
= _M_token_stream
->token((int) expr
->end_token
);
709 e
->setValue(QString::fromUtf8(&start_token
.text
[start_token
.position
],
710 (int) (end_token
.position
- start_token
.position
)).trimmed());
713 _M_current_enum
->addEnumerator(e
);
716 void Binder::visitUsingDirective(UsingDirectiveAST
*node
)
718 DefaultVisitor::visitUsingDirective(node
);
721 void Binder::visitQProperty(QPropertyAST
*node
)
723 const Token
&start
= _M_token_stream
->token((int) node
->start_token
);
724 const Token
&end
= _M_token_stream
->token((int) node
->end_token
);
725 QString property
= QString::fromLatin1(start
.text
+ start
.position
,
726 end
.position
- start
.position
);
727 _M_current_class
->addPropertyDeclaration(property
);
730 void Binder::applyStorageSpecifiers(const ListNode
<std::size_t> *it
, MemberModelItem item
)
736 const ListNode
<std::size_t> *end
= it
;
740 switch (decode_token(it
->element
))
746 item
->setFriend(true);
752 item
->setRegister(true);
755 item
->setStatic(true);
758 item
->setExtern(true);
761 item
->setMutable(true);
769 void Binder::applyFunctionSpecifiers(const ListNode
<std::size_t> *it
, FunctionModelItem item
)
775 const ListNode
<std::size_t> *end
= it
;
779 switch (decode_token(it
->element
))
785 item
->setInline(true);
789 item
->setVirtual(true);
793 item
->setExplicit(true);
801 TypeInfo
Binder::qualifyType(const TypeInfo
&type
, const QStringList
&context
) const
803 // ### Potentially improve to use string list in the name table to
804 if (context
.size() == 0)
806 // ### We can assume that this means global namespace for now...
809 else if (_M_qualified_types
.contains(type
.qualifiedName().join(".")))
815 QStringList expanded
= context
;
816 expanded
<< type
.qualifiedName();
817 if (_M_qualified_types
.contains(expanded
.join(".")))
819 TypeInfo modified_type
= type
;
820 modified_type
.setQualifiedName(expanded
);
821 return modified_type
;
825 CodeModelItem scope
= model ()->findItem (context
, _M_current_file
->toItem ());
827 if (ClassModelItem klass
= model_dynamic_cast
<ClassModelItem
> (scope
))
829 foreach (QString base
, klass
->baseClasses ())
831 QStringList ctx
= context
;
835 TypeInfo qualified
= qualifyType (type
, ctx
);
836 if (qualified
!= type
)
841 QStringList copy
= context
;
843 return qualifyType(type
, copy
);
848 void Binder::updateItemPosition(CodeModelItem item
, AST
*node
)
854 _M_location
.positionAt (_M_token_stream
->position(node
->start_token
), &line
, &column
, &filename
);
855 item
->setFileName (filename
);
858 // kate: space-indent on; indent-width 2; replace-tabs on;