diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index dc9448cd7233344431437b8a58ee84ca48db8315..02eddeb8ba2fa7aa48b21e49b9463ba975cbeab2 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -3904,12 +3904,17 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de startOfNamedTypeSpecifier = cursor(); if (parseName(named_type_specifier)) { - if (LA() == T_LPAREN && identifier(named_type_specifier) == className(declaringClass)) { - // looks like a constructor declaration - rewind(startOfNamedTypeSpecifier); - break; - } - + const Identifier *classIdentifier = className(declaringClass); + if (QualifiedNameAST *qn = named_type_specifier->asQualifiedName()) + if (NestedNameSpecifierListAST *namesList = qn->nested_name_specifier_list) + if (NestedNameSpecifierAST *lastName = namesList->lastValue()) + classIdentifier = identifier(lastName->class_or_namespace_name); + + if (LA() == T_LPAREN && identifier(named_type_specifier) == classIdentifier) { + // looks like a constructor declaration + rewind(startOfNamedTypeSpecifier); + break; + } NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST; spec->name = named_type_specifier; diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp index 0afa5e25329784b35dcb31a66d305a370f67f225..33be7a677e59e64cae363f5d2f7fc45b4140ddbc 100644 --- a/tests/auto/cplusplus/ast/tst_ast.cpp +++ b/tests/auto/cplusplus/ast/tst_ast.cpp @@ -136,6 +136,16 @@ private slots: void assignment_1(); void assignment_2(); + // constructor declarations + void cpp_constructor_one_unamed_arg(); + void cpp_constructor_one_unamed_arg_namespace(); + void cpp_constructor_one_knowntype_arg(); + void cpp_constructor_one_const_arg(); + void cpp_constructor_one_ref_arg(); + void cpp_constructor_one_named_arg(); + void cpp_constructor_no_arg(); + void cpp_constructor_multiple_args(); + // objc++ void objc_simple_class(); void objc_attributes_followed_by_at_keyword(); @@ -1050,6 +1060,150 @@ void tst_AST::cpp_initializer_or_function_declaration() QCOMPARE(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4U); } +void tst_AST::cpp_constructor_one_unamed_arg() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("QFileInfo::QFileInfo(QString /*name*/) {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause != 0); + QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); +} + +void tst_AST::cpp_constructor_one_unamed_arg_namespace() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("Foo::QFileInfo::QFileInfo(QString /*name*/) {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause != 0); + QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); +} + +void tst_AST::cpp_constructor_one_named_arg() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("QFileInfo::QFileInfo(QString name) {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause != 0); + QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); +} + +void tst_AST::cpp_constructor_one_knowntype_arg() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("QFileInfo::QFileInfo(int /*name*/) {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause != 0); + QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); +} + + +void tst_AST::cpp_constructor_one_const_arg() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("QFileInfo::QFileInfo(const QString /*name*/) {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause != 0); + QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); +} + +void tst_AST::cpp_constructor_one_ref_arg() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("QFileInfo::QFileInfo(QString & /*name*/) {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause != 0); + QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); +} + +void tst_AST::cpp_constructor_no_arg() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("QFileInfo::QFileInfo() {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause == 0); +} + +void tst_AST::cpp_constructor_multiple_args() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("QFileInfo::QFileInfo(QString /*name*/, QString /*type*/) {}")); + AST *ast = unit->ast(); + QVERIFY(ast != 0); + + FunctionDefinitionAST *funDef = ast->asFunctionDefinition(); + QVERIFY(funDef != 0); + QVERIFY(funDef->declarator != 0); + QVERIFY(funDef->declarator->postfix_declarator_list != 0); + QVERIFY(funDef->declarator->postfix_declarator_list->lastValue() != 0); + + FunctionDeclaratorAST *funDecl = funDef->declarator->postfix_declarator_list->lastValue()->asFunctionDeclarator(); + QVERIFY(funDecl != 0); + QVERIFY(funDecl->parameter_declaration_clause != 0); + QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); +} + void tst_AST::objc_simple_class() { QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"