cppparser: Parse parenthesised noexcept() and explicit()

This commit is contained in:
rdb 2021-03-02 13:29:36 +01:00
parent 8eccc9f569
commit 807be99f10
5 changed files with 4811 additions and 4660 deletions

File diff suppressed because it is too large Load Diff

View File

@ -129,79 +129,81 @@ extern int cppyydebug;
KW_EXTENSION = 330, /* KW_EXTENSION */ KW_EXTENSION = 330, /* KW_EXTENSION */
KW_EXTERN = 331, /* KW_EXTERN */ KW_EXTERN = 331, /* KW_EXTERN */
KW_EXPLICIT = 332, /* KW_EXPLICIT */ KW_EXPLICIT = 332, /* KW_EXPLICIT */
KW_PUBLISHED = 333, /* KW_PUBLISHED */ KW_EXPLICIT_LPAREN = 333, /* KW_EXPLICIT_LPAREN */
KW_FALSE = 334, /* KW_FALSE */ KW_PUBLISHED = 334, /* KW_PUBLISHED */
KW_FINAL = 335, /* KW_FINAL */ KW_FALSE = 335, /* KW_FALSE */
KW_FLOAT = 336, /* KW_FLOAT */ KW_FINAL = 336, /* KW_FINAL */
KW_FRIEND = 337, /* KW_FRIEND */ KW_FLOAT = 337, /* KW_FLOAT */
KW_FOR = 338, /* KW_FOR */ KW_FRIEND = 338, /* KW_FRIEND */
KW_GOTO = 339, /* KW_GOTO */ KW_FOR = 339, /* KW_FOR */
KW_HAS_VIRTUAL_DESTRUCTOR = 340, /* KW_HAS_VIRTUAL_DESTRUCTOR */ KW_GOTO = 340, /* KW_GOTO */
KW_IF = 341, /* KW_IF */ KW_HAS_VIRTUAL_DESTRUCTOR = 341, /* KW_HAS_VIRTUAL_DESTRUCTOR */
KW_INLINE = 342, /* KW_INLINE */ KW_IF = 342, /* KW_IF */
KW_INT = 343, /* KW_INT */ KW_INLINE = 343, /* KW_INLINE */
KW_IS_ABSTRACT = 344, /* KW_IS_ABSTRACT */ KW_INT = 344, /* KW_INT */
KW_IS_BASE_OF = 345, /* KW_IS_BASE_OF */ KW_IS_ABSTRACT = 345, /* KW_IS_ABSTRACT */
KW_IS_CLASS = 346, /* KW_IS_CLASS */ KW_IS_BASE_OF = 346, /* KW_IS_BASE_OF */
KW_IS_CONSTRUCTIBLE = 347, /* KW_IS_CONSTRUCTIBLE */ KW_IS_CLASS = 347, /* KW_IS_CLASS */
KW_IS_CONVERTIBLE_TO = 348, /* KW_IS_CONVERTIBLE_TO */ KW_IS_CONSTRUCTIBLE = 348, /* KW_IS_CONSTRUCTIBLE */
KW_IS_DESTRUCTIBLE = 349, /* KW_IS_DESTRUCTIBLE */ KW_IS_CONVERTIBLE_TO = 349, /* KW_IS_CONVERTIBLE_TO */
KW_IS_EMPTY = 350, /* KW_IS_EMPTY */ KW_IS_DESTRUCTIBLE = 350, /* KW_IS_DESTRUCTIBLE */
KW_IS_ENUM = 351, /* KW_IS_ENUM */ KW_IS_EMPTY = 351, /* KW_IS_EMPTY */
KW_IS_FINAL = 352, /* KW_IS_FINAL */ KW_IS_ENUM = 352, /* KW_IS_ENUM */
KW_IS_FUNDAMENTAL = 353, /* KW_IS_FUNDAMENTAL */ KW_IS_FINAL = 353, /* KW_IS_FINAL */
KW_IS_POD = 354, /* KW_IS_POD */ KW_IS_FUNDAMENTAL = 354, /* KW_IS_FUNDAMENTAL */
KW_IS_POLYMORPHIC = 355, /* KW_IS_POLYMORPHIC */ KW_IS_POD = 355, /* KW_IS_POD */
KW_IS_STANDARD_LAYOUT = 356, /* KW_IS_STANDARD_LAYOUT */ KW_IS_POLYMORPHIC = 356, /* KW_IS_POLYMORPHIC */
KW_IS_TRIVIAL = 357, /* KW_IS_TRIVIAL */ KW_IS_STANDARD_LAYOUT = 357, /* KW_IS_STANDARD_LAYOUT */
KW_IS_UNION = 358, /* KW_IS_UNION */ KW_IS_TRIVIAL = 358, /* KW_IS_TRIVIAL */
KW_LONG = 359, /* KW_LONG */ KW_IS_UNION = 359, /* KW_IS_UNION */
KW_MAKE_MAP_KEYS_SEQ = 360, /* KW_MAKE_MAP_KEYS_SEQ */ KW_LONG = 360, /* KW_LONG */
KW_MAKE_MAP_PROPERTY = 361, /* KW_MAKE_MAP_PROPERTY */ KW_MAKE_MAP_KEYS_SEQ = 361, /* KW_MAKE_MAP_KEYS_SEQ */
KW_MAKE_PROPERTY = 362, /* KW_MAKE_PROPERTY */ KW_MAKE_MAP_PROPERTY = 362, /* KW_MAKE_MAP_PROPERTY */
KW_MAKE_PROPERTY2 = 363, /* KW_MAKE_PROPERTY2 */ KW_MAKE_PROPERTY = 363, /* KW_MAKE_PROPERTY */
KW_MAKE_SEQ = 364, /* KW_MAKE_SEQ */ KW_MAKE_PROPERTY2 = 364, /* KW_MAKE_PROPERTY2 */
KW_MAKE_SEQ_PROPERTY = 365, /* KW_MAKE_SEQ_PROPERTY */ KW_MAKE_SEQ = 365, /* KW_MAKE_SEQ */
KW_MUTABLE = 366, /* KW_MUTABLE */ KW_MAKE_SEQ_PROPERTY = 366, /* KW_MAKE_SEQ_PROPERTY */
KW_NAMESPACE = 367, /* KW_NAMESPACE */ KW_MUTABLE = 367, /* KW_MUTABLE */
KW_NEW = 368, /* KW_NEW */ KW_NAMESPACE = 368, /* KW_NAMESPACE */
KW_NOEXCEPT = 369, /* KW_NOEXCEPT */ KW_NEW = 369, /* KW_NEW */
KW_NULLPTR = 370, /* KW_NULLPTR */ KW_NOEXCEPT = 370, /* KW_NOEXCEPT */
KW_OPERATOR = 371, /* KW_OPERATOR */ KW_NOEXCEPT_LPAREN = 371, /* KW_NOEXCEPT_LPAREN */
KW_OVERRIDE = 372, /* KW_OVERRIDE */ KW_NULLPTR = 372, /* KW_NULLPTR */
KW_PRIVATE = 373, /* KW_PRIVATE */ KW_OPERATOR = 373, /* KW_OPERATOR */
KW_PROTECTED = 374, /* KW_PROTECTED */ KW_OVERRIDE = 374, /* KW_OVERRIDE */
KW_PUBLIC = 375, /* KW_PUBLIC */ KW_PRIVATE = 375, /* KW_PRIVATE */
KW_REGISTER = 376, /* KW_REGISTER */ KW_PROTECTED = 376, /* KW_PROTECTED */
KW_REINTERPRET_CAST = 377, /* KW_REINTERPRET_CAST */ KW_PUBLIC = 377, /* KW_PUBLIC */
KW_RETURN = 378, /* KW_RETURN */ KW_REGISTER = 378, /* KW_REGISTER */
KW_SHORT = 379, /* KW_SHORT */ KW_REINTERPRET_CAST = 379, /* KW_REINTERPRET_CAST */
KW_SIGNED = 380, /* KW_SIGNED */ KW_RETURN = 380, /* KW_RETURN */
KW_SIZEOF = 381, /* KW_SIZEOF */ KW_SHORT = 381, /* KW_SHORT */
KW_STATIC = 382, /* KW_STATIC */ KW_SIGNED = 382, /* KW_SIGNED */
KW_STATIC_ASSERT = 383, /* KW_STATIC_ASSERT */ KW_SIZEOF = 383, /* KW_SIZEOF */
KW_STATIC_CAST = 384, /* KW_STATIC_CAST */ KW_STATIC = 384, /* KW_STATIC */
KW_STRUCT = 385, /* KW_STRUCT */ KW_STATIC_ASSERT = 385, /* KW_STATIC_ASSERT */
KW_TEMPLATE = 386, /* KW_TEMPLATE */ KW_STATIC_CAST = 386, /* KW_STATIC_CAST */
KW_THREAD_LOCAL = 387, /* KW_THREAD_LOCAL */ KW_STRUCT = 387, /* KW_STRUCT */
KW_THROW = 388, /* KW_THROW */ KW_TEMPLATE = 388, /* KW_TEMPLATE */
KW_TRUE = 389, /* KW_TRUE */ KW_THREAD_LOCAL = 389, /* KW_THREAD_LOCAL */
KW_TRY = 390, /* KW_TRY */ KW_THROW = 390, /* KW_THROW */
KW_TYPEDEF = 391, /* KW_TYPEDEF */ KW_TRUE = 391, /* KW_TRUE */
KW_TYPEID = 392, /* KW_TYPEID */ KW_TRY = 392, /* KW_TRY */
KW_TYPENAME = 393, /* KW_TYPENAME */ KW_TYPEDEF = 393, /* KW_TYPEDEF */
KW_UNDERLYING_TYPE = 394, /* KW_UNDERLYING_TYPE */ KW_TYPEID = 394, /* KW_TYPEID */
KW_UNION = 395, /* KW_UNION */ KW_TYPENAME = 395, /* KW_TYPENAME */
KW_UNSIGNED = 396, /* KW_UNSIGNED */ KW_UNDERLYING_TYPE = 396, /* KW_UNDERLYING_TYPE */
KW_USING = 397, /* KW_USING */ KW_UNION = 397, /* KW_UNION */
KW_VIRTUAL = 398, /* KW_VIRTUAL */ KW_UNSIGNED = 398, /* KW_UNSIGNED */
KW_VOID = 399, /* KW_VOID */ KW_USING = 399, /* KW_USING */
KW_VOLATILE = 400, /* KW_VOLATILE */ KW_VIRTUAL = 400, /* KW_VIRTUAL */
KW_WCHAR_T = 401, /* KW_WCHAR_T */ KW_VOID = 401, /* KW_VOID */
KW_WHILE = 402, /* KW_WHILE */ KW_VOLATILE = 402, /* KW_VOLATILE */
START_CPP = 403, /* START_CPP */ KW_WCHAR_T = 403, /* KW_WCHAR_T */
START_CONST_EXPR = 404, /* START_CONST_EXPR */ KW_WHILE = 404, /* KW_WHILE */
START_TYPE = 405 /* START_TYPE */ START_CPP = 405, /* START_CPP */
START_CONST_EXPR = 406, /* START_CONST_EXPR */
START_TYPE = 407 /* START_TYPE */
}; };
typedef enum yytokentype yytoken_kind_t; typedef enum yytokentype yytoken_kind_t;
#endif #endif
@ -284,79 +286,81 @@ extern int cppyydebug;
#define KW_EXTENSION 330 #define KW_EXTENSION 330
#define KW_EXTERN 331 #define KW_EXTERN 331
#define KW_EXPLICIT 332 #define KW_EXPLICIT 332
#define KW_PUBLISHED 333 #define KW_EXPLICIT_LPAREN 333
#define KW_FALSE 334 #define KW_PUBLISHED 334
#define KW_FINAL 335 #define KW_FALSE 335
#define KW_FLOAT 336 #define KW_FINAL 336
#define KW_FRIEND 337 #define KW_FLOAT 337
#define KW_FOR 338 #define KW_FRIEND 338
#define KW_GOTO 339 #define KW_FOR 339
#define KW_HAS_VIRTUAL_DESTRUCTOR 340 #define KW_GOTO 340
#define KW_IF 341 #define KW_HAS_VIRTUAL_DESTRUCTOR 341
#define KW_INLINE 342 #define KW_IF 342
#define KW_INT 343 #define KW_INLINE 343
#define KW_IS_ABSTRACT 344 #define KW_INT 344
#define KW_IS_BASE_OF 345 #define KW_IS_ABSTRACT 345
#define KW_IS_CLASS 346 #define KW_IS_BASE_OF 346
#define KW_IS_CONSTRUCTIBLE 347 #define KW_IS_CLASS 347
#define KW_IS_CONVERTIBLE_TO 348 #define KW_IS_CONSTRUCTIBLE 348
#define KW_IS_DESTRUCTIBLE 349 #define KW_IS_CONVERTIBLE_TO 349
#define KW_IS_EMPTY 350 #define KW_IS_DESTRUCTIBLE 350
#define KW_IS_ENUM 351 #define KW_IS_EMPTY 351
#define KW_IS_FINAL 352 #define KW_IS_ENUM 352
#define KW_IS_FUNDAMENTAL 353 #define KW_IS_FINAL 353
#define KW_IS_POD 354 #define KW_IS_FUNDAMENTAL 354
#define KW_IS_POLYMORPHIC 355 #define KW_IS_POD 355
#define KW_IS_STANDARD_LAYOUT 356 #define KW_IS_POLYMORPHIC 356
#define KW_IS_TRIVIAL 357 #define KW_IS_STANDARD_LAYOUT 357
#define KW_IS_UNION 358 #define KW_IS_TRIVIAL 358
#define KW_LONG 359 #define KW_IS_UNION 359
#define KW_MAKE_MAP_KEYS_SEQ 360 #define KW_LONG 360
#define KW_MAKE_MAP_PROPERTY 361 #define KW_MAKE_MAP_KEYS_SEQ 361
#define KW_MAKE_PROPERTY 362 #define KW_MAKE_MAP_PROPERTY 362
#define KW_MAKE_PROPERTY2 363 #define KW_MAKE_PROPERTY 363
#define KW_MAKE_SEQ 364 #define KW_MAKE_PROPERTY2 364
#define KW_MAKE_SEQ_PROPERTY 365 #define KW_MAKE_SEQ 365
#define KW_MUTABLE 366 #define KW_MAKE_SEQ_PROPERTY 366
#define KW_NAMESPACE 367 #define KW_MUTABLE 367
#define KW_NEW 368 #define KW_NAMESPACE 368
#define KW_NOEXCEPT 369 #define KW_NEW 369
#define KW_NULLPTR 370 #define KW_NOEXCEPT 370
#define KW_OPERATOR 371 #define KW_NOEXCEPT_LPAREN 371
#define KW_OVERRIDE 372 #define KW_NULLPTR 372
#define KW_PRIVATE 373 #define KW_OPERATOR 373
#define KW_PROTECTED 374 #define KW_OVERRIDE 374
#define KW_PUBLIC 375 #define KW_PRIVATE 375
#define KW_REGISTER 376 #define KW_PROTECTED 376
#define KW_REINTERPRET_CAST 377 #define KW_PUBLIC 377
#define KW_RETURN 378 #define KW_REGISTER 378
#define KW_SHORT 379 #define KW_REINTERPRET_CAST 379
#define KW_SIGNED 380 #define KW_RETURN 380
#define KW_SIZEOF 381 #define KW_SHORT 381
#define KW_STATIC 382 #define KW_SIGNED 382
#define KW_STATIC_ASSERT 383 #define KW_SIZEOF 383
#define KW_STATIC_CAST 384 #define KW_STATIC 384
#define KW_STRUCT 385 #define KW_STATIC_ASSERT 385
#define KW_TEMPLATE 386 #define KW_STATIC_CAST 386
#define KW_THREAD_LOCAL 387 #define KW_STRUCT 387
#define KW_THROW 388 #define KW_TEMPLATE 388
#define KW_TRUE 389 #define KW_THREAD_LOCAL 389
#define KW_TRY 390 #define KW_THROW 390
#define KW_TYPEDEF 391 #define KW_TRUE 391
#define KW_TYPEID 392 #define KW_TRY 392
#define KW_TYPENAME 393 #define KW_TYPEDEF 393
#define KW_UNDERLYING_TYPE 394 #define KW_TYPEID 394
#define KW_UNION 395 #define KW_TYPENAME 395
#define KW_UNSIGNED 396 #define KW_UNDERLYING_TYPE 396
#define KW_USING 397 #define KW_UNION 397
#define KW_VIRTUAL 398 #define KW_UNSIGNED 398
#define KW_VOID 399 #define KW_USING 399
#define KW_VOLATILE 400 #define KW_VIRTUAL 400
#define KW_WCHAR_T 401 #define KW_VOID 401
#define KW_WHILE 402 #define KW_VOLATILE 402
#define START_CPP 403 #define KW_WCHAR_T 403
#define START_CONST_EXPR 404 #define KW_WHILE 404
#define START_TYPE 405 #define START_CPP 405
#define START_CONST_EXPR 406
#define START_TYPE 407
/* Value type. */ /* Value type. */

View File

@ -283,6 +283,7 @@ pop_struct() {
%token KW_EXTENSION %token KW_EXTENSION
%token KW_EXTERN %token KW_EXTERN
%token KW_EXPLICIT %token KW_EXPLICIT
%token KW_EXPLICIT_LPAREN
%token KW_PUBLISHED %token KW_PUBLISHED
%token KW_FALSE %token KW_FALSE
%token KW_FINAL %token KW_FINAL
@ -320,6 +321,7 @@ pop_struct() {
%token KW_NAMESPACE %token KW_NAMESPACE
%token KW_NEW %token KW_NEW
%token KW_NOEXCEPT %token KW_NOEXCEPT
%token KW_NOEXCEPT_LPAREN
%token KW_NULLPTR %token KW_NULLPTR
%token KW_OPERATOR %token KW_OPERATOR
%token KW_OVERRIDE %token KW_OVERRIDE
@ -995,6 +997,15 @@ storage_class:
| KW_EXPLICIT storage_class | KW_EXPLICIT storage_class
{ {
$$ = $2 | (int)CPPInstance::SC_explicit; $$ = $2 | (int)CPPInstance::SC_explicit;
}
| KW_EXPLICIT_LPAREN const_expr ')' storage_class
{
CPPExpression::Result result = $2->evaluate();
if (result._type == CPPExpression::RT_error) {
yywarning("explicit() requires a constant expression", @2);
} else if (result.as_boolean()) {
$$ = $4 | (int)CPPInstance::SC_explicit;
}
} }
| KW_REGISTER storage_class | KW_REGISTER storage_class
{ {
@ -1452,15 +1463,15 @@ function_post:
{ {
$$ = $1 | (int)CPPFunctionType::F_noexcept; $$ = $1 | (int)CPPFunctionType::F_noexcept;
} }
/* | function_post KW_NOEXCEPT '(' const_expr ')' | function_post KW_NOEXCEPT_LPAREN const_expr ')'
{ {
CPPExpression::Result result = $4->evaluate(); CPPExpression::Result result = $3->evaluate();
if (result._type == CPPExpression::RT_error) { if (result._type == CPPExpression::RT_error) {
yywarning("noexcept requires a constant expression", @4); yywarning("noexcept() requires a constant expression", @3);
} else if (result.as_boolean()) { } else if (result.as_boolean()) {
$$ = $1 | (int)CPPFunctionType::F_noexcept; $$ = $1 | (int)CPPFunctionType::F_noexcept;
} }
}*/ }
| function_post KW_FINAL | function_post KW_FINAL
{ {
$$ = $1 | (int)CPPFunctionType::F_final; $$ = $1 | (int)CPPFunctionType::F_final;
@ -3071,6 +3082,12 @@ using_declaration:
CPPUsing *using_decl = new CPPUsing($3, true, @1.file); CPPUsing *using_decl = new CPPUsing($3, true, @1.file);
current_scope->add_declaration(using_decl, global_scope, current_lexer, @1); current_scope->add_declaration(using_decl, global_scope, current_lexer, @1);
current_scope->add_using(using_decl, global_scope, current_lexer); current_scope->add_using(using_decl, global_scope, current_lexer);
}
| KW_USING KW_ENUM name ';'
{
CPPUsing *using_decl = new CPPUsing($3, false, @1.file);
current_scope->add_declaration(using_decl, global_scope, current_lexer, @1);
current_scope->add_using(using_decl, global_scope, current_lexer);
} }
; ;
@ -3219,10 +3236,10 @@ element:
| KW_CHAR | KW_CHAR8_T | KW_CHAR16_T | KW_CHAR32_T | KW_CLASS | KW_CHAR | KW_CHAR8_T | KW_CHAR16_T | KW_CHAR32_T | KW_CLASS
| KW_CONST | KW_CONSTEVAL | KW_CONSTEXPR | KW_CONSTINIT | KW_CONST_CAST | KW_CONST | KW_CONSTEVAL | KW_CONSTEXPR | KW_CONSTINIT | KW_CONST_CAST
| KW_DECLTYPE | KW_DEFAULT | KW_DELETE | KW_DOUBLE | KW_DYNAMIC_CAST | KW_DECLTYPE | KW_DEFAULT | KW_DELETE | KW_DOUBLE | KW_DYNAMIC_CAST
| KW_ELSE | KW_ENUM | KW_EXTERN | KW_EXPLICIT | KW_ELSE | KW_ENUM | KW_EXTERN | KW_EXPLICIT | KW_EXPLICIT_LPAREN
| KW_FALSE | KW_FINAL | KW_FLOAT | KW_FRIEND | KW_FOR | KW_FALSE | KW_FINAL | KW_FLOAT | KW_FRIEND | KW_FOR
| KW_GOTO | KW_IF | KW_INLINE | KW_INT | KW_GOTO | KW_IF | KW_INLINE | KW_INT | KW_LONG | KW_MUTABLE
| KW_LONG | KW_MUTABLE | KW_NAMESPACE | KW_NEW | KW_NULLPTR | KW_NAMESPACE | KW_NEW | KW_NOEXCEPT | KW_NOEXCEPT_LPAREN | KW_NULLPTR
| KW_OPERATOR | KW_OVERRIDE | KW_PRIVATE | KW_PROTECTED | KW_OPERATOR | KW_OVERRIDE | KW_PRIVATE | KW_PROTECTED
| KW_PUBLIC | KW_PUBLISHED | KW_REGISTER | KW_REINTERPRET_CAST | KW_PUBLIC | KW_PUBLISHED | KW_REGISTER | KW_REINTERPRET_CAST
| KW_RETURN | KW_SHORT | KW_SIGNED | KW_SIZEOF | KW_STATIC | KW_RETURN | KW_SHORT | KW_SIGNED | KW_SIZEOF | KW_STATIC
@ -3723,6 +3740,10 @@ const_expr:
| const_expr '(' ')' | const_expr '(' ')'
{ {
$$ = new CPPExpression('f', $1); $$ = new CPPExpression('f', $1);
}
| KW_NOEXCEPT_LPAREN const_expr ')'
{
$$ = new CPPExpression(KW_NOEXCEPT, $2);
} }
| const_expr '.' name | const_expr '.' name
{ {

View File

@ -860,6 +860,9 @@ evaluate() const {
case ',': case ',':
return r2; return r2;
case KW_NOEXCEPT:
return Result();
default: default:
cerr << "**unexpected operator**\n"; cerr << "**unexpected operator**\n";
abort(); abort();
@ -1180,6 +1183,7 @@ determine_type() const {
case GECOMPARE: case GECOMPARE:
case '<': case '<':
case '>': case '>':
case KW_NOEXCEPT:
return bool_type; return bool_type;
case SPACESHIP: case SPACESHIP:
@ -1908,6 +1912,12 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool) const {
out << "()"; out << "()";
break; break;
case KW_NOEXCEPT:
out << "noexcept(";
_u._op._op1->output(out, indent_level, scope, false);
out << ")";
break;
default: default:
out << "(" << (char)_u._op._operator << " "; out << "(" << (char)_u._op._operator << " ";
_u._op._op1->output(out, indent_level, scope, false); _u._op._op1->output(out, indent_level, scope, false);

View File

@ -1987,6 +1987,24 @@ get_identifier(int c) {
} }
if (kw != 0) { if (kw != 0) {
if (kw == KW_EXPLICIT || kw == KW_NOEXCEPT) {
// These can be followed by a left-paren. Doing this helps to avoid
// shift/reduce conflicts in the parser.
while (c != EOF && isspace(c)) {
get();
c = peek();
}
if (c == '(') {
if (kw == KW_EXPLICIT) {
kw = KW_EXPLICIT_LPAREN;
}
else if (kw == KW_NOEXCEPT) {
kw = KW_NOEXCEPT_LPAREN;
}
get();
}
}
YYSTYPE result; YYSTYPE result;
result.u.identifier = nullptr; result.u.identifier = nullptr;
return CPPToken(kw, loc, name, result); return CPPToken(kw, loc, name, result);