forked from qt-creator/qt-creator
C++11: Make 'enum struct', enum-base and opaque enum decls work.
For declarations like: enum struct Foo : long int; Change-Id: Id813efdbc31c8d70a4b40bb0101dc33a8dd2556a Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
14
src/libs/3rdparty/cplusplus/AST.cpp
vendored
14
src/libs/3rdparty/cplusplus/AST.cpp
vendored
@@ -1077,9 +1077,16 @@ unsigned EnumSpecifierAST::firstToken() const
|
|||||||
{
|
{
|
||||||
if (enum_token)
|
if (enum_token)
|
||||||
return enum_token;
|
return enum_token;
|
||||||
|
if (key_token)
|
||||||
|
return key_token;
|
||||||
if (name)
|
if (name)
|
||||||
if (unsigned candidate = name->firstToken())
|
if (unsigned candidate = name->firstToken())
|
||||||
return candidate;
|
return candidate;
|
||||||
|
if (colon_token)
|
||||||
|
return colon_token;
|
||||||
|
if (type_specifier_list)
|
||||||
|
if (unsigned candidate = type_specifier_list->firstToken())
|
||||||
|
return candidate;
|
||||||
if (lbrace_token)
|
if (lbrace_token)
|
||||||
return lbrace_token;
|
return lbrace_token;
|
||||||
if (enumerator_list)
|
if (enumerator_list)
|
||||||
@@ -1104,9 +1111,16 @@ unsigned EnumSpecifierAST::lastToken() const
|
|||||||
return candidate;
|
return candidate;
|
||||||
if (lbrace_token)
|
if (lbrace_token)
|
||||||
return lbrace_token + 1;
|
return lbrace_token + 1;
|
||||||
|
if (type_specifier_list)
|
||||||
|
if (unsigned candidate = type_specifier_list->lastToken())
|
||||||
|
return candidate;
|
||||||
|
if (colon_token)
|
||||||
|
return colon_token + 1;
|
||||||
if (name)
|
if (name)
|
||||||
if (unsigned candidate = name->lastToken())
|
if (unsigned candidate = name->lastToken())
|
||||||
return candidate;
|
return candidate;
|
||||||
|
if (key_token)
|
||||||
|
return key_token + 1;
|
||||||
if (enum_token)
|
if (enum_token)
|
||||||
return enum_token + 1;
|
return enum_token + 1;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
6
src/libs/3rdparty/cplusplus/AST.h
vendored
6
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -1634,7 +1634,10 @@ class CPLUSPLUS_EXPORT EnumSpecifierAST: public SpecifierAST
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned enum_token;
|
unsigned enum_token;
|
||||||
|
unsigned key_token; // struct, class or 0
|
||||||
NameAST *name;
|
NameAST *name;
|
||||||
|
unsigned colon_token; // can be 0 if there is no enum-base
|
||||||
|
SpecifierListAST *type_specifier_list; // ditto
|
||||||
unsigned lbrace_token;
|
unsigned lbrace_token;
|
||||||
EnumeratorListAST *enumerator_list;
|
EnumeratorListAST *enumerator_list;
|
||||||
unsigned stray_comma_token;
|
unsigned stray_comma_token;
|
||||||
@@ -1646,7 +1649,10 @@ public: // annotations
|
|||||||
public:
|
public:
|
||||||
EnumSpecifierAST()
|
EnumSpecifierAST()
|
||||||
: enum_token(0)
|
: enum_token(0)
|
||||||
|
, key_token(0)
|
||||||
, name(0)
|
, name(0)
|
||||||
|
, colon_token(0)
|
||||||
|
, type_specifier_list(0)
|
||||||
, lbrace_token(0)
|
, lbrace_token(0)
|
||||||
, enumerator_list(0)
|
, enumerator_list(0)
|
||||||
, stray_comma_token(0)
|
, stray_comma_token(0)
|
||||||
|
|||||||
5
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
5
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -558,8 +558,13 @@ EnumSpecifierAST *EnumSpecifierAST::clone(MemoryPool *pool) const
|
|||||||
{
|
{
|
||||||
EnumSpecifierAST *ast = new (pool) EnumSpecifierAST;
|
EnumSpecifierAST *ast = new (pool) EnumSpecifierAST;
|
||||||
ast->enum_token = enum_token;
|
ast->enum_token = enum_token;
|
||||||
|
ast->key_token = key_token;
|
||||||
if (name)
|
if (name)
|
||||||
ast->name = name->clone(pool);
|
ast->name = name->clone(pool);
|
||||||
|
ast->colon_token = colon_token;
|
||||||
|
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
|
||||||
|
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
||||||
|
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
|
||||||
ast->lbrace_token = lbrace_token;
|
ast->lbrace_token = lbrace_token;
|
||||||
for (EnumeratorListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list;
|
for (EnumeratorListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list;
|
||||||
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
||||||
|
|||||||
9
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
9
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -935,11 +935,20 @@ bool ASTMatcher::match(EnumSpecifierAST *node, EnumSpecifierAST *pattern)
|
|||||||
|
|
||||||
pattern->enum_token = node->enum_token;
|
pattern->enum_token = node->enum_token;
|
||||||
|
|
||||||
|
pattern->key_token = node->key_token;
|
||||||
|
|
||||||
if (! pattern->name)
|
if (! pattern->name)
|
||||||
pattern->name = node->name;
|
pattern->name = node->name;
|
||||||
else if (! AST::match(node->name, pattern->name, this))
|
else if (! AST::match(node->name, pattern->name, this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
pattern->colon_token = node->colon_token;
|
||||||
|
|
||||||
|
if (! pattern->type_specifier_list)
|
||||||
|
pattern->type_specifier_list = node->type_specifier_list;
|
||||||
|
else if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this))
|
||||||
|
return false;
|
||||||
|
|
||||||
pattern->lbrace_token = node->lbrace_token;
|
pattern->lbrace_token = node->lbrace_token;
|
||||||
|
|
||||||
if (! pattern->enumerator_list)
|
if (! pattern->enumerator_list)
|
||||||
|
|||||||
@@ -374,10 +374,11 @@ public:
|
|||||||
return __ast;
|
return __ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumSpecifierAST *EnumSpecifier(NameAST *name = 0, EnumeratorListAST *enumerator_list = 0)
|
EnumSpecifierAST *EnumSpecifier(NameAST *name = 0, SpecifierListAST *type_specifier_list = 0, EnumeratorListAST *enumerator_list = 0)
|
||||||
{
|
{
|
||||||
EnumSpecifierAST *__ast = new (&pool) EnumSpecifierAST;
|
EnumSpecifierAST *__ast = new (&pool) EnumSpecifierAST;
|
||||||
__ast->name = name;
|
__ast->name = name;
|
||||||
|
__ast->type_specifier_list = type_specifier_list;
|
||||||
__ast->enumerator_list = enumerator_list;
|
__ast->enumerator_list = enumerator_list;
|
||||||
return __ast;
|
return __ast;
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
1
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
@@ -410,6 +410,7 @@ void EnumSpecifierAST::accept0(ASTVisitor *visitor)
|
|||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
accept(name, visitor);
|
accept(name, visitor);
|
||||||
|
accept(type_specifier_list, visitor);
|
||||||
accept(enumerator_list, visitor);
|
accept(enumerator_list, visitor);
|
||||||
}
|
}
|
||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
|
|||||||
32
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
32
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -28,7 +28,7 @@
|
|||||||
#include "QtContextKeywords.h"
|
#include "QtContextKeywords.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdio> // for putchar
|
#include <cstdio> // for putchar
|
||||||
|
#include <QDebug>
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define va_copy(dst, src) ((dst) = (src))
|
# define va_copy(dst, src) ((dst) = (src))
|
||||||
#elif defined(__INTEL_COMPILER) && !defined(va_copy)
|
#elif defined(__INTEL_COMPILER) && !defined(va_copy)
|
||||||
@@ -1684,16 +1684,19 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
|
|||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
if (LA() == T_ENUM) {
|
if (LA() == T_ENUM) {
|
||||||
unsigned enum_token = consumeToken();
|
EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST;
|
||||||
if (_cxx0xEnabled && LA() == T_CLASS)
|
|
||||||
consumeToken();
|
|
||||||
|
|
||||||
NameAST *name = 0;
|
ast->enum_token = consumeToken();
|
||||||
parseName(name);
|
if (_cxx0xEnabled && (LA() == T_CLASS || LA() == T_STRUCT))
|
||||||
|
ast->key_token = consumeToken();
|
||||||
|
|
||||||
|
parseName(ast->name);
|
||||||
|
|
||||||
|
if (_cxx0xEnabled && LA() == T_COLON) {
|
||||||
|
ast->colon_token = consumeToken();
|
||||||
|
parseTypeSpecifier(ast->type_specifier_list);
|
||||||
|
}
|
||||||
if (LA() == T_LBRACE) {
|
if (LA() == T_LBRACE) {
|
||||||
EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST;
|
|
||||||
ast->enum_token = enum_token;
|
|
||||||
ast->name = name;
|
|
||||||
ast->lbrace_token = consumeToken();
|
ast->lbrace_token = consumeToken();
|
||||||
unsigned comma_token = 0;
|
unsigned comma_token = 0;
|
||||||
EnumeratorListAST **enumerator_ptr = &ast->enumerator_list;
|
EnumeratorListAST **enumerator_ptr = &ast->enumerator_list;
|
||||||
@@ -1717,9 +1720,12 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
|
|||||||
match(T_COMMA, &comma_token);
|
match(T_COMMA, &comma_token);
|
||||||
}
|
}
|
||||||
match(T_RBRACE, &ast->rbrace_token);
|
match(T_RBRACE, &ast->rbrace_token);
|
||||||
node = new (_pool) SpecifierListAST(ast);
|
} else if (!_cxx0xEnabled) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = new (_pool) SpecifierListAST(ast);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -3920,7 +3926,9 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
|
|||||||
}
|
}
|
||||||
} else if (! has_type_specifier && LA() == T_ENUM) {
|
} else if (! has_type_specifier && LA() == T_ENUM) {
|
||||||
unsigned startOfTypeSpecifier = cursor();
|
unsigned startOfTypeSpecifier = cursor();
|
||||||
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) || LA() == T_LBRACE) {
|
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)
|
||||||
|
|| LA() == T_LBRACE
|
||||||
|
|| (_cxx0xEnabled && LA() == T_COLON)) {
|
||||||
rewind(startOfTypeSpecifier);
|
rewind(startOfTypeSpecifier);
|
||||||
if (! parseEnumSpecifier(*decl_specifier_seq_ptr)) {
|
if (! parseEnumSpecifier(*decl_specifier_seq_ptr)) {
|
||||||
error(startOfTypeSpecifier,
|
error(startOfTypeSpecifier,
|
||||||
|
|||||||
11
tests/auto/cplusplus/cxx11/data/enums.1.cpp
Normal file
11
tests/auto/cplusplus/cxx11/data/enums.1.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
enum { A, B };
|
||||||
|
enum : int;
|
||||||
|
enum : int { A, B };
|
||||||
|
enum Foo1 { A, B };
|
||||||
|
enum Foo2 : int;
|
||||||
|
enum Foo3 : int { A, B };
|
||||||
|
enum class Foo4 : int;
|
||||||
|
enum struct Foo5;
|
||||||
|
enum class Foo6 { A, B };
|
||||||
|
enum struct Foo7 { A, B };
|
||||||
|
enum struct Foo8 : long long;
|
||||||
@@ -143,6 +143,7 @@ void tst_cxx11::parse_data()
|
|||||||
QTest::newRow("alignofAlignas.1") << "alignofAlignas.1.cpp" << "";
|
QTest::newRow("alignofAlignas.1") << "alignofAlignas.1.cpp" << "";
|
||||||
QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << "";
|
QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << "";
|
||||||
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
|
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
|
||||||
|
QTest::newRow("enums.1") << "enums.1.cpp" << "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_cxx11::parse()
|
void tst_cxx11::parse()
|
||||||
|
|||||||
@@ -548,7 +548,13 @@ virtual bool visit(EnumSpecifierAST *ast)
|
|||||||
{
|
{
|
||||||
if (ast->enum_token)
|
if (ast->enum_token)
|
||||||
terminal(ast->enum_token, ast);
|
terminal(ast->enum_token, ast);
|
||||||
|
if (ast->key_token)
|
||||||
|
terminal(ast->key_token, ast);
|
||||||
nonterminal(ast->name);
|
nonterminal(ast->name);
|
||||||
|
if (ast->colon_token)
|
||||||
|
terminal(ast->colon_token, ast);
|
||||||
|
for (SpecifierListAST *iter = ast->type_specifier_list; iter; iter = iter->next)
|
||||||
|
nonterminal(iter->value);
|
||||||
if (ast->lbrace_token)
|
if (ast->lbrace_token)
|
||||||
terminal(ast->lbrace_token, ast);
|
terminal(ast->lbrace_token, ast);
|
||||||
for (EnumeratorListAST *iter = ast->enumerator_list; iter; iter = iter->next)
|
for (EnumeratorListAST *iter = ast->enumerator_list; iter; iter = iter->next)
|
||||||
|
|||||||
Reference in New Issue
Block a user