bool CheckDeclaration::visit(ParameterDeclarationAST *ast) { unsigned sourceLocation = locationOfDeclaratorId(ast->declarator); if (! sourceLocation) { if (ast->declarator) sourceLocation = ast->declarator->firstToken(); else sourceLocation = ast->firstToken(); } const Name *argName = 0; FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(), _scope, &argName); FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); Argument *arg = control()->newArgument(sourceLocation, argName); ast->symbol = arg; if (ast->expression) { unsigned startOfExpression = ast->expression->firstToken(); unsigned endOfExpression = ast->expression->lastToken(); std::string buffer; for (unsigned index = startOfExpression; index != endOfExpression; ++index) { const Token &tk = tokenAt(index); if (tk.whitespace() || tk.newline()) buffer += ' '; buffer += tk.spell(); } const StringLiteral *initializer = control()->findOrInsertStringLiteral(buffer.c_str(), buffer.size()); arg->setInitializer(initializer); } arg->setType(argTy); _scope->enterSymbol(arg); return false; }
bool CheckExpression::visit(TypeIdAST *ast) { FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope); FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(), _scope); _fullySpecifiedType = declTy; return false; }
bool CheckDeclaration::visit(ExceptionDeclarationAST *ast) { FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); Name *name = 0; FullySpecifiedType declTy = semantic()->check(ast->declarator, qualTy, _scope, &name); unsigned location = locationOfDeclaratorId(ast->declarator); if (! location) { if (ast->declarator) location = ast->declarator->firstToken(); else location = ast->firstToken(); } Declaration *symbol = control()->newDeclaration(location, name); symbol->setStartOffset(tokenAt(ast->firstToken()).offset); symbol->setEndOffset(tokenAt(ast->lastToken()).offset); symbol->setType(declTy); _scope->enterSymbol(symbol); return false; }
static QStringList collectFieldNames(ClassSpecifierAST *classAST, bool onlyTokensAndASTNodes) { QStringList fields; Overview oo; Class *clazz = classAST->symbol; for (unsigned i = 0; i < clazz->memberCount(); ++i) { Symbol *s = clazz->memberAt(i); if (Declaration *decl = s->asDeclaration()) { const QString declName = oo(decl->name()); const FullySpecifiedType ty = decl->type(); if (const PointerType *ptrTy = ty->asPointerType()) { if (onlyTokensAndASTNodes) { if (const NamedType *namedTy = ptrTy->elementType()->asNamedType()) { if (oo(namedTy->name()).endsWith(QLatin1String("AST"))) fields.append(declName); } } else { fields.append(declName); } } else if (ty.isUnsigned()) { fields.append(declName); } } } return fields; }
bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast) { if (!ast->method_prototype) return false; FullySpecifiedType ty = semantic()->check(ast->method_prototype, _scope); ObjCMethod *methodType = ty.type()->asObjCMethodType(); if (!methodType) return false; Symbol *symbol; if (ast->function_body) { if (!semantic()->skipFunctionBodies()) { semantic()->check(ast->function_body, methodType->members()); } symbol = methodType; } else { Declaration *decl = control()->newDeclaration(ast->firstToken(), methodType->name()); decl->setType(methodType); symbol = decl; } symbol->setStartOffset(tokenAt(ast->firstToken()).offset); symbol->setEndOffset(tokenAt(ast->lastToken()).offset); symbol->setVisibility(semantic()->currentVisibility()); if (semantic()->isObjCClassMethod(ast->method_prototype->method_type_token)) symbol->setStorage(Symbol::Static); _scope->enterSymbol(symbol); return false; }
bool CheckStatement::visit(QtMemberDeclarationAST *ast) { const Name *name = 0; if (tokenKind(ast->q_token) == T_Q_D) name = control()->nameId(control()->findOrInsertIdentifier("d")); else name = control()->nameId(control()->findOrInsertIdentifier("q")); FullySpecifiedType declTy = semantic()->check(ast->type_id, _scope); if (tokenKind(ast->q_token) == T_Q_D) { if (NamedType *namedTy = declTy->asNamedType()) { if (const NameId *nameId = namedTy->name()->asNameId()) { std::string privateClass; privateClass += nameId->identifier()->chars(); privateClass += "Private"; const Name *privName = control()->nameId(control()->findOrInsertIdentifier(privateClass.c_str(), privateClass.size())); declTy.setType(control()->namedType(privName)); } } } Declaration *symbol = control()->newDeclaration(/*generated*/ 0, name); symbol->setType(control()->pointerType(declTy)); _scope->enterSymbol(symbol); return false; }
void accept(const FullySpecifiedType &ty) { TypeVisitor::accept(ty.type()); unsigned flags = ty.flags(); flags |= temps.back().flags(); temps.back().setFlags(flags); }
void TypePrettyPrinter::prependSpaceBeforeIndirection(const FullySpecifiedType &type) { const bool elementTypeIsPointerOrReference = type.type()->isPointerType() || type.type()->isReferenceType(); const bool elementIsConstPointerOrReference = elementTypeIsPointerOrReference && type.isConst(); const bool shouldBindToLeftSpecifier = _overview->starBindFlags & Overview::BindToLeftSpecifier; if (elementIsConstPointerOrReference && ! shouldBindToLeftSpecifier) _text.prepend(QLatin1String(" ")); }
bool CheckExpression::visit(CastExpressionAST *ast) { FullySpecifiedType castTy = semantic()->check(ast->type_id, _scope); FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); if (_checkOldStyleCasts && ! castTy->isVoidType()) translationUnit()->warning(ast->firstToken(), "ugly old style cast"); return false; }
void CloneType::visit(NamedType *type) { const Name *name = _clone->name(type->name(), _subst); FullySpecifiedType ty; if (_subst) ty = _subst->apply(name); if (! ty.isValid()) ty = _control->namedType(name); _type.setType(ty.type()); }
virtual void visit(NamedType *type) { FullySpecifiedType ty = rewrite->env->apply(type->name(), rewrite); if (! ty->isUndefinedType()) { temps.append(ty); } else { const Name *name = rewrite->rewriteName(type->name()); temps.append(control()->namedType(name)); } }
bool CheckExpression::visit(ConditionAST *ast) { FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope); const Name *name = 0; FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(), _scope, &name); Declaration *decl = control()->newDeclaration(ast->declarator->firstToken(), name); decl->setType(declTy); _scope->enterSymbol(decl); return false; }
void TypePrettyPrinter::outCV(const FullySpecifiedType &ty) { if (ty.isConst() && ty.isVolatile()) _text += QLatin1String("const volatile"); else if (ty.isConst()) _text += QLatin1String("const"); else if (ty.isVolatile()) _text += QLatin1String("volatile"); }
void TypePrettyPrinter::prependCv(const FullySpecifiedType &ty) { if (ty.isVolatile()) { prependWordSeparatorSpace(); _text.prepend("volatile"); } if (ty.isConst()) { prependWordSeparatorSpace(); _text.prepend("const"); } }
void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty) { if (ty.isSigned()) _text += QLatin1String("signed "); else if (ty.isUnsigned()) _text += QLatin1String("unsigned "); const FullySpecifiedType previousFullySpecifiedType = _fullySpecifiedType; _fullySpecifiedType = ty; accept(ty.type()); _fullySpecifiedType = previousFullySpecifiedType; }
FullySpecifiedType SubstitutionEnvironment::apply(const Name *name, Rewrite *rewrite) const { if (name) { for (int index = _substs.size() - 1; index != -1; --index) { const Substitution *subst = _substs.at(index); FullySpecifiedType ty = subst->apply(name, rewrite); if (! ty->isUndefinedType()) return ty; } } return FullySpecifiedType(); }
FullySpecifiedType FullySpecifiedType::qualifiedType() const { FullySpecifiedType ty = *this; ty.setFriend(false); ty.setRegister(false); ty.setStatic(false); ty.setExtern(false); ty.setMutable(false); ty.setTypedef(false); ty.setInline(false); ty.setVirtual(false); ty.setExplicit(false); return ty; }
std::string TypeNameSpeller::spellTypeName(const FullySpecifiedType& fullType, const CPlusPlus::Scope* scope, std::string* alpha) { spelling_.clear(); alpha_ = alpha; if (fullType.isUnsigned()) spelling_.append("unsigned "); scope_ = scope; accept(fullType.type()); return spelling_; }
bool FullySpecifiedType::match(const FullySpecifiedType &otherTy, TypeMatcher *matcher) const { if (_flags != otherTy._flags) return false; return type()->matchType(otherTy.type(), matcher); }
void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty) { const FullySpecifiedType previousFullySpecifiedType = _fullySpecifiedType; _fullySpecifiedType = ty; accept(ty.type()); _fullySpecifiedType = previousFullySpecifiedType; }
QList<Function *> FunctionUtils::overrides(Function *function, Class *functionsClass, Class *staticClass, const Snapshot &snapshot) { QList<Function *> result; QTC_ASSERT(function && functionsClass && staticClass, return result); FullySpecifiedType referenceType = function->type(); const Name *referenceName = function->name(); QTC_ASSERT(referenceName && referenceType.isValid(), return result); // Find overrides TypeHierarchyBuilder builder(staticClass, snapshot); const TypeHierarchy &staticClassHierarchy = builder.buildDerivedTypeHierarchy(); QList<TypeHierarchy> l; if (functionsClass != staticClass) l.append(TypeHierarchy(functionsClass)); l.append(staticClassHierarchy); while (!l.isEmpty()) { // Add derived const TypeHierarchy hierarchy = l.takeFirst(); QTC_ASSERT(hierarchy.symbol(), continue); Class *c = hierarchy.symbol()->asClass(); QTC_ASSERT(c, continue); foreach (const TypeHierarchy &t, hierarchy.hierarchy()) { if (!l.contains(t)) l << t; } // Check member functions for (int i = 0, total = c->memberCount(); i < total; ++i) { Symbol *candidate = c->memberAt(i); const Name *candidateName = candidate->name(); Function *candidateFunc = candidate->type()->asFunctionType(); if (!candidateName || !candidateFunc) continue; if (candidateName->match(referenceName) && candidateFunc->isSignatureEqualTo(function)) { result << candidateFunc; } } } return result; }
bool CheckExpression::visit(QtMethodAST *ast) { const Name *name = 0; Scope dummy; FullySpecifiedType methTy = semantic()->check(ast->declarator, FullySpecifiedType(), &dummy, &name); Function *fty = methTy->asFunctionType(); if (! fty) translationUnit()->warning(ast->firstToken(), "expected a function declarator"); else { for (unsigned i = 0; i < fty->argumentCount(); ++i) { Symbol *arg = fty->argumentAt(i); if (arg->name()) translationUnit()->warning(arg->sourceLocation(), "argument should be anonymous"); } } return false; }
void TypePrettyPrinter::applyPtrOperators(bool wantSpace) { if (wantSpace && !_ptrOperators.isEmpty()) space(); for (int i = _ptrOperators.size() - 1; i != -1; --i) { const FullySpecifiedType op = _ptrOperators.at(i); if (op->isPointerType()) { _text += QLatin1Char('*'); outCV(op); } else if (op->isReferenceType()) { _text += QLatin1Char('&'); } else if (const PointerToMemberType *memPtrTy = op->asPointerToMemberType()) { space(); _text += _overview->prettyName(memPtrTy->memberName()); _text += QLatin1Char('*'); outCV(op); } } }
/*! Rewrite/format the given type and name. */ QString PointerDeclarationFormatter::rewriteDeclaration(FullySpecifiedType type, const Name *name) const { CHECK_RV(type.isValid(), "Invalid type", QString()); const char *identifier = 0; if (const Name *declarationName = name) { if (const Identifier *id = declarationName->identifier()) identifier = id->chars(); } return m_overview.prettyType(type, QLatin1String(identifier)); }
bool CheckDeclaration::visit(ParameterDeclarationAST *ast) { unsigned sourceLocation = locationOfDeclaratorId(ast->declarator); if (! sourceLocation) { if (ast->declarator) sourceLocation = ast->declarator->firstToken(); else sourceLocation = ast->firstToken(); } Name *argName = 0; FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope); FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(), _scope, &argName); FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); Argument *arg = control()->newArgument(sourceLocation, argName); ast->symbol = arg; if (ast->expression) arg->setInitializer(true); arg->setType(argTy); _scope->enterSymbol(arg); return false; }
bool CheckDeclaration::visit(FunctionDefinitionAST *ast) { FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); Name *name = 0; FullySpecifiedType funTy = semantic()->check(ast->declarator, qualTy, _scope, &name); if (! (funTy && funTy->isFunctionType())) { translationUnit()->error(ast->firstToken(), "expected a function prototype"); return false; } Function *fun = funTy->asFunctionType(); fun->setVirtual(ty.isVirtual()); fun->setStartOffset(tokenAt(ast->firstToken()).offset); fun->setEndOffset(tokenAt(ast->lastToken()).offset); if (ast->declarator) fun->setSourceLocation(ast->declarator->firstToken()); fun->setName(name); fun->setTemplateParameters(_templateParameters); fun->setVisibility(semantic()->currentVisibility()); fun->setMethodKey(semantic()->currentMethodKey()); const bool isQ_SLOT = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT; const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; if (isQ_SIGNAL) fun->setMethodKey(Function::SignalMethod); else if (isQ_SLOT) fun->setMethodKey(Function::SlotMethod); checkFunctionArguments(fun); ast->symbol = fun; _scope->enterSymbol(fun); if (! semantic()->skipFunctionBodies()) { if (ast->ctor_initializer) { bool looksLikeCtor = false; if (ty.isValid() || ! fun->identity()) looksLikeCtor = false; else if (fun->identity()->isNameId() || fun->identity()->isTemplateNameId()) looksLikeCtor = true; if (! looksLikeCtor) { translationUnit()->error(ast->ctor_initializer->firstToken(), "only constructors take base initializers"); } accept(ast->ctor_initializer); } const int previousVisibility = semantic()->switchVisibility(Symbol::Public); const int previousMethodKey = semantic()->switchMethodKey(Function::NormalMethod); semantic()->check(ast->function_body, fun->members()); semantic()->switchMethodKey(previousMethodKey); semantic()->switchVisibility(previousVisibility); } return false; }
SymbolInfo::ElementType SymbolInfo::elementTypeFromSymbol( const CPlusPlus::Symbol *symbol ) { if (const Template *templ = symbol->asTemplate()) { if (Symbol *decl = templ->declaration()) return elementTypeFromSymbol(decl); } FullySpecifiedType symbolType = symbol->type(); if (symbol->isFunction() || (symbol->isDeclaration() && symbolType && symbolType->isFunctionType())) { const CPlusPlus::Function *func = symbol->asFunction(); if (!func) func = symbol->type()->asFunctionType(); if (func->isSlot() ) { if (func->isPublic()) return SymbolInfo::SlotPublic; else if (func->isProtected()) return SymbolInfo::SlotProtected; else if (func->isPrivate()) return SymbolInfo::SlotPrivate; } else if (func->isSignal()) { return SymbolInfo::Signal; } else if (symbol->isPublic()) { return SymbolInfo::FuncPublic; } else if (symbol->isProtected()) { return SymbolInfo::FuncProtected; } else if (symbol->isPrivate()) { return SymbolInfo::FuncPrivate; } } else if (symbol->enclosingScope() && symbol->enclosingScope()->isEnum()) { return SymbolInfo::Enumerator; } else if (symbol->isDeclaration() || symbol->isArgument()) { if (symbol->isPublic()) return SymbolInfo::VarPublic; else if (symbol->isProtected()) return SymbolInfo::VarProtected; else if (symbol->isPrivate()) return SymbolInfo::VarPrivate; } else if (symbol->isEnum()) { return SymbolInfo::Enum; } else if (symbol->isClass() || symbol->isForwardClassDeclaration()) { return SymbolInfo::Class; } else if (symbol->isObjCClass() || symbol->isObjCForwardClassDeclaration()) { return SymbolInfo::Class; } else if (symbol->isObjCProtocol() || symbol->isObjCForwardProtocolDeclaration()) { return SymbolInfo::Class; } else if (symbol->isObjCMethod()) { return SymbolInfo::FuncPublic; } else if (symbol->isNamespace()) { return SymbolInfo::Namespace; } else if (symbol->isTypenameArgument()) { return SymbolInfo::Class; } else if (symbol->isUsingNamespaceDirective() || symbol->isUsingDeclaration()) { // TODO: Might be nice to have a different icons for these things return SymbolInfo::Namespace; } else if (symbol->isBlock()){ return SymbolInfo::Block; } return SymbolInfo::Unknown; }
bool CheckDeclaration::visit(SimpleDeclarationAST *ast) { FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); if (_templateParameters && ty) { if (Class *klass = ty->asClassType()) { klass->setTemplateParameters(_templateParameters); } } if (! ast->declarators && ast->decl_specifier_seq && ! ast->decl_specifier_seq->next) { if (ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) { unsigned sourceLocation = elab_type_spec->firstToken(); if (elab_type_spec->name) sourceLocation = elab_type_spec->name->firstToken(); Name *name = semantic()->check(elab_type_spec->name, _scope); ForwardClassDeclaration *symbol = control()->newForwardClassDeclaration(sourceLocation, name); if (_templateParameters) { symbol->setTemplateParameters(_templateParameters); _templateParameters = 0; } _scope->enterSymbol(symbol); return false; } } const bool isQ_SLOT = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT; const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; List<Declaration *> **decl_it = &ast->symbols; for (DeclaratorListAST *it = ast->declarators; it; it = it->next) { Name *name = 0; FullySpecifiedType declTy = semantic()->check(it->declarator, qualTy, _scope, &name); unsigned location = locationOfDeclaratorId(it->declarator); if (! location) { if (it->declarator) location = it->declarator->firstToken(); else location = ast->firstToken(); } Function *fun = 0; if (declTy && 0 != (fun = declTy->asFunctionType())) { fun->setSourceLocation(location); fun->setScope(_scope); fun->setName(name); fun->setMethodKey(semantic()->currentMethodKey()); fun->setVirtual(ty.isVirtual()); if (isQ_SIGNAL) fun->setMethodKey(Function::SignalMethod); else if (isQ_SLOT) fun->setMethodKey(Function::SlotMethod); fun->setVisibility(semantic()->currentVisibility()); } else if (semantic()->currentMethodKey() != Function::NormalMethod) { translationUnit()->warning(ast->firstToken(), "expected a function declaration"); } Declaration *symbol = control()->newDeclaration(location, name); symbol->setStartOffset(tokenAt(ast->firstToken()).offset); symbol->setEndOffset(tokenAt(ast->lastToken()).offset); symbol->setType(control()->integerType(IntegerType::Int)); symbol->setType(declTy); if (_templateParameters && it == ast->declarators && ty && ! ty->isClassType()) symbol->setTemplateParameters(_templateParameters); symbol->setVisibility(semantic()->currentVisibility()); if (ty.isFriend()) symbol->setStorage(Symbol::Friend); else if (ty.isRegister()) symbol->setStorage(Symbol::Register); else if (ty.isStatic()) symbol->setStorage(Symbol::Static); else if (ty.isExtern()) symbol->setStorage(Symbol::Extern); else if (ty.isMutable()) symbol->setStorage(Symbol::Mutable); else if (ty.isTypedef()) symbol->setStorage(Symbol::Typedef); if (it->declarator && it->declarator->initializer) { FullySpecifiedType initTy = semantic()->check(it->declarator->initializer, _scope); } *decl_it = new (translationUnit()->memoryPool()) List<Declaration *>(); (*decl_it)->value = symbol; decl_it = &(*decl_it)->next; _scope->enterSymbol(symbol); } return false; }
/*! Performs some further checks and rewrites the type and name of \a symbol into the substitution range in the file specified by \a tokenRange. */ void PointerDeclarationFormatter::checkAndRewrite(DeclaratorAST *declarator, Symbol *symbol, TokenRange tokenRange, unsigned charactersToRemove) { CHECK_R(tokenRange.end > 0, "TokenRange invalid1"); CHECK_R(tokenRange.start < tokenRange.end, "TokenRange invalid2"); CHECK_R(symbol, "No symbol"); // Check for expanded tokens for (unsigned token = tokenRange.start; token <= tokenRange.end; ++token) CHECK_R(!tokenAt(token).expanded(), "Token is expanded"); Range range(m_cppRefactoringFile->startOf(tokenRange.start), m_cppRefactoringFile->endOf(tokenRange.end)); CHECK_R(range.start >= 0 && range.end > 0, "ChangeRange invalid1"); CHECK_R(range.start < range.end, "ChangeRange invalid2"); // Check range with respect to cursor position / selection if (m_cursorHandling == RespectCursor) { const QTextCursor cursor = m_cppRefactoringFile->cursor(); if (cursor.hasSelection()) { CHECK_R(cursor.selectionStart() <= range.start, "Change not in selection range"); CHECK_R(range.end <= cursor.selectionEnd(), "Change not in selection range"); } else { CHECK_R(range.start <= cursor.selectionStart(), "Cursor before activation range"); CHECK_R(cursor.selectionEnd() <= range.end, "Cursor after activation range"); } } FullySpecifiedType type = symbol->type(); if (Function *function = type->asFunctionType()) type = function->returnType(); // Check if pointers or references are involved const QString originalDeclaration = m_cppRefactoringFile->textOf(range); CHECK_R(originalDeclaration.contains(QLatin1Char('&')) || originalDeclaration.contains(QLatin1Char('*')), "No pointer or references"); // Does the rewritten declaration (part) differs from the original source (part)? QString rewrittenDeclaration; const Name *name = symbol->name(); if (name) { if (name->isOperatorNameId() || (name->isQualifiedNameId() && name->asQualifiedNameId()->name()->isOperatorNameId())) { const QString operatorText = m_cppRefactoringFile->textOf(declarator->core_declarator); m_overview.includeWhiteSpaceInOperatorName = operatorText.contains(QLatin1Char(' ')); } } rewrittenDeclaration = m_overview.prettyType(type, name); rewrittenDeclaration.remove(0, charactersToRemove); CHECK_R(originalDeclaration != rewrittenDeclaration, "Rewritten is same as original"); CHECK_R(rewrittenDeclaration.contains(QLatin1Char('&')) || rewrittenDeclaration.contains(QLatin1Char('*')), "No pointer or references in rewritten declaration"); if (DEBUG_OUTPUT) { qDebug("==> Rewritten: \"%s\" --> \"%s\"", originalDeclaration.toLatin1().constData(), rewrittenDeclaration.toLatin1().constData()); } // Creating the replacement in the changeset may fail due to operations // in the changeset that overlap with the current range. // // Consider this case: // // void (*foo)(char * s) = 0; // // First visit(SimpleDeclarationAST *ast) will be called. It creates a // replacement that also includes the parameter. // Next visit(ParameterDeclarationAST *ast) is called with the // original source. It tries to create an replacement operation // at this position and fails due to overlapping ranges (the // simple declaration range includes parameter declaration range). ChangeSet change(m_changeSet); if (change.replace(range, rewrittenDeclaration)) m_changeSet = change; else if (DEBUG_OUTPUT) qDebug() << "Replacement operation failed"; }
Icons::IconType Icons::iconTypeForSymbol(const Symbol *symbol) { if (const Template *templ = symbol->asTemplate()) { if (Symbol *decl = templ->declaration()) return iconTypeForSymbol(decl); } FullySpecifiedType symbolType = symbol->type(); if (symbol->isFunction() || (symbol->isDeclaration() && symbolType && symbolType->isFunctionType())) { const Function *function = symbol->asFunction(); if (!function) function = symbol->type()->asFunctionType(); if (function->isSlot()) { if (function->isPublic()) return SlotPublicIconType; else if (function->isProtected()) return SlotProtectedIconType; else if (function->isPrivate()) return SlotPrivateIconType; } else if (function->isSignal()) { return SignalIconType; } else if (symbol->isPublic()) { return FuncPublicIconType; } else if (symbol->isProtected()) { return FuncProtectedIconType; } else if (symbol->isPrivate()) { return FuncPrivateIconType; } } else if (symbol->enclosingScope() && symbol->enclosingScope()->isEnum()) { return EnumeratorIconType; } else if (symbol->isDeclaration() || symbol->isArgument()) { if (symbol->isPublic()) return VarPublicIconType; else if (symbol->isProtected()) return VarProtectedIconType; else if (symbol->isPrivate()) return VarPrivateIconType; } else if (symbol->isEnum()) { return EnumIconType; } else if (symbol->isClass() || symbol->isForwardClassDeclaration()) { return ClassIconType; } else if (symbol->isObjCClass() || symbol->isObjCForwardClassDeclaration()) { return ClassIconType; } else if (symbol->isObjCProtocol() || symbol->isObjCForwardProtocolDeclaration()) { return ClassIconType; } else if (symbol->isObjCMethod()) { return FuncPublicIconType; } else if (symbol->isNamespace()) { return NamespaceIconType; } else if (symbol->isTypenameArgument()) { return ClassIconType; } else if (symbol->isUsingNamespaceDirective() || symbol->isUsingDeclaration()) { // TODO: Might be nice to have a different icons for these things return NamespaceIconType; } return UnknownIconType; }