aboutsummaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorRoberto Raggi <[email protected]>2009-02-16 15:43:24 +0100
committerRoberto Raggi <[email protected]>2009-02-16 18:20:46 +0100
commitba78e075da3919aafd2afdb8508952115f713c36 (patch)
treede94307448655b215342d82ec6f9fe5b728c4717 /src/shared
parent2788d77229dbecdeae293f8e3edff70f39750e63 (diff)
Introduced support for forward class declarations.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/cplusplus/CPlusPlusForwardDeclarations.h1
-rw-r--r--src/shared/cplusplus/CheckDeclaration.cpp17
-rw-r--r--src/shared/cplusplus/Control.cpp15
-rw-r--r--src/shared/cplusplus/Control.h3
-rw-r--r--src/shared/cplusplus/Symbol.cpp3
-rw-r--r--src/shared/cplusplus/Symbol.h5
-rw-r--r--src/shared/cplusplus/SymbolVisitor.h1
-rw-r--r--src/shared/cplusplus/Symbols.cpp47
-rw-r--r--src/shared/cplusplus/Symbols.h37
-rw-r--r--src/shared/cplusplus/Type.h2
-rw-r--r--src/shared/cplusplus/TypeVisitor.h1
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