forked from qt-creator/qt-creator
Improved template instantiation.
This commit is contained in:
@@ -194,6 +194,22 @@ protected:
|
|||||||
{ Q_ASSERT(false); }
|
{ Q_ASSERT(false); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
|
||||||
|
{
|
||||||
|
QList<_Tp> uniqueList;
|
||||||
|
QSet<_Tp> processed;
|
||||||
|
foreach (const _Tp &r, results) {
|
||||||
|
if (processed.contains(r))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
processed.insert(r);
|
||||||
|
uniqueList.append(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return uniqueList;
|
||||||
|
}
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@@ -212,7 +228,7 @@ QList<ResolveExpression::Result> ResolveExpression::operator()(ExpressionAST *as
|
|||||||
{
|
{
|
||||||
const QList<Result> previousResults = switchResults(QList<Result>());
|
const QList<Result> previousResults = switchResults(QList<Result>());
|
||||||
accept(ast);
|
accept(ast);
|
||||||
return switchResults(previousResults);
|
return removeDuplicates(switchResults(previousResults));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ResolveExpression::Result>
|
QList<ResolveExpression::Result>
|
||||||
@@ -482,7 +498,7 @@ bool ResolveExpression::visit(QualifiedNameAST *ast)
|
|||||||
if (NamedType *namedTy = symbol->type()->asNamedType()) {
|
if (NamedType *namedTy = symbol->type()->asNamedType()) {
|
||||||
const Result r(namedTy, symbol);
|
const Result r(namedTy, symbol);
|
||||||
const QList<Symbol *> resolvedClasses =
|
const QList<Symbol *> resolvedClasses =
|
||||||
resolveClass(r, _context);
|
resolveClass(namedTy->name(), r, _context);
|
||||||
if (resolvedClasses.count()) {
|
if (resolvedClasses.count()) {
|
||||||
foreach (Symbol *s, resolvedClasses) {
|
foreach (Symbol *s, resolvedClasses) {
|
||||||
addResult(s->type(), s);
|
addResult(s->type(), s);
|
||||||
@@ -591,7 +607,7 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
|
|||||||
addResult(arrTy->elementType(), contextSymbol);
|
addResult(arrTy->elementType(), contextSymbol);
|
||||||
} else if (NamedType *namedTy = ty->asNamedType()) {
|
} else if (NamedType *namedTy = ty->asNamedType()) {
|
||||||
const QList<Symbol *> classObjectCandidates =
|
const QList<Symbol *> classObjectCandidates =
|
||||||
symbolsForDotAcccess(p, _context);
|
symbolsForDotAcccess(namedTy->name(), p, _context);
|
||||||
|
|
||||||
foreach (Symbol *classObject, classObjectCandidates) {
|
foreach (Symbol *classObject, classObjectCandidates) {
|
||||||
const QList<Result> overloads =
|
const QList<Result> overloads =
|
||||||
@@ -630,30 +646,38 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Symbol *> ResolveExpression::resolveBaseExpression(const QList<Result> &baseResults, int accessOp) const
|
QList<ResolveExpression::Result>
|
||||||
|
ResolveExpression::resolveBaseExpression(const QList<Result> &baseResults, int accessOp) const
|
||||||
{
|
{
|
||||||
QList<Symbol *> classObjectCandidates;
|
QList<Result> results;
|
||||||
|
|
||||||
if (baseResults.isEmpty())
|
if (baseResults.isEmpty())
|
||||||
return classObjectCandidates;
|
return results;
|
||||||
|
|
||||||
Result result = baseResults.first();
|
Result result = baseResults.first();
|
||||||
|
FullySpecifiedType ty = result.first.simplified();
|
||||||
|
Symbol *lastVisibleSymbol = result.second;
|
||||||
|
|
||||||
if (accessOp == T_ARROW) {
|
if (accessOp == T_ARROW) {
|
||||||
FullySpecifiedType ty = result.first.simplified();
|
if (lastVisibleSymbol && ty->isClassType() && ! lastVisibleSymbol->isClass()) {
|
||||||
|
// ### remove ! lastVisibleSymbol->isClass() from the condition.
|
||||||
|
results.append(Result(ty, lastVisibleSymbol));
|
||||||
|
|
||||||
if (Class *classTy = ty->asClassType()) {
|
|
||||||
Symbol *symbol = result.second;
|
|
||||||
if (symbol && ! symbol->isClass())
|
|
||||||
classObjectCandidates.append(classTy);
|
|
||||||
} else if (NamedType *namedTy = ty->asNamedType()) {
|
} else if (NamedType *namedTy = ty->asNamedType()) {
|
||||||
// ### This code is pretty slow.
|
// ### This code is pretty slow.
|
||||||
const QList<Symbol *> candidates = _context.resolve(namedTy->name());
|
const QList<Symbol *> candidates = _context.resolve(namedTy->name());
|
||||||
|
|
||||||
foreach (Symbol *candidate, candidates) {
|
foreach (Symbol *candidate, candidates) {
|
||||||
if (candidate->isTypedef()) {
|
if (candidate->isTypedef()) {
|
||||||
ty = candidate->type();
|
FullySpecifiedType declTy = candidate->type().simplified();
|
||||||
const ResolveExpression::Result r(ty, candidate);
|
const ResolveExpression::Result r(declTy, candidate);
|
||||||
|
|
||||||
|
// update the result
|
||||||
result = r;
|
result = r;
|
||||||
|
|
||||||
|
// refresh the cached ty and lastVisibileSymbol.
|
||||||
|
ty = result.first.simplified();
|
||||||
|
lastVisibleSymbol = result.second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,82 +686,49 @@ QList<Symbol *> ResolveExpression::resolveBaseExpression(const QList<Result> &ba
|
|||||||
if (NamedType *namedTy = ty->asNamedType()) {
|
if (NamedType *namedTy = ty->asNamedType()) {
|
||||||
ResolveClass resolveClass;
|
ResolveClass resolveClass;
|
||||||
|
|
||||||
const QList<Symbol *> candidates = resolveClass(result, _context);
|
const QList<Symbol *> candidates = resolveClass(namedTy->name(), result, _context);
|
||||||
foreach (Symbol *classObject, candidates) {
|
foreach (Symbol *classObject, candidates) {
|
||||||
const QList<Result> overloads = resolveArrowOperator(result, namedTy,
|
const QList<Result> overloads = resolveArrowOperator(result, namedTy,
|
||||||
classObject->asClass());
|
classObject->asClass());
|
||||||
|
|
||||||
foreach (Result r, overloads) {
|
foreach (const Result &r, overloads) {
|
||||||
FullySpecifiedType ty = r.first;
|
FullySpecifiedType typeOfOverloadFunction = r.first.simplified();
|
||||||
Function *funTy = ty->asFunctionType();
|
Symbol *lastVisibleSymbol = r.second;
|
||||||
|
Function *funTy = typeOfOverloadFunction->asFunctionType();
|
||||||
if (! funTy)
|
if (! funTy)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ty = funTy->returnType().simplified();
|
typeOfOverloadFunction = funTy->returnType().simplified();
|
||||||
|
|
||||||
if (PointerType *ptrTy = ty->asPointerType()) {
|
if (PointerType *ptrTy = typeOfOverloadFunction->asPointerType()) {
|
||||||
if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
|
FullySpecifiedType elementTy = ptrTy->elementType().simplified();
|
||||||
const QList<Symbol *> classes =
|
|
||||||
resolveClass(namedTy, result, _context);
|
|
||||||
|
|
||||||
foreach (Symbol *c, classes) {
|
if (elementTy->isNamedType())
|
||||||
if (! classObjectCandidates.contains(c))
|
results.append(Result(elementTy, lastVisibleSymbol));
|
||||||
classObjectCandidates.append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (PointerType *ptrTy = ty->asPointerType()) {
|
} else if (PointerType *ptrTy = ty->asPointerType()) {
|
||||||
if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
|
FullySpecifiedType elementTy = ptrTy->elementType().simplified();
|
||||||
ResolveClass resolveClass;
|
|
||||||
|
|
||||||
const QList<Symbol *> classes = resolveClass(namedTy, result,
|
if (elementTy->isNamedType() || elementTy->isClassType())
|
||||||
_context);
|
results.append(Result(elementTy, lastVisibleSymbol));
|
||||||
|
|
||||||
foreach (Symbol *c, classes) {
|
|
||||||
if (! classObjectCandidates.contains(c))
|
|
||||||
classObjectCandidates.append(c);
|
|
||||||
}
|
|
||||||
} else if (Class *classTy = ptrTy->elementType()->asClassType()) {
|
|
||||||
// typedef struct { int x } *Ptr;
|
|
||||||
// Ptr p;
|
|
||||||
// p->
|
|
||||||
classObjectCandidates.append(classTy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (accessOp == T_DOT) {
|
} else if (accessOp == T_DOT) {
|
||||||
FullySpecifiedType ty = result.first.simplified();
|
if (ty->isClassType() || ty->isNamedType())
|
||||||
|
results.append(Result(ty, lastVisibleSymbol));
|
||||||
|
|
||||||
NamedType *namedTy = 0;
|
if (Function *fun = ty->asFunctionType()) {
|
||||||
|
Scope *funScope = fun->scope();
|
||||||
|
|
||||||
if (Class *classTy = ty->asClassType()) {
|
if (funScope && (funScope->isBlockScope() || funScope->isNamespaceScope())) {
|
||||||
Symbol *symbol = result.second;
|
FullySpecifiedType retTy = fun->returnType().simplified();
|
||||||
if (symbol && ! symbol->isClass())
|
results.append(Result(retTy, lastVisibleSymbol));
|
||||||
classObjectCandidates.append(classTy);
|
|
||||||
} else {
|
|
||||||
namedTy = ty->asNamedType();
|
|
||||||
if (! namedTy) {
|
|
||||||
Function *fun = ty->asFunctionType();
|
|
||||||
if (fun && fun->scope() && (fun->scope()->isBlockScope() || fun->scope()->isNamespaceScope()))
|
|
||||||
namedTy = fun->returnType()->asNamedType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (namedTy) {
|
|
||||||
ResolveClass resolveClass;
|
|
||||||
const QList<Symbol *> symbols = resolveClass(namedTy, result,
|
|
||||||
_context);
|
|
||||||
foreach (Symbol *symbol, symbols) {
|
|
||||||
if (classObjectCandidates.contains(symbol))
|
|
||||||
continue;
|
|
||||||
if (Class *klass = symbol->asClass())
|
|
||||||
classObjectCandidates.append(klass);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return classObjectCandidates;
|
return removeDuplicates(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ResolveExpression::Result>
|
QList<ResolveExpression::Result>
|
||||||
@@ -745,25 +736,42 @@ ResolveExpression::resolveMemberExpression(const QList<Result> &baseResults,
|
|||||||
unsigned accessOp,
|
unsigned accessOp,
|
||||||
Name *memberName) const
|
Name *memberName) const
|
||||||
{
|
{
|
||||||
|
ResolveClass resolveClass;
|
||||||
QList<Result> results;
|
QList<Result> results;
|
||||||
|
|
||||||
const QList<Symbol *> classObjectCandidates = resolveBaseExpression(baseResults, accessOp);
|
const QList<Result> classObjectResults = resolveBaseExpression(baseResults, accessOp);
|
||||||
foreach (Symbol *candidate, classObjectCandidates) {
|
foreach (const Result &r, classObjectResults) {
|
||||||
Class *klass = candidate->asClass();
|
FullySpecifiedType ty = r.first;
|
||||||
if (! klass)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
if (Class *klass = ty->asClassType())
|
||||||
results += resolveMember(memberName, klass);
|
results += resolveMember(memberName, klass);
|
||||||
|
|
||||||
|
else if (NamedType *namedTy = ty->asNamedType()) {
|
||||||
|
Name *className = namedTy->name();
|
||||||
|
const QList<Symbol *> classes = resolveClass(className, r, _context);
|
||||||
|
|
||||||
|
foreach (Symbol *c, classes) {
|
||||||
|
if (Class *klass = c->asClass())
|
||||||
|
results += resolveMember(memberName, klass, className);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return removeDuplicates(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ResolveExpression::Result>
|
QList<ResolveExpression::Result>
|
||||||
ResolveExpression::resolveMember(Name *memberName, Class *klass) const
|
ResolveExpression::resolveMember(Name *memberName, Class *klass,
|
||||||
|
Name *className) const
|
||||||
{
|
{
|
||||||
QList<Result> results;
|
QList<Result> results;
|
||||||
|
|
||||||
|
if (! className)
|
||||||
|
className = klass->name();
|
||||||
|
|
||||||
|
if (! className)
|
||||||
|
return results;
|
||||||
|
|
||||||
QList<Scope *> scopes;
|
QList<Scope *> scopes;
|
||||||
_context.expand(klass->members(), _context.visibleScopes(), &scopes);
|
_context.expand(klass->members(), _context.visibleScopes(), &scopes);
|
||||||
|
|
||||||
@@ -771,8 +779,6 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass) const
|
|||||||
|
|
||||||
foreach (Symbol *candidate, candidates) {
|
foreach (Symbol *candidate, candidates) {
|
||||||
FullySpecifiedType ty = candidate->type();
|
FullySpecifiedType ty = candidate->type();
|
||||||
|
|
||||||
if (Name *className = klass->name()) {
|
|
||||||
Name *unqualifiedNameId = className;
|
Name *unqualifiedNameId = className;
|
||||||
|
|
||||||
if (QualifiedNameId *q = className->asQualifiedNameId())
|
if (QualifiedNameId *q = className->asQualifiedNameId())
|
||||||
@@ -792,14 +798,11 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass) const
|
|||||||
Instantiation inst(control(), subst);
|
Instantiation inst(control(), subst);
|
||||||
ty = inst(ty);
|
ty = inst(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
results.append(Result(ty, candidate));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Result result(ty, candidate);
|
return removeDuplicates(results);
|
||||||
if (! results.contains(result))
|
|
||||||
results.append(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ResolveExpression::Result>
|
QList<ResolveExpression::Result>
|
||||||
@@ -832,11 +835,10 @@ ResolveExpression::resolveArrowOperator(const Result &,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Result result(ty, candidate);
|
const Result result(ty, candidate);
|
||||||
if (! results.contains(result))
|
|
||||||
results.append(result);
|
results.append(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return removeDuplicates(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ResolveExpression::Result>
|
QList<ResolveExpression::Result>
|
||||||
@@ -870,12 +872,10 @@ ResolveExpression::resolveArrayOperator(const Result &,
|
|||||||
ty = inst(ty);
|
ty = inst(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Result result(ty, candidate);
|
results.append(Result(ty, candidate));
|
||||||
if (! results.contains(result))
|
|
||||||
results.append(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return removeDuplicates(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResolveExpression::visit(PostIncrDecrAST *)
|
bool ResolveExpression::visit(PostIncrDecrAST *)
|
||||||
@@ -894,27 +894,18 @@ bool ResolveClass::pointerAccess() const
|
|||||||
void ResolveClass::setPointerAccess(bool pointerAccess)
|
void ResolveClass::setPointerAccess(bool pointerAccess)
|
||||||
{ _pointerAccess = pointerAccess; }
|
{ _pointerAccess = pointerAccess; }
|
||||||
|
|
||||||
QList<Symbol *> ResolveClass::operator()(NamedType *namedTy,
|
QList<Symbol *> ResolveClass::operator()(Name *name,
|
||||||
ResolveExpression::Result p,
|
const ResolveExpression::Result &p,
|
||||||
const LookupContext &context)
|
const LookupContext &context)
|
||||||
{
|
{
|
||||||
const QList<ResolveExpression::Result> previousBlackList = _blackList;
|
const QList<ResolveExpression::Result> previousBlackList = _blackList;
|
||||||
const QList<Symbol *> symbols = resolveClass(namedTy, p, context);
|
const QList<Symbol *> symbols = resolveClass(name, p, context);
|
||||||
_blackList = previousBlackList;
|
_blackList = previousBlackList;
|
||||||
return symbols;
|
return symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Symbol *> ResolveClass::operator()(ResolveExpression::Result p,
|
QList<Symbol *> ResolveClass::resolveClass(Name *name,
|
||||||
const LookupContext &context)
|
const ResolveExpression::Result &p,
|
||||||
{
|
|
||||||
const QList<ResolveExpression::Result> previousBlackList = _blackList;
|
|
||||||
const QList<Symbol *> symbols = resolveClass(p, context);
|
|
||||||
_blackList = previousBlackList;
|
|
||||||
return symbols;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Symbol *> ResolveClass::resolveClass(NamedType *namedTy,
|
|
||||||
ResolveExpression::Result p,
|
|
||||||
const LookupContext &context)
|
const LookupContext &context)
|
||||||
{
|
{
|
||||||
QList<Symbol *> resolvedSymbols;
|
QList<Symbol *> resolvedSymbols;
|
||||||
@@ -925,7 +916,7 @@ QList<Symbol *> ResolveClass::resolveClass(NamedType *namedTy,
|
|||||||
_blackList.append(p);
|
_blackList.append(p);
|
||||||
|
|
||||||
const QList<Symbol *> candidates =
|
const QList<Symbol *> candidates =
|
||||||
context.resolve(namedTy->name(), context.visibleScopes(p));
|
context.resolve(name, context.visibleScopes(p));
|
||||||
|
|
||||||
foreach (Symbol *candidate, candidates) {
|
foreach (Symbol *candidate, candidates) {
|
||||||
if (Class *klass = candidate->asClass()) {
|
if (Class *klass = candidate->asClass()) {
|
||||||
@@ -936,10 +927,13 @@ QList<Symbol *> ResolveClass::resolveClass(NamedType *namedTy,
|
|||||||
if (Declaration *decl = candidate->asDeclaration()) {
|
if (Declaration *decl = candidate->asDeclaration()) {
|
||||||
if (_pointerAccess && decl->type()->isPointerType()) {
|
if (_pointerAccess && decl->type()->isPointerType()) {
|
||||||
PointerType *ptrTy = decl->type()->asPointerType();
|
PointerType *ptrTy = decl->type()->asPointerType();
|
||||||
|
FullySpecifiedType elementTy = ptrTy->elementType().simplified();
|
||||||
|
if (NamedType *namedTy = elementTy->asNamedType()) {
|
||||||
_pointerAccess = false;
|
_pointerAccess = false;
|
||||||
const ResolveExpression::Result r(ptrTy->elementType(), decl);
|
const ResolveExpression::Result r(elementTy, decl);
|
||||||
resolvedSymbols += resolveClass(r, context);
|
resolvedSymbols += resolveClass(namedTy->name(), r, context);
|
||||||
_pointerAccess = true;
|
_pointerAccess = true;
|
||||||
|
}
|
||||||
} else if (Class *asClass = decl->type()->asClassType()) {
|
} else if (Class *asClass = decl->type()->asClassType()) {
|
||||||
// typedef struct { } Point;
|
// typedef struct { } Point;
|
||||||
// Point pt;
|
// Point pt;
|
||||||
@@ -949,8 +943,11 @@ QList<Symbol *> ResolveClass::resolveClass(NamedType *namedTy,
|
|||||||
// typedef Point Boh;
|
// typedef Point Boh;
|
||||||
// Boh b;
|
// Boh b;
|
||||||
// b.
|
// b.
|
||||||
const ResolveExpression::Result r(decl->type(), decl);
|
FullySpecifiedType declType = decl->type().simplified();
|
||||||
resolvedSymbols += resolveClass(r, context);
|
if (NamedType *namedTy = declType->asNamedType()) {
|
||||||
|
const ResolveExpression::Result r(declType, decl);
|
||||||
|
resolvedSymbols += resolveClass(namedTy->name(), r, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (Declaration *decl = candidate->asDeclaration()) {
|
} else if (Declaration *decl = candidate->asDeclaration()) {
|
||||||
@@ -958,8 +955,11 @@ QList<Symbol *> ResolveClass::resolveClass(NamedType *namedTy,
|
|||||||
// QString foo("ciao");
|
// QString foo("ciao");
|
||||||
// foo.
|
// foo.
|
||||||
if (funTy->scope() && (funTy->scope()->isBlockScope() || funTy->scope()->isNamespaceScope())) {
|
if (funTy->scope() && (funTy->scope()->isBlockScope() || funTy->scope()->isNamespaceScope())) {
|
||||||
const ResolveExpression::Result r(funTy->returnType(), decl);
|
FullySpecifiedType retTy = funTy->returnType().simplified();
|
||||||
resolvedSymbols += resolveClass(r, context);
|
if (NamedType *namedTy = retTy->asNamedType()) {
|
||||||
|
const ResolveExpression::Result r(retTy, decl);
|
||||||
|
resolvedSymbols += resolveClass(namedTy->name(), r, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -967,19 +967,3 @@ QList<Symbol *> ResolveClass::resolveClass(NamedType *namedTy,
|
|||||||
|
|
||||||
return resolvedSymbols;
|
return resolvedSymbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Symbol *> ResolveClass::resolveClass(ResolveExpression::Result p,
|
|
||||||
const LookupContext &context)
|
|
||||||
{
|
|
||||||
FullySpecifiedType ty = p.first;
|
|
||||||
|
|
||||||
if (NamedType *namedTy = ty->asNamedType()) {
|
|
||||||
return resolveClass(namedTy, p, context);
|
|
||||||
} else if (ReferenceType *refTy = ty->asReferenceType()) {
|
|
||||||
const ResolveExpression::Result e(refTy->elementType(), p.second);
|
|
||||||
return resolveClass(e, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QList<Symbol *>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
unsigned accessOp,
|
unsigned accessOp,
|
||||||
Name *memberName) const;
|
Name *memberName) const;
|
||||||
|
|
||||||
QList<Result> resolveMember(Name *memberName, Class *klass) const;
|
QList<Result> resolveMember(Name *memberName, Class *klass, Name *className = 0) const;
|
||||||
|
|
||||||
QList<Result> resolveArrowOperator(const Result &result,
|
QList<Result> resolveArrowOperator(const Result &result,
|
||||||
NamedType *namedTy,
|
NamedType *namedTy,
|
||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
Class *klass) const;
|
Class *klass) const;
|
||||||
|
|
||||||
|
|
||||||
QList<Symbol *> resolveBaseExpression(const QList<Result> &baseResults,
|
QList<Result> resolveBaseExpression(const QList<Result> &baseResults,
|
||||||
int accessOp) const;
|
int accessOp) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -131,19 +131,13 @@ public:
|
|||||||
bool pointerAccess() const;
|
bool pointerAccess() const;
|
||||||
void setPointerAccess(bool pointerAccess);
|
void setPointerAccess(bool pointerAccess);
|
||||||
|
|
||||||
QList<Symbol *> operator()(NamedType *namedTy,
|
QList<Symbol *> operator()(Name *name,
|
||||||
ResolveExpression::Result p,
|
const ResolveExpression::Result &p,
|
||||||
const LookupContext &context);
|
|
||||||
|
|
||||||
QList<Symbol *> operator()(ResolveExpression::Result p,
|
|
||||||
const LookupContext &context);
|
const LookupContext &context);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<Symbol *> resolveClass(NamedType *namedTy,
|
QList<Symbol *> resolveClass(Name *name,
|
||||||
ResolveExpression::Result p,
|
const ResolveExpression::Result &p,
|
||||||
const LookupContext &context);
|
|
||||||
|
|
||||||
QList<Symbol *> resolveClass(ResolveExpression::Result p,
|
|
||||||
const LookupContext &context);
|
const LookupContext &context);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1011,7 +1011,7 @@ bool CppCodeCompletion::completeMember(const QList<TypeOfExpression::Result> &re
|
|||||||
ResolveExpression resolveExpression(context);
|
ResolveExpression resolveExpression(context);
|
||||||
ResolveClass resolveClass;
|
ResolveClass resolveClass;
|
||||||
|
|
||||||
const QList<Symbol *> candidates = resolveClass(result, context);
|
const QList<Symbol *> candidates = resolveClass(namedTy->name(), result, context);
|
||||||
foreach (Symbol *classObject, candidates) {
|
foreach (Symbol *classObject, candidates) {
|
||||||
const QList<TypeOfExpression::Result> overloads =
|
const QList<TypeOfExpression::Result> overloads =
|
||||||
resolveExpression.resolveArrowOperator(result, namedTy,
|
resolveExpression.resolveArrowOperator(result, namedTy,
|
||||||
@@ -1026,9 +1026,10 @@ bool CppCodeCompletion::completeMember(const QList<TypeOfExpression::Result> &re
|
|||||||
ty = funTy->returnType().simplified();
|
ty = funTy->returnType().simplified();
|
||||||
|
|
||||||
if (PointerType *ptrTy = ty->asPointerType()) {
|
if (PointerType *ptrTy = ty->asPointerType()) {
|
||||||
if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
|
FullySpecifiedType elementTy = ptrTy->elementType().simplified();
|
||||||
|
if (NamedType *namedTy = elementTy->asNamedType()) {
|
||||||
const QList<Symbol *> classes =
|
const QList<Symbol *> classes =
|
||||||
resolveClass(namedTy, result, context);
|
resolveClass(namedTy->name(), result, context);
|
||||||
|
|
||||||
foreach (Symbol *c, classes) {
|
foreach (Symbol *c, classes) {
|
||||||
if (! classObjectCandidates.contains(c))
|
if (! classObjectCandidates.contains(c))
|
||||||
@@ -1039,17 +1040,18 @@ bool CppCodeCompletion::completeMember(const QList<TypeOfExpression::Result> &re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (PointerType *ptrTy = ty->asPointerType()) {
|
} else if (PointerType *ptrTy = ty->asPointerType()) {
|
||||||
if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
|
FullySpecifiedType elementTy = ptrTy->elementType().simplified();
|
||||||
|
if (NamedType *namedTy = elementTy->asNamedType()) {
|
||||||
ResolveClass resolveClass;
|
ResolveClass resolveClass;
|
||||||
|
|
||||||
const QList<Symbol *> classes = resolveClass(namedTy, result,
|
const QList<Symbol *> classes = resolveClass(namedTy->name(), result,
|
||||||
context);
|
context);
|
||||||
|
|
||||||
foreach (Symbol *c, classes) {
|
foreach (Symbol *c, classes) {
|
||||||
if (! classObjectCandidates.contains(c))
|
if (! classObjectCandidates.contains(c))
|
||||||
classObjectCandidates.append(c);
|
classObjectCandidates.append(c);
|
||||||
}
|
}
|
||||||
} else if (Class *classTy = ptrTy->elementType()->asClassType()) {
|
} else if (Class *classTy = elementTy->asClassType()) {
|
||||||
// typedef struct { int x } *Ptr;
|
// typedef struct { int x } *Ptr;
|
||||||
// Ptr p;
|
// Ptr p;
|
||||||
// p->
|
// p->
|
||||||
@@ -1099,7 +1101,7 @@ bool CppCodeCompletion::completeMember(const QList<TypeOfExpression::Result> &re
|
|||||||
|
|
||||||
if (namedTy) {
|
if (namedTy) {
|
||||||
ResolveClass resolveClass;
|
ResolveClass resolveClass;
|
||||||
const QList<Symbol *> symbols = resolveClass(namedTy, result,
|
const QList<Symbol *> symbols = resolveClass(namedTy->name(), result,
|
||||||
context);
|
context);
|
||||||
foreach (Symbol *symbol, symbols) {
|
foreach (Symbol *symbol, symbols) {
|
||||||
if (classObjectCandidates.contains(symbol))
|
if (classObjectCandidates.contains(symbol))
|
||||||
@@ -1330,7 +1332,7 @@ bool CppCodeCompletion::completeQtMethod(const QList<TypeOfExpression::Result> &
|
|||||||
FullySpecifiedType ty = p.first.simplified();
|
FullySpecifiedType ty = p.first.simplified();
|
||||||
|
|
||||||
if (PointerType *ptrTy = ty->asPointerType())
|
if (PointerType *ptrTy = ty->asPointerType())
|
||||||
ty = ptrTy->elementType();
|
ty = ptrTy->elementType().simplified();
|
||||||
else
|
else
|
||||||
continue; // not a pointer or a reference to a pointer.
|
continue; // not a pointer or a reference to a pointer.
|
||||||
|
|
||||||
@@ -1339,7 +1341,7 @@ bool CppCodeCompletion::completeQtMethod(const QList<TypeOfExpression::Result> &
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QList<Symbol *> classObjects =
|
const QList<Symbol *> classObjects =
|
||||||
resolveClass(namedTy, p, context);
|
resolveClass(namedTy->name(), p, context);
|
||||||
|
|
||||||
if (classObjects.isEmpty())
|
if (classObjects.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user