From 26267c03445266233159b2f61bbc3a4d5864c01a Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Tue, 28 Jul 2009 16:34:15 +0200 Subject: [PATCH] Improved ObjC parsing, and added semantic checks. --- src/libs/cplusplus/CheckUndefinedSymbols.cpp | 8 + src/libs/cplusplus/Icons.cpp | 4 + src/shared/cplusplus/AST.cpp | 132 +++++++++--- src/shared/cplusplus/AST.h | 193 ++++++++++++++++-- src/shared/cplusplus/ASTClone.cpp | 65 ++++-- src/shared/cplusplus/ASTVisit.cpp | 56 ++++- src/shared/cplusplus/ASTVisitor.h | 22 +- src/shared/cplusplus/ASTfwd.h | 12 +- .../cplusplus/CPlusPlusForwardDeclarations.h | 6 + src/shared/cplusplus/CheckDeclaration.cpp | 142 +++++++++++++ src/shared/cplusplus/CheckDeclaration.h | 7 + src/shared/cplusplus/CheckDeclarator.cpp | 37 ++++ src/shared/cplusplus/CheckDeclarator.h | 5 + src/shared/cplusplus/CheckName.cpp | 35 ++++ src/shared/cplusplus/CheckName.h | 5 + src/shared/cplusplus/Control.cpp | 47 +++++ src/shared/cplusplus/Control.h | 12 ++ src/shared/cplusplus/Parser.cpp | 170 ++++++++------- src/shared/cplusplus/Parser.h | 4 +- src/shared/cplusplus/Semantic.cpp | 47 +++++ src/shared/cplusplus/Semantic.h | 9 + src/shared/cplusplus/Symbol.cpp | 12 ++ src/shared/cplusplus/Symbol.h | 23 ++- src/shared/cplusplus/SymbolVisitor.h | 6 + src/shared/cplusplus/Symbols.cpp | 134 ++++++++++++ src/shared/cplusplus/Symbols.h | 127 ++++++++++++ src/shared/cplusplus/Type.cpp | 12 ++ src/shared/cplusplus/Type.h | 12 ++ src/shared/cplusplus/TypeVisitor.h | 4 + 29 files changed, 1192 insertions(+), 156 deletions(-) diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.cpp b/src/libs/cplusplus/CheckUndefinedSymbols.cpp index d0d69187468..3e7304c6179 100644 --- a/src/libs/cplusplus/CheckUndefinedSymbols.cpp +++ b/src/libs/cplusplus/CheckUndefinedSymbols.cpp @@ -154,6 +154,14 @@ void CheckUndefinedSymbols::buildTypeMap(NamespaceBinding *binding, QSet<Namespa } else if (Declaration *decl = member->asDeclaration()) { if (decl->isTypedef()) addType(decl->name()); + } else if (ObjCForwardClassDeclaration *fKlass = member->asObjCForwardClassDeclaration()) { + addType(fKlass->name()); + } else if (ObjCClass *klass = member->asObjCClass()) { + addType(klass->name()); + } else if (ObjCForwardProtocolDeclaration *fProto = member->asObjCForwardProtocolDeclaration()) { + addType(fProto->name()); + } else if (ObjCProtocol *proto = member->asObjCProtocol()) { + addType(proto->name()); } } } diff --git a/src/libs/cplusplus/Icons.cpp b/src/libs/cplusplus/Icons.cpp index 90b03f871ab..894cf86eebd 100644 --- a/src/libs/cplusplus/Icons.cpp +++ b/src/libs/cplusplus/Icons.cpp @@ -98,6 +98,10 @@ QIcon Icons::iconForSymbol(const Symbol *symbol) const return _enumIcon; } else if (symbol->isClass() || symbol->isForwardClassDeclaration()) { return _classIcon; + } else if (symbol->isObjCClass() || symbol->isObjCForwardClassDeclaration()) { + return _classIcon; + } else if (symbol->isObjCProtocol() || symbol->isObjCForwardProtocolDeclaration()) { + return _classIcon; } else if (symbol->isNamespace()) { return _namespaceIcon; } else if (symbol->isUsingNamespaceDirective() || diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 0eae1bd0fed..967894cc743 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -1906,14 +1906,17 @@ unsigned WhileStatementAST::lastToken() const // ObjC++ unsigned IdentifierListAST::firstToken() const { - return identifier_token; + if (name) + return name->firstToken(); + else + return comma_token; } unsigned IdentifierListAST::lastToken() const { for (const IdentifierListAST *it = this; it; it = it->next) { - if (! it->next && it->identifier_token) { - return it->identifier_token + 1; + if (! it->next && it->name) { + return it->name->lastToken(); } } // ### assert? @@ -1934,8 +1937,8 @@ unsigned ObjCClassDeclarationAST::lastToken() const return semicolon_token + 1; for (IdentifierListAST *it = identifier_list; it; it = it->next) { - if (! it->next && it->identifier_token) - return it->identifier_token + 1; + if (! it->next && it->name) + return it->name->lastToken(); } for (SpecifierAST *it = attributes; it; it = it->next) { @@ -1959,8 +1962,8 @@ unsigned ObjCProtocolDeclarationAST::lastToken() const return semicolon_token + 1; for (IdentifierListAST *it = identifier_list; it; it = it->next) { - if (! it->next && it->identifier_token) - return it->identifier_token + 1; + if (! it->next && it->name) + return it->name->lastToken(); } for (SpecifierAST *it = attributes; it; it = it->next) { @@ -1971,21 +1974,21 @@ unsigned ObjCProtocolDeclarationAST::lastToken() const return protocol_token + 1; } -unsigned ObjCClassInterfaceDeclarationAST::firstToken() const +unsigned ObjCClassInterfaceDefinitionAST::firstToken() const { if (attributes) return attributes->firstToken(); return interface_token; } -unsigned ObjCClassInterfaceDeclarationAST::lastToken() const +unsigned ObjCClassInterfaceDefinitionAST::lastToken() const { if (end_token) return end_token + 1; if (member_declarations) return member_declarations->lastToken(); if (inst_vars_decl) return inst_vars_decl->lastToken(); if (superclass_identifier_token) return superclass_identifier_token + 1; if (colon_token) return colon_token + 1; - if (class_identifier_token) return class_identifier_token + 1; + if (class_name) return class_name->lastToken(); for (SpecifierAST *it = attributes; it; it = it->next) { if (! it->next) @@ -2036,8 +2039,8 @@ unsigned ObjCProtocolDefinitionAST::lastToken() const if (protocol_refs) return protocol_refs->lastToken(); - if (identifier_token) - return identifier_token + 1; + if (name) + return name->lastToken(); for (SpecifierAST *it = attributes; it; it = it->next) { if (! it->next) @@ -2057,8 +2060,8 @@ unsigned ObjCProtocolRefsAST::lastToken() const if (greater_token) return greater_token + 1; for (IdentifierListAST *it = identifier_list; it; it = it->next) { - if (! it->next && it->identifier_token) - return it->identifier_token + 1; + if (! it->next && it->name) + return it->name->lastToken(); } return less_token + 1; @@ -2169,6 +2172,74 @@ unsigned ObjCEncodeExpressionAST::lastToken() const return encode_token + 1; } +unsigned ObjCSelectorWithoutArgumentsAST::firstToken() const +{ + return name_token; +} + +unsigned ObjCSelectorWithoutArgumentsAST::lastToken() const +{ + return name_token + 1; +} + +unsigned ObjCSelectorArgumentAST::firstToken() const +{ + return name_token; +} + +unsigned ObjCSelectorArgumentAST::lastToken() const +{ + if (colon_token) + return colon_token + 1; + else + return name_token + 1; +} + +unsigned ObjCSelectorArgumentListAST::firstToken() const +{ + if (argument) + return argument->firstToken(); + + // ### assert? + return 0; +} + +unsigned ObjCSelectorArgumentListAST::lastToken() const +{ + for (const ObjCSelectorArgumentListAST *it = this; it; it = it->next) + if (!it->next && it->argument) + return it->argument->lastToken(); + + // ### assert? + return 0; +} + +unsigned ObjCSelectorWithArgumentsAST::firstToken() const +{ + return selector_arguments->firstToken(); +} + +unsigned ObjCSelectorWithArgumentsAST::lastToken() const +{ + return selector_arguments->lastToken(); +} + +unsigned ObjCSelectorExpressionAST::firstToken() const +{ + return selector_token; +} + +unsigned ObjCSelectorExpressionAST::lastToken() const +{ + if (rparen_token) + return rparen_token + 1; + if (selector) + return selector->lastToken(); + if (lparen_token) + return rparen_token + 1; + return selector_token + 1; +} + unsigned ObjCInstanceVariablesDeclarationAST::firstToken() const { return lbrace_token; @@ -2179,9 +2250,6 @@ unsigned ObjCInstanceVariablesDeclarationAST::lastToken() const if (rbrace_token) return rbrace_token + 1; - if (member_declarations) - return member_declarations->lastToken(); - if (instance_variables) return instance_variables->lastToken(); @@ -2198,24 +2266,22 @@ unsigned ObjCVisibilityDeclarationAST::lastToken() const return visibility_token + 1; } -unsigned ObjcPropertyAttributeAST::firstToken() const +unsigned ObjCPropertyAttributeAST::firstToken() const { return attribute_identifier_token; } -unsigned ObjcPropertyAttributeAST::lastToken() const +unsigned ObjCPropertyAttributeAST::lastToken() const { - if (colon_token) - return colon_token + 1; - if (method_selector_identifier_token) - return method_selector_identifier_token + 1; + if (method_selector) + return method_selector->lastToken(); if (equals_token) return equals_token + 1; return attribute_identifier_token + 1; } -unsigned ObjcPropertyAttributeListAST::firstToken() const +unsigned ObjCPropertyAttributeListAST::firstToken() const { if (attr) return attr->firstToken(); @@ -2228,9 +2294,9 @@ unsigned ObjcPropertyAttributeListAST::firstToken() const return 0; } -unsigned ObjcPropertyAttributeListAST::lastToken() const +unsigned ObjCPropertyAttributeListAST::lastToken() const { - for (const ObjcPropertyAttributeListAST *it = this; it; it = it->next) { + for (const ObjCPropertyAttributeListAST *it = this; it; it = it->next) { if (! it->next && (comma_token || it->attr)) { if (comma_token) return comma_token + 1; @@ -2266,21 +2332,21 @@ unsigned ObjCPropertyDeclarationAST::lastToken() const unsigned ObjCMessageArgumentDeclarationAST::firstToken() const { - return param_selector_token; + if (type_name) + return type_name->firstToken(); + else + return param_name_token; } unsigned ObjCMessageArgumentDeclarationAST::lastToken() const { if (param_name_token) return param_name_token + 1; - else if (colon_token) - return colon_token + 1; else if (type_name) return type_name->lastToken(); - else if (attributes) - return attributes->lastToken(); - else - return param_name_token + 1; + + // ### assert? + return 0; } unsigned ObjCMessageArgumentDeclarationListAST::firstToken() const diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index cbbbc5da69f..df54fc106c7 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -196,9 +196,40 @@ public: virtual UsingDirectiveAST *asUsingDirective() { return 0; } virtual WhileStatementAST *asWhileStatement() { return 0; } virtual IdentifierListAST *asIdentifierList() { return 0; } + virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; } virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return 0; } virtual ObjCProtocolDefinitionAST *asObjCProtocolDefinition() { return 0; } + virtual ObjCProtocolRefsAST *asObjCProtocolRefs() { return 0; } + virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return 0; } + virtual ObjCMessageArgumentListAST *asObjCMessageArgumentList() { return 0; } + virtual ObjCMessageExpressionAST *asObjCMessageExpression() { return 0; } + virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() { return 0; } + virtual ObjCTypeNameAST *asObjCTypeName() { return 0; } + virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return 0; } + virtual ObjCSelectorAST *asObjCSelector() { return 0; } + virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() { return 0; } + virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return 0; } + virtual ObjCSelectorArgumentListAST *asObjCSelectorArgumentList() { return 0; } + virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() { return 0; } + virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return 0; } + virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return 0; } + virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return 0; } + virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return 0; } + virtual ObjCPropertyAttributeListAST *asObjCPropertyAttributeList() { return 0; } + virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return 0; } + virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return 0; } + virtual ObjCMessageArgumentDeclarationListAST *asObjCMessageArgumentDeclarationList() { return 0; } + virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return 0; } + virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() { return 0; } + virtual ObjCMethodDefinitionAST *asObjCMethodDefinition() { return 0; } + virtual ObjCClassImplementationAST *asObjCClassImplementation() { return 0; } + virtual ObjCCategoryImplementationAST *asObjCCategoryImplementation() { return 0; } + virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return 0; } + virtual ObjCSynthesizedPropertyListAST *asObjCSynthesizedPropertyList() { return 0; } + virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return 0; } + virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return 0; } + virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return 0; } virtual AST *clone(MemoryPool *pool) const = 0; @@ -2444,7 +2475,7 @@ protected: class CPLUSPLUS_EXPORT IdentifierListAST: public AST { public: - unsigned identifier_token; + SimpleNameAST *name; unsigned comma_token; IdentifierListAST *next; @@ -2469,6 +2500,9 @@ public: IdentifierListAST *identifier_list; unsigned semicolon_token; +public: // annotations + List<ObjCForwardClassDeclaration *> *symbols; + public: virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return this; } @@ -2482,12 +2516,12 @@ protected: virtual void accept0(ASTVisitor *visitor); }; -class CPLUSPLUS_EXPORT ObjCClassInterfaceDeclarationAST: public DeclarationAST +class CPLUSPLUS_EXPORT ObjCClassInterfaceDefinitionAST: public DeclarationAST { public: SpecifierAST *attributes; unsigned interface_token; - unsigned class_identifier_token; + SimpleNameAST *class_name; unsigned colon_token; unsigned superclass_identifier_token; ObjCProtocolRefsAST *protocol_refs; @@ -2495,14 +2529,17 @@ public: DeclarationListAST *member_declarations; unsigned end_token; +public: // annotations + ObjCClass *symbol; + public: - virtual ObjCClassInterfaceDeclarationAST *asObjCClassInterfaceDeclaration() + virtual ObjCClassInterfaceDefinitionAST *asObjCClassInterfaceDefinition() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCClassInterfaceDeclarationAST *clone(MemoryPool *pool) const; + virtual ObjCClassInterfaceDefinitionAST *clone(MemoryPool *pool) const; protected: virtual void accept0(ASTVisitor *visitor); @@ -2542,6 +2579,9 @@ public: IdentifierListAST *identifier_list; unsigned semicolon_token; +public: // annotations + List<ObjCForwardProtocolDeclaration *> *symbols; + public: virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return this; } @@ -2560,11 +2600,14 @@ class CPLUSPLUS_EXPORT ObjCProtocolDefinitionAST: public DeclarationAST public: SpecifierAST *attributes; unsigned protocol_token; - unsigned identifier_token; + SimpleNameAST *name; ObjCProtocolRefsAST *protocol_refs; DeclarationListAST *member_declarations; unsigned end_token; +public: // annotations + ObjCProtocol *symbol; + public: virtual ObjCProtocolDefinitionAST *asObjCProtocolDefinition() { return this; } @@ -2719,12 +2762,118 @@ protected: virtual void accept0(ASTVisitor *visitor); }; +class CPLUSPLUS_EXPORT ObjCSelectorAST: public AST +{ +public: // annotation + Name *selector_name; + +public: + virtual ObjCSelectorAST *asObjCSelector() + { return this; } + + virtual ObjCSelectorAST *clone(MemoryPool *pool) const = 0; +}; + +class CPLUSPLUS_EXPORT ObjCSelectorWithoutArgumentsAST: public ObjCSelectorAST +{ +public: + unsigned name_token; + +public: + virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSelectorWithoutArgumentsAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCSelectorArgumentAST: public AST +{ +public: + unsigned name_token; + unsigned colon_token; + +public: + virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSelectorArgumentAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCSelectorArgumentListAST: public AST +{ +public: + ObjCSelectorArgumentAST *argument; + ObjCSelectorArgumentListAST *next; + +public: + virtual ObjCSelectorArgumentListAST *asObjCSelectorArgumentList() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSelectorArgumentListAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCSelectorWithArgumentsAST: public ObjCSelectorAST +{ +public: + ObjCSelectorArgumentListAST *selector_arguments; + +public: + virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSelectorWithArgumentsAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCSelectorExpressionAST: public ExpressionAST +{ +public: + unsigned selector_token; + unsigned lparen_token; + ObjCSelectorAST *selector; + unsigned rparen_token; + +public: + virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCSelectorExpressionAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + class CPLUSPLUS_EXPORT ObjCInstanceVariablesDeclarationAST: public AST { public: unsigned lbrace_token; DeclarationListAST *instance_variables; - DeclarationListAST *member_declarations; unsigned rbrace_token; public: @@ -2758,42 +2907,41 @@ protected: virtual void accept0(ASTVisitor *visitor); }; -class CPLUSPLUS_EXPORT ObjcPropertyAttributeAST: public AST +class CPLUSPLUS_EXPORT ObjCPropertyAttributeAST: public AST { public: unsigned attribute_identifier_token; unsigned equals_token; - unsigned method_selector_identifier_token; - unsigned colon_token; + ObjCSelectorAST *method_selector; public: - virtual ObjcPropertyAttributeAST *asObjcPropertyAttribute() + virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjcPropertyAttributeAST *clone(MemoryPool *pool) const; + virtual ObjCPropertyAttributeAST *clone(MemoryPool *pool) const; protected: virtual void accept0(ASTVisitor *visitor); }; -class CPLUSPLUS_EXPORT ObjcPropertyAttributeListAST: public AST +class CPLUSPLUS_EXPORT ObjCPropertyAttributeListAST: public AST { public: - ObjcPropertyAttributeAST *attr; + ObjCPropertyAttributeAST *attr; unsigned comma_token; - ObjcPropertyAttributeListAST *next; + ObjCPropertyAttributeListAST *next; public: - virtual ObjcPropertyAttributeListAST *asObjcPropertyAttributeList() + virtual ObjCPropertyAttributeListAST *asObjCPropertyAttributeList() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjcPropertyAttributeListAST *clone(MemoryPool *pool) const; + virtual ObjCPropertyAttributeListAST *clone(MemoryPool *pool) const; protected: virtual void accept0(ASTVisitor *visitor); @@ -2805,7 +2953,7 @@ public: SpecifierAST *attributes; unsigned property_token; unsigned lparen_token; - ObjcPropertyAttributeListAST *property_attributes; + ObjCPropertyAttributeListAST *property_attributes; unsigned rparen_token; DeclarationAST *simple_declaration; @@ -2825,12 +2973,13 @@ protected: class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationAST: public AST { public: - unsigned param_selector_token; - unsigned colon_token; ObjCTypeNameAST* type_name; SpecifierAST *attributes; unsigned param_name_token; +public: // annotations + Name *param_name; + public: virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return this; } @@ -2868,9 +3017,13 @@ class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public AST public: unsigned method_type_token; ObjCTypeNameAST *type_name; + ObjCSelectorAST *selector; ObjCMessageArgumentDeclarationListAST *arguments; SpecifierAST *attributes; +public: // annotations + Function *symbol; + public: virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return this; } diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index 3340a39f25c..24717e300a4 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1207,7 +1207,8 @@ IdentifierListAST *IdentifierListAST::clone(MemoryPool *pool) const { IdentifierListAST *ast = new (pool) IdentifierListAST; // copy IdentifierListAST - ast->identifier_token = identifier_token; + if (ast->name) ast->name = name->clone(pool); + ast->comma_token = comma_token; if (next) ast->next = next->clone(pool); return ast; } @@ -1224,14 +1225,14 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const return ast; } -ObjCClassInterfaceDeclarationAST *ObjCClassInterfaceDeclarationAST::clone(MemoryPool *pool) const +ObjCClassInterfaceDefinitionAST *ObjCClassInterfaceDefinitionAST::clone(MemoryPool *pool) const { - ObjCClassInterfaceDeclarationAST *ast = new (pool) ObjCClassInterfaceDeclarationAST; + ObjCClassInterfaceDefinitionAST *ast = new (pool) ObjCClassInterfaceDefinitionAST; // copy DeclarationAST // copy ObjCClassInterfaceDeclarationAST if (attributes) ast->attributes = attributes->clone(pool); ast->interface_token = interface_token; - ast->class_identifier_token = class_identifier_token; + if (class_name) ast->class_name = class_name->clone(pool); ast->colon_token = colon_token; ast->superclass_identifier_token = superclass_identifier_token; if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool); @@ -1273,7 +1274,7 @@ ObjCProtocolDefinitionAST *ObjCProtocolDefinitionAST::clone(MemoryPool *pool) co ObjCProtocolDefinitionAST *ast = new (pool) ObjCProtocolDefinitionAST; if (attributes) ast->attributes = attributes->clone(pool); ast->protocol_token = protocol_token; - ast->identifier_token = identifier_token; + if (name) ast->name = name->clone(pool); if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool); if (member_declarations) ast->member_declarations = member_declarations->clone(pool); ast->end_token = end_token; @@ -1344,12 +1345,51 @@ ObjCEncodeExpressionAST *ObjCEncodeExpressionAST::clone(MemoryPool *pool) const return ast; } +ObjCSelectorWithoutArgumentsAST *ObjCSelectorWithoutArgumentsAST::clone(MemoryPool *pool) const +{ + ObjCSelectorWithoutArgumentsAST *ast = new (pool) ObjCSelectorWithoutArgumentsAST; + ast->name_token = name_token; + return ast; +} + +ObjCSelectorArgumentAST *ObjCSelectorArgumentAST::clone(MemoryPool *pool) const +{ + ObjCSelectorArgumentAST *ast = new (pool) ObjCSelectorArgumentAST; + ast->name_token = name_token; + ast->colon_token = colon_token; + return ast; +} + +ObjCSelectorArgumentListAST *ObjCSelectorArgumentListAST::clone(MemoryPool *pool) const +{ + ObjCSelectorArgumentListAST *ast = new (pool) ObjCSelectorArgumentListAST; + if (argument) ast->argument = argument->clone(pool); + if (next) ast->next = next->clone(pool); + return ast; +} + +ObjCSelectorWithArgumentsAST *ObjCSelectorWithArgumentsAST::clone(MemoryPool *pool) const +{ + ObjCSelectorWithArgumentsAST *ast = new (pool) ObjCSelectorWithArgumentsAST; + if (selector_arguments) ast->selector_arguments = selector_arguments->clone(pool); + return ast; +} + +ObjCSelectorExpressionAST *ObjCSelectorExpressionAST::clone(MemoryPool *pool) const +{ + ObjCSelectorExpressionAST *ast = new (pool) ObjCSelectorExpressionAST; + ast->selector_token = selector_token; + ast->lparen_token = lparen_token; + if (selector) ast->selector = selector->clone(pool); + ast->rparen_token = rparen_token; + return ast; +} + ObjCInstanceVariablesDeclarationAST *ObjCInstanceVariablesDeclarationAST::clone(MemoryPool *pool) const { ObjCInstanceVariablesDeclarationAST *ast = new (pool) ObjCInstanceVariablesDeclarationAST; ast->lbrace_token = lbrace_token; if (instance_variables) ast->instance_variables = instance_variables->clone(pool); - if (member_declarations) ast->member_declarations = member_declarations->clone(pool); ast->rbrace_token = rbrace_token; return ast; } @@ -1361,19 +1401,18 @@ ObjCVisibilityDeclarationAST *ObjCVisibilityDeclarationAST::clone(MemoryPool *po return ast; } -ObjcPropertyAttributeAST *ObjcPropertyAttributeAST::clone(MemoryPool *pool) const +ObjCPropertyAttributeAST *ObjCPropertyAttributeAST::clone(MemoryPool *pool) const { - ObjcPropertyAttributeAST *ast = new (pool) ObjcPropertyAttributeAST; + ObjCPropertyAttributeAST *ast = new (pool) ObjCPropertyAttributeAST; ast->attribute_identifier_token = attribute_identifier_token; ast->equals_token = equals_token; - ast->method_selector_identifier_token = method_selector_identifier_token; - ast->colon_token = colon_token; + if (method_selector) ast->method_selector = method_selector->clone(pool); return ast; } -ObjcPropertyAttributeListAST *ObjcPropertyAttributeListAST::clone(MemoryPool *pool) const +ObjCPropertyAttributeListAST *ObjCPropertyAttributeListAST::clone(MemoryPool *pool) const { - ObjcPropertyAttributeListAST *ast = new (pool) ObjcPropertyAttributeListAST; + ObjCPropertyAttributeListAST *ast = new (pool) ObjCPropertyAttributeListAST; if (attr) ast->attr = attr->clone(pool); ast->comma_token = comma_token; if (next) ast->next = next->clone(pool); @@ -1395,8 +1434,6 @@ ObjCPropertyDeclarationAST *ObjCPropertyDeclarationAST::clone(MemoryPool *pool) ObjCMessageArgumentDeclarationAST *ObjCMessageArgumentDeclarationAST::clone(MemoryPool *pool) const { ObjCMessageArgumentDeclarationAST *ast = new (pool) ObjCMessageArgumentDeclarationAST; - ast->param_selector_token = param_selector_token; - ast->colon_token = colon_token; if (type_name) ast->type_name = type_name->clone(pool); if (attributes) ast->attributes = attributes->clone(pool); ast->param_name_token = param_name_token; diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index 9b43a34bfd7..dbf8d0a91d2 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1122,6 +1122,9 @@ void IdentifierListAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit IdentifierListAST + if (name) + accept(name, visitor); + // visit AST } visitor->endVisit(this); } @@ -1139,7 +1142,7 @@ void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } -void ObjCClassInterfaceDeclarationAST::accept0(ASTVisitor *visitor) +void ObjCClassInterfaceDefinitionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjCClassInterfaceDeclarationAST @@ -1189,6 +1192,8 @@ void ObjCProtocolDefinitionAST::accept0(ASTVisitor *visitor) // visit ObjCProtocolDefinitionAST for (SpecifierAST *it = attributes; it; it = it->next) accept(it, visitor); + if (name) + accept(name, visitor); if (protocol_refs) accept(protocol_refs, visitor); if (member_declarations) @@ -1277,14 +1282,53 @@ void ObjCEncodeExpressionAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void ObjCSelectorWithoutArgumentsAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + } + visitor->endVisit(this); +} + +void ObjCSelectorArgumentAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + } + visitor->endVisit(this); +} + +void ObjCSelectorArgumentListAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + if (argument) + accept(argument, visitor); + } + visitor->endVisit(this); +} + +void ObjCSelectorWithArgumentsAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + for (ObjCSelectorArgumentListAST *it = selector_arguments; it; it = it->next) + accept(it, visitor); + } + visitor->endVisit(this); +} + +void ObjCSelectorExpressionAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + if (selector) + accept(selector, visitor); + } + visitor->endVisit(this); +} + void ObjCInstanceVariablesDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjCInstanceVariablesDeclarationAST if (instance_variables) accept(instance_variables, visitor); - if (member_declarations) - accept(member_declarations, visitor); // visit AST } visitor->endVisit(this); @@ -1299,7 +1343,7 @@ void ObjCVisibilityDeclarationAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } -void ObjcPropertyAttributeAST::accept0(ASTVisitor *visitor) +void ObjCPropertyAttributeAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjcPropertyAttributeAST @@ -1308,7 +1352,7 @@ void ObjcPropertyAttributeAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } -void ObjcPropertyAttributeListAST::accept0(ASTVisitor *visitor) +void ObjCPropertyAttributeListAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { // visit ObjcPropertyAttributeListAST @@ -1325,7 +1369,7 @@ void ObjCPropertyDeclarationAST::accept0(ASTVisitor *visitor) // visit ObjCPropertyDeclarationAST: for (SpecifierAST *it = attributes; it; it = it->next) accept(it, visitor); - for (ObjcPropertyAttributeListAST *it = property_attributes; it; it = it->next) + for (ObjCPropertyAttributeListAST *it = property_attributes; it; it = it->next) accept(it, visitor); if (simple_declaration) accept(simple_declaration, visitor); diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index dc289fdcb5a..ebe28a83da0 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -198,7 +198,7 @@ public: // ObjC++ virtual bool visit(IdentifierListAST *) { return true; } virtual bool visit(ObjCClassDeclarationAST *) { return true; } - virtual bool visit(ObjCClassInterfaceDeclarationAST *) { return true; } + virtual bool visit(ObjCClassInterfaceDefinitionAST *) { return true; } virtual bool visit(ObjCCategoryInterfaceDeclarationAST *) { return true; } virtual bool visit(ObjCProtocolDeclarationAST *) { return true; } virtual bool visit(ObjCProtocolDefinitionAST *) { return true; } @@ -209,10 +209,15 @@ public: virtual bool visit(ObjCProtocolExpressionAST *) { return true; } virtual bool visit(ObjCTypeNameAST *) { return true; } virtual bool visit(ObjCEncodeExpressionAST *) { return true; } + virtual bool visit(ObjCSelectorWithoutArgumentsAST *) { return true; } + virtual bool visit(ObjCSelectorArgumentAST *) { return true; } + virtual bool visit(ObjCSelectorArgumentListAST *) { return true; } + virtual bool visit(ObjCSelectorWithArgumentsAST *) { return true; } + virtual bool visit(ObjCSelectorExpressionAST *) { return true; } virtual bool visit(ObjCInstanceVariablesDeclarationAST *) { return true; } virtual bool visit(ObjCVisibilityDeclarationAST *) { return true; } - virtual bool visit(ObjcPropertyAttributeAST *) { return true; } - virtual bool visit(ObjcPropertyAttributeListAST *) { return true; } + virtual bool visit(ObjCPropertyAttributeAST *) { return true; } + virtual bool visit(ObjCPropertyAttributeListAST *) { return true; } virtual bool visit(ObjCPropertyDeclarationAST *) { return true; } virtual bool visit(ObjCMethodPrototypeAST *) { return true; } virtual bool visit(ObjCMethodDeclarationAST *) { return true; } @@ -335,7 +340,7 @@ public: // ObjC++ virtual void endVisit(IdentifierListAST *) { } virtual void endVisit(ObjCClassDeclarationAST *) { } - virtual void endVisit(ObjCClassInterfaceDeclarationAST *) { } + virtual void endVisit(ObjCClassInterfaceDefinitionAST *) { } virtual void endVisit(ObjCCategoryInterfaceDeclarationAST *) { } virtual void endVisit(ObjCProtocolDeclarationAST *) { } virtual void endVisit(ObjCProtocolDefinitionAST *) { } @@ -346,10 +351,15 @@ public: virtual void endVisit(ObjCProtocolExpressionAST *) { } virtual void endVisit(ObjCTypeNameAST *) { } virtual void endVisit(ObjCEncodeExpressionAST *) { } + virtual void endVisit(ObjCSelectorWithoutArgumentsAST *) { } + virtual void endVisit(ObjCSelectorArgumentAST *) { } + virtual void endVisit(ObjCSelectorArgumentListAST *) { } + virtual void endVisit(ObjCSelectorWithArgumentsAST *) { } + virtual void endVisit(ObjCSelectorExpressionAST *) { } virtual void endVisit(ObjCInstanceVariablesDeclarationAST *) { } virtual void endVisit(ObjCVisibilityDeclarationAST *) { } - virtual void endVisit(ObjcPropertyAttributeAST *) { } - virtual void endVisit(ObjcPropertyAttributeListAST *) { } + virtual void endVisit(ObjCPropertyAttributeAST *) { } + virtual void endVisit(ObjCPropertyAttributeListAST *) { } virtual void endVisit(ObjCPropertyDeclarationAST *) { } virtual void endVisit(ObjCMethodPrototypeAST *) { } virtual void endVisit(ObjCMethodDeclarationAST *) { } diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index a6ad8261756..be29bc7eea8 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -173,7 +173,7 @@ class IdentifierListAST; class ObjCClassDeclarationAST; class ObjCProtocolDeclarationAST; class ObjCProtocolDefinitionAST; -class ObjCClassInterfaceDeclarationAST; +class ObjCClassInterfaceDefinitionAST; class ObjCCategoryInterfaceDeclarationAST; class ObjCProtocolRefsAST; class ObjCMessageExpressionAST; @@ -182,11 +182,17 @@ class ObjCMessageArgumentAST; class ObjCProtocolExpressionAST; class ObjCTypeNameAST; class ObjCEncodeExpressionAST; +class ObjCSelectorAST; +class ObjCSelectorWithoutArgumentsAST; +class ObjCSelectorArgumentAST; +class ObjCSelectorArgumentListAST; +class ObjCSelectorWithArgumentsAST; +class ObjCSelectorExpressionAST; class ObjCInstanceVariablesDeclarationAST; class ObjCVisibilityDeclarationAST; class ObjCPropertyDeclarationAST; -class ObjcPropertyAttributeListAST; -class ObjcPropertyAttributeAST; +class ObjCPropertyAttributeListAST; +class ObjCPropertyAttributeAST; class ObjCMethodPrototypeAST; class ObjCMethodDeclarationAST; class ObjCMethodDefinitionAST; diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h index a60d0fe10f7..76ee3061dc5 100644 --- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h @@ -133,6 +133,12 @@ class ForwardClassDeclaration; class Token; +// Objective-C symbols +class ObjCClass; +class ObjCForwardClassDeclaration; +class ObjCProtocol; +class ObjCForwardProtocolDeclaration; + CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_HEADER diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index 83fbc1dd0ef..1a9877db156 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 diff --git a/src/shared/cplusplus/CheckDeclaration.h b/src/shared/cplusplus/CheckDeclaration.h index 4abd8598479..97c4d5ff449 100644 --- a/src/shared/cplusplus/CheckDeclaration.h +++ b/src/shared/cplusplus/CheckDeclaration.h @@ -91,6 +91,13 @@ protected: virtual bool visit(UsingAST *ast); virtual bool visit(UsingDirectiveAST *ast); + virtual bool visit(ObjCProtocolDeclarationAST *ast); + virtual bool visit(ObjCProtocolDefinitionAST *ast); + virtual bool visit(ObjCClassDeclarationAST *ast); + virtual bool visit(ObjCClassInterfaceDefinitionAST *ast); + virtual bool visit(ObjCMethodDeclarationAST *ast); + virtual bool visit(ObjCVisibilityDeclarationAST *ast); + private: DeclarationAST *_declaration; Scope *_scope; diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp index bf9ae94cb97..27a0a03fc3d 100644 --- a/src/shared/cplusplus/CheckDeclarator.cpp +++ b/src/shared/cplusplus/CheckDeclarator.cpp @@ -94,6 +94,15 @@ FullySpecifiedType CheckDeclarator::check(PtrOperatorAST *ptrOperators, return switchFullySpecifiedType(previousType); } +FullySpecifiedType CheckDeclarator::check(ObjCMethodPrototypeAST *methodPrototype, + Scope *scope) +{ + Scope *previousScope = switchScope(scope); + accept(methodPrototype); + (void) switchScope(previousScope); + return _fullySpecifiedType; +} + DeclaratorAST *CheckDeclarator::switchDeclarator(DeclaratorAST *declarator) { DeclaratorAST *previousDeclarator = _declarator; @@ -237,6 +246,34 @@ bool CheckDeclarator::visit(ReferenceAST *ast) return false; } +bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast) +{ + unsigned location = ast->firstToken(); + + Name *name = semantic()->check(ast->selector, _scope); + + Function *fun = control()->newFunction(location, name); + ast->symbol = fun; + fun->setSourceLocation(location); + fun->setScope(_scope); + fun->setMethodKey(Function::NormalMethod); + fun->setVisibility(semantic()->currentVisibility()); + fun->setPureVirtual(false); + + // TODO: check return type (EV) +// fun->setReturnType(semantic()->check(ast->type_name, _scope)); + // TODO: check the parameters (EV) + // fun->setVariadic(...); + // TODO: add arguments (EV) + + FullySpecifiedType mTy(fun); + _fullySpecifiedType = mTy; + + // TODO: check which specifiers are allowed here (EV) + + return false; +} + void CheckDeclarator::applyCvQualifiers(SpecifierAST *cv) { for (; cv; cv = cv->next) { diff --git a/src/shared/cplusplus/CheckDeclarator.h b/src/shared/cplusplus/CheckDeclarator.h index 75d027f001b..1903c6e26a7 100644 --- a/src/shared/cplusplus/CheckDeclarator.h +++ b/src/shared/cplusplus/CheckDeclarator.h @@ -71,6 +71,9 @@ public: FullySpecifiedType type, Scope *scope); + FullySpecifiedType check(ObjCMethodPrototypeAST *methodPrototype, + Scope *scope); + protected: DeclaratorAST *switchDeclarator(DeclaratorAST *declarator); FullySpecifiedType switchFullySpecifiedType(FullySpecifiedType type); @@ -90,6 +93,8 @@ protected: // postfix declarators virtual bool visit(FunctionDeclaratorAST *ast); virtual bool visit(ArrayDeclaratorAST *ast); + // ObjC + virtual bool visit(ObjCMethodPrototypeAST *ast); void applyCvQualifiers(SpecifierAST *cv); diff --git a/src/shared/cplusplus/CheckName.cpp b/src/shared/cplusplus/CheckName.cpp index 8045ea9a961..c18a9f34002 100644 --- a/src/shared/cplusplus/CheckName.cpp +++ b/src/shared/cplusplus/CheckName.cpp @@ -97,6 +97,17 @@ Name *CheckName::check(NestedNameSpecifierAST *nested_name_specifier, Scope *sco return switchName(previousName); } +Name *CheckName::check(ObjCSelectorAST *args, Scope *scope) +{ + Name *previousName = switchName(0); + Scope *previousScope = switchScope(scope); + + accept(args); + + (void) switchScope(previousScope); + return switchName(previousName); +} + Name *CheckName::switchName(Name *name) { Name *previousName = _name; @@ -351,4 +362,28 @@ bool CheckName::visit(TemplateIdAST *ast) return false; } +bool CheckName::visit(ObjCSelectorWithoutArgumentsAST *ast) +{ + Identifier *id = identifier(ast->name_token); + _name = control()->nameId(id); + ast->selector_name = _name; + + return false; +} + +bool CheckName::visit(ObjCSelectorWithArgumentsAST *ast) +{ + std::vector<Name *> names; + for (ObjCSelectorArgumentListAST *it = ast->selector_arguments; it; it = it->next) { + Identifier *id = identifier(it->argument->name_token); + Name *name = control()->nameId(id); + + names.push_back(name); + } + _name = control()->qualifiedNameId(&names[0], names.size(), false); + ast->selector_name = _name; + + return false; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/CheckName.h b/src/shared/cplusplus/CheckName.h index 4d12497988e..21bd550a7c4 100644 --- a/src/shared/cplusplus/CheckName.h +++ b/src/shared/cplusplus/CheckName.h @@ -63,6 +63,7 @@ public: Name *check(NameAST *name, Scope *scope); Name *check(NestedNameSpecifierAST *name, Scope *scope); + Name *check(ObjCSelectorAST *args, Scope *scope); protected: Name *switchName(Name *name); @@ -77,6 +78,10 @@ protected: virtual bool visit(DestructorNameAST *ast); virtual bool visit(TemplateIdAST *ast); + // ObjC + virtual bool visit(ObjCSelectorWithoutArgumentsAST *ast); + virtual bool visit(ObjCSelectorWithArgumentsAST *ast); + private: Name *_name; Scope *_scope; diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp index fe94d79d824..49f965f7da3 100644 --- a/src/shared/cplusplus/Control.cpp +++ b/src/shared/cplusplus/Control.cpp @@ -121,6 +121,10 @@ public: delete_array_entries(enums); delete_array_entries(usingDeclarations); delete_array_entries(classForwardDeclarations); + delete_array_entries(objcClasses); + delete_array_entries(objcProtocols); + delete_array_entries(objcForwardClassDeclarations); + delete_array_entries(objcForwardProtocolDeclarations); } NameId *findOrInsertNameId(Identifier *id) @@ -327,6 +331,34 @@ public: return c; } + ObjCClass *newObjCClass(unsigned sourceLocation, Name *name) + { + ObjCClass *c = new ObjCClass(translationUnit, sourceLocation, name); + objcClasses.push_back(c); + return c; + } + + ObjCForwardClassDeclaration *newObjCForwardClassDeclaration(unsigned sourceLocation, Name *name) + { + ObjCForwardClassDeclaration *fwd = new ObjCForwardClassDeclaration(translationUnit, sourceLocation, name); + objcForwardClassDeclarations.push_back(fwd); + return fwd; + } + + ObjCProtocol *newObjCProtocol(unsigned sourceLocation, Name *name) + { + ObjCProtocol *p = new ObjCProtocol(translationUnit, sourceLocation, name); + objcProtocols.push_back(p); + return p; + } + + ObjCForwardProtocolDeclaration *newObjCForwardProtocolDeclaration(unsigned sourceLocation, Name *name) + { + ObjCForwardProtocolDeclaration *fwd = new ObjCForwardProtocolDeclaration(translationUnit, sourceLocation, name); + objcForwardProtocolDeclarations.push_back(fwd); + return fwd; + } + Enum *newEnum(unsigned sourceLocation, Name *name) { Enum *e = new Enum(translationUnit, @@ -482,6 +514,10 @@ public: std::vector<Enum *> enums; std::vector<UsingDeclaration *> usingDeclarations; std::vector<ForwardClassDeclaration *> classForwardDeclarations; + std::vector<ObjCClass *> objcClasses; + std::vector<ObjCProtocol *> objcProtocols; + std::vector<ObjCForwardClassDeclaration *> objcForwardClassDeclarations; + std::vector<ObjCForwardProtocolDeclaration *> objcForwardProtocolDeclarations; }; Control::Control() @@ -638,5 +674,16 @@ ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLoca Name *name) { return d->newForwardClassDeclaration(sourceLocation, name); } +ObjCClass *Control::newObjCClass(unsigned sourceLocation, Name *name) +{ return d->newObjCClass(sourceLocation, name); } + +ObjCForwardClassDeclaration *Control::newObjCForwardClassDeclaration(unsigned sourceLocation, Name *name) +{ return d->newObjCForwardClassDeclaration(sourceLocation, name); } + +ObjCProtocol *Control::newObjCProtocol(unsigned sourceLocation, Name *name) +{ return d->newObjCProtocol(sourceLocation, name); } + +ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(unsigned sourceLocation, Name *name) +{ return d->newObjCForwardProtocolDeclaration(sourceLocation, name); } CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h index 8b4f09afffb..a9b85b7baee 100644 --- a/src/shared/cplusplus/Control.h +++ b/src/shared/cplusplus/Control.h @@ -147,6 +147,18 @@ public: /// Creates a new ForwardClassDeclaration symbol. ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, Name *name = 0); + /// Creates a new Objective-C class symbol. + ObjCClass *newObjCClass(unsigned sourceLocation, Name *name = 0); + + /// Creates a new Objective-C class forward declaration symbol. + ObjCForwardClassDeclaration *newObjCForwardClassDeclaration(unsigned sourceLocation, Name *name = 0); + + /// Creates a new Objective-C protocol symbol. + ObjCProtocol *newObjCProtocol(unsigned sourceLocation, Name *name = 0); + + /// Creates a new Objective-C protocol forward declaration symbol. + ObjCForwardProtocolDeclaration *newObjCForwardProtocolDeclaration(unsigned sourceLocation, Name *name = 0); + Identifier *findOrInsertIdentifier(const char *chars, unsigned size); Identifier *findOrInsertIdentifier(const char *chars); diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 616d2ed3e2a..b7151055a33 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -2894,48 +2894,41 @@ bool Parser::parseObjCProtocolExpression(ExpressionAST *&node) return true; } -bool Parser::parseObjCSelectorExpression(ExpressionAST *&) +bool Parser::parseObjCSelectorExpression(ExpressionAST *&node) { if (LA() != T_AT_SELECTOR) return false; - /*unsigned selector_token = */consumeToken(); - unsigned lparen_token = 0, rparen_token = 0; - match(T_LPAREN, &lparen_token); - - if (LA() == T_COLON || LA() == T_COLON_COLON) { - consumeToken(); - - if (LA() == T_RPAREN) { - _translationUnit->warning(cursor(), - "error expended a selector"); - match(T_RPAREN, &rparen_token); - return true; - } - } else if (lookAtObjCSelector()) { - unsigned start = cursor(); - consumeToken(); - if (LA() != T_RPAREN) - rewind(start); - else { - match(T_RPAREN, &rparen_token); - return true; - } - } + ObjCSelectorExpressionAST *ast = new (_pool) ObjCSelectorExpressionAST; + ast->selector_token = consumeToken(); + match(T_LPAREN, &(ast->lparen_token)); - while (lookAtObjCSelector()) { - unsigned selector_token = 0; - parseObjCSelector(selector_token); - if (LA() == T_COLON) - consumeToken(); - else { - _translationUnit->error(cursor(), - "expected :"); - break; + unsigned identifier_token = 0; + match(T_IDENTIFIER, &identifier_token); + if (LA() == T_COLON) { + ObjCSelectorWithArgumentsAST *args = new (_pool) ObjCSelectorWithArgumentsAST; + ast->selector = args; + ObjCSelectorArgumentListAST *last = new (_pool) ObjCSelectorArgumentListAST; + args->selector_arguments = last; + last->argument = new (_pool) ObjCSelectorArgumentAST; + last->argument->name_token = identifier_token; + last->argument->colon_token = consumeToken(); + + while (LA() != T_RPAREN) { + last->next = new (_pool) ObjCSelectorArgumentListAST; + last = last->next; + last->argument = new (_pool) ObjCSelectorArgumentAST; + match(T_IDENTIFIER, &(last->argument->name_token)); + match(T_COLON, &(last->argument->colon_token)); } + } else { + ObjCSelectorWithoutArgumentsAST *args = new (_pool) ObjCSelectorWithoutArgumentsAST; + ast->selector = args; + args->name_token = identifier_token; } - match(T_RPAREN, &rparen_token); + match(T_RPAREN, &(ast->rparen_token)); + node = ast; return true; } @@ -3923,7 +3916,8 @@ bool Parser::parseObjCClassDeclaration(DeclarationAST *&node) match(T_IDENTIFIER, &identifier_token); ast->identifier_list = new (_pool) IdentifierListAST; - ast->identifier_list->identifier_token = identifier_token; + ast->identifier_list->name = new (_pool) SimpleNameAST; + ast->identifier_list->name->identifier_token = identifier_token; IdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { @@ -3932,7 +3926,8 @@ bool Parser::parseObjCClassDeclaration(DeclarationAST *&node) *nextId = new (_pool) IdentifierListAST; (*nextId)->comma_token = comma_token; - (*nextId)->identifier_token = identifier_token; + (*nextId)->name = new (_pool) SimpleNameAST; + (*nextId)->name->identifier_token = identifier_token; nextId = &((*nextId)->next); } @@ -4006,10 +4001,11 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, return true; } else { // a class interface declaration - ObjCClassInterfaceDeclarationAST *ast = new (_pool) ObjCClassInterfaceDeclarationAST; + ObjCClassInterfaceDefinitionAST *ast = new (_pool) ObjCClassInterfaceDefinitionAST; ast->attributes = attributes; ast->interface_token = objc_interface_token; - ast->class_identifier_token = identifier_token; + ast->class_name = new (_pool) SimpleNameAST; + ast->class_name->identifier_token = identifier_token; if (LA() == T_COLON) { ast->colon_token = consumeToken(); @@ -4059,7 +4055,8 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, ast->attributes = attributes; ast->protocol_token = protocol_token; ast->identifier_list = new (_pool) IdentifierListAST; - ast->identifier_list->identifier_token = identifier_token; + ast->identifier_list->name = new (_pool) SimpleNameAST; + ast->identifier_list->name->identifier_token = identifier_token; IdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { @@ -4068,7 +4065,8 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, *nextId = new (_pool) IdentifierListAST; (*nextId)->comma_token = comma_token; - (*nextId)->identifier_token = identifier_token; + (*nextId)->name = new (_pool) SimpleNameAST; + (*nextId)->name->identifier_token = identifier_token; nextId = &((*nextId)->next); } @@ -4080,7 +4078,8 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, ObjCProtocolDefinitionAST *ast = new (_pool) ObjCProtocolDefinitionAST; ast->attributes = attributes; ast->protocol_token = protocol_token; - ast->identifier_token = identifier_token; + ast->name = new (_pool) SimpleNameAST; + ast->name->identifier_token = identifier_token; parseObjCProtocolRefs(ast->protocol_refs); @@ -4206,14 +4205,16 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST; ast->dynamic_token = consumeToken(); ast->property_identifiers = new (_pool) IdentifierListAST; - match(T_IDENTIFIER, &(ast->property_identifiers->identifier_token)); + ast->property_identifiers->name = new (_pool) SimpleNameAST; + match(T_IDENTIFIER, &(ast->property_identifiers->name->identifier_token)); IdentifierListAST *last = ast->property_identifiers; while (LA() == T_COMMA) { last->comma_token = consumeToken(); last->next = new (_pool) IdentifierListAST; last = last->next; - match(T_IDENTIFIER, &(last->identifier_token)); + last->name = new (_pool) SimpleNameAST; + match(T_IDENTIFIER, &(last->name->identifier_token)); } match(T_SEMICOLON, &(ast->semicolon_token)); @@ -4284,7 +4285,8 @@ bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node) unsigned identifier_token = 0; match(T_IDENTIFIER, &identifier_token); ast->identifier_list = new (_pool) IdentifierListAST; - ast->identifier_list->identifier_token = identifier_token; + ast->identifier_list->name = new (_pool) SimpleNameAST; + ast->identifier_list->name->identifier_token = identifier_token; IdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { @@ -4293,7 +4295,8 @@ bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node) *nextId = new (_pool) IdentifierListAST; (*nextId)->comma_token = comma_token; - (*nextId)->identifier_token = identifier_token; + (*nextId)->name = new (_pool) SimpleNameAST; + (*nextId)->name->identifier_token = identifier_token; nextId = &((*nextId)->next); } @@ -4422,15 +4425,15 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *a if (LA() == T_LPAREN) { match(T_LPAREN, &(ast->lparen_token)); - ObjcPropertyAttributeAST *property_attribute = 0; + ObjCPropertyAttributeAST *property_attribute = 0; if (parseObjCPropertyAttribute(property_attribute)) { - ast->property_attributes = new (_pool) ObjcPropertyAttributeListAST; + ast->property_attributes = new (_pool) ObjCPropertyAttributeListAST; ast->property_attributes->attr = property_attribute; - ObjcPropertyAttributeListAST *last = ast->property_attributes; + ObjCPropertyAttributeListAST *last = ast->property_attributes; while (LA() == T_COMMA) { last->comma_token = consumeToken(); - last->next = new (_pool) ObjcPropertyAttributeListAST; + last->next = new (_pool) ObjCPropertyAttributeListAST; last = last->next; parseObjCPropertyAttribute(last->attr); } @@ -4461,17 +4464,28 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) parseObjCTypeName(ast->type_name); if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) { + ObjCSelectorArgumentAST *argument = 0; ObjCMessageArgumentDeclarationAST *declaration = 0; - parseObjCKeywordDeclaration(declaration); + parseObjCKeywordDeclaration(argument, declaration); + + ObjCSelectorWithArgumentsAST *sel = new (_pool) ObjCSelectorWithArgumentsAST; + ast->selector = sel; + ObjCSelectorArgumentListAST *lastSel = new (_pool) ObjCSelectorArgumentListAST; + sel->selector_arguments = lastSel; + sel->selector_arguments->argument = argument; ast->arguments = new (_pool) ObjCMessageArgumentDeclarationListAST; ast->arguments->argument_declaration = declaration; - ObjCMessageArgumentDeclarationListAST **last = &(ast->arguments); + ObjCMessageArgumentDeclarationListAST *lastArg = ast->arguments; + + while (parseObjCKeywordDeclaration(argument, declaration)) { + lastSel->next = new (_pool) ObjCSelectorArgumentListAST; + lastSel = lastSel->next; + lastSel->argument = argument; - while (parseObjCKeywordDeclaration(declaration)) { - (*last)->next = new (_pool) ObjCMessageArgumentDeclarationListAST; - last = &((*last)->next); - (*last)->argument_declaration = declaration; + lastArg->next = new (_pool) ObjCMessageArgumentDeclarationListAST; + lastArg = lastArg->next; + lastArg->argument_declaration = declaration; } // TODO EV: get this in the ast @@ -4487,9 +4501,9 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) parseParameterDeclaration(parameter_declaration); } } else if (lookAtObjCSelector()) { - ast->arguments = new (_pool) ObjCMessageArgumentDeclarationListAST; - ast->arguments->argument_declaration = new (_pool) ObjCMessageArgumentDeclarationAST; - parseObjCSelector(ast->arguments->argument_declaration->param_selector_token); + ObjCSelectorWithoutArgumentsAST *sel = new (_pool) ObjCSelectorWithoutArgumentsAST; + parseObjCSelector(sel->name_token); + ast->selector = sel; } else { _translationUnit->error(cursor(), "expected a selector"); } @@ -4510,18 +4524,31 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) // objc-property-attribute ::= retain // objc-property-attribute ::= copy // objc-property-attribute ::= nonatomic -bool Parser::parseObjCPropertyAttribute(ObjcPropertyAttributeAST *&node) +bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node) { if (LA() != T_IDENTIFIER) return false; - node = new (_pool) ObjcPropertyAttributeAST; + node = new (_pool) ObjCPropertyAttributeAST; match(T_IDENTIFIER, &(node->attribute_identifier_token)); if (LA() == T_EQUAL) { node->equals_token = consumeToken(); - match(T_IDENTIFIER, &(node->method_selector_identifier_token)); - if (LA() == T_COLON) - node->colon_token = consumeToken(); + + unsigned identifier_token = 0; + match(T_IDENTIFIER, &identifier_token); + + if (LA() == T_COLON) { + ObjCSelectorWithArgumentsAST *selector = new (_pool) ObjCSelectorWithArgumentsAST; + selector->selector_arguments = new (_pool) ObjCSelectorArgumentListAST; + selector->selector_arguments->argument = new (_pool) ObjCSelectorArgumentAST; + selector->selector_arguments->argument->name_token = identifier_token; + selector->selector_arguments->argument->colon_token = consumeToken(); + node->method_selector = selector; + } else { + ObjCSelectorWithoutArgumentsAST *selector = new (_pool) ObjCSelectorWithoutArgumentsAST; + selector->name_token = identifier_token; + node->method_selector = selector; + } } return true; @@ -4556,24 +4583,25 @@ bool Parser::parseObjCSelector(unsigned &selector_token) // objc-keyword-decl ::= objc-selector? T_COLON objc-type-name? objc-keyword-attributes-opt T_IDENTIFIER // -bool Parser::parseObjCKeywordDeclaration(ObjCMessageArgumentDeclarationAST *&node) +bool Parser::parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, ObjCMessageArgumentDeclarationAST *&node) { if (! (LA() == T_COLON || (lookAtObjCSelector() && LA(2) == T_COLON))) return false; - ObjCMessageArgumentDeclarationAST *ast = new (_pool) ObjCMessageArgumentDeclarationAST; + node = new (_pool) ObjCMessageArgumentDeclarationAST; + argument = new (_pool) ObjCSelectorArgumentAST; - parseObjCSelector(ast->param_selector_token); - match(T_COLON, &(ast->colon_token)); - parseObjCTypeName(ast->type_name); + parseObjCSelector(argument->name_token); + match(T_COLON, &(argument->colon_token)); - SpecifierAST **attr = &(ast->attributes); + parseObjCTypeName(node->type_name); + + SpecifierAST **attr = &(node->attributes); while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; - match(T_IDENTIFIER, &(ast->param_name_token)); + match(T_IDENTIFIER, &(node->param_name_token)); - node = ast; return true; } diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index 5fd5253e348..2fc12384f24 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -239,10 +239,10 @@ public: SpecifierAST *attributes = 0); bool parseObjCImplementation(DeclarationAST *&node); bool parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node); - bool parseObjCPropertyAttribute(ObjcPropertyAttributeAST *&node); + bool parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node); bool parseObjCTypeName(ObjCTypeNameAST *&node); bool parseObjCSelector(unsigned &selector_token); - bool parseObjCKeywordDeclaration(ObjCMessageArgumentDeclarationAST *&node); + bool parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, ObjCMessageArgumentDeclarationAST *&node); bool parseObjCTypeQualifiers(unsigned &type_qualifier); bool parseObjCContextKeyword(int kind, unsigned &in_token); diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp index 6f44072302e..23e69decd00 100644 --- a/src/shared/cplusplus/Semantic.cpp +++ b/src/shared/cplusplus/Semantic.cpp @@ -69,6 +69,7 @@ public: control(control), skipFunctionBodies(false), visibility(Symbol::Public), + ojbcVisibility(Symbol::Protected), methodKey(Function::NormalMethod), checkSpecifier(0), checkDeclaration(0), @@ -92,6 +93,7 @@ public: Control *control; bool skipFunctionBodies; int visibility; + int ojbcVisibility; int methodKey; CheckSpecifier *checkSpecifier; CheckDeclaration *checkDeclaration; @@ -132,6 +134,9 @@ FullySpecifiedType Semantic::check(PtrOperatorAST *ptrOperators, FullySpecifiedT Scope *scope) { return d->checkDeclarator->check(ptrOperators, type, scope); } +FullySpecifiedType Semantic::check(ObjCMethodPrototypeAST *methodPrototype, Scope *scope) +{ return d->checkDeclarator->check(methodPrototype, scope); } + FullySpecifiedType Semantic::check(ExpressionAST *expression, Scope *scope) { return d->checkExpression->check(expression, scope); } @@ -144,6 +149,9 @@ Name *Semantic::check(NameAST *name, Scope *scope) Name *Semantic::check(NestedNameSpecifierAST *name, Scope *scope) { return d->checkName->check(name, scope); } +Name *Semantic::check(ObjCSelectorAST *args, Scope *scope) +{ return d->checkName->check(args, scope); } + bool Semantic::skipFunctionBodies() const { return d->skipFunctionBodies; } @@ -160,6 +168,16 @@ int Semantic::switchVisibility(int visibility) return previousVisibility; } +int Semantic::currentObjCVisibility() const +{ return d->ojbcVisibility; } + +int Semantic::switchObjCVisibility(int visibility) +{ + int previousOjbCVisibility = d->ojbcVisibility; + d->ojbcVisibility = visibility; + return previousOjbCVisibility; +} + int Semantic::currentMethodKey() const { return d->methodKey; } @@ -186,6 +204,35 @@ int Semantic::visibilityForAccessSpecifier(int tokenKind) const } } +int Semantic::visibilityForObjCAccessSpecifier(int tokenKind) const +{ + switch (tokenKind) { + case T_AT_PUBLIC: + return Symbol::Public; + case T_AT_PROTECTED: + return Symbol::Protected; + case T_AT_PRIVATE: + return Symbol::Private; + case T_AT_PACKAGE: + return Symbol::Package; + default: + return Symbol::Protected; + } +} + +bool Semantic::isObjCClassMethod(int tokenKind) const +{ + switch (tokenKind) { + case T_PLUS: + return true; + case T_MINUS: + return false; + default: + // TODO EV: assert here? + return false; + } +} + int Semantic::visibilityForClassKey(int tokenKind) const { switch (tokenKind) { diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h index 9b9a4195be8..113796bafb2 100644 --- a/src/shared/cplusplus/Semantic.h +++ b/src/shared/cplusplus/Semantic.h @@ -74,6 +74,8 @@ public: FullySpecifiedType check(PtrOperatorAST *ptrOperators, FullySpecifiedType type, Scope *scope); + FullySpecifiedType check(ObjCMethodPrototypeAST *methodPrototype, Scope *scope); + FullySpecifiedType check(ExpressionAST *expression, Scope *scope); void check(DeclarationAST *declaration, Scope *scope, Scope *templateParameters = 0); @@ -84,17 +86,24 @@ public: Name *check(NestedNameSpecifierAST *name, Scope *scope); + Name *check(ObjCSelectorAST *args, Scope *scope); + bool skipFunctionBodies() const; void setSkipFunctionBodies(bool skipFunctionBodies); int currentVisibility() const; int switchVisibility(int visibility); + int currentObjCVisibility() const; + int switchObjCVisibility(int visibility); + int currentMethodKey() const; int switchMethodKey(int methodKey); int visibilityForClassKey(int tokenKind) const; int visibilityForAccessSpecifier(int tokenKind) const; + int visibilityForObjCAccessSpecifier(int tokenKind) const; + bool isObjCClassMethod(int tokenKind) const; private: class Data; diff --git a/src/shared/cplusplus/Symbol.cpp b/src/shared/cplusplus/Symbol.cpp index 31c33039255..37909bf98b1 100644 --- a/src/shared/cplusplus/Symbol.cpp +++ b/src/shared/cplusplus/Symbol.cpp @@ -453,4 +453,16 @@ bool Symbol::isArgument() const bool Symbol::isBaseClass() const { return asBaseClass() != 0; } +bool Symbol::isObjCClass() const +{ return asObjCClass() != 0; } + +bool Symbol::isObjCForwardClassDeclaration() const +{ return asObjCForwardClassDeclaration() != 0; } + +bool Symbol::isObjCProtocol() const +{ return asObjCProtocol() != 0; } + +bool Symbol::isObjCForwardProtocolDeclaration() const +{ return asObjCForwardProtocolDeclaration() != 0; } + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h index 403deceb123..c34416078d8 100644 --- a/src/shared/cplusplus/Symbol.h +++ b/src/shared/cplusplus/Symbol.h @@ -75,7 +75,8 @@ public: enum Visibility { Public, Protected, - Private + Private, + Package }; public: @@ -209,6 +210,18 @@ public: /// Returns true if this Symbol is a ForwardClassDeclaration. bool isForwardClassDeclaration() const; + /// Returns true if this Symbol is a Objective-C Class definition. + bool isObjCClass() const; + + /// Returns true if this Symbol is a Objective-C Class forward declaration. + bool isObjCForwardClassDeclaration() const; + + /// Returns true if this Symbol is a Objective-C Protocol definition. + bool isObjCProtocol() const; + + /// Returns true if this Symbol is a Objective-C Protocol forward declaration. + bool isObjCForwardProtocolDeclaration() const; + virtual const ScopedSymbol *asScopedSymbol() const { return 0; } virtual const Enum *asEnum() const { return 0; } virtual const Function *asFunction() const { return 0; } @@ -221,6 +234,10 @@ public: virtual const Argument *asArgument() const { return 0; } virtual const BaseClass *asBaseClass() const { return 0; } virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return 0; } + virtual const ObjCClass *asObjCClass() const { return 0; } + virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const { return 0; } + virtual const ObjCProtocol *asObjCProtocol() const { return 0; } + virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return 0; } virtual ScopedSymbol *asScopedSymbol() { return 0; } virtual Enum *asEnum() { return 0; } @@ -234,6 +251,10 @@ public: virtual Argument *asArgument() { return 0; } virtual BaseClass *asBaseClass() { return 0; } virtual ForwardClassDeclaration *asForwardClassDeclaration() { return 0; } + virtual ObjCClass *asObjCClass() { return 0; } + virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() { return 0; } + virtual ObjCProtocol *asObjCProtocol() { return 0; } + virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return 0; } /// Returns this Symbol's type. virtual FullySpecifiedType type() const = 0; diff --git a/src/shared/cplusplus/SymbolVisitor.h b/src/shared/cplusplus/SymbolVisitor.h index 552dd05052c..cfac498887b 100644 --- a/src/shared/cplusplus/SymbolVisitor.h +++ b/src/shared/cplusplus/SymbolVisitor.h @@ -79,6 +79,12 @@ public: virtual bool visit(Class *) { return true; } virtual bool visit(Block *) { return true; } virtual bool visit(ForwardClassDeclaration *) { return true; } + + // Objective-C + virtual bool visit(ObjCClass *) { return true; } + virtual bool visit(ObjCForwardClassDeclaration *) { return true; } + virtual bool visit(ObjCProtocol *) { return true; } + virtual bool visit(ObjCForwardProtocolDeclaration *) { return true; } }; CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp index dddc1539288..d7446f98525 100644 --- a/src/shared/cplusplus/Symbols.cpp +++ b/src/shared/cplusplus/Symbols.cpp @@ -553,4 +553,138 @@ void Class::visitSymbol0(SymbolVisitor *visitor) } } +ObjCClass::ObjCClass(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name): + ScopedSymbol(translationUnit, sourceLocation, name) +{ +} + +ObjCClass::~ObjCClass() +{} + +FullySpecifiedType ObjCClass::type() const +{ return FullySpecifiedType(const_cast<ObjCClass *>(this)); } + +bool ObjCClass::isEqualTo(const Type *other) const +{ + const ObjCClass *o = other->asObjCClassType(); + if (!o) + return false; + + Name *l = identity(); + Name *r = o->identity(); + if (l == r || (l && l->isEqualTo(r))) + return true; + else + return false; +} + +void ObjCClass::visitSymbol0(SymbolVisitor *visitor) +{ + if (visitor->visit(this)) { + for (unsigned i = 0; i < _baseClasses.size(); ++i) + visitSymbol(_baseClasses.at(i), visitor); + for (unsigned i = 0; i < _protocols.size(); ++i) + visitSymbol(_protocols.at(i), visitor); + } +} + +void ObjCClass::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + +ObjCProtocol::ObjCProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name): + ScopedSymbol(translationUnit, sourceLocation, name) +{ +} + +ObjCProtocol::~ObjCProtocol() +{} + +FullySpecifiedType ObjCProtocol::type() const +{ return FullySpecifiedType(const_cast<ObjCProtocol *>(this)); } + +bool ObjCProtocol::isEqualTo(const Type *other) const +{ + const ObjCProtocol *o = other->asObjCProtocolType(); + if (!o) + return false; + + Name *l = identity(); + Name *r = o->identity(); + if (l == r || (l && l->isEqualTo(r))) + return true; + else + return false; +} + +void ObjCProtocol::visitSymbol0(SymbolVisitor *visitor) +{ + if (visitor->visit(this)) { + for (unsigned i = 0; i < _protocols.size(); ++i) + visitSymbol(_protocols.at(i), visitor); + } +} + +void ObjCProtocol::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + +ObjCForwardClassDeclaration::ObjCForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name): + Symbol(translationUnit, sourceLocation, name) +{ +} + +ObjCForwardClassDeclaration::~ObjCForwardClassDeclaration() +{} + +FullySpecifiedType ObjCForwardClassDeclaration::type() const +{ return FullySpecifiedType(const_cast<ObjCForwardClassDeclaration *>(this)); } + +bool ObjCForwardClassDeclaration::isEqualTo(const Type *other) const +{ + if (const ObjCForwardClassDeclaration *otherForward = other->asObjCForwardClassDeclarationType()) { + if (name() == otherForward->name()) + return true; + else if (name() && otherForward->name()) + return name()->isEqualTo(otherForward->name()); + + return false; + } + return false; +} + +void ObjCForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor) +{ visitor->visit(this); } + +void ObjCForwardClassDeclaration::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + +ObjCForwardProtocolDeclaration::ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name): + Symbol(translationUnit, sourceLocation, name) +{ +} + +ObjCForwardProtocolDeclaration::~ObjCForwardProtocolDeclaration() +{} + +FullySpecifiedType ObjCForwardProtocolDeclaration::type() const +{ return FullySpecifiedType(const_cast<ObjCForwardProtocolDeclaration *>(this)); } + +bool ObjCForwardProtocolDeclaration::isEqualTo(const Type *other) const +{ + if (const ObjCForwardProtocolDeclaration *otherForward = other->asObjCForwardProtocolDeclarationType()) { + if (name() == otherForward->name()) + return true; + else if (name() && otherForward->name()) + return name()->isEqualTo(otherForward->name()); + + return false; + } + return false; +} + +void ObjCForwardProtocolDeclaration::visitSymbol0(SymbolVisitor *visitor) +{ visitor->visit(this); } + +void ObjCForwardProtocolDeclaration::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h index 03a66778d74..a35dbf30b56 100644 --- a/src/shared/cplusplus/Symbols.h +++ b/src/shared/cplusplus/Symbols.h @@ -463,6 +463,133 @@ private: Array<BaseClass *> _baseClasses; }; +class CPLUSPLUS_EXPORT ObjCForwardProtocolDeclaration: public Symbol, public Type +{ +public: + ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name); + virtual ~ObjCForwardProtocolDeclaration(); + + // Symbol's interface + virtual FullySpecifiedType type() const; + + // Type's interface + virtual bool isEqualTo(const Type *other) const; + + virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const + { return this; } + + virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() + { return this; } + + virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() const + { return this; } + + virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); + +private: +}; + +class CPLUSPLUS_EXPORT ObjCProtocol: public ScopedSymbol, public Type +{ +public: + ObjCProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name); + virtual ~ObjCProtocol(); + + // Symbol's interface + virtual FullySpecifiedType type() const; + + // Type's interface + virtual bool isEqualTo(const Type *other) const; + + virtual const ObjCProtocol *asObjCProtocol() const + { return this; } + + virtual ObjCProtocol *asObjCProtocol() + { return this; } + + virtual const ObjCProtocol *asObjCProtocolType() const + { return this; } + + virtual ObjCProtocol *asObjCProtocolType() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); + +private: + Array<ObjCProtocol *> _protocols; +}; + +class CPLUSPLUS_EXPORT ObjCForwardClassDeclaration: public Symbol, public Type +{ +public: + ObjCForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name); + virtual ~ObjCForwardClassDeclaration(); + + // Symbol's interface + virtual FullySpecifiedType type() const; + + // Type's interface + virtual bool isEqualTo(const Type *other) const; + + virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const + { return this; } + + virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() + { return this; } + + virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() const + { return this; } + + virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); + +private: +}; + +class CPLUSPLUS_EXPORT ObjCClass: public ScopedSymbol, public Type +{ +public: + ObjCClass(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name); + virtual ~ObjCClass(); + + // Symbol's interface + virtual FullySpecifiedType type() const; + + // Type's interface + virtual bool isEqualTo(const Type *other) const; + + virtual const ObjCClass *asObjCClass() const + { return this; } + + virtual ObjCClass *asObjCClass() + { return this; } + + virtual const ObjCClass *asObjCClassType() const + { return this; } + + virtual ObjCClass *asObjCClassType() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); + +private: + Array<ObjCClass *> _baseClasses; + Array<ObjCProtocol *> _protocols; +}; + CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_HEADER diff --git a/src/shared/cplusplus/Type.cpp b/src/shared/cplusplus/Type.cpp index 5f5809c0c64..8b41f36407e 100644 --- a/src/shared/cplusplus/Type.cpp +++ b/src/shared/cplusplus/Type.cpp @@ -101,6 +101,18 @@ bool Type::isEnumType() const bool Type::isForwardClassDeclarationType() const { return asForwardClassDeclarationType() != 0; } +bool Type::isObjCClassType() const +{ return asObjCClassType() != 0; } + +bool Type::isObjCForwardClassDeclarationType() const +{ return asObjCForwardClassDeclarationType() != 0; } + +bool Type::isObjCProtocolType() const +{ return asObjCProtocolType() != 0; } + +bool Type::isObjCForwardProtocolDeclarationType() const +{ return asObjCForwardProtocolDeclarationType() != 0; } + void Type::accept(TypeVisitor *visitor) { if (visitor->preVisit(this)) diff --git a/src/shared/cplusplus/Type.h b/src/shared/cplusplus/Type.h index a0067bd0965..1ddc67eb58a 100644 --- a/src/shared/cplusplus/Type.h +++ b/src/shared/cplusplus/Type.h @@ -77,6 +77,10 @@ public: bool isClassType() const; bool isEnumType() const; bool isForwardClassDeclarationType() const; + bool isObjCClassType() const; + bool isObjCForwardClassDeclarationType() const; + bool isObjCProtocolType() const; + bool isObjCForwardProtocolDeclarationType() const; virtual const VoidType *asVoidType() const { return 0; } virtual const IntegerType *asIntegerType() const { return 0; } @@ -91,6 +95,10 @@ public: virtual const Class *asClassType() const { return 0; } virtual const Enum *asEnumType() const { return 0; } virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; } + virtual const ObjCClass *asObjCClassType() const { return 0; } + virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() const { return 0; } + virtual const ObjCProtocol *asObjCProtocolType() const { return 0; } + virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() const { return 0; } virtual VoidType *asVoidType() { return 0; } virtual IntegerType *asIntegerType() { return 0; } @@ -105,6 +113,10 @@ public: virtual Class *asClassType() { return 0; } virtual Enum *asEnumType() { return 0; } virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; } + virtual ObjCClass *asObjCClassType() { return 0; } + virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() { return 0; } + virtual ObjCProtocol *asObjCProtocoTypel() { return 0; } + virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() { return 0; } void accept(TypeVisitor *visitor); static void accept(Type *type, TypeVisitor *visitor); diff --git a/src/shared/cplusplus/TypeVisitor.h b/src/shared/cplusplus/TypeVisitor.h index a29af362db7..a0de7065570 100644 --- a/src/shared/cplusplus/TypeVisitor.h +++ b/src/shared/cplusplus/TypeVisitor.h @@ -81,6 +81,10 @@ public: virtual void visit(Class *) {} virtual void visit(Enum *) {} virtual void visit(ForwardClassDeclaration *) {} + virtual void visit(ObjCClass *) {} + virtual void visit(ObjCProtocol *) {} + virtual void visit(ObjCForwardClassDeclaration *) {} + virtual void visit(ObjCForwardProtocolDeclaration *) {} }; CPLUSPLUS_END_NAMESPACE -- GitLab