diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index bf19628fd23..498bdd5a653 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -1314,31 +1314,47 @@ bool Parser::parseTemplateArgument(ExpressionAST *&node) return parsed; } +/** Parses a sequence of + * + * storage-class-specifier (unless noStorageSpecifier is true) + * trailing-type-specifier, which contains + * cv-qualifier + * simple-type-specifier + * typename-specifier + * elaborated-type-specifier + * + * If onlySimpleTypeSpecifiers is true, it only eats simple-type-specifiers + * and cv-qualifiers. + */ bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq, - bool onlyTypeSpecifiers, - bool simplified) + bool noStorageSpecifiers, + bool onlySimpleTypeSpecifiers) { DEBUG_THIS_RULE(); bool has_type_specifier = false; NameAST *named_type_specifier = 0; SpecifierListAST **decl_specifier_seq_ptr = &decl_specifier_seq; for (;;) { - if (lookAtCVQualifier()) { + if (! noStorageSpecifiers && ! onlySimpleTypeSpecifiers && lookAtStorageClassSpecifier()) { + // storage-class-specifier SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; - } else if (! onlyTypeSpecifiers && lookAtStorageClassSpecifier()) { + } else if (lookAtCVQualifier()) { + // cv-qualifier SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; } else if (! named_type_specifier && lookAtBuiltinTypeSpecifier()) { + // parts of simple-type-specifier parseBuiltinTypeSpecifier(*decl_specifier_seq_ptr); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; has_type_specifier = true; } else if (! has_type_specifier && (LA() == T_COLON_COLON || LA() == T_IDENTIFIER)) { + // parts of simple-type-specifier if (! parseName(named_type_specifier)) return false; NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST; @@ -1346,9 +1362,9 @@ bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq, *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; has_type_specifier = true; - } else if (! simplified && ! has_type_specifier && (LA() == T_TYPENAME || - LA() == T_ENUM || - lookAtClassKey())) { + } else if (! onlySimpleTypeSpecifiers && ! has_type_specifier && + (LA() == T_TYPENAME || LA() == T_ENUM || lookAtClassKey())) { + // typename-specifier, elaborated-type-specifier unsigned startOfElaboratedTypeSpecifier = cursor(); if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)) { error(startOfElaboratedTypeSpecifier, @@ -6472,12 +6488,6 @@ bool Parser::parseTrailingReturnType(TrailingReturnTypeAST *&node) return true; } -bool Parser::parseTrailingTypeSpecifierSeq(SpecifierListAST *&node) -{ - DEBUG_THIS_RULE(); - return parseSimpleTypeSpecifier(node); -} - void Parser::rewind(unsigned cursor) { #ifndef CPLUSPLUS_NO_DEBUG_RULE diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h index 1a2bfa04fd4..ea49df5e561 100644 --- a/src/libs/3rdparty/cplusplus/Parser.h +++ b/src/libs/3rdparty/cplusplus/Parser.h @@ -167,15 +167,18 @@ public: bool parseAttributeSpecifier(SpecifierListAST *&node); bool parseAttributeList(AttributeListAST *&node); + bool parseDeclSpecifierSeq(SpecifierListAST *&node, + bool noStorageSpecifiers = false, + bool onlySimpleTypeSpecifiers = false); + + bool parseTrailingTypeSpecifierSeq(SpecifierListAST *&node) + { return parseDeclSpecifierSeq(node, true); } + /// This actually parses a trailing-type-specifier sequence + bool parseTypeSpecifier(SpecifierListAST *&node) + { return parseTrailingTypeSpecifierSeq(node); } bool parseSimpleTypeSpecifier(SpecifierListAST *&node) { return parseDeclSpecifierSeq(node, true, true); } - bool parseTypeSpecifier(SpecifierListAST *&node) - { return parseDeclSpecifierSeq(node, true); } - - bool parseDeclSpecifierSeq(SpecifierListAST *&node, - bool onlyTypeSpecifiers = false, - bool simplified = false); bool parseUnaryExpression(ExpressionAST *&node); bool parseUnqualifiedName(NameAST *&node, bool acceptTemplateId = true); bool parseUsing(DeclarationAST *&node); @@ -202,7 +205,6 @@ public: bool parseCapture(CaptureAST *&node); bool parseCaptureList(CaptureListAST *&node); bool parseTrailingReturnType(TrailingReturnTypeAST *&node); - bool parseTrailingTypeSpecifierSeq(SpecifierListAST *&node); // ObjC++ bool parseObjCExpression(ExpressionAST *&node); diff --git a/tests/auto/cplusplus/cxx11/data/trailingtypespec.1.cpp b/tests/auto/cplusplus/cxx11/data/trailingtypespec.1.cpp new file mode 100644 index 00000000000..b6e1cc781cb --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/trailingtypespec.1.cpp @@ -0,0 +1,5 @@ +auto foo() + -> const typename XYZ::abc::def; + +auto foo() + -> class XYZ::def; diff --git a/tests/auto/cplusplus/cxx11/data/trailingtypespec.1.errors.txt b/tests/auto/cplusplus/cxx11/data/trailingtypespec.1.errors.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp index 35475b6583e..5f2e67c33f7 100644 --- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp +++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp @@ -152,6 +152,7 @@ void tst_cxx11::parse_data() QTest::newRow("packExpansion.1") << "packExpansion.1.cpp" << ""; QTest::newRow("declType.1") << "declType.1.cpp" << ""; QTest::newRow("threadLocal.1") << "threadLocal.1.cpp" << ""; + QTest::newRow("trailingtypespec.1") << "trailingtypespec.1.cpp" << ""; } void tst_cxx11::parse()