aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/cplusplus
diff options
context:
space:
mode:
authorEike Ziller <[email protected]>2013-05-24 16:22:08 +0200
committerEike Ziller <[email protected]>2013-05-24 16:22:08 +0200
commit1c34b266fb86a591eb9d7ef406780073e0d6a647 (patch)
tree627e7641741b6f2ac0de72932d17a51826f79056 /src/libs/cplusplus
parente6c822882038f1f7df93ee319b391326fe3b2f02 (diff)
parent75aeb5866816e2dccea8b226ed31f0df9cdbfb45 (diff)
Merge remote-tracking branch 'origin/2.8'
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r--src/libs/cplusplus/CppDocument.cpp8
-rw-r--r--src/libs/cplusplus/LookupContext.cpp68
-rw-r--r--src/libs/cplusplus/LookupContext.h3
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp43
-rw-r--r--src/libs/cplusplus/ResolveExpression.h2
5 files changed, 92 insertions, 32 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 13c0b3f6ad8..ee6d7f3a9d6 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -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; }
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 6b718cfbc35..fdcd0e286fc 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -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 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 (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);
+ }
}
}
}
@@ -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);
+}
+
diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h
index a372634053e..921c605b149 100644
--- a/src/libs/cplusplus/LookupContext.h
+++ b/src/libs/cplusplus/LookupContext.h
@@ -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;
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 029bcee00d4..55e1d694928 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -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();
+ }
}
}
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index 95268e69536..157c51246e5 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -123,7 +123,7 @@ protected:
private:
Scope *_scope;
- LookupContext _context;
+ const LookupContext& _context;
Bind bind;
QList<LookupItem> _results;
bool _reference;