Skip to content

Commit

Permalink
Add constexpr and decltype parsing (#125)
Browse files Browse the repository at this point in the history
- parses constexpr (in the manner of const) and decltype (in the manner of __typeof) 
  and adds flags for them
  • Loading branch information
jbowler authored and mrbean-bremen committed Nov 2, 2023
1 parent 2779d8a commit 42d5084
Show file tree
Hide file tree
Showing 17 changed files with 134 additions and 50 deletions.
1 change: 1 addition & 0 deletions .vimrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set expandtab
2 changes: 1 addition & 1 deletion generator/abstractmetabuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class AbstractMetaBuilder
bool isEnum(const QStringList &qualified_name);

void fixQObjectForScope (TypeDatabase *types,
NamespaceModelItem item);
NamespaceModelItem item);

// QtScript
QSet<QString> qtMetaTypeDeclaredTypeNames() const
Expand Down
18 changes: 18 additions & 0 deletions generator/parser/codemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ TypeInfo TypeInfo::combine (const TypeInfo &__lhs, const TypeInfo &__rhs)
TypeInfo __result = __lhs;

__result.setConstant (__result.isConstant () || __rhs.isConstant ());
__result.setConstexpr (__result.isConstexpr () || __rhs.isConstexpr ());
__result.setVolatile (__result.isVolatile () || __rhs.isVolatile ());
__result.setMutable (__result.isMutable () || __rhs.isMutable ());
__result.setReference (__result.isReference () || __rhs.isReference ());
__result.setRvalueReference (__result.isRvalueReference () || __rhs.isRvalueReference ());
__result.setIndirections (__result.indirections () + __rhs.indirections ());
Expand Down Expand Up @@ -182,9 +184,15 @@ QString TypeInfo::toString() const
if (isConstant())
tmp += QLatin1String(" const");

if (isConstexpr())
tmp += QLatin1String(" constexpr");

if (isVolatile())
tmp += QLatin1String(" volatile");

if (isMutable())
tmp += QLatin1String(" mutable");

if (indirections())
tmp += QString(indirections(), QLatin1Char('*'));

Expand Down Expand Up @@ -917,6 +925,16 @@ void _MemberModelItem::setConstant(bool isConstant)
_M_isConstant = isConstant;
}

bool _MemberModelItem::isConstexpr() const
{
return _M_isConstexpr;
}

void _MemberModelItem::setConstexpr(bool isConstexpr)
{
_M_isConstexpr = isConstexpr;
}

bool _MemberModelItem::isVolatile() const
{
return _M_isVolatile;
Expand Down
31 changes: 23 additions & 8 deletions generator/parser/codemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,15 @@ struct TypeInfo
bool isConstant() const { return m_flags.m_constant; }
void setConstant(bool is) { m_flags.m_constant = is; }

bool isConstexpr() const { return m_flags.m_constexpr; }
void setConstexpr(bool is) { m_flags.m_constexpr = is; }

bool isVolatile() const { return m_flags.m_volatile; }
void setVolatile(bool is) { m_flags.m_volatile = is; }

bool isMutable() const { return m_flags.m_mutable; }
void setMutable(bool is) { m_flags.m_mutable = is; }

bool isReference() const { return m_flags.m_reference; }
void setReference(bool is) { m_flags.m_reference = is; }

Expand Down Expand Up @@ -166,19 +172,24 @@ struct TypeInfo

private:
struct TypeInfo_flags {
uint m_constant: 1;
uint m_volatile: 1;
uint m_reference: 1;
uint m_functionPointer: 1;
uint m_indirections: 6;
inline bool equals(TypeInfo_flags other) const {
uint m_constant: 1;
uint m_constexpr: 1;
uint m_volatile: 1;
uint m_mutable: 1;
uint m_reference: 1;
uint m_functionPointer: 1;
uint m_indirections: 6;
inline bool equals(TypeInfo_flags other) const {
/* m_auto and m_friend don't matter here */
return m_constant == other.m_constant
&& m_constexpr == other.m_constexpr
&& m_volatile == other.m_volatile
&& m_mutable == other.m_mutable
&& m_reference == other.m_reference
&& m_functionPointer == other.m_functionPointer
&& m_indirections == other.m_indirections;
}
} m_flags {0, 0, 0, 0, 0};
}
} m_flags {0, 0, 0, 0, 0, 0, 0};

QStringList m_qualifiedName;
QStringList m_arrayElements;
Expand Down Expand Up @@ -455,6 +466,9 @@ class _MemberModelItem: public _CodeModelItem
bool isConstant() const;
void setConstant(bool isConstant);

bool isConstexpr() const;
void setConstexpr(bool isConstexpr);

bool isVolatile() const;
void setVolatile(bool isVolatile);

Expand Down Expand Up @@ -504,6 +518,7 @@ class _MemberModelItem: public _CodeModelItem
struct
{
uint _M_isConstant: 1;
uint _M_isConstexpr: 1;
uint _M_isVolatile: 1;
uint _M_isStatic: 1;
uint _M_isAuto: 1;
Expand Down
2 changes: 2 additions & 0 deletions generator/parser/compiler_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ TypeInfo CompilerUtils::typeDescription(TypeSpecifierAST *type_specifier, Declar
TypeInfo typeInfo;
typeInfo.setQualifiedName (type_cc.qualifiedName ());
typeInfo.setConstant (type_cc.isConstant ());
typeInfo.setConstexpr (type_cc.isConstexpr ());
typeInfo.setVolatile (type_cc.isVolatile ());
typeInfo.setMutable (type_cc.isMutable ());
typeInfo.setReference (decl_cc.isReference ());
typeInfo.setRvalueReference (decl_cc.isRvalueReference ());
typeInfo.setIndirections (decl_cc.indirection ());
Expand Down
29 changes: 29 additions & 0 deletions generator/parser/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,20 @@ void Lexer::scanKeyword8()
}
break;

case 'd':
if (*(cursor + 1) == 'e' &&
*(cursor + 2) == 'c' &&
*(cursor + 3) == 'l' &&
*(cursor + 4) == 't' &&
*(cursor + 5) == 'y' &&
*(cursor + 6) == 'p' &&
*(cursor + 7) == 'e')
{
token_stream[(int) index++].kind = Token_decltype;
return;
}
break;

case 'e':
if (*(cursor + 1) == 'x' &&
*(cursor + 2) == 'p' &&
Expand Down Expand Up @@ -1680,6 +1694,21 @@ void Lexer::scanKeyword9()
{
switch (*cursor)
{
case 'c':
if (*(cursor + 1) == 'o' &&
*(cursor + 2) == 'n' &&
*(cursor + 3) == 's' &&
*(cursor + 4) == 't' &&
*(cursor + 5) == 'e' &&
*(cursor + 6) == 'x' &&
*(cursor + 7) == 'p' &&
*(cursor + 8) == 'r')
{
token_stream[(int) index++].kind = Token_constexpr;
return;
}
break;

case 'p':
if (*(cursor + 1) == 'r' &&
*(cursor + 2) == 'o' &&
Expand Down
2 changes: 1 addition & 1 deletion generator/parser/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ struct ListNode

template <class Tp>
inline const ListNode<Tp> *snoc(const ListNode<Tp> *list,
const Tp &element, pool *p)
const Tp &element, pool *p)
{
if (!list)
return ListNode<Tp>::create(element, p);
Expand Down
6 changes: 6 additions & 0 deletions generator/parser/name_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ void NameCompiler::visitTemplateArgument(TemplateArgumentAST *node)
if (type_cc.isConstant())
_M_name.last() += "const ";

/* An id can't be 'constexpr' but it may have a function type in which
* case constexpr could appear.
*/
if (type_cc.isConstexpr())
_M_name.last() += "constexpr ";

QStringList q = type_cc.qualifiedName ();

if (q.count () == 1)
Expand Down
22 changes: 18 additions & 4 deletions generator/parser/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,9 @@ bool Parser::skipUntilDeclaration()
case Token_export:

case Token_const: // cv
case Token_constexpr: // cv
case Token_volatile: // cv
case Token_mutable: // cv

case Token_public:
case Token_protected:
Expand All @@ -258,6 +260,11 @@ bool Parser::skipUntilDeclaration()
case Token_slots: // Qt
return true;

case Token_decltype:
case Token___typeof:
reportError("C++11 decltype/__typeof(id|expression) not handled");
return true;

default:
token_stream.nextToken();
}
Expand All @@ -276,7 +283,11 @@ bool Parser::skipUntilStatement()
case '{':
case '}':
case Token_const:
case Token_constexpr:
case Token_decltype:
case Token___typeof:
case Token_volatile:
case Token_mutable:
case Token_identifier:
case Token_case:
case Token_default:
Expand Down Expand Up @@ -984,7 +995,8 @@ bool Parser::parseCvQualify(const ListNode<std::size_t> *&node)

int tk;
while (0 != (tk = token_stream.lookAhead())
&& (tk == Token_const || tk == Token_volatile))
&& (tk == Token_const || tk == Token_constexpr ||
tk == Token_volatile || tk == Token_mutable))
{
node = snoc(node, token_stream.cursor(), _M_pool);
token_stream.nextToken();
Expand Down Expand Up @@ -1032,7 +1044,8 @@ bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
{
ast->integrals = integrals;
}
else if (token_stream.lookAhead() == Token___typeof)
else if (token_stream.lookAhead() == Token___typeof ||
token_stream.lookAhead() == Token_decltype)
{
ast->type_of = token_stream.cursor();
token_stream.nextToken();
Expand Down Expand Up @@ -1627,7 +1640,7 @@ bool Parser::parseStorageClassSpecifier(const ListNode<std::size_t> *&node)
while (0 != (tk = token_stream.lookAhead())
&& (tk == Token_friend || tk == Token_auto
|| tk == Token_register || tk == Token_static
|| tk == Token_extern || tk == Token_mutable))
|| tk == Token_extern))
{
node = snoc(node, token_stream.cursor(), _M_pool);
token_stream.nextToken();
Expand Down Expand Up @@ -3262,7 +3275,8 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node)
start_decl:
token_stream.rewind((int) index);

if (token_stream.lookAhead() == Token_const
if ((token_stream.lookAhead() == Token_const ||
token_stream.lookAhead() == Token_constexpr)
&& token_stream.lookAhead(1) == Token_identifier
&& token_stream.lookAhead(2) == '=')
{
Expand Down
18 changes: 9 additions & 9 deletions generator/parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ class Parser
bool parseEnumSpecifier(TypeSpecifierAST *&node);
bool parseEnumerator(EnumeratorAST *&node);
bool parseEqualityExpression(ExpressionAST *&node,
bool templArgs = false);
bool templArgs = false);
bool parseExceptionSpecification(ExceptionSpecificationAST *&node);
bool parseExclusiveOrExpression(ExpressionAST *&node,
bool templArgs = false);
bool templArgs = false);
bool parseExpression(ExpressionAST *&node);
bool parseExpressionOrDeclarationStatement(StatementAST *&node);
bool parseExpressionStatement(StatementAST *&node);
Expand All @@ -113,7 +113,7 @@ class Parser
bool parseFunctionSpecifier(const ListNode<std::size_t> *&node);
bool parseIfStatement(StatementAST *&node);
bool parseInclusiveOrExpression(ExpressionAST *&node,
bool templArgs = false);
bool templArgs = false);
bool parseInitDeclarator(InitDeclaratorAST *&node);
bool parseInitDeclaratorList(const ListNode<InitDeclaratorAST*> *&node);
bool parseInitializer(InitializerAST *&node);
Expand All @@ -122,9 +122,9 @@ class Parser
bool parseLinkageBody(LinkageBodyAST *&node);
bool parseLinkageSpecification(DeclarationAST *&node);
bool parseLogicalAndExpression(ExpressionAST *&node,
bool templArgs = false);
bool templArgs = false);
bool parseLogicalOrExpression(ExpressionAST *&node,
bool templArgs = false);
bool templArgs = false);
bool parseMemInitializer(MemInitializerAST *&node);
bool parseMemInitializerList(const ListNode<MemInitializerAST*> *&node);
bool parseMemberSpecification(DeclarationAST *&node);
Expand All @@ -148,17 +148,17 @@ class Parser
bool parsePtrOperator(PtrOperatorAST *&node);
bool parsePtrToMember(PtrToMemberAST *&node);
bool parseRelationalExpression(ExpressionAST *&node,
bool templArgs = false);
bool templArgs = false);
bool parseShiftExpression(ExpressionAST *&node);
bool parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
bool onlyIntegral = false);
bool onlyIntegral = false);
bool parseStatement(StatementAST *&node);
bool parseStorageClassSpecifier(const ListNode<std::size_t> *&node);
bool parseStringLiteral(StringLiteralAST *&node);
bool parseSwitchStatement(StatementAST *&node);
bool parseTemplateArgument(TemplateArgumentAST *&node);
bool parseTemplateArgumentList(const ListNode<TemplateArgumentAST*> *&node,
bool reportError = true);
bool reportError = true);
bool parseTemplateDeclaration(DeclarationAST *&node);
bool parseTemplateParameter(TemplateParameterAST *&node);
bool parseTemplateParameterList(const ListNode<TemplateParameterAST*> *&node);
Expand All @@ -173,7 +173,7 @@ class Parser
bool parseTypedef(DeclarationAST *&node);
bool parseUnaryExpression(ExpressionAST *&node);
bool parseUnqualifiedName(UnqualifiedNameAST *&node,
bool parseTemplateId = true);
bool parseTemplateId = true);
bool parseUsing(DeclarationAST *&node);
bool parseUsingTypedef(DeclarationAST*& node);
bool parseUsingDirective(DeclarationAST *&node);
Expand Down
16 changes: 8 additions & 8 deletions generator/parser/rxx_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,20 @@ template <class _Tp> class rxx_allocator {
const size_type bytes = __n * sizeof(_Tp);

if (_M_current_block == 0
|| _S_block_size < _M_current_index + bytes)
|| _S_block_size < _M_current_index + bytes)
{
++_M_block_index;
++_M_block_index;

_M_storage = reinterpret_cast<char**>
(::realloc(_M_storage, sizeof(char*) * (1 + _M_block_index)));
_M_storage = reinterpret_cast<char**>
(::realloc(_M_storage, sizeof(char*) * (1 + _M_block_index)));

_M_current_block = _M_storage[_M_block_index] = reinterpret_cast<char*>
(new char[_S_block_size]);
_M_current_block = _M_storage[_M_block_index] = reinterpret_cast<char*>
(new char[_S_block_size]);

#if defined(RXX_ALLOCATOR_INIT_0) // ### make it a policy
::memset(_M_current_block, 0, _S_block_size);
::memset(_M_current_block, 0, _S_block_size);
#endif
_M_current_index = 0;
_M_current_index = 0;
}

pointer p = reinterpret_cast<pointer>
Expand Down
4 changes: 2 additions & 2 deletions generator/parser/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ class NameTable
NameSymbol *name = _M_storage.value(key);
if (!name)
{
name = new NameSymbol(str, len);
_M_storage.insert(key, name);
name = new NameSymbol(str, len);
_M_storage.insert(key, name);
}

return name;
Expand Down
2 changes: 2 additions & 0 deletions generator/parser/tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ static char const * const _S_token_names[] = {
"compl",
"concat",
"const",
"constexpr",
"const_cast",
"continue",
"decltype",
"decr",
"default",
"delete",
Expand Down
2 changes: 2 additions & 0 deletions generator/parser/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ enum TOKEN_KIND
Token_compl,
Token_concat,
Token_const,
Token_constexpr,
Token_const_cast,
Token_continue,
Token_decltype,
Token_decr,
Token_default,
Token_delete,
Expand Down
Loading

0 comments on commit 42d5084

Please sign in to comment.