forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/2.8'
This commit is contained in:
@@ -175,6 +175,14 @@ protected:
|
||||
virtual bool visit(Block *symbol)
|
||||
{ return process(symbol); }
|
||||
|
||||
virtual bool visit(Template *symbol)
|
||||
{
|
||||
if (symbol->declaration() && symbol->declaration()->isFunction())
|
||||
return process(symbol);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
// Objective-C
|
||||
virtual bool visit(ObjCBaseClass *) { return false; }
|
||||
virtual bool visit(ObjCBaseProtocol *) { return false; }
|
||||
|
||||
@@ -249,17 +249,19 @@ QList<LookupItem> LookupContext::lookupByUsing(const Name *name, Scope *scope) c
|
||||
if (name->isNameId()) {
|
||||
for (unsigned i = 0, count = scope->memberCount(); i < count; ++i) {
|
||||
if (UsingDeclaration *u = scope->memberAt(i)->asUsingDeclaration()) {
|
||||
if (const QualifiedNameId *q = u->name()->asQualifiedNameId()) {
|
||||
if (q->name()->isEqualTo(name)) {
|
||||
candidates = bindings()->globalNamespace()->find(q);
|
||||
if (const Name *usingDeclarationName = u->name()) {
|
||||
if (const QualifiedNameId *q = usingDeclarationName->asQualifiedNameId()) {
|
||||
if (q->name() && q->name()->isEqualTo(name)) {
|
||||
candidates = bindings()->globalNamespace()->find(q);
|
||||
|
||||
// if it is not a global scope(scope of scope is not equal 0)
|
||||
// then add current using declaration as a candidate
|
||||
if (scope->scope()) {
|
||||
LookupItem item;
|
||||
item.setDeclaration(u);
|
||||
item.setScope(scope);
|
||||
candidates.append(item);
|
||||
// if it is not a global scope(scope of scope is not equal 0)
|
||||
// then add current using declaration as a candidate
|
||||
if (scope->scope()) {
|
||||
LookupItem item;
|
||||
item.setDeclaration(u);
|
||||
item.setScope(scope);
|
||||
candidates.append(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,9 +330,11 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
|
||||
}
|
||||
} else if (UsingDeclaration *ud = m->asUsingDeclaration()) {
|
||||
if (name->isNameId()) {
|
||||
if (const QualifiedNameId *q = ud->name()->asQualifiedNameId()) {
|
||||
if (q->name()->isEqualTo(name)) {
|
||||
return bindings()->globalNamespace()->lookupType(q);
|
||||
if (const Name *usingDeclarationName = ud->name()) {
|
||||
if (const QualifiedNameId *q = usingDeclarationName->asQualifiedNameId()) {
|
||||
if (q->name() && q->name()->isEqualTo(name)) {
|
||||
return bindings()->globalNamespace()->lookupType(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,6 +692,16 @@ void CreateBindings::lookupInScope(const Name *name, Scope *scope,
|
||||
item.setType(ty); // override the type.
|
||||
}
|
||||
|
||||
// instantiate function template
|
||||
if (name->isTemplateNameId() && s->isTemplate() && s->asTemplate()->declaration()
|
||||
&& s->asTemplate()->declaration()->isFunction()) {
|
||||
const TemplateNameId *instantiation = name->asTemplateNameId();
|
||||
Template *specialization = s->asTemplate();
|
||||
Symbol *instantiatedFunctionTemplate = instantiateTemplateFunction(instantiation,
|
||||
specialization);
|
||||
item.setType(instantiatedFunctionTemplate->type()); // override the type.
|
||||
}
|
||||
|
||||
result->append(item);
|
||||
}
|
||||
}
|
||||
@@ -1599,3 +1613,29 @@ bool CreateBindings::visit(ObjCMethod *)
|
||||
return false;
|
||||
}
|
||||
|
||||
Symbol *CreateBindings::instantiateTemplateFunction(const TemplateNameId *instantiation,
|
||||
Template *specialization) const
|
||||
{
|
||||
const unsigned argumentCountOfInitialization = instantiation->templateArgumentCount();
|
||||
const unsigned argumentCountOfSpecialization = specialization->templateParameterCount();
|
||||
|
||||
Clone cloner(_control.data());
|
||||
Subst subst(_control.data());
|
||||
for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) {
|
||||
const TypenameArgument *tParam
|
||||
= specialization->templateParameterAt(i)->asTypenameArgument();
|
||||
if (!tParam)
|
||||
continue;
|
||||
const Name *name = tParam->name();
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
FullySpecifiedType ty = (i < argumentCountOfInitialization) ?
|
||||
instantiation->templateArgumentAt(i):
|
||||
cloner.type(tParam->type(), &subst);
|
||||
|
||||
subst.bind(cloner.name(name, &subst), ty);
|
||||
}
|
||||
return cloner.symbol(specialization, &subst);
|
||||
}
|
||||
|
||||
|
||||
@@ -253,6 +253,9 @@ protected:
|
||||
virtual bool visit(ObjCMethod *);
|
||||
|
||||
private:
|
||||
Symbol *instantiateTemplateFunction(const TemplateNameId *instantiation,
|
||||
Template *specialization) const;
|
||||
|
||||
Snapshot _snapshot;
|
||||
QSharedPointer<Control> _control;
|
||||
QSet<Namespace *> _processed;
|
||||
|
||||
@@ -697,6 +697,14 @@ bool ResolveExpression::visit(CallAST *ast)
|
||||
// Constructor call
|
||||
FullySpecifiedType ctorTy = control()->namedType(classTy->name());
|
||||
addResult(ctorTy, scope);
|
||||
} else if (Template *templateTy = ty->asTemplateType()) {
|
||||
// template function
|
||||
if (Symbol *declaration = templateTy->declaration()) {
|
||||
if (Function *funTy = declaration->asFunction()) {
|
||||
if (maybeValidPrototype(funTy, actualArgumentCount))
|
||||
addResult(funTy->returnType().simplified(), scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,6 +946,18 @@ private:
|
||||
ClassOrNamespace *_binding;
|
||||
};
|
||||
|
||||
static bool isTypeTypedefed(const FullySpecifiedType &originalTy,
|
||||
const FullySpecifiedType &typedefedTy)
|
||||
{
|
||||
return ! originalTy.isEqualTo(typedefedTy);
|
||||
}
|
||||
|
||||
static bool areOriginalAndTypedefedTypePointer(const FullySpecifiedType &originalTy,
|
||||
const FullySpecifiedType &typedefedTy)
|
||||
{
|
||||
return originalTy->isPointerType() && typedefedTy->isPointerType();
|
||||
}
|
||||
|
||||
ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &baseResults,
|
||||
int accessOp,
|
||||
bool *replacedDotOperator) const
|
||||
@@ -1027,23 +1047,12 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
|
||||
}
|
||||
} else if (accessOp == T_DOT) {
|
||||
if (replacedDotOperator) {
|
||||
*replacedDotOperator = originalType->isPointerType() || ty->isPointerType();
|
||||
// replace . with ->
|
||||
if (PointerType *ptrTy = originalType->asPointerType()) {
|
||||
// case when original type is a pointer and
|
||||
// typedef is for type
|
||||
// e.g.:
|
||||
// typedef S SType;
|
||||
// SType *p;
|
||||
ty = ptrTy->elementType();
|
||||
}
|
||||
else if (PointerType *ptrTy = ty->asPointerType()) {
|
||||
// case when original type is a type and
|
||||
// typedef is for pointer of type
|
||||
// e.g.:
|
||||
// typedef S* SPTR;
|
||||
// SPTR p;
|
||||
ty = ptrTy->elementType();
|
||||
if (! isTypeTypedefed(originalType, ty)
|
||||
|| ! areOriginalAndTypedefedTypePointer(originalType, ty)) {
|
||||
*replacedDotOperator = originalType->isPointerType() || ty->isPointerType();
|
||||
if (PointerType *ptrTy = ty->asPointerType()) {
|
||||
ty = ptrTy->elementType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ protected:
|
||||
|
||||
private:
|
||||
Scope *_scope;
|
||||
LookupContext _context;
|
||||
const LookupContext& _context;
|
||||
Bind bind;
|
||||
QList<LookupItem> _results;
|
||||
bool _reference;
|
||||
|
||||
Reference in New Issue
Block a user