diff options
author | Roberto Raggi <[email protected]> | 2009-02-16 15:43:24 +0100 |
---|---|---|
committer | Roberto Raggi <[email protected]> | 2009-02-16 18:20:46 +0100 |
commit | ba78e075da3919aafd2afdb8508952115f713c36 (patch) | |
tree | de94307448655b215342d82ec6f9fe5b728c4717 /src/shared | |
parent | 2788d77229dbecdeae293f8e3edff70f39750e63 (diff) |
Introduced support for forward class declarations.
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/cplusplus/CPlusPlusForwardDeclarations.h | 1 | ||||
-rw-r--r-- | src/shared/cplusplus/CheckDeclaration.cpp | 17 | ||||
-rw-r--r-- | src/shared/cplusplus/Control.cpp | 15 | ||||
-rw-r--r-- | src/shared/cplusplus/Control.h | 3 | ||||
-rw-r--r-- | src/shared/cplusplus/Symbol.cpp | 3 | ||||
-rw-r--r-- | src/shared/cplusplus/Symbol.h | 5 | ||||
-rw-r--r-- | src/shared/cplusplus/SymbolVisitor.h | 1 | ||||
-rw-r--r-- | src/shared/cplusplus/Symbols.cpp | 47 | ||||
-rw-r--r-- | src/shared/cplusplus/Symbols.h | 37 | ||||
-rw-r--r-- | src/shared/cplusplus/Type.h | 2 | ||||
-rw-r--r-- | src/shared/cplusplus/TypeVisitor.h | 1 |
11 files changed, 131 insertions, 1 deletions
diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h index 2909c0775ab..3233c7449f1 100644 --- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h @@ -132,6 +132,7 @@ class BaseClass; class Block; class Class; class Enum; +class ForwardClassDeclaration; class Use; diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index ee9e80ffa66..f8ddde8b48e 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -136,6 +136,23 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast) } } + if (! ast->declarators && ast->decl_specifier_seq && ! ast->decl_specifier_seq->next) { + if (ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) { + Name *name = semantic()->check(elab_type_spec->name, _scope); + ForwardClassDeclaration *symbol = + control()->newForwardClassDeclaration(elab_type_spec->firstToken(), + name); + + if (_templateParameters) { + symbol->setTemplateParameters(_templateParameters); + _templateParameters = 0; + } + + _scope->enterSymbol(symbol); + return false; + } + } + List<Declaration *> **decl_it = &ast->symbols; for (DeclaratorListAST *it = ast->declarators; it; it = it->next) { Name *name = 0; diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp index 4d708f4340c..7f5fd273cae 100644 --- a/src/shared/cplusplus/Control.cpp +++ b/src/shared/cplusplus/Control.cpp @@ -124,6 +124,7 @@ public: delete_array_entries(usingNamespaceDirectives); delete_array_entries(enums); delete_array_entries(usingDeclarations); + delete_array_entries(classForwardDeclarations); } NameId *findOrInsertNameId(Identifier *id) @@ -322,6 +323,14 @@ public: return u; } + ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, Name *name) + { + ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit, + sourceLocation, name); + classForwardDeclarations.push_back(c); + return c; + } + Enum *newEnum(unsigned sourceLocation, Name *name) { Enum *e = new Enum(translationUnit, @@ -477,6 +486,7 @@ public: std::vector<UsingNamespaceDirective *> usingNamespaceDirectives; std::vector<Enum *> enums; std::vector<UsingDeclaration *> usingDeclarations; + std::vector<ForwardClassDeclaration *> classForwardDeclarations; }; Control::Control() @@ -632,4 +642,9 @@ UsingNamespaceDirective *Control::newUsingNamespaceDirective(unsigned sourceLoca UsingDeclaration *Control::newUsingDeclaration(unsigned sourceLocation, Name *name) { return d->newUsingDeclaration(sourceLocation, name); } +ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLocation, + Name *name) +{ return d->newForwardClassDeclaration(sourceLocation, name); } + + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h index 98c1bacdd29..cb64a888aac 100644 --- a/src/shared/cplusplus/Control.h +++ b/src/shared/cplusplus/Control.h @@ -148,6 +148,9 @@ public: /// Creates a new UsingDeclaration symbol. UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, Name *name = 0); + /// Creates a new ForwardClassDeclaration symbol. + ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, Name *name = 0); + Identifier *findOrInsertIdentifier(const char *chars, unsigned size); Identifier *findOrInsertIdentifier(const char *chars); diff --git a/src/shared/cplusplus/Symbol.cpp b/src/shared/cplusplus/Symbol.cpp index 8e9ba22bb78..6effeaa1c7d 100644 --- a/src/shared/cplusplus/Symbol.cpp +++ b/src/shared/cplusplus/Symbol.cpp @@ -334,6 +334,9 @@ bool Symbol::isNamespace() const bool Symbol::isClass() const { return asClass() != 0; } +bool Symbol::isForwardClassDeclaration() const +{ return asForwardClassDeclaration() != 0; } + bool Symbol::isBlock() const { return asBlock() != 0; } diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h index 2b9a428dce9..318cc1ca83b 100644 --- a/src/shared/cplusplus/Symbol.h +++ b/src/shared/cplusplus/Symbol.h @@ -197,6 +197,9 @@ public: /// Returns true if this Symbol is a BaseClass. bool isBaseClass() const; + /// Returns true if this Symbol is a ForwardClassDeclaration. + bool isForwardClassDeclaration() const; + virtual const ScopedSymbol *asScopedSymbol() const { return 0; } virtual const Enum *asEnum() const { return 0; } virtual const Function *asFunction() const { return 0; } @@ -208,6 +211,7 @@ public: virtual const Declaration *asDeclaration() const { return 0; } virtual const Argument *asArgument() const { return 0; } virtual const BaseClass *asBaseClass() const { return 0; } + virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return 0; } virtual ScopedSymbol *asScopedSymbol() { return 0; } virtual Enum *asEnum() { return 0; } @@ -220,6 +224,7 @@ public: virtual Declaration *asDeclaration() { return 0; } virtual Argument *asArgument() { return 0; } virtual BaseClass *asBaseClass() { return 0; } + virtual ForwardClassDeclaration *asForwardClassDeclaration() { 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 f0f4738de7f..b7113715858 100644 --- a/src/shared/cplusplus/SymbolVisitor.h +++ b/src/shared/cplusplus/SymbolVisitor.h @@ -82,6 +82,7 @@ public: virtual bool visit(Namespace *) { return true; } virtual bool visit(Class *) { return true; } virtual bool visit(Block *) { return true; } + virtual bool visit(ForwardClassDeclaration *) { return true; } }; CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp index 6fae11453bf..b8195c7db18 100644 --- a/src/shared/cplusplus/Symbols.cpp +++ b/src/shared/cplusplus/Symbols.cpp @@ -401,6 +401,53 @@ void BaseClass::setVirtual(bool isVirtual) void BaseClass::visitSymbol0(SymbolVisitor *visitor) { visitor->visit(this); } +ForwardClassDeclaration::ForwardClassDeclaration(TranslationUnit *translationUnit, + unsigned sourceLocation, Name *name) + : Symbol(translationUnit, sourceLocation, name), + _templateParameters(0) +{ } + +ForwardClassDeclaration::~ForwardClassDeclaration() +{ delete _templateParameters; } + +unsigned ForwardClassDeclaration::templateParameterCount() const +{ + if (! _templateParameters) + return 0; + return _templateParameters->symbolCount(); +} + +Symbol *ForwardClassDeclaration::templateParameterAt(unsigned index) const +{ return _templateParameters->symbolAt(index); } + +Scope *ForwardClassDeclaration::templateParameters() const +{ return _templateParameters; } + +void ForwardClassDeclaration::setTemplateParameters(Scope *templateParameters) +{ _templateParameters = templateParameters; } + +FullySpecifiedType ForwardClassDeclaration::type() const +{ return FullySpecifiedType(const_cast<ForwardClassDeclaration *>(this)); } + +bool ForwardClassDeclaration::isEqualTo(const Type *other) const +{ + if (const ForwardClassDeclaration *otherClassFwdTy = other->asForwardClassDeclarationType()) { + if (name() == otherClassFwdTy->name()) + return true; + else if (name() && otherClassFwdTy->name()) + return name()->isEqualTo(otherClassFwdTy->name()); + + return false; + } + return false; +} + +void ForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor) +{ visitor->visit(this); } + +void ForwardClassDeclaration::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + Class::Class(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name) : ScopedSymbol(translationUnit, sourceLocation, name), _key(ClassKey), diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h index 2153b55393e..1253621fec3 100644 --- a/src/shared/cplusplus/Symbols.h +++ b/src/shared/cplusplus/Symbols.h @@ -199,6 +199,42 @@ protected: virtual void visitSymbol0(SymbolVisitor *visitor); }; +class CPLUSPLUS_EXPORT ForwardClassDeclaration: public Symbol, public Type +{ +public: + ForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name); + virtual ~ForwardClassDeclaration(); + + unsigned templateParameterCount() const; + Symbol *templateParameterAt(unsigned index) const; + + Scope *templateParameters() const; + void setTemplateParameters(Scope *templateParameters); + + virtual FullySpecifiedType type() const; + + virtual bool isEqualTo(const Type *other) const; + + virtual const ForwardClassDeclaration *asForwardClassDeclaration() const + { return this; } + + virtual ForwardClassDeclaration *asForwardClassDeclaration() + { return this; } + + virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const + { return this; } + + virtual ForwardClassDeclaration *asForwardClassDeclarationType() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); + +private: + Scope *_templateParameters; +}; + class CPLUSPLUS_EXPORT Enum: public ScopedSymbol, public Type { public: @@ -295,7 +331,6 @@ protected: virtual void accept0(TypeVisitor *visitor); private: - Name *_name; Scope *_templateParameters; FullySpecifiedType _returnType; union { diff --git a/src/shared/cplusplus/Type.h b/src/shared/cplusplus/Type.h index 320555b40cf..f80362f3497 100644 --- a/src/shared/cplusplus/Type.h +++ b/src/shared/cplusplus/Type.h @@ -93,6 +93,7 @@ public: virtual const Namespace *asNamespaceType() const { return 0; } virtual const Class *asClassType() const { return 0; } virtual const Enum *asEnumType() const { return 0; } + virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; } virtual VoidType *asVoidType() { return 0; } virtual IntegerType *asIntegerType() { return 0; } @@ -106,6 +107,7 @@ public: virtual Namespace *asNamespaceType() { return 0; } virtual Class *asClassType() { return 0; } virtual Enum *asEnumType() { return 0; } + virtual ForwardClassDeclaration *asForwardClassDeclarationType() { 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 16fb37c4ad0..41cc5751575 100644 --- a/src/shared/cplusplus/TypeVisitor.h +++ b/src/shared/cplusplus/TypeVisitor.h @@ -84,6 +84,7 @@ public: virtual void visit(Namespace *) {} virtual void visit(Class *) {} virtual void visit(Enum *) {} + virtual void visit(ForwardClassDeclaration *) {} }; CPLUSPLUS_END_NAMESPACE |