diff options
author | Erik Verbruggen <erik.verbruggen@nokia.com> | 2009-07-28 16:34:15 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@nokia.com> | 2009-07-28 16:34:15 +0200 |
commit | 26267c03445266233159b2f61bbc3a4d5864c01a (patch) | |
tree | 8b7536d8f41fea63adc180d56830a73aae1192ad /src/shared/cplusplus/CheckDeclaration.cpp | |
parent | a9b521f80af025ac11f9735fc070606952894b60 (diff) | |
download | qt-creator-26267c03445266233159b2f61bbc3a4d5864c01a.tar.gz |
Improved ObjC parsing, and added semantic checks.
Diffstat (limited to 'src/shared/cplusplus/CheckDeclaration.cpp')
-rw-r--r-- | src/shared/cplusplus/CheckDeclaration.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index 83fbc1dd0e..1a9877db15 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -464,4 +464,146 @@ bool CheckDeclaration::visit(UsingDirectiveAST *ast) return false; } +bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast) +{ + const unsigned sourceLocation = ast->firstToken(); + + List<ObjCForwardProtocolDeclaration *> **symbolIter = &ast->symbols; + for (IdentifierListAST *it = ast->identifier_list; it; it = it->next) { + unsigned declarationLocation; + if (it->name) + declarationLocation = it->name->firstToken(); + else + declarationLocation = sourceLocation; + + Name *protocolName = semantic()->check(it->name, _scope); + ObjCForwardProtocolDeclaration *fwdProtocol = control()->newObjCForwardProtocolDeclaration(sourceLocation, protocolName); + fwdProtocol->setStartOffset(tokenAt(ast->firstToken()).offset); + fwdProtocol->setEndOffset(tokenAt(ast->lastToken()).offset); + + _scope->enterSymbol(fwdProtocol); + + *symbolIter = new (translationUnit()->memoryPool()) List<ObjCForwardProtocolDeclaration *>(); + (*symbolIter)->value = fwdProtocol; + symbolIter = &(*symbolIter)->next; + } + + return false; +} + +bool CheckDeclaration::visit(ObjCProtocolDefinitionAST *ast) +{ + unsigned sourceLocation; + if (ast->name) + sourceLocation = ast->name->firstToken(); + else + sourceLocation = ast->firstToken(); + + Name *protocolName = semantic()->check(ast->name, _scope); + ObjCProtocol *protocol = control()->newObjCProtocol(sourceLocation, protocolName); + protocol->setStartOffset(tokenAt(ast->firstToken()).offset); + protocol->setEndOffset(tokenAt(ast->lastToken()).offset); + ast->symbol = protocol; + + _scope->enterSymbol(protocol); + + // TODO EV: walk protocols and method prototypes + return false; +} + +bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast) +{ + const unsigned sourceLocation = ast->firstToken(); + + List<ObjCForwardClassDeclaration *> **symbolIter = &ast->symbols; + for (IdentifierListAST *it = ast->identifier_list; it; it = it->next) { + unsigned declarationLocation; + if (it->name) + declarationLocation = it->name->firstToken(); + else + declarationLocation = sourceLocation; + + Name *className = semantic()->check(it->name, _scope); + ObjCForwardClassDeclaration *fwdClass = control()->newObjCForwardClassDeclaration(sourceLocation, className); + fwdClass->setStartOffset(tokenAt(ast->firstToken()).offset); + fwdClass->setEndOffset(tokenAt(ast->lastToken()).offset); + + _scope->enterSymbol(fwdClass); + + *symbolIter = new (translationUnit()->memoryPool()) List<ObjCForwardClassDeclaration *>(); + (*symbolIter)->value = fwdClass; + symbolIter = &(*symbolIter)->next; + } + + return false; +} + +bool CheckDeclaration::visit(ObjCClassInterfaceDefinitionAST *ast) +{ + unsigned sourceLocation; + if (ast->class_name) + sourceLocation = ast->class_name->firstToken(); + else + sourceLocation = ast->firstToken(); + + Name *className = semantic()->check(ast->class_name, _scope); + ObjCClass *klass = control()->newObjCClass(sourceLocation, className); + klass->setStartOffset(tokenAt(ast->firstToken()).offset); + klass->setEndOffset(tokenAt(ast->lastToken()).offset); + ast->symbol = klass; + + // TODO: walk super-class, and protocols (EV) + _scope->enterSymbol(klass); + + int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Protected); + + if (ast->inst_vars_decl) { + for (DeclarationListAST *it = ast->inst_vars_decl->instance_variables; it; it = it->next) { + semantic()->check(it->declaration, klass->members()); + } + } + + for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) { + semantic()->check(it->declaration, klass->members()); + } + + (void) semantic()->switchObjCVisibility(previousObjCVisibility); + + return false; +} + +bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast) +{ + if (!ast->method_prototype) + return false; + + FullySpecifiedType ty = semantic()->check(ast->method_prototype, _scope); + Function *fun = ty.type()->asFunctionType(); + if (!fun) + return false; + + Declaration *symbol = control()->newDeclaration(ast->firstToken(), fun->name()); + symbol->setStartOffset(tokenAt(ast->firstToken()).offset); + symbol->setEndOffset(tokenAt(ast->lastToken()).offset); + + symbol->setType(fun->returnType()); + + symbol->setVisibility(semantic()->currentVisibility()); + + if (semantic()->isObjCClassMethod(ast->method_prototype->method_type_token)) + symbol->setStorage(Symbol::Static); + + _scope->enterSymbol(symbol); + + return false; +} + +bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast) +{ + int accessSpecifier = tokenKind(ast->visibility_token); + int visibility = semantic()->visibilityForObjCAccessSpecifier(accessSpecifier); + semantic()->switchObjCVisibility(visibility); + return false; +} + CPLUSPLUS_END_NAMESPACE |