Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

constexpr and decltype parsing #125

Merged
merged 5 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -1666,6 +1680,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 @@ -248,7 +248,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 @@ -257,6 +259,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 @@ -275,7 +282,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 @@ -943,7 +954,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 @@ -991,7 +1003,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 @@ -1570,7 +1583,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 @@ -3190,7 +3203,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 parseUsingDirective(DeclarationAST *&node);
bool parseWhileStatement(StatementAST *&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
Loading