summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus/CheckDeclaration.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@nokia.com>2009-07-28 16:34:15 +0200
committerErik Verbruggen <erik.verbruggen@nokia.com>2009-07-28 16:34:15 +0200
commit26267c03445266233159b2f61bbc3a4d5864c01a (patch)
tree8b7536d8f41fea63adc180d56830a73aae1192ad /src/shared/cplusplus/CheckDeclaration.cpp
parenta9b521f80af025ac11f9735fc070606952894b60 (diff)
downloadqt-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.cpp142
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