1
/****************************************************************************
3
** Copyright (C) 2004-2005 Trolltech AS. All rights reserved.
4
** Copyright (C) 2001-2004 Roberto Raggi
6
** This file is part of the porting application of the Qt Toolkit.
8
** This file may be distributed under the terms of the Q Public License
9
** as defined by Trolltech AS of Norway and appearing in the file
10
** LICENSE.QPL included in the packaging of this file.
12
** This file may be distributed and/or modified under the terms of the
13
** GNU General Public License version 2 as published by the Free Software
14
** Foundation and appearing in the file LICENSE.GPL included in the
15
** packaging of this file.
17
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
18
** information about Qt Commercial License Agreements.
19
** See http://www.trolltech.com/qpl/ for QPL licensing information.
20
** See http://www.trolltech.com/gpl/ for GPL licensing information.
22
** Contact info@trolltech.com if any conditions of this licensing are
25
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28
****************************************************************************/
34
#include "smallobject.h"
35
#include "tokenengine.h"
37
using namespace TokenStreamAdapter;
38
using namespace TokenEngine;
39
using namespace CodeModel;
42
Semantic::Semantic(CodeModel::NamespaceScope *globalScope,
43
TokenStreamAdapter::TokenStream *tokenStream,
44
TypedPool<CodeModel::Item> *storage)
47
m_tokenStream = tokenStream;
49
m_currentAccess = CodeModel::Member::Public;
52
m_inStorageSpec = false;
55
globalScope->setName("::");
56
currentScope.push(globalScope);
58
//create global UnknownType and UnknownTypeMember
59
UnknownType *type = Create<UnknownType>(m_storage);
60
type->setName("__UnknownType");
61
globalScope->addType(type);
62
type->setParent(globalScope);
64
m_sharedUnknownMember = Create<TypeMember>(m_storage);
65
m_sharedUnknownMember->setNameToken(TokenRef());
66
m_sharedUnknownMember->setName("Unknown");
67
m_sharedUnknownMember->setType(type);
68
globalScope->addMember(m_sharedUnknownMember);
69
m_sharedUnknownMember->setParent(globalScope);
73
void Semantic::parseAST(TranslationUnitAST *node)
75
TreeWalker::parseTranslationUnit(node);
79
void Semantic::parseLinkageSpecification(LinkageSpecificationAST *ast)
83
int inStorageSpec = m_inStorageSpec;
84
m_inStorageSpec = true;
85
TreeWalker::parseLinkageSpecification(ast);
86
m_inStorageSpec = inStorageSpec;
89
void Semantic::parseNamespace(NamespaceAST *ast)
91
CodeModel::NamespaceScope *parent = currentScope.top()->toNamespaceScope();
92
if(!parent->toNamespaceScope()) {
93
emit error("Error in Semantic::parseNamespace: parent scope was not a namespace");
98
if (!ast->namespaceName() || textOf(ast->namespaceName()).isEmpty()){
99
nsName = "(__QT_ANON_NAMESPACE)";
101
nsName = textOf(ast->namespaceName());
104
CodeModel::NamespaceScope *namespaceScope = 0;
106
// Look up namespace scope in case it is already defined.
107
// (Unlike classes, C++ namespaces are "open" and can be added to.)
108
CodeModel::Scope *scope = parent->scopes().value(nsName);
110
namespaceScope = scope->toNamespaceScope();
112
// Create new namespace if not found.
113
if (!namespaceScope) {
114
namespaceScope = CodeModel::Create<CodeModel::NamespaceScope>(m_storage);
115
namespaceScope->setName(nsName);
116
parent->addScope(namespaceScope);
118
NamespaceMember *namespaceMember = Create<NamespaceMember>(m_storage);
119
namespaceMember->setNameToken(tokenRefFromAST(ast->namespaceName()));
120
namespaceMember->setName(nsName);
121
namespaceMember->setNamespaceScope(namespaceScope);
122
currentScope.top()->addMember(namespaceMember);
123
namespaceMember->setParent(currentScope.top());
126
currentScope.push(namespaceScope);
127
TreeWalker::parseNamespace(ast);
131
void Semantic::parseClassSpecifier(ClassSpecifierAST *ast)
137
QByteArray kind = textOf(ast->classKey());
139
m_currentAccess = CodeModel::Member::Private;
140
else // kind =="struct"
141
m_currentAccess = CodeModel::Member::Public;
143
QByteArray className = textOf(ast->name()->unqualifiedName());
146
CodeModel::ClassScope *klass = CodeModel::Create<CodeModel::ClassScope>(m_storage);
147
klass->setName(className);
148
currentScope.top()->addScope(klass);
151
CodeModel::ClassType *type = CodeModel::Create<CodeModel::ClassType>(m_storage);
152
type->setScope(klass);
153
currentScope.top()->addType(type);
154
type->setParent(currentScope.top());
157
CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
158
typeMember->setNameToken(tokenRefFromAST(ast->name()->unqualifiedName()));
159
typeMember->setName(className);
160
typeMember->setType(type);
161
currentScope.top()->addMember(typeMember);
162
typeMember->setParent(currentScope.top());
164
currentScope.push(klass);
165
if (ast->baseClause())
166
parseBaseClause(ast->baseClause(), klass);
168
//TreeWalker::parseClassSpecifier(ast);
169
parseNode(ast->winDeclSpec());
170
parseNode(ast->classKey());
171
parseNode(ast->baseClause());
173
// Here's the trick for parsing c++ classes:
174
// All inline function definitions must be interpreted as if they were
175
// written after any other declarations in the class.
176
QList<DeclarationAST *> functionDefinitions;
177
if (ast->declarationList())
178
foreach(DeclarationAST *decl, *ast->declarationList()) {
179
if(decl->nodeType() == NodeType_FunctionDefinition)
180
functionDefinitions.append(decl);
184
foreach(DeclarationAST *decl, functionDefinitions)
190
Parse a class, struct or enum forward decalration.
192
void Semantic::parseElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node)
196
AST *kind = node->kind();
200
const QByteArray kindText = textOf(kind);
201
const QByteArray nameText = textOf(node->name());
203
if (kindText == "class" || kindText == "struct") {
205
CodeModel::ClassType *type = CodeModel::Create<CodeModel::ClassType>(m_storage);
207
currentScope.top()->addType(type);
208
type->setParent(currentScope.top());
210
// Create TypeMember.
211
CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
212
typeMember->setNameToken(tokenRefFromAST(node->name()->unqualifiedName()));
213
typeMember->setName(nameText);
214
typeMember->setType(type);
215
currentScope.top()->addMember(typeMember);
216
typeMember->setParent(currentScope.top());
217
} else if (kindText == "enum") {
219
CodeModel::EnumType *enumType = CodeModel::Create<CodeModel::EnumType>(m_storage);
220
enumType->setName(nameText);
221
currentScope.top()->addType(enumType);
222
enumType->setParent(currentScope.top());
224
//create a TypeMember
225
CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
227
typeMember->setNameToken(tokenRefFromAST(node->name()->unqualifiedName()));
228
typeMember->setName(nameText);
229
typeMember->setType(enumType);
230
currentScope.top()->addMember(typeMember);
231
typeMember->setParent(currentScope.top());
235
void Semantic::parseSimpleDeclaration(SimpleDeclarationAST *ast)
237
TypeSpecifierAST *typeSpec = ast->typeSpec();
238
InitDeclaratorListAST *declarators = ast->initDeclaratorList();
241
parseTypeSpecifier(typeSpec);
244
List<InitDeclaratorAST*> l = *declarators->initDeclaratorList();
246
foreach (InitDeclaratorAST *current, l) {
247
parseDeclaration(ast->functionSpecifier(), ast->storageSpecifier(), typeSpec, current);
252
void Semantic::parseDeclaration(AST *funSpec, AST *storageSpec, TypeSpecifierAST *typeSpec, InitDeclaratorAST *decl)
260
DeclaratorAST *d = decl->declarator();
264
if (!d->subDeclarator() && d->parameterDeclarationClause()) {
265
parseFunctionDeclaration(funSpec, storageSpec, typeSpec, decl);
268
if(!typeSpec || !typeSpec->name())
271
DeclaratorAST *t = d;
272
while (t && t->subDeclarator())
273
t = t->subDeclarator();
276
if (t && t->declaratorId() && t->declaratorId()->unqualifiedName())
277
id = textOf(t->declaratorId()->unqualifiedName());
279
if (!t || !t->declaratorId() || !t->declaratorId()->unqualifiedName())
281
AST *nameAST = t->declaratorId()->unqualifiedName();
282
QByteArray name = textOf(nameAST);
285
if (!scopeOfDeclarator(d, QList<QByteArray>()).isEmpty()){
289
//create VariableMember
290
CodeModel::VariableMember *variableMember = CodeModel::Create<CodeModel::VariableMember>(m_storage);
291
variableMember->setNameToken(tokenRefFromAST(nameAST));
292
variableMember->setName(name);
293
variableMember->setAccess(m_currentAccess);
294
variableMember->setParent(currentScope.top());
295
currentScope.top()->addMember(variableMember);
297
//look up type of variableMember,
299
TypeMember *typeMember = typeLookup(currentScope.top(), typeSpec->name());
301
variableMember->setType(typeMember->type());
303
QByteArray text = typeOfDeclaration(typeSpec, d);
304
CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
306
variableMember->setType(type);
310
parseNode(decl->initializer());
314
void Semantic::parseFunctionDeclaration(AST *funSpec, AST *storageSpec,
315
TypeSpecifierAST * typeSpec, InitDeclaratorAST * initDeclarator)
317
bool isFriend = false;
318
bool isVirtual = false;
319
bool isStatic = false;
320
bool isInline = false;
321
bool isPure = initDeclarator->initializer() != 0;
324
List<AST*> l = *funSpec->children();
325
foreach (AST *current, l) {
326
QByteArray text = textOf(current);
327
if (text == "virtual") isVirtual = true;
328
else if (text == "inline") isInline = true;
333
List<AST*> l = *storageSpec->children();
334
foreach (AST *current, l) {
335
QByteArray text = textOf(current);
336
if (text == "friend") isFriend = true;
337
else if (text == "static") isStatic = true;
340
DeclaratorAST *declarator = initDeclarator->declarator();
341
if(!declarator || !declarator->declaratorId())
343
AST *nameAST = declarator->declaratorId()->unqualifiedName();
344
QByteArray name = textOf(nameAST);
346
CodeModel::FunctionMember *method = CodeModel::Create<CodeModel::FunctionMember>(m_storage);
347
method->setNameToken(tokenRefFromAST(nameAST));
348
method->setName(name);
349
method->setAccess(m_currentAccess);
350
method->setStatic(isStatic);
351
method->setVirtual(isVirtual);
352
method->setAbstract(isPure);
354
parseFunctionArguments(declarator, method);
357
method->setSignal(true);
360
method->setSlot(true);
362
method->setConstant(declarator->constant() != 0);
364
QByteArray text = typeOfDeclaration(typeSpec, declarator);
365
if (!text.isEmpty()) {
366
CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
368
method->setReturnType(type);
371
method->setParent(currentScope.top());
372
currentScope.top()->addMember(method);
376
void Semantic::parseBaseClause(BaseClauseAST * baseClause, CodeModel::ClassScope *klass)
382
List<BaseSpecifierAST*> *l = baseClause->baseSpecifierList();
385
foreach (BaseSpecifierAST *baseSpecifier, *l) {
387
if (!baseSpecifier->name())
390
// Look up a class with the correct name.
391
QList<Member *> candidates = nameLookup(klass, baseSpecifier->name());
392
if (candidates.count() == 1 ) {
393
Member *member = candidates.at(0);
395
TypeMember *typeMember = member->toTypeMember();
397
Q_ASSERT(typeMember->type());
398
ClassType *classType = typeMember->type()->toClassType();
400
klass->addBaseClass(classType);
406
void Semantic::parseFunctionArguments(const DeclaratorAST *declarator, CodeModel::FunctionMember *method)
408
if(!declarator || !method)
411
ParameterDeclarationClauseAST *clause = declarator->parameterDeclarationClause();
413
if (clause && clause->parameterDeclarationList()){
414
ParameterDeclarationListAST *params = clause->parameterDeclarationList();
415
List<ParameterDeclarationAST*> *l = params->parameterList();
418
foreach (ParameterDeclarationAST *param, *l) {
419
CodeModel::Argument *arg = CodeModel::Create<CodeModel::Argument>(m_storage);
420
arg->setParent(method);
422
if (param->declarator()){
423
QByteArray text = declaratorToString(param->declarator(), QByteArray(), true);
424
if(param->declarator()->declaratorId())
425
arg->setNameToken(tokenRefFromAST(param->declarator()->declaratorId()->unqualifiedName()));
430
QByteArray tp = typeOfDeclaration(param->typeSpec(), param->declarator());
432
CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
437
method->addArgument(arg);
442
// using directive (using namespace A)
443
void Semantic::parseUsingDirective(UsingDirectiveAST *ast)
445
QByteArray qualifiedname = textOf(ast->name());
446
QByteArray name = textOf(ast->name()->unqualifiedName());
448
//look up target namespace name
449
QList<Member *> memberList = nameLookup(currentScope.top(), ast->name());
451
NamespaceScope *targetNamespace = 0;
453
// search for namespace in member list.
454
QList<Member *>::ConstIterator it = memberList.constBegin();
455
while(it != memberList.constEnd()) {
456
if (NamespaceMember *namespaceMember = (*it)->toNamespaceMember()) {
457
targetNamespace = namespaceMember->namespaceScope();
463
if (targetNamespace == 0)
466
// Find the insertion namespace, wich is the first common
467
// ancesotor namespace for the current sope and the insertion namespace
469
// currentScope might be a block scope, find the first namespace parent
470
CodeModel::Scope *currentParent = currentScope.top();
471
while (currentParent->toNamespaceScope() == 0) {
472
currentParent = currentParent->parent();
475
CodeModel::Scope *namespaceA = currentParent;
476
while (namespaceA != 0) {
477
CodeModel::Scope *namespaceB = targetNamespace;
478
while (namespaceB != 0) {
479
if (namespaceB == namespaceA)
481
namespaceB = namespaceB->parent();
483
if (namespaceB == namespaceA)
485
namespaceA = namespaceA->parent();
488
if (namespaceA == 0 || namespaceA->toNamespaceScope() == 0)
491
NamespaceScope *insertionNamespace = namespaceA->toNamespaceScope();
493
// Create using directive link
494
UsingDirectiveLink *usingDirectiveLink = Create<UsingDirectiveLink>(m_storage);
495
usingDirectiveLink->setParent(currentScope.top());
496
usingDirectiveLink->setTargetNamespace(targetNamespace);
497
usingDirectiveLink->setInsertionNamespace(insertionNamespace);
499
// add it to current namespace
500
if (NamespaceScope *namespaceScope = currentScope.top()->toNamespaceScope())
501
namespaceScope->addUsingDirectiveLink(usingDirectiveLink);
502
else if (BlockScope *blockScope = currentScope.top()->toBlockScope())
503
blockScope->addUsingDirectiveLink(usingDirectiveLink);
506
void Semantic::parseFunctionDefinition(FunctionDefinitionAST *ast)
508
AST *funSpec = ast->functionSpecifier();
509
AST *storageSpec = ast->storageSpecifier();
510
TypeSpecifierAST *typeSpec = ast->typeSpec();
511
InitDeclaratorAST *initDeclarator = ast->initDeclarator();
512
if (!ast->initDeclarator())
515
DeclaratorAST *d = initDeclarator->declarator();
517
if (!d->declaratorId())
521
// Check if function already has been declared, if not then this is also a declaration.
522
CodeModel::FunctionMember *method = functionLookup(currentScope.top(), d);
524
parseFunctionDeclaration(funSpec, storageSpec, typeSpec, initDeclarator);
525
method = functionLookup(currentScope.top(), d);
528
emit error("Error in Semantic::parseFunctionDefinition: Could not find declaration for function definition");
532
CodeModel::Scope *parent = method->parent();
534
if(!ast->functionBody()) {
535
emit error("Error in Semantic::parseFunctionDefinition: no function body in function definition");
539
//create child function scope
540
QByteArray id = textOf(d->declaratorId()->unqualifiedName());
541
CodeModel::BlockScope *functionScope = CodeModel::Create<CodeModel::BlockScope>(m_storage);
542
functionScope->setName(QByteArray("__QT_ANON_BLOCK_SCOPE(Function: ") + id + QByteArray(")"));
543
functionScope->setParent(parent);
544
method->setFunctionBodyScope(functionScope);
546
//add arguments to child scope
547
ArgumentCollection arguments = method->arguments();
548
ArgumentCollection::ConstIterator it = arguments.constBegin();
549
while(it != arguments.constEnd()) {
550
CodeModel::Argument *argument = *it;
551
CodeModel::VariableMember *variableMember = CodeModel::Create<CodeModel::VariableMember>(m_storage);
552
variableMember->setNameToken(argument->nameToken());
553
variableMember->setType(argument->type());
554
variableMember->setName(argument->name());
555
variableMember->setParent(functionScope);
556
functionScope->addMember(variableMember);
560
//push function scope and parse function body
561
currentScope.push(functionScope);
562
parseStatementList(ast->functionBody());
566
void Semantic::parseStatementList(StatementListAST *statemenList)
570
CodeModel::BlockScope *blockScope = CodeModel::Create<CodeModel::BlockScope>(m_storage);
571
blockScope->setName("__QT_ANON_BLOCK_SCOPE");
572
blockScope->setParent(currentScope.top());
573
currentScope.top()->addScope(blockScope);
575
currentScope.push(blockScope);
576
TreeWalker::parseStatementList(statemenList);
580
void Semantic::parseExpression(AbstractExpressionAST* node)
584
if(node->nodeType() == NodeType_ClassMemberAccess)
585
parseClassMemberAccess(static_cast<ClassMemberAccessAST *>(node));
587
TreeWalker::parseExpression(node);
591
Pretty hardwired code for handling class member access of the types:
592
object.member and objectPtr->member.
594
This function creates a name use for object to its declaration, and a
595
name use from member to its declaration in the class.
597
void Semantic::parseClassMemberAccess(ClassMemberAccessAST *node)
601
parseExpression(node->expression());
602
// Get a name use for the 'object' name.
603
NameUse *nameUse = findNameUse(node->expression());
604
// Since the NameUse refers to an object, its decalaration must be
605
// a ClassType. Get the scope of this class type.
607
&& nameUse->declaration()
608
&& nameUse->declaration()->toVariableMember()
609
&& nameUse->declaration()->toVariableMember()->type()
610
&& nameUse->declaration()->toVariableMember()->type()->toClassType()
611
&& nameUse->declaration()->toVariableMember()->type()->toClassType()->scope()) {
613
CodeModel::Scope *scope = nameUse->declaration()->toVariableMember()->type()->toClassType()->scope();
614
QList<CodeModel::Member *> members = lookupNameInScope(scope, node->name());
615
if(members.count() != 0) {
616
createNameUse(members.at(0), node->name());
620
// Create a NameUse that refers to the global shared unknown type.
621
createNameUse(m_sharedUnknownMember, node->name());
624
void Semantic::parseExpressionStatement(ExpressionStatementAST *node)
626
TreeWalker::parseExpressionStatement(node);
629
// using declaration (using A::b)
630
void Semantic::parseUsing(UsingAST *ast)
632
//CodeModel::Scope *s = lookUpScope(currentScope.top(), ast->name());
633
QList<CodeModel::Member *> members = nameLookup(currentScope.top(), ast->name());
634
if(members.isEmpty()) {
635
emit error("Error in Semantic::parseUsing: could not look up using target");
638
//TODO: handle multiple members (when nameLookup returns a set of overloded functions)
639
CodeModel::Member *member = members[0];
640
CodeModel::Scope *targetScope = member->parent();
642
emit error("Error in Semantic::parseUsing: target has no parent scope");
648
AST *nameAST = ast->name()->unqualifiedName();
651
QByteArray name = textOf(nameAST);
654
void Semantic::parseEnumSpecifier(EnumSpecifierAST *ast)
659
QByteArray name = textOf(ast->name());
662
CodeModel::EnumType *enumType = CodeModel::Create<CodeModel::EnumType>(m_storage);
663
enumType->setName(name);
664
currentScope.top()->addType(enumType);
665
enumType->setParent(currentScope.top());
667
//create a TypeMember
668
CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
670
typeMember->setNameToken(tokenRefFromAST(ast->name()->unqualifiedName()));
671
typeMember->setName(name);
672
typeMember->setType(enumType);
673
currentScope.top()->addMember(typeMember);
674
typeMember->setParent(currentScope.top());
676
//parse the eneumerators
677
List<EnumeratorAST*> *list = ast->enumeratorList();
680
foreach (EnumeratorAST *current, *list) {
681
CodeModel::VariableMember *enumerator = CodeModel::Create<CodeModel::VariableMember>(m_storage);
682
enumerator->setNameToken(tokenRefFromAST(current->id()));
683
enumerator->setName(textOf(current->id()));
684
enumerator->setAccess(m_currentAccess);
685
enumerator->setStatic(true);
686
enumerator->setType(enumType);
687
currentScope.top()->addMember(enumerator);
688
enumerator->setParent(currentScope.top());
693
void Semantic::parseTypedef(TypedefAST *ast)
695
TypeSpecifierAST *typeSpec = ast->typeSpec();
696
InitDeclaratorListAST *declarators = ast->initDeclaratorList();
698
if (typeSpec && declarators){
701
if (typeSpec->name())
702
typeId = textOf(typeSpec->name());
704
List<InitDeclaratorAST*> *l = declarators->initDeclaratorList();
707
foreach (InitDeclaratorAST *initDecl, *l) {
709
if (initDecl->declarator()){
710
type = typeOfDeclaration(typeSpec, initDecl->declarator());
712
DeclaratorAST *d = initDecl->declarator();
713
while (d->subDeclarator()){
714
d = d->subDeclarator();
717
if (d->declaratorId())
718
id = textOf(d->declaratorId());
722
CodeModel::Scope *scope = currentScope.top();
723
CodeModel::AliasType *typeAlias = CodeModel::Create<CodeModel::AliasType>(m_storage);
724
//typeAlias->setName(id);
725
//typeAlias->setParent(scope);
726
scope->addType(typeAlias);
728
//create a TypeMember
729
CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
731
typeMember->setNameToken(tokenRefFromAST(typeSpec->name()->unqualifiedName()));
732
typeMember->setName(id);
733
typeMember->setType(typeAlias);
734
currentScope.top()->addMember(typeMember);
735
typeMember->setParent(currentScope.top());
742
void Semantic::parseTypeSpecifier(TypeSpecifierAST *ast)
744
// If this is a classSpecifier or a EnumSpecifier we skip the name lookup,
745
// becuase looking up the name "E" in a class definition like
746
// "class E { ..." makes no sense. (There might be a variable named E
747
// already declared, but that variable is now shadowed by the class type.)
748
if( ast->nodeType() != NodeType_EnumSpecifier
749
&& ast->nodeType() != NodeType_ClassSpecifier
750
&& ast->nodeType() != NodeType_ElaboratedTypeSpecifier )
751
parseNameUse(ast->name());
752
TreeWalker::parseTypeSpecifier(ast);
756
Parses a name: looks up name, creates name use.
758
void Semantic::parseNameUse(NameAST* name)
764
QList<CodeModel::Member *> members = nameLookup(currentScope.top(), name);
765
if(members.isEmpty()) {
766
//cout << "no declaration found for " << textOf(name).constData() << endl;
767
// Create NameUse that refer to a shared UnknownMember
768
createNameUse(m_sharedUnknownMember, name);
772
//TODO: handle multiple members (when nameLookup returns a set of overloaded functions)
773
CodeModel::Member *member = members[0];
774
if(!member->parent()) {
775
emit error("Error in Semantic::parseUsing: target has no parent scope");
779
createNameUse(member, name);
783
looks up name used in basescope. If name->isGlobal() is true or if classOrNamespaceList()
784
returns a non-emty list, the C++ qualified name lookup rules are used. Otherwise the
785
unquialified name lookup rules are used. Returns the a list of members that was found,
786
In most cases this list will contain zero or one element, exept in the case of overloaded functions.
787
TODO: Argument-dependent name lookup
789
QList<CodeModel::Member *> Semantic::nameLookup(CodeModel::Scope *baseScope, const NameAST* name)
791
if (name->isGlobal() || (name->classOrNamespaceNameList()
792
&& name->classOrNamespaceNameList()->size()>0 )) {
793
return qualifiedNameLookup(baseScope, name);
795
return unqualifiedNameLookup(baseScope, name);
799
//look up an unqualified name
800
QList<CodeModel::Member *> Semantic::unqualifiedNameLookup(CodeModel::Scope *baseScope, const NameAST* name)
802
QList<UsingDirectiveLink *> usingDirectiveLinks;
803
CodeModel::Scope *currentScope = baseScope;
804
QList<CodeModel::Member *> entities;
806
while (currentScope != 0) {
807
// Add any "using namespace" directive links for the current scope to
808
// usingDirectiveLinks
809
if (NamespaceScope *namespaceScope = currentScope->toNamespaceScope())
810
usingDirectiveLinks += namespaceScope->usingDirectiveLinks();
811
if (BlockScope *blockScope = currentScope->toBlockScope())
812
usingDirectiveLinks += blockScope->usingDirectiveLinks();
814
// Search usingDirectiveLinks for a link where currentScope is the
815
// insertion namespace. If found look up name in the target namespace
817
if (NamespaceScope *namespaceScope = currentScope->toNamespaceScope()) {
818
QList<UsingDirectiveLink *>::ConstIterator it = usingDirectiveLinks.constBegin();
819
while (it != usingDirectiveLinks.constEnd()) {
820
if ((*it)->insertionNamespace() == namespaceScope)
821
entities = lookupNameInScope((*it)->targetNamespace(), name);
826
// Look up names in this scope.
827
entities += lookupNameInScope(currentScope, name);
828
if (!entities.isEmpty())
830
currentScope = currentScope->parent();
835
//look up a qualified name
836
QList<CodeModel::Member *> Semantic::qualifiedNameLookup(CodeModel::Scope *baseScope, const NameAST* name)
838
QList<CodeModel::Member *> entities;
839
CodeModel::Scope *currentScope = baseScope;
841
// Check if the global ("::") scope has been specified.
842
if(name->isGlobal()) {
843
while (currentScope->parent())
844
currentScope = currentScope->parent();
847
while (entities.isEmpty() && currentScope != 0) {
848
CodeModel::Scope *targetScope = scopeLookup(currentScope, name);
849
entities = lookupNameInScope(targetScope, name);
850
currentScope = currentScope->parent();
856
//looks up a name in a scope, includes base classes if scope is a class scope
857
QList<CodeModel::Member *> Semantic::lookupNameInScope(CodeModel::Scope *scope, const NameAST* name)
859
QList<CodeModel::Member *> entities;
864
QByteArray nameText = textOf(name->unqualifiedName()->name());
865
//look up name in members of current scope
866
const CodeModel::MemberCollection members = scope->members();
867
if (members.contains(nameText))
868
entities.append(members.value(nameText));
870
// if not found, look up name in base classes (if any)
871
CodeModel::ClassScope *classScope = scope->toClassScope();
872
if (entities.isEmpty() && classScope) {
873
const TypeCollection baseClasses = classScope->baseClasses();
874
TypeCollection::ConstIterator it = baseClasses.constBegin();
875
while (it != baseClasses.constEnd()) {
876
CodeModel::Scope *baseClass = it.value()->toClassType()->scope();
877
if (scope != baseClass)
878
entities += lookupNameInScope(baseClass, name);
882
if (entities.count() > 1)
883
emit error("Error in Semantic::lookupNameInScope: name "
884
+ nameText + " is ambigous");
890
Resolves the classOrNamespaceNameList part of a NameAST against a base scope.
892
CodeModel::Scope *Semantic::scopeLookup(CodeModel::Scope *baseScope, const NameAST* name)
894
CodeModel::Scope *currentScope = baseScope;
895
const List<ClassOrNamespaceNameAST *> *scopeList = name->classOrNamespaceNameList();
896
// if there is no scope list, then the scope we are looking for is baseScope
900
// Check if the global ("::") scope has been specified.
901
if(name->isGlobal()) {
902
while (currentScope->parent())
903
currentScope = currentScope->parent();
906
while(currentScope != 0) {
907
int nestingCounter = 0;
908
CodeModel::Scope *nestedScope = currentScope;
909
while (nestingCounter < scopeList->count()) {
910
const QByteArray nameText = textOf((*scopeList)[nestingCounter]->name());
911
nestedScope = nestedScope->scopes().value(nameText);
916
if(nestedScope) // found target scope?
919
currentScope = currentScope->parent(); //look in parent scope
925
TypeMember *Semantic::typeLookup(CodeModel::Scope *baseScope, const NameAST* name)
927
QList<CodeModel::Member *> memberList = nameLookup(baseScope, name);
929
foreach(Member *member, memberList) {
930
if(TypeMember *typeMember = member->toTypeMember())
936
FunctionMember *Semantic::functionLookup(CodeModel::Scope *baseScope,
937
const DeclaratorAST *functionDeclarator)
940
QList<CodeModel::Member*> candidateList =
941
nameLookup(baseScope, functionDeclarator->declaratorId());
942
return selectFunction(candidateList, functionDeclarator);
946
This is a simplified function lookup routine, for matching member function
947
definitions with member function declarations. It does not implement
948
the general C++ function overload resolution rules.
950
FunctionMember *Semantic::selectFunction(QList<CodeModel::Member*> candidatateList, const DeclaratorAST *functionDeclarator)
952
// get arguments for funciton we are looking for
953
FunctionMember testFunction;
954
parseFunctionArguments(functionDeclarator, &testFunction);
955
const ArgumentCollection testArgumentCollection = testFunction.arguments();
957
//test againts functions in overload list.
958
foreach(Member* member, candidatateList) {
959
FunctionMember *function = member->toFunctionMember();
962
const ArgumentCollection argumentCollection = function->arguments();
964
//test argument types and number of arguments
965
ArgumentCollection::ConstIterator arg1 = argumentCollection.constBegin();
966
ArgumentCollection::ConstIterator arg2 = testArgumentCollection.constBegin();
968
while(arg1 != argumentCollection.constEnd() && arg2 != testArgumentCollection.constEnd()) {
969
if( arg1.value()->type()->name() != arg2.value()->type()->name() ) {
982
QByteArray Semantic::typeOfDeclaration(TypeSpecifierAST *typeSpec, DeclaratorAST *declarator)
989
if (typeSpec->cvQualify()) {
990
List<AST*> cv = *typeSpec->cvQualify()->children();
991
foreach (AST *current, cv) {
992
text += " " + textOf(current);
998
text += textOf(typeSpec);
1000
if (typeSpec->cv2Qualify()) {
1001
List<AST*> cv = *typeSpec->cv2Qualify()->children();
1002
foreach (AST *current, cv) {
1003
text += textOf(current) + " ";
1007
if (declarator && declarator->ptrOpList()) {
1008
List<AST*> ptrOpList = *declarator->ptrOpList();
1009
foreach (AST *current, ptrOpList) {
1010
text += " " + textOf(current);
1015
return text.trimmed().simplified();
1020
QList<QByteArray> Semantic::scopeOfName(NameAST *id, const QList<QByteArray>& startScope)
1022
QList<QByteArray> scope = startScope;
1023
if (id && id->classOrNamespaceNameList()){
1027
List<ClassOrNamespaceNameAST*> l = *id->classOrNamespaceNameList();
1028
foreach (ClassOrNamespaceNameAST *current, l) {
1029
if (current->name())
1030
scope << textOf(current->name());
1037
QList<QByteArray> Semantic::scopeOfDeclarator(DeclaratorAST *d, const QList<QByteArray>& startScope)
1040
return QList<QByteArray>();
1041
return scopeOfName(d->declaratorId(), startScope);
1044
QByteArray Semantic::typeSpecToString(TypeSpecifierAST* typeSpec)
1047
return QByteArray();
1050
if (typeSpec->cvQualify()) {
1054
tp += (QString(textOf(typeSpec)).replace(QRegExp(" :: "), QString::fromUtf8("::"))).toLatin1();
1058
QByteArray Semantic::declaratorToString(DeclaratorAST* declarator, const QByteArray& scope, bool skipPtrOp)
1061
return QByteArray();
1065
if (!skipPtrOp && declarator->ptrOpList()){
1066
List<AST*> ptrOpList = *declarator->ptrOpList();
1067
foreach (AST *current, ptrOpList) {
1068
text += textOf(current);
1075
if (declarator->subDeclarator())
1076
text += "(" + declaratorToString(declarator->subDeclarator()) + ")";
1078
if (declarator->declaratorId())
1079
text += textOf(declarator->declaratorId());
1081
if (declarator->arrayDimensionList()) {
1082
List<AST*> arrays = *declarator->arrayDimensionList();
1083
foreach (AST *current, arrays) {
1084
current=current; //silence unused symbol warning
1089
if (declarator->parameterDeclarationClause()){
1092
ParameterDeclarationListAST* l = declarator->parameterDeclarationClause()->parameterDeclarationList();
1094
List<ParameterDeclarationAST*> params = *l->parameterList();
1095
foreach (ParameterDeclarationAST *current, params) {
1096
QByteArray type = typeSpecToString(current->typeSpec());
1098
if (!type.isEmpty())
1100
text += declaratorToString(current->declarator());
1102
// ### FIXME if (it.current())
1109
if (declarator->constant() != 0)
1113
return QString(text).replace(QRegExp(" :: "), "::").simplified().toLatin1();
1116
QByteArray Semantic::textOf(const AST *node) const
1119
return QByteArray();
1121
for (int i = node->startToken(); i < node->endToken(); ++i) {
1122
if (!m_tokenStream->isHidden(i)) {
1123
if (i != node->startToken())
1125
text += m_tokenStream->tokenText(i);
1131
void Semantic::createNameUse(Member *member, NameAST *name)
1133
AST *unqualifedName = name->unqualifiedName()->name();
1135
if(!unqualifedName || !member || !name)
1138
CodeModel::NameUse *nameUse = CodeModel::Create<CodeModel::NameUse>(m_storage);
1139
nameUse->setParent(currentScope.top());
1140
nameUse->setNameToken(tokenRefFromAST(unqualifedName));
1141
nameUse->setName(textOf(unqualifedName));
1142
nameUse->setDeclaration(member);
1144
currentScope.top()->addNameUse(nameUse);
1145
addNameUse(unqualifedName, nameUse);
1148
void Semantic::addNameUse(AST *node, NameUse *nameUse)
1150
const int tokenIndex = node->startToken();
1151
m_nameUses.insert(tokenIndex, nameUse);
1155
Searches a AST node and all its children for a nameUse. The name use is
1156
found by looking up each node's tokens in the m_nameUses map. A depth-first
1159
NameUse *Semantic::findNameUse(AST *node)
1164
List<AST*> *children = node->children();
1166
NameUse *nameUse = 0;
1167
foreach(AST* child , *children) {
1168
nameUse = findNameUse(child);
1176
for (int t = node->startToken(); t < node->endToken(); ++t) {
1177
// cout << t <<" |" <<m_tokenStream->tokenText(t).constData() << "|" << endl;
1178
if (m_nameUses.contains(t))
1179
return m_nameUses.value(t);
1185
Gets a TokenRef from an AST node.
1186
Assumes that the node only covers one token, which means that
1187
node->statToken() == node->endToken(). If this is not the case
1188
then the TokenRef will reference the token at startToken.
1190
TokenEngine::TokenRef Semantic::tokenRefFromAST(AST *node)
1192
const int startTokenIndex = node->startToken();
1193
const TokenEngine::TokenContainer tokenContainer = m_tokenStream->tokenContainer(startTokenIndex);
1194
const int containerIndex = m_tokenStream->containerIndex(startTokenIndex);
1195
return TokenEngine::TokenRef(tokenContainer, containerIndex);