diff options
Diffstat (limited to 'src/libs/cplusplus')
| -rw-r--r-- | src/libs/cplusplus/CppDocument.cpp | 8 | ||||
| -rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 68 | ||||
| -rw-r--r-- | src/libs/cplusplus/LookupContext.h | 3 | ||||
| -rw-r--r-- | src/libs/cplusplus/ResolveExpression.cpp | 43 | ||||
| -rw-r--r-- | src/libs/cplusplus/ResolveExpression.h | 2 |
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; |
