From b0618281ecaa71a99dea7235c3c955b2135cc127 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 24 Mar 2014 16:06:39 +0100 Subject: C++: Do type and name equality checking in a safe manner. Change the TypeMatcher to also match names, and use two "block" lists in SafeMatcher to prevent infinite recursion. Task-number: QTCREATORBUG-11240 Change-Id: I0367ae795ee6be579b83aeb8d46723c877e4aa75 Reviewed-by: Nikolai Kosjar --- src/libs/3rdparty/cplusplus/CPlusPlus.h | 2 +- .../cplusplus/CPlusPlusForwardDeclarations.h | 2 +- src/libs/3rdparty/cplusplus/Control.cpp | 3 - src/libs/3rdparty/cplusplus/CoreTypes.cpp | 20 +- src/libs/3rdparty/cplusplus/CoreTypes.h | 18 +- src/libs/3rdparty/cplusplus/FullySpecifiedType.cpp | 4 +- src/libs/3rdparty/cplusplus/FullySpecifiedType.h | 2 +- src/libs/3rdparty/cplusplus/Literals.cpp | 8 + src/libs/3rdparty/cplusplus/Literals.h | 1 + src/libs/3rdparty/cplusplus/Matcher.cpp | 311 +++++++++++++++++++++ src/libs/3rdparty/cplusplus/Matcher.h | 83 ++++++ src/libs/3rdparty/cplusplus/Name.cpp | 6 + src/libs/3rdparty/cplusplus/Name.h | 8 +- src/libs/3rdparty/cplusplus/Names.cpp | 52 +++- src/libs/3rdparty/cplusplus/Names.h | 7 + src/libs/3rdparty/cplusplus/SafeMatcher.cpp | 160 +++++++++++ src/libs/3rdparty/cplusplus/SafeMatcher.h | 64 +++++ src/libs/3rdparty/cplusplus/Symbols.cpp | 24 +- src/libs/3rdparty/cplusplus/Symbols.h | 22 +- src/libs/3rdparty/cplusplus/Type.cpp | 6 +- src/libs/3rdparty/cplusplus/Type.h | 14 +- src/libs/3rdparty/cplusplus/TypeMatcher.cpp | 211 -------------- src/libs/3rdparty/cplusplus/TypeMatcher.h | 45 --- src/libs/3rdparty/cplusplus/cplusplus.pri | 10 +- .../cplusplus/AlreadyConsideredClassContainer.h | 5 +- src/libs/cplusplus/cplusplus.qbs | 6 +- 26 files changed, 767 insertions(+), 327 deletions(-) create mode 100644 src/libs/3rdparty/cplusplus/Matcher.cpp create mode 100644 src/libs/3rdparty/cplusplus/Matcher.h create mode 100644 src/libs/3rdparty/cplusplus/SafeMatcher.cpp create mode 100644 src/libs/3rdparty/cplusplus/SafeMatcher.h delete mode 100644 src/libs/3rdparty/cplusplus/TypeMatcher.cpp delete mode 100644 src/libs/3rdparty/cplusplus/TypeMatcher.h (limited to 'src/libs') diff --git a/src/libs/3rdparty/cplusplus/CPlusPlus.h b/src/libs/3rdparty/cplusplus/CPlusPlus.h index 2af173ebc4..5fedc986a8 100644 --- a/src/libs/3rdparty/cplusplus/CPlusPlus.h +++ b/src/libs/3rdparty/cplusplus/CPlusPlus.h @@ -49,7 +49,7 @@ #include "Token.h" #include "TranslationUnit.h" #include "Type.h" -#include "TypeMatcher.h" +#include "Matcher.h" #include "TypeVisitor.h" #include "Templates.h" diff --git a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h index fe1316ddaa..9b1c5a30cf 100644 --- a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h @@ -82,7 +82,7 @@ class QualifiedNameId; class SelectorNameId; // types -class TypeMatcher; +class Matcher; class FullySpecifiedType; class TypeVisitor; class Type; diff --git a/src/libs/3rdparty/cplusplus/Control.cpp b/src/libs/3rdparty/cplusplus/Control.cpp index 1b04f04c19..02686f152e 100644 --- a/src/libs/3rdparty/cplusplus/Control.cpp +++ b/src/libs/3rdparty/cplusplus/Control.cpp @@ -25,7 +25,6 @@ #include "CoreTypes.h" #include "Symbols.h" #include "Names.h" -#include "TypeMatcher.h" #include #include #include @@ -479,8 +478,6 @@ public: TranslationUnit *translationUnit; DiagnosticClient *diagnosticClient; - TypeMatcher matcher; - LiteralTable identifiers; LiteralTable stringLiterals; LiteralTable numericLiterals; diff --git a/src/libs/3rdparty/cplusplus/CoreTypes.cpp b/src/libs/3rdparty/cplusplus/CoreTypes.cpp index a408b9af70..fd1e2e05b1 100644 --- a/src/libs/3rdparty/cplusplus/CoreTypes.cpp +++ b/src/libs/3rdparty/cplusplus/CoreTypes.cpp @@ -20,7 +20,7 @@ #include "CoreTypes.h" #include "TypeVisitor.h" -#include "TypeMatcher.h" +#include "Matcher.h" #include "Names.h" #include @@ -37,7 +37,7 @@ bool UndefinedType::isEqualTo(const Type *other) const void UndefinedType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool UndefinedType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool UndefinedType::match0(const Type *otherType, Matcher *matcher) const { if (const UndefinedType *otherUndefinedTy = otherType->asUndefinedType()) return matcher->match(this, otherUndefinedTy); @@ -54,7 +54,7 @@ bool VoidType::isEqualTo(const Type *other) const void VoidType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool VoidType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool VoidType::match0(const Type *otherType, Matcher *matcher) const { if (const VoidType *otherVoidTy = otherType->asVoidType()) return matcher->match(this, otherVoidTy); @@ -89,7 +89,7 @@ bool PointerToMemberType::isEqualTo(const Type *other) const void PointerToMemberType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool PointerToMemberType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool PointerToMemberType::match0(const Type *otherType, Matcher *matcher) const { if (const PointerToMemberType *otherTy = otherType->asPointerToMemberType()) return matcher->match(this, otherTy); @@ -115,7 +115,7 @@ bool PointerType::isEqualTo(const Type *other) const void PointerType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool PointerType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool PointerType::match0(const Type *otherType, Matcher *matcher) const { if (const PointerType *otherTy = otherType->asPointerType()) return matcher->match(this, otherTy); @@ -146,7 +146,7 @@ bool ReferenceType::isEqualTo(const Type *other) const void ReferenceType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ReferenceType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ReferenceType::match0(const Type *otherType, Matcher *matcher) const { if (const ReferenceType *otherTy = otherType->asReferenceType()) return matcher->match(this, otherTy); @@ -178,7 +178,7 @@ bool IntegerType::isEqualTo(const Type *other) const void IntegerType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool IntegerType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool IntegerType::match0(const Type *otherType, Matcher *matcher) const { if (const IntegerType *otherTy = otherType->asIntegerType()) return matcher->match(this, otherTy); @@ -199,7 +199,7 @@ FloatType::~FloatType() void FloatType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool FloatType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool FloatType::match0(const Type *otherType, Matcher *matcher) const { if (const FloatType *otherTy = otherType->asFloatType()) return matcher->match(this, otherTy); @@ -238,7 +238,7 @@ bool ArrayType::isEqualTo(const Type *other) const void ArrayType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ArrayType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ArrayType::match0(const Type *otherType, Matcher *matcher) const { if (const ArrayType *otherTy = otherType->asArrayType()) return matcher->match(this, otherTy); @@ -282,7 +282,7 @@ bool NamedType::isEqualTo(const Type *other) const void NamedType::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool NamedType::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool NamedType::match0(const Type *otherType, Matcher *matcher) const { if (const NamedType *otherTy = otherType->asNamedType()) return matcher->match(this, otherTy); diff --git a/src/libs/3rdparty/cplusplus/CoreTypes.h b/src/libs/3rdparty/cplusplus/CoreTypes.h index e3c797f1c3..d957767178 100644 --- a/src/libs/3rdparty/cplusplus/CoreTypes.h +++ b/src/libs/3rdparty/cplusplus/CoreTypes.h @@ -46,7 +46,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; }; class CPLUSPLUS_EXPORT VoidType: public Type @@ -62,7 +62,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; }; class CPLUSPLUS_EXPORT IntegerType: public Type @@ -96,7 +96,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: int _kind; @@ -127,7 +127,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: int _kind; @@ -151,7 +151,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: FullySpecifiedType _elementType; @@ -176,7 +176,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: const Name *_memberName; @@ -202,7 +202,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: FullySpecifiedType _elementType; @@ -228,7 +228,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: FullySpecifiedType _elementType; @@ -253,7 +253,7 @@ public: protected: virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: const Name *_name; diff --git a/src/libs/3rdparty/cplusplus/FullySpecifiedType.cpp b/src/libs/3rdparty/cplusplus/FullySpecifiedType.cpp index 0fbd3f41b9..8ae82349ac 100644 --- a/src/libs/3rdparty/cplusplus/FullySpecifiedType.cpp +++ b/src/libs/3rdparty/cplusplus/FullySpecifiedType.cpp @@ -245,10 +245,10 @@ void FullySpecifiedType::copySpecifiers(const FullySpecifiedType &type) f._isExplicit = type.f._isExplicit; } -bool FullySpecifiedType::match(const FullySpecifiedType &otherTy, TypeMatcher *matcher) const +bool FullySpecifiedType::match(const FullySpecifiedType &otherTy, Matcher *matcher) const { if (_flags != otherTy._flags) return false; - return type()->matchType(otherTy.type(), matcher); + return Type::match(type(), otherTy.type(), matcher); } diff --git a/src/libs/3rdparty/cplusplus/FullySpecifiedType.h b/src/libs/3rdparty/cplusplus/FullySpecifiedType.h index 895e171df5..2656939d08 100644 --- a/src/libs/3rdparty/cplusplus/FullySpecifiedType.h +++ b/src/libs/3rdparty/cplusplus/FullySpecifiedType.h @@ -106,7 +106,7 @@ public: bool operator != (const FullySpecifiedType &other) const; bool operator < (const FullySpecifiedType &other) const; - bool match(const FullySpecifiedType &otherTy, TypeMatcher *matcher) const; + bool match(const FullySpecifiedType &otherTy, Matcher *matcher) const; FullySpecifiedType simplified() const; diff --git a/src/libs/3rdparty/cplusplus/Literals.cpp b/src/libs/3rdparty/cplusplus/Literals.cpp index ca0cfc8735..17d02cf8bf 100644 --- a/src/libs/3rdparty/cplusplus/Literals.cpp +++ b/src/libs/3rdparty/cplusplus/Literals.cpp @@ -20,6 +20,7 @@ #include "Literals.h" #include "NameVisitor.h" +#include "Matcher.h" #include #include #include @@ -200,6 +201,13 @@ Identifier::~Identifier() void Identifier::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool Identifier::match0(const Name *otherName, Matcher *matcher) const +{ + if (const Identifier *id = otherName->asNameId()) + return matcher->match(this, id); + return false; +} + bool Identifier::isEqualTo(const Name *other) const { if (this == other) diff --git a/src/libs/3rdparty/cplusplus/Literals.h b/src/libs/3rdparty/cplusplus/Literals.h index 1fa70540e0..0ff88d4d09 100644 --- a/src/libs/3rdparty/cplusplus/Literals.h +++ b/src/libs/3rdparty/cplusplus/Literals.h @@ -113,6 +113,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; }; } // namespace CPlusPlus diff --git a/src/libs/3rdparty/cplusplus/Matcher.cpp b/src/libs/3rdparty/cplusplus/Matcher.cpp new file mode 100644 index 0000000000..447bec5118 --- /dev/null +++ b/src/libs/3rdparty/cplusplus/Matcher.cpp @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "Matcher.h" +#include "CoreTypes.h" +#include "Symbols.h" +#include "Names.h" +#include "Literals.h" + +using namespace CPlusPlus; + +Matcher::Matcher() +{ +} + +Matcher::~Matcher() +{ +} + +bool Matcher::match(const Type *type, const Type *otherType, Matcher *matcher) +{ + if (type == otherType) + return true; + if (!type) + return false; + + return type->match0(otherType, matcher); +} + +bool Matcher::match(const Name *name, const Name *otherName, Matcher *matcher) +{ + if (name == otherName) + return true; + if (!name || !otherName) + return false; + + return name->match0(otherName, matcher); +} + +bool Matcher::match(const UndefinedType *, const UndefinedType *) +{ + return true; +} + +bool Matcher::match(const VoidType *, const VoidType *) +{ + return true; +} + +bool Matcher::match(const IntegerType *type, const IntegerType *otherType) +{ + if (type == otherType) + return true; + + else if (type->kind() != otherType->kind()) + return false; + + return true; +} + +bool Matcher::match(const FloatType *type, const FloatType *otherType) +{ + if (type == otherType) + return true; + + else if (type->kind() != otherType->kind()) + return false; + + return true; +} + +bool Matcher::match(const PointerToMemberType *type, const PointerToMemberType *otherType) +{ + if (type == otherType) + return true; + + else if (! Name::match(type->memberName(), otherType->memberName(), this)) + return false; + + else if (! type->elementType().match(otherType->elementType(), this)) + return false; + + return true; +} + +bool Matcher::match(const PointerType *type, const PointerType *otherType) +{ + if (type == otherType) + return true; + + else if (! type->elementType().match(otherType->elementType(), this)) + return false; + + return true; +} + +bool Matcher::match(const ReferenceType *type, const ReferenceType *otherType) +{ + if (type == otherType) + return true; + + else if (type->isRvalueReference() != otherType->isRvalueReference()) + return false; + + else if (! type->elementType().match(otherType->elementType(), this)) + return false; + + return true; +} + +bool Matcher::match(const ArrayType *type, const ArrayType *otherType) +{ + if (type == otherType) + return true; + + else if (type->size() != otherType->size()) + return false; + + else if (! type->elementType().match(otherType->elementType(), this)) + return false; + + return true; +} + +bool Matcher::match(const NamedType *type, const NamedType *otherType) +{ + if (type == otherType) + return true; + + else if (! Name::match(type->name(), otherType->name(), this)) + return false; + + return true; +} + +bool Matcher::match(const Function *type, const Function *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const Enum *type, const Enum *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const Namespace *type, const Namespace *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const Template *type, const Template *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const Class *type, const Class *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const ObjCClass *type, const ObjCClass *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const ObjCProtocol *type, const ObjCProtocol *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const ObjCForwardClassDeclaration *type, const ObjCForwardClassDeclaration *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const ObjCForwardProtocolDeclaration *type, const ObjCForwardProtocolDeclaration *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const ObjCMethod *type, const ObjCMethod *otherType) +{ + if (type != otherType) + return false; + + return true; +} + +bool Matcher::match(const Identifier *name, const Identifier *otherName) +{ + if (name == otherName) + return true; + return name->equalTo(otherName); +} + +bool Matcher::match(const AnonymousNameId *name, const AnonymousNameId *otherName) +{ + return otherName && name->classTokenIndex() == otherName->classTokenIndex(); +} + +bool Matcher::match(const TemplateNameId *name, const TemplateNameId *otherName) +{ + const Identifier *l = name->identifier(); + const Identifier *r = otherName->identifier(); + if (! match(l, r)) + return false; + if (name->templateArgumentCount() != otherName->templateArgumentCount()) + return false; + for (unsigned i = 0, ei = name->templateArgumentCount(); i != ei; ++i) { + const FullySpecifiedType &l = name->templateArgumentAt(i); + const FullySpecifiedType &r = otherName->templateArgumentAt(i); + if (! l.match(r, this)) + return false; + } + return true; +} + +bool Matcher::match(const DestructorNameId *name, const DestructorNameId *otherName) +{ + return Name::match(name->name(), otherName->name(), this); +} + +bool Matcher::match(const OperatorNameId *name, const OperatorNameId *otherName) +{ + return name->kind() == otherName->kind(); +} + +bool Matcher::match(const ConversionNameId *name, const ConversionNameId *otherName) +{ + return name->type().match(otherName->type(), this); +} + +bool Matcher::match(const QualifiedNameId *name, const QualifiedNameId *otherName) +{ + if (Name::match(name->base(), otherName->base(), this)) + return Name::match(name->name(), otherName->name(), this); + return false; +} + +bool Matcher::match(const SelectorNameId *name, const SelectorNameId *otherName) +{ + const unsigned nc = name->nameCount(); + if (name->hasArguments() != otherName->hasArguments() || + nc != otherName->nameCount()) + return false; + for (unsigned i = 0; i < nc; ++i) + if (!Name::match(name->nameAt(i), otherName->nameAt(i), this)) + return false; + return true; +} diff --git a/src/libs/3rdparty/cplusplus/Matcher.h b/src/libs/3rdparty/cplusplus/Matcher.h new file mode 100644 index 0000000000..07a0e96b52 --- /dev/null +++ b/src/libs/3rdparty/cplusplus/Matcher.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef TYPEMATCHER_H +#define TYPEMATCHER_H + +#include "CPlusPlusForwardDeclarations.h" + +namespace CPlusPlus { + +class CPLUSPLUS_EXPORT Matcher +{ + Matcher(const Matcher &other); + void operator = (const Matcher &other); + +public: + Matcher(); + virtual ~Matcher(); + + static bool match(const Type *type, const Type *otherType, Matcher *matcher); + static bool match(const Name *name, const Name *otherName, Matcher *matcher); + + virtual bool match(const UndefinedType *type, const UndefinedType *otherType); + virtual bool match(const VoidType *type, const VoidType *otherType); + virtual bool match(const IntegerType *type, const IntegerType *otherType); + virtual bool match(const FloatType *type, const FloatType *otherType); + virtual bool match(const PointerToMemberType *type, const PointerToMemberType *otherType); + virtual bool match(const PointerType *type, const PointerType *otherType); + virtual bool match(const ReferenceType *type, const ReferenceType *otherType); + virtual bool match(const ArrayType *type, const ArrayType *otherType); + virtual bool match(const NamedType *type, const NamedType *otherType); + + virtual bool match(const Function *type, const Function *otherType); + virtual bool match(const Enum *type, const Enum *otherType); + virtual bool match(const Namespace *type, const Namespace *otherType); + virtual bool match(const Template *type, const Template *otherType); + virtual bool match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType); + virtual bool match(const Class *type, const Class *otherType); + virtual bool match(const ObjCClass *type, const ObjCClass *otherType); + virtual bool match(const ObjCProtocol *type, const ObjCProtocol *otherType); + virtual bool match(const ObjCForwardClassDeclaration *type, const ObjCForwardClassDeclaration *otherType); + virtual bool match(const ObjCForwardProtocolDeclaration *type, const ObjCForwardProtocolDeclaration *otherType); + virtual bool match(const ObjCMethod *type, const ObjCMethod *otherType); + + virtual bool match(const Identifier *name, const Identifier *otherName); + virtual bool match(const AnonymousNameId *name, const AnonymousNameId *otherName); + virtual bool match(const TemplateNameId *name, const TemplateNameId *otherName); + virtual bool match(const DestructorNameId *name, const DestructorNameId *otherName); + virtual bool match(const OperatorNameId *name, const OperatorNameId *otherName); + virtual bool match(const ConversionNameId *name, const ConversionNameId *otherName); + virtual bool match(const QualifiedNameId *name, const QualifiedNameId *otherName); + virtual bool match(const SelectorNameId *name, const SelectorNameId *otherName); +}; + +} // namespace CPlusPlus + +#endif // TYPEMATCHER_H diff --git a/src/libs/3rdparty/cplusplus/Name.cpp b/src/libs/3rdparty/cplusplus/Name.cpp index a8d453fc02..a7fe40f4b8 100644 --- a/src/libs/3rdparty/cplusplus/Name.cpp +++ b/src/libs/3rdparty/cplusplus/Name.cpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #include "Literals.h" +#include "Matcher.h" #include "Name.h" #include "Names.h" #include "NameVisitor.h" @@ -57,6 +58,11 @@ bool Name::isQualifiedNameId() const bool Name::isSelectorNameId() const { return asSelectorNameId() != 0; } +bool Name::match(const Name *name, const Name *otherName, Matcher *matcher) +{ + return Matcher::match(name, otherName, matcher); +} + void Name::accept(NameVisitor *visitor) const { if (visitor->preVisit(this)) diff --git a/src/libs/3rdparty/cplusplus/Name.h b/src/libs/3rdparty/cplusplus/Name.h index 9d19748471..ce6c7b336d 100644 --- a/src/libs/3rdparty/cplusplus/Name.h +++ b/src/libs/3rdparty/cplusplus/Name.h @@ -53,7 +53,9 @@ public: virtual const QualifiedNameId *asQualifiedNameId() const { return 0; } virtual const SelectorNameId *asSelectorNameId() const { return 0; } - virtual bool isEqualTo(const Name *other) const = 0; + virtual bool isEqualTo(const Name *other) const = 0; // TODO: remove me + + static bool match(const Name *name, const Name *otherName, Matcher *matcher); void accept(NameVisitor *visitor) const; static void accept(const Name *name, NameVisitor *visitor); @@ -65,6 +67,10 @@ public: protected: virtual void accept0(NameVisitor *visitor) const = 0; + +protected: // for Matcher + friend Matcher; + virtual bool match0(const Name *otherName, Matcher *matcher) const = 0; }; } // namespace CPlusPlus diff --git a/src/libs/3rdparty/cplusplus/Names.cpp b/src/libs/3rdparty/cplusplus/Names.cpp index 7f26ea1ad6..c0c2fe0d21 100644 --- a/src/libs/3rdparty/cplusplus/Names.cpp +++ b/src/libs/3rdparty/cplusplus/Names.cpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #include "Names.h" +#include "Matcher.h" #include "NameVisitor.h" #include "Literals.h" #include @@ -32,6 +33,13 @@ QualifiedNameId::~QualifiedNameId() void QualifiedNameId::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool QualifiedNameId::match0(const Name *otherName, Matcher *matcher) const +{ + if (const QualifiedNameId *name = otherName->asQualifiedNameId()) + return matcher->match(this, name); + return false; +} + const Identifier *QualifiedNameId::identifier() const { if (const Name *u = name()) @@ -71,6 +79,13 @@ DestructorNameId::~DestructorNameId() void DestructorNameId::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool DestructorNameId::match0(const Name *otherName, Matcher *matcher) const +{ + if (const DestructorNameId *name = otherName->asDestructorNameId()) + return matcher->match(this, name); + return false; +} + const Name *DestructorNameId::name() const { return _name; } @@ -96,6 +111,13 @@ TemplateNameId::~TemplateNameId() void TemplateNameId::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool TemplateNameId::match0(const Name *otherName, Matcher *matcher) const +{ + if (const TemplateNameId *other = otherName->asTemplateNameId()) + return matcher->match(this, other); + return false; +} + const Identifier *TemplateNameId::identifier() const { return _identifier; } @@ -117,7 +139,7 @@ bool TemplateNameId::isEqualTo(const Name *other) const return false; if (templateArgumentCount() != t->templateArgumentCount()) return false; - for (unsigned i = 0; i < templateArgumentCount(); ++i) { + for (unsigned i = 0, ei = templateArgumentCount(); i != ei; ++i) { const FullySpecifiedType &l = _templateArguments[i]; const FullySpecifiedType &r = t->_templateArguments[i]; if (! l.isEqualTo(r)) @@ -171,6 +193,13 @@ OperatorNameId::~OperatorNameId() void OperatorNameId::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool OperatorNameId::match0(const Name *otherName, Matcher *matcher) const +{ + if (const OperatorNameId *name = otherName->asOperatorNameId()) + return matcher->match(this, name); + return false; +} + OperatorNameId::Kind OperatorNameId::kind() const { return _kind; } @@ -198,6 +227,13 @@ ConversionNameId::~ConversionNameId() void ConversionNameId::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool ConversionNameId::match0(const Name *otherName, Matcher *matcher) const +{ + if (const ConversionNameId *name = otherName->asConversionNameId()) + return matcher->match(this, name); + return false; +} + FullySpecifiedType ConversionNameId::type() const { return _type; } @@ -221,6 +257,13 @@ SelectorNameId::~SelectorNameId() void SelectorNameId::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool SelectorNameId::match0(const Name *otherName, Matcher *matcher) const +{ + if (const SelectorNameId *name = otherName->asSelectorNameId()) + return matcher->match(this, name); + return false; +} + const Identifier *SelectorNameId::identifier() const { if (_names.empty()) @@ -276,6 +319,13 @@ unsigned AnonymousNameId::classTokenIndex() const void AnonymousNameId::accept0(NameVisitor *visitor) const { visitor->visit(this); } +bool AnonymousNameId::match0(const Name *otherName, Matcher *matcher) const +{ + if (const AnonymousNameId *id = otherName->asAnonymousNameId()) + return matcher->match(this, id); + return false; +} + const Identifier *AnonymousNameId::identifier() const { return 0; } diff --git a/src/libs/3rdparty/cplusplus/Names.h b/src/libs/3rdparty/cplusplus/Names.h index 855dd4987f..ca59da702f 100644 --- a/src/libs/3rdparty/cplusplus/Names.h +++ b/src/libs/3rdparty/cplusplus/Names.h @@ -48,6 +48,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; private: const Name *_base; @@ -71,6 +72,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; private: const Name *_name; @@ -115,6 +117,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; private: const Identifier *_identifier; @@ -194,6 +197,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; private: Kind _kind; @@ -215,6 +219,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; private: FullySpecifiedType _type; @@ -247,6 +252,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; private: std::vector _names; @@ -269,6 +275,7 @@ public: protected: virtual void accept0(NameVisitor *visitor) const; + virtual bool match0(const Name *otherName, Matcher *matcher) const; private: unsigned _classTokenIndex; diff --git a/src/libs/3rdparty/cplusplus/SafeMatcher.cpp b/src/libs/3rdparty/cplusplus/SafeMatcher.cpp new file mode 100644 index 0000000000..4b139f754f --- /dev/null +++ b/src/libs/3rdparty/cplusplus/SafeMatcher.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "CoreTypes.h" +#include "Names.h" +#include "SafeMatcher.h" + +using namespace std; +using namespace CPlusPlus; + +namespace { +template +class Blocker +{ + vector &v; + +public: + Blocker(vector &v, const T *el1, const T *el2) + : v(v) + { v.push_back(el1); v.push_back(el2); } + ~Blocker() { v.pop_back(); v.pop_back(); } +}; + +template +bool isBlocked(const vector &v, const U *t1, const U *t2) +{ + for (size_t i = v.size(); i > 0; ) { + const T *t = v[--i]; + if (t == t1 || t == t2) + return true; + } + + return false; +} +} // anonymous namespace + +SafeMatcher::SafeMatcher() +{ + _blockedTypes.reserve(8); + _blockedNames.reserve(8); +} + +SafeMatcher::~SafeMatcher() +{} + +bool SafeMatcher::match(const PointerToMemberType *type, const PointerToMemberType *otherType) +{ + if (isBlocked(_blockedTypes, type, otherType)) + return true; + + Blocker b(_blockedTypes, type, otherType); + return Matcher::match(type, otherType); +} + +bool SafeMatcher::match(const PointerType *type, const PointerType *otherType) +{ + if (isBlocked(_blockedTypes, type, otherType)) + return true; + + Blocker b(_blockedTypes, type, otherType); + return Matcher::match(type, otherType); +} + +bool SafeMatcher::match(const ReferenceType *type, const ReferenceType *otherType) +{ + if (isBlocked(_blockedTypes, type, otherType)) + return true; + + Blocker b(_blockedTypes, type, otherType); + return Matcher::match(type, otherType); +} + +bool SafeMatcher::match(const ArrayType *type, const ArrayType *otherType) +{ + if (isBlocked(_blockedTypes, type, otherType)) + return true; + + Blocker b(_blockedTypes, type, otherType); + return Matcher::match(type, otherType); +} + +bool SafeMatcher::match(const NamedType *type, const NamedType *otherType) +{ + if (isBlocked(_blockedTypes, type, otherType)) + return true; + + Blocker b(_blockedTypes, type, otherType); + return Matcher::match(type, otherType); +} + +bool SafeMatcher::match(const TemplateNameId *name, const TemplateNameId *otherName) +{ + if (isBlocked(_blockedNames, name, otherName)) + return true; + + Blocker b(_blockedNames, name, otherName); + return Matcher::match(name, otherName); +} + +bool SafeMatcher::match(const DestructorNameId *name, const DestructorNameId *otherName) +{ + if (isBlocked(_blockedNames, name, otherName)) + return true; + + Blocker b(_blockedNames, name, otherName); + return Matcher::match(name, otherName); +} + +bool SafeMatcher::match(const ConversionNameId *name, const ConversionNameId *otherName) +{ + if (isBlocked(_blockedNames, name, otherName)) + return true; + + Blocker b(_blockedNames, name, otherName); + return Matcher::match(name, otherName); +} + +bool SafeMatcher::match(const QualifiedNameId *name, const QualifiedNameId *otherName) +{ + if (isBlocked(_blockedNames, name, otherName)) + return true; + + Blocker b(_blockedNames, name, otherName); + return Matcher::match(name, otherName); +} + +bool SafeMatcher::match(const SelectorNameId *name, const SelectorNameId *otherName) +{ + if (isBlocked(_blockedNames, name, otherName)) + return true; + + Blocker b(_blockedNames, name, otherName); + return Matcher::match(name, otherName); +} diff --git a/src/libs/3rdparty/cplusplus/SafeMatcher.h b/src/libs/3rdparty/cplusplus/SafeMatcher.h new file mode 100644 index 0000000000..90c1711bc5 --- /dev/null +++ b/src/libs/3rdparty/cplusplus/SafeMatcher.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CPLUSPLUS_SAFETYPEMATCHER_H +#define CPLUSPLUS_SAFETYPEMATCHER_H + +#include "Matcher.h" + +#include + +namespace CPlusPlus { + +class SafeMatcher: public Matcher +{ +public: + SafeMatcher(); + ~SafeMatcher() override; + + bool match(const PointerToMemberType *type, const PointerToMemberType *otherType) override; + bool match(const PointerType *type, const PointerType *otherType) override; + bool match(const ReferenceType *type, const ReferenceType *otherType) override; + bool match(const ArrayType *type, const ArrayType *otherType) override; + bool match(const NamedType *type, const NamedType *otherType) override; + + bool match(const TemplateNameId *name, const TemplateNameId *otherName) override; + bool match(const DestructorNameId *name, const DestructorNameId *otherName) override; + bool match(const ConversionNameId *name, const ConversionNameId *otherName) override; + bool match(const QualifiedNameId *name, const QualifiedNameId *otherName) override; + bool match(const SelectorNameId *name, const SelectorNameId *otherName) override; + +private: + std::vector _blockedTypes; + std::vector _blockedNames; +}; + +} // CPlusPlus namespace + +#endif // CPLUSPLUS_SAFETYPEMATCHER_H diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp index bae2992293..f8b990139f 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.cpp +++ b/src/libs/3rdparty/cplusplus/Symbols.cpp @@ -22,7 +22,7 @@ #include "Names.h" #include "TypeVisitor.h" #include "SymbolVisitor.h" -#include "TypeMatcher.h" +#include "Matcher.h" #include "Scope.h" #include "Templates.h" @@ -259,7 +259,7 @@ bool Function::isEqualTo(const Type *other) const void Function::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool Function::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool Function::match0(const Type *otherType, Matcher *matcher) const { if (const Function *otherTy = otherType->asFunctionType()) return matcher->match(this, otherTy); @@ -487,7 +487,7 @@ void Enum::setScoped(bool scoped) void Enum::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool Enum::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool Enum::match0(const Type *otherType, Matcher *matcher) const { if (const Enum *otherTy = otherType->asEnumType()) return matcher->match(this, otherTy); @@ -558,7 +558,7 @@ void Template::visitSymbol0(SymbolVisitor *visitor) void Template::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool Template::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool Template::match0(const Type *otherType, Matcher *matcher) const { if (const Template *otherTy = otherType->asTemplateType()) return matcher->match(this, otherTy); @@ -593,7 +593,7 @@ bool Namespace::isEqualTo(const Type *other) const void Namespace::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool Namespace::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool Namespace::match0(const Type *otherType, Matcher *matcher) const { if (const Namespace *otherTy = otherType->asNamespaceType()) return matcher->match(this, otherTy); @@ -676,7 +676,7 @@ void ForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor) void ForwardClassDeclaration::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ForwardClassDeclaration::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ForwardClassDeclaration::match0(const Type *otherType, Matcher *matcher) const { if (const ForwardClassDeclaration *otherTy = otherType->asForwardClassDeclarationType()) return matcher->match(this, otherTy); @@ -718,7 +718,7 @@ void Class::setClassKey(Key key) void Class::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool Class::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool Class::match0(const Type *otherType, Matcher *matcher) const { if (const Class *otherTy = otherType->asClassType()) return matcher->match(this, otherTy); @@ -932,7 +932,7 @@ void ObjCClass::visitSymbol0(SymbolVisitor *visitor) void ObjCClass::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ObjCClass::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ObjCClass::match0(const Type *otherType, Matcher *matcher) const { if (const ObjCClass *otherTy = otherType->asObjCClassType()) return matcher->match(this, otherTy); @@ -992,7 +992,7 @@ void ObjCProtocol::visitSymbol0(SymbolVisitor *visitor) void ObjCProtocol::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ObjCProtocol::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ObjCProtocol::match0(const Type *otherType, Matcher *matcher) const { if (const ObjCProtocol *otherTy = otherType->asObjCProtocolType()) return matcher->match(this, otherTy); @@ -1036,7 +1036,7 @@ void ObjCForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor) void ObjCForwardClassDeclaration::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ObjCForwardClassDeclaration::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ObjCForwardClassDeclaration::match0(const Type *otherType, Matcher *matcher) const { if (const ObjCForwardClassDeclaration *otherTy = otherType->asObjCForwardClassDeclarationType()) return matcher->match(this, otherTy); @@ -1080,7 +1080,7 @@ void ObjCForwardProtocolDeclaration::visitSymbol0(SymbolVisitor *visitor) void ObjCForwardProtocolDeclaration::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ObjCForwardProtocolDeclaration::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ObjCForwardProtocolDeclaration::match0(const Type *otherType, Matcher *matcher) const { if (const ObjCForwardProtocolDeclaration *otherTy = otherType->asObjCForwardProtocolDeclarationType()) return matcher->match(this, otherTy); @@ -1129,7 +1129,7 @@ bool ObjCMethod::isEqualTo(const Type *other) const void ObjCMethod::accept0(TypeVisitor *visitor) { visitor->visit(this); } -bool ObjCMethod::matchType0(const Type *otherType, TypeMatcher *matcher) const +bool ObjCMethod::match0(const Type *otherType, Matcher *matcher) const { if (const ObjCMethod *otherTy = otherType->asObjCMethodType()) return matcher->match(this, otherTy); diff --git a/src/libs/3rdparty/cplusplus/Symbols.h b/src/libs/3rdparty/cplusplus/Symbols.h index 63432e33f1..cc4913c2c8 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.h +++ b/src/libs/3rdparty/cplusplus/Symbols.h @@ -251,7 +251,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; }; class CPLUSPLUS_EXPORT Enum: public Scope, public Type @@ -285,7 +285,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: bool _isScoped; @@ -375,7 +375,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: FullySpecifiedType _returnType; @@ -428,7 +428,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; }; @@ -466,7 +466,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: bool _isInline; @@ -544,7 +544,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: Key _key; @@ -686,7 +686,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; }; class CPLUSPLUS_EXPORT ObjCProtocol: public Scope, public Type @@ -721,7 +721,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: std::vector _protocols; @@ -753,7 +753,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; }; class CPLUSPLUS_EXPORT ObjCClass: public Scope, public Type @@ -798,7 +798,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: const Name *_categoryName; @@ -850,7 +850,7 @@ public: protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const; + virtual bool match0(const Type *otherType, Matcher *matcher) const; private: FullySpecifiedType _returnType; diff --git a/src/libs/3rdparty/cplusplus/Type.cpp b/src/libs/3rdparty/cplusplus/Type.cpp index 8f1c0c4cd2..9a868d95f4 100644 --- a/src/libs/3rdparty/cplusplus/Type.cpp +++ b/src/libs/3rdparty/cplusplus/Type.cpp @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include "Matcher.h" #include "Type.h" #include "TypeVisitor.h" #include "CoreTypes.h" @@ -106,8 +107,7 @@ void Type::accept(Type *type, TypeVisitor *visitor) type->accept(visitor); } -bool Type::matchType(const Type *otherType, TypeMatcher *matcher) const +bool Type::match(const Type *type, const Type *otherType, Matcher *matcher) { - return matchType0(otherType, matcher); + return Matcher::match(type, otherType, matcher); } - diff --git a/src/libs/3rdparty/cplusplus/Type.h b/src/libs/3rdparty/cplusplus/Type.h index fe686807f5..77cd20a8c3 100644 --- a/src/libs/3rdparty/cplusplus/Type.h +++ b/src/libs/3rdparty/cplusplus/Type.h @@ -97,21 +97,17 @@ public: void accept(TypeVisitor *visitor); static void accept(Type *type, TypeVisitor *visitor); - static bool matchType(const Type *type, const Type *otherType, TypeMatcher *matcher) - { - if (! type) - return type == otherType; + static bool match(const Type *type, const Type *otherType, Matcher *matcher); - return type->matchType(otherType, matcher); - } - - bool matchType(const Type *otherType, TypeMatcher *matcher) const; virtual bool isEqualTo(const Type *other) const = 0; // ### remove protected: virtual void accept0(TypeVisitor *visitor) = 0; - virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const = 0; + +protected: // for Matcher + friend Matcher; + virtual bool match0(const Type *otherType, Matcher *matcher) const = 0; }; } // namespace CPlusPlus diff --git a/src/libs/3rdparty/cplusplus/TypeMatcher.cpp b/src/libs/3rdparty/cplusplus/TypeMatcher.cpp deleted file mode 100644 index 95c7df7f76..0000000000 --- a/src/libs/3rdparty/cplusplus/TypeMatcher.cpp +++ /dev/null @@ -1,211 +0,0 @@ - -#include "TypeMatcher.h" -#include "CoreTypes.h" -#include "Symbols.h" -#include "Names.h" -#include "Literals.h" - -using namespace CPlusPlus; - -TypeMatcher::TypeMatcher() -{ -} - -TypeMatcher::~TypeMatcher() -{ -} - -bool TypeMatcher::isEqualTo(const Name *name, const Name *otherName) const -{ - if (name == otherName) - return true; - - else if (! name || ! otherName) - return false; - - return name->isEqualTo(otherName); -} - -bool TypeMatcher::match(const UndefinedType *, const UndefinedType *) -{ - return true; -} - -bool TypeMatcher::match(const VoidType *, const VoidType *) -{ - return true; -} - -bool TypeMatcher::match(const IntegerType *type, const IntegerType *otherType) -{ - if (type == otherType) - return true; - - else if (type->kind() != otherType->kind()) - return false; - - return true; -} - -bool TypeMatcher::match(const FloatType *type, const FloatType *otherType) -{ - if (type == otherType) - return true; - - else if (type->kind() != otherType->kind()) - return false; - - return true; -} - -bool TypeMatcher::match(const PointerToMemberType *type, const PointerToMemberType *otherType) -{ - if (type == otherType) - return true; - - else if (! isEqualTo(type->memberName(), otherType->memberName())) - return false; - - else if (! type->elementType().match(otherType->elementType(), this)) - return false; - - return true; -} - -bool TypeMatcher::match(const PointerType *type, const PointerType *otherType) -{ - if (type == otherType) - return true; - - else if (! type->elementType().match(otherType->elementType(), this)) - return false; - - return true; -} - -bool TypeMatcher::match(const ReferenceType *type, const ReferenceType *otherType) -{ - if (type == otherType) - return true; - - else if (type->isRvalueReference() != otherType->isRvalueReference()) - return false; - - else if (! type->elementType().match(otherType->elementType(), this)) - return false; - - return true; -} - -bool TypeMatcher::match(const ArrayType *type, const ArrayType *otherType) -{ - if (type == otherType) - return true; - - else if (type->size() != otherType->size()) - return false; - - else if (! type->elementType().match(otherType->elementType(), this)) - return false; - - return true; -} - -bool TypeMatcher::match(const NamedType *type, const NamedType *otherType) -{ - if (type == otherType) - return true; - - else if (! isEqualTo(type->name(), otherType->name())) - return false; - - return true; -} - -bool TypeMatcher::match(const Function *type, const Function *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const Enum *type, const Enum *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const Namespace *type, const Namespace *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const Template *type, const Template *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const Class *type, const Class *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const ObjCClass *type, const ObjCClass *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const ObjCProtocol *type, const ObjCProtocol *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const ObjCForwardClassDeclaration *type, const ObjCForwardClassDeclaration *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const ObjCForwardProtocolDeclaration *type, const ObjCForwardProtocolDeclaration *otherType) -{ - if (type != otherType) - return false; - - return true; -} - -bool TypeMatcher::match(const ObjCMethod *type, const ObjCMethod *otherType) -{ - if (type != otherType) - return false; - - return true; -} diff --git a/src/libs/3rdparty/cplusplus/TypeMatcher.h b/src/libs/3rdparty/cplusplus/TypeMatcher.h deleted file mode 100644 index b44c9e9755..0000000000 --- a/src/libs/3rdparty/cplusplus/TypeMatcher.h +++ /dev/null @@ -1,45 +0,0 @@ - -#ifndef TYPEMATCHER_H -#define TYPEMATCHER_H - -#include "CPlusPlusForwardDeclarations.h" - -namespace CPlusPlus { - -class CPLUSPLUS_EXPORT TypeMatcher -{ - TypeMatcher(const TypeMatcher &other); - void operator = (const TypeMatcher &other); - -public: - TypeMatcher(); - virtual ~TypeMatcher(); - - virtual bool match(const UndefinedType *type, const UndefinedType *otherType); - virtual bool match(const VoidType *type, const VoidType *otherType); - virtual bool match(const IntegerType *type, const IntegerType *otherType); - virtual bool match(const FloatType *type, const FloatType *otherType); - virtual bool match(const PointerToMemberType *type, const PointerToMemberType *otherType); - virtual bool match(const PointerType *type, const PointerType *otherType); - virtual bool match(const ReferenceType *type, const ReferenceType *otherType); - virtual bool match(const ArrayType *type, const ArrayType *otherType); - virtual bool match(const NamedType *type, const NamedType *otherType); - - virtual bool match(const Function *type, const Function *otherType); - virtual bool match(const Enum *type, const Enum *otherType); - virtual bool match(const Namespace *type, const Namespace *otherType); - virtual bool match(const Template *type, const Template *otherType); - virtual bool match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType); - virtual bool match(const Class *type, const Class *otherType); - virtual bool match(const ObjCClass *type, const ObjCClass *otherType); - virtual bool match(const ObjCProtocol *type, const ObjCProtocol *otherType); - virtual bool match(const ObjCForwardClassDeclaration *type, const ObjCForwardClassDeclaration *otherType); - virtual bool match(const ObjCForwardProtocolDeclaration *type, const ObjCForwardProtocolDeclaration *otherType); - virtual bool match(const ObjCMethod *type, const ObjCMethod *otherType); - - bool isEqualTo(const Name *name, const Name *otherName) const; -}; - -} // namespace CPlusPlus - -#endif // TYPEMATCHER_H diff --git a/src/libs/3rdparty/cplusplus/cplusplus.pri b/src/libs/3rdparty/cplusplus/cplusplus.pri index 004ef4014e..fac7129452 100644 --- a/src/libs/3rdparty/cplusplus/cplusplus.pri +++ b/src/libs/3rdparty/cplusplus/cplusplus.pri @@ -6,7 +6,7 @@ HEADERS += \ $$PWD/ASTMatcher.h \ $$PWD/ASTPatternBuilder.h \ $$PWD/ASTfwd.h \ - $$PWD/TypeMatcher.h \ + $$PWD/Matcher.h \ $$PWD/CPlusPlusForwardDeclarations.h \ $$PWD/Control.h \ $$PWD/CoreTypes.h \ @@ -31,7 +31,8 @@ HEADERS += \ $$PWD/TypeVisitor.h \ $$PWD/ObjectiveCTypeQualifiers.h \ $$PWD/QtContextKeywords.h \ - $$PWD/Templates.h + $$PWD/Templates.h \ + $$PWD/SafeMatcher.h SOURCES += \ $$PWD/AST.cpp \ @@ -41,7 +42,7 @@ SOURCES += \ $$PWD/ASTClone.cpp \ $$PWD/ASTPatternBuilder.cpp \ $$PWD/ASTMatcher.cpp \ - $$PWD/TypeMatcher.cpp \ + $$PWD/Matcher.cpp \ $$PWD/Control.cpp \ $$PWD/CoreTypes.cpp \ $$PWD/DiagnosticClient.cpp \ @@ -67,4 +68,5 @@ SOURCES += \ $$PWD/Type.cpp \ $$PWD/TypeVisitor.cpp \ $$PWD/QtContextKeywords.cpp \ - $$PWD/Templates.cpp + $$PWD/Templates.cpp \ + $$PWD/SafeMatcher.cpp diff --git a/src/libs/cplusplus/AlreadyConsideredClassContainer.h b/src/libs/cplusplus/AlreadyConsideredClassContainer.h index 4ada3866c4..cc819ab80a 100644 --- a/src/libs/cplusplus/AlreadyConsideredClassContainer.h +++ b/src/libs/cplusplus/AlreadyConsideredClassContainer.h @@ -1,6 +1,8 @@ #ifndef CPLUSPLUS_ALREADYCONSIDEREDCLASSCONTAINER_H #define CPLUSPLUS_ALREADYCONSIDEREDCLASSCONTAINER_H +#include + #include namespace CPlusPlus { @@ -21,8 +23,9 @@ public: if (_container.contains(item)) return true; + SafeMatcher matcher; foreach (const T *existingItem, _container) { - if (existingItem->isEqualTo(item)) + if (Matcher::match(existingItem, item, &matcher)) return true; } diff --git a/src/libs/cplusplus/cplusplus.qbs b/src/libs/cplusplus/cplusplus.qbs index 3ea4a34b90..4499a4b094 100644 --- a/src/libs/cplusplus/cplusplus.qbs +++ b/src/libs/cplusplus/cplusplus.qbs @@ -47,6 +47,8 @@ QtcLibrary { "LiteralTable.h", "Literals.cpp", "Literals.h", + "Matcher.cpp", + "Matcher.h", "MemoryPool.cpp", "MemoryPool.h", "Name.cpp", @@ -62,6 +64,8 @@ QtcLibrary { "Parser.h", "QtContextKeywords.cpp", "QtContextKeywords.h", + "SafeMatcher.cpp", + "SafeMatcher.h", "Scope.cpp", "Scope.h", "Symbol.cpp", @@ -78,8 +82,6 @@ QtcLibrary { "TranslationUnit.h", "Type.cpp", "Type.h", - "TypeMatcher.cpp", - "TypeMatcher.h", "TypeVisitor.cpp", "TypeVisitor.h", ] -- cgit v1.2.3