Commit 1d3dc301 authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

C++11: add support for static_assert.



Change-Id: I82d8d60acaa9265fd25e0a3734855b19bdef9c06
Reviewed-by: default avatarRoberto Raggi <roberto.raggi@nokia.com>
parent 3afd3a37
......@@ -4269,3 +4269,47 @@ unsigned NoExceptSpecificationAST::lastToken() const
return 1;
}
/** \generated */
unsigned StaticAssertDeclarationAST::firstToken() const
{
if (static_assert_token)
return static_assert_token;
if (lparen_token)
return lparen_token;
if (expression)
if (unsigned candidate = expression->firstToken())
return candidate;
if (comma_token)
return comma_token;
if (string_literal)
if (unsigned candidate = string_literal->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (semicolon_token)
return semicolon_token;
return 0;
}
/** \generated */
unsigned StaticAssertDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (rparen_token)
return rparen_token + 1;
if (string_literal)
if (unsigned candidate = string_literal->lastToken())
return candidate;
if (comma_token)
return comma_token + 1;
if (expression)
if (unsigned candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (static_assert_token)
return static_assert_token + 1;
return 1;
}
......@@ -254,6 +254,7 @@ public:
virtual SizeofExpressionAST *asSizeofExpression() { return 0; }
virtual SpecifierAST *asSpecifier() { return 0; }
virtual StatementAST *asStatement() { return 0; }
virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return 0; }
virtual StringLiteralAST *asStringLiteral() { return 0; }
virtual SwitchStatementAST *asSwitchStatement() { return 0; }
virtual TemplateDeclarationAST *asTemplateDeclaration() { return 0; }
......@@ -3062,6 +3063,40 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT StaticAssertDeclarationAST: public DeclarationAST
{
public:
unsigned static_assert_token;
unsigned lparen_token;
ExpressionAST *expression;
unsigned comma_token;
ExpressionAST *string_literal;
unsigned rparen_token;
unsigned semicolon_token;
public:
StaticAssertDeclarationAST()
: static_assert_token(0)
, lparen_token(0)
, expression(0)
, comma_token(0)
, string_literal(0)
, rparen_token(0)
, semicolon_token(0)
{}
virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual StaticAssertDeclarationAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT StringLiteralAST: public ExpressionAST
{
public:
......
......@@ -1142,6 +1142,21 @@ NestedExpressionAST *NestedExpressionAST::clone(MemoryPool *pool) const
return ast;
}
StaticAssertDeclarationAST *StaticAssertDeclarationAST::clone(MemoryPool *pool) const
{
StaticAssertDeclarationAST *ast = new (pool) StaticAssertDeclarationAST;
ast->static_assert_token = static_assert_token;
ast->lparen_token = lparen_token;
if (expression)
ast->expression = expression->clone(pool);
ast->comma_token = comma_token;
if (string_literal)
ast->string_literal = string_literal->clone(pool);
ast->rparen_token = rparen_token;
ast->semicolon_token = semicolon_token;
return ast;
}
StringLiteralAST *StringLiteralAST::clone(MemoryPool *pool) const
{
StringLiteralAST *ast = new (pool) StringLiteralAST;
......
......@@ -800,6 +800,14 @@ bool NestedExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool StaticAssertDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (StaticAssertDeclarationAST *_other = pattern->asStaticAssertDeclaration())
return matcher->match(this, _other);
return false;
}
bool StringLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (StringLiteralAST *_other = pattern->asStringLiteral())
......
......@@ -1917,6 +1917,34 @@ bool ASTMatcher::match(NestedExpressionAST *node, NestedExpressionAST *pattern)
return true;
}
bool ASTMatcher::match(StaticAssertDeclarationAST *node, StaticAssertDeclarationAST *pattern)
{
(void) node;
(void) pattern;
pattern->static_assert_token = node->static_assert_token;
pattern->lparen_token = node->lparen_token;
if (! pattern->expression)
pattern->expression = node->expression;
else if (! AST::match(node->expression, pattern->expression, this))
return false;
pattern->comma_token = node->comma_token;
if (! pattern->string_literal)
pattern->string_literal = node->string_literal;
else if (! AST::match(node->string_literal, pattern->string_literal, this))
return false;
pattern->rparen_token = node->rparen_token;
pattern->semicolon_token = node->semicolon_token;
return true;
}
bool ASTMatcher::match(StringLiteralAST *node, StringLiteralAST *pattern)
{
(void) node;
......
......@@ -151,6 +151,7 @@ public:
virtual bool match(SimpleNameAST *node, SimpleNameAST *pattern);
virtual bool match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern);
virtual bool match(SizeofExpressionAST *node, SizeofExpressionAST *pattern);
virtual bool match(StaticAssertDeclarationAST *node, StaticAssertDeclarationAST *pattern);
virtual bool match(StringLiteralAST *node, StringLiteralAST *pattern);
virtual bool match(SwitchStatementAST *node, SwitchStatementAST *pattern);
virtual bool match(TemplateDeclarationAST *node, TemplateDeclarationAST *pattern);
......
......@@ -759,6 +759,14 @@ public:
return __ast;
}
StaticAssertDeclarationAST *StaticAssertDeclaration(ExpressionAST *expression = 0, ExpressionAST *string_literal = 0)
{
StaticAssertDeclarationAST *__ast = new (&pool) StaticAssertDeclarationAST;
__ast->expression = expression;
__ast->string_literal = string_literal;
return __ast;
}
StringLiteralAST *StringLiteral(StringLiteralAST *next = 0)
{
StringLiteralAST *__ast = new (&pool) StringLiteralAST;
......
......@@ -843,6 +843,15 @@ void NestedExpressionAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void StaticAssertDeclarationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
accept(string_literal, visitor);
}
visitor->endVisit(this);
}
void StringLiteralAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
......
......@@ -193,6 +193,7 @@ public:
virtual bool visit(SimpleNameAST *) { return true; }
virtual bool visit(SimpleSpecifierAST *) { return true; }
virtual bool visit(SizeofExpressionAST *) { return true; }
virtual bool visit(StaticAssertDeclarationAST *) { return true; }
virtual bool visit(StringLiteralAST *) { return true; }
virtual bool visit(SwitchStatementAST *) { return true; }
virtual bool visit(TemplateDeclarationAST *) { return true; }
......@@ -334,6 +335,7 @@ public:
virtual void endVisit(SimpleNameAST *) {}
virtual void endVisit(SimpleSpecifierAST *) {}
virtual void endVisit(SizeofExpressionAST *) {}
virtual void endVisit(StaticAssertDeclarationAST *) {}
virtual void endVisit(StringLiteralAST *) {}
virtual void endVisit(SwitchStatementAST *) {}
virtual void endVisit(TemplateDeclarationAST *) {}
......
......@@ -161,6 +161,7 @@ class SimpleSpecifierAST;
class SizeofExpressionAST;
class SpecifierAST;
class StatementAST;
class StaticAssertDeclarationAST;
class StringLiteralAST;
class SwitchStatementAST;
class TemplateDeclarationAST;
......
......@@ -1360,7 +1360,7 @@ static inline int classify12(const char *s, bool q, bool) {
return T_IDENTIFIER;
}
static inline int classify13(const char *s, bool, bool) {
static inline int classify13(const char *s, bool, bool x) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'a') {
......@@ -1387,6 +1387,32 @@ static inline int classify13(const char *s, bool, bool) {
}
}
}
} else if (x && s[0] == 's') {
if (s[1] == 't') {
if (s[2] == 'a') {
if (s[3] == 't') {
if (s[4] == 'i') {
if (s[5] == 'c') {
if (s[6] == '_') {
if (s[7] == 'a') {
if (s[8] == 's') {
if (s[9] == 's') {
if (s[10] == 'e') {
if (s[11] == 'r') {
if (s[12] == 't') {
return T_STATIC_ASSERT;
}
}
}
}
}
}
}
}
}
}
}
}
}
return T_IDENTIFIER;
}
......
......@@ -269,6 +269,8 @@ void Parser::skipUntilDeclaration()
// declarations
case T_ENUM:
case T_NAMESPACE:
case T_INLINE:
case T_STATIC_ASSERT:
case T_ASM:
case T_EXPORT:
case T_AT_CLASS:
......@@ -621,6 +623,7 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
consumeToken();
break;
// C++11
case T_INLINE:
if (_cxx0xEnabled && LA(2) == T_NAMESPACE)
return parseNamespace(node);
......@@ -707,6 +710,25 @@ bool Parser::parseLinkageBody(DeclarationAST *&node)
return false;
}
bool Parser::parseStaticAssertDeclaration(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_STATIC_ASSERT)
return false;
StaticAssertDeclarationAST *ast = new (_pool) StaticAssertDeclarationAST;
ast->static_assert_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
parseConstantExpression(ast->expression);
match(T_COMMA, &ast->comma_token);
parseStringLiteral(ast->string_literal);
match(T_RPAREN, &ast->rparen_token);
match(T_SEMICOLON, &ast->semicolon_token);
node = ast;
return true;
}
// ### rename parseNamespaceAliarOrDeclaration?
bool Parser::parseNamespace(DeclarationAST *&node)
{
......@@ -2259,6 +2281,10 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node, ClassSpecifierAST *
case T_Q_INTERFACES:
return parseQtInterfaces(node);
// C++11
case T_STATIC_ASSERT:
return parseStaticAssertDeclaration(node);
default:
return parseSimpleDeclaration(node, declaringClass);
} // switch
......
......@@ -125,6 +125,7 @@ public:
bool parseName(NameAST *&node, bool acceptTemplateId = true);
bool parseNestedNameSpecifier(NestedNameSpecifierListAST *&node, bool acceptTemplateId);
bool parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId);
bool parseStaticAssertDeclaration(DeclarationAST *&node);
bool parseNamespace(DeclarationAST *&node);
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node);
......
......@@ -48,7 +48,7 @@ static const char *token_names[] = {
("mutable"), ("namespace"), ("new"), ("noexcept"),
("nullptr"), ("operator"), ("private"),
("protected"), ("public"), ("register"), ("reinterpret_cast"),
("return"), ("short"), ("signed"), ("sizeof"), ("static"),
("return"), ("short"), ("signed"), ("sizeof"), ("static"),("static_assert"),
("static_cast"), ("struct"), ("switch"), ("template"), ("this"),
("throw"), ("true"), ("try"), ("typedef"), ("typeid"), ("typename"),
("union"), ("unsigned"), ("using"), ("virtual"), ("void"),
......
......@@ -148,6 +148,7 @@ enum Kind {
T_SIGNED,
T_SIZEOF,
T_STATIC,
T_STATIC_ASSERT,
T_STATIC_CAST,
T_STRUCT,
T_SWITCH,
......
......@@ -1674,6 +1674,12 @@ bool FindUsages::visit(ParameterDeclarationAST *ast)
return false;
}
bool FindUsages::visit(StaticAssertDeclarationAST *ast)
{
this->expression(ast->expression);
return false;
}
bool FindUsages::visit(TemplateDeclarationAST *ast)
{
// unsigned export_token = ast->export_token;
......
......@@ -236,6 +236,7 @@ protected:
virtual bool visit(NamespaceAST *ast);
virtual bool visit(NamespaceAliasDefinitionAST *ast);
virtual bool visit(ParameterDeclarationAST *ast);
virtual bool visit(StaticAssertDeclarationAST *ast);
virtual bool visit(TemplateDeclarationAST *ast);
virtual bool visit(TypenameTypeParameterAST *ast);
virtual bool visit(TemplateTypeParameterAST *ast);
......
......@@ -145,6 +145,7 @@ void parse(const char *fileName, const char *source, unsigned size)
Control control;
TranslationUnit unit(&control, control.stringLiteral(fileName));
unit.setSource(source, size);
unit.setCxxOxEnabled(true);
unit.parse();
#if 1
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment