C++: Fix lookup for instantiation by class object

Task-number: QTCREATORBUG-14352
Change-Id: I2ce4bc1d0dba2414afe050e80607b581686081a9
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Orgad Shaneh
2015-04-24 09:55:20 +03:00
committed by Orgad Shaneh
parent ee37f60bff
commit 9b30795c02
10 changed files with 99 additions and 81 deletions

View File

@@ -601,7 +601,7 @@ public:
QSet<const Declaration *> _alreadyConsideredTypedefs;
Class *_rootClass;
const Name *_name; // For debug
const Name *_name;
bool _hasTypedefs;
};
@@ -1118,6 +1118,13 @@ LookupScope *LookupScopePrivate::lookupType_helper(
return r;
}
}
if (_instantiationOrigin) {
if (LookupScope *o = _instantiationOrigin->lookupType_helper(
name, processed, /*searchInEnclosingScope =*/ true, origin)) {
return o;
}
}
}
if (_parent && searchInEnclosingScope)
@@ -1529,6 +1536,10 @@ void Instantiator::instantiate(LookupScopePrivate *lookupScope,
if (!clone->enclosingScope()) // Not from the cache but just cloned.
clone->setEnclosingScope(s->enclosingScope());
instantiation->_symbols.append(clone);
if (s == instantiation->_rootClass) {
clone->setName(instantiation->_name);
instantiation->_rootClass = clone->asClass();
}
if (Q_UNLIKELY(debug)) {
Overview oo;
oo.showFunctionSignatures = true;

View File

@@ -915,61 +915,47 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
if (accessOp == T_ARROW) {
if (PointerType *ptrTy = ty->asPointerType()) {
FullySpecifiedType type = ptrTy->elementType();
if (LookupScope *binding
= findClassForTemplateParameterInExpressionScope(r.binding(),
type)) {
return binding;
}
if (LookupScope *binding = findClass(type, scope))
return binding;
} else {
LookupScope *binding
= findClassForTemplateParameterInExpressionScope(r.binding(),
ty);
} else if (LookupScope *binding = findClass(ty, scope, r.binding())) {
// lookup for overloads of operator->
if (! binding)
binding = findClass(ty, scope, r.binding());
const OperatorNameId *arrowOp
= control()->operatorNameId(OperatorNameId::ArrowOp);
foreach (const LookupItem &r, binding->find(arrowOp)) {
Symbol *overload = r.declaration();
if (! overload)
continue;
Scope *functionScope = overload->enclosingScope();
if (binding){
// lookup for overloads of operator->
if (Function *funTy = overload->type()->asFunctionType()) {
FullySpecifiedType retTy = funTy->returnType().simplified();
const OperatorNameId *arrowOp
= control()->operatorNameId(OperatorNameId::ArrowOp);
foreach (const LookupItem &r, binding->find(arrowOp)) {
Symbol *overload = r.declaration();
if (! overload)
typeResolver.resolve(&retTy, &functionScope, r.binding());
if (! retTy->isPointerType() && ! retTy->isNamedType())
continue;
Scope *functionScope = overload->enclosingScope();
if (Function *funTy = overload->type()->asFunctionType()) {
FullySpecifiedType retTy = funTy->returnType().simplified();
if (PointerType *ptrTy = retTy->asPointerType())
retTy = ptrTy->elementType();
typeResolver.resolve(&retTy, &functionScope, r.binding());
if (LookupScope *retBinding = findClass(retTy, functionScope))
return retBinding;
if (! retTy->isPointerType() && ! retTy->isNamedType())
continue;
if (PointerType *ptrTy = retTy->asPointerType())
retTy = ptrTy->elementType();
if (LookupScope *retBinding = findClass(retTy, functionScope))
if (scope != functionScope) {
if (LookupScope *retBinding = findClass(retTy, scope))
return retBinding;
}
if (scope != functionScope) {
if (LookupScope *retBinding = findClass(retTy, scope))
return retBinding;
}
if (LookupScope *origin = binding->instantiationOrigin()) {
foreach (Symbol *originSymbol, origin->symbols()) {
Scope *originScope = originSymbol->asScope();
if (originScope && originScope != scope
&& originScope != functionScope) {
if (LookupScope *retBinding
= findClass(retTy, originScope))
return retBinding;
}
if (LookupScope *origin = binding->instantiationOrigin()) {
foreach (Symbol *originSymbol, origin->symbols()) {
Scope *originScope = originSymbol->asScope();
if (originScope && originScope != scope
&& originScope != functionScope) {
if (LookupScope *retBinding
= findClass(retTy, originScope))
return retBinding;
}
}
}
@@ -983,12 +969,6 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
ty = ptrTy->elementType();
}
if (LookupScope *binding
= findClassForTemplateParameterInExpressionScope(r.binding(),
ty)) {
return binding;
}
LookupScope *enclosingBinding = 0;
if (LookupScope *binding = r.binding()) {
if (binding->instantiationOrigin())
@@ -1003,24 +983,6 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
return 0;
}
LookupScope *ResolveExpression::findClassForTemplateParameterInExpressionScope(
LookupScope *resultBinding,
const FullySpecifiedType &ty) const
{
if (resultBinding) {
if (LookupScope *origin = resultBinding->instantiationOrigin()) {
foreach (Symbol *originSymbol, origin->symbols()) {
if (Scope *originScope = originSymbol->asScope()) {
if (LookupScope *retBinding = findClass(ty, originScope))
return retBinding;
}
}
}
}
return 0;
}
bool ResolveExpression::visit(PostIncrDecrAST *ast)
{
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);

View File

@@ -125,10 +125,6 @@ protected:
private:
LookupScope *findClassForTemplateParameterInExpressionScope(
LookupScope *resultBinding,
const FullySpecifiedType &ty) const;
Scope *_scope;
const LookupContext& _context;
Bind bind;