diff options
Diffstat (limited to 'src')
24 files changed, 181 insertions, 6 deletions
diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index 961bc2e1a7..9699ff8e0d 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -127,6 +127,7 @@ public: virtual AccessDeclarationAST *asAccessDeclaration() { return 0; } virtual AliasDeclarationAST *asAliasDeclaration() { return 0; } virtual AlignofExpressionAST *asAlignofExpression() { return 0; } + virtual AnonymousNameAST *asAnonymousName() { return 0; } virtual ArrayAccessAST *asArrayAccess() { return 0; } virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; } virtual ArrayInitializerAST *asArrayInitializer() { return 0; } @@ -2267,6 +2268,26 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; +class CPLUSPLUS_EXPORT AnonymousNameAST: public NameAST +{ +public: + unsigned class_token; +public: + AnonymousNameAST() + : class_token(0) + {} + + virtual AnonymousNameAST *asAnonymousName() { return this; } + virtual unsigned firstToken() const { return 0; } + virtual unsigned lastToken() const { return 0; } + + virtual AnonymousNameAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); + virtual bool match0(AST *, ASTMatcher *); +}; + class CPLUSPLUS_EXPORT SimpleNameAST: public NameAST { public: diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp index 73565b8037..0a8db781cb 100644 --- a/src/libs/3rdparty/cplusplus/ASTClone.cpp +++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp @@ -824,6 +824,13 @@ ConversionFunctionIdAST *ConversionFunctionIdAST::clone(MemoryPool *pool) const return ast; } +AnonymousNameAST *AnonymousNameAST::clone(MemoryPool *pool) const +{ + AnonymousNameAST *ast = new (pool) AnonymousNameAST; + ast->class_token = class_token; + return ast; +} + SimpleNameAST *SimpleNameAST::clone(MemoryPool *pool) const { SimpleNameAST *ast = new (pool) SimpleNameAST; diff --git a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp index c49b5dae65..69e3daf615 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp @@ -552,6 +552,14 @@ bool ConversionFunctionIdAST::match0(AST *pattern, ASTMatcher *matcher) return false; } +bool AnonymousNameAST::match0(AST *pattern, ASTMatcher *matcher) +{ + if (AnonymousNameAST *_other = pattern->asAnonymousName()) + return matcher->match(this, _other); + + return false; +} + bool SimpleNameAST::match0(AST *pattern, ASTMatcher *matcher) { if (SimpleNameAST *_other = pattern->asSimpleName()) diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp index 4fbb9d6f8e..3d74bbfcb5 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp @@ -1403,6 +1403,16 @@ bool ASTMatcher::match(ConversionFunctionIdAST *node, ConversionFunctionIdAST *p return true; } +bool ASTMatcher::match(AnonymousNameAST *node, AnonymousNameAST *pattern) +{ + (void) node; + (void) pattern; + + pattern->class_token = node->class_token; + + return true; +} + bool ASTMatcher::match(SimpleNameAST *node, SimpleNameAST *pattern) { (void) node; diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.h b/src/libs/3rdparty/cplusplus/ASTMatcher.h index 29842253cd..eee507b941 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.h +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.h @@ -34,6 +34,7 @@ public: virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern); virtual bool match(AliasDeclarationAST *node, AliasDeclarationAST *pattern); virtual bool match(AlignofExpressionAST *node, AlignofExpressionAST *pattern); + virtual bool match(AnonymousNameAST *node, AnonymousNameAST *pattern); virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern); virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern); virtual bool match(ArrayInitializerAST *node, ArrayInitializerAST *pattern); diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h index 04a0fdd12c..a444c7e3f6 100644 --- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h +++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h @@ -543,6 +543,12 @@ public: return __ast; } + AnonymousNameAST *AnonymousName() + { + AnonymousNameAST *__ast = new (&pool) AnonymousNameAST; + return __ast; + } + SimpleNameAST *SimpleName() { SimpleNameAST *__ast = new (&pool) SimpleNameAST; diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp index 76adc01c53..9fec231127 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp @@ -596,6 +596,13 @@ void ConversionFunctionIdAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void AnonymousNameAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + } + visitor->endVisit(this); +} + void SimpleNameAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.h b/src/libs/3rdparty/cplusplus/ASTVisitor.h index a7d3f728f6..d9578a4061 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisitor.h +++ b/src/libs/3rdparty/cplusplus/ASTVisitor.h @@ -76,6 +76,7 @@ public: virtual bool visit(AccessDeclarationAST *) { return true; } virtual bool visit(AliasDeclarationAST *) { return true; } virtual bool visit(AlignofExpressionAST *) { return true; } + virtual bool visit(AnonymousNameAST *) { return true; } virtual bool visit(ArrayAccessAST *) { return true; } virtual bool visit(ArrayDeclaratorAST *) { return true; } virtual bool visit(ArrayInitializerAST *) { return true; } @@ -221,6 +222,7 @@ public: virtual void endVisit(AccessDeclarationAST *) {} virtual void endVisit(AliasDeclarationAST *) {} virtual void endVisit(AlignofExpressionAST *) {} + virtual void endVisit(AnonymousNameAST *) {} virtual void endVisit(ArrayAccessAST *) {} virtual void endVisit(ArrayDeclaratorAST *) {} virtual void endVisit(ArrayInitializerAST *) {} diff --git a/src/libs/3rdparty/cplusplus/ASTfwd.h b/src/libs/3rdparty/cplusplus/ASTfwd.h index 722a5b0d38..7b79947cb9 100644 --- a/src/libs/3rdparty/cplusplus/ASTfwd.h +++ b/src/libs/3rdparty/cplusplus/ASTfwd.h @@ -34,6 +34,7 @@ class ASTMatcher; class AccessDeclarationAST; class AliasDeclarationAST; class AlignofExpressionAST; +class AnonymousNameAST; class ArrayAccessAST; class ArrayDeclaratorAST; class ArrayInitializerAST; diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index b21b167655..3f2ffea7c8 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -2614,6 +2614,12 @@ bool Bind::visit(ConversionFunctionIdAST *ast) return false; } +bool Bind::visit(AnonymousNameAST *ast) +{ + ast->name = _name = control()->anonymousNameId(ast->class_token); + return false; +} + bool Bind::visit(SimpleNameAST *ast) { const Identifier *id = identifier(ast->identifier_token); @@ -2896,7 +2902,7 @@ bool Bind::visit(ClassSpecifierAST *ast) const Name *className = this->name(ast->name); - if (ast->name) { + if (ast->name && ! ast->name->asAnonymousName()) { sourceLocation = location(ast->name, sourceLocation); startScopeOffset = tokenAt(sourceLocation).end(); // at the end of the class name diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h index ca2c6084ba..04fed44a10 100644 --- a/src/libs/3rdparty/cplusplus/Bind.h +++ b/src/libs/3rdparty/cplusplus/Bind.h @@ -237,6 +237,7 @@ protected: virtual bool visit(QualifiedNameAST *ast); virtual bool visit(OperatorFunctionIdAST *ast); virtual bool visit(ConversionFunctionIdAST *ast); + virtual bool visit(AnonymousNameAST *ast); virtual bool visit(SimpleNameAST *ast); virtual bool visit(DestructorNameAST *ast); virtual bool visit(TemplateIdAST *ast); diff --git a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h index 7a3b2e0f3b..fe1316ddaa 100644 --- a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h @@ -73,6 +73,7 @@ class SymbolTable; class NameVisitor; class Name; class Identifier; +class AnonymousNameId; class TemplateNameId; class DestructorNameId; class OperatorNameId; diff --git a/src/libs/3rdparty/cplusplus/Control.cpp b/src/libs/3rdparty/cplusplus/Control.cpp index 8f6136534f..e274a20906 100644 --- a/src/libs/3rdparty/cplusplus/Control.cpp +++ b/src/libs/3rdparty/cplusplus/Control.cpp @@ -101,6 +101,14 @@ template <> struct Compare<ArrayType> } }; +template <> struct Compare<AnonymousNameId> +{ + bool operator()(const AnonymousNameId &name, const AnonymousNameId &otherName) const + { + return name.classTokenIndex() < otherName.classTokenIndex(); + } +}; + template <> struct Compare<DestructorNameId> { bool operator()(const DestructorNameId &name, const DestructorNameId &otherName) const @@ -219,6 +227,11 @@ public: delete_array_entries(symbols); } + const AnonymousNameId *findOrInsertAnonymousNameId(unsigned classTokenIndex) + { + return anonymousNameIds.intern(AnonymousNameId(classTokenIndex)); + } + template <typename _Iterator> const TemplateNameId *findOrInsertTemplateNameId(const Identifier *id, bool isSpecialization, _Iterator first, _Iterator last) @@ -475,6 +488,7 @@ public: // ### replace std::map with lookup tables. ASAP! // names + Table<AnonymousNameId> anonymousNameIds; Table<DestructorNameId> destructorNameIds; Table<OperatorNameId> operatorNameIds; Table<ConversionNameId> conversionNameIds; @@ -550,6 +564,9 @@ DiagnosticClient *Control::diagnosticClient() const void Control::setDiagnosticClient(DiagnosticClient *diagnosticClient) { d->diagnosticClient = diagnosticClient; } +const AnonymousNameId *Control::anonymousNameId(unsigned classTokenIndex) +{ return d->findOrInsertAnonymousNameId(classTokenIndex); } + const OperatorNameId *Control::findOperatorNameId(OperatorNameId::Kind operatorId) const { Table<OperatorNameId>::const_iterator i = d->operatorNameIds.find(operatorId); diff --git a/src/libs/3rdparty/cplusplus/Control.h b/src/libs/3rdparty/cplusplus/Control.h index cef4df40f7..538ecc2766 100644 --- a/src/libs/3rdparty/cplusplus/Control.h +++ b/src/libs/3rdparty/cplusplus/Control.h @@ -49,6 +49,9 @@ public: DiagnosticClient *diagnosticClient() const; void setDiagnosticClient(DiagnosticClient *diagnosticClient); + /// Returns the canonical anonymous name id + const AnonymousNameId *anonymousNameId(unsigned classTokenIndex); + /// Returns the canonical template name id. const TemplateNameId *templateNameId(const Identifier *id, bool isSpecialization, diff --git a/src/libs/3rdparty/cplusplus/Name.cpp b/src/libs/3rdparty/cplusplus/Name.cpp index 5a203d61ef..a8d453fc02 100644 --- a/src/libs/3rdparty/cplusplus/Name.cpp +++ b/src/libs/3rdparty/cplusplus/Name.cpp @@ -36,6 +36,9 @@ Name::~Name() bool Name::isNameId() const { return asNameId() != 0; } +bool Name::isAnonymousNameId() const +{ return asAnonymousNameId() != 0; } + bool Name::isTemplateNameId() const { return asTemplateNameId() != 0; } diff --git a/src/libs/3rdparty/cplusplus/Name.h b/src/libs/3rdparty/cplusplus/Name.h index 43dcf3d35c..9d19748471 100644 --- a/src/libs/3rdparty/cplusplus/Name.h +++ b/src/libs/3rdparty/cplusplus/Name.h @@ -36,6 +36,7 @@ public: virtual const Identifier *identifier() const = 0; bool isNameId() const; + bool isAnonymousNameId() const; bool isTemplateNameId() const; bool isDestructorNameId() const; bool isOperatorNameId() const; @@ -44,6 +45,7 @@ public: bool isSelectorNameId() const; virtual const Identifier *asNameId() const { return 0; } + virtual const AnonymousNameId *asAnonymousNameId() const { return 0; } virtual const TemplateNameId *asTemplateNameId() const { return 0; } virtual const DestructorNameId *asDestructorNameId() const { return 0; } virtual const OperatorNameId *asOperatorNameId() const { return 0; } diff --git a/src/libs/3rdparty/cplusplus/NameVisitor.h b/src/libs/3rdparty/cplusplus/NameVisitor.h index bb0ef5335f..c2a5f89da6 100644 --- a/src/libs/3rdparty/cplusplus/NameVisitor.h +++ b/src/libs/3rdparty/cplusplus/NameVisitor.h @@ -40,6 +40,7 @@ public: virtual bool preVisit(const Name *) { return true; } virtual void postVisit(const Name *) {} + virtual void visit(const AnonymousNameId *) {} virtual void visit(const Identifier *) {} virtual void visit(const TemplateNameId *) {} virtual void visit(const DestructorNameId *) {} diff --git a/src/libs/3rdparty/cplusplus/Names.cpp b/src/libs/3rdparty/cplusplus/Names.cpp index 4c5cb7db79..4a65fea2a8 100644 --- a/src/libs/3rdparty/cplusplus/Names.cpp +++ b/src/libs/3rdparty/cplusplus/Names.cpp @@ -249,3 +249,29 @@ bool SelectorNameId::isEqualTo(const Name *other) const return true; } +AnonymousNameId::AnonymousNameId(unsigned classTokenIndex) + : _classTokenIndex(classTokenIndex) +{ } + +AnonymousNameId::~AnonymousNameId() +{ } + +unsigned AnonymousNameId::classTokenIndex() const +{ + return _classTokenIndex; +} + +void AnonymousNameId::accept0(NameVisitor *visitor) const +{ visitor->visit(this); } + +const Identifier *AnonymousNameId::identifier() const +{ return 0; } + +bool AnonymousNameId::isEqualTo(const Name *other) const +{ + if (other) { + const AnonymousNameId *c = other->asAnonymousNameId(); + return (c && this->_classTokenIndex == c->_classTokenIndex); + } + return false; +} diff --git a/src/libs/3rdparty/cplusplus/Names.h b/src/libs/3rdparty/cplusplus/Names.h index e600ec1daf..855dd4987f 100644 --- a/src/libs/3rdparty/cplusplus/Names.h +++ b/src/libs/3rdparty/cplusplus/Names.h @@ -253,6 +253,29 @@ private: bool _hasArguments; }; +class CPLUSPLUS_EXPORT AnonymousNameId: public Name +{ +public: + AnonymousNameId(unsigned classTokenIndex); + virtual ~AnonymousNameId(); + + unsigned classTokenIndex() const; + + virtual const Identifier *identifier() const; + virtual bool isEqualTo(const Name *other) const; + + virtual const AnonymousNameId *asAnonymousNameId() const + { return this; } + +protected: + virtual void accept0(NameVisitor *visitor) const; + +private: + unsigned _classTokenIndex; +}; + + + } // namespace CPlusPlus #endif // CPLUSPLUS_NAMES_H diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 00b79dfc25..38938d3545 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -2003,6 +2003,12 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node) NameAST *name = 0; parseName(name); + if (! name && LA() == T_LBRACE && (LA(0) == T_CLASS || LA(0) == T_STRUCT || LA(0) == T_UNION || LA(0) == T_ENUM)) { + AnonymousNameAST *ast = new (_pool) AnonymousNameAST; + ast->class_token = classkey_token; + name = ast; + } + bool parsed = false; const bool previousInFunctionBody = _inFunctionBody; diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index fab318e8ca..dde50df687 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -60,7 +60,7 @@ static void addNames(const Name *name, QList<const Name *> *names, bool addAllNa else if (const QualifiedNameId *q = name->asQualifiedNameId()) { addNames(q->base(), names); addNames(q->name(), names, addAllNames); - } else if (addAllNames || name->isNameId() || name->isTemplateNameId()) { + } else if (addAllNames || name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) { names->append(name); } } @@ -716,7 +716,7 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name, } else if (! processed->contains(this)) { processed->insert(this); - if (name->isNameId() || name->isTemplateNameId()) { + if (name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) { flush(); foreach (Symbol *s, symbols()) { @@ -798,10 +798,26 @@ ClassOrNamespace *ClassOrNamespace::findSpecializationWithPointer(const Template ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespace *origin) { Q_ASSERT(name != 0); - Q_ASSERT(name->isNameId() || name->isTemplateNameId()); + Q_ASSERT(name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()); const_cast<ClassOrNamespace *>(this)->flush(); + const AnonymousNameId *anonymousNameId = name->asAnonymousNameId(); + if (anonymousNameId) { + QHash<const AnonymousNameId *, ClassOrNamespace *>::const_iterator cit + = _anonymouses.find(anonymousNameId); + if (cit != _anonymouses.end()) { + return cit.value(); + } else { + ClassOrNamespace *newAnonymous = _factory->allocClassOrNamespace(this); +#ifdef DEBUG_LOOKUP + newAnonymous->_name = anonymousNameId; +#endif // DEBUG_LOOKUP + _anonymouses[anonymousNameId] = newAnonymous; + return newAnonymous; + } + } + Table::const_iterator it = _classOrNamespaces.find(name); if (it == _classOrNamespaces.end()) return 0; @@ -1201,7 +1217,7 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNa return findOrCreateType(q->base(), origin)->findOrCreateType(q->name(), origin); - } else if (name->isNameId() || name->isTemplateNameId()) { + } else if (name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) { ClassOrNamespace *e = nestedType(name, origin); if (! e) { @@ -1470,7 +1486,7 @@ bool CreateBindings::visit(NamespaceAlias *a) return false; } else if (ClassOrNamespace *e = _currentClassOrNamespace->lookupType(a->namespaceName())) { - if (a->name()->isNameId() || a->name()->isTemplateNameId()) + if (a->name()->isNameId() || a->name()->isTemplateNameId() || a->name()->isAnonymousNameId()) _currentClassOrNamespace->addNestedType(a->name(), e); } else if (false) { diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index ead7d2dfe3..3dbe525766 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -131,6 +131,7 @@ private: QSharedPointer<Control> _control; TemplateNameIdTable _specializations; QMap<const TemplateNameId *, ClassOrNamespace *> _instantiations; + QHash<const AnonymousNameId *, ClassOrNamespace *> _anonymouses; QHash<Internal::FullyQualifiedName, Symbol *> *_scopeLookupCache; diff --git a/src/libs/cplusplus/NamePrettyPrinter.cpp b/src/libs/cplusplus/NamePrettyPrinter.cpp index a638135d46..d78e3eaa65 100644 --- a/src/libs/cplusplus/NamePrettyPrinter.cpp +++ b/src/libs/cplusplus/NamePrettyPrinter.cpp @@ -268,3 +268,8 @@ void NamePrettyPrinter::visit(const SelectorNameId *name) } } } + +void NamePrettyPrinter::visit(const AnonymousNameId *name) +{ + _name = QString(QLatin1String("Anonymous:%1")).arg(name->classTokenIndex()); +} diff --git a/src/libs/cplusplus/NamePrettyPrinter.h b/src/libs/cplusplus/NamePrettyPrinter.h index 348ba84b10..f5f0297022 100644 --- a/src/libs/cplusplus/NamePrettyPrinter.h +++ b/src/libs/cplusplus/NamePrettyPrinter.h @@ -57,6 +57,7 @@ protected: virtual void visit(const ConversionNameId *name); virtual void visit(const QualifiedNameId *name); virtual void visit(const SelectorNameId *name); + virtual void visit(const AnonymousNameId *name); private: const Overview *_overview; |