IndexedTypeIdentifier typeIdentifierFromTemplateArgument(ParseSession* session, TemplateArgumentAST *node) { IndexedTypeIdentifier id; if(node->expression) { id = IndexedTypeIdentifier(session->stringForNode(node), true); }else if(node->type_id) { //Parse the pointer operators TypeCompiler tc(session); tc.run(node->type_id->type_specifier); id = IndexedTypeIdentifier(tc.identifier()); //node->type_id->type_specifier->cv if(node->type_id->type_specifier) id.setIsConstant(parseConstVolatile(session, node->type_id->type_specifier->cv) & AbstractType::ConstModifier); if(node->type_id->declarator && node->type_id->declarator->ptr_ops) { const ListNode<PtrOperatorAST*> *it = node->type_id->declarator->ptr_ops->toFront(); const ListNode<PtrOperatorAST*> *end = it; ///@todo check ordering, eventually walk the list in reversed order do { if(it->element && it->element->op) { ///@todo What about ptr-to-member? int kind = session->token_stream->kind(it->element->op); if(kind == '&') { //We're handling a 'reference' id.setIsReference(true); } else if(kind == Token_and) { //We're handling an rvalue-reference id.setIsReference(true); id.setIsRValue(true); } else { //We're handling a real pointer id.setPointerDepth(id.pointerDepth()+1); if(it->element->cv) { id.setIsConstPointer(id.pointerDepth()-1, parseConstVolatile(session, it->element->cv) & AbstractType::ConstModifier); } } } it = it->next; } while (it != end); } else if (node->type_id->declarator && node->type_id->declarator->array_dimensions) { ///FIXME: find a way to put this information into the identifier /// e.g.: id.setArrayDepth(id.arrayDepth() + 1) ? const ListNode< ExpressionAST* >* it = node->type_id->declarator->array_dimensions->toFront(); const ListNode< ExpressionAST* >* end = node->type_id->declarator->array_dimensions-> toBack(); do { QualifiedIdentifier qid = id.identifier(); Identifier last = qid.last(); qid.pop(); last.setIdentifier(last.toString() + "[]"); qid.push(last); id.setIdentifier(IndexedQualifiedIdentifier( qid )); it = it->next; } while (it != end); } } return id; }
QualifiedIdentifier InstantiationInformation::applyToIdentifier(const QualifiedIdentifier& id) const { QualifiedIdentifier ret; if(id.count() > 1) { ret = id; ret.pop(); if(previousInstantiationInformation.index()) ret = previousInstantiationInformation.information().applyToIdentifier(ret); } Identifier lastId(id.last()); KDevVarLengthArray<IndexedTypeIdentifier> oldTemplateIdentifiers; for(uint a = 0; a < lastId.templateIdentifiersCount(); ++a) oldTemplateIdentifiers.append(lastId.templateIdentifier(a)); lastId.clearTemplateIdentifiers(); for(uint a = 0; a < templateParametersSize(); ++a) { if(templateParameters()[a].abstractType()) { lastId.appendTemplateIdentifier(IndexedTypeIdentifier(templateParameters()[a].abstractType()->toString(), true)); }else{ lastId.appendTemplateIdentifier((uint) oldTemplateIdentifiers.size() > a ? oldTemplateIdentifiers[a] : IndexedTypeIdentifier()); } } for(int a = templateParametersSize(); a < oldTemplateIdentifiers.size(); ++a) lastId.appendTemplateIdentifier(oldTemplateIdentifiers[a]); ret.push(lastId); return ret; }
void NamespaceAliasDeclaration::registerAliasIdentifier() { if(indexedIdentifier() != globalImportIdentifier()) { QualifiedIdentifier aliasId = qualifiedIdentifier(); aliasId.push(globalAliasIdentifier()); KDevelop::PersistentSymbolTable::self().addDeclaration(aliasId, this); } }
void TestIdentifier::testQualifiedIdentifier() { QFETCH(QString, stringId); const QStringList list = stringId.split(QStringLiteral("::"), QString::SkipEmptyParts); QualifiedIdentifier id(stringId); QCOMPARE(id.isEmpty(), stringId.isEmpty()); QCOMPARE(id, QualifiedIdentifier(stringId)); QVERIFY(!(id != QualifiedIdentifier(stringId))); QCOMPARE(id, QualifiedIdentifier(stringId)); if (list.size() == 1) { QCOMPARE(id, QualifiedIdentifier(Identifier(list.last()))); } else if (list.isEmpty()) { QualifiedIdentifier empty{Identifier()}; QCOMPARE(id, empty); QVERIFY(empty.isEmpty()); QVERIFY(empty.inRepository()); } QCOMPARE(id.toString(), stringId); QCOMPARE(id.toStringList(), list); QCOMPARE(id.top(), Identifier(list.isEmpty() ? QString() : list.last())); if (stringId.isEmpty()) { QVERIFY(id.inRepository()); QVERIFY(QualifiedIdentifier(id).inRepository()); } QualifiedIdentifier copy = id; QCOMPARE(copy, id); copy = copy; QCOMPARE(copy, id); copy = QualifiedIdentifier(); QVERIFY(copy.isEmpty()); copy = id; QCOMPARE(copy, id); IndexedQualifiedIdentifier indexedId(id); QVERIFY(indexedId == id); QCOMPARE(indexedId, IndexedQualifiedIdentifier(id)); QCOMPARE(indexedId.isValid(), !stringId.isEmpty()); QCOMPARE(indexedId.identifier(), id); IndexedQualifiedIdentifier indexedCopy = indexedId; QCOMPARE(indexedCopy, indexedId); indexedCopy = indexedCopy; QCOMPARE(indexedCopy, indexedId); indexedCopy = IndexedQualifiedIdentifier(); QVERIFY(!indexedCopy.isValid()); indexedCopy = indexedId; QCOMPARE(indexedCopy, indexedId); QualifiedIdentifier moved = std::move(id); QVERIFY(id.isEmpty()); QCOMPARE(moved, copy); IndexedQualifiedIdentifier movedIndexed = std::move(indexedId); QVERIFY(indexedId.isEmpty()); QCOMPARE(movedIndexed, indexedCopy); copy.clear(); QVERIFY(copy.isEmpty()); copy.push(moved); QCOMPARE(copy, moved); copy.push(Identifier(QStringLiteral("lalala"))); QCOMPARE(copy.count(), moved.count() + 1); }