Interrogate cppparser improvements, C++11/14/17 additions:
* Support trailing return type. * Ignore C++14 digit separators. * Parse C++14 binary number representations. * Support "using"-style type aliases. * Support decltype and auto with "new". * Remove silly "long float" and "long long float". * Support default visibility with class inheritance. * Remove -longlong hack since C++11 supports long long natively. * Support unary plus operator. * Preserve bitfield definitions. * Support constructor inits using braces. * Support override/final specifiers. * Ignore [[attributes]] in certain cases * Add support for typeid() in expressions * Parse (but ignore) lambda expressions * Differentiate between casts, add const_cast/reinterpret_cast * Support thread_local variables.
This commit is contained in:
parent
1f32c1dff0
commit
caa03c53dd
File diff suppressed because it is too large
Load Diff
|
|
@ -72,95 +72,101 @@ extern int cppyydebug;
|
|||
UNARY_NOT = 281,
|
||||
UNARY_NEGATE = 282,
|
||||
UNARY_MINUS = 283,
|
||||
UNARY_STAR = 284,
|
||||
UNARY_REF = 285,
|
||||
POINTSAT = 286,
|
||||
SCOPE = 287,
|
||||
PLUSPLUS = 288,
|
||||
MINUSMINUS = 289,
|
||||
TIMESEQUAL = 290,
|
||||
DIVIDEEQUAL = 291,
|
||||
MODEQUAL = 292,
|
||||
PLUSEQUAL = 293,
|
||||
MINUSEQUAL = 294,
|
||||
OREQUAL = 295,
|
||||
ANDEQUAL = 296,
|
||||
XOREQUAL = 297,
|
||||
LSHIFTEQUAL = 298,
|
||||
RSHIFTEQUAL = 299,
|
||||
KW_ALIGNAS = 300,
|
||||
KW_ALIGNOF = 301,
|
||||
KW_AUTO = 302,
|
||||
KW_BEGIN_PUBLISH = 303,
|
||||
KW_BLOCKING = 304,
|
||||
KW_BOOL = 305,
|
||||
KW_CATCH = 306,
|
||||
KW_CHAR = 307,
|
||||
KW_CHAR16_T = 308,
|
||||
KW_CHAR32_T = 309,
|
||||
KW_CLASS = 310,
|
||||
KW_CONST = 311,
|
||||
KW_CONSTEXPR = 312,
|
||||
KW_DECLTYPE = 313,
|
||||
KW_DEFAULT = 314,
|
||||
KW_DELETE = 315,
|
||||
KW_DOUBLE = 316,
|
||||
KW_DYNAMIC_CAST = 317,
|
||||
KW_ELSE = 318,
|
||||
KW_END_PUBLISH = 319,
|
||||
KW_ENUM = 320,
|
||||
KW_EXTENSION = 321,
|
||||
KW_EXTERN = 322,
|
||||
KW_EXPLICIT = 323,
|
||||
KW_PUBLISHED = 324,
|
||||
KW_FALSE = 325,
|
||||
KW_FLOAT = 326,
|
||||
KW_FRIEND = 327,
|
||||
KW_FOR = 328,
|
||||
KW_GOTO = 329,
|
||||
KW_IF = 330,
|
||||
KW_INLINE = 331,
|
||||
KW_INT = 332,
|
||||
KW_LONG = 333,
|
||||
KW_LONGLONG = 334,
|
||||
KW_MAKE_PROPERTY = 335,
|
||||
KW_MAKE_PROPERTY2 = 336,
|
||||
KW_MAKE_SEQ = 337,
|
||||
KW_MUTABLE = 338,
|
||||
KW_NAMESPACE = 339,
|
||||
KW_NEW = 340,
|
||||
KW_NOEXCEPT = 341,
|
||||
KW_NULLPTR = 342,
|
||||
KW_OPERATOR = 343,
|
||||
KW_PRIVATE = 344,
|
||||
KW_PROTECTED = 345,
|
||||
KW_PUBLIC = 346,
|
||||
KW_REGISTER = 347,
|
||||
KW_RETURN = 348,
|
||||
KW_SHORT = 349,
|
||||
KW_SIGNED = 350,
|
||||
KW_SIZEOF = 351,
|
||||
KW_STATIC = 352,
|
||||
KW_STATIC_ASSERT = 353,
|
||||
KW_STATIC_CAST = 354,
|
||||
KW_STRUCT = 355,
|
||||
KW_TEMPLATE = 356,
|
||||
KW_THROW = 357,
|
||||
KW_TRUE = 358,
|
||||
KW_TRY = 359,
|
||||
KW_TYPEDEF = 360,
|
||||
KW_TYPENAME = 361,
|
||||
KW_UNION = 362,
|
||||
KW_UNSIGNED = 363,
|
||||
KW_USING = 364,
|
||||
KW_VIRTUAL = 365,
|
||||
KW_VOID = 366,
|
||||
KW_VOLATILE = 367,
|
||||
KW_WCHAR_T = 368,
|
||||
KW_WHILE = 369,
|
||||
START_CPP = 370,
|
||||
START_CONST_EXPR = 371,
|
||||
START_TYPE = 372
|
||||
UNARY_PLUS = 284,
|
||||
UNARY_STAR = 285,
|
||||
UNARY_REF = 286,
|
||||
POINTSAT = 287,
|
||||
SCOPE = 288,
|
||||
PLUSPLUS = 289,
|
||||
MINUSMINUS = 290,
|
||||
TIMESEQUAL = 291,
|
||||
DIVIDEEQUAL = 292,
|
||||
MODEQUAL = 293,
|
||||
PLUSEQUAL = 294,
|
||||
MINUSEQUAL = 295,
|
||||
OREQUAL = 296,
|
||||
ANDEQUAL = 297,
|
||||
XOREQUAL = 298,
|
||||
LSHIFTEQUAL = 299,
|
||||
RSHIFTEQUAL = 300,
|
||||
KW_ALIGNAS = 301,
|
||||
KW_ALIGNOF = 302,
|
||||
KW_AUTO = 303,
|
||||
KW_BEGIN_PUBLISH = 304,
|
||||
KW_BLOCKING = 305,
|
||||
KW_BOOL = 306,
|
||||
KW_CATCH = 307,
|
||||
KW_CHAR = 308,
|
||||
KW_CHAR16_T = 309,
|
||||
KW_CHAR32_T = 310,
|
||||
KW_CLASS = 311,
|
||||
KW_CONST = 312,
|
||||
KW_CONSTEXPR = 313,
|
||||
KW_CONST_CAST = 314,
|
||||
KW_DECLTYPE = 315,
|
||||
KW_DEFAULT = 316,
|
||||
KW_DELETE = 317,
|
||||
KW_DOUBLE = 318,
|
||||
KW_DYNAMIC_CAST = 319,
|
||||
KW_ELSE = 320,
|
||||
KW_END_PUBLISH = 321,
|
||||
KW_ENUM = 322,
|
||||
KW_EXTENSION = 323,
|
||||
KW_EXTERN = 324,
|
||||
KW_EXPLICIT = 325,
|
||||
KW_PUBLISHED = 326,
|
||||
KW_FALSE = 327,
|
||||
KW_FINAL = 328,
|
||||
KW_FLOAT = 329,
|
||||
KW_FRIEND = 330,
|
||||
KW_FOR = 331,
|
||||
KW_GOTO = 332,
|
||||
KW_IF = 333,
|
||||
KW_INLINE = 334,
|
||||
KW_INT = 335,
|
||||
KW_LONG = 336,
|
||||
KW_MAKE_PROPERTY = 337,
|
||||
KW_MAKE_PROPERTY2 = 338,
|
||||
KW_MAKE_SEQ = 339,
|
||||
KW_MUTABLE = 340,
|
||||
KW_NAMESPACE = 341,
|
||||
KW_NEW = 342,
|
||||
KW_NOEXCEPT = 343,
|
||||
KW_NULLPTR = 344,
|
||||
KW_OPERATOR = 345,
|
||||
KW_OVERRIDE = 346,
|
||||
KW_PRIVATE = 347,
|
||||
KW_PROTECTED = 348,
|
||||
KW_PUBLIC = 349,
|
||||
KW_REGISTER = 350,
|
||||
KW_REINTERPRET_CAST = 351,
|
||||
KW_RETURN = 352,
|
||||
KW_SHORT = 353,
|
||||
KW_SIGNED = 354,
|
||||
KW_SIZEOF = 355,
|
||||
KW_STATIC = 356,
|
||||
KW_STATIC_ASSERT = 357,
|
||||
KW_STATIC_CAST = 358,
|
||||
KW_STRUCT = 359,
|
||||
KW_TEMPLATE = 360,
|
||||
KW_THREAD_LOCAL = 361,
|
||||
KW_THROW = 362,
|
||||
KW_TRUE = 363,
|
||||
KW_TRY = 364,
|
||||
KW_TYPEDEF = 365,
|
||||
KW_TYPEID = 366,
|
||||
KW_TYPENAME = 367,
|
||||
KW_UNION = 368,
|
||||
KW_UNSIGNED = 369,
|
||||
KW_USING = 370,
|
||||
KW_VIRTUAL = 371,
|
||||
KW_VOID = 372,
|
||||
KW_VOLATILE = 373,
|
||||
KW_WCHAR_T = 374,
|
||||
KW_WHILE = 375,
|
||||
START_CPP = 376,
|
||||
START_CONST_EXPR = 377,
|
||||
START_TYPE = 378
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
|
|
@ -190,95 +196,101 @@ extern int cppyydebug;
|
|||
#define UNARY_NOT 281
|
||||
#define UNARY_NEGATE 282
|
||||
#define UNARY_MINUS 283
|
||||
#define UNARY_STAR 284
|
||||
#define UNARY_REF 285
|
||||
#define POINTSAT 286
|
||||
#define SCOPE 287
|
||||
#define PLUSPLUS 288
|
||||
#define MINUSMINUS 289
|
||||
#define TIMESEQUAL 290
|
||||
#define DIVIDEEQUAL 291
|
||||
#define MODEQUAL 292
|
||||
#define PLUSEQUAL 293
|
||||
#define MINUSEQUAL 294
|
||||
#define OREQUAL 295
|
||||
#define ANDEQUAL 296
|
||||
#define XOREQUAL 297
|
||||
#define LSHIFTEQUAL 298
|
||||
#define RSHIFTEQUAL 299
|
||||
#define KW_ALIGNAS 300
|
||||
#define KW_ALIGNOF 301
|
||||
#define KW_AUTO 302
|
||||
#define KW_BEGIN_PUBLISH 303
|
||||
#define KW_BLOCKING 304
|
||||
#define KW_BOOL 305
|
||||
#define KW_CATCH 306
|
||||
#define KW_CHAR 307
|
||||
#define KW_CHAR16_T 308
|
||||
#define KW_CHAR32_T 309
|
||||
#define KW_CLASS 310
|
||||
#define KW_CONST 311
|
||||
#define KW_CONSTEXPR 312
|
||||
#define KW_DECLTYPE 313
|
||||
#define KW_DEFAULT 314
|
||||
#define KW_DELETE 315
|
||||
#define KW_DOUBLE 316
|
||||
#define KW_DYNAMIC_CAST 317
|
||||
#define KW_ELSE 318
|
||||
#define KW_END_PUBLISH 319
|
||||
#define KW_ENUM 320
|
||||
#define KW_EXTENSION 321
|
||||
#define KW_EXTERN 322
|
||||
#define KW_EXPLICIT 323
|
||||
#define KW_PUBLISHED 324
|
||||
#define KW_FALSE 325
|
||||
#define KW_FLOAT 326
|
||||
#define KW_FRIEND 327
|
||||
#define KW_FOR 328
|
||||
#define KW_GOTO 329
|
||||
#define KW_IF 330
|
||||
#define KW_INLINE 331
|
||||
#define KW_INT 332
|
||||
#define KW_LONG 333
|
||||
#define KW_LONGLONG 334
|
||||
#define KW_MAKE_PROPERTY 335
|
||||
#define KW_MAKE_PROPERTY2 336
|
||||
#define KW_MAKE_SEQ 337
|
||||
#define KW_MUTABLE 338
|
||||
#define KW_NAMESPACE 339
|
||||
#define KW_NEW 340
|
||||
#define KW_NOEXCEPT 341
|
||||
#define KW_NULLPTR 342
|
||||
#define KW_OPERATOR 343
|
||||
#define KW_PRIVATE 344
|
||||
#define KW_PROTECTED 345
|
||||
#define KW_PUBLIC 346
|
||||
#define KW_REGISTER 347
|
||||
#define KW_RETURN 348
|
||||
#define KW_SHORT 349
|
||||
#define KW_SIGNED 350
|
||||
#define KW_SIZEOF 351
|
||||
#define KW_STATIC 352
|
||||
#define KW_STATIC_ASSERT 353
|
||||
#define KW_STATIC_CAST 354
|
||||
#define KW_STRUCT 355
|
||||
#define KW_TEMPLATE 356
|
||||
#define KW_THROW 357
|
||||
#define KW_TRUE 358
|
||||
#define KW_TRY 359
|
||||
#define KW_TYPEDEF 360
|
||||
#define KW_TYPENAME 361
|
||||
#define KW_UNION 362
|
||||
#define KW_UNSIGNED 363
|
||||
#define KW_USING 364
|
||||
#define KW_VIRTUAL 365
|
||||
#define KW_VOID 366
|
||||
#define KW_VOLATILE 367
|
||||
#define KW_WCHAR_T 368
|
||||
#define KW_WHILE 369
|
||||
#define START_CPP 370
|
||||
#define START_CONST_EXPR 371
|
||||
#define START_TYPE 372
|
||||
#define UNARY_PLUS 284
|
||||
#define UNARY_STAR 285
|
||||
#define UNARY_REF 286
|
||||
#define POINTSAT 287
|
||||
#define SCOPE 288
|
||||
#define PLUSPLUS 289
|
||||
#define MINUSMINUS 290
|
||||
#define TIMESEQUAL 291
|
||||
#define DIVIDEEQUAL 292
|
||||
#define MODEQUAL 293
|
||||
#define PLUSEQUAL 294
|
||||
#define MINUSEQUAL 295
|
||||
#define OREQUAL 296
|
||||
#define ANDEQUAL 297
|
||||
#define XOREQUAL 298
|
||||
#define LSHIFTEQUAL 299
|
||||
#define RSHIFTEQUAL 300
|
||||
#define KW_ALIGNAS 301
|
||||
#define KW_ALIGNOF 302
|
||||
#define KW_AUTO 303
|
||||
#define KW_BEGIN_PUBLISH 304
|
||||
#define KW_BLOCKING 305
|
||||
#define KW_BOOL 306
|
||||
#define KW_CATCH 307
|
||||
#define KW_CHAR 308
|
||||
#define KW_CHAR16_T 309
|
||||
#define KW_CHAR32_T 310
|
||||
#define KW_CLASS 311
|
||||
#define KW_CONST 312
|
||||
#define KW_CONSTEXPR 313
|
||||
#define KW_CONST_CAST 314
|
||||
#define KW_DECLTYPE 315
|
||||
#define KW_DEFAULT 316
|
||||
#define KW_DELETE 317
|
||||
#define KW_DOUBLE 318
|
||||
#define KW_DYNAMIC_CAST 319
|
||||
#define KW_ELSE 320
|
||||
#define KW_END_PUBLISH 321
|
||||
#define KW_ENUM 322
|
||||
#define KW_EXTENSION 323
|
||||
#define KW_EXTERN 324
|
||||
#define KW_EXPLICIT 325
|
||||
#define KW_PUBLISHED 326
|
||||
#define KW_FALSE 327
|
||||
#define KW_FINAL 328
|
||||
#define KW_FLOAT 329
|
||||
#define KW_FRIEND 330
|
||||
#define KW_FOR 331
|
||||
#define KW_GOTO 332
|
||||
#define KW_IF 333
|
||||
#define KW_INLINE 334
|
||||
#define KW_INT 335
|
||||
#define KW_LONG 336
|
||||
#define KW_MAKE_PROPERTY 337
|
||||
#define KW_MAKE_PROPERTY2 338
|
||||
#define KW_MAKE_SEQ 339
|
||||
#define KW_MUTABLE 340
|
||||
#define KW_NAMESPACE 341
|
||||
#define KW_NEW 342
|
||||
#define KW_NOEXCEPT 343
|
||||
#define KW_NULLPTR 344
|
||||
#define KW_OPERATOR 345
|
||||
#define KW_OVERRIDE 346
|
||||
#define KW_PRIVATE 347
|
||||
#define KW_PROTECTED 348
|
||||
#define KW_PUBLIC 349
|
||||
#define KW_REGISTER 350
|
||||
#define KW_REINTERPRET_CAST 351
|
||||
#define KW_RETURN 352
|
||||
#define KW_SHORT 353
|
||||
#define KW_SIGNED 354
|
||||
#define KW_SIZEOF 355
|
||||
#define KW_STATIC 356
|
||||
#define KW_STATIC_ASSERT 357
|
||||
#define KW_STATIC_CAST 358
|
||||
#define KW_STRUCT 359
|
||||
#define KW_TEMPLATE 360
|
||||
#define KW_THREAD_LOCAL 361
|
||||
#define KW_THROW 362
|
||||
#define KW_TRUE 363
|
||||
#define KW_TRY 364
|
||||
#define KW_TYPEDEF 365
|
||||
#define KW_TYPEID 366
|
||||
#define KW_TYPENAME 367
|
||||
#define KW_UNION 368
|
||||
#define KW_UNSIGNED 369
|
||||
#define KW_USING 370
|
||||
#define KW_VIRTUAL 371
|
||||
#define KW_VOID 372
|
||||
#define KW_VOLATILE 373
|
||||
#define KW_WCHAR_T 374
|
||||
#define KW_WHILE 375
|
||||
#define START_CPP 376
|
||||
#define START_CONST_EXPR 377
|
||||
#define START_TYPE 378
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -58,6 +58,29 @@ CPPEnumType(CPPIdentifier *ident, CPPType *element_type,
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPEnumType::get_element_type
|
||||
// Access: Public
|
||||
// Description: Returns the integral type used to store enum values.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPType *CPPEnumType::
|
||||
get_element_type() {
|
||||
if (_element_type == NULL) {
|
||||
// This enum is untyped. Use a suitable default, ie. 'int'.
|
||||
// In the future, we might want to check whether it fits in an int.
|
||||
static CPPType *default_element_type = NULL;
|
||||
if (default_element_type == NULL) {
|
||||
default_element_type =
|
||||
CPPType::new_type(new CPPConstType(new CPPSimpleType(CPPSimpleType::T_int, 0)));
|
||||
}
|
||||
|
||||
return default_element_type;
|
||||
} else {
|
||||
// This enum has an explicit type, so use that.
|
||||
return CPPType::new_type(new CPPConstType(_element_type));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPEnumType::add_element
|
||||
// Access: Public
|
||||
|
|
@ -67,22 +90,8 @@ CPPInstance *CPPEnumType::
|
|||
add_element(const string &name, CPPExpression *value) {
|
||||
CPPIdentifier *ident = new CPPIdentifier(name);
|
||||
ident->_native_scope = _parent_scope;
|
||||
CPPInstance *inst;
|
||||
|
||||
static CPPType *default_element_type = NULL;
|
||||
if (_element_type == NULL) {
|
||||
// This enum is untyped. Use a suitable default, ie. 'int'.
|
||||
if (default_element_type == NULL) {
|
||||
default_element_type =
|
||||
CPPType::new_type(new CPPConstType(new CPPSimpleType(CPPSimpleType::T_int, 0)));
|
||||
}
|
||||
|
||||
inst = new CPPInstance(default_element_type, ident);
|
||||
} else {
|
||||
// This enum has an explicit type, so use that.
|
||||
inst = new CPPInstance(CPPType::new_type(new CPPConstType(_element_type)), ident);
|
||||
}
|
||||
|
||||
CPPInstance *inst = new CPPInstance(get_element_type(), ident);
|
||||
inst->_storage_class |= CPPInstance::SC_constexpr;
|
||||
_elements.push_back(inst);
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public:
|
|||
CPPEnumType(CPPIdentifier *ident, CPPType *element_type,
|
||||
CPPScope *current_scope, const CPPFile &file);
|
||||
|
||||
CPPType *get_element_type();
|
||||
|
||||
CPPInstance *add_element(const string &name,
|
||||
CPPExpression *value = (CPPExpression *)NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -356,9 +356,10 @@ CPPExpression(int trinary_operator, CPPExpression *op1, CPPExpression *op2,
|
|||
// operation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPExpression CPPExpression::
|
||||
typecast_op(CPPType *type, CPPExpression *op1) {
|
||||
typecast_op(CPPType *type, CPPExpression *op1, Type cast_type) {
|
||||
assert(cast_type >= T_typecast && cast_type <= T_reinterpret_cast);
|
||||
CPPExpression expr(0);
|
||||
expr._type = T_typecast;
|
||||
expr._type = cast_type;
|
||||
expr._u._typecast._to = type;
|
||||
expr._u._typecast._op1 = op1;
|
||||
return expr;
|
||||
|
|
@ -410,6 +411,36 @@ new_op(CPPType *type, CPPExpression *op1) {
|
|||
return expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPExpression::named typeid_op constructor
|
||||
// Access: Public, Static
|
||||
// Description: Creates an expression that represents a use of the
|
||||
// typeid operator.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPExpression CPPExpression::
|
||||
typeid_op(CPPType *type, CPPType *std_type_info) {
|
||||
CPPExpression expr(0);
|
||||
expr._type = T_typeid_type;
|
||||
expr._u._typeid._type = type;
|
||||
expr._u._typeid._std_type_info = std_type_info;
|
||||
return expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPExpression::named typeid_op constructor
|
||||
// Access: Public, Static
|
||||
// Description: Creates an expression that represents a use of the
|
||||
// typeid operator.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPExpression CPPExpression::
|
||||
typeid_op(CPPExpression *op1, CPPType *std_type_info) {
|
||||
CPPExpression expr(0);
|
||||
expr._type = T_typeid_expr;
|
||||
expr._u._typeid._expr = op1;
|
||||
expr._u._typeid._std_type_info = std_type_info;
|
||||
return expr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPExpression::named sizeof_func constructor
|
||||
// Access: Public, Static
|
||||
|
|
@ -591,6 +622,10 @@ evaluate() const {
|
|||
return Result();
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
assert(_u._typecast._op1 != NULL);
|
||||
r1 = _u._typecast._op1->evaluate();
|
||||
if (r1._type != RT_error) {
|
||||
|
|
@ -706,6 +741,9 @@ evaluate() const {
|
|||
case UNARY_MINUS:
|
||||
return (r1._type == RT_real) ? Result(-r1.as_real()) : Result(-r1.as_integer());
|
||||
|
||||
case UNARY_PLUS:
|
||||
return r1;
|
||||
|
||||
case UNARY_STAR:
|
||||
case UNARY_REF:
|
||||
return Result();
|
||||
|
|
@ -835,6 +873,10 @@ evaluate() const {
|
|||
case T_raw_literal:
|
||||
return Result();
|
||||
|
||||
case T_typeid_type:
|
||||
case T_typeid_expr:
|
||||
return Result();
|
||||
|
||||
default:
|
||||
cerr << "**invalid operand**\n";
|
||||
abort();
|
||||
|
|
@ -940,6 +982,10 @@ determine_type() const {
|
|||
return (CPPType *)NULL;
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_default_construct:
|
||||
return _u._typecast._to;
|
||||
|
|
@ -973,7 +1019,34 @@ determine_type() const {
|
|||
return int_type;
|
||||
|
||||
case UNARY_MINUS:
|
||||
return t1;
|
||||
case UNARY_PLUS:
|
||||
if (t1 != NULL) {
|
||||
switch (t1->get_subtype()) {
|
||||
case CPPDeclaration::ST_array:
|
||||
// Decay into pointer.
|
||||
return CPPType::new_type(new CPPPointerType(t1->as_array_type()->_element_type));
|
||||
|
||||
case CPPDeclaration::ST_enum:
|
||||
// Convert into integral type.
|
||||
return t1->as_enum_type()->get_element_type();
|
||||
|
||||
case CPPDeclaration::ST_simple:
|
||||
{
|
||||
CPPSimpleType *simple_type = t1->as_simple_type();
|
||||
if ((simple_type->_flags & CPPSimpleType::F_short) != 0 ||
|
||||
simple_type->_type == CPPSimpleType::T_bool ||
|
||||
simple_type->_type == CPPSimpleType::T_wchar_t ||
|
||||
simple_type->_type == CPPSimpleType::T_char16_t) {
|
||||
// Integer promotion.
|
||||
return int_type;
|
||||
}
|
||||
}
|
||||
// Fall through.
|
||||
default:
|
||||
return t1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
case UNARY_STAR:
|
||||
case '[': // Array element reference
|
||||
|
|
@ -1059,6 +1132,10 @@ determine_type() const {
|
|||
}
|
||||
return NULL;
|
||||
|
||||
case T_typeid_type:
|
||||
case T_typeid_expr:
|
||||
return _u._typeid._std_type_info;
|
||||
|
||||
default:
|
||||
cerr << "**invalid operand**\n";
|
||||
abort();
|
||||
|
|
@ -1103,6 +1180,10 @@ is_fully_specified() const {
|
|||
return _u._ident->is_fully_specified();
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
return (_u._typecast._to->is_fully_specified() &&
|
||||
|
|
@ -1136,6 +1217,12 @@ is_fully_specified() const {
|
|||
case T_raw_literal:
|
||||
return _u._literal._value->is_fully_specified();
|
||||
|
||||
case T_typeid_type:
|
||||
return _u._typeid._type->is_fully_specified();
|
||||
|
||||
case T_typeid_expr:
|
||||
return _u._typeid._expr->is_fully_specified();
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1215,6 +1302,10 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
break;
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
rep->_u._typecast._op1 =
|
||||
|
|
@ -1254,6 +1345,20 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
any_changed = any_changed || (rep->_u._op._op1 != _u._op._op1);
|
||||
break;
|
||||
|
||||
case T_typeid_type:
|
||||
rep->_u._typeid._type =
|
||||
_u._typeid._type->substitute_decl(subst, current_scope, global_scope)
|
||||
->as_type();
|
||||
any_changed = any_changed || (rep->_u._typeid._type != _u._typeid._type);
|
||||
break;
|
||||
|
||||
case T_typeid_expr:
|
||||
rep->_u._typeid._expr =
|
||||
_u._typeid._expr->substitute_decl(subst, current_scope, global_scope)
|
||||
->as_expression();
|
||||
any_changed = any_changed || (rep->_u._typeid._expr != _u._typeid._expr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1295,6 +1400,10 @@ is_tbd() const {
|
|||
return true;
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
case T_default_construct:
|
||||
|
|
@ -1321,6 +1430,12 @@ is_tbd() const {
|
|||
}
|
||||
return false;
|
||||
|
||||
case T_typeid_type:
|
||||
return _u._typeid._type->is_tbd();
|
||||
|
||||
case T_typeid_expr:
|
||||
return _u._typeid._expr->is_tbd();
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1450,6 +1565,38 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
out << ")";
|
||||
break;
|
||||
|
||||
case T_static_cast:
|
||||
out << "static_cast<";
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << ">(";
|
||||
_u._typecast._op1->output(out, indent_level, scope, false);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case T_dynamic_cast:
|
||||
out << "dynamic_cast<";
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << ">(";
|
||||
_u._typecast._op1->output(out, indent_level, scope, false);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case T_const_cast:
|
||||
out << "const_cast<";
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << ">(";
|
||||
_u._typecast._op1->output(out, indent_level, scope, false);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case T_reinterpret_cast:
|
||||
out << "reinterpret_cast<";
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << ">(";
|
||||
_u._typecast._op1->output(out, indent_level, scope, false);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case T_construct:
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << "(";
|
||||
|
|
@ -1507,6 +1654,11 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
_u._op._op1->output(out, indent_level, scope, false);
|
||||
break;
|
||||
|
||||
case UNARY_PLUS:
|
||||
out << '+';
|
||||
_u._op._op1->output(out, indent_level, scope, false);
|
||||
break;
|
||||
|
||||
case UNARY_STAR:
|
||||
out << "(* ";
|
||||
_u._op._op1->output(out, indent_level, scope, false);
|
||||
|
|
@ -1599,11 +1751,9 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
break;
|
||||
|
||||
case '.':
|
||||
out << "(";
|
||||
_u._op._op1->output(out, indent_level, scope, false);
|
||||
out << ".";
|
||||
_u._op._op2->output(out, indent_level, scope, false);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case POINTSAT:
|
||||
|
|
@ -1671,6 +1821,18 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
}
|
||||
break;
|
||||
|
||||
case T_typeid_type:
|
||||
out << "typeid(";
|
||||
_u._typeid._type->output(out, indent_level, scope, false);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case T_typeid_expr:
|
||||
out << "typeid(";
|
||||
_u._typeid._expr->output(out, indent_level, scope, false);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case T_default:
|
||||
out << "default";
|
||||
break;
|
||||
|
|
@ -1802,6 +1964,10 @@ is_equal(const CPPDeclaration *other) const {
|
|||
return *_u._ident == *ot->_u._ident;
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
return _u._typecast._to == ot->_u._typecast._to &&
|
||||
|
|
@ -1832,6 +1998,12 @@ is_equal(const CPPDeclaration *other) const {
|
|||
return _str == ot->_str &&
|
||||
_u._literal._operator == ot->_u._literal._operator;
|
||||
|
||||
case T_typeid_type:
|
||||
return _u._typeid._type == ot->_u._typeid._type;
|
||||
|
||||
case T_typeid_expr:
|
||||
return _u._typeid._expr == ot->_u._typeid._expr;
|
||||
|
||||
default:
|
||||
cerr << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
@ -1885,6 +2057,10 @@ is_less(const CPPDeclaration *other) const {
|
|||
return *_u._ident < *ot->_u._ident;
|
||||
|
||||
case T_typecast:
|
||||
case T_static_cast:
|
||||
case T_dynamic_cast:
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
if (_u._typecast._to != ot->_u._typecast._to) {
|
||||
|
|
@ -1925,6 +2101,12 @@ is_less(const CPPDeclaration *other) const {
|
|||
}
|
||||
return _str < ot->_str;
|
||||
|
||||
case T_typeid_type:
|
||||
return _u._typeid._type < ot->_u._typeid._type;
|
||||
|
||||
case T_typeid_expr:
|
||||
return *_u._typeid._expr < *ot->_u._typeid._expr;
|
||||
|
||||
default:
|
||||
cerr << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,43 @@ class CPPFunctionGroup;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class CPPExpression : public CPPDeclaration {
|
||||
public:
|
||||
enum Type {
|
||||
T_nullptr,
|
||||
T_boolean,
|
||||
T_integer,
|
||||
T_real,
|
||||
T_string,
|
||||
T_wstring,
|
||||
T_u8string,
|
||||
T_u16string,
|
||||
T_u32string,
|
||||
T_variable,
|
||||
T_function,
|
||||
T_unknown_ident,
|
||||
T_typecast,
|
||||
T_static_cast,
|
||||
T_dynamic_cast,
|
||||
T_const_cast,
|
||||
T_reinterpret_cast,
|
||||
T_construct,
|
||||
T_default_construct,
|
||||
T_new,
|
||||
T_default_new,
|
||||
T_sizeof,
|
||||
T_alignof,
|
||||
T_unary_operation,
|
||||
T_binary_operation,
|
||||
T_trinary_operation,
|
||||
T_literal,
|
||||
T_raw_literal,
|
||||
T_typeid_type,
|
||||
T_typeid_expr,
|
||||
|
||||
// These are used when parsing =default and =delete methods.
|
||||
T_default,
|
||||
T_delete,
|
||||
};
|
||||
|
||||
CPPExpression(bool value);
|
||||
CPPExpression(unsigned long long value);
|
||||
CPPExpression(int value);
|
||||
|
|
@ -41,9 +78,11 @@ public:
|
|||
CPPExpression(int binary_operator, CPPExpression *op1, CPPExpression *op2);
|
||||
CPPExpression(int trinary_operator, CPPExpression *op1, CPPExpression *op2, CPPExpression *op3);
|
||||
|
||||
static CPPExpression typecast_op(CPPType *type, CPPExpression *op1);
|
||||
static CPPExpression typecast_op(CPPType *type, CPPExpression *op1, Type cast_type = T_typecast);
|
||||
static CPPExpression construct_op(CPPType *type, CPPExpression *op1);
|
||||
static CPPExpression new_op(CPPType *type, CPPExpression *op1 = NULL);
|
||||
static CPPExpression typeid_op(CPPType *type, CPPType *std_type_info);
|
||||
static CPPExpression typeid_op(CPPExpression *op1, CPPType *std_type_info);
|
||||
static CPPExpression sizeof_func(CPPType *type);
|
||||
static CPPExpression alignof_func(CPPType *type);
|
||||
|
||||
|
|
@ -102,38 +141,6 @@ public:
|
|||
|
||||
virtual CPPExpression *as_expression();
|
||||
|
||||
|
||||
enum Type {
|
||||
T_nullptr,
|
||||
T_boolean,
|
||||
T_integer,
|
||||
T_real,
|
||||
T_string,
|
||||
T_wstring,
|
||||
T_u8string,
|
||||
T_u16string,
|
||||
T_u32string,
|
||||
T_variable,
|
||||
T_function,
|
||||
T_unknown_ident,
|
||||
T_typecast,
|
||||
T_construct,
|
||||
T_default_construct,
|
||||
T_new,
|
||||
T_default_new,
|
||||
T_sizeof,
|
||||
T_alignof,
|
||||
T_unary_operation,
|
||||
T_binary_operation,
|
||||
T_trinary_operation,
|
||||
T_literal,
|
||||
T_raw_literal,
|
||||
|
||||
// These are used when parsing =default and =delete methods.
|
||||
T_default,
|
||||
T_delete,
|
||||
};
|
||||
|
||||
Type _type;
|
||||
string _str;
|
||||
union {
|
||||
|
|
@ -143,13 +150,18 @@ public:
|
|||
CPPInstance *_variable;
|
||||
CPPFunctionGroup *_fgroup;
|
||||
CPPIdentifier *_ident;
|
||||
class {
|
||||
public:
|
||||
struct {
|
||||
union {
|
||||
CPPType *_type;
|
||||
CPPExpression *_expr;
|
||||
};
|
||||
CPPType *_std_type_info;
|
||||
} _typeid;
|
||||
struct {
|
||||
CPPType *_to;
|
||||
CPPExpression *_op1;
|
||||
} _typecast;
|
||||
class {
|
||||
public:
|
||||
struct {
|
||||
// One of the yytoken values: a character, or something
|
||||
// like EQCOMPARE.
|
||||
int _operator;
|
||||
|
|
@ -157,8 +169,7 @@ public:
|
|||
CPPExpression *_op2;
|
||||
CPPExpression *_op3;
|
||||
} _op;
|
||||
class {
|
||||
public:
|
||||
struct {
|
||||
CPPInstance *_operator;
|
||||
CPPExpression *_value;
|
||||
} _literal;
|
||||
|
|
|
|||
|
|
@ -214,10 +214,10 @@ is_equivalent(const CPPType &other) const {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CPPExtensionType::
|
||||
output(ostream &out, int, CPPScope *scope, bool) const {
|
||||
output(ostream &out, int, CPPScope *scope, bool complete) const {
|
||||
if (_ident != NULL) {
|
||||
// If we have a name, use it.
|
||||
if (cppparser_output_class_keyword) {
|
||||
if (complete || cppparser_output_class_keyword) {
|
||||
out << _type << " ";
|
||||
}
|
||||
out << _ident->get_local_name(scope);
|
||||
|
|
|
|||
|
|
@ -193,12 +193,44 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
|||
void CPPFunctionType::
|
||||
output(ostream &out, int indent_level, CPPScope *scope, bool complete,
|
||||
int num_default_parameters) const {
|
||||
_return_type->output(out, indent_level, scope, complete);
|
||||
out << "(";
|
||||
_parameters->output(out, scope, true, num_default_parameters);
|
||||
out << ")";
|
||||
if (_flags & F_const_method) {
|
||||
out << " const";
|
||||
|
||||
if (_flags & F_trailing_return_type) {
|
||||
// It was declared using trailing return type, so let's format it that way.
|
||||
out << "auto(";
|
||||
_parameters->output(out, scope, true, num_default_parameters);
|
||||
out << ")";
|
||||
if (_flags & F_const_method) {
|
||||
out << " const";
|
||||
}
|
||||
if (_flags & F_noexcept) {
|
||||
out << " noexcept";
|
||||
}
|
||||
if (_flags & F_final) {
|
||||
out << " final";
|
||||
}
|
||||
if (_flags & F_override) {
|
||||
out << " override";
|
||||
}
|
||||
out << " -> ";
|
||||
_return_type->output(out, indent_level, scope, false);
|
||||
|
||||
} else {
|
||||
_return_type->output(out, indent_level, scope, complete);
|
||||
out << "(";
|
||||
_parameters->output(out, scope, true, num_default_parameters);
|
||||
out << ")";
|
||||
if (_flags & F_const_method) {
|
||||
out << " const";
|
||||
}
|
||||
if (_flags & F_noexcept) {
|
||||
out << " noexcept";
|
||||
}
|
||||
if (_flags & F_final) {
|
||||
out << " final";
|
||||
}
|
||||
if (_flags & F_override) {
|
||||
out << " override";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,6 +273,18 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
|
|||
// No return type for constructors and destructors.
|
||||
out << prename << name << str;
|
||||
|
||||
} else if (_flags & F_trailing_return_type) {
|
||||
// It was declared using trailing return type, so let's format it that way.
|
||||
out << "auto ";
|
||||
|
||||
if (prename.empty()) {
|
||||
out << name;
|
||||
} else {
|
||||
out << "(" << prename << name << ")";
|
||||
}
|
||||
|
||||
out << str;
|
||||
|
||||
} else {
|
||||
if (prename.empty()) {
|
||||
_return_type->output_instance(out, indent_level, scope, complete,
|
||||
|
|
@ -257,6 +301,17 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
|
|||
if (_flags & F_noexcept) {
|
||||
out << " noexcept";
|
||||
}
|
||||
if (_flags & F_final) {
|
||||
out << " final";
|
||||
}
|
||||
if (_flags & F_override) {
|
||||
out << " override";
|
||||
}
|
||||
|
||||
if (_flags & F_trailing_return_type) {
|
||||
out << " -> ";
|
||||
_return_type->output(out, indent_level, scope, false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ public:
|
|||
F_noexcept = 0x080,
|
||||
F_copy_constructor = 0x200,
|
||||
F_move_constructor = 0x400,
|
||||
F_trailing_return_type = 0x800,
|
||||
F_final = 0x1000,
|
||||
F_override = 0x2000,
|
||||
};
|
||||
|
||||
CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ CPPInstance(CPPType *type, const string &name, int storage_class) :
|
|||
_type(type),
|
||||
_ident(new CPPIdentifier(name)),
|
||||
_storage_class(storage_class),
|
||||
_alignment(NULL)
|
||||
_alignment(NULL),
|
||||
_bit_width(-1)
|
||||
{
|
||||
_initializer = NULL;
|
||||
}
|
||||
|
|
@ -55,7 +56,8 @@ CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class) :
|
|||
_type(type),
|
||||
_ident(ident),
|
||||
_storage_class(storage_class),
|
||||
_alignment(NULL)
|
||||
_alignment(NULL),
|
||||
_bit_width(-1)
|
||||
{
|
||||
_initializer = NULL;
|
||||
}
|
||||
|
|
@ -79,6 +81,7 @@ CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
|
|||
ii->_ident = NULL;
|
||||
_storage_class = storage_class;
|
||||
_initializer = NULL;
|
||||
_bit_width = ii->_bit_width;
|
||||
|
||||
CPPParameterList *params = ii->get_initializer();
|
||||
if (params != (CPPParameterList *)NULL) {
|
||||
|
|
@ -106,7 +109,8 @@ CPPInstance(const CPPInstance ©) :
|
|||
_ident(copy._ident),
|
||||
_initializer(copy._initializer),
|
||||
_storage_class(copy._storage_class),
|
||||
_alignment(copy._alignment)
|
||||
_alignment(copy._alignment),
|
||||
_bit_width(copy._bit_width)
|
||||
{
|
||||
assert(_type != NULL);
|
||||
}
|
||||
|
|
@ -612,6 +616,9 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
|
|||
if (_storage_class & SC_constexpr) {
|
||||
out << "constexpr ";
|
||||
}
|
||||
if (_storage_class & SC_thread_local) {
|
||||
out << "thread_local ";
|
||||
}
|
||||
|
||||
string name;
|
||||
if (_ident != NULL) {
|
||||
|
|
@ -627,6 +634,10 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
|
|||
_type->output_instance(out, indent_level, scope, complete, "", name);
|
||||
}
|
||||
|
||||
if (_bit_width != -1) {
|
||||
out << " : " << _bit_width;
|
||||
}
|
||||
|
||||
if (_storage_class & SC_pure_virtual) {
|
||||
out << " = 0";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ public:
|
|||
// These are for =default and =delete functions.
|
||||
SC_defaulted = 0x4000,
|
||||
SC_deleted = 0x8000,
|
||||
|
||||
SC_thread_local = 0x10000,
|
||||
};
|
||||
|
||||
CPPInstance(CPPType *type, const string &name, int storage_class = 0);
|
||||
|
|
@ -119,6 +121,7 @@ public:
|
|||
|
||||
int _storage_class;
|
||||
CPPExpression *_alignment;
|
||||
int _bit_width;
|
||||
|
||||
private:
|
||||
typedef map<const CPPTemplateParameterList *, CPPInstance *, CPPTPLCompare> Instantiations;
|
||||
|
|
|
|||
|
|
@ -43,10 +43,11 @@ Modifier(CPPInstanceIdentifierType type) :
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
|
||||
func_type(CPPParameterList *params, int flags) {
|
||||
func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
|
||||
Modifier mod(IIT_func);
|
||||
mod._func_params = params;
|
||||
mod._func_flags = flags;
|
||||
mod._trailing_return_type = trailing_return_type;
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +94,9 @@ initializer_type(CPPParameterList *params) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPInstanceIdentifier::
|
||||
CPPInstanceIdentifier(CPPIdentifier *ident) : _ident(ident) {
|
||||
CPPInstanceIdentifier(CPPIdentifier *ident) :
|
||||
_ident(ident),
|
||||
_bit_width(-1) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -128,7 +131,7 @@ add_modifier(CPPInstanceIdentifierType type) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CPPInstanceIdentifier::
|
||||
add_func_modifier(CPPParameterList *params, int flags) {
|
||||
add_func_modifier(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
|
||||
// As a special hack, if we added a parameter list to an operator
|
||||
// function, check if the parameter list is empty. If it is, this
|
||||
// is really a unary operator, so set the unary_op flag. Operators
|
||||
|
|
@ -146,7 +149,12 @@ add_func_modifier(CPPParameterList *params, int flags) {
|
|||
flags |= CPPFunctionType::F_operator;
|
||||
}
|
||||
|
||||
_modifiers.push_back(Modifier::func_type(params, flags));
|
||||
if (trailing_return_type != NULL) {
|
||||
// Remember whether trailing return type notation was used.
|
||||
flags |= CPPFunctionType::F_trailing_return_type;
|
||||
}
|
||||
|
||||
_modifiers.push_back(Modifier::func_type(params, flags, trailing_return_type));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -188,6 +196,25 @@ add_initializer_modifier(CPPParameterList *params) {
|
|||
_modifiers.push_back(Modifier::initializer_type(params));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPInstanceIdentifier::add_trailing_return_type
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CPPInstanceIdentifier::
|
||||
add_trailing_return_type(CPPType *type) {
|
||||
// This is an awkward hack. Improve in the future.
|
||||
if (!_modifiers.empty()) {
|
||||
Modifier &mod = _modifiers.back();
|
||||
if (mod._type == IIT_func) {
|
||||
mod._trailing_return_type = type;
|
||||
mod._func_flags |= CPPFunctionType::F_trailing_return_type;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cerr << "trailing return type can only be added to a function\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPInstanceIdentifier::get_initializer
|
||||
// Access: Public
|
||||
|
|
@ -237,6 +264,8 @@ get_scope(CPPScope *current_scope, CPPScope *global_scope,
|
|||
CPPType *CPPInstanceIdentifier::
|
||||
r_unroll_type(CPPType *start_type,
|
||||
CPPInstanceIdentifier::Modifiers::const_iterator mi) {
|
||||
assert(start_type != NULL);
|
||||
|
||||
start_type = CPPType::new_type(start_type);
|
||||
|
||||
if (mi == _modifiers.end()) {
|
||||
|
|
@ -298,6 +327,14 @@ r_unroll_type(CPPType *start_type,
|
|||
case IIT_func:
|
||||
{
|
||||
CPPType *return_type = r_unroll_type(start_type, mi);
|
||||
if (mod._trailing_return_type != (CPPType *)NULL) {
|
||||
CPPSimpleType *simple_type = return_type->as_simple_type();
|
||||
if (simple_type != NULL && simple_type->_type == CPPSimpleType::T_auto) {
|
||||
return_type = mod._trailing_return_type;
|
||||
} else {
|
||||
cerr << "function with trailing return type needs auto\n";
|
||||
}
|
||||
}
|
||||
result = new CPPFunctionType(return_type, mod._func_params,
|
||||
mod._func_flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,11 +57,14 @@ public:
|
|||
CPPType *unroll_type(CPPType *start_type);
|
||||
|
||||
void add_modifier(CPPInstanceIdentifierType type);
|
||||
void add_func_modifier(CPPParameterList *params, int flags);
|
||||
void add_func_modifier(CPPParameterList *params, int flags,
|
||||
CPPType *trailing_return_type = NULL);
|
||||
void add_scoped_pointer_modifier(CPPIdentifier *scoping);
|
||||
void add_array_modifier(CPPExpression *expr);
|
||||
void add_initializer_modifier(CPPParameterList *params);
|
||||
|
||||
void add_trailing_return_type(CPPType *type);
|
||||
|
||||
CPPParameterList *get_initializer() const;
|
||||
|
||||
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
|
||||
|
|
@ -72,7 +75,8 @@ public:
|
|||
class Modifier {
|
||||
public:
|
||||
Modifier(CPPInstanceIdentifierType type);
|
||||
static Modifier func_type(CPPParameterList *params, int flags);
|
||||
static Modifier func_type(CPPParameterList *params, int flags,
|
||||
CPPType *trailing_return_type);
|
||||
static Modifier array_type(CPPExpression *expr);
|
||||
static Modifier scoped_pointer_type(CPPIdentifier *scoping);
|
||||
static Modifier initializer_type(CPPParameterList *params);
|
||||
|
|
@ -82,10 +86,13 @@ public:
|
|||
int _func_flags;
|
||||
CPPIdentifier *_scoping;
|
||||
CPPExpression *_expr;
|
||||
CPPType *_trailing_return_type;
|
||||
};
|
||||
typedef vector<Modifier> Modifiers;
|
||||
Modifiers _modifiers;
|
||||
|
||||
int _bit_width;
|
||||
|
||||
private:
|
||||
CPPType *
|
||||
r_unroll_type(CPPType *start_type, Modifiers::const_iterator mi);
|
||||
|
|
|
|||
|
|
@ -1367,6 +1367,50 @@ skip_cpp_comment(int c) {
|
|||
return c;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPPreprocessor::skip_digit_separator
|
||||
// Access: Private
|
||||
// Description: Skips a C++14 digit separator that has just been
|
||||
// found through peek().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int CPPPreprocessor::
|
||||
skip_digit_separator(int c) {
|
||||
if (c != '\'') {
|
||||
return c;
|
||||
}
|
||||
|
||||
get();
|
||||
c = peek();
|
||||
|
||||
if (isdigit(c)) {
|
||||
return c;
|
||||
}
|
||||
|
||||
YYLTYPE loc;
|
||||
loc.file = get_file();
|
||||
loc.first_line = get_line_number();
|
||||
loc.first_column = get_col_number();
|
||||
loc.last_line = loc.first_line;
|
||||
loc.last_column = loc.first_column;
|
||||
|
||||
if (c != '\'') {
|
||||
// This assumes that this isn't a character constant directly follows
|
||||
// a digit sequence, like 123'a' -- I can't think of a situation
|
||||
// where that's legal anyway, though.
|
||||
error("digit separator cannot occur at end of digit sequence", loc);
|
||||
return c;
|
||||
}
|
||||
|
||||
while (c == '\'') {
|
||||
get();
|
||||
++loc.last_column;
|
||||
c = peek();
|
||||
}
|
||||
error("adjacent digit separators", loc);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPPreprocessor::process_directive
|
||||
// Access: Private
|
||||
|
|
@ -2395,7 +2439,8 @@ extract_manifest_args_inline(const string &name, int num_args,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPPreprocessor::get_number
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description: Assuming that we've just read a digit or a period
|
||||
// indicating the start of a number, read the rest.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPToken CPPPreprocessor::
|
||||
get_number(int c) {
|
||||
|
|
@ -2410,16 +2455,16 @@ get_number(int c) {
|
|||
bool leading_zero = (c == '0');
|
||||
bool decimal_point = (c == '.');
|
||||
|
||||
c = peek();
|
||||
c = skip_digit_separator(peek());
|
||||
|
||||
if (leading_zero && c == 'x') {
|
||||
if (leading_zero && (c == 'x' || c == 'X')) {
|
||||
// Here we have a hex number.
|
||||
num += get();
|
||||
c = peek();
|
||||
|
||||
while (c != EOF && (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f'))) {
|
||||
num += get();
|
||||
c = peek();
|
||||
c = skip_digit_separator(peek());
|
||||
}
|
||||
|
||||
loc.last_line = get_line_number();
|
||||
|
|
@ -2429,11 +2474,30 @@ get_number(int c) {
|
|||
result.u.integer = strtol(num.c_str(), (char **)NULL, 16);
|
||||
|
||||
return get_literal(INTEGER, loc, num, result);
|
||||
|
||||
} else if (leading_zero && (c == 'b' || c == 'B')) {
|
||||
// A C++14-style binary number.
|
||||
get();
|
||||
c = peek();
|
||||
string bin(1, (char)c);
|
||||
|
||||
while (c != EOF && (c == '0' || c == '1')) {
|
||||
bin += get();
|
||||
c = skip_digit_separator(peek());
|
||||
}
|
||||
|
||||
loc.last_line = get_line_number();
|
||||
loc.last_column = get_col_number();
|
||||
|
||||
YYSTYPE result;
|
||||
result.u.integer = strtol(bin.c_str(), (char **)NULL, 2);
|
||||
|
||||
return get_literal(INTEGER, loc, bin, result);
|
||||
}
|
||||
|
||||
while (c != EOF && isdigit(c)) {
|
||||
num += get();
|
||||
c = peek();
|
||||
c = skip_digit_separator(peek());
|
||||
}
|
||||
|
||||
if (c == '.' && !decimal_point) {
|
||||
|
|
@ -2459,7 +2523,7 @@ get_number(int c) {
|
|||
}
|
||||
while (c != EOF && isdigit(c)) {
|
||||
num += get();
|
||||
c = peek();
|
||||
c = skip_digit_separator(peek());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2517,6 +2581,7 @@ check_keyword(const string &name) {
|
|||
if (name == "__const") return KW_CONST;
|
||||
if (name == "__const__") return KW_CONST;
|
||||
if (name == "constexpr") return KW_CONSTEXPR;
|
||||
if (name == "const_cast") return KW_CONST_CAST;
|
||||
if (name == "decltype") return KW_DECLTYPE;
|
||||
if (name == "default") return KW_DEFAULT;
|
||||
if (name == "delete") return KW_DELETE;
|
||||
|
|
@ -2530,6 +2595,7 @@ check_keyword(const string &name) {
|
|||
if (name == "explicit") return KW_EXPLICIT;
|
||||
if (name == "__published") return KW_PUBLISHED;
|
||||
if (name == "false") return KW_FALSE;
|
||||
if (name == "final") return KW_FINAL;
|
||||
if (name == "float") return KW_FLOAT;
|
||||
if (name == "friend") return KW_FRIEND;
|
||||
if (name == "for") return KW_FOR;
|
||||
|
|
@ -2549,10 +2615,12 @@ check_keyword(const string &name) {
|
|||
if (name == "nullptr") return KW_NULLPTR;
|
||||
if (name == "new") return KW_NEW;
|
||||
if (name == "operator") return KW_OPERATOR;
|
||||
if (name == "override") return KW_OVERRIDE;
|
||||
if (name == "private") return KW_PRIVATE;
|
||||
if (name == "protected") return KW_PROTECTED;
|
||||
if (name == "public") return KW_PUBLIC;
|
||||
if (name == "register") return KW_REGISTER;
|
||||
if (name == "reinterpret_cast") return KW_REINTERPRET_CAST;
|
||||
if (name == "return") return KW_RETURN;
|
||||
if (name == "short") return KW_SHORT;
|
||||
if (name == "signed") return KW_SIGNED;
|
||||
|
|
@ -2562,10 +2630,12 @@ check_keyword(const string &name) {
|
|||
if (name == "static_cast") return KW_STATIC_CAST;
|
||||
if (name == "struct") return KW_STRUCT;
|
||||
if (name == "template") return KW_TEMPLATE;
|
||||
if (name == "thread_local") return KW_THREAD_LOCAL;
|
||||
if (name == "throw") return KW_THROW;
|
||||
if (name == "true") return KW_TRUE;
|
||||
if (name == "try") return KW_TRY;
|
||||
if (name == "typedef") return KW_TYPEDEF;
|
||||
if (name == "typeid") return KW_TYPEID;
|
||||
if (name == "typename") return KW_TYPENAME;
|
||||
if (name == "union") return KW_UNION;
|
||||
if (name == "unsigned") return KW_UNSIGNED;
|
||||
|
|
@ -2589,10 +2659,6 @@ check_keyword(const string &name) {
|
|||
if (name == "xor") return '^';
|
||||
if (name == "xor_eq") return XOREQUAL;
|
||||
|
||||
if (!cpp_longlong_keyword.empty() && name == cpp_longlong_keyword) {
|
||||
return KW_LONGLONG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ private:
|
|||
int skip_comment(int c);
|
||||
int skip_c_comment(int c);
|
||||
int skip_cpp_comment(int c);
|
||||
int skip_digit_separator(int c);
|
||||
int process_directive(int c);
|
||||
|
||||
int get_preprocessor_command(int c, string &command);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ CPPStructType(CPPStructType::Type type, CPPIdentifier *ident,
|
|||
CPPScope *current_scope, CPPScope *scope,
|
||||
const CPPFile &file) :
|
||||
CPPExtensionType(type, ident, current_scope, file),
|
||||
_scope(scope)
|
||||
_scope(scope),
|
||||
_final(false)
|
||||
{
|
||||
_subst_decl_recursive_protect = false;
|
||||
_incomplete = true;
|
||||
|
|
@ -64,7 +65,8 @@ CPPStructType(const CPPStructType ©) :
|
|||
CPPExtensionType(copy),
|
||||
_scope(copy._scope),
|
||||
_incomplete(copy._incomplete),
|
||||
_derivation(copy._derivation)
|
||||
_derivation(copy._derivation),
|
||||
_final(copy._final)
|
||||
{
|
||||
_subst_decl_recursive_protect = false;
|
||||
}
|
||||
|
|
@ -80,6 +82,7 @@ operator = (const CPPStructType ©) {
|
|||
_scope = copy._scope;
|
||||
_incomplete = copy._incomplete;
|
||||
_derivation = copy._derivation;
|
||||
_final = copy._final;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -99,6 +102,15 @@ append_derivation(CPPType *base, CPPVisibility vis, bool is_virtual) {
|
|||
def = base->as_typedef_type();
|
||||
}
|
||||
|
||||
if (vis == V_unknown && base->as_extension_type() != NULL) {
|
||||
// Default visibility.
|
||||
if (base->as_extension_type()->_type == T_class) {
|
||||
vis = V_private;
|
||||
} else {
|
||||
vis = V_public;
|
||||
}
|
||||
}
|
||||
|
||||
Base b;
|
||||
b._base = base;
|
||||
b._vis = vis;
|
||||
|
|
@ -794,10 +806,14 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
|||
out << _type;
|
||||
}
|
||||
|
||||
if (_final) {
|
||||
out << " final";
|
||||
}
|
||||
|
||||
// Show any derivation we may have
|
||||
if (!_derivation.empty()) {
|
||||
Derivation::const_iterator di = _derivation.begin();
|
||||
out << ": " << *di;
|
||||
out << " : " << *di;
|
||||
++di;
|
||||
while (di != _derivation.end()) {
|
||||
out << ", " << *di;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public:
|
|||
|
||||
CPPScope *_scope;
|
||||
bool _incomplete;
|
||||
bool _final;
|
||||
|
||||
class Base {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -200,6 +200,10 @@ output(ostream &out) const {
|
|||
out << "UNARY_MINUS";
|
||||
break;
|
||||
|
||||
case UNARY_PLUS:
|
||||
out << "UNARY_PLUS";
|
||||
break;
|
||||
|
||||
case UNARY_NEGATE:
|
||||
out << "UNARY_NEGATE";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ CPPTypedefType::
|
|||
CPPTypedefType(CPPType *type, const string &name, CPPScope *current_scope) :
|
||||
CPPType(CPPFile()),
|
||||
_type(type),
|
||||
_ident(new CPPIdentifier(name))
|
||||
_ident(new CPPIdentifier(name)),
|
||||
_using(false)
|
||||
{
|
||||
if (_ident != NULL) {
|
||||
_ident->_native_scope = current_scope;
|
||||
|
|
@ -49,7 +50,8 @@ CPPTypedefType::
|
|||
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
|
||||
CPPType(CPPFile()),
|
||||
_type(type),
|
||||
_ident(ident)
|
||||
_ident(ident),
|
||||
_using(false)
|
||||
{
|
||||
if (_ident != NULL) {
|
||||
_ident->_native_scope = current_scope;
|
||||
|
|
@ -68,8 +70,10 @@ CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
|
|||
CPPTypedefType::
|
||||
CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
|
||||
CPPScope *current_scope, const CPPFile &file) :
|
||||
CPPType(file)
|
||||
CPPType(file),
|
||||
_using(false)
|
||||
{
|
||||
assert(ii != NULL);
|
||||
_type = ii->unroll_type(type);
|
||||
_ident = ii->_ident;
|
||||
ii->_ident = NULL;
|
||||
|
|
@ -363,8 +367,14 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
|||
}
|
||||
|
||||
if (complete) {
|
||||
out << "typedef ";
|
||||
_type->output_instance(out, indent_level, scope, false, "", name);
|
||||
if (_using) {
|
||||
// It was declared using the "using" keyword.
|
||||
out << "using " << name << " = ";
|
||||
_type->output(out, 0, scope, false);
|
||||
} else {
|
||||
out << "typedef ";
|
||||
_type->output_instance(out, indent_level, scope, false, "", name);
|
||||
}
|
||||
} else {
|
||||
out << name;
|
||||
}
|
||||
|
|
@ -401,7 +411,7 @@ is_equal(const CPPDeclaration *other) const {
|
|||
const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
|
||||
assert(ot != NULL);
|
||||
|
||||
return (*_type == *ot->_type) && (*_ident == *ot->_ident);
|
||||
return (*_type == *ot->_type) && (*_ident == *ot->_ident) && (_using == ot->_using);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
CPPType *_type;
|
||||
CPPIdentifier *_ident;
|
||||
bool _using;
|
||||
|
||||
protected:
|
||||
virtual bool is_equal(const CPPDeclaration *other) const;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ using namespace std;
|
|||
#define TYPENAME typename
|
||||
#define CONSTEXPR constexpr
|
||||
#define NOEXCEPT noexcept
|
||||
#define FINAL
|
||||
#define OVERRIDE
|
||||
#define FINAL final
|
||||
#define OVERRIDE override
|
||||
#define MOVE(x) x
|
||||
#define DEFAULT_CTOR = default
|
||||
|
||||
|
|
|
|||
|
|
@ -272,10 +272,6 @@ void show_help() {
|
|||
<< " function wrappers already, from some external source. This is most\n"
|
||||
<< " useful in conjunction with -true-names.\n\n"
|
||||
|
||||
<< " -longlong typename\n"
|
||||
<< " Specify the name of the 64-bit integer type for the current compiler.\n"
|
||||
<< " By default, this is \"long long\".\n\n"
|
||||
|
||||
<< " -promiscuous\n"
|
||||
<< " Export *all* public symbols, functions, and classes seen, even those\n"
|
||||
<< " not explicitly marked to be published.\n\n"
|
||||
|
|
@ -436,6 +432,7 @@ main(int argc, char **argv) {
|
|||
break;
|
||||
|
||||
case CO_longlong:
|
||||
cerr << "Warning: ignoring deprecated -longlong option.\n";
|
||||
cpp_longlong_keyword = optarg;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
class type_info;
|
||||
class bad_cast;
|
||||
class bad_typeid;
|
||||
#include <stdtypedefs.h>
|
||||
|
||||
namespace std {
|
||||
class type_info {
|
||||
public:
|
||||
type_info(const type_info& rhs) = delete;
|
||||
virtual ~type_info();
|
||||
|
||||
type_info &operator = (const type_info &rhs) = delete;
|
||||
|
||||
bool operator ==(const type_info &rhs) const noexcept;
|
||||
bool operator !=(const type_info &rhs) const noexcept;
|
||||
bool before(const type_info &rhs) const noexcept;
|
||||
size_t hash_code() const noexcept;
|
||||
const char *name() const noexcept;
|
||||
};
|
||||
|
||||
class bad_cast;
|
||||
class bad_typeid;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue