summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus/CheckDeclaration.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@nokia.com>2009-10-05 18:02:01 +0200
committerErik Verbruggen <erik.verbruggen@nokia.com>2009-10-05 18:02:01 +0200
commitf1e665463b221ff33d714d55683033afdaf46576 (patch)
treea580aec2664c9977be748d6f93c7d295bb854a50 /src/shared/cplusplus/CheckDeclaration.cpp
parentb43f279227e7eb074f68f2222a908c568b1e749e (diff)
downloadqt-creator-f1e665463b221ff33d714d55683033afdaf46576.tar.gz
Added protocol & class definedness checks, and added property attribute checks.
Diffstat (limited to 'src/shared/cplusplus/CheckDeclaration.cpp')
-rw-r--r--src/shared/cplusplus/CheckDeclaration.cpp117
1 files changed, 114 insertions, 3 deletions
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 69e645b1be..4b2604de40 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -57,6 +57,7 @@
#include "Control.h"
#include "Literals.h"
#include <cassert>
+#include <QtCore/QByteArray>
CPLUSPLUS_BEGIN_NAMESPACE
@@ -506,11 +507,25 @@ bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast)
ObjCProtocol *protocol = control()->newObjCProtocol(sourceLocation, protocolName);
protocol->setStartOffset(tokenAt(ast->firstToken()).offset);
protocol->setEndOffset(tokenAt(ast->lastToken()).offset);
- ast->symbol = protocol;
+ if (ast->protocol_refs && ast->protocol_refs->identifier_list) {
+ for (IdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
+ NameAST* name = iter->name;
+ Name *protocolName = semantic()->check(name, _scope);
+ ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName);
+ protocol->addProtocol(baseProtocol);
+ }
+ }
+
+ int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Public);
+ for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) {
+ semantic()->check(it->declaration, protocol->members());
+ }
+ (void) semantic()->switchObjCVisibility(previousObjCVisibility);
+
+ ast->symbol = protocol;
_scope->enterSymbol(protocol);
- // TODO EV: walk protocols and method prototypes
return false;
}
@@ -562,7 +577,21 @@ bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast)
klass->setCategoryName(categoryName);
}
- // TODO: super-class, and protocols (EV)
+ if (ast->superclass) {
+ Name *superClassName = semantic()->check(ast->superclass, _scope);
+ ObjCBaseClass *superKlass = control()->newObjCBaseClass(ast->superclass->firstToken(), superClassName);
+ klass->setBaseClass(superKlass);
+ }
+
+ if (ast->protocol_refs && ast->protocol_refs->identifier_list) {
+ for (IdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
+ NameAST* name = iter->name;
+ Name *protocolName = semantic()->check(name, _scope);
+ ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName);
+ klass->addProtocol(baseProtocol);
+ }
+ }
+
_scope->enterSymbol(klass);
int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Protected);
@@ -627,4 +656,86 @@ bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast)
return false;
}
+enum PropertyAttributes {
+ None = 0,
+ Assign = 1 << 0,
+ Retain = 1 << 1,
+ Copy = 1 << 2,
+ ReadOnly = 1 << 3,
+ ReadWrite = 1 << 4,
+ Getter = 1 << 5,
+ Setter = 1 << 6,
+ NonAtomic = 1 << 7,
+
+ WritabilityMask = ReadOnly | ReadWrite,
+ SetterSemanticsMask = Assign | Retain | Copy,
+};
+
+bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
+ int &flags,
+ int attr)
+{
+ if (flags & attr) {
+ translationUnit()->warning(attrAst->attribute_identifier_token,
+ "duplicate property attribute \"%s\"",
+ spell(attrAst->attribute_identifier_token));
+ return false;
+ } else {
+ flags |= attr;
+ return true;
+ }
+}
+
+bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast)
+{
+ int propAttrs = None;
+
+ for (ObjCPropertyAttributeListAST *iter= ast->property_attributes; iter; iter = iter->next) {
+ ObjCPropertyAttributeAST *attrAst = iter->attr;
+ if (!attrAst)
+ continue;
+
+ const char *attrName = spell(attrAst->attribute_identifier_token);
+ if (!qstrcmp("getter", attrName)) {
+ if (checkPropertyAttribute(attrAst, propAttrs, Getter)) {
+ // TODO: find method declaration for getter
+ }
+ } else if (!qstrcmp("setter", attrName)) {
+ if (checkPropertyAttribute(attrAst, propAttrs, Setter)) {
+ // TODO: find method declaration for setter
+ }
+ } else if (!qstrcmp("readwrite", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, ReadWrite);
+ } else if (!qstrcmp("readonly", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, ReadOnly);
+ } else if (!qstrcmp("assign", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, Assign);
+ } else if (!qstrcmp("retain", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, Retain);
+ } else if (!qstrcmp("copy", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, Copy);
+ } else if (!qstrcmp("nonatomic", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, NonAtomic);
+ }
+ }
+
+ if (propAttrs & ReadOnly && propAttrs & ReadWrite)
+ // Should this be an error instead of only a warning?
+ translationUnit()->warning(ast->property_token,
+ "property can have at most one attribute \"readonly\" or \"readwrite\" specified");
+ int setterSemAttrs = propAttrs & SetterSemanticsMask;
+ if (setterSemAttrs
+ && setterSemAttrs != Assign
+ && setterSemAttrs != Retain
+ && setterSemAttrs != Copy) {
+ // Should this be an error instead of only a warning?
+ translationUnit()->warning(ast->property_token,
+ "property can have at most one attribute \"assign\", \"retain\", or \"copy\" specified");
+ }
+
+ // TODO: Check if the next line is correct (EV)
+ semantic()->check(ast->simple_declaration, _scope);
+ return false;
+}
+
CPLUSPLUS_END_NAMESPACE