///TODO: share code with TypeBuilder void TypeASTVisitor::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *node) { if(m_stopSearch) return; Cpp::FindDeclaration find( m_context, m_source, m_flags, m_context->range().end ); find.openQualifiedIdentifier(false); // Don't forget the modifiers! uint modifiers = AbstractType::NoModifiers; if (node->cv) { const ListNode<uint> *it = node->cv->toFront(); const ListNode<uint> *end = it; do { int kind = m_session->token_stream->kind(it->element); switch (kind) { case Token_const: modifiers |= AbstractType::ConstModifier; break; case Token_volatile: modifiers |= AbstractType::VolatileModifier; break; default: //qCDebug(CPPDUCHAIN) << "Unknown modifier token" << kind; break; } it = it->next; } while (it != end); } if (node->integrals) { uint type = IntegralType::TypeNone; const ListNode<uint> *it2 = node->integrals->toFront(); const ListNode<uint> *end = it2; do { int kind = m_session->token_stream->kind(it2->element); switch (kind) { case Token_char: type = IntegralType::TypeChar; break; case Token_char16_t: type = IntegralType::TypeChar16_t; break; case Token_char32_t: type = IntegralType::TypeChar32_t; break; case Token_wchar_t: type = IntegralType::TypeWchar_t; break; case Token_bool: type = IntegralType::TypeBoolean; break; case Token_short: modifiers |= AbstractType::ShortModifier; break; case Token_int: type = IntegralType::TypeInt; break; case Token_long: if (modifiers & AbstractType::LongModifier) modifiers |= AbstractType::LongLongModifier; else modifiers |= AbstractType::LongModifier; break; case Token_signed: modifiers |= AbstractType::SignedModifier; break; case Token_unsigned: modifiers |= AbstractType::UnsignedModifier; break; case Token_float: type = IntegralType::TypeFloat; break; case Token_double: type = IntegralType::TypeDouble; break; case Token_void: type = IntegralType::TypeVoid; break; } it2 = it2->next; } while (it2 != end); if(type == IntegralType::TypeNone) type = IntegralType::TypeInt; //Happens, example: "unsigned short" KDevelop::IntegralType::Ptr integral ( new KDevelop::IntegralType(type) ); integral->setModifiers(modifiers); m_type = integral.cast<AbstractType>(); m_typeId = QualifiedIdentifier(integral->toString()); } else if (node->isTypeof || node->isDecltype) { if (node->expression) { bool isDecltypeInParen = false; if (node->isDecltype && node->expression->kind == AST::Kind_PrimaryExpression) { int startPosition = m_session->token_stream->position(node->expression->start_token); static IndexedString paren("("); isDecltypeInParen = m_session->contentsVector()[startPosition] == paren.index(); } ExpressionParser parser(false, false, isDecltypeInParen); node->expression->ducontext = const_cast<DUContext*>(m_context); ExpressionEvaluationResult result = parser.evaluateType(node->expression, m_session); m_type = result.type.abstractType(); m_typeId = QualifiedIdentifier(result.toString()); { LOCKDUCHAIN; // Transform specific constants like '5' into their type 'int' m_type = TypeUtils::removeConstants(m_type, m_source); } // make reference for decltype in additional parens - but only if it's not already a reference // see spec 7.1.6/4 if (isDecltypeInParen && m_type && !TypeUtils::isReferenceType(m_type)) { // type might already be a ref type ReferenceType::Ptr refType = ReferenceType::Ptr(new ReferenceType); refType->setBaseType(m_type); m_type = refType.cast<AbstractType>(); ///TODO: anything todo with m_typeId ? } if(m_visitor) m_visitor->parse(node->expression); // Give the visitor a chance to build uses } } { LOCKDUCHAIN; find.closeQualifiedIdentifier(); m_declarations = find.lastDeclarations(); if(!m_declarations.isEmpty() && m_declarations[0]) m_type = m_declarations[0]->abstractType(); } visit(node->name); }