Skip to content

Commit 2f9dfdd

Browse files
jbowlerjcfr
authored andcommitted
[Backport generator] Add constexpr and decltype parsing (#125)
- parses constexpr (in the manner of const) and decltype (in the manner of __typeof) and adds flags for them (cherry picked from commit MeVisLab/pythonqt@42d5084)
1 parent 9561d81 commit 2f9dfdd

17 files changed

+134
-50
lines changed

Diff for: .vimrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
set expandtab

Diff for: generator/abstractmetabuilder.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class AbstractMetaBuilder
127127
bool isEnum(const QStringList &qualified_name);
128128

129129
void fixQObjectForScope (TypeDatabase *types,
130-
NamespaceModelItem item);
130+
NamespaceModelItem item);
131131

132132
// QtScript
133133
QSet<QString> qtMetaTypeDeclaredTypeNames() const

Diff for: generator/parser/codemodel.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,9 @@ TypeInfo TypeInfo::combine (const TypeInfo &__lhs, const TypeInfo &__rhs)
142142
TypeInfo __result = __lhs;
143143

144144
__result.setConstant (__result.isConstant () || __rhs.isConstant ());
145+
__result.setConstexpr (__result.isConstexpr () || __rhs.isConstexpr ());
145146
__result.setVolatile (__result.isVolatile () || __rhs.isVolatile ());
147+
__result.setMutable (__result.isMutable () || __rhs.isMutable ());
146148
__result.setReference (__result.isReference () || __rhs.isReference ());
147149
__result.setRvalueReference (__result.isRvalueReference () || __rhs.isRvalueReference ());
148150
__result.setIndirections (__result.indirections () + __rhs.indirections ());
@@ -182,9 +184,15 @@ QString TypeInfo::toString() const
182184
if (isConstant())
183185
tmp += QLatin1String(" const");
184186

187+
if (isConstexpr())
188+
tmp += QLatin1String(" constexpr");
189+
185190
if (isVolatile())
186191
tmp += QLatin1String(" volatile");
187192

193+
if (isMutable())
194+
tmp += QLatin1String(" mutable");
195+
188196
if (indirections())
189197
tmp += QString(indirections(), QLatin1Char('*'));
190198

@@ -917,6 +925,16 @@ void _MemberModelItem::setConstant(bool isConstant)
917925
_M_isConstant = isConstant;
918926
}
919927

928+
bool _MemberModelItem::isConstexpr() const
929+
{
930+
return _M_isConstexpr;
931+
}
932+
933+
void _MemberModelItem::setConstexpr(bool isConstexpr)
934+
{
935+
_M_isConstexpr = isConstexpr;
936+
}
937+
920938
bool _MemberModelItem::isVolatile() const
921939
{
922940
return _M_isVolatile;

Diff for: generator/parser/codemodel.h

+23-8
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,15 @@ struct TypeInfo
132132
bool isConstant() const { return m_flags.m_constant; }
133133
void setConstant(bool is) { m_flags.m_constant = is; }
134134

135+
bool isConstexpr() const { return m_flags.m_constexpr; }
136+
void setConstexpr(bool is) { m_flags.m_constexpr = is; }
137+
135138
bool isVolatile() const { return m_flags.m_volatile; }
136139
void setVolatile(bool is) { m_flags.m_volatile = is; }
137140

141+
bool isMutable() const { return m_flags.m_mutable; }
142+
void setMutable(bool is) { m_flags.m_mutable = is; }
143+
138144
bool isReference() const { return m_flags.m_reference; }
139145
void setReference(bool is) { m_flags.m_reference = is; }
140146

@@ -166,19 +172,24 @@ struct TypeInfo
166172

167173
private:
168174
struct TypeInfo_flags {
169-
uint m_constant: 1;
170-
uint m_volatile: 1;
171-
uint m_reference: 1;
172-
uint m_functionPointer: 1;
173-
uint m_indirections: 6;
174-
inline bool equals(TypeInfo_flags other) const {
175+
uint m_constant: 1;
176+
uint m_constexpr: 1;
177+
uint m_volatile: 1;
178+
uint m_mutable: 1;
179+
uint m_reference: 1;
180+
uint m_functionPointer: 1;
181+
uint m_indirections: 6;
182+
inline bool equals(TypeInfo_flags other) const {
183+
/* m_auto and m_friend don't matter here */
175184
return m_constant == other.m_constant
185+
&& m_constexpr == other.m_constexpr
176186
&& m_volatile == other.m_volatile
187+
&& m_mutable == other.m_mutable
177188
&& m_reference == other.m_reference
178189
&& m_functionPointer == other.m_functionPointer
179190
&& m_indirections == other.m_indirections;
180-
}
181-
} m_flags {0, 0, 0, 0, 0};
191+
}
192+
} m_flags {0, 0, 0, 0, 0, 0, 0};
182193

183194
QStringList m_qualifiedName;
184195
QStringList m_arrayElements;
@@ -455,6 +466,9 @@ class _MemberModelItem: public _CodeModelItem
455466
bool isConstant() const;
456467
void setConstant(bool isConstant);
457468

469+
bool isConstexpr() const;
470+
void setConstexpr(bool isConstexpr);
471+
458472
bool isVolatile() const;
459473
void setVolatile(bool isVolatile);
460474

@@ -504,6 +518,7 @@ class _MemberModelItem: public _CodeModelItem
504518
struct
505519
{
506520
uint _M_isConstant: 1;
521+
uint _M_isConstexpr: 1;
507522
uint _M_isVolatile: 1;
508523
uint _M_isStatic: 1;
509524
uint _M_isAuto: 1;

Diff for: generator/parser/compiler_utils.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ TypeInfo CompilerUtils::typeDescription(TypeSpecifierAST *type_specifier, Declar
5858
TypeInfo typeInfo;
5959
typeInfo.setQualifiedName (type_cc.qualifiedName ());
6060
typeInfo.setConstant (type_cc.isConstant ());
61+
typeInfo.setConstexpr (type_cc.isConstexpr ());
6162
typeInfo.setVolatile (type_cc.isVolatile ());
63+
typeInfo.setMutable (type_cc.isMutable ());
6264
typeInfo.setReference (decl_cc.isReference ());
6365
typeInfo.setRvalueReference (decl_cc.isRvalueReference ());
6466
typeInfo.setIndirections (decl_cc.indirection ());

Diff for: generator/parser/lexer.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,20 @@ void Lexer::scanKeyword8()
15491549
}
15501550
break;
15511551

1552+
case 'd':
1553+
if (*(cursor + 1) == 'e' &&
1554+
*(cursor + 2) == 'c' &&
1555+
*(cursor + 3) == 'l' &&
1556+
*(cursor + 4) == 't' &&
1557+
*(cursor + 5) == 'y' &&
1558+
*(cursor + 6) == 'p' &&
1559+
*(cursor + 7) == 'e')
1560+
{
1561+
token_stream[(int) index++].kind = Token_decltype;
1562+
return;
1563+
}
1564+
break;
1565+
15521566
case 'e':
15531567
if (*(cursor + 1) == 'x' &&
15541568
*(cursor + 2) == 'p' &&
@@ -1680,6 +1694,21 @@ void Lexer::scanKeyword9()
16801694
{
16811695
switch (*cursor)
16821696
{
1697+
case 'c':
1698+
if (*(cursor + 1) == 'o' &&
1699+
*(cursor + 2) == 'n' &&
1700+
*(cursor + 3) == 's' &&
1701+
*(cursor + 4) == 't' &&
1702+
*(cursor + 5) == 'e' &&
1703+
*(cursor + 6) == 'x' &&
1704+
*(cursor + 7) == 'p' &&
1705+
*(cursor + 8) == 'r')
1706+
{
1707+
token_stream[(int) index++].kind = Token_constexpr;
1708+
return;
1709+
}
1710+
break;
1711+
16831712
case 'p':
16841713
if (*(cursor + 1) == 'r' &&
16851714
*(cursor + 2) == 'o' &&

Diff for: generator/parser/list.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct ListNode
105105

106106
template <class Tp>
107107
inline const ListNode<Tp> *snoc(const ListNode<Tp> *list,
108-
const Tp &element, pool *p)
108+
const Tp &element, pool *p)
109109
{
110110
if (!list)
111111
return ListNode<Tp>::create(element, p);

Diff for: generator/parser/name_compiler.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ void NameCompiler::visitTemplateArgument(TemplateArgumentAST *node)
127127
if (type_cc.isConstant())
128128
_M_name.last() += "const ";
129129

130+
/* An id can't be 'constexpr' but it may have a function type in which
131+
* case constexpr could appear.
132+
*/
133+
if (type_cc.isConstexpr())
134+
_M_name.last() += "constexpr ";
135+
130136
QStringList q = type_cc.qualifiedName ();
131137

132138
if (q.count () == 1)

Diff for: generator/parser/parser.cpp

+18-4
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,9 @@ bool Parser::skipUntilDeclaration()
249249
case Token_export:
250250

251251
case Token_const: // cv
252+
case Token_constexpr: // cv
252253
case Token_volatile: // cv
254+
case Token_mutable: // cv
253255

254256
case Token_public:
255257
case Token_protected:
@@ -258,6 +260,11 @@ bool Parser::skipUntilDeclaration()
258260
case Token_slots: // Qt
259261
return true;
260262

263+
case Token_decltype:
264+
case Token___typeof:
265+
reportError("C++11 decltype/__typeof(id|expression) not handled");
266+
return true;
267+
261268
default:
262269
token_stream.nextToken();
263270
}
@@ -276,7 +283,11 @@ bool Parser::skipUntilStatement()
276283
case '{':
277284
case '}':
278285
case Token_const:
286+
case Token_constexpr:
287+
case Token_decltype:
288+
case Token___typeof:
279289
case Token_volatile:
290+
case Token_mutable:
280291
case Token_identifier:
281292
case Token_case:
282293
case Token_default:
@@ -984,7 +995,8 @@ bool Parser::parseCvQualify(const ListNode<std::size_t> *&node)
984995

985996
int tk;
986997
while (0 != (tk = token_stream.lookAhead())
987-
&& (tk == Token_const || tk == Token_volatile))
998+
&& (tk == Token_const || tk == Token_constexpr ||
999+
tk == Token_volatile || tk == Token_mutable))
9881000
{
9891001
node = snoc(node, token_stream.cursor(), _M_pool);
9901002
token_stream.nextToken();
@@ -1032,7 +1044,8 @@ bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
10321044
{
10331045
ast->integrals = integrals;
10341046
}
1035-
else if (token_stream.lookAhead() == Token___typeof)
1047+
else if (token_stream.lookAhead() == Token___typeof ||
1048+
token_stream.lookAhead() == Token_decltype)
10361049
{
10371050
ast->type_of = token_stream.cursor();
10381051
token_stream.nextToken();
@@ -1627,7 +1640,7 @@ bool Parser::parseStorageClassSpecifier(const ListNode<std::size_t> *&node)
16271640
while (0 != (tk = token_stream.lookAhead())
16281641
&& (tk == Token_friend || tk == Token_auto
16291642
|| tk == Token_register || tk == Token_static
1630-
|| tk == Token_extern || tk == Token_mutable))
1643+
|| tk == Token_extern))
16311644
{
16321645
node = snoc(node, token_stream.cursor(), _M_pool);
16331646
token_stream.nextToken();
@@ -3262,7 +3275,8 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node)
32623275
start_decl:
32633276
token_stream.rewind((int) index);
32643277

3265-
if (token_stream.lookAhead() == Token_const
3278+
if ((token_stream.lookAhead() == Token_const ||
3279+
token_stream.lookAhead() == Token_constexpr)
32663280
&& token_stream.lookAhead(1) == Token_identifier
32673281
&& token_stream.lookAhead(2) == '=')
32683282
{

Diff for: generator/parser/parser.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ class Parser
100100
bool parseEnumSpecifier(TypeSpecifierAST *&node);
101101
bool parseEnumerator(EnumeratorAST *&node);
102102
bool parseEqualityExpression(ExpressionAST *&node,
103-
bool templArgs = false);
103+
bool templArgs = false);
104104
bool parseExceptionSpecification(ExceptionSpecificationAST *&node);
105105
bool parseExclusiveOrExpression(ExpressionAST *&node,
106-
bool templArgs = false);
106+
bool templArgs = false);
107107
bool parseExpression(ExpressionAST *&node);
108108
bool parseExpressionOrDeclarationStatement(StatementAST *&node);
109109
bool parseExpressionStatement(StatementAST *&node);
@@ -113,7 +113,7 @@ class Parser
113113
bool parseFunctionSpecifier(const ListNode<std::size_t> *&node);
114114
bool parseIfStatement(StatementAST *&node);
115115
bool parseInclusiveOrExpression(ExpressionAST *&node,
116-
bool templArgs = false);
116+
bool templArgs = false);
117117
bool parseInitDeclarator(InitDeclaratorAST *&node);
118118
bool parseInitDeclaratorList(const ListNode<InitDeclaratorAST*> *&node);
119119
bool parseInitializer(InitializerAST *&node);
@@ -122,9 +122,9 @@ class Parser
122122
bool parseLinkageBody(LinkageBodyAST *&node);
123123
bool parseLinkageSpecification(DeclarationAST *&node);
124124
bool parseLogicalAndExpression(ExpressionAST *&node,
125-
bool templArgs = false);
125+
bool templArgs = false);
126126
bool parseLogicalOrExpression(ExpressionAST *&node,
127-
bool templArgs = false);
127+
bool templArgs = false);
128128
bool parseMemInitializer(MemInitializerAST *&node);
129129
bool parseMemInitializerList(const ListNode<MemInitializerAST*> *&node);
130130
bool parseMemberSpecification(DeclarationAST *&node);
@@ -148,17 +148,17 @@ class Parser
148148
bool parsePtrOperator(PtrOperatorAST *&node);
149149
bool parsePtrToMember(PtrToMemberAST *&node);
150150
bool parseRelationalExpression(ExpressionAST *&node,
151-
bool templArgs = false);
151+
bool templArgs = false);
152152
bool parseShiftExpression(ExpressionAST *&node);
153153
bool parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
154-
bool onlyIntegral = false);
154+
bool onlyIntegral = false);
155155
bool parseStatement(StatementAST *&node);
156156
bool parseStorageClassSpecifier(const ListNode<std::size_t> *&node);
157157
bool parseStringLiteral(StringLiteralAST *&node);
158158
bool parseSwitchStatement(StatementAST *&node);
159159
bool parseTemplateArgument(TemplateArgumentAST *&node);
160160
bool parseTemplateArgumentList(const ListNode<TemplateArgumentAST*> *&node,
161-
bool reportError = true);
161+
bool reportError = true);
162162
bool parseTemplateDeclaration(DeclarationAST *&node);
163163
bool parseTemplateParameter(TemplateParameterAST *&node);
164164
bool parseTemplateParameterList(const ListNode<TemplateParameterAST*> *&node);
@@ -173,7 +173,7 @@ class Parser
173173
bool parseTypedef(DeclarationAST *&node);
174174
bool parseUnaryExpression(ExpressionAST *&node);
175175
bool parseUnqualifiedName(UnqualifiedNameAST *&node,
176-
bool parseTemplateId = true);
176+
bool parseTemplateId = true);
177177
bool parseUsing(DeclarationAST *&node);
178178
bool parseUsingTypedef(DeclarationAST*& node);
179179
bool parseUsingDirective(DeclarationAST *&node);

Diff for: generator/parser/rxx_allocator.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,20 @@ template <class _Tp> class rxx_allocator {
8282
const size_type bytes = __n * sizeof(_Tp);
8383

8484
if (_M_current_block == 0
85-
|| _S_block_size < _M_current_index + bytes)
85+
|| _S_block_size < _M_current_index + bytes)
8686
{
87-
++_M_block_index;
87+
++_M_block_index;
8888

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

92-
_M_current_block = _M_storage[_M_block_index] = reinterpret_cast<char*>
93-
(new char[_S_block_size]);
92+
_M_current_block = _M_storage[_M_block_index] = reinterpret_cast<char*>
93+
(new char[_S_block_size]);
9494

9595
#if defined(RXX_ALLOCATOR_INIT_0) // ### make it a policy
96-
::memset(_M_current_block, 0, _S_block_size);
96+
::memset(_M_current_block, 0, _S_block_size);
9797
#endif
98-
_M_current_index = 0;
98+
_M_current_index = 0;
9999
}
100100

101101
pointer p = reinterpret_cast<pointer>

Diff for: generator/parser/symbol.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ class NameTable
117117
NameSymbol *name = _M_storage.value(key);
118118
if (!name)
119119
{
120-
name = new NameSymbol(str, len);
121-
_M_storage.insert(key, name);
120+
name = new NameSymbol(str, len);
121+
_M_storage.insert(key, name);
122122
}
123123

124124
return name;

Diff for: generator/parser/tokens.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,10 @@ static char const * const _S_token_names[] = {
6969
"compl",
7070
"concat",
7171
"const",
72+
"constexpr",
7273
"const_cast",
7374
"continue",
75+
"decltype",
7476
"decr",
7577
"default",
7678
"delete",

Diff for: generator/parser/tokens.h

+2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ enum TOKEN_KIND
7171
Token_compl,
7272
Token_concat,
7373
Token_const,
74+
Token_constexpr,
7475
Token_const_cast,
7576
Token_continue,
77+
Token_decltype,
7678
Token_decr,
7779
Token_default,
7880
Token_delete,

0 commit comments

Comments
 (0)