diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2015-03-25 22:32:46 +0200 |
---|---|---|
committer | Orgad Shaneh <orgads@gmail.com> | 2015-04-11 17:27:44 +0000 |
commit | aedfbd571065be9410788b7402a04139135729c3 (patch) | |
tree | f48f582c42b8bc75e30b0cf4cb61b300249d58d5 /src/libs/cplusplus/ResolveExpression.cpp | |
parent | 7ba2210102ce12ae845cccfa17624d59a1ba66bd (diff) | |
download | qt-creator-aedfbd571065be9410788b7402a04139135729c3.tar.gz |
C++: Extract TypedefsResolver out of ResolveExpression
... and rename it TypeResolver
Change-Id: I5cb076812d2e3ac132f18ea884ec69328b69999c
Reviewed-by: Przemyslaw Gorszkowski <pgorszkowski@gmail.com>
Diffstat (limited to 'src/libs/cplusplus/ResolveExpression.cpp')
-rw-r--r-- | src/libs/cplusplus/ResolveExpression.cpp | 143 |
1 files changed, 7 insertions, 136 deletions
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index adaac12ab5..e38d634b8c 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -35,6 +35,7 @@ #include "DeprecatedGenTemplateInstance.h" #include "CppRewriter.h" #include "TypeOfExpression.h" +#include "TypeResolver.h" #include <cplusplus/Control.h> #include <cplusplus/AST.h> @@ -75,131 +76,6 @@ static QList<T> removeDuplicates(const QList<T> &results) return uniqueList; } -class TypedefsResolver -{ -public: - TypedefsResolver(const LookupContext &context) : _context(context) {} - void resolve(FullySpecifiedType *type, Scope **scope, ClassOrNamespace *binding) - { - QSet<Symbol *> visited; - _binding = binding; - // Use a hard limit when trying to resolve typedefs. Typedefs in templates can refer to - // each other, each time enhancing the template argument and thus making it impossible to - // use an "alreadyResolved" container. FIXME: We might overcome this by resolving the - // template parameters. - unsigned maxDepth = 15; - for (NamedType *namedTy = 0; maxDepth && (namedTy = getNamedType(*type)); --maxDepth) { - QList<LookupItem> namedTypeItems = getNamedTypeItems(namedTy->name(), *scope, _binding); - - if (Q_UNLIKELY(debug)) - qDebug() << "-- we have" << namedTypeItems.size() << "candidates"; - - if (!findTypedef(namedTypeItems, type, scope, visited)) - break; - } - } - -private: - NamedType *getNamedType(FullySpecifiedType& type) const - { - NamedType *namedTy = type->asNamedType(); - if (! namedTy) { - if (PointerType *pointerTy = type->asPointerType()) - namedTy = pointerTy->elementType()->asNamedType(); - } - return namedTy; - } - - QList<LookupItem> getNamedTypeItems(const Name *name, Scope *scope, - ClassOrNamespace *binding) const - { - QList<LookupItem> namedTypeItems = typedefsFromScopeUpToFunctionScope(name, scope); - if (namedTypeItems.isEmpty()) { - if (binding) - namedTypeItems = binding->lookup(name); - if (ClassOrNamespace *scopeCon = _context.lookupType(scope)) - namedTypeItems += scopeCon->lookup(name); - } - - return namedTypeItems; - } - - /// Return all typedefs with given name from given scope up to function scope. - static QList<LookupItem> typedefsFromScopeUpToFunctionScope(const Name *name, Scope *scope) - { - QList<LookupItem> results; - if (!scope) - return results; - Scope *enclosingBlockScope = 0; - for (Block *block = scope->asBlock(); block; - block = enclosingBlockScope ? enclosingBlockScope->asBlock() : 0) { - const unsigned memberCount = block->memberCount(); - for (unsigned i = 0; i < memberCount; ++i) { - Symbol *symbol = block->memberAt(i); - if (Declaration *declaration = symbol->asDeclaration()) { - if (isTypedefWithName(declaration, name)) { - LookupItem item; - item.setDeclaration(declaration); - item.setScope(block); - item.setType(declaration->type()); - results.append(item); - } - } - } - enclosingBlockScope = block->enclosingScope(); - } - return results; - } - - static bool isTypedefWithName(const Declaration *declaration, const Name *name) - { - if (declaration->isTypedef()) { - const Identifier *identifier = declaration->name()->identifier(); - if (name->identifier()->match(identifier)) - return true; - } - return false; - } - - bool findTypedef(const QList<LookupItem>& namedTypeItems, FullySpecifiedType *type, - Scope **scope, QSet<Symbol *>& visited) - { - bool foundTypedef = false; - foreach (const LookupItem &it, namedTypeItems) { - Symbol *declaration = it.declaration(); - if (declaration && declaration->isTypedef()) { - if (visited.contains(declaration)) - break; - visited.insert(declaration); - - // continue working with the typedefed type and scope - if (type->type()->isPointerType()) { - *type = FullySpecifiedType( - _context.bindings()->control()->pointerType(declaration->type())); - } else if (type->type()->isReferenceType()) { - *type = FullySpecifiedType( - _context.bindings()->control()->referenceType( - declaration->type(), - declaration->type()->asReferenceType()->isRvalueReference())); - } else { - *type = declaration->type(); - } - - *scope = it.scope(); - _binding = it.binding(); - foundTypedef = true; - break; - } - } - - return foundTypedef; - } - - const LookupContext &_context; - // binding has to be remembered in case of resolving typedefs for templates - ClassOrNamespace *_binding; -}; - static int evaluateFunctionArgument(const FullySpecifiedType &actualTy, const FullySpecifiedType &formalTy) { @@ -916,8 +792,8 @@ bool ResolveExpression::visit(ArrayAccessAST *ast) FullySpecifiedType ty = result.type().simplified(); Scope *scope = result.scope(); - TypedefsResolver typedefsResolver(_context); - typedefsResolver.resolve(&ty, &scope, result.binding()); + TypeResolver typeResolver(_context); + typeResolver.resolve(&ty, &scope, result.binding()); if (PointerType *ptrTy = ty->asPointerType()) { addResult(ptrTy->elementType().simplified(), scope); @@ -1047,7 +923,7 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas qDebug() << "In ResolveExpression::baseExpression with" << baseResults.size() << "results..."; int i = 0; Overview oo; - TypedefsResolver typedefsResolver(_context); + TypeResolver typeResolver(_context); foreach (const LookupItem &r, baseResults) { if (!r.type().type() || !r.scope()) @@ -1056,15 +932,10 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas FullySpecifiedType originalType = ty; Scope *scope = r.scope(); - if (Q_UNLIKELY(debug)) { + if (Q_UNLIKELY(debug)) qDebug("trying result #%d", ++i); - qDebug() << "- before typedef resolving we have:" << oo(ty); - } - typedefsResolver.resolve(&ty, &scope, r.binding()); - - if (Q_UNLIKELY(debug)) - qDebug() << "- after typedef resolving:" << oo(ty); + typeResolver.resolve(&ty, &scope, r.binding()); if (accessOp == T_ARROW) { if (PointerType *ptrTy = ty->asPointerType()) { @@ -1105,7 +976,7 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas FullySpecifiedType retTy = instantiatedFunction->returnType().simplified(); - typedefsResolver.resolve(&retTy, &functionScope, r.binding()); + typeResolver.resolve(&retTy, &functionScope, r.binding()); if (! retTy->isPointerType() && ! retTy->isNamedType()) continue; |