forked from qt-creator/qt-creator
C++: improve support for anonymous classes
Fix: * highlighting * find usages * follow symbol * code completion Task-number: QTCREATORBUG-6497 Task-number: QTCREATORBUG-8963 Task-number: QTCREATORBUG-3610 Task-number: QTCREATORBUG-7579 Change-Id: I3dcaf1c515d0199c3e6bee72284fbb40064686ee Reviewed-by: Petar Perisin <petar.perisin@gmail.com> Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
committed by
Erik Verbruggen
parent
a2b2857b44
commit
080bf4ecb8
21
src/libs/3rdparty/cplusplus/AST.h
vendored
21
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -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:
|
||||
|
||||
7
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
7
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -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;
|
||||
|
||||
8
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
8
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
@@ -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())
|
||||
|
||||
10
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
10
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -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;
|
||||
|
||||
1
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
1
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
@@ -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);
|
||||
|
||||
@@ -543,6 +543,12 @@ public:
|
||||
return __ast;
|
||||
}
|
||||
|
||||
AnonymousNameAST *AnonymousName()
|
||||
{
|
||||
AnonymousNameAST *__ast = new (&pool) AnonymousNameAST;
|
||||
return __ast;
|
||||
}
|
||||
|
||||
SimpleNameAST *SimpleName()
|
||||
{
|
||||
SimpleNameAST *__ast = new (&pool) SimpleNameAST;
|
||||
|
||||
7
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
7
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
@@ -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)) {
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/ASTVisitor.h
vendored
2
src/libs/3rdparty/cplusplus/ASTVisitor.h
vendored
@@ -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 *) {}
|
||||
|
||||
1
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
1
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
@@ -34,6 +34,7 @@ class ASTMatcher;
|
||||
class AccessDeclarationAST;
|
||||
class AliasDeclarationAST;
|
||||
class AlignofExpressionAST;
|
||||
class AnonymousNameAST;
|
||||
class ArrayAccessAST;
|
||||
class ArrayDeclaratorAST;
|
||||
class ArrayInitializerAST;
|
||||
|
||||
8
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
8
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -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
|
||||
|
||||
|
||||
1
src/libs/3rdparty/cplusplus/Bind.h
vendored
1
src/libs/3rdparty/cplusplus/Bind.h
vendored
@@ -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);
|
||||
|
||||
@@ -73,6 +73,7 @@ class SymbolTable;
|
||||
class NameVisitor;
|
||||
class Name;
|
||||
class Identifier;
|
||||
class AnonymousNameId;
|
||||
class TemplateNameId;
|
||||
class DestructorNameId;
|
||||
class OperatorNameId;
|
||||
|
||||
17
src/libs/3rdparty/cplusplus/Control.cpp
vendored
17
src/libs/3rdparty/cplusplus/Control.cpp
vendored
@@ -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);
|
||||
|
||||
3
src/libs/3rdparty/cplusplus/Control.h
vendored
3
src/libs/3rdparty/cplusplus/Control.h
vendored
@@ -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,
|
||||
|
||||
3
src/libs/3rdparty/cplusplus/Name.cpp
vendored
3
src/libs/3rdparty/cplusplus/Name.cpp
vendored
@@ -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; }
|
||||
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/Name.h
vendored
2
src/libs/3rdparty/cplusplus/Name.h
vendored
@@ -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; }
|
||||
|
||||
1
src/libs/3rdparty/cplusplus/NameVisitor.h
vendored
1
src/libs/3rdparty/cplusplus/NameVisitor.h
vendored
@@ -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 *) {}
|
||||
|
||||
26
src/libs/3rdparty/cplusplus/Names.cpp
vendored
26
src/libs/3rdparty/cplusplus/Names.cpp
vendored
@@ -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;
|
||||
}
|
||||
|
||||
23
src/libs/3rdparty/cplusplus/Names.h
vendored
23
src/libs/3rdparty/cplusplus/Names.h
vendored
@@ -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
|
||||
|
||||
6
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
6
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user