diff options
Diffstat (limited to 'src/libs/3rdparty/cplusplus')
-rw-r--r-- | src/libs/3rdparty/cplusplus/Bind.cpp | 8 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Control.cpp | 23 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Control.h | 1 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Names.cpp | 21 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Names.h | 18 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Templates.cpp | 8 |
6 files changed, 66 insertions, 13 deletions
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 98310f9ee8..b21b167655 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -2639,10 +2639,14 @@ bool Bind::visit(TemplateIdAST *ast) } const Identifier *id = identifier(ast->identifier_token); + const int tokenKindBeforeIdentifier(translationUnit()->tokenKind(ast->identifier_token - 1)); + const bool isSpecialization = (tokenKindBeforeIdentifier == T_CLASS || + tokenKindBeforeIdentifier == T_STRUCT); if (templateArguments.empty()) - _name = control()->templateNameId(id); + _name = control()->templateNameId(id, isSpecialization); else - _name = control()->templateNameId(id, &templateArguments[0], templateArguments.size()); + _name = control()->templateNameId(id, isSpecialization, &templateArguments[0], + templateArguments.size()); ast->name = _name; return false; diff --git a/src/libs/3rdparty/cplusplus/Control.cpp b/src/libs/3rdparty/cplusplus/Control.cpp index ba709de052..8f6136534f 100644 --- a/src/libs/3rdparty/cplusplus/Control.cpp +++ b/src/libs/3rdparty/cplusplus/Control.cpp @@ -131,9 +131,18 @@ template <> struct Compare<TemplateNameId> const Identifier *id = name.identifier(); const Identifier *otherId = otherName.identifier(); - if (id == otherId) - return std::lexicographical_compare(name.firstTemplateArgument(), name.lastTemplateArgument(), - otherName.firstTemplateArgument(), otherName.lastTemplateArgument()); + if (id == otherId) { + // we have to differentiate TemplateNameId with respect to specialization or + // instantiation + if (name.isSpecialization() == otherName.isSpecialization()) { + return std::lexicographical_compare(name.firstTemplateArgument(), + name.lastTemplateArgument(), + otherName.firstTemplateArgument(), + otherName.lastTemplateArgument()); + } else { + return name.isSpecialization(); + } + } return id < otherId; } @@ -211,9 +220,10 @@ public: } template <typename _Iterator> - const TemplateNameId *findOrInsertTemplateNameId(const Identifier *id, _Iterator first, _Iterator last) + const TemplateNameId *findOrInsertTemplateNameId(const Identifier *id, bool isSpecialization, + _Iterator first, _Iterator last) { - return templateNameIds.intern(TemplateNameId(id, first, last)); + return templateNameIds.intern(TemplateNameId(id, isSpecialization, first, last)); } const DestructorNameId *findOrInsertDestructorNameId(const Name *name) @@ -598,10 +608,11 @@ const NumericLiteral *Control::numericLiteral(const char *chars) } const TemplateNameId *Control::templateNameId(const Identifier *id, + bool isSpecialization, const FullySpecifiedType *const args, unsigned argv) { - return d->findOrInsertTemplateNameId(id, args, args + argv); + return d->findOrInsertTemplateNameId(id, isSpecialization, args, args + argv); } const DestructorNameId *Control::destructorNameId(const Name *name) diff --git a/src/libs/3rdparty/cplusplus/Control.h b/src/libs/3rdparty/cplusplus/Control.h index 4132d5f3cf..cef4df40f7 100644 --- a/src/libs/3rdparty/cplusplus/Control.h +++ b/src/libs/3rdparty/cplusplus/Control.h @@ -51,6 +51,7 @@ public: /// Returns the canonical template name id. const TemplateNameId *templateNameId(const Identifier *id, + bool isSpecialization, const FullySpecifiedType *const args = 0, unsigned argc = 0); diff --git a/src/libs/3rdparty/cplusplus/Names.cpp b/src/libs/3rdparty/cplusplus/Names.cpp index 9024b65a91..4c5cb7db79 100644 --- a/src/libs/3rdparty/cplusplus/Names.cpp +++ b/src/libs/3rdparty/cplusplus/Names.cpp @@ -128,6 +128,27 @@ bool TemplateNameId::isEqualTo(const Name *other) const return true; } +bool TemplateNameId::Compare::operator()(const TemplateNameId *name, + const TemplateNameId *other) const +{ + const Identifier *id = name->identifier(); + const Identifier *otherId = other->identifier(); + + if (id == otherId) { + // we have to differentiate TemplateNameId with respect to specialization or instantiation + if (name->isSpecialization() == other->isSpecialization()) { + return std::lexicographical_compare(name->firstTemplateArgument(), + name->lastTemplateArgument(), + other->firstTemplateArgument(), + other->lastTemplateArgument()); + } else { + return name->isSpecialization(); + } + } + + return id < otherId; +} + OperatorNameId::OperatorNameId(Kind kind) : _kind(kind) { } diff --git a/src/libs/3rdparty/cplusplus/Names.h b/src/libs/3rdparty/cplusplus/Names.h index 70c782591f..e600ec1daf 100644 --- a/src/libs/3rdparty/cplusplus/Names.h +++ b/src/libs/3rdparty/cplusplus/Names.h @@ -80,8 +80,11 @@ class CPLUSPLUS_EXPORT TemplateNameId: public Name { public: template <typename _Iterator> - TemplateNameId(const Identifier *identifier, _Iterator first, _Iterator last) - : _identifier(identifier), _templateArguments(first, last) {} + TemplateNameId(const Identifier *identifier, bool isSpecialization, _Iterator first, + _Iterator last) + : _identifier(identifier) + , _templateArguments(first, last) + , _isSpecialization(isSpecialization) {} virtual ~TemplateNameId(); @@ -100,6 +103,15 @@ public: TemplateArgumentIterator firstTemplateArgument() const { return _templateArguments.begin(); } TemplateArgumentIterator lastTemplateArgument() const { return _templateArguments.end(); } + bool isSpecialization() const { return _isSpecialization; } + // this is temporary solution needed in ClassOrNamespace::nestedType + // when we try to find correct specialization for instantiation + void setIsSpecialization(bool isSpecialization) { _isSpecialization = isSpecialization; } + + // Comparator needed to distinguish between two different TemplateNameId(e.g.:used in std::map) + struct Compare: std::binary_function<const TemplateNameId *, const TemplateNameId *, bool> { + bool operator()(const TemplateNameId *name, const TemplateNameId *other) const; + }; protected: virtual void accept0(NameVisitor *visitor) const; @@ -107,6 +119,8 @@ protected: private: const Identifier *_identifier; std::vector<FullySpecifiedType> _templateArguments; + // now TemplateNameId can be a specialization or an instantiation + bool _isSpecialization; }; class CPLUSPLUS_EXPORT OperatorNameId: public Name diff --git a/src/libs/3rdparty/cplusplus/Templates.cpp b/src/libs/3rdparty/cplusplus/Templates.cpp index fd1ee873d9..c81ed51b09 100644 --- a/src/libs/3rdparty/cplusplus/Templates.cpp +++ b/src/libs/3rdparty/cplusplus/Templates.cpp @@ -414,9 +414,10 @@ void CloneName::visit(const TemplateNameId *name) for (unsigned i = 0; i < args.size(); ++i) args[i] = _clone->type(name->templateArgumentAt(i), _subst); if (args.empty()) - _name = _control->templateNameId(_clone->identifier(name->identifier())); + _name = _control->templateNameId(_clone->identifier(name->identifier()), name->isSpecialization()); else - _name = _control->templateNameId(_clone->identifier(name->identifier()), &args[0], args.size()); + _name = _control->templateNameId(_clone->identifier(name->identifier()), name->isSpecialization(), + &args[0], args.size()); } void CloneName::visit(const DestructorNameId *name) @@ -528,7 +529,8 @@ FullySpecifiedType Subst::apply(const Name *name) const const NamedType *name = apply(q->base())->asNamedType(); const NamedType *unqualified = apply(q->name())->asNamedType(); if (name && name->name()->identifier() != 0 && unqualified) - return control()->namedType(control()->qualifiedNameId(name->name()->identifier(), unqualified->name())); + return control()->namedType(control()->qualifiedNameId(name->name()->identifier(), + unqualified->name())); } } |