aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kamm <kamm@incasoftware.de>2012-09-18 11:17:29 +0200
committerhjk <qthjk@ovi.com>2012-09-19 11:57:23 +0200
commit44c9cef30a022125e8ebc70b7b58c5ad25fafcd6 (patch)
tree82b2bbb9d9ab7e01ceafae47b4924331e27cd626
parent871112119714c422655f3429d1f190cf6502a97e (diff)
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>
-rw-r--r--src/libs/3rdparty/cplusplus/AST.cpp14
-rw-r--r--src/libs/3rdparty/cplusplus/AST.h6
-rw-r--r--src/libs/3rdparty/cplusplus/ASTClone.cpp5
-rw-r--r--src/libs/3rdparty/cplusplus/ASTMatcher.cpp9
-rw-r--r--src/libs/3rdparty/cplusplus/ASTPatternBuilder.h3
-rw-r--r--src/libs/3rdparty/cplusplus/ASTVisit.cpp1
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.cpp32
-rw-r--r--tests/auto/cplusplus/cxx11/data/enums.1.cpp11
-rw-r--r--tests/auto/cplusplus/cxx11/tst_cxx11.cpp1
-rw-r--r--tests/tools/cplusplus-dump/dumpers.inc6
10 files changed, 75 insertions, 13 deletions
diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp
index 14d7fc48b07..89d5a1a84aa 100644
--- a/src/libs/3rdparty/cplusplus/AST.cpp
+++ b/src/libs/3rdparty/cplusplus/AST.cpp
@@ -1077,9 +1077,16 @@ unsigned EnumSpecifierAST::firstToken() const
{
if (enum_token)
return enum_token;
+ if (key_token)
+ return key_token;
if (name)
if (unsigned candidate = name->firstToken())
return candidate;
+ if (colon_token)
+ return colon_token;
+ if (type_specifier_list)
+ if (unsigned candidate = type_specifier_list->firstToken())
+ return candidate;
if (lbrace_token)
return lbrace_token;
if (enumerator_list)
@@ -1104,9 +1111,16 @@ unsigned EnumSpecifierAST::lastToken() const
return candidate;
if (lbrace_token)
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 (unsigned candidate = name->lastToken())
return candidate;
+ if (key_token)
+ return key_token + 1;
if (enum_token)
return enum_token + 1;
return 1;
diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h
index f6718e19144..6dc218dd317 100644
--- a/src/libs/3rdparty/cplusplus/AST.h
+++ b/src/libs/3rdparty/cplusplus/AST.h
@@ -1634,7 +1634,10 @@ class CPLUSPLUS_EXPORT EnumSpecifierAST: public SpecifierAST
{
public:
unsigned enum_token;
+ unsigned key_token; // struct, class or 0
NameAST *name;
+ unsigned colon_token; // can be 0 if there is no enum-base
+ SpecifierListAST *type_specifier_list; // ditto
unsigned lbrace_token;
EnumeratorListAST *enumerator_list;
unsigned stray_comma_token;
@@ -1646,7 +1649,10 @@ public: // annotations
public:
EnumSpecifierAST()
: enum_token(0)
+ , key_token(0)
, name(0)
+ , colon_token(0)
+ , type_specifier_list(0)
, lbrace_token(0)
, enumerator_list(0)
, stray_comma_token(0)
diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp
index 64b1c1bc81e..a2a3ef3759e 100644
--- a/src/libs/3rdparty/cplusplus/ASTClone.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp
@@ -558,8 +558,13 @@ EnumSpecifierAST *EnumSpecifierAST::clone(MemoryPool *pool) const
{
EnumSpecifierAST *ast = new (pool) EnumSpecifierAST;
ast->enum_token = enum_token;
+ ast->key_token = key_token;
if (name)
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;
for (EnumeratorListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
index 061c75814d2..e4e899c7e51 100644
--- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
@@ -935,11 +935,20 @@ bool ASTMatcher::match(EnumSpecifierAST *node, EnumSpecifierAST *pattern)
pattern->enum_token = node->enum_token;
+ pattern->key_token = node->key_token;
+
if (! pattern->name)
pattern->name = node->name;
else if (! AST::match(node->name, pattern->name, this))
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;
if (! pattern->enumerator_list)
diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
index 004f5d80b5c..ec21afabe7e 100644
--- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
+++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
@@ -374,10 +374,11 @@ public:
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;
__ast->name = name;
+ __ast->type_specifier_list = type_specifier_list;
__ast->enumerator_list = enumerator_list;
return __ast;
}
diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp
index e59a0385ae4..5e5cbefe711 100644
--- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp
@@ -410,6 +410,7 @@ void EnumSpecifierAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(name, visitor);
+ accept(type_specifier_list, visitor);
accept(enumerator_list, visitor);
}
visitor->endVisit(this);
diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp
index 7769b0cc094..64723254700 100644
--- a/src/libs/3rdparty/cplusplus/Parser.cpp
+++ b/src/libs/3rdparty/cplusplus/Parser.cpp
@@ -28,7 +28,7 @@
#include "QtContextKeywords.h"
#include <string>
#include <cstdio> // for putchar
-
+#include <QDebug>
#ifdef _MSC_VER
# define va_copy(dst, src) ((dst) = (src))
#elif defined(__INTEL_COMPILER) && !defined(va_copy)
@@ -1684,16 +1684,19 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_ENUM) {
- unsigned enum_token = consumeToken();
- if (_cxx0xEnabled && LA() == T_CLASS)
- consumeToken();
+ EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST;
- NameAST *name = 0;
- parseName(name);
+ ast->enum_token = consumeToken();
+ 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) {
- EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST;
- ast->enum_token = enum_token;
- ast->name = name;
ast->lbrace_token = consumeToken();
unsigned comma_token = 0;
EnumeratorListAST **enumerator_ptr = &ast->enumerator_list;
@@ -1717,9 +1720,12 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
match(T_COMMA, &comma_token);
}
match(T_RBRACE, &ast->rbrace_token);
- node = new (_pool) SpecifierListAST(ast);
- return true;
+ } else if (!_cxx0xEnabled) {
+ return false;
}
+
+ node = new (_pool) SpecifierListAST(ast);
+ return true;
}
return false;
}
@@ -3920,7 +3926,9 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
}
} else if (! has_type_specifier && LA() == T_ENUM) {
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);
if (! parseEnumSpecifier(*decl_specifier_seq_ptr)) {
error(startOfTypeSpecifier,
diff --git a/tests/auto/cplusplus/cxx11/data/enums.1.cpp b/tests/auto/cplusplus/cxx11/data/enums.1.cpp
new file mode 100644
index 00000000000..c8cd725ad07
--- /dev/null
+++ b/tests/auto/cplusplus/cxx11/data/enums.1.cpp
@@ -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;
diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
index aeb992aec27..8ccc5567586 100644
--- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
+++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
@@ -143,6 +143,7 @@ void tst_cxx11::parse_data()
QTest::newRow("alignofAlignas.1") << "alignofAlignas.1.cpp" << "";
QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << "";
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
+ QTest::newRow("enums.1") << "enums.1.cpp" << "";
}
void tst_cxx11::parse()
diff --git a/tests/tools/cplusplus-dump/dumpers.inc b/tests/tools/cplusplus-dump/dumpers.inc
index 6585ffa7e88..015e2a39bef 100644
--- a/tests/tools/cplusplus-dump/dumpers.inc
+++ b/tests/tools/cplusplus-dump/dumpers.inc
@@ -548,7 +548,13 @@ virtual bool visit(EnumSpecifierAST *ast)
{
if (ast->enum_token)
terminal(ast->enum_token, ast);
+ if (ast->key_token)
+ terminal(ast->key_token, ast);
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)
terminal(ast->lbrace_token, ast);
for (EnumeratorListAST *iter = ast->enumerator_list; iter; iter = iter->next)