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 1 commit
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
22 changes: 22 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 @@ -618,6 +626,10 @@ bool _FunctionModelItem::isSimilar(FunctionModelItem other) const
if (isConstant() != other->isConstant())
return false;

// ### this may be incorrect (note that isVolatile is not checked!)
if (isConstexpr() != other->isConstexpr())
return false;

jbowler marked this conversation as resolved.
Show resolved Hide resolved
if (isVariadics() != other->isVariadics())
return false;

Expand Down Expand Up @@ -917,6 +929,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
25 changes: 24 additions & 1 deletion generator/parser/codemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,21 @@ 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 isFriend() const { return m_flags.m_friend; }
void setFriend(bool is) { m_flags.m_friend = is; }

bool isAuto() const { return m_flags.m_auto; }
void setAuto(bool is) { m_flags.m_auto = is; }

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

Expand Down Expand Up @@ -167,18 +179,25 @@ struct TypeInfo
private:
struct TypeInfo_flags {
uint m_constant: 1;
uint m_constexpr: 1;
uint m_volatile: 1;
uint m_mutable: 1;
uint m_friend: 1;
uint m_auto: 1;
jbowler marked this conversation as resolved.
Show resolved Hide resolved
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, 0, 0};

QStringList m_qualifiedName;
QStringList m_arrayElements;
Expand Down Expand Up @@ -455,6 +474,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 +526,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
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
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
16 changes: 16 additions & 0 deletions generator/parser/type_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ void TypeCompiler::visitName(NameAST *node)
_M_type = name_cc.qualifiedName();
}

#if 0 //UNUSED
QStringList TypeCompiler::cvString() const
{
QStringList lst;
jbowler marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -135,21 +136,36 @@ QStringList TypeCompiler::cvString() const
{
if (q == Token_const)
lst.append(QLatin1String("const"));
else if (q == Token_constexpr)
lst.append(QLatin1String("constexpr"));
else if (q == Token_volatile)
lst.append(QLatin1String("volatile"));
else if (q == Token_mutable)
lst.append(QLatin1String("mutable"));
}

return lst;
}
#endif

bool TypeCompiler::isConstant() const
{
return _M_cv.contains(Token_const);
}

bool TypeCompiler::isConstexpr() const
{
return _M_cv.contains(Token_constexpr);
}

bool TypeCompiler::isVolatile() const
{
return _M_cv.contains(Token_volatile);
}

bool TypeCompiler::isMutable() const
{
return _M_cv.contains(Token_mutable);
}

// kate: space-indent on; indent-width 2; replace-tabs on;
4 changes: 3 additions & 1 deletion generator/parser/type_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ class TypeCompiler: protected DefaultVisitor
inline QList<int> cv() const { return _M_cv; }

bool isConstant() const;
bool isConstexpr() const;
bool isVolatile() const;
bool isMutable() const;

QStringList cvString() const;
//QStringList cvString() const; //UNUSED
jbowler marked this conversation as resolved.
Show resolved Hide resolved

void run(TypeSpecifierAST *node);

Expand Down
Loading