mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
cppparser: support for various C++11/C++14/C++17 features:
- decltype(auto) - attributes (ie. [[deprecated]]), incl. with C++17 "using" - extern template class (parses) - sizeof struct members - aggregate initialization - initializers in capture lists - alignas (parses)
This commit is contained in:
parent
e12420571b
commit
e2771d39a9
@ -249,6 +249,8 @@ pop_struct() {
|
||||
%token XOREQUAL
|
||||
%token LSHIFTEQUAL
|
||||
%token RSHIFTEQUAL
|
||||
%token ATTR_LEFT
|
||||
%token ATTR_RIGHT
|
||||
|
||||
%token KW_ALIGNAS
|
||||
%token KW_ALIGNOF
|
||||
@ -874,10 +876,18 @@ storage_class:
|
||||
{
|
||||
$$ = $2 | (int)CPPInstance::SC_thread_local;
|
||||
}
|
||||
| '[' '[' attribute_specifiers ']' ']' storage_class
|
||||
| ATTR_LEFT attribute_specifiers ATTR_RIGHT storage_class
|
||||
{
|
||||
// Ignore attribute specifiers for now.
|
||||
$$ = $6;
|
||||
$$ = $4;
|
||||
}
|
||||
| KW_ALIGNAS '(' const_expr ')' storage_class
|
||||
{
|
||||
$$ = $5;
|
||||
}
|
||||
| KW_ALIGNAS '(' type_decl ')' storage_class
|
||||
{
|
||||
$$ = $5;
|
||||
}
|
||||
;
|
||||
|
||||
@ -889,6 +899,7 @@ attribute_specifiers:
|
||||
attribute_specifier:
|
||||
name
|
||||
| name '(' formal_parameter_list ')'
|
||||
| KW_USING name ':' attribute_specifier
|
||||
;
|
||||
|
||||
type_like_declaration:
|
||||
@ -1272,10 +1283,10 @@ function_post:
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
/* | function_post '[' '[' attribute_specifiers ']' ']'
|
||||
| function_post ATTR_LEFT attribute_specifiers ATTR_RIGHT
|
||||
{
|
||||
$$ = $1;
|
||||
}*/
|
||||
}
|
||||
;
|
||||
|
||||
function_operator:
|
||||
@ -1443,7 +1454,8 @@ more_template_declaration:
|
||||
;
|
||||
|
||||
template_declaration:
|
||||
KW_TEMPLATE
|
||||
KW_EXTERN template_declaration
|
||||
| KW_TEMPLATE
|
||||
{
|
||||
push_scope(new CPPTemplateScope(current_scope));
|
||||
}
|
||||
@ -1451,7 +1463,7 @@ template_declaration:
|
||||
{
|
||||
pop_scope();
|
||||
}
|
||||
| KW_TEMPLATE type_like_declaration
|
||||
| KW_TEMPLATE type_like_declaration
|
||||
;
|
||||
|
||||
template_formal_parameters:
|
||||
@ -1903,6 +1915,10 @@ function_parameter:
|
||||
| KW_REGISTER function_parameter
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| ATTR_LEFT attribute_specifiers ATTR_RIGHT function_parameter
|
||||
{
|
||||
$$ = $4;
|
||||
}
|
||||
;
|
||||
|
||||
@ -2246,16 +2262,16 @@ type:
|
||||
{
|
||||
$$ = CPPType::new_type($1);
|
||||
}
|
||||
| struct_keyword name
|
||||
| struct_keyword struct_attributes name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
||||
if (scope != NULL) {
|
||||
scope->define_extension_type(et);
|
||||
}
|
||||
@ -2286,6 +2302,10 @@ type:
|
||||
str << *$3;
|
||||
yyerror("could not determine type of " + str.str(), @3);
|
||||
}
|
||||
}
|
||||
| KW_DECLTYPE '(' KW_AUTO ')'
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
|
||||
}
|
||||
| KW_UNDERLYING_TYPE '(' full_type ')'
|
||||
{
|
||||
@ -2343,16 +2363,16 @@ type_decl:
|
||||
{
|
||||
$$ = new CPPTypeDeclaration(CPPType::new_type($1));
|
||||
}
|
||||
| struct_keyword name
|
||||
| struct_keyword struct_attributes name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
||||
if (scope != NULL) {
|
||||
scope->define_extension_type(et);
|
||||
}
|
||||
@ -2401,6 +2421,10 @@ type_decl:
|
||||
str << *$3;
|
||||
yyerror("could not determine type of " + str.str(), @3);
|
||||
}
|
||||
}
|
||||
| KW_DECLTYPE '(' KW_AUTO ')'
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
|
||||
}
|
||||
| KW_UNDERLYING_TYPE '(' full_type ')'
|
||||
{
|
||||
@ -2435,16 +2459,16 @@ predefined_type:
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPTBDType($2));
|
||||
}
|
||||
| struct_keyword name
|
||||
| struct_keyword struct_attributes name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
||||
if (scope != NULL) {
|
||||
scope->define_extension_type(et);
|
||||
}
|
||||
@ -2525,8 +2549,15 @@ full_type:
|
||||
}
|
||||
;
|
||||
|
||||
struct_attributes:
|
||||
empty
|
||||
| struct_attributes ATTR_LEFT attribute_specifiers ATTR_RIGHT
|
||||
| struct_attributes KW_ALIGNAS '(' const_expr ')'
|
||||
| struct_attributes KW_ALIGNAS '(' type_decl ')'
|
||||
;
|
||||
|
||||
anonymous_struct:
|
||||
struct_keyword '{'
|
||||
struct_keyword struct_attributes '{'
|
||||
{
|
||||
CPPVisibility starting_vis =
|
||||
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
||||
@ -2550,19 +2581,19 @@ anonymous_struct:
|
||||
;
|
||||
|
||||
named_struct:
|
||||
struct_keyword name_no_final
|
||||
struct_keyword struct_attributes name_no_final
|
||||
{
|
||||
CPPVisibility starting_vis =
|
||||
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
||||
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope, current_lexer);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope, current_lexer);
|
||||
if (scope == NULL) {
|
||||
scope = current_scope;
|
||||
}
|
||||
CPPScope *new_scope = new CPPScope(scope, $2->_names.back(),
|
||||
CPPScope *new_scope = new CPPScope(scope, $3->_names.back(),
|
||||
starting_vis);
|
||||
|
||||
CPPStructType *st = new CPPStructType($1, $2, current_scope,
|
||||
CPPStructType *st = new CPPStructType($1, $3, current_scope,
|
||||
new_scope, @1.file);
|
||||
new_scope->set_struct_type(st);
|
||||
current_scope->define_extension_type(st);
|
||||
@ -2945,6 +2976,7 @@ element:
|
||||
| SCOPE | PLUSPLUS | MINUSMINUS
|
||||
| TIMESEQUAL | DIVIDEEQUAL | MODEQUAL | PLUSEQUAL | MINUSEQUAL
|
||||
| OREQUAL | ANDEQUAL | XOREQUAL | LSHIFTEQUAL | RSHIFTEQUAL
|
||||
| ATTR_LEFT | ATTR_RIGHT
|
||||
| KW_ALIGNAS | KW_ALIGNOF | KW_AUTO | KW_BOOL | KW_CATCH
|
||||
| KW_CHAR | KW_CHAR16_T | KW_CHAR32_T | KW_CLASS | KW_CONST
|
||||
| KW_CONSTEXPR | KW_CONST_CAST | KW_DECLTYPE | KW_DEFAULT
|
||||
@ -3028,6 +3060,18 @@ no_angle_bracket_const_expr:
|
||||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
||||
}
|
||||
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
||||
{
|
||||
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (arg == (CPPDeclaration *)NULL) {
|
||||
yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
|
||||
} else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
|
||||
CPPInstance *inst = arg->as_instance();
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
|
||||
} else {
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
|
||||
}
|
||||
}
|
||||
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
||||
{
|
||||
@ -3190,6 +3234,16 @@ const_expr:
|
||||
}
|
||||
assert(type != NULL);
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}'
|
||||
{
|
||||
// Aggregate initialization.
|
||||
CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert(type != NULL);
|
||||
$$ = new CPPExpression(CPPExpression::aggregate_init_op(type, $3));
|
||||
}
|
||||
| KW_INT '(' optional_const_expr_comma ')'
|
||||
{
|
||||
@ -3270,6 +3324,18 @@ const_expr:
|
||||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
||||
}
|
||||
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
||||
{
|
||||
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (arg == (CPPDeclaration *)NULL) {
|
||||
yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
|
||||
} else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
|
||||
CPPInstance *inst = arg->as_instance();
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
|
||||
} else {
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
|
||||
}
|
||||
}
|
||||
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
||||
{
|
||||
@ -3602,6 +3668,18 @@ formal_const_expr:
|
||||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
||||
}
|
||||
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
||||
{
|
||||
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (arg == (CPPDeclaration *)NULL) {
|
||||
yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
|
||||
} else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
|
||||
CPPInstance *inst = arg->as_instance();
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
|
||||
} else {
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
|
||||
}
|
||||
}
|
||||
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
||||
{
|
||||
@ -3828,15 +3906,17 @@ capture_list:
|
||||
{
|
||||
$$ = new CPPClosureType(CPPClosureType::CT_by_reference);
|
||||
}
|
||||
| capture
|
||||
| capture maybe_initialize
|
||||
{
|
||||
$$ = new CPPClosureType();
|
||||
$1->_initializer = $2;
|
||||
$$->_captures.push_back(*$1);
|
||||
delete $1;
|
||||
}
|
||||
| capture_list ',' capture
|
||||
| capture_list ',' capture maybe_initialize
|
||||
{
|
||||
$$ = $1;
|
||||
$3->_initializer = $4;
|
||||
$$->_captures.push_back(*$3);
|
||||
delete $3;
|
||||
}
|
||||
@ -3884,14 +3964,6 @@ class_derivation_name:
|
||||
type = CPPType::new_type(new CPPTBDType($1));
|
||||
}
|
||||
$$ = type;
|
||||
}
|
||||
| struct_keyword name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, true, current_lexer);
|
||||
if (type == NULL) {
|
||||
type = CPPType::new_type(new CPPTBDType($2));
|
||||
}
|
||||
$$ = type;
|
||||
}
|
||||
| KW_TYPENAME name
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "cppClosureType.h"
|
||||
#include "cppExpression.h"
|
||||
|
||||
/**
|
||||
*
|
||||
@ -47,7 +48,7 @@ operator = (const CPPClosureType ©) {
|
||||
* Adds a new capture to the beginning of the capture list.
|
||||
*/
|
||||
void CPPClosureType::
|
||||
add_capture(string name, CaptureType type) {
|
||||
add_capture(string name, CaptureType type, CPPExpression *initializer) {
|
||||
if (type == CT_none) {
|
||||
if (name == "this") {
|
||||
type = CT_by_reference;
|
||||
@ -56,7 +57,7 @@ add_capture(string name, CaptureType type) {
|
||||
}
|
||||
}
|
||||
|
||||
Capture capture = {move(name), type};
|
||||
Capture capture = {move(name), type, initializer};
|
||||
_captures.insert(_captures.begin(), move(capture));
|
||||
}
|
||||
|
||||
@ -117,19 +118,25 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
||||
|
||||
Captures::const_iterator it;
|
||||
for (it = _captures.begin(); it != _captures.end(); ++it) {
|
||||
const Capture &capture = *it;
|
||||
if (have_capture) {
|
||||
out << ", ";
|
||||
}
|
||||
if ((*it)._name == "this") {
|
||||
if ((*it)._type == CT_by_value) {
|
||||
if (capture._name == "this") {
|
||||
if (capture._type == CT_by_value) {
|
||||
out.put('*');
|
||||
}
|
||||
} else {
|
||||
if ((*it)._type == CT_by_reference) {
|
||||
if (capture._type == CT_by_reference) {
|
||||
out.put('&');
|
||||
}
|
||||
}
|
||||
out << (*it)._name;
|
||||
out << capture._name;
|
||||
|
||||
if (capture._initializer != NULL) {
|
||||
out << " = " << *capture._initializer;
|
||||
}
|
||||
|
||||
have_capture = true;
|
||||
}
|
||||
out.put(']');
|
||||
|
@ -37,13 +37,14 @@ public:
|
||||
struct Capture {
|
||||
string _name;
|
||||
CaptureType _type;
|
||||
CPPExpression *_initializer;
|
||||
};
|
||||
typedef vector<Capture> Captures;
|
||||
Captures _captures;
|
||||
|
||||
CaptureType _default_capture;
|
||||
|
||||
void add_capture(string name, CaptureType type);
|
||||
void add_capture(string name, CaptureType type, CPPExpression *initializer = NULL);
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
|
||||
|
@ -257,13 +257,12 @@ CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
|
||||
_u._variable = inst;
|
||||
return;
|
||||
}
|
||||
// Actually, we can't scope function groups.
|
||||
/*CPPFunctionGroup *fgroup = decl->as_function_group();
|
||||
CPPFunctionGroup *fgroup = decl->as_function_group();
|
||||
if (fgroup != NULL) {
|
||||
_type = T_function;
|
||||
_u._fgroup = fgroup;
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
_type = T_unknown_ident;
|
||||
@ -347,6 +346,22 @@ construct_op(CPPType *type, CPPExpression *op1) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression that represents an aggregate initialization.
|
||||
*/
|
||||
CPPExpression CPPExpression::
|
||||
aggregate_init_op(CPPType *type, CPPExpression *op1) {
|
||||
CPPExpression expr(0);
|
||||
if (op1 == NULL) {
|
||||
expr._type = T_empty_aggregate_init;
|
||||
} else {
|
||||
expr._type = T_aggregate_init;
|
||||
}
|
||||
expr._u._typecast._to = type;
|
||||
expr._u._typecast._op1 = op1;
|
||||
return expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression that represents a use of the new operator.
|
||||
*/
|
||||
@ -606,6 +621,8 @@ evaluate() const {
|
||||
|
||||
case T_construct:
|
||||
case T_default_construct:
|
||||
case T_aggregate_init:
|
||||
case T_empty_aggregate_init:
|
||||
case T_new:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
@ -1029,6 +1046,8 @@ determine_type() const {
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_default_construct:
|
||||
case T_aggregate_init:
|
||||
case T_empty_aggregate_init:
|
||||
return _u._typecast._to;
|
||||
|
||||
case T_new:
|
||||
@ -1147,10 +1166,28 @@ determine_type() const {
|
||||
|
||||
case 'f': // Function evaluation
|
||||
if (t1 != NULL) {
|
||||
// Easy case, function with only a single overload.
|
||||
CPPFunctionType *ftype = t1->as_function_type();
|
||||
if (ftype != (CPPFunctionType *)NULL) {
|
||||
return ftype->_return_type;
|
||||
}
|
||||
} else if (_u._op._op1->_type == T_function) {
|
||||
CPPFunctionGroup *fgroup = _u._op._op1->_u._fgroup;
|
||||
if (_u._op._op2 == NULL) {
|
||||
// If we are passing no args, look for an overload that has takes no
|
||||
// args.
|
||||
for (auto it = fgroup->_instances.begin(); it != fgroup->_instances.end(); ++it) {
|
||||
CPPInstance *inst = *it;
|
||||
if (inst != NULL && inst->_type != NULL) {
|
||||
CPPFunctionType *type = inst->_type->as_function_type();
|
||||
if (type != NULL && type->accepts_num_parameters(0)) {
|
||||
return type->_return_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
@ -1230,11 +1267,13 @@ is_fully_specified() const {
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
return (_u._typecast._to->is_fully_specified() &&
|
||||
_u._typecast._op1->is_fully_specified());
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
@ -1360,6 +1399,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
rep->_u._typecast._op1 =
|
||||
_u._typecast._op1->substitute_decl(subst, current_scope, global_scope)
|
||||
@ -1368,6 +1408,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
||||
// fall through
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
@ -1462,6 +1503,8 @@ is_tbd() const {
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_empty_aggregate_init:
|
||||
case T_new:
|
||||
case T_default_construct:
|
||||
case T_default_new:
|
||||
@ -1674,6 +1717,18 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
||||
out << "()";
|
||||
break;
|
||||
|
||||
case T_aggregate_init:
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << "{";
|
||||
_u._typecast._op1->output(out, indent_level, scope, false);
|
||||
out << "}";
|
||||
break;
|
||||
|
||||
case T_empty_aggregate_init:
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << "{}";
|
||||
break;
|
||||
|
||||
case T_new:
|
||||
out << "(new ";
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
@ -2095,11 +2150,13 @@ is_equal(const CPPDeclaration *other) const {
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
return _u._typecast._to == ot->_u._typecast._to &&
|
||||
*_u._typecast._op1 == *ot->_u._typecast._op1;
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
@ -2193,6 +2250,7 @@ is_less(const CPPDeclaration *other) const {
|
||||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
if (_u._typecast._to != ot->_u._typecast._to) {
|
||||
return _u._typecast._to < ot->_u._typecast._to;
|
||||
@ -2200,6 +2258,7 @@ is_less(const CPPDeclaration *other) const {
|
||||
return *_u._typecast._op1 < *ot->_u._typecast._op1;
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
T_reinterpret_cast,
|
||||
T_construct,
|
||||
T_default_construct,
|
||||
T_aggregate_init,
|
||||
T_empty_aggregate_init,
|
||||
T_new,
|
||||
T_default_new,
|
||||
T_sizeof,
|
||||
@ -81,6 +83,7 @@ public:
|
||||
|
||||
static CPPExpression typecast_op(CPPType *type, CPPExpression *op1, Type cast_type = T_typecast);
|
||||
static CPPExpression construct_op(CPPType *type, CPPExpression *op1);
|
||||
static CPPExpression aggregate_init_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);
|
||||
|
@ -66,6 +66,31 @@ operator = (const CPPFunctionType ©) {
|
||||
_class_owner = copy._class_owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the function accepts the given number of parameters.
|
||||
*/
|
||||
bool CPPFunctionType::
|
||||
accepts_num_parameters(int num_parameters) {
|
||||
if (_parameters == NULL) {
|
||||
return (num_parameters == 0);
|
||||
}
|
||||
size_t actual_num_parameters = _parameters->_parameters.size();
|
||||
// If we passed too many parameters, it must have an ellipsis.
|
||||
if (num_parameters > actual_num_parameters) {
|
||||
return _parameters->_includes_ellipsis;
|
||||
}
|
||||
|
||||
// Make sure all superfluous parameters have a default value.
|
||||
for (size_t i = num_parameters; i < actual_num_parameters; ++i) {
|
||||
CPPInstance *param = _parameters->_parameters[i];
|
||||
if (param->_initializer == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this declaration is an actual, factual declaration, or
|
||||
* false if some part of the declaration depends on a template parameter which
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
CPPFunctionType(const CPPFunctionType ©);
|
||||
void operator = (const CPPFunctionType ©);
|
||||
|
||||
bool accepts_num_parameters(int num_parameters);
|
||||
|
||||
CPPType *_return_type;
|
||||
CPPParameterList *_parameters;
|
||||
int _flags;
|
||||
|
@ -209,6 +209,7 @@ CPPPreprocessor() {
|
||||
_state = S_eof;
|
||||
_paren_nesting = 0;
|
||||
_parsing_template_params = false;
|
||||
_parsing_attribute = false;
|
||||
_unget = '\0';
|
||||
_last_c = '\0';
|
||||
_start_of_line = true;
|
||||
@ -986,6 +987,13 @@ internal_get_next_token() {
|
||||
return CPPToken(0, loc);
|
||||
}
|
||||
}
|
||||
} else if (_parsing_attribute) {
|
||||
// If we're parsing an attribute, also keep track of the paren nesting.
|
||||
if (c == '[' || c == '(') {
|
||||
++_paren_nesting;
|
||||
} else if (c == ']' || c == ')') {
|
||||
--_paren_nesting;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for an end-of-line comment, and parse it before we finish this
|
||||
@ -1090,6 +1098,20 @@ check_digraph(int c) {
|
||||
if (next_c == '=') return MODEQUAL;
|
||||
if (next_c == '>') return '}';
|
||||
break;
|
||||
|
||||
case '[':
|
||||
if (next_c == '[' && !_parsing_attribute) {
|
||||
_parsing_attribute = true;
|
||||
return ATTR_LEFT;
|
||||
}
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (next_c == ']' && _parsing_attribute && _paren_nesting == 0) {
|
||||
_parsing_attribute = false;
|
||||
return ATTR_RIGHT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -213,6 +213,7 @@ private:
|
||||
State _state;
|
||||
int _paren_nesting;
|
||||
bool _parsing_template_params;
|
||||
bool _parsing_attribute;
|
||||
|
||||
bool _start_of_line;
|
||||
int _unget;
|
||||
|
@ -252,6 +252,14 @@ output(ostream &out) const {
|
||||
out << "RSHIFTEQUAL";
|
||||
break;
|
||||
|
||||
case ATTR_LEFT:
|
||||
out << "ATTR_LEFT";
|
||||
break;
|
||||
|
||||
case ATTR_RIGHT:
|
||||
out << "ATTR_RIGHT";
|
||||
break;
|
||||
|
||||
case KW_BOOL:
|
||||
out << "KW_BOOL";
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user