forked from qt-creator/qt-creator
Introduced support for forward class declarations.
This commit is contained in:
@@ -100,7 +100,7 @@ QIcon Icons::iconForSymbol(const Symbol *symbol) const
|
||||
}
|
||||
} else if (symbol->isEnum()) {
|
||||
return _enumIcon;
|
||||
} else if (symbol->isClass()) {
|
||||
} else if (symbol->isClass() || symbol->isForwardClassDeclaration()) {
|
||||
return _classIcon;
|
||||
} else if (symbol->isNamespace()) {
|
||||
return _namespaceIcon;
|
||||
|
@@ -156,6 +156,9 @@ static QString buildHelpId(const FullySpecifiedType &type,
|
||||
} else if (const Enum *e = type->asEnumType()) {
|
||||
name = e->name();
|
||||
scope = e->scope();
|
||||
} else if (const ForwardClassDeclaration *fwd = type->asForwardClassDeclarationType()) {
|
||||
name = fwd->name();
|
||||
scope = fwd->scope();
|
||||
} else if (const NamedType *t = type->asNamedType()) {
|
||||
name = t->name();
|
||||
} else if (symbol && symbol->isDeclaration()) {
|
||||
@@ -178,14 +181,19 @@ static QString buildHelpId(const FullySpecifiedType &type,
|
||||
qualifiedNames.prepend(overview.prettyName(name));
|
||||
|
||||
for (; scope; scope = scope->enclosingScope()) {
|
||||
if (scope->owner() && scope->owner()->name() && !scope->isEnumScope()) {
|
||||
Name *name = scope->owner()->name();
|
||||
Symbol *owner = scope->owner();
|
||||
|
||||
if (owner && owner->name() && ! scope->isEnumScope()) {
|
||||
Name *name = owner->name();
|
||||
|
||||
Identifier *id = 0;
|
||||
|
||||
if (NameId *nameId = name->asNameId()) {
|
||||
id = nameId->identifier();
|
||||
} else if (TemplateNameId *nameId = name->asTemplateNameId()) {
|
||||
id = nameId->identifier();
|
||||
}
|
||||
|
||||
if (id)
|
||||
qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size()));
|
||||
}
|
||||
|
@@ -132,6 +132,7 @@ class BaseClass;
|
||||
class Block;
|
||||
class Class;
|
||||
class Enum;
|
||||
class ForwardClassDeclaration;
|
||||
|
||||
class Use;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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; }
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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),
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
@@ -84,6 +84,7 @@ public:
|
||||
virtual void visit(Namespace *) {}
|
||||
virtual void visit(Class *) {}
|
||||
virtual void visit(Enum *) {}
|
||||
virtual void visit(ForwardClassDeclaration *) {}
|
||||
};
|
||||
|
||||
CPLUSPLUS_END_NAMESPACE
|
||||
|
Reference in New Issue
Block a user