diff --git a/src/libs/cplusplus/Icons.cpp b/src/libs/cplusplus/Icons.cpp index 8626088052f..5071efde8ab 100644 --- a/src/libs/cplusplus/Icons.cpp +++ b/src/libs/cplusplus/Icons.cpp @@ -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; diff --git a/src/libs/cplusplus/Overview.cpp b/src/libs/cplusplus/Overview.cpp index 0f973753d0b..331471fe363 100644 --- a/src/libs/cplusplus/Overview.cpp +++ b/src/libs/cplusplus/Overview.cpp @@ -42,7 +42,8 @@ Overview::Overview() : _markArgument(0), _showArgumentNames(false), _showReturnTypes(false), - _showFunctionSignatures(true) + _showFunctionSignatures(true), + _showFullyQualifiedNames(false) { } Overview::~Overview() @@ -88,6 +89,16 @@ void Overview::setShowFunctionSignatures(bool showFunctionSignatures) _showFunctionSignatures = showFunctionSignatures; } +bool Overview::showFullyQualifiedNames() const +{ + return _showFullyQualifiedNames; +} + +void Overview::setShowFullyQualifiedNamed(bool showFullyQualifiedNames) +{ + _showFullyQualifiedNames = showFullyQualifiedNames; +} + QString Overview::prettyName(Name *name) const { NamePrettyPrinter pp(this); diff --git a/src/libs/cplusplus/Overview.h b/src/libs/cplusplus/Overview.h index 6918ee45ff8..f7076559f2a 100644 --- a/src/libs/cplusplus/Overview.h +++ b/src/libs/cplusplus/Overview.h @@ -57,6 +57,9 @@ public: bool showFunctionSignatures() const; void setShowFunctionSignatures(bool showFunctionSignatures); + bool showFullyQualifiedNames() const; + void setShowFullyQualifiedNamed(bool showFullyQualifiedNames); + // 1-based // ### rename unsigned markArgument() const; @@ -77,6 +80,7 @@ private: bool _showArgumentNames: 1; bool _showReturnTypes: 1; bool _showFunctionSignatures: 1; + bool _showFullyQualifiedNames: 1; }; } // end of namespace CPlusPlus diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp index 6e46361b7f4..a198844499c 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.cpp +++ b/src/libs/cplusplus/TypePrettyPrinter.cpp @@ -37,9 +37,41 @@ #include #include #include +#include +#include using namespace CPlusPlus; + +static QString fullyQualifiedName(Symbol *symbol, const Overview *overview) +{ + QStringList nestedNameSpecifier; + + for (Scope *scope = symbol->scope(); scope && scope->enclosingScope(); + scope = scope->enclosingScope()) + { + Symbol *owner = scope->owner(); + + if (! owner) { + qWarning() << "invalid scope."; // ### better message. + continue; + } + + if (! owner->name()) + nestedNameSpecifier.prepend(QLatin1String("")); + + else { + const QString name = overview->prettyName(owner->name()); + + nestedNameSpecifier.prepend(name); + } + } + + nestedNameSpecifier.append(overview->prettyName(symbol->name())); + + return nestedNameSpecifier.join(QLatin1String("::")); +} + TypePrettyPrinter::TypePrettyPrinter(const Overview *overview) : _overview(overview), _name(0) @@ -150,16 +182,26 @@ void TypePrettyPrinter::visit(Namespace *type) applyPtrOperators(); } -void TypePrettyPrinter::visit(Class *type) +void TypePrettyPrinter::visit(Class *classTy) { - _text += overview()->prettyName(type->name()); + if (overview()->showFullyQualifiedNames()) + _text += fullyQualifiedName(classTy, overview()); + + else + _text += overview()->prettyName(classTy->name()); + applyPtrOperators(); } void TypePrettyPrinter::visit(Enum *type) { - _text += overview()->prettyName(type->name()); + if (overview()->showFullyQualifiedNames()) + _text += fullyQualifiedName(type, overview()); + + else + _text += overview()->prettyName(type->name()); + applyPtrOperators(); } @@ -259,11 +301,14 @@ void TypePrettyPrinter::visit(Function *type) if (! _ptrOperators.isEmpty()) { out(QLatin1Char('(')); applyPtrOperators(false); + if (! _name.isEmpty()) { _text += _name; _name.clear(); } + out(QLatin1Char(')')); + } else if (! _name.isEmpty() && _overview->showFunctionSignatures()) { space(); out(_name); diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index e47fbe65812..66dc226e4d7 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -141,30 +142,13 @@ void CppHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint } } -static QString buildHelpId(const FullySpecifiedType &type, - const Symbol *symbol) +static QString buildHelpId(Symbol *symbol, Name *name) { - Name *name = 0; Scope *scope = 0; - if (const Function *f = type->asFunctionType()) { - name = f->name(); - scope = f->scope(); - } else if (const Class *c = type->asClassType()) { - name = c->name(); - scope = c->scope(); - } else if (const Enum *e = type->asEnumType()) { - name = e->name(); - scope = e->scope(); - } else if (const NamedType *t = type->asNamedType()) { - name = t->name(); - } else if (symbol && symbol->isDeclaration()) { - const Declaration *d = symbol->asDeclaration(); - - if (d->scope() && d->scope()->isEnumScope()) { - name = d->name(); - scope = d->scope(); - } + if (symbol) { + scope = symbol->scope(); + name = symbol->name(); } if (! name) @@ -178,14 +162,18 @@ 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()) { + + if (NameId *nameId = name->asNameId()) id = nameId->identifier(); - } else if (TemplateNameId *nameId = name->asTemplateNameId()) { + + else if (TemplateNameId *nameId = name->asTemplateNameId()) id = nameId->identifier(); - } + if (id) qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size())); } @@ -194,6 +182,70 @@ static QString buildHelpId(const FullySpecifiedType &type, return qualifiedNames.join(QLatin1String("::")); } +// ### move me +static FullySpecifiedType resolve(const FullySpecifiedType &ty, + const LookupContext &context, + Symbol **resolvedSymbol, + Name **resolvedName) +{ + Control *control = context.control(); + + if (const PointerType *ptrTy = ty->asPointerType()) { + return control->pointerType(resolve(ptrTy->elementType(), context, + resolvedSymbol, resolvedName)); + + } else if (const ReferenceType *refTy = ty->asReferenceType()) { + return control->referenceType(resolve(refTy->elementType(), context, + resolvedSymbol, resolvedName)); + + } else if (const PointerToMemberType *ptrToMemTy = ty->asPointerToMemberType()) { + return control->pointerToMemberType(ptrToMemTy->memberName(), + resolve(ptrToMemTy->elementType(), context, + resolvedSymbol, resolvedName)); + + } else if (const NamedType *namedTy = ty->asNamedType()) { + if (resolvedName) + *resolvedName = namedTy->name(); + + const QList candidates = context.resolve(namedTy->name()); + + foreach (Symbol *c, candidates) { + if (c->isClass() || c->isEnum()) { + if (resolvedSymbol) + *resolvedSymbol = c; + + return c->type(); + } + } + + } else if (const Namespace *nsTy = ty->asNamespaceType()) { + if (resolvedName) + *resolvedName = nsTy->name(); + + } else if (const Class *classTy = ty->asClassType()) { + if (resolvedName) + *resolvedName = classTy->name(); + + if (resolvedSymbol) + *resolvedSymbol = const_cast(classTy); + + } else if (const ForwardClassDeclaration *fwdClassTy = ty->asForwardClassDeclarationType()) { + if (resolvedName) + *resolvedName = fwdClassTy->name(); + + } else if (const Enum *enumTy = ty->asEnumType()) { + if (resolvedName) + *resolvedName = enumTy->name(); + + } else if (const Function *funTy = ty->asFunctionType()) { + if (resolvedName) + *resolvedName = funTy->name(); + + } + + return ty; +} + void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos) { m_helpId.clear(); @@ -262,26 +314,38 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in typeOfExpression(expression, doc, lastSymbol); if (!types.isEmpty()) { - FullySpecifiedType firstType = types.first().first; - Symbol *symbol = types.first().second; - FullySpecifiedType docType = firstType; + const TypeOfExpression::Result result = types.first(); - if (const PointerType *pt = firstType->asPointerType()) { - docType = pt->elementType(); - } else if (const ReferenceType *rt = firstType->asReferenceType()) { - docType = rt->elementType(); - } + FullySpecifiedType firstType = result.first; // result of `type of expression'. + Symbol *lookupSymbol = result.second; // lookup symbol - m_helpId = buildHelpId(docType, symbol); - QString displayName = buildHelpId(firstType, symbol); + Symbol *resolvedSymbol = 0; + Name *resolvedName = 0; + firstType = resolve(firstType, typeOfExpression.lookupContext(), + &resolvedSymbol, &resolvedName); - if (!firstType->isClassType() && !firstType->isNamedType()) { - Overview overview; - overview.setShowArgumentNames(true); - overview.setShowReturnTypes(true); - m_toolTip = overview.prettyType(firstType, displayName); - } else { + m_helpId = buildHelpId(resolvedSymbol, resolvedName); + + Symbol *symbol = result.second; + if (resolvedSymbol) + symbol = resolvedSymbol; + + Overview overview; + overview.setShowArgumentNames(true); + overview.setShowReturnTypes(true); + overview.setShowFullyQualifiedNamed(true); + + if (lookupSymbol && lookupSymbol->isDeclaration()) { + Declaration *decl = lookupSymbol->asDeclaration(); + m_toolTip = overview.prettyType(firstType, decl->name()); + + } else if (firstType->isClassType() || firstType->isEnumType() || + firstType->isForwardClassDeclarationType()) { m_toolTip = m_helpId; + + } else { + m_toolTip = overview.prettyType(firstType, m_helpId); + } } } diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 1d845a1e3e6..6f41c83379d 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -1562,6 +1562,7 @@ bool GdbEngine::startDebugger() //sendCommand("set pagination off"); sendCommand("set breakpoint pending on", BreakEnablePending); sendCommand("set print elements 10000"); + sendCommand("-data-list-register-names", RegisterListNames); // one of the following is needed to prevent crashes in gdb on code like: // template T foo() { return T(0); } @@ -1633,8 +1634,6 @@ bool GdbEngine::startDebugger() sendCommand("x/2i " + startSymbolName(), GdbStart); } - sendCommand("-data-list-register-names", RegisterListNames); - // set all to "pending" if (q->startMode() == DebuggerManager::AttachExternal) qq->breakHandler()->removeAllBreakpoints(); diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 8a9c201dc5d..6ab5c9b92ec 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -1178,7 +1178,7 @@ unsigned DeclaratorListAST::lastToken() const { for (const DeclaratorListAST *it = this; it; it = it->next) { if (! it->next) - return it->lastToken(); + return it->declarator->lastToken(); } return 0; } 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 **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 usingNamespaceDirectives; std::vector enums; std::vector usingDeclarations; + std::vector 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(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.cpp b/src/shared/cplusplus/Type.cpp index b88b0afab48..f2128f03e80 100644 --- a/src/shared/cplusplus/Type.cpp +++ b/src/shared/cplusplus/Type.cpp @@ -102,6 +102,9 @@ bool Type::isClassType() const bool Type::isEnumType() const { return asEnumType() != 0; } +bool Type::isForwardClassDeclarationType() const +{ return asForwardClassDeclarationType() != 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 320555b40cf..1ac54f4dfbe 100644 --- a/src/shared/cplusplus/Type.h +++ b/src/shared/cplusplus/Type.h @@ -80,6 +80,7 @@ public: bool isNamespaceType() const; bool isClassType() const; bool isEnumType() const; + bool isForwardClassDeclarationType() const; virtual const VoidType *asVoidType() const { return 0; } virtual const IntegerType *asIntegerType() const { return 0; } @@ -93,6 +94,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 +108,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