foreach (Symbol *symbol, symbols) { LookupItem item; item.setType(symbol->type()); item.setScope(symbol->enclosingScope()); item.setDeclaration(symbol); _results.append(item); }
/// 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; }
void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot, const LookupItem &lookupItem, const LookupContext &context, const Scope *scope) { Symbol *declaration = lookupItem.declaration(); if (!declaration) { const QString &type = Overview().prettyType(lookupItem.type(), QString()); // special case for bug QTCREATORBUG-4780 if (scope && scope->isFunction() && lookupItem.type().match(scope->asFunction()->returnType())) { return; } m_element = QSharedPointer<CppElement>(new Unknown(type)); } else { const FullySpecifiedType &type = declaration->type(); if (declaration->isNamespace()) { m_element = QSharedPointer<CppElement>(new CppNamespace(declaration)); } else if (declaration->isClass() || declaration->isForwardClassDeclaration() || (declaration->isTemplate() && declaration->asTemplate()->declaration() && (declaration->asTemplate()->declaration()->isClass() || declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) { LookupContext contextToUse = context; if (declaration->isForwardClassDeclaration()) if (Symbol *classDeclaration = m_symbolFinder.findMatchingClassDeclaration(declaration, snapshot)) { declaration = classDeclaration; const QString fileName = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength()); const Document::Ptr declarationDocument = snapshot.document(fileName); if (declarationDocument != context.thisDocument()) contextToUse = LookupContext(declarationDocument, snapshot); } CppClass *cppClass = new CppClass(declaration); if (m_lookupBaseClasses) cppClass->lookupBases(declaration, contextToUse); if (m_lookupDerivedClasses) cppClass->lookupDerived(declaration, snapshot); m_element = QSharedPointer<CppElement>(cppClass); } else if (Enum *enumDecl = declaration->asEnum()) { m_element = QSharedPointer<CppElement>(new CppEnum(enumDecl)); } else if (EnumeratorDeclaration *enumerator = dynamic_cast<EnumeratorDeclaration *>(declaration)) { m_element = QSharedPointer<CppElement>(new CppEnumerator(enumerator)); } else if (declaration->isTypedef()) { m_element = QSharedPointer<CppElement>(new CppTypedef(declaration)); } else if (declaration->isFunction() || (type.isValid() && type->isFunctionType()) || declaration->isTemplate()) { m_element = QSharedPointer<CppElement>(new CppFunction(declaration)); } else if (declaration->isDeclaration() && type.isValid()) { m_element = QSharedPointer<CppElement>( new CppVariable(declaration, context, lookupItem.scope())); } else { m_element = QSharedPointer<CppElement>(new CppDeclarableElement(declaration)); } } }
void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot, const LookupItem &lookupItem, const LookupContext &context) { Symbol *declaration = lookupItem.declaration(); if (!declaration) { const QString &type = Overview().prettyType(lookupItem.type(), QString()); m_element = QSharedPointer<CppElement>(new Unknown(type)); } else { const FullySpecifiedType &type = declaration->type(); if (declaration->isNamespace()) { m_element = QSharedPointer<CppElement>(new CppNamespace(declaration)); } else if (declaration->isClass() || declaration->isForwardClassDeclaration() || (declaration->isTemplate() && declaration->asTemplate()->declaration() && (declaration->asTemplate()->declaration()->isClass() || declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) { if (declaration->isForwardClassDeclaration()) if (Symbol *classDeclaration = m_symbolFinder.findMatchingClassDeclaration(declaration, snapshot)) { declaration = classDeclaration; } CppClass *cppClass = new CppClass(declaration); if (m_lookupBaseClasses) cppClass->lookupBases(declaration, context); if (m_lookupDerivedClasses) cppClass->lookupDerived(declaration, snapshot); m_element = QSharedPointer<CppElement>(cppClass); } else if (Enum *enumDecl = declaration->asEnum()) { m_element = QSharedPointer<CppElement>(new CppEnum(enumDecl)); } else if (EnumeratorDeclaration *enumerator = dynamic_cast<EnumeratorDeclaration *>(declaration)) { m_element = QSharedPointer<CppElement>(new CppEnumerator(enumerator)); } else if (declaration->isTypedef()) { m_element = QSharedPointer<CppElement>(new CppTypedef(declaration)); } else if (declaration->isFunction() || (type.isValid() && type->isFunctionType()) || declaration->isTemplate()) { m_element = QSharedPointer<CppElement>(new CppFunction(declaration)); } else if (declaration->isDeclaration() && type.isValid()) { m_element = QSharedPointer<CppElement>( new CppVariable(declaration, context, lookupItem.scope())); } else { m_element = QSharedPointer<CppElement>(new CppDeclarableElement(declaration)); } } }
bool TypeResolver::findTypedef(const QList<LookupItem> &namedTypeItems, FullySpecifiedType *type, Scope **scope, QSet<Symbol *> &visited) { foreach (const LookupItem &it, namedTypeItems) { Symbol *declaration = it.declaration(); if (!declaration) continue; if (Template *specialization = declaration->asTemplate()) declaration = specialization->declaration(); if (!declaration || (!declaration->isTypedef() && !declaration->type().isDecltype())) continue; if (visited.contains(declaration)) break; visited.insert(declaration); // continue working with the typedefed type and scope if (type->type()->isPointerType()) { *type = FullySpecifiedType( _factory.control()->pointerType(declaration->type())); } else if (type->type()->isReferenceType()) { *type = FullySpecifiedType( _factory.control()->referenceType( declaration->type(), declaration->type()->asReferenceType()->isRvalueReference())); } else if (declaration->type().isDecltype()) { Declaration *decl = declaration->asDeclaration(); const QList<LookupItem> resolved = resolveDeclInitializer(_factory, decl, QSet<const Declaration* >() << decl); if (!resolved.isEmpty()) { LookupItem item = resolved.first(); *type = item.type(); *scope = item.scope(); _binding = item.binding(); return true; } } else { *type = it.type(); } *scope = it.scope(); _binding = it.binding(); return true; }
QString CPlusPlus::toString(const LookupItem &it, const QString &id) { QString result = QString::fromLatin1("%1:").arg(id); if (it.declaration()) result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.declaration(), QLatin1String("Decl"))))); if (it.type().isValid()) result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.type())))); if (it.scope()) result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.scope(), QLatin1String("Scope"))))); if (it.binding()) result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.binding(), QLatin1String("Binding"))))); return result; }