Merge remote-tracking branch 'origin/2.8'

This commit is contained in:
Eike Ziller
2013-05-24 16:22:08 +02:00
126 changed files with 2480 additions and 1039 deletions

View File

@@ -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; }

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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();
}
}
}

View File

@@ -123,7 +123,7 @@ protected:
private:
Scope *_scope;
LookupContext _context;
const LookupContext& _context;
Bind bind;
QList<LookupItem> _results;
bool _reference;