Huge cppparser and interrogate overhaul, bringing:
* Better support for typedefs * Same code should compile for both 32-bit and 64-bit * C++11 typed enum support * Synthesize __setitem__ when operator [] returns reference * Rewrite coerce system to have better performance * Change semantics of __getattr__ and __setattr__ to match Python's, add __getattribute__, __delattr__ and __delitem__ * Improve performance of slot functions a bit more * Reduce memory overhead of type system * Some support for wrapping arrays of numeric types * C++11 character type support in cppparser * Chars are handled as strings of length 1 * Template functions for CreatePyInstance that use runtime type map * More functions from dtool as extension functions * Code cleanup
This commit is contained in:
parent
9c3553b3fc
commit
6db5d0dc11
|
|
@ -1,6 +1,6 @@
|
|||
// Filename: cppBison.y
|
||||
// Created by: drose (16Jan99)
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
%{
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
#include "cppClassTemplateParameter.h"
|
||||
#include "cppTemplateParameterList.h"
|
||||
#include "cppInstanceIdentifier.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppTypeDeclaration.h"
|
||||
#include "cppVisibility.h"
|
||||
#include "cppIdentifier.h"
|
||||
|
|
@ -38,7 +38,7 @@ CPPScope *current_scope = NULL;
|
|||
CPPScope *global_scope = NULL;
|
||||
CPPPreprocessor *current_lexer = NULL;
|
||||
|
||||
static CPPStructType *current_struct = NULL;
|
||||
static CPPStructType *current_struct = NULL;
|
||||
static CPPEnumType *current_enum = NULL;
|
||||
static int current_storage_class = 0;
|
||||
static CPPType *current_type = NULL;
|
||||
|
|
@ -98,7 +98,7 @@ parse_cpp(CPPParser *cp) {
|
|||
current_scope = old_scope;
|
||||
global_scope = old_global_scope;
|
||||
current_lexer = old_lexer;
|
||||
|
||||
|
||||
}
|
||||
|
||||
CPPExpression *
|
||||
|
|
@ -140,7 +140,7 @@ parse_type(CPPPreprocessor *pp, CPPScope *new_current_scope,
|
|||
yyparse();
|
||||
|
||||
CPPType *result = current_type;
|
||||
|
||||
|
||||
current_scope = old_scope;
|
||||
global_scope = old_global_scope;
|
||||
current_lexer = old_lexer;
|
||||
|
|
@ -223,8 +223,8 @@ pop_struct() {
|
|||
%token UNARY_REF
|
||||
%token POINTSAT
|
||||
%token SCOPE
|
||||
%token PLUSPLUS
|
||||
%token MINUSMINUS
|
||||
%token PLUSPLUS
|
||||
%token MINUSMINUS
|
||||
%token TIMESEQUAL
|
||||
%token DIVIDEEQUAL
|
||||
%token MODEQUAL
|
||||
|
|
@ -241,15 +241,16 @@ pop_struct() {
|
|||
%token KW_BOOL
|
||||
%token KW_CATCH
|
||||
%token KW_CHAR
|
||||
%token KW_WCHAR_T
|
||||
%token KW_CLASS
|
||||
%token KW_CONST
|
||||
%token KW_CHAR16_T
|
||||
%token KW_CHAR32_T
|
||||
%token KW_CLASS
|
||||
%token KW_CONST
|
||||
%token KW_DELETE
|
||||
%token KW_DOUBLE
|
||||
%token KW_DYNAMIC_CAST
|
||||
%token KW_ELSE
|
||||
%token KW_END_PUBLISH
|
||||
%token KW_ENUM
|
||||
%token KW_END_PUBLISH
|
||||
%token KW_ENUM
|
||||
%token KW_EXTENSION
|
||||
%token KW_EXTERN
|
||||
%token KW_EXPLICIT
|
||||
|
|
@ -280,19 +281,20 @@ pop_struct() {
|
|||
%token KW_SIZEOF
|
||||
%token KW_STATIC
|
||||
%token KW_STATIC_CAST
|
||||
%token KW_STRUCT
|
||||
%token KW_STRUCT
|
||||
%token KW_TEMPLATE
|
||||
%token KW_THROW
|
||||
%token KW_TRUE
|
||||
%token KW_TRY
|
||||
%token KW_TYPEDEF
|
||||
%token KW_TYPEDEF
|
||||
%token KW_TYPENAME
|
||||
%token KW_UNION
|
||||
%token KW_UNION
|
||||
%token KW_UNSIGNED
|
||||
%token KW_USING
|
||||
%token KW_VIRTUAL
|
||||
%token KW_VOID
|
||||
%token KW_VOLATILE
|
||||
%token KW_WCHAR_T
|
||||
%token KW_WHILE
|
||||
|
||||
/* These special tokens are used to set the starting state of the
|
||||
|
|
@ -324,8 +326,7 @@ pop_struct() {
|
|||
%type <u.type> full_type
|
||||
%type <u.struct_type> anonymous_struct
|
||||
%type <u.struct_type> named_struct
|
||||
%type <u.enum_type> anonymous_enum
|
||||
%type <u.enum_type> named_enum
|
||||
%type <u.enum_type> enum
|
||||
%type <u.extension_enum> enum_keyword
|
||||
%type <u.extension_enum> struct_keyword
|
||||
%type <u.simple_type> simple_type
|
||||
|
|
@ -333,6 +334,7 @@ pop_struct() {
|
|||
%type <u.simple_type> simple_float_type
|
||||
%type <u.simple_type> simple_void_type
|
||||
%type <u.type> class_derivation_name
|
||||
%type <u.type> enum_element_type
|
||||
/*%type <u.type> typedefname*/
|
||||
%type <u.identifier> name
|
||||
%type <str> string
|
||||
|
|
@ -352,7 +354,7 @@ pop_struct() {
|
|||
|
||||
/* Precedence rules. */
|
||||
|
||||
%left IDENTIFIER TYPENAME_IDENTIFIER TYPEDEFNAME KW_ENUM ELLIPSIS KW_OPERATOR KW_TYPENAME KW_INT KW_SHORT KW_UNSIGNED KW_SIGNED KW_LONG KW_FLOAT KW_DOUBLE KW_CHAR KW_WCHAR_T KW_BOOL
|
||||
%left IDENTIFIER TYPENAME_IDENTIFIER TYPEDEFNAME KW_ENUM ELLIPSIS KW_OPERATOR KW_TYPENAME KW_INT KW_SHORT KW_UNSIGNED KW_SIGNED KW_LONG KW_FLOAT KW_DOUBLE KW_CHAR KW_WCHAR_T KW_CHAR16_T KW_CHAR32_T KW_BOOL
|
||||
|
||||
%left '{' ',' ';'
|
||||
|
||||
|
|
@ -417,7 +419,7 @@ constructor_init:
|
|||
extern_c:
|
||||
storage_class '{'
|
||||
{
|
||||
push_storage_class((current_storage_class & ~CPPInstance::SC_c_binding) |
|
||||
push_storage_class((current_storage_class & ~CPPInstance::SC_c_binding) |
|
||||
($1 & CPPInstance::SC_c_binding));
|
||||
}
|
||||
cpp '}'
|
||||
|
|
@ -434,7 +436,7 @@ declaration:
|
|||
| using_declaration
|
||||
| friend_declaration
|
||||
| KW_TYPEDEF typedef_declaration
|
||||
| KW_BEGIN_PUBLISH
|
||||
| KW_BEGIN_PUBLISH
|
||||
{
|
||||
if (publish_nest_level != 0) {
|
||||
yyerror("Unclosed __begin_publish", publish_loc);
|
||||
|
|
@ -447,7 +449,7 @@ declaration:
|
|||
publish_nest_level++;
|
||||
current_scope->set_current_vis(V_published);
|
||||
}
|
||||
| KW_END_PUBLISH
|
||||
| KW_END_PUBLISH
|
||||
{
|
||||
if (publish_nest_level != 1) {
|
||||
yyerror("Unmatched __end_publish", @1);
|
||||
|
|
@ -716,7 +718,8 @@ typedef_declaration:
|
|||
if (inst != (CPPInstance *)NULL) {
|
||||
inst->_storage_class |= (current_storage_class | $1);
|
||||
current_scope->add_declaration(inst, global_scope, current_lexer, @2);
|
||||
current_scope->add_declaration(new CPPTypedef(inst, current_scope == global_scope), global_scope, current_lexer, @2);
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(inst->_type, inst->_ident, current_scope);
|
||||
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -725,19 +728,15 @@ typedef_declaration:
|
|||
typedef_instance_identifiers:
|
||||
instance_identifier maybe_initialize_or_function_body
|
||||
{
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
inst->set_initializer($2);
|
||||
current_scope->add_declaration(new CPPTypedef(inst, current_scope == global_scope), global_scope, current_lexer, @1);
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
|
||||
}
|
||||
| instance_identifier maybe_initialize ',' typedef_instance_identifiers
|
||||
{
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
inst->set_initializer($2);
|
||||
current_scope->add_declaration(new CPPTypedef(inst, current_scope == global_scope), global_scope, current_lexer, @1);
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -745,27 +744,23 @@ typedef_const_instance_identifiers:
|
|||
instance_identifier maybe_initialize_or_function_body
|
||||
{
|
||||
$1->add_modifier(IIT_const);
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
inst->set_initializer($2);
|
||||
current_scope->add_declaration(new CPPTypedef(inst, current_scope == global_scope), global_scope, current_lexer, @1);
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
|
||||
}
|
||||
| instance_identifier maybe_initialize ',' typedef_const_instance_identifiers
|
||||
{
|
||||
$1->add_modifier(IIT_const);
|
||||
CPPInstance *inst = new CPPInstance(current_type, $1,
|
||||
current_storage_class,
|
||||
@1.file);
|
||||
inst->set_initializer($2);
|
||||
current_scope->add_declaration(new CPPTypedef(inst, current_scope == global_scope), global_scope, current_lexer, @1);
|
||||
CPPType *target_type = current_type;
|
||||
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
|
||||
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
|
||||
}
|
||||
;
|
||||
|
||||
function_prototype:
|
||||
|
||||
/* Functions with implicit return types, and constructors */
|
||||
IDENTIFIER '('
|
||||
IDENTIFIER '('
|
||||
{
|
||||
push_scope($1->get_scope(current_scope, global_scope));
|
||||
}
|
||||
|
|
@ -821,13 +816,13 @@ function_prototype:
|
|||
if ($2->is_scoped()) {
|
||||
yyerror("Invalid destructor name: ~" + $2->get_fully_scoped_name(), @2);
|
||||
} else {
|
||||
CPPIdentifier *ident =
|
||||
CPPIdentifier *ident =
|
||||
new CPPIdentifier("~" + $2->get_simple_name(), @2.file);
|
||||
delete $2;
|
||||
|
||||
CPPType *type;
|
||||
type = new CPPSimpleType(CPPSimpleType::T_void);
|
||||
|
||||
|
||||
CPPInstanceIdentifier *ii = new CPPInstanceIdentifier(ident);
|
||||
ii->add_func_modifier($5, $7);
|
||||
|
||||
|
|
@ -932,7 +927,7 @@ function_prototype:
|
|||
avoid shift/reduce conflicts. */
|
||||
| IDENTIFIER
|
||||
{
|
||||
CPPDeclaration *decl =
|
||||
CPPDeclaration *decl =
|
||||
$1->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (decl != (CPPDeclaration *)NULL) {
|
||||
$$ = decl->as_instance();
|
||||
|
|
@ -1560,11 +1555,7 @@ type:
|
|||
{
|
||||
$$ = CPPType::new_type($1);
|
||||
}
|
||||
| anonymous_enum
|
||||
{
|
||||
$$ = CPPType::new_type($1);
|
||||
}
|
||||
| named_enum
|
||||
| enum
|
||||
{
|
||||
$$ = CPPType::new_type($1);
|
||||
}
|
||||
|
|
@ -1574,7 +1565,7 @@ type:
|
|||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
|
|
@ -1584,13 +1575,13 @@ type:
|
|||
$$ = et;
|
||||
}
|
||||
}
|
||||
| enum_keyword name
|
||||
| enum_keyword name ':' enum_element_type
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
|
|
@ -1624,11 +1615,7 @@ type_decl:
|
|||
{
|
||||
$$ = new CPPTypeDeclaration(CPPType::new_type($1));
|
||||
}
|
||||
| anonymous_enum
|
||||
{
|
||||
$$ = CPPType::new_type($1);
|
||||
}
|
||||
| named_enum
|
||||
| enum
|
||||
{
|
||||
$$ = new CPPTypeDeclaration(CPPType::new_type($1));
|
||||
}
|
||||
|
|
@ -1638,7 +1625,7 @@ type_decl:
|
|||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
|
|
@ -1648,13 +1635,13 @@ type_decl:
|
|||
$$ = et;
|
||||
}
|
||||
}
|
||||
| enum_keyword name
|
||||
| enum_keyword name ':' enum_element_type
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
|
|
@ -1686,7 +1673,7 @@ predefined_type:
|
|||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
|
|
@ -1702,7 +1689,7 @@ predefined_type:
|
|||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
|
|
@ -1733,9 +1720,9 @@ full_type:
|
|||
anonymous_struct:
|
||||
struct_keyword '{'
|
||||
{
|
||||
CPPVisibility starting_vis =
|
||||
CPPVisibility starting_vis =
|
||||
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
||||
|
||||
|
||||
CPPScope *new_scope = new CPPScope(current_scope, CPPNameComponent("anon"),
|
||||
starting_vis);
|
||||
CPPStructType *st = new CPPStructType($1, NULL, current_scope,
|
||||
|
|
@ -1757,7 +1744,7 @@ anonymous_struct:
|
|||
named_struct:
|
||||
struct_keyword name
|
||||
{
|
||||
CPPVisibility starting_vis =
|
||||
CPPVisibility starting_vis =
|
||||
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
||||
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope, current_lexer);
|
||||
|
|
@ -1771,7 +1758,7 @@ named_struct:
|
|||
new_scope, @1.file);
|
||||
new_scope->set_struct_type(st);
|
||||
current_scope->define_extension_type(st);
|
||||
|
||||
|
||||
push_scope(new_scope);
|
||||
push_struct(st);
|
||||
}
|
||||
|
|
@ -1833,27 +1820,41 @@ base_specification:
|
|||
}
|
||||
;
|
||||
|
||||
anonymous_enum:
|
||||
enum_keyword '{'
|
||||
{
|
||||
current_enum = new CPPEnumType(NULL, current_scope, @1.file);
|
||||
}
|
||||
enum_body '}'
|
||||
enum:
|
||||
enum_decl '{' enum_body '}'
|
||||
{
|
||||
$$ = current_enum;
|
||||
current_enum = NULL;
|
||||
}
|
||||
;
|
||||
|
||||
named_enum:
|
||||
enum_keyword name '{'
|
||||
enum_decl:
|
||||
enum_keyword name ':' enum_element_type
|
||||
{
|
||||
current_enum = new CPPEnumType($2, $4, current_scope, @1.file);
|
||||
}
|
||||
| enum_keyword name
|
||||
{
|
||||
current_enum = new CPPEnumType($2, current_scope, @1.file);
|
||||
}
|
||||
enum_body '}'
|
||||
| enum_keyword ':' enum_element_type
|
||||
{
|
||||
$$ = current_enum;
|
||||
current_enum = NULL;
|
||||
current_enum = new CPPEnumType(NULL, $3, current_scope, @1.file);
|
||||
}
|
||||
| enum_keyword
|
||||
{
|
||||
current_enum = new CPPEnumType(NULL, current_scope, @1.file);
|
||||
}
|
||||
;
|
||||
|
||||
enum_element_type:
|
||||
simple_int_type
|
||||
{
|
||||
$$ = CPPType::new_type($1);
|
||||
}
|
||||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1916,7 +1917,7 @@ namespace_declaration:
|
|||
CPPScope *scope = $2->find_scope(current_scope, global_scope, current_lexer);
|
||||
if (scope == NULL) {
|
||||
// This must be a new namespace declaration.
|
||||
CPPScope *parent_scope =
|
||||
CPPScope *parent_scope =
|
||||
$2->get_scope(current_scope, global_scope, current_lexer);
|
||||
if (parent_scope == NULL) {
|
||||
parent_scope = current_scope;
|
||||
|
|
@ -1969,6 +1970,14 @@ simple_int_type:
|
|||
| KW_WCHAR_T
|
||||
{
|
||||
$$ = new CPPSimpleType(CPPSimpleType::T_wchar_t);
|
||||
}
|
||||
| KW_CHAR16_T
|
||||
{
|
||||
$$ = new CPPSimpleType(CPPSimpleType::T_char16_t);
|
||||
}
|
||||
| KW_CHAR32_T
|
||||
{
|
||||
$$ = new CPPSimpleType(CPPSimpleType::T_char32_t);
|
||||
}
|
||||
| KW_SHORT
|
||||
{
|
||||
|
|
@ -2104,13 +2113,14 @@ element:
|
|||
| ELLIPSIS | OROR | ANDAND
|
||||
| EQCOMPARE | NECOMPARE | LECOMPARE | GECOMPARE
|
||||
| LSHIFT | RSHIFT | POINTSAT_STAR | DOT_STAR | POINTSAT
|
||||
| SCOPE | PLUSPLUS | MINUSMINUS
|
||||
| SCOPE | PLUSPLUS | MINUSMINUS
|
||||
| TIMESEQUAL | DIVIDEEQUAL | MODEQUAL | PLUSEQUAL | MINUSEQUAL
|
||||
| OREQUAL | ANDEQUAL | XOREQUAL | LSHIFTEQUAL | RSHIFTEQUAL
|
||||
| KW_BOOL | KW_CATCH | KW_CHAR | KW_WCHAR_T | KW_CLASS | KW_CONST
|
||||
| KW_BOOL | KW_CATCH | KW_CHAR | KW_CHAR16_T | KW_CHAR32_T
|
||||
| KW_WCHAR_T | KW_CLASS | KW_CONST
|
||||
| KW_DELETE | KW_DOUBLE | KW_DYNAMIC_CAST | KW_ELSE | KW_ENUM
|
||||
| KW_EXTERN | KW_EXPLICIT | KW_FALSE
|
||||
| KW_FLOAT | KW_FRIEND | KW_FOR | KW_GOTO
|
||||
| KW_FLOAT | KW_FRIEND | KW_FOR | KW_GOTO
|
||||
| KW_IF | KW_INLINE | KW_INT
|
||||
| KW_LONG | KW_MUTABLE | KW_NEW | KW_PRIVATE | KW_PROTECTED
|
||||
| KW_PUBLIC | KW_PUBLISHED | KW_REGISTER | KW_RETURN
|
||||
|
|
@ -2329,65 +2339,77 @@ const_expr:
|
|||
}
|
||||
| KW_INT '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_CHAR '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_WCHAR_T '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_wchar_t));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_CHAR16_T '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char16_t));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_CHAR32_T '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char32_t));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_BOOL '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_bool));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_SHORT '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int,
|
||||
CPPSimpleType::F_short));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_LONG '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int,
|
||||
CPPSimpleType::F_long));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_UNSIGNED '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int,
|
||||
CPPSimpleType::F_unsigned));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_SIGNED '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int,
|
||||
CPPSimpleType::F_signed));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_FLOAT '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_float));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| KW_DOUBLE '(' optional_const_expr_comma ')'
|
||||
{
|
||||
CPPType *type =
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_double));
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,13 +177,13 @@ as_class_template_parameter() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPDeclaration::as_typedef
|
||||
// Function: CPPDeclaration::as_typedef_type
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedef *CPPDeclaration::
|
||||
as_typedef() {
|
||||
return (CPPTypedef *)NULL;
|
||||
CPPTypedefType *CPPDeclaration::
|
||||
as_typedef_type() {
|
||||
return (CPPTypedefType *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ using namespace std;
|
|||
|
||||
class CPPInstance;
|
||||
class CPPTemplateParameterList;
|
||||
class CPPTypedef;
|
||||
class CPPTypedefType;
|
||||
class CPPTypeDeclaration;
|
||||
class CPPExpression;
|
||||
class CPPType;
|
||||
|
|
@ -64,7 +64,6 @@ public:
|
|||
enum SubType {
|
||||
// Subtypes of CPPDeclaration
|
||||
ST_instance,
|
||||
ST_typedef,
|
||||
ST_type_declaration,
|
||||
ST_expression,
|
||||
ST_type,
|
||||
|
|
@ -87,6 +86,7 @@ public:
|
|||
ST_class_template_parameter,
|
||||
ST_tbd,
|
||||
ST_type_proxy,
|
||||
ST_typedef,
|
||||
};
|
||||
|
||||
CPPDeclaration(const CPPFile &file);
|
||||
|
|
@ -120,7 +120,7 @@ public:
|
|||
|
||||
virtual CPPInstance *as_instance();
|
||||
virtual CPPClassTemplateParameter *as_class_template_parameter();
|
||||
virtual CPPTypedef *as_typedef();
|
||||
virtual CPPTypedefType *as_typedef_type();
|
||||
virtual CPPTypeDeclaration *as_type_declaration();
|
||||
virtual CPPExpression *as_expression();
|
||||
virtual CPPType *as_type();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cppEnumType.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppExpression.h"
|
||||
#include "cppSimpleType.h"
|
||||
#include "cppConstType.h"
|
||||
|
|
@ -24,12 +24,29 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPEnumType::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Creates an untyped, unscoped enum.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPEnumType::
|
||||
CPPEnumType(CPPIdentifier *ident, CPPScope *current_scope,
|
||||
const CPPFile &file) :
|
||||
CPPExtensionType(T_enum, ident, current_scope, file),
|
||||
_parent_scope(current_scope),
|
||||
_element_type(NULL),
|
||||
_last_value(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPEnumType::Constructor
|
||||
// Access: Public
|
||||
// Description: Creates a typed but unscoped enum.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPEnumType::
|
||||
CPPEnumType(CPPIdentifier *ident, CPPType *element_type,
|
||||
CPPScope *current_scope, const CPPFile &file) :
|
||||
CPPExtensionType(T_enum, ident, current_scope, file),
|
||||
_parent_scope(current_scope),
|
||||
_element_type(element_type),
|
||||
_last_value(NULL)
|
||||
{
|
||||
}
|
||||
|
|
@ -41,12 +58,24 @@ CPPEnumType(CPPIdentifier *ident, CPPScope *current_scope,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPPInstance *CPPEnumType::
|
||||
add_element(const string &name, CPPExpression *value) {
|
||||
CPPType *type =
|
||||
CPPType::new_type(new CPPConstType(new CPPSimpleType(
|
||||
CPPSimpleType::T_int, CPPSimpleType::F_unsigned)));
|
||||
|
||||
CPPIdentifier *ident = new CPPIdentifier(name);
|
||||
CPPInstance *inst = new CPPInstance(type, ident);
|
||||
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);
|
||||
}
|
||||
|
||||
_elements.push_back(inst);
|
||||
|
||||
if (value == (CPPExpression *)NULL) {
|
||||
|
|
@ -81,6 +110,39 @@ is_incomplete() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPEnumType::is_fully_specified
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this declaration is an actual,
|
||||
// factual declaration, or false if some part of the
|
||||
// declaration depends on a template parameter which has
|
||||
// not yet been instantiated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPEnumType::
|
||||
is_fully_specified() const {
|
||||
if (!CPPDeclaration::is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_ident != NULL && !_ident->is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_element_type != NULL && !_element_type->is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Elements::const_iterator ei;
|
||||
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
|
||||
if (!(*ei)->is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPEnumType::substitute_decl
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -100,7 +162,28 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
_ident->substitute_decl(subst, current_scope, global_scope);
|
||||
}
|
||||
|
||||
if (rep->_ident == _ident) {
|
||||
if (_element_type != NULL) {
|
||||
rep->_element_type =
|
||||
_element_type->substitute_decl(subst, current_scope, global_scope)
|
||||
->as_type();
|
||||
}
|
||||
|
||||
bool any_changed = false;
|
||||
|
||||
for (int i = 0; i < _elements.size(); ++i) {
|
||||
CPPInstance *elem_rep =
|
||||
_elements[i]->substitute_decl(subst, current_scope, global_scope)
|
||||
->as_instance();
|
||||
|
||||
if (elem_rep != _elements[i]) {
|
||||
_elements[i] = elem_rep;
|
||||
any_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rep->_ident == _ident &&
|
||||
rep->_element_type == _element_type &&
|
||||
!any_changed) {
|
||||
delete rep;
|
||||
rep = this;
|
||||
}
|
||||
|
|
@ -124,15 +207,14 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
|||
}
|
||||
out << _ident->get_local_name(scope);
|
||||
|
||||
} else if (!complete && !_typedefs.empty()) {
|
||||
// If we have a typedef name, use it.
|
||||
out << _typedefs.front()->get_local_name(scope);
|
||||
|
||||
} else {
|
||||
out << _type;
|
||||
if (_ident != NULL) {
|
||||
out << " " << _ident->get_local_name(scope);
|
||||
}
|
||||
if (_element_type != NULL) {
|
||||
out << " : " << _element_type->get_local_name(scope);
|
||||
}
|
||||
|
||||
out << " {\n";
|
||||
Elements::const_iterator ei;
|
||||
|
|
|
|||
|
|
@ -34,12 +34,15 @@ class CPPEnumType : public CPPExtensionType {
|
|||
public:
|
||||
CPPEnumType(CPPIdentifier *ident, CPPScope *current_scope,
|
||||
const CPPFile &file);
|
||||
CPPEnumType(CPPIdentifier *ident, CPPType *element_type,
|
||||
CPPScope *current_scope, const CPPFile &file);
|
||||
|
||||
CPPInstance *add_element(const string &name,
|
||||
CPPExpression *value = (CPPExpression *)NULL);
|
||||
|
||||
virtual bool is_incomplete() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
|
||||
CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
|
|
@ -50,6 +53,9 @@ public:
|
|||
|
||||
virtual CPPEnumType *as_enum_type();
|
||||
|
||||
CPPScope *_parent_scope;
|
||||
CPPType *_element_type;
|
||||
|
||||
typedef vector<CPPInstance *> Elements;
|
||||
Elements _elements;
|
||||
CPPExpression *_last_value;
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
|
|||
CPPDeclaration(CPPFile())
|
||||
{
|
||||
CPPDeclaration *decl =
|
||||
ident->find_symbol(current_scope, global_scope, error_sink);
|
||||
ident->find_symbol(current_scope, global_scope);
|
||||
|
||||
if (decl != NULL) {
|
||||
CPPInstance *inst = decl->as_instance();
|
||||
|
|
@ -245,6 +245,7 @@ CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
|
|||
|
||||
_type = T_unknown_ident;
|
||||
_u._ident = ident;
|
||||
_u._ident->_native_scope = current_scope;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -801,6 +802,66 @@ determine_type() const {
|
|||
return NULL; // Compiler kludge; can't get here.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPExpression::is_fully_specified
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this declaration is an actual,
|
||||
// factual declaration, or false if some part of the
|
||||
// declaration depends on a template parameter which has
|
||||
// not yet been instantiated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPExpression::
|
||||
is_fully_specified() const {
|
||||
if (!CPPDeclaration::is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (_type) {
|
||||
case T_integer:
|
||||
case T_real:
|
||||
case T_string:
|
||||
return false;
|
||||
|
||||
case T_variable:
|
||||
return _u._variable->is_fully_specified();
|
||||
|
||||
case T_function:
|
||||
return _u._fgroup->is_fully_specified();
|
||||
|
||||
case T_unknown_ident:
|
||||
return _u._ident->is_fully_specified();
|
||||
|
||||
case T_typecast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
return (_u._typecast._to->is_fully_specified() &&
|
||||
_u._typecast._op1->is_fully_specified());
|
||||
|
||||
case T_default_construct:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
return _u._typecast._to->is_fully_specified();
|
||||
|
||||
case T_trinary_operation:
|
||||
if (!_u._op._op3->is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
// Fall through
|
||||
|
||||
case T_binary_operation:
|
||||
if (!_u._op._op2->is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
// Fall through
|
||||
|
||||
case T_unary_operation:
|
||||
return _u._op._op1->is_fully_specified();
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPExpression::substitute_decl
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -827,6 +888,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
// Replacing the variable reference with another variable reference.
|
||||
rep->_u._variable = decl->as_instance();
|
||||
any_changed = true;
|
||||
|
||||
} else if (decl->as_expression()) {
|
||||
// Replacing the variable reference with an expression.
|
||||
delete rep;
|
||||
|
|
@ -836,6 +898,43 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
}
|
||||
break;
|
||||
|
||||
case T_unknown_ident:
|
||||
rep->_u._ident = _u._ident->substitute_decl(subst, current_scope, global_scope);
|
||||
any_changed = any_changed || (rep->_u._ident != _u._ident);
|
||||
|
||||
// See if we can define it now.
|
||||
decl = rep->_u._ident->find_symbol(current_scope, global_scope, subst);
|
||||
if (decl != NULL) {
|
||||
CPPInstance *inst = decl->as_instance();
|
||||
if (inst != NULL) {
|
||||
rep->_type = T_variable;
|
||||
rep->_u._variable = inst;
|
||||
any_changed = true;
|
||||
|
||||
decl = inst->substitute_decl(subst, current_scope, global_scope);
|
||||
if (decl != inst) {
|
||||
if (decl->as_instance()) {
|
||||
// Replacing the variable reference with another variable reference.
|
||||
rep->_u._variable = decl->as_instance();
|
||||
|
||||
} else if (decl->as_expression()) {
|
||||
// Replacing the variable reference with an expression.
|
||||
delete rep;
|
||||
rep = decl->as_expression();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
CPPFunctionGroup *fgroup = decl->as_function_group();
|
||||
if (fgroup != NULL) {
|
||||
rep->_type = T_function;
|
||||
rep->_u._fgroup = fgroup;
|
||||
any_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case T_typecast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
|
|
@ -909,6 +1008,9 @@ is_tbd() const {
|
|||
|
||||
return true;
|
||||
|
||||
case T_unknown_ident:
|
||||
return true;
|
||||
|
||||
case T_typecast:
|
||||
case T_construct:
|
||||
case T_new:
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public:
|
|||
CPPType *determine_type() const;
|
||||
bool is_tbd() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
|
||||
CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
|
||||
#include "cppExtensionType.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppIdentifier.h"
|
||||
#include "cppParser.h"
|
||||
#include "indent.h"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ CPPIdentifier(const string &name, const CPPFile &file) : _file(file) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPIdentifier::
|
||||
CPPIdentifier(const CPPNameComponent &name) {
|
||||
CPPIdentifier(const CPPNameComponent &name, const CPPFile &file) : _file(file) {
|
||||
_names.push_back(name);
|
||||
_native_scope = (CPPScope *)NULL;
|
||||
}
|
||||
|
|
@ -382,6 +382,7 @@ find_type(CPPScope *current_scope, CPPScope *global_scope,
|
|||
if (scope == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CPPType *type = scope->find_type(get_simple_name(), subst, global_scope);
|
||||
if (type != NULL && _names.back().has_templ()) {
|
||||
// This is a template type.
|
||||
|
|
@ -398,7 +399,6 @@ find_type(CPPScope *current_scope, CPPScope *global_scope,
|
|||
assert(new_type != NULL);
|
||||
if (new_type == type) {
|
||||
type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
|
||||
// type = new_type;
|
||||
} else {
|
||||
type = new_type;
|
||||
}
|
||||
|
|
@ -424,6 +424,7 @@ find_symbol(CPPScope *current_scope, CPPScope *global_scope,
|
|||
if (scope == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CPPDeclaration *sym;
|
||||
if (!_names.back().has_templ()) {
|
||||
sym = scope->find_symbol(get_simple_name());
|
||||
|
|
@ -446,6 +447,43 @@ find_symbol(CPPScope *current_scope, CPPScope *global_scope,
|
|||
return sym;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPIdentifier::find_symbol
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPDeclaration *CPPIdentifier::
|
||||
find_symbol(CPPScope *current_scope, CPPScope *global_scope,
|
||||
CPPDeclaration::SubstDecl &subst,
|
||||
CPPPreprocessor *error_sink) const {
|
||||
CPPScope *scope = get_scope(current_scope, global_scope, subst, error_sink);
|
||||
if (scope == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CPPDeclaration *sym;
|
||||
if (!_names.back().has_templ()) {
|
||||
sym = scope->find_symbol(get_simple_name());
|
||||
|
||||
} else {
|
||||
sym = scope->find_template(get_simple_name());
|
||||
|
||||
if (sym != NULL) {
|
||||
CPPType *type = sym->as_type();
|
||||
if (type != NULL && type->is_incomplete()) {
|
||||
// We can't instantiate an incomplete type.
|
||||
sym = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
|
||||
} else {
|
||||
// Instantiate the symbol.
|
||||
sym = sym->instantiate(_names.back().get_templ(), current_scope,
|
||||
global_scope, error_sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPIdentifier::find_template
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class CPPTemplateParameterList;
|
|||
class CPPIdentifier {
|
||||
public:
|
||||
CPPIdentifier(const string &name, const CPPFile &file = CPPFile());
|
||||
CPPIdentifier(const CPPNameComponent &name);
|
||||
CPPIdentifier(const CPPNameComponent &name, const CPPFile &file = CPPFile());
|
||||
void add_name(const string &name);
|
||||
void add_name(const CPPNameComponent &name);
|
||||
|
||||
|
|
@ -69,6 +69,10 @@ public:
|
|||
CPPDeclaration *find_symbol(CPPScope *current_scope,
|
||||
CPPScope *global_scope,
|
||||
CPPPreprocessor *error_sink = NULL) const;
|
||||
CPPDeclaration *find_symbol(CPPScope *current_scope,
|
||||
CPPScope *global_scope,
|
||||
CPPDeclaration::SubstDecl &subst,
|
||||
CPPPreprocessor *error_sink = NULL) const;
|
||||
CPPDeclaration *find_template(CPPScope *current_scope,
|
||||
CPPScope *global_scope,
|
||||
CPPPreprocessor *error_sink = NULL) const;
|
||||
|
|
|
|||
|
|
@ -372,6 +372,7 @@ CPPDeclaration *CPPInstance::
|
|||
instantiate(const CPPTemplateParameterList *actual_params,
|
||||
CPPScope *current_scope, CPPScope *global_scope,
|
||||
CPPPreprocessor *error_sink) const {
|
||||
|
||||
if (!is_template()) {
|
||||
if (error_sink != NULL) {
|
||||
error_sink->warning("Ignoring template parameters for instance " +
|
||||
|
|
@ -457,7 +458,6 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
rep->_type = new_type->as_type();
|
||||
|
||||
if (rep->_type == NULL) {
|
||||
cerr << "Type " << *_type << " became " << *new_type << " which isn't a type\n";
|
||||
rep->_type = _type;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ ExpansionNode(const string &str, bool paste) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPPManifest::
|
||||
CPPManifest(const string &args, const CPPFile &file) :
|
||||
_file(file),
|
||||
_variadic_param(-1),
|
||||
_file(file),
|
||||
_expr((CPPExpression *)NULL)
|
||||
{
|
||||
assert(!args.empty());
|
||||
|
|
@ -184,7 +184,7 @@ expand(const vector_string &args) const {
|
|||
// to a comma and no arguments are passed, the comma
|
||||
// is removed. MSVC does this automatically. Not sure
|
||||
// if we should allow MSVC behavior as well.
|
||||
if (*result.rbegin() == ',') {
|
||||
if (!result.empty() && *result.rbegin() == ',') {
|
||||
result.resize(result.size() - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ CPPPreprocessor() {
|
|||
|
||||
_warning_count = 0;
|
||||
_error_count = 0;
|
||||
_error_abort = true;
|
||||
#ifdef CPP_VERBOSE_LEX
|
||||
_token_index = 0;
|
||||
#endif
|
||||
|
|
@ -404,8 +405,7 @@ get_next_token0() {
|
|||
|
||||
int token_type = IDENTIFIER;
|
||||
CPPDeclaration *decl = ident->find_symbol(current_scope, global_scope);
|
||||
if (decl != NULL &&
|
||||
(decl->as_typedef() != NULL || decl->as_type() != NULL)) {
|
||||
if (decl != NULL && decl->as_type() != NULL) {
|
||||
token_type = TYPENAME_IDENTIFIER;
|
||||
}
|
||||
|
||||
|
|
@ -452,7 +452,7 @@ error(const string &message, int line, int col, CPPFile file) {
|
|||
// Don't report or log errors in the nested state. These will be
|
||||
// reported when the nesting level collapses.
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
if (_verbose >= 1) {
|
||||
if (line == 0) {
|
||||
|
|
@ -467,6 +467,11 @@ error(const string &message, int line, int col, CPPFile file) {
|
|||
<< " near line " << line << ", column " << col << ":\n";
|
||||
indent(cerr, _files.size() * 2)
|
||||
<< message << "\n";
|
||||
|
||||
if (_error_abort) {
|
||||
cerr << "Aborting.\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
_error_count++;
|
||||
}
|
||||
|
|
@ -2005,7 +2010,8 @@ check_keyword(const string &name) {
|
|||
if (name == "bool") return KW_BOOL;
|
||||
if (name == "catch") return KW_CATCH;
|
||||
if (name == "char") return KW_CHAR;
|
||||
if (name == "wchar_t") return KW_WCHAR_T;
|
||||
if (name == "char16_t") return KW_CHAR16_T;
|
||||
if (name == "char32_t") return KW_CHAR32_T;
|
||||
if (name == "class") return KW_CLASS;
|
||||
if (name == "const") return KW_CONST;
|
||||
if (name == "delete") return KW_DELETE;
|
||||
|
|
@ -2056,6 +2062,7 @@ check_keyword(const string &name) {
|
|||
if (name == "virtual") return KW_VIRTUAL;
|
||||
if (name == "void") return KW_VOID;
|
||||
if (name == "volatile") return KW_VOLATILE;
|
||||
if (name == "wchar_t") return KW_WCHAR_T;
|
||||
if (name == "while") return KW_WHILE;
|
||||
|
||||
if (!cpp_longlong_keyword.empty() && name == cpp_longlong_keyword) {
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ private:
|
|||
|
||||
int _warning_count;
|
||||
int _error_count;
|
||||
bool _error_abort;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include "cppScope.h"
|
||||
#include "cppDeclaration.h"
|
||||
#include "cppNamespace.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppTypeDeclaration.h"
|
||||
#include "cppExtensionType.h"
|
||||
#include "cppInstance.h"
|
||||
|
|
@ -200,28 +200,28 @@ define_extension_type(CPPExtensionType *type) {
|
|||
|
||||
case CPPExtensionType::T_union:
|
||||
_unions[name] = type;
|
||||
break;
|
||||
|
||||
case CPPExtensionType::T_enum:
|
||||
_enums[name] = type;
|
||||
}
|
||||
|
||||
// Create an implicit typedef for the extension.
|
||||
CPPIdentifier *ident = new CPPIdentifier(name);
|
||||
CPPTypedef *td = new CPPTypedef(new CPPInstance(type, ident), false);
|
||||
pair<Typedefs::iterator, bool> result =
|
||||
_typedefs.insert(Typedefs::value_type(name, td));
|
||||
//CPPTypedefType *td = new CPPTypedefType(type, name);
|
||||
pair<Types::iterator, bool> result =
|
||||
_types.insert(Types::value_type(name, type));
|
||||
|
||||
if (!result.second) {
|
||||
// There's already a typedef for this extension. This one
|
||||
// overrides if it has template parameters and the other one
|
||||
// doesn't.
|
||||
CPPType *other_type = (*result.first).second->_type;
|
||||
CPPType *other_type = (*result.first).second;
|
||||
if (type->is_template() && !other_type->is_template()) {
|
||||
(*result.first).second = td;
|
||||
(*result.first).second = type;
|
||||
|
||||
// Or if the other one is a forward reference.
|
||||
} else if (other_type->get_subtype() == CPPDeclaration::ST_extension) {
|
||||
(*result.first).second = td;
|
||||
(*result.first).second = type;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -391,11 +391,13 @@ instantiate(const CPPTemplateParameterList *actual_params,
|
|||
CPPDeclaration *decl = (*pi);
|
||||
CPPClassTemplateParameter *ctp = decl->as_class_template_parameter();
|
||||
if (ctp != NULL) {
|
||||
CPPInstance *inst = new CPPInstance(ctp, ctp->_ident);
|
||||
CPPTypedef *td = new CPPTypedef(inst, true);
|
||||
scope->_typedefs.insert(Typedefs::value_type
|
||||
(ctp->_ident->get_local_name(),
|
||||
td));
|
||||
//CPPTypedefType *td = new CPPTypedefType(ctp, ctp->_ident);
|
||||
//scope->_typedefs.insert(Typedefs::value_type
|
||||
// (ctp->_ident->get_local_name(),
|
||||
// td));
|
||||
scope->_types.insert(Types::value_type
|
||||
(ctp->_ident->get_local_name(),
|
||||
ctp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -465,10 +467,10 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPPType *CPPScope::
|
||||
find_type(const string &name, bool recurse) const {
|
||||
Typedefs::const_iterator ti;
|
||||
ti = _typedefs.find(name);
|
||||
if (ti != _typedefs.end()) {
|
||||
return (*ti).second->_type;
|
||||
Types::const_iterator ti;
|
||||
ti = _types.find(name);
|
||||
if (ti != _types.end()) {
|
||||
return ti->second;
|
||||
}
|
||||
|
||||
Using::const_iterator ui;
|
||||
|
|
@ -509,11 +511,11 @@ find_type(const string &name, bool recurse) const {
|
|||
CPPType *CPPScope::
|
||||
find_type(const string &name, CPPDeclaration::SubstDecl &subst,
|
||||
CPPScope *global_scope, bool recurse) const {
|
||||
Typedefs::const_iterator ti;
|
||||
ti = _typedefs.find(name);
|
||||
if (ti != _typedefs.end()) {
|
||||
Types::const_iterator ti;
|
||||
ti = _types.find(name);
|
||||
if (ti != _types.end()) {
|
||||
CPPScope *current_scope = (CPPScope *)this;
|
||||
return (*ti).second->_type->substitute_decl
|
||||
return (*ti).second->substitute_decl
|
||||
(subst, current_scope, global_scope)->as_type();
|
||||
}
|
||||
|
||||
|
|
@ -562,10 +564,14 @@ find_scope(const string &name, bool recurse) const {
|
|||
|
||||
CPPType *type = (CPPType *)NULL;
|
||||
|
||||
Typedefs::const_iterator ti;
|
||||
ti = _typedefs.find(name);
|
||||
if (ti != _typedefs.end()) {
|
||||
type = (*ti).second->_type;
|
||||
Types::const_iterator ti;
|
||||
ti = _types.find(name);
|
||||
if (ti != _types.end()) {
|
||||
type = (*ti).second;
|
||||
// Resolve if this is a typedef.
|
||||
while (type->as_typedef_type() != (CPPTypedefType *)NULL) {
|
||||
type = type->as_typedef_type()->_type;
|
||||
}
|
||||
|
||||
} else if (_struct_type != NULL) {
|
||||
CPPStructType::Derivation::const_iterator di;
|
||||
|
|
@ -613,10 +619,17 @@ find_scope(const string &name, CPPDeclaration::SubstDecl &subst,
|
|||
if (type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Resolve this if it is a typedef.
|
||||
while (type->get_subtype() == CPPDeclaration::ST_typedef) {
|
||||
type = type->as_typedef_type()->_type;
|
||||
}
|
||||
|
||||
CPPStructType *st = type->as_struct_type();
|
||||
if (st == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return st->_scope;
|
||||
}
|
||||
|
||||
|
|
@ -631,10 +644,10 @@ find_symbol(const string &name, bool recurse) const {
|
|||
return _struct_type;
|
||||
}
|
||||
|
||||
Typedefs::const_iterator ti;
|
||||
ti = _typedefs.find(name);
|
||||
if (ti != _typedefs.end()) {
|
||||
return (*ti).second->_type;
|
||||
Types::const_iterator ti;
|
||||
ti = _types.find(name);
|
||||
if (ti != _types.end()) {
|
||||
return (*ti).second;
|
||||
}
|
||||
|
||||
Variables::const_iterator vi;
|
||||
|
|
@ -816,8 +829,7 @@ write(ostream &out, int indent_level, CPPScope *scope) const {
|
|||
}
|
||||
bool complete = false;
|
||||
|
||||
if (cd->as_typedef() != NULL || cd->as_type() != NULL ||
|
||||
cd->as_namespace() != NULL) {
|
||||
if (cd->as_type() != NULL || cd->as_namespace() != NULL) {
|
||||
complete = true;
|
||||
}
|
||||
|
||||
|
|
@ -880,7 +892,7 @@ copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
|
|||
}
|
||||
to_scope->_struct_type =
|
||||
new CPPStructType(_struct_type->_type,
|
||||
new CPPIdentifier(to_scope->_name),
|
||||
new CPPIdentifier(to_scope->_name, _struct_type->_file),
|
||||
native_scope, to_scope, _struct_type->_file);
|
||||
to_scope->_struct_type->_incomplete = false;
|
||||
|
||||
|
|
@ -985,11 +997,11 @@ copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
|
|||
}
|
||||
}
|
||||
|
||||
Typedefs::const_iterator ti;
|
||||
for (ti = _typedefs.begin(); ti != _typedefs.end(); ++ti) {
|
||||
CPPTypedef *td =
|
||||
(*ti).second->substitute_decl(subst, to_scope, global_scope)->as_typedef();
|
||||
to_scope->_typedefs.insert(Typedefs::value_type((*ti).first, td));
|
||||
Types::const_iterator ti;
|
||||
for (ti = _types.begin(); ti != _types.end(); ++ti) {
|
||||
CPPType *td =
|
||||
(*ti).second->substitute_decl(subst, to_scope, global_scope)->as_type();
|
||||
to_scope->_types.insert(Types::value_type((*ti).first, td));
|
||||
if (td != (*ti).second) {
|
||||
anything_changed = true;
|
||||
}
|
||||
|
|
@ -1004,6 +1016,15 @@ copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
|
|||
}
|
||||
}
|
||||
|
||||
for (vi = _enum_values.begin(); vi != _enum_values.end(); ++vi) {
|
||||
CPPInstance *inst =
|
||||
(*vi).second->substitute_decl(subst, to_scope, global_scope)->as_instance();
|
||||
to_scope->_enum_values.insert(Variables::value_type((*vi).first, inst));
|
||||
if (inst != (*vi).second) {
|
||||
anything_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
Templates::const_iterator tmi;
|
||||
for (tmi = _templates.begin(); tmi != _templates.end(); ++tmi) {
|
||||
CPPDeclaration *decl =
|
||||
|
|
@ -1027,24 +1048,17 @@ copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CPPScope::
|
||||
handle_declaration(CPPDeclaration *decl, CPPScope *global_scope) {
|
||||
CPPTypedef *def = decl->as_typedef();
|
||||
CPPTypedefType *def = decl->as_typedef_type();
|
||||
if (def != NULL) {
|
||||
string name = def->get_simple_name();
|
||||
_typedefs[name] = def;
|
||||
|
||||
_types[name] = def;
|
||||
|
||||
CPPExtensionType *et = def->_type->as_extension_type();
|
||||
if (et != NULL) {
|
||||
define_extension_type(et);
|
||||
}
|
||||
|
||||
if (!name.empty() && def->get_scope(this, global_scope) == this) {
|
||||
// Don't add a new template definition if we already had one
|
||||
// by the same name in another scope.
|
||||
|
||||
if (find_template(name) == NULL) {
|
||||
_templates.insert(Templates::value_type(name, def));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class CPPExtensionType;
|
|||
class CPPStructType;
|
||||
class CPPNamespace;
|
||||
class CPPUsing;
|
||||
class CPPTypedef;
|
||||
class CPPTypedefType;
|
||||
class CPPInstance;
|
||||
class CPPFunctionGroup;
|
||||
class CPPTemplateScope;
|
||||
|
|
@ -128,8 +128,8 @@ public:
|
|||
typedef map<string, CPPNamespace *> Namespaces;
|
||||
Namespaces _namespaces;
|
||||
|
||||
typedef map<string, CPPTypedef *> Typedefs;
|
||||
Typedefs _typedefs;
|
||||
typedef map<string, CPPType *> Types;
|
||||
Types _types;
|
||||
typedef map<string, CPPInstance *> Variables;
|
||||
Variables _variables;
|
||||
Variables _enum_values;
|
||||
|
|
|
|||
|
|
@ -99,6 +99,10 @@ output(ostream &out, int, CPPScope *, bool) const {
|
|||
}
|
||||
|
||||
switch (_type) {
|
||||
case T_unknown:
|
||||
out << "unknown";
|
||||
break;
|
||||
|
||||
case T_bool:
|
||||
out << "bool";
|
||||
break;
|
||||
|
|
@ -111,6 +115,14 @@ output(ostream &out, int, CPPScope *, bool) const {
|
|||
out << "wchar_t";
|
||||
break;
|
||||
|
||||
case T_char16_t:
|
||||
out << "char16_t";
|
||||
break;
|
||||
|
||||
case T_char32_t:
|
||||
out << "char32_t";
|
||||
break;
|
||||
|
||||
case T_int:
|
||||
out << "int";
|
||||
break;
|
||||
|
|
@ -127,10 +139,6 @@ output(ostream &out, int, CPPScope *, bool) const {
|
|||
out << "void";
|
||||
break;
|
||||
|
||||
case T_unknown:
|
||||
out << "unknown";
|
||||
break;
|
||||
|
||||
case T_parameter:
|
||||
out << "parameter";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,16 @@
|
|||
class CPPSimpleType : public CPPType {
|
||||
public:
|
||||
enum Type {
|
||||
T_unknown,
|
||||
T_bool,
|
||||
T_char,
|
||||
T_wchar_t, // Not strictly a builtin type, but we pretend.
|
||||
T_wchar_t,
|
||||
T_char16_t,
|
||||
T_char32_t,
|
||||
T_int,
|
||||
T_float,
|
||||
T_double,
|
||||
T_void,
|
||||
T_unknown,
|
||||
|
||||
// T_parameter is a special type which is assigned to expressions
|
||||
// that are discovered where a formal parameter was expected.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
|
||||
#include "cppStructType.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppScope.h"
|
||||
#include "cppTypeProxy.h"
|
||||
#include "cppTemplateScope.h"
|
||||
|
|
@ -91,6 +91,13 @@ operator = (const CPPStructType ©) {
|
|||
void CPPStructType::
|
||||
append_derivation(CPPType *base, CPPVisibility vis, bool is_virtual) {
|
||||
if (base != NULL) {
|
||||
// Unwrap any typedefs, since we can't inherit from a typedef.
|
||||
CPPTypedefType *def = base->as_typedef_type();
|
||||
while (def != NULL) {
|
||||
base = def->_type;
|
||||
def = base->as_typedef_type();
|
||||
}
|
||||
|
||||
Base b;
|
||||
b._base = base;
|
||||
b._vis = vis;
|
||||
|
|
@ -110,7 +117,6 @@ get_scope() const {
|
|||
return _scope;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPStructType::is_abstract
|
||||
// Access: Public
|
||||
|
|
@ -246,7 +252,7 @@ instantiate(const CPPTemplateParameterList *actual_params,
|
|||
// don't yet know what its associated struct type will be.
|
||||
|
||||
// Postpone the evaluation of this type.
|
||||
CPPIdentifier *ident = new CPPIdentifier(get_fully_scoped_name());
|
||||
CPPIdentifier *ident = new CPPIdentifier(get_fully_scoped_name(), _file);
|
||||
|
||||
return CPPType::new_type(new CPPTBDType(ident));
|
||||
}
|
||||
|
|
@ -318,7 +324,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
rep->_template_scope = (CPPTemplateScope *)NULL;
|
||||
CPPNameComponent nc(get_simple_name());
|
||||
nc.set_templ(pscope->_name.get_templ());
|
||||
rep->_ident = new CPPIdentifier(nc);
|
||||
rep->_ident = new CPPIdentifier(nc, _file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -356,7 +362,6 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
assert(rep != NULL);
|
||||
if (rep != this) {
|
||||
_instantiations.insert(rep);
|
||||
// cerr << "Subst for " << *this << " is " << *rep << "\n";
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
|
@ -377,15 +382,9 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
|||
|
||||
if (is_template()) {
|
||||
CPPTemplateScope *tscope = get_template_scope();
|
||||
out << "< ";
|
||||
tscope->_parameters.output(out, scope);
|
||||
out << " >";
|
||||
}
|
||||
|
||||
} else if (!complete && !_typedefs.empty()) {
|
||||
// If we have a typedef name, use it.
|
||||
out << _typedefs.front()->get_local_name(scope);
|
||||
|
||||
} else {
|
||||
if (is_template()) {
|
||||
get_template_scope()->_parameters.write_formal(out, scope);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ void CPPTemplateParameterList::
|
|||
build_subst_decl(const CPPTemplateParameterList &formal_params,
|
||||
CPPDeclaration::SubstDecl &subst,
|
||||
CPPScope *current_scope, CPPScope *global_scope) const {
|
||||
|
||||
Parameters::const_iterator pfi, pai;
|
||||
for (pfi = formal_params._parameters.begin(), pai = _parameters.begin();
|
||||
pfi != formal_params._parameters.end() && pai != _parameters.end();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include "cppExtensionType.h"
|
||||
#include "cppClassTemplateParameter.h"
|
||||
#include "cppIdentifier.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTemplateScope::Constructor
|
||||
|
|
@ -105,8 +105,9 @@ add_template_parameter(CPPDeclaration *param) {
|
|||
if (cl != NULL) {
|
||||
// Create an implicit typedef for this class parameter.
|
||||
string name = cl->_ident->get_local_name();
|
||||
_typedefs[name] = new CPPTypedef(new CPPInstance(cl, cl->_ident), false);
|
||||
_types[name] = cl;
|
||||
}
|
||||
|
||||
CPPInstance *inst = param->as_instance();
|
||||
if (inst != NULL) {
|
||||
// Register the variable for this value parameter.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
|
||||
#include "cppType.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include <algorithm>
|
||||
|
||||
CPPType::Types CPPType::_types;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include <set>
|
||||
|
||||
class CPPType;
|
||||
class CPPTypedef;
|
||||
class CPPTypedefType;
|
||||
class CPPTypeDeclaration;
|
||||
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ public:
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class CPPType : public CPPDeclaration {
|
||||
public:
|
||||
typedef vector<CPPTypedef *> Typedefs;
|
||||
typedef vector<CPPTypedefType *> Typedefs;
|
||||
Typedefs _typedefs;
|
||||
|
||||
CPPType(const CPPFile &file);
|
||||
|
|
|
|||
|
|
@ -357,6 +357,19 @@ as_tbd_type() {
|
|||
return _actual_type->as_tbd_type();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypeProxy::as_typedef_type
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedefType *CPPTypeProxy::
|
||||
as_typedef_type() {
|
||||
if (_actual_type == (CPPType *)NULL) {
|
||||
return (CPPTypedefType *)NULL;
|
||||
}
|
||||
return _actual_type->as_typedef_type();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypeProxy::as_type_proxy
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -366,4 +379,3 @@ CPPTypeProxy *CPPTypeProxy::
|
|||
as_type_proxy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "cppType.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : CPPTypeProxy
|
||||
// Description : This is a special kind of type that is a placeholder
|
||||
|
|
@ -66,6 +65,7 @@ public:
|
|||
virtual CPPStructType *as_struct_type();
|
||||
virtual CPPEnumType *as_enum_type();
|
||||
virtual CPPTBDType *as_tbd_type();
|
||||
virtual CPPTypedefType *as_typedef_type();
|
||||
virtual CPPTypeProxy *as_type_proxy();
|
||||
|
||||
CPPType *_actual_type;
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
// Filename: cppTypedef.cxx
|
||||
// Created by: drose (19Oct99)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "cppTypedef.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedef::Constructor
|
||||
// Access: Public
|
||||
// Description: Constructs a new CPPTypedef object based on the
|
||||
// indicated CPPInstance object. The CPPInstance is
|
||||
// deallocated.
|
||||
//
|
||||
// If global is true, the typedef is defined at the
|
||||
// global scope, and hence it's worth telling the type
|
||||
// itself about. Otherwise, it's just a locally-scoped
|
||||
// typedef.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedef::
|
||||
CPPTypedef(CPPInstance *inst, bool global) : CPPInstance(*inst)
|
||||
{
|
||||
// Actually, we'll avoid deleting this for now. It causes problems
|
||||
// for some reason to be determined later.
|
||||
// delete inst;
|
||||
|
||||
assert(_type != NULL);
|
||||
if (global) {
|
||||
_type->_typedefs.push_back(this);
|
||||
CPPType::record_alt_name_for(_type, inst->get_local_name());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedef::substitute_decl
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPDeclaration *CPPTypedef::
|
||||
substitute_decl(CPPDeclaration::SubstDecl &subst,
|
||||
CPPScope *current_scope, CPPScope *global_scope) {
|
||||
CPPDeclaration *decl =
|
||||
CPPInstance::substitute_decl(subst, current_scope, global_scope);
|
||||
assert(decl != NULL);
|
||||
if (decl->as_typedef()) {
|
||||
return decl;
|
||||
}
|
||||
assert(decl->as_instance() != NULL);
|
||||
return new CPPTypedef(new CPPInstance(*decl->as_instance()), false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedef::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CPPTypedef::
|
||||
output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
||||
out << "typedef ";
|
||||
CPPInstance::output(out, indent_level, scope, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedef::get_subtype
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPDeclaration::SubType CPPTypedef::
|
||||
get_subtype() const {
|
||||
return ST_typedef;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedef::as_typedef
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedef *CPPTypedef::
|
||||
as_typedef() {
|
||||
return this;
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
// Filename: cppTypedef.h
|
||||
// Created by: drose (19Oct99)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CPPTYPEDEF_H
|
||||
#define CPPTYPEDEF_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#include "cppInstance.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : CPPTypedef
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class CPPTypedef : public CPPInstance {
|
||||
public:
|
||||
CPPTypedef(CPPInstance *instance, bool global);
|
||||
|
||||
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
|
||||
CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
bool complete) const;
|
||||
virtual SubType get_subtype() const;
|
||||
|
||||
virtual CPPTypedef *as_typedef();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,388 @@
|
|||
// Filename: cppTypedefType.cxx
|
||||
// Created by: rdb (01Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppIdentifier.h"
|
||||
#include "cppInstanceIdentifier.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedefType::
|
||||
CPPTypedefType(CPPType *type, const string &name, CPPScope *current_scope) :
|
||||
CPPType(CPPFile()),
|
||||
_type(type),
|
||||
_ident(new CPPIdentifier(name))
|
||||
{
|
||||
if (_ident != NULL) {
|
||||
_ident->_native_scope = current_scope;
|
||||
}
|
||||
|
||||
_subst_decl_recursive_protect = false;
|
||||
|
||||
//assert(_type != NULL);
|
||||
//if (global) {
|
||||
// _type->_typedefs.push_back(this);
|
||||
// CPPType::record_alt_name_for(_type, inst->get_local_name());
|
||||
//}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedefType::
|
||||
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
|
||||
CPPType(CPPFile()),
|
||||
_type(type),
|
||||
_ident(ident)
|
||||
{
|
||||
if (_ident != NULL) {
|
||||
_ident->_native_scope = current_scope;
|
||||
}
|
||||
_subst_decl_recursive_protect = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::Constructor
|
||||
// Access: Public
|
||||
// Description: Constructs a new CPPTypedefType object that defines a
|
||||
// typedef to the indicated type according to the type
|
||||
// and the InstanceIdentifier. The InstanceIdentifier
|
||||
// pointer is deallocated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedefType::
|
||||
CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
|
||||
CPPScope *current_scope, const CPPFile &file) :
|
||||
CPPType(file)
|
||||
{
|
||||
_type = ii->unroll_type(type);
|
||||
_ident = ii->_ident;
|
||||
ii->_ident = NULL;
|
||||
delete ii;
|
||||
|
||||
if (_ident != NULL) {
|
||||
_ident->_native_scope = current_scope;
|
||||
}
|
||||
|
||||
_subst_decl_recursive_protect = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_scoped
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_scoped() const {
|
||||
if (_ident == NULL) {
|
||||
return false;
|
||||
} else {
|
||||
return _ident->is_scoped();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::get_scope
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPScope *CPPTypedefType::
|
||||
get_scope(CPPScope *current_scope, CPPScope *global_scope,
|
||||
CPPPreprocessor *error_sink) const {
|
||||
if (_ident == NULL) {
|
||||
return current_scope;
|
||||
} else {
|
||||
return _ident->get_scope(current_scope, global_scope, error_sink);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::get_simple_name
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CPPTypedefType::
|
||||
get_simple_name() const {
|
||||
if (_ident == NULL) {
|
||||
return "";
|
||||
}
|
||||
return _ident->get_simple_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::get_local_name
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CPPTypedefType::
|
||||
get_local_name(CPPScope *scope) const {
|
||||
if (_ident == NULL) {
|
||||
return "";
|
||||
}
|
||||
return _ident->get_local_name(scope);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::get_fully_scoped_name
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string CPPTypedefType::
|
||||
get_fully_scoped_name() const {
|
||||
if (_ident == NULL) {
|
||||
return "";
|
||||
}
|
||||
return _ident->get_fully_scoped_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_incomplete
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type has not yet been fully
|
||||
// specified, false if it has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_incomplete() const {
|
||||
return false;
|
||||
//return _type->is_incomplete();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_tbd
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type, or any nested type within
|
||||
// the type, is a CPPTBDType and thus isn't fully
|
||||
// determined right now. In this case, calling
|
||||
// resolve_type() may or may not resolve the type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_tbd() const {
|
||||
if (_ident != NULL && _ident->is_tbd()) {
|
||||
return true;
|
||||
}
|
||||
return _type->is_tbd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_fully_specified
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this declaration is an actual,
|
||||
// factual declaration, or false if some part of the
|
||||
// declaration depends on a template parameter which has
|
||||
// not yet been instantiated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_fully_specified() const {
|
||||
if (_ident != NULL && !_ident->is_fully_specified()) {
|
||||
return false;
|
||||
}
|
||||
return CPPDeclaration::is_fully_specified() &&
|
||||
_type->is_fully_specified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::substitute_decl
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPDeclaration *CPPTypedefType::
|
||||
substitute_decl(CPPDeclaration::SubstDecl &subst,
|
||||
CPPScope *current_scope, CPPScope *global_scope) {
|
||||
|
||||
return _type->substitute_decl(subst, current_scope, global_scope);
|
||||
|
||||
// Bah, this doesn't seem to work, and I can't figure out why.
|
||||
// Well, for now, let's just substitute it with the type we're
|
||||
// pointing to. This is not a huge deal for now, until we find
|
||||
// that we need to preserve these typedefs.
|
||||
|
||||
/*
|
||||
CPPDeclaration *top =
|
||||
CPPType::substitute_decl(subst, current_scope, global_scope);
|
||||
if (top != this) {
|
||||
return top;
|
||||
}
|
||||
|
||||
if (_subst_decl_recursive_protect) {
|
||||
// We're already executing this block; we'll have to return a
|
||||
// proxy to the type which we'll define later.
|
||||
CPPTypeProxy *proxy = new CPPTypeProxy;
|
||||
_proxies.push_back(proxy);
|
||||
assert(proxy != NULL);
|
||||
return proxy;
|
||||
}
|
||||
_subst_decl_recursive_protect = true;
|
||||
|
||||
CPPTypedefType *rep = new CPPTypedefType(*this);
|
||||
CPPDeclaration *new_type =
|
||||
_type->substitute_decl(subst, current_scope, global_scope);
|
||||
rep->_type = new_type->as_type();
|
||||
|
||||
if (rep->_type == NULL) {
|
||||
rep->_type = _type;
|
||||
}
|
||||
|
||||
if (_ident != NULL) {
|
||||
rep->_ident =
|
||||
_ident->substitute_decl(subst, current_scope, global_scope);
|
||||
}
|
||||
|
||||
if (rep->_type == _type && rep->_ident == _ident) {
|
||||
delete rep;
|
||||
rep = this;
|
||||
}
|
||||
|
||||
rep = CPPType::new_type(rep)->as_typedef_type();
|
||||
subst.insert(SubstDecl::value_type(this, rep));
|
||||
|
||||
_subst_decl_recursive_protect = false;
|
||||
// Now fill in all the proxies we created for our recursive
|
||||
// references.
|
||||
Proxies::iterator pi;
|
||||
for (pi = _proxies.begin(); pi != _proxies.end(); ++pi) {
|
||||
(*pi)->_actual_type = rep;
|
||||
}
|
||||
|
||||
return rep; */
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPFunctionType::resolve_type
|
||||
// Access: Public, Virtual
|
||||
// Description: If this CPPType object is a forward reference or
|
||||
// other nonspecified reference to a type that might now
|
||||
// be known a real type, returns the real type.
|
||||
// Otherwise returns the type itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPType *CPPTypedefType::
|
||||
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
|
||||
CPPType *ptype = _type->resolve_type(current_scope, global_scope);
|
||||
|
||||
if (ptype != _type) {
|
||||
CPPTypedefType *rep = new CPPTypedefType(*this);
|
||||
rep->_type = ptype;
|
||||
return CPPType::new_type(rep);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_equivalent_type
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a little more forgiving than is_equal(): it
|
||||
// returns true if the types appear to be referring to
|
||||
// the same thing, even if they may have different
|
||||
// pointers or somewhat different definitions. It's
|
||||
// useful for parameter matching, etc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_equivalent(const CPPType &other) const {
|
||||
CPPType *ot = (CPPType *)&other;
|
||||
|
||||
// Unwrap all the typedefs to get to where it is pointing.
|
||||
while (ot->get_subtype() == ST_typedef) {
|
||||
ot = ot->as_typedef_type()->_type;
|
||||
}
|
||||
|
||||
// Compare the unwrapped type to what we are pointing to.
|
||||
// If we are pointing to a typedef ourselves, then this will
|
||||
// automatically recurse.
|
||||
return _type->is_equivalent(*ot);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CPPTypedefType::
|
||||
output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
||||
string name;
|
||||
if (_ident != NULL) {
|
||||
name = _ident->get_local_name(scope);
|
||||
}
|
||||
|
||||
if (complete) {
|
||||
out << "typedef ";
|
||||
_type->output_instance(out, indent_level, scope, false, "", name);
|
||||
} else {
|
||||
out << name;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::get_subtype
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPDeclaration::SubType CPPTypedefType::
|
||||
get_subtype() const {
|
||||
return ST_typedef;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::as_typedef_type
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPPTypedefType *CPPTypedefType::
|
||||
as_typedef_type() {
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_equal
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called by CPPDeclaration() to determine whether this type is
|
||||
// equivalent to another type of the same type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_equal(const CPPDeclaration *other) const {
|
||||
const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
|
||||
assert(ot != NULL);
|
||||
|
||||
return (_type == ot->_type) && (*_ident == *ot->_ident);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_less
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called by CPPDeclaration() to determine whether this type
|
||||
// should be ordered before another type of the same
|
||||
// type, in an arbitrary but fixed ordering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_less(const CPPDeclaration *other) const {
|
||||
return CPPDeclaration::is_less(other);
|
||||
|
||||
// The below code causes a crash for unknown reasons.
|
||||
/*
|
||||
const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
|
||||
assert(ot != NULL);
|
||||
|
||||
if (_type != ot->_type) {
|
||||
return _type < ot->_type;
|
||||
}
|
||||
|
||||
if (*_ident != *ot->_ident) {
|
||||
return *_ident < *ot->_ident;
|
||||
}
|
||||
|
||||
return false; */
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Filename: cppTypedefType.h
|
||||
// Created by: rdb (01Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CPPTYPEDEFTYPE_H
|
||||
#define CPPTYPEDEFTYPE_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
#include "cppType.h"
|
||||
|
||||
class CPPIdentifier;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : CPPTypedefType
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class CPPTypedefType : public CPPType {
|
||||
public:
|
||||
CPPTypedefType(CPPType *type, const string &name, CPPScope *current_scope);
|
||||
CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope);
|
||||
CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
|
||||
CPPScope *current_scope, const CPPFile &file);
|
||||
|
||||
bool is_scoped() const;
|
||||
CPPScope *get_scope(CPPScope *current_scope, CPPScope *global_scope,
|
||||
CPPPreprocessor *error_sink = NULL) const;
|
||||
|
||||
virtual string get_simple_name() const;
|
||||
virtual string get_local_name(CPPScope *scope = NULL) const;
|
||||
virtual string get_fully_scoped_name() const;
|
||||
|
||||
virtual bool is_incomplete() const;
|
||||
virtual bool is_tbd() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
|
||||
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
|
||||
CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
|
||||
virtual CPPType *resolve_type(CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
bool complete) const;
|
||||
virtual SubType get_subtype() const;
|
||||
|
||||
virtual CPPTypedefType *as_typedef_type();
|
||||
|
||||
CPPType *_type;
|
||||
CPPIdentifier *_ident;
|
||||
|
||||
protected:
|
||||
virtual bool is_equal(const CPPDeclaration *other) const;
|
||||
virtual bool is_less(const CPPDeclaration *other) const;
|
||||
|
||||
bool _subst_decl_recursive_protect;
|
||||
typedef vector<CPPTypeProxy *> Proxies;
|
||||
Proxies _proxies;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -18,13 +18,8 @@
|
|||
#include "cppTypeDeclaration.cxx"
|
||||
#include "cppTypeParser.cxx"
|
||||
#include "cppTypeProxy.cxx"
|
||||
#include "cppTypedefType.cxx"
|
||||
#include "cppSimpleType.cxx"
|
||||
#include "cppTBDType.cxx"
|
||||
#include "cppTypedef.cxx"
|
||||
#include "cppUsing.cxx"
|
||||
#include "cppVisibility.cxx"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,15 @@
|
|||
#include "dtoolbase.h"
|
||||
#include "selectThreadImpl.h"
|
||||
|
||||
#if defined(THREAD_DUMMY_IMPL)||defined(THREAD_SIMPLE_IMPL)
|
||||
#if defined(CPPPARSER)
|
||||
|
||||
struct AtomicAdjust {
|
||||
typedef long Integer;
|
||||
typedef void *UnalignedPointer;
|
||||
typedef UnalignedPointer Pointer;
|
||||
};
|
||||
|
||||
#elif defined(THREAD_DUMMY_IMPL) || defined(THREAD_SIMPLE_IMPL)
|
||||
|
||||
#include "atomicAdjustDummyImpl.h"
|
||||
typedef AtomicAdjustDummyImpl AtomicAdjust;
|
||||
|
|
|
|||
|
|
@ -16,33 +16,9 @@
|
|||
#include "typeRegistryNode.h"
|
||||
#include "atomicAdjust.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#include "Python.h"
|
||||
#endif
|
||||
|
||||
// This is initialized to zero by static initialization.
|
||||
TypeHandle TypeHandle::_none;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeHandle::make
|
||||
// Access: Published
|
||||
// Description: This special method allows coercion to a TypeHandle
|
||||
// from a Python class object or instance. It simply
|
||||
// attempts to call classobj.get_class_type(), and
|
||||
// returns that value (or raises an exception if that
|
||||
// method doesn't work).
|
||||
//
|
||||
// This method allows a Python class object to be used
|
||||
// anywhere a TypeHandle is expected by the C++
|
||||
// interface.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *TypeHandle::
|
||||
make(PyObject *classobj) {
|
||||
return PyObject_CallMethod(classobj, (char *)"get_class_type", (char *)"");
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeHandle::get_memory_usage
|
||||
|
|
@ -80,7 +56,10 @@ inc_memory_usage(MemoryClass memory_class, int size) {
|
|||
assert(rnode != (TypeRegistryNode *)NULL);
|
||||
AtomicAdjust::add(rnode->_memory_usage[memory_class], (AtomicAdjust::Integer)size);
|
||||
//cerr << *this << ".inc(" << memory_class << ", " << size << ") -> " << rnode->_memory_usage[memory_class] << "\n";
|
||||
assert(rnode->_memory_usage[memory_class] >= 0);
|
||||
if (rnode->_memory_usage[memory_class] < 0) {
|
||||
cerr << "Memory usage overflow for type " << *this << ".\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
|
|
|||
|
|
@ -65,13 +65,6 @@
|
|||
|
||||
class TypedObject;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#ifndef PyObject_HEAD
|
||||
struct _object;
|
||||
typedef _object PyObject;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TypeHandle
|
||||
// Description : TypeHandle is the identifier used to differentiate
|
||||
|
|
@ -105,9 +98,7 @@ PUBLISHED:
|
|||
INLINE TypeHandle();
|
||||
INLINE TypeHandle(const TypeHandle ©);
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
static PyObject *make(PyObject *classobj);
|
||||
#endif // HAVE_PYTHON
|
||||
EXTENSION(static TypeHandle make(PyTypeObject *classobj));
|
||||
|
||||
INLINE bool operator == (const TypeHandle &other) const;
|
||||
INLINE bool operator != (const TypeHandle &other) const;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
filename.h \
|
||||
$[if $[IS_OSX],filename_assist.mm filename_assist.h,] \
|
||||
globPattern.I globPattern.h \
|
||||
lineStream.I lineStream.h \
|
||||
lineStreamBuf.I lineStreamBuf.h \
|
||||
load_dso.h \
|
||||
pandaFileStream.h pandaFileStream.I \
|
||||
pandaFileStreamBuf.h \
|
||||
|
|
@ -38,6 +40,7 @@
|
|||
dSearchPath.cxx \
|
||||
executionEnvironment.cxx filename.cxx \
|
||||
globPattern.cxx \
|
||||
lineStream.cxx lineStreamBuf.cxx \
|
||||
load_dso.cxx \
|
||||
pandaFileStream.cxx pandaFileStreamBuf.cxx \
|
||||
pandaSystem.cxx \
|
||||
|
|
@ -58,6 +61,8 @@
|
|||
executionEnvironment.I executionEnvironment.h filename.I \
|
||||
filename.h \
|
||||
globPattern.I globPattern.h \
|
||||
lineStream.I lineStream.h \
|
||||
lineStreamBuf.I lineStreamBuf.h \
|
||||
load_dso.h \
|
||||
pandaFileStream.h pandaFileStream.I \
|
||||
pandaFileStreamBuf.h \
|
||||
|
|
|
|||
|
|
@ -306,6 +306,17 @@ operator + (const string &other) const {
|
|||
return a;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::operator /
|
||||
// Access: Published
|
||||
// Description: Returns a new Filename that is composed of the
|
||||
// other filename added to the end of this filename,
|
||||
// with an intervening slash added if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Filename Filename::
|
||||
operator / (const Filename &other) const {
|
||||
return Filename(*this, other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::get_fullpath
|
||||
|
|
|
|||
|
|
@ -308,30 +308,6 @@ Filename(const Filename &dirname, const Filename &basename) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::__reduce__
|
||||
// Access: Published
|
||||
// Description: This special Python method is implement to provide
|
||||
// support for the pickle module.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *Filename::
|
||||
__reduce__(PyObject *self) const {
|
||||
// We should return at least a 2-tuple, (Class, (args)): the
|
||||
// necessary class object whose constructor we should call
|
||||
// (e.g. this), and the arguments necessary to reconstruct this
|
||||
// object.
|
||||
PyObject *this_class = PyObject_Type(self);
|
||||
if (this_class == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *result = Py_BuildValue("(O(s))", this_class, c_str());
|
||||
Py_DECREF(this_class);
|
||||
return result;
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::from_os_specific
|
||||
// Access: Published, Static
|
||||
|
|
@ -2005,49 +1981,13 @@ scan_directory(vector_string &contents) const {
|
|||
globfree(&globbuf);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
#else
|
||||
// Don't know how to scan directories!
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::scan_directory
|
||||
// Access: Published
|
||||
// Description: This variant on scan_directory returns a Python list
|
||||
// of strings on success, or None on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *Filename::
|
||||
scan_directory() const {
|
||||
vector_string contents;
|
||||
if (!scan_directory(contents)) {
|
||||
PyObject *result = Py_None;
|
||||
Py_INCREF(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject *result = PyList_New(contents.size());
|
||||
for (size_t i = 0; i < contents.size(); ++i) {
|
||||
const string &filename = contents[i];
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
// This function expects UTF-8.
|
||||
PyObject *str = PyUnicode_FromStringAndSize(filename.data(), filename.size());
|
||||
#else
|
||||
PyObject *str = PyString_FromStringAndSize(filename.data(), filename.size());
|
||||
#endif
|
||||
#ifdef Py_LIMITED_API
|
||||
PyList_SetItem(result, i, str);
|
||||
#else
|
||||
PyList_SET_ITEM(result, i, str);
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::open_read
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ PUBLISHED:
|
|||
INLINE ~Filename();
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject *__reduce__(PyObject *self) const;
|
||||
EXTENSION(PyObject *__reduce__(PyObject *self) const);
|
||||
#endif
|
||||
|
||||
// Static constructors to explicitly create a filename that refers
|
||||
|
|
@ -116,6 +116,8 @@ PUBLISHED:
|
|||
INLINE void operator += (const string &other);
|
||||
INLINE Filename operator + (const string &other) const;
|
||||
|
||||
INLINE Filename operator / (const Filename &other) const;
|
||||
|
||||
// Or, you can use any of these.
|
||||
INLINE string get_fullpath() const;
|
||||
INLINE wstring get_fullpath_w() const;
|
||||
|
|
@ -190,11 +192,11 @@ PUBLISHED:
|
|||
const string &default_extension = string());
|
||||
bool make_relative_to(Filename directory, bool allow_backups = true);
|
||||
int find_on_searchpath(const DSearchPath &searchpath);
|
||||
|
||||
|
||||
bool scan_directory(vector_string &contents) const;
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject *scan_directory() const;
|
||||
#endif
|
||||
EXTENSION(PyObject *scan_directory() const);
|
||||
#endif
|
||||
|
||||
bool open_read(ifstream &stream) const;
|
||||
bool open_write(ofstream &stream, bool truncate = true) const;
|
||||
|
|
|
|||
|
|
@ -113,44 +113,12 @@ match_files(vector_string &results, const Filename &cwd) const {
|
|||
pattern = source.substr(0, slash);
|
||||
suffix = source.substr(slash + 1);
|
||||
}
|
||||
|
||||
|
||||
GlobPattern glob(pattern);
|
||||
glob.set_case_sensitive(_case_sensitive);
|
||||
return glob.r_match_files(prefix, suffix, results, cwd);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GlobPattern::match_files
|
||||
// Access: Published
|
||||
// Description: This variant on match_files returns a Python list
|
||||
// of strings.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *GlobPattern::
|
||||
match_files(const Filename &cwd) const {
|
||||
vector_string contents;
|
||||
match_files(contents, cwd);
|
||||
|
||||
PyObject *result = PyList_New(contents.size());
|
||||
for (size_t i = 0; i < contents.size(); ++i) {
|
||||
const string &filename = contents[i];
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
// This function expects UTF-8.
|
||||
PyObject *str = PyUnicode_FromStringAndSize(filename.data(), filename.size());
|
||||
#else
|
||||
PyObject *str = PyString_FromStringAndSize(filename.data(), filename.size());
|
||||
#endif
|
||||
#ifdef Py_LIMITED_API
|
||||
PyList_SetItem(result, i, str);
|
||||
#else
|
||||
PyList_SET_ITEM(result, i, str);
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GlobPattern::r_match_files
|
||||
// Access: Private
|
||||
|
|
@ -195,21 +163,21 @@ r_match_files(const Filename &prefix, const string &suffix,
|
|||
return next_glob.r_match_files(Filename(prefix, _pattern),
|
||||
next_suffix, results, cwd);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// If there *are* special glob characters, we must attempt to
|
||||
// match the pattern against the files in this directory.
|
||||
|
||||
|
||||
vector_string dir_files;
|
||||
if (!parent_dir.scan_directory(dir_files)) {
|
||||
// Not a directory, or unable to read directory; stop here.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Now go through each file in the directory looking for one that
|
||||
// matches the pattern.
|
||||
int num_matched = 0;
|
||||
|
||||
|
||||
vector_string::const_iterator fi;
|
||||
for (fi = dir_files.begin(); fi != dir_files.end(); ++fi) {
|
||||
const string &local_file = (*fi);
|
||||
|
|
@ -218,7 +186,7 @@ r_match_files(const Filename &prefix, const string &suffix,
|
|||
// We have a match; continue.
|
||||
if (suffix.empty()) {
|
||||
results.push_back(Filename(prefix, local_file));
|
||||
num_matched++;
|
||||
num_matched++;
|
||||
} else {
|
||||
num_matched += next_glob.r_match_files(Filename(prefix, local_file),
|
||||
next_suffix, results, cwd);
|
||||
|
|
@ -226,7 +194,7 @@ r_match_files(const Filename &prefix, const string &suffix,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return num_matched;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ PUBLISHED:
|
|||
string get_const_prefix() const;
|
||||
int match_files(vector_string &results, const Filename &cwd = Filename()) const;
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject *match_files(const Filename &cwd = Filename()) const;
|
||||
#endif
|
||||
EXTENSION(PyObject *match_files(const Filename &cwd = Filename()) const);
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool matches_substr(string::const_iterator pi,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef LINESTREAM_H
|
||||
#define LINESTREAM_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#include "lineStreamBuf.h"
|
||||
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
// More text can still be written to it and continuously
|
||||
// extracted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_PUTIL LineStream : public ostream {
|
||||
class EXPCL_DTOOL LineStream : public ostream {
|
||||
PUBLISHED:
|
||||
INLINE LineStream();
|
||||
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef LINESTREAMBUF_H
|
||||
#define LINESTREAMBUF_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
// continuously extracted as a sequence of lines of
|
||||
// text.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_PUTIL LineStreamBuf : public streambuf {
|
||||
class EXPCL_DTOOL LineStreamBuf : public streambuf {
|
||||
public:
|
||||
LineStreamBuf();
|
||||
virtual ~LineStreamBuf();
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
#include "executionEnvironment.cxx"
|
||||
#include "filename.cxx"
|
||||
#include "globPattern.cxx"
|
||||
#include "lineStream.cxx"
|
||||
#include "lineStreamBuf.cxx"
|
||||
#include "load_dso.cxx"
|
||||
#include "pandaSystem.cxx"
|
||||
|
||||
|
|
|
|||
|
|
@ -275,7 +275,6 @@ make_wrapper_entry(FunctionIndex function_index) {
|
|||
iwrapper._comment = InterrogateBuilder::trim_blanks(_cppfunc->_leading_comment->_comment);
|
||||
}
|
||||
|
||||
|
||||
if (output_function_names) {
|
||||
// If we're keeping the function names, record that the wrapper is
|
||||
// callable.
|
||||
|
|
@ -413,14 +412,26 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
|||
separator = ", ";
|
||||
}
|
||||
|
||||
for (int pn = _first_true_parameter;
|
||||
pn < (int)_parameters.size();
|
||||
++pn) {
|
||||
int pn = _first_true_parameter;
|
||||
int num_parameters = _parameters.size();
|
||||
|
||||
if (_type == T_item_assignment_operator) {
|
||||
// The last parameter is the value to set.
|
||||
--num_parameters;
|
||||
}
|
||||
|
||||
for (pn = _first_true_parameter;
|
||||
pn < num_parameters; ++pn) {
|
||||
call << separator;
|
||||
_parameters[pn]._remap->pass_parameter(call, get_parameter_expr(pn, pexprs));
|
||||
separator = ", ";
|
||||
}
|
||||
call << ")";
|
||||
|
||||
if (_type == T_item_assignment_operator) {
|
||||
call << " = ";
|
||||
_parameters[pn]._remap->pass_parameter(call, get_parameter_expr(pn, pexprs));
|
||||
}
|
||||
}
|
||||
|
||||
return call.str();
|
||||
|
|
@ -484,6 +495,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
|
||||
string fname = _cppfunc->get_simple_name();
|
||||
CPPType *rtype = _ftype->_return_type->resolve_type(&parser, _cppscope);
|
||||
|
||||
if (_cpptype != (CPPType *)NULL &&
|
||||
((_cppfunc->_storage_class & CPPInstance::SC_static) == 0) &&
|
||||
|
|
@ -520,13 +532,22 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
fname == "operator <<=" ||
|
||||
fname == "operator >>=") {
|
||||
_type = T_assignment_method;
|
||||
|
||||
} else if (fname == "operator []" && !_const_method && rtype != NULL) {
|
||||
// Check if this is an item-assignment operator.
|
||||
CPPReferenceType *reftype = rtype->as_reference_type();
|
||||
if (reftype != NULL && reftype->_pointing_at->as_const_type() == NULL) {
|
||||
// It returns a mutable reference.
|
||||
_type = T_item_assignment_operator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CPPParameterList::Parameters ¶ms =
|
||||
_ftype->_parameters->_parameters;
|
||||
for (int i = 0; i < (int)params.size() - _num_default_parameters; i++) {
|
||||
CPPType *type = params[i]->_type->resolve_type(&parser, _cppscope);
|
||||
//CPPType *type = params[i]->_type->resolve_type(&parser, _cppscope);
|
||||
CPPType *type = params[i]->_type;
|
||||
Parameter param;
|
||||
param._has_name = true;
|
||||
param._name = params[i]->get_simple_name();
|
||||
|
|
@ -588,9 +609,39 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
}
|
||||
|
||||
} else if (_type == T_item_assignment_operator) {
|
||||
// An item-assignment method isn't really a thing in C++, but it is
|
||||
// in scripting languages, so we use this to denote item-access operators
|
||||
// that return a non-const reference.
|
||||
|
||||
if (_cpptype == (CPPType *)NULL) {
|
||||
nout << "Method " << *_cppfunc << " has no struct type\n";
|
||||
return false;
|
||||
} else {
|
||||
// Synthesize a const reference parameter for the assignment.
|
||||
CPPType *bare_type = TypeManager::unwrap_reference(rtype);
|
||||
CPPType *const_type = CPPType::new_type(new CPPConstType(bare_type));
|
||||
CPPType *ref_type = CPPType::new_type(new CPPReferenceType(const_type));
|
||||
|
||||
Parameter param;
|
||||
param._has_name = true;
|
||||
param._name = "assign_val";
|
||||
param._remap = interface_maker->remap_parameter(_cpptype, ref_type);
|
||||
|
||||
if (param._remap == NULL || !param._remap->is_valid()) {
|
||||
nout << "Invalid remap for assignment type of method " << *_cppfunc << "\n";
|
||||
return false;
|
||||
}
|
||||
_parameters.push_back(param);
|
||||
|
||||
// Pretend we don't return anything at all.
|
||||
CPPType *void_type = TypeManager::get_void_type();
|
||||
_return_type = interface_maker->remap_parameter(_cpptype, void_type);
|
||||
_void_return = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// The normal case.
|
||||
CPPType *rtype = _ftype->_return_type->resolve_type(&parser, _cppscope);
|
||||
_return_type = interface_maker->remap_parameter(_cpptype, rtype);
|
||||
if (_return_type != (ParameterRemap *)NULL) {
|
||||
_void_return = TypeManager::is_void(rtype);
|
||||
|
|
@ -639,7 +690,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
|
||||
if (_has_this || _type == T_constructor) {
|
||||
if (_parameters.size() > first_param && _parameters[first_param]._name == "self" &&
|
||||
if ((int)_parameters.size() > first_param && _parameters[first_param]._name == "self" &&
|
||||
TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) {
|
||||
// Here's a special case. If the first parameter of a nonstatic
|
||||
// method is a PyObject * called "self", then we will
|
||||
|
|
@ -650,9 +701,9 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
}
|
||||
|
||||
if (_parameters.size() == first_param) {
|
||||
if ((int)_parameters.size() == first_param) {
|
||||
_args_type = InterfaceMaker::AT_no_args;
|
||||
} else if (_parameters.size() == first_param + 1) {
|
||||
} else if ((int)_parameters.size() == first_param + 1) {
|
||||
_args_type = InterfaceMaker::AT_single_arg;
|
||||
} else {
|
||||
_args_type = InterfaceMaker::AT_varargs;
|
||||
|
|
@ -669,8 +720,8 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
|
||||
} else if (fname == "__setitem__") {
|
||||
_flags |= F_setitem;
|
||||
if (_has_this && _parameters.size() > 2) {
|
||||
_flags |= F_setitem;
|
||||
if (TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
|
||||
// Its first parameter is an int parameter, presumably an index.
|
||||
_flags |= F_setitem_int;
|
||||
|
|
@ -678,6 +729,16 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
}
|
||||
|
||||
} else if (fname == "__delitem__") {
|
||||
if (_has_this && _parameters.size() == 2) {
|
||||
_flags |= F_delitem;
|
||||
if (TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
|
||||
// Its first parameter is an int parameter, presumably an index.
|
||||
_flags |= F_delitem_int;
|
||||
_args_type = InterfaceMaker::AT_single_arg;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (fname == "size" || fname == "__len__") {
|
||||
if ((int)_parameters.size() == first_param &&
|
||||
TypeManager::is_integer(_return_type->get_new_type())) {
|
||||
|
|
@ -722,11 +783,20 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
_flags |= F_compare_to;
|
||||
}
|
||||
|
||||
} else if (fname == "make") {
|
||||
if (!_has_this && _parameters.size() >= 1 &&
|
||||
TypeManager::is_pointer(_return_type->get_new_type())) {
|
||||
// We can use this for coercion.
|
||||
_flags |= F_coerce_constructor;
|
||||
}
|
||||
|
||||
} else if (fname == "operator ()" || fname == "__call__") {
|
||||
// Call operators always take keyword arguments.
|
||||
_args_type = InterfaceMaker::AT_keyword_args;
|
||||
|
||||
} else if (fname == "__setattr__" || fname == "__getattr__") {
|
||||
} else if (fname == "__setattr__"
|
||||
|| fname == "__getattr__"
|
||||
|| fname == "__delattr__") {
|
||||
// Just to prevent these from getting keyword arguments.
|
||||
|
||||
} else {
|
||||
|
|
@ -737,6 +807,19 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
}
|
||||
|
||||
} else if (_type == T_item_assignment_operator) {
|
||||
// The concept of "item assignment operator" doesn't really exist in C++,
|
||||
// but it does in scripting languages, and this allows us to wrap cases
|
||||
// where the C++ getitem returns an assignable reference.
|
||||
_flags |= F_setitem;
|
||||
if (_has_this && _parameters.size() > 2) {
|
||||
if (TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
|
||||
// Its first parameter is an int parameter, presumably an index.
|
||||
_flags |= F_setitem_int;
|
||||
}
|
||||
}
|
||||
_args_type = InterfaceMaker::AT_varargs;
|
||||
|
||||
} else if (_type == T_constructor) {
|
||||
if (!_has_this && _parameters.size() == 1 &&
|
||||
TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
|
||||
|
|
@ -745,7 +828,12 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
// "this" type, this is a copy constructor.
|
||||
_flags |= F_copy_constructor;
|
||||
|
||||
} else if (!_has_this && _parameters.size() > 0 &&
|
||||
(_cppfunc->_storage_class & CPPInstance::SC_explicit) == 0) {
|
||||
// A non-explicit non-copy constructor might be eligible for coercion.
|
||||
_flags |= F_coerce_constructor;
|
||||
}
|
||||
|
||||
// Constructors always take varargs and keyword args.
|
||||
_args_type = InterfaceMaker::AT_keyword_args;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,21 +76,25 @@ public:
|
|||
T_typecast,
|
||||
T_getter,
|
||||
T_setter,
|
||||
T_item_assignment_operator,
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
F_getitem = 0x0001,
|
||||
F_getitem_int = 0x0002,
|
||||
F_size = 0x0004,
|
||||
F_setitem = 0x0008,
|
||||
F_setitem_int = 0x0010,
|
||||
F_make_copy = 0x0020,
|
||||
F_copy_constructor = 0x0040,
|
||||
F_explicit_self = 0x0080,
|
||||
F_iter = 0x0100,
|
||||
F_getbuffer = 0x0200,
|
||||
F_releasebuffer = 0x0400,
|
||||
F_compare_to = 0x0800,
|
||||
F_getitem = 0x0001,
|
||||
F_getitem_int = 0x0002,
|
||||
F_size = 0x0004,
|
||||
F_setitem = 0x0008,
|
||||
F_setitem_int = 0x0010,
|
||||
F_delitem = 0x0020,
|
||||
F_delitem_int = 0x0040,
|
||||
F_make_copy = 0x0080,
|
||||
F_copy_constructor = 0x0100,
|
||||
F_explicit_self = 0x0200,
|
||||
F_iter = 0x0400,
|
||||
F_getbuffer = 0x0800,
|
||||
F_releasebuffer = 0x1000,
|
||||
F_compare_to = 0x2000,
|
||||
F_coerce_constructor = 0x4000,
|
||||
};
|
||||
|
||||
typedef vector<Parameter> Parameters;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#include "pnotify.h"
|
||||
|
||||
InterrogateType dummy_type;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterfaceMaker::Function::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -59,7 +59,7 @@ Function(const string &name,
|
|||
_flags = 0;
|
||||
_args_type = AT_unknown;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterfaceMaker::Function::Destructor
|
||||
// Access: Public
|
||||
|
|
@ -72,7 +72,7 @@ InterfaceMaker::Function::
|
|||
delete (*ri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterfaceMaker::MakeSeq::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -143,7 +143,7 @@ check_protocols() {
|
|||
flags |= func->_flags;
|
||||
}
|
||||
|
||||
if ((flags & (FunctionRemap::F_getitem_int | FunctionRemap::F_size)) ==
|
||||
if ((flags & (FunctionRemap::F_getitem_int | FunctionRemap::F_size)) ==
|
||||
(FunctionRemap::F_getitem_int | FunctionRemap::F_size)) {
|
||||
// If we have both a getitem that receives an int, and a size,
|
||||
// then we implement the sequence protocol: you can iterate
|
||||
|
|
@ -169,8 +169,6 @@ check_protocols() {
|
|||
_protocol_types |= PT_iter;
|
||||
}
|
||||
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
|
||||
// Now are there any make_seq requests within this class?
|
||||
if (_itype._cpptype != NULL) {
|
||||
CPPStructType *stype = _itype._cpptype->as_struct_type();
|
||||
|
|
@ -269,18 +267,8 @@ generate_wrappers() {
|
|||
// traversal.
|
||||
int ti = 0;
|
||||
while (ti < idb->get_num_all_types()) {
|
||||
TypeIndex type_index = idb->get_all_type(ti);
|
||||
TypeIndex type_index = idb->get_all_type(ti++);
|
||||
record_object(type_index);
|
||||
|
||||
if (interrogate_type_is_enum(ti)) {
|
||||
int enum_count = interrogate_type_number_of_enum_values(ti);
|
||||
for (int xx = 0; xx < enum_count; ++xx) {
|
||||
// printf(" PyModule_AddIntConstant(module,\"%s\",%d)\n",interrogate_type_enum_value_name(ti,xx),interrogate_type_enum_value(ti,xx));
|
||||
}
|
||||
}
|
||||
|
||||
++ti;
|
||||
// printf(" New Type %d\n",ti);
|
||||
}
|
||||
|
||||
int num_global_elements = idb->get_num_global_elements();
|
||||
|
|
@ -321,7 +309,7 @@ generate_wrappers() {
|
|||
FunctionIndex func_index = ielement.get_setter();
|
||||
record_function(dummy_type, func_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -396,7 +384,7 @@ remap_parameter(CPPType *struct_type, CPPType *param_type) {
|
|||
// convert basic_string<char>'s to atomic strings.
|
||||
|
||||
if (struct_type == (CPPType *)NULL ||
|
||||
!(TypeManager::is_basic_string_char(struct_type) ||
|
||||
!(TypeManager::is_basic_string_char(struct_type) ||
|
||||
TypeManager::is_basic_string_wchar(struct_type))) {
|
||||
if (TypeManager::is_basic_string_char(param_type)) {
|
||||
return new ParameterRemapBasicStringToString(param_type);
|
||||
|
|
@ -454,7 +442,10 @@ remap_parameter(CPPType *struct_type, CPPType *param_type) {
|
|||
} else if (TypeManager::is_const_ref_to_simple(param_type)) {
|
||||
return new ParameterRemapReferenceToConcrete(param_type);
|
||||
|
||||
} else if (TypeManager::is_pointer(param_type) || TypeManager::is_simple(param_type)) {
|
||||
} else if (TypeManager::is_pointer(param_type) ||
|
||||
TypeManager::is_void(param_type) ||
|
||||
TypeManager::is_simple(param_type) ||
|
||||
TypeManager::is_simple_array(param_type)) {
|
||||
return new ParameterRemapUnchanged(param_type);
|
||||
|
||||
} else {
|
||||
|
|
@ -550,21 +541,19 @@ FunctionRemap *InterfaceMaker::
|
|||
make_function_remap(const InterrogateType &itype,
|
||||
const InterrogateFunction &ifunc,
|
||||
CPPInstance *cppfunc, int num_default_parameters) {
|
||||
FunctionRemap *remap =
|
||||
FunctionRemap *remap =
|
||||
new FunctionRemap(itype, ifunc, cppfunc, num_default_parameters, this);
|
||||
if (remap->_is_valid)
|
||||
{
|
||||
if (separate_overloading())
|
||||
{
|
||||
if (remap->_is_valid) {
|
||||
if (separate_overloading()) {
|
||||
hash_function_signature(remap);
|
||||
remap->_unique_name =
|
||||
get_unique_prefix() + _def->library_hash_name + remap->_hash;
|
||||
remap->_wrapper_name =
|
||||
remap->_wrapper_name =
|
||||
get_wrapper_prefix() + _def->library_hash_name + remap->_hash;
|
||||
remap->_reported_name = remap->_wrapper_name;
|
||||
if (true_wrapper_names)
|
||||
{
|
||||
remap->_reported_name =
|
||||
|
||||
if (true_wrapper_names) {
|
||||
remap->_reported_name =
|
||||
InterrogateBuilder::clean_identifier(remap->_cppfunc->get_local_name(&parser));
|
||||
}
|
||||
}
|
||||
|
|
@ -589,7 +578,7 @@ make_function_remap(const InterrogateType &itype,
|
|||
// an overloaded function) need not define a name here.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string InterfaceMaker::
|
||||
get_wrapper_name(const InterrogateType &itype,
|
||||
get_wrapper_name(const InterrogateType &itype,
|
||||
const InterrogateFunction &ifunc,
|
||||
FunctionIndex func_index) {
|
||||
string func_name = ifunc.get_scoped_name();
|
||||
|
|
@ -677,12 +666,13 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
|
|||
// parameters. This will happen only if separate_overloading(),
|
||||
// tested above, returned true; otherwise, max_default_parameters
|
||||
// will be 0 and the loop will only be traversed once.
|
||||
for (int num_default_parameters = 0;
|
||||
for (int num_default_parameters = 0;
|
||||
num_default_parameters <= max_default_parameters;
|
||||
num_default_parameters++) {
|
||||
FunctionRemap *remap =
|
||||
FunctionRemap *remap =
|
||||
make_function_remap(itype, ifunc, cppfunc, num_default_parameters);
|
||||
if (remap != (FunctionRemap *)NULL) {
|
||||
|
||||
func->_remaps.push_back(remap);
|
||||
|
||||
// If *any* of the variants of this function has a "this"
|
||||
|
|
@ -741,7 +731,8 @@ record_object(TypeIndex type_index) {
|
|||
}
|
||||
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
const InterrogateType &itype = idb->get_type(type_index);
|
||||
const InterrogateType &itype = idb->get_type(type_index);
|
||||
assert(&itype != NULL);
|
||||
|
||||
Object *object = new Object(itype);
|
||||
bool inserted = _objects.insert(Objects::value_type(type_index, object)).second;
|
||||
|
|
@ -754,29 +745,26 @@ record_object(TypeIndex type_index) {
|
|||
function = record_function(itype, itype.get_constructor(ci));
|
||||
object->_constructors.push_back(function);
|
||||
}
|
||||
|
||||
|
||||
int num_methods = itype.number_of_methods();
|
||||
int mi;
|
||||
for (mi = 0; mi < num_methods; mi++) {
|
||||
function = record_function(itype, itype.get_method(mi));
|
||||
object->_methods.push_back(function);
|
||||
}
|
||||
|
||||
|
||||
int num_casts = itype.number_of_casts();
|
||||
for (mi = 0; mi < num_casts; mi++) {
|
||||
function = record_function(itype, itype.get_cast(mi));
|
||||
object->_methods.push_back(function);
|
||||
}
|
||||
|
||||
|
||||
int num_derivations = itype.number_of_derivations();
|
||||
for (int di = 0; di < num_derivations; di++)
|
||||
{
|
||||
if (itype.derivation_has_upcast(di))
|
||||
{
|
||||
for (int di = 0; di < num_derivations; di++) {
|
||||
if (itype.derivation_has_upcast(di)) {
|
||||
record_function(itype, itype.derivation_get_upcast(di));
|
||||
}
|
||||
if (itype.derivation_has_downcast(di))
|
||||
{
|
||||
if (itype.derivation_has_downcast(di)) {
|
||||
// Downcasts are methods of the base class, not the child class.
|
||||
TypeIndex base_type_index = itype.get_derivation(di);
|
||||
const InterrogateType &base_type = idb->get_type(base_type_index);
|
||||
|
|
@ -785,27 +773,23 @@ record_object(TypeIndex type_index) {
|
|||
}
|
||||
|
||||
int num_elements = itype.number_of_elements();
|
||||
for (int ei = 0; ei < num_elements; ei++)
|
||||
{
|
||||
for (int ei = 0; ei < num_elements; ei++) {
|
||||
ElementIndex element_index = itype.get_element(ei);
|
||||
const InterrogateElement &ielement = idb->get_element(element_index);
|
||||
if (ielement.has_getter())
|
||||
{
|
||||
if (ielement.has_getter()) {
|
||||
FunctionIndex func_index = ielement.get_getter();
|
||||
record_function(itype, func_index);
|
||||
}
|
||||
if (ielement.has_setter())
|
||||
{
|
||||
if (ielement.has_setter()) {
|
||||
FunctionIndex func_index = ielement.get_setter();
|
||||
record_function(itype, func_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object->check_protocols();
|
||||
|
||||
int num_nested = itype.number_of_nested_types();
|
||||
for (int ni = 0; ni < num_nested; ni++)
|
||||
{
|
||||
for (int ni = 0; ni < num_nested; ni++) {
|
||||
TypeIndex nested_index = itype.get_nested_type(ni);
|
||||
record_object(nested_index);
|
||||
}
|
||||
|
|
@ -885,7 +869,7 @@ delete_return_value(ostream &out, int indent_level,
|
|||
// the indicated variable name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMaker::
|
||||
output_ref(ostream &out, int indent_level, FunctionRemap *remap,
|
||||
output_ref(ostream &out, int indent_level, FunctionRemap *remap,
|
||||
const string &varname) const {
|
||||
if (remap->_type == FunctionRemap::T_constructor ||
|
||||
remap->_type == FunctionRemap::T_typecast) {
|
||||
|
|
@ -915,7 +899,7 @@ output_ref(ostream &out, int indent_level, FunctionRemap *remap,
|
|||
// the indicated variable name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMaker::
|
||||
output_unref(ostream &out, int indent_level, FunctionRemap *remap,
|
||||
output_unref(ostream &out, int indent_level, FunctionRemap *remap,
|
||||
const string &varname) const {
|
||||
if (remap->_type == FunctionRemap::T_constructor ||
|
||||
remap->_type == FunctionRemap::T_typecast) {
|
||||
|
|
@ -931,8 +915,17 @@ output_unref(ostream &out, int indent_level, FunctionRemap *remap,
|
|||
indent(out, indent_level)
|
||||
<< "if (" << varname << " != ("
|
||||
<< remap->_return_type->get_new_type()->get_local_name(&parser) << ")NULL) {\n";
|
||||
indent(out, indent_level + 2)
|
||||
<< "unref_delete(" << varname << ");\n";
|
||||
|
||||
if (TypeManager::is_pointer_to_base(remap->_return_type->get_temporary_type())) {
|
||||
// We're sure the reference count won't reach zero since we have it
|
||||
// stored in a PointerTo, so call the unref() method directly.
|
||||
indent(out, indent_level + 2)
|
||||
<< varname << "->unref();\n";
|
||||
} else {
|
||||
indent(out, indent_level + 2)
|
||||
<< "unref_delete(" << varname << ");\n";
|
||||
}
|
||||
|
||||
indent(out, indent_level)
|
||||
<< "}\n";
|
||||
}
|
||||
|
|
@ -967,7 +960,7 @@ hash_function_signature(FunctionRemap *remap) {
|
|||
nout << "Internal error! Function signature "
|
||||
<< remap->_function_signature << " repeated!\n";
|
||||
remap->_hash = hash;
|
||||
abort();
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -31,32 +31,32 @@ class InterfaceMakerPythonNative : public InterfaceMakerPython {
|
|||
public:
|
||||
InterfaceMakerPythonNative(InterrogateModuleDef *def);
|
||||
virtual ~InterfaceMakerPythonNative();
|
||||
|
||||
|
||||
|
||||
|
||||
virtual void write_prototypes(ostream &out, ostream *out_h);
|
||||
void write_prototypes_class(ostream &out, ostream *out_h, Object *obj) ;
|
||||
void write_prototypes_class_external(ostream &out, Object *obj);
|
||||
|
||||
|
||||
virtual void write_functions(ostream &out);
|
||||
|
||||
|
||||
virtual void write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def);
|
||||
virtual void write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def);
|
||||
|
||||
void write_module_class(ostream &out, Object *cls);
|
||||
virtual void write_sub_module(ostream &out, Object *obj);
|
||||
|
||||
|
||||
void write_module_class(ostream &out, Object *cls);
|
||||
virtual void write_sub_module(ostream &out, Object *obj);
|
||||
|
||||
virtual bool synthesize_this_parameter();
|
||||
|
||||
|
||||
virtual Object *record_object(TypeIndex type_index);
|
||||
|
||||
|
||||
protected:
|
||||
virtual string get_wrapper_prefix();
|
||||
virtual string get_unique_prefix();
|
||||
virtual void record_function_wrapper(InterrogateFunction &ifunc,
|
||||
virtual void record_function_wrapper(InterrogateFunction &ifunc,
|
||||
FunctionWrapperIndex wrapper_index);
|
||||
|
||||
|
||||
virtual void generate_wrappers();
|
||||
|
||||
|
||||
private:
|
||||
// This enum defines the various prototypes that must be generated
|
||||
// for the specialty functions that Python requires, especially for
|
||||
|
|
@ -65,7 +65,7 @@ private:
|
|||
WT_none,
|
||||
WT_no_params,
|
||||
WT_one_param,
|
||||
WT_numeric_operator,
|
||||
WT_binary_operator,
|
||||
WT_setattr,
|
||||
WT_getattr,
|
||||
WT_sequence_getitem,
|
||||
|
|
@ -76,8 +76,33 @@ private:
|
|||
WT_getbuffer,
|
||||
WT_releasebuffer,
|
||||
WT_iter_next,
|
||||
WT_one_or_two_params,
|
||||
WT_ternary_operator,
|
||||
WT_inplace_binary_operator,
|
||||
WT_inplace_ternary_operator,
|
||||
};
|
||||
|
||||
// This enum is passed to the wrapper generation functions to indicate
|
||||
// what sort of values the wrapper function is expected to return.
|
||||
enum ReturnFlags {
|
||||
// -1 on failure, 0 on success.
|
||||
RF_int = 0x100,
|
||||
|
||||
// Returns the actual return value as PyObject*.
|
||||
RF_pyobject = 0x010,
|
||||
|
||||
// Returns a reference to self.
|
||||
RF_self = 0x020,
|
||||
|
||||
// Assign to the coerced argument, in the case of a coercion constructor.
|
||||
RF_coerced = 0x040,
|
||||
|
||||
// These indicate what should be returned on error.
|
||||
RF_err_notimplemented = 0x002,
|
||||
RF_err_null = 0x004,
|
||||
RF_err_false = 0x008,
|
||||
|
||||
// Decref temporary args object before returning.
|
||||
RF_decref_args = 0x200,
|
||||
};
|
||||
|
||||
class SlottedFunctionDef {
|
||||
|
|
@ -85,37 +110,41 @@ private:
|
|||
string _answer_location;
|
||||
WrapperType _wrapper_type;
|
||||
int _min_version;
|
||||
Function *_func;
|
||||
set<FunctionRemap*> _remaps;
|
||||
};
|
||||
|
||||
static bool get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def);
|
||||
static bool get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap, SlottedFunctionDef &def);
|
||||
|
||||
void write_prototype_for_name(ostream &out, Function *func, const std::string &name);
|
||||
void write_prototype_for(ostream &out, Function *func);
|
||||
void write_function_for_top(ostream &out, Object *obj, Function *func);
|
||||
void write_function_for_name(ostream &out, Object *obj, Function *func,
|
||||
const std::string &name,
|
||||
bool coercion_allowed, bool &coercion_attempted,
|
||||
ArgsType args_type, bool return_int, bool write_comment);
|
||||
|
||||
void write_function_forset(ostream &out, Object *obj, Function *func,
|
||||
std::set<FunctionRemap*> &remaps, string &expected_params,
|
||||
int indent_level, bool inplace,
|
||||
bool coercion_allowed, bool &coercion_attempted,
|
||||
ArgsType args_type, bool return_int,
|
||||
void write_function_for_name(ostream &out, Object *obj,
|
||||
const Function::Remaps &remaps,
|
||||
const std::string &name, string &expected_params,
|
||||
bool coercion_allowed,
|
||||
ArgsType args_type, int return_flags);
|
||||
void write_coerce_constructor(ostream &out, Object *obj, bool is_const);
|
||||
|
||||
void write_function_forset(ostream &out,
|
||||
const std::set<FunctionRemap*> &remaps,
|
||||
string &expected_params, int indent_level,
|
||||
bool coercion_allowed, bool report_errors,
|
||||
ArgsType args_type, int return_flags,
|
||||
bool check_exceptions = true,
|
||||
const string &first_expr = string());
|
||||
|
||||
void write_function_instance(ostream &out, Object *obj, Function *func,
|
||||
FunctionRemap *remap, string &expected_params,
|
||||
int indent_level, bool is_inplace,
|
||||
bool coercion_allowed, bool &coercion_attempted,
|
||||
ArgsType args_type, bool return_int,
|
||||
void write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
string &expected_params, int indent_level,
|
||||
bool coercion_allowed, bool report_errors,
|
||||
ArgsType args_type, int return_flags,
|
||||
bool check_exceptions = true,
|
||||
const string &first_pexpr = string());
|
||||
|
||||
void error_return(ostream &out, int indent_level, int return_flags);
|
||||
void pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
|
||||
const std::string &return_expr, bool in_place);
|
||||
void pack_python_value(ostream &out, int indent_level, FunctionRemap *remap,
|
||||
ParameterRemap *return_type, const std::string &return_expr,
|
||||
const std::string &assign_expr, bool in_place);
|
||||
const std::string &return_expr);
|
||||
|
||||
void write_make_seq(ostream &out, Object *obj, const std::string &ClassName,
|
||||
MakeSeq *make_seq);
|
||||
|
|
@ -126,7 +155,9 @@ private:
|
|||
|
||||
public:
|
||||
bool is_remap_legal(FunctionRemap *remap);
|
||||
bool is_function_legal( Function *func);
|
||||
int has_coerce_constructor(CPPStructType *type);
|
||||
bool is_remap_coercion_possible(FunctionRemap *remap);
|
||||
bool is_function_legal(Function *func);
|
||||
bool is_cpp_type_legal(CPPType *ctype);
|
||||
bool isExportThisRun(CPPType *ctype);
|
||||
bool isExportThisRun(Function *func);
|
||||
|
|
@ -145,7 +176,7 @@ public:
|
|||
void get_valid_child_classes(std::map<std::string, CastDetails> &answer, CPPStructType *inclass, const std::string &upcast_seed = "", bool can_downcast = true);
|
||||
bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
|
||||
bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
|
||||
void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, const std::string &assign_expr, std::string &owns_memory_flag, const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag);
|
||||
void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, bool owns_memory, const std::string &class_name, CPPType *ctype, bool is_const);
|
||||
string HasAGetKeyFunction(const InterrogateType &itype_class);
|
||||
bool HasAGetClassTypeFunction(const InterrogateType &itype_class);
|
||||
int NeedsAStrFunction(const InterrogateType &itype_class);
|
||||
|
|
@ -153,9 +184,9 @@ public:
|
|||
bool NeedsARichCompareFunction(const InterrogateType &itype_class);
|
||||
|
||||
void output_quoted(ostream &out, int indent_level, const std::string &str);
|
||||
|
||||
|
||||
// stash the forward declarations for this compile pass..
|
||||
std::set<std::string> _external_imports;
|
||||
std::set<CPPType *> _external_imports;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ bool save_unique_names = false;
|
|||
bool no_database = false;
|
||||
bool generate_spam = false;
|
||||
bool left_inheritance_requires_upcast = true;
|
||||
bool mangle_names = true;
|
||||
CPPVisibility min_vis = V_published;
|
||||
string library_name;
|
||||
string module_name;
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ extern bool save_unique_names;
|
|||
extern bool no_database;
|
||||
extern bool generate_spam;
|
||||
extern bool left_inheritance_requires_upcast;
|
||||
extern bool mangle_names;
|
||||
extern CPPVisibility min_vis;
|
||||
extern string library_name;
|
||||
extern string module_name;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include "cppExtensionType.h"
|
||||
#include "cppStructType.h"
|
||||
#include "cppExpression.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppTypeDeclaration.h"
|
||||
#include "cppEnumType.h"
|
||||
#include "cppCommentBlock.h"
|
||||
|
|
@ -270,7 +270,8 @@ build() {
|
|||
}
|
||||
|
||||
} else if ((*di)->get_subtype() == CPPDeclaration::ST_typedef) {
|
||||
CPPTypedef *tdef = (*di)->as_typedef();
|
||||
CPPTypedefType *tdef = (*di)->as_typedef_type();
|
||||
|
||||
if (tdef->_type->get_subtype() == CPPDeclaration::ST_struct) {
|
||||
// A typedef counts as a declaration. This lets us pick up
|
||||
// most template instantiations.
|
||||
|
|
@ -279,13 +280,16 @@ build() {
|
|||
scan_struct_type(struct_type);
|
||||
}
|
||||
|
||||
scan_typedef_type(tdef);
|
||||
|
||||
} else if ((*di)->get_subtype() == CPPDeclaration::ST_type_declaration) {
|
||||
CPPType *type = (*di)->as_type_declaration()->_type;
|
||||
|
||||
type->_vis = (*di)->_vis;
|
||||
|
||||
if (type->get_subtype() == CPPDeclaration::ST_struct)
|
||||
{
|
||||
CPPStructType *struct_type =type->as_type()->resolve_type(&parser, &parser)->as_struct_type();
|
||||
if (type->get_subtype() == CPPDeclaration::ST_struct) {
|
||||
CPPStructType *struct_type =
|
||||
type->as_type()->resolve_type(&parser, &parser)->as_struct_type();
|
||||
scan_struct_type(struct_type);
|
||||
|
||||
} else if (type->get_subtype() == CPPDeclaration::ST_enum) {
|
||||
|
|
@ -313,7 +317,8 @@ build() {
|
|||
// Description: Generates all the code necessary to the indicated
|
||||
// output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, InterrogateModuleDef *def) {
|
||||
void InterrogateBuilder::
|
||||
write_code(ostream &out_code,ostream * out_include, InterrogateModuleDef *def) {
|
||||
typedef vector<InterfaceMaker *> InterfaceMakers;
|
||||
InterfaceMakers makers;
|
||||
|
||||
|
|
@ -378,9 +383,10 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
}
|
||||
declaration_bodies << "#include \"py_panda.h\"\n";
|
||||
declaration_bodies << "#include \"extension.h\"\n";
|
||||
declaration_bodies << "#include \"dcast.h\"\n";
|
||||
}
|
||||
declaration_bodies << "\n";
|
||||
|
||||
|
||||
IncludeFiles::const_iterator ifi;
|
||||
for (ifi = _include_files.begin();
|
||||
ifi != _include_files.end();
|
||||
|
|
@ -397,7 +403,6 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
}
|
||||
declaration_bodies << "\n";
|
||||
|
||||
|
||||
for (mi = makers.begin(); mi != makers.end(); ++mi) {
|
||||
(*mi)->write_includes(declaration_bodies);
|
||||
}
|
||||
|
|
@ -411,8 +416,6 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
|
||||
declaration_bodies << "\n";
|
||||
|
||||
|
||||
|
||||
// And now the prototypes.
|
||||
for (mi = makers.begin(); mi != makers.end(); ++mi) {
|
||||
(*mi)->write_prototypes(declaration_bodies,out_include);
|
||||
|
|
@ -422,21 +425,19 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
// if(out_include != NULL)
|
||||
// (*out_include) << declaration_bodies.str();
|
||||
// else
|
||||
out_code << declaration_bodies.str();
|
||||
out_code << declaration_bodies.str();
|
||||
|
||||
|
||||
// Followed by the function bodies.
|
||||
out_code << function_bodies.str() << "\n";
|
||||
|
||||
for (mi = makers.begin(); mi != makers.end(); ++mi) {
|
||||
(*mi)->write_module_support(out_code,out_include,def);
|
||||
}
|
||||
|
||||
for (mi = makers.begin(); mi != makers.end(); ++mi) {
|
||||
(*mi)->write_module_support(out_code, out_include, def);
|
||||
}
|
||||
|
||||
if (output_module_specific) {
|
||||
// Output whatever stuff we should output if this were a module.
|
||||
for (mi = makers.begin(); mi != makers.end(); ++mi) {
|
||||
(*mi)->write_module(out_code,out_include, def);
|
||||
(*mi)->write_module(out_code, out_include, def);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -445,7 +446,7 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
for (mi = makers.begin(); mi != makers.end(); ++mi) {
|
||||
(*mi)->get_function_remaps(remaps);
|
||||
}
|
||||
|
||||
|
||||
// Make sure all of the function wrappers appear first in the set of
|
||||
// indices, and that they occupy consecutive index numbers, so we
|
||||
// can build a simple array of function pointers by index.
|
||||
|
|
@ -488,7 +489,6 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
out_code << "};\n\n";
|
||||
}
|
||||
|
||||
|
||||
if (save_unique_names) {
|
||||
// Write out the table of unique names, in no particular order.
|
||||
out_code << "static InterrogateUniqueNameDef _in_unique_names["
|
||||
|
|
@ -502,9 +502,6 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
out_code << "};\n\n";
|
||||
}
|
||||
|
||||
//if(1==2)
|
||||
{
|
||||
|
||||
if (!no_database) {
|
||||
// Now build the module definition structure to add ourselves to
|
||||
// the global interrogate database.
|
||||
|
|
@ -528,7 +525,7 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
<< " 0, /* num_unique_names */\n";
|
||||
}
|
||||
|
||||
if (output_function_pointers) {
|
||||
if (output_function_pointers) {
|
||||
out_code << " _in_fptrs,\n"
|
||||
<< " " << num_wrappers << ", /* num_fptrs */\n";
|
||||
} else {
|
||||
|
|
@ -549,7 +546,6 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
|||
<< "}\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::make_module_def
|
||||
|
|
@ -871,6 +867,15 @@ in_ignoreinvolved(CPPType *type) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
case CPPDeclaration::ST_typedef:
|
||||
{
|
||||
if (in_ignoreinvolved(type->get_simple_name())) {
|
||||
return true;
|
||||
}
|
||||
CPPTypedefType *tdef = type->as_typedef_type();
|
||||
return in_ignoreinvolved(tdef->_type);
|
||||
}
|
||||
|
||||
default:
|
||||
return in_ignoreinvolved(type->get_simple_name());
|
||||
}
|
||||
|
|
@ -1129,7 +1134,7 @@ scan_function(CPPInstance *function) {
|
|||
}
|
||||
|
||||
get_function(function, "",
|
||||
(CPPStructType *)NULL, scope,
|
||||
(CPPStructType *)NULL, scope,
|
||||
InterrogateFunction::F_global);
|
||||
}
|
||||
|
||||
|
|
@ -1165,8 +1170,7 @@ scan_struct_type(CPPStructType *type) {
|
|||
|
||||
// Check if any of the members are exported. If none of them are,
|
||||
// and the type itself is not marked for export, then never mind.
|
||||
if (type->_vis > min_vis)
|
||||
{
|
||||
if (type->_vis > min_vis) {
|
||||
CPPScope *scope = type->_scope;
|
||||
|
||||
bool any_exported = false;
|
||||
|
|
@ -1176,6 +1180,7 @@ scan_struct_type(CPPStructType *type) {
|
|||
++di) {
|
||||
if ((*di)->_vis <= min_vis) {
|
||||
any_exported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1225,6 +1230,93 @@ scan_enum_type(CPPEnumType *type) {
|
|||
get_type(type, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::scan_typedef_type
|
||||
// Access: Private
|
||||
// Description: Adds the indicated typedef type to the database, if
|
||||
// warranted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterrogateBuilder::
|
||||
scan_typedef_type(CPPTypedefType *type) {
|
||||
if (type == (CPPTypedefType *)NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A typedef cannot be a template declaration.
|
||||
assert(!type->is_template());
|
||||
|
||||
if (type->_file.is_c_file()) {
|
||||
// This type declaration appears in a .C file. We can only export
|
||||
// types defined in a .h file.
|
||||
return;
|
||||
}
|
||||
|
||||
if (type->_file._source != CPPFile::S_local ||
|
||||
in_ignorefile(type->_file._filename_as_referenced)) {
|
||||
// The type is defined in some other package or in an
|
||||
// ignorable file.
|
||||
return;
|
||||
}
|
||||
|
||||
// Do we require explicitly placing BEGIN_PUBLISH/END_PUBLISH
|
||||
// blocks around typedefs for them to be exported? My thinking is
|
||||
// that we shoudn't, for now, since we don't require it for structs
|
||||
// either (we only require it to have published methods).
|
||||
//if (type->_vis > min_vis) {
|
||||
// // The wrapped type is not marked to be exported.
|
||||
// return;
|
||||
//}
|
||||
|
||||
// Find out what this typedef points to.
|
||||
CPPType *wrapped_type = type->_type;
|
||||
bool forced = in_forcetype(wrapped_type->get_local_name(&parser));
|
||||
|
||||
while (wrapped_type->get_subtype() == CPPDeclaration::ST_typedef) {
|
||||
wrapped_type = wrapped_type->as_typedef_type()->_type;
|
||||
forced = forced || in_forcetype(wrapped_type->get_local_name(&parser));
|
||||
}
|
||||
|
||||
CPPStructType *struct_type = wrapped_type->as_struct_type();
|
||||
if (struct_type == (CPPStructType *)NULL) {
|
||||
// We only export typedefs to structs, for now.
|
||||
return;
|
||||
}
|
||||
|
||||
// Always export typedefs pointing to forced types.
|
||||
if (!forced) {
|
||||
if (wrapped_type->_file._source != CPPFile::S_local ||
|
||||
in_ignorefile(wrapped_type->_file._filename_as_referenced)) {
|
||||
// The wrapped type is defined in some other package or
|
||||
// in an ignorable file.
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if any of the wrapped type's members are published.
|
||||
// If none of them are, and the wrapped type itself is not
|
||||
// marked for export, then never mind.
|
||||
if (struct_type->_vis > min_vis) {
|
||||
CPPScope *scope = struct_type->_scope;
|
||||
|
||||
bool any_exported = false;
|
||||
CPPScope::Declarations::const_iterator di;
|
||||
for (di = scope->_declarations.begin();
|
||||
di != scope->_declarations.end() && !any_exported;
|
||||
++di) {
|
||||
if ((*di)->_vis <= min_vis) {
|
||||
any_exported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_exported) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_type(type, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::scan_manifest
|
||||
// Access: Private
|
||||
|
|
@ -1667,6 +1759,11 @@ get_function(CPPInstance *function, string description,
|
|||
return 0;
|
||||
}
|
||||
|
||||
TypeIndex class_index = 0;
|
||||
if (struct_type != (CPPStructType *)NULL) {
|
||||
class_index = get_type(struct_type, false);
|
||||
}
|
||||
|
||||
string function_name = TypeManager::get_function_name(function);
|
||||
string function_signature = TypeManager::get_function_signature(function);
|
||||
|
||||
|
|
@ -1682,18 +1779,17 @@ get_function(CPPInstance *function, string description,
|
|||
_functions_by_name.find(function_name);
|
||||
if (tni != _functions_by_name.end()) {
|
||||
FunctionIndex index = (*tni).second;
|
||||
|
||||
// It's already here, so update the flags.
|
||||
InterrogateFunction &ifunction =
|
||||
InterrogateDatabase::get_ptr()->update_function(index);
|
||||
|
||||
// Not 100% sure why, but there's a case where this happens,
|
||||
// in a case where a typedef shadowed an actual type. ~rdb
|
||||
nassertr(&ifunction != NULL, 0);
|
||||
|
||||
ifunction._flags |= flags;
|
||||
|
||||
// Also, make sure this particular signature is defined.
|
||||
pair<InterrogateFunction::Instances::iterator, bool> result =
|
||||
pair<InterrogateFunction::Instances::iterator, bool> result =
|
||||
ifunction._instances->insert(InterrogateFunction::Instances::value_type(function_signature, function));
|
||||
|
||||
InterrogateFunction::Instances::iterator ii = result.first;
|
||||
|
|
@ -1748,7 +1844,7 @@ get_function(CPPInstance *function, string description,
|
|||
if (struct_type != (CPPStructType *)NULL) {
|
||||
// The function is a method.
|
||||
ifunction->_flags |= InterrogateFunction::F_method;
|
||||
ifunction->_class = get_type(struct_type, false);
|
||||
ifunction->_class = class_index;
|
||||
}
|
||||
|
||||
if (ftype->_flags & CPPFunctionType::F_unary_op) {
|
||||
|
|
@ -1958,7 +2054,7 @@ get_type(CPPType *type, bool global) {
|
|||
if (true_name.empty()) {
|
||||
// Whoops, it's an anonymous type. That's okay, because we'll
|
||||
// usually only encounter them once anyway, so let's go ahead and
|
||||
// define it without checking in _types_by_name.
|
||||
// define it without checking _types_by_name first.
|
||||
|
||||
} else {
|
||||
TypesByName::const_iterator tni = _types_by_name.find(true_name);
|
||||
|
|
@ -2028,29 +2124,39 @@ get_type(CPPType *type, bool global) {
|
|||
}
|
||||
}
|
||||
|
||||
CPPExtensionType *ext_type = type->as_extension_type();
|
||||
if (ext_type != (CPPExtensionType *)NULL) {
|
||||
// If it's an extension type of some kind, it might be scoped.
|
||||
CPPScope *scope = NULL;
|
||||
// If it's an extension type or typedef, it might be scoped.
|
||||
if (CPPTypedefType *td_type = type->as_typedef_type()) {
|
||||
scope = td_type->_ident->get_scope(&parser, &parser);
|
||||
|
||||
} else if (CPPExtensionType *ext_type = type->as_extension_type()) {
|
||||
if (ext_type->_ident != (CPPIdentifier *)NULL) {
|
||||
CPPScope *scope = ext_type->_ident->get_scope(&parser, &parser);
|
||||
while (scope->as_template_scope() != (CPPTemplateScope *)NULL)
|
||||
{
|
||||
assert(scope->get_parent_scope() != scope);
|
||||
scope = scope->get_parent_scope();
|
||||
assert(scope != (CPPScope *)NULL);
|
||||
}
|
||||
itype._cppscope = scope;
|
||||
scope = ext_type->_ident->get_scope(&parser, &parser);
|
||||
|
||||
if (scope != &parser) {
|
||||
// We're scoped!
|
||||
itype._scoped_name =
|
||||
descope(scope->get_local_name(&parser) + "::" + itype._name);
|
||||
CPPStructType *struct_type = scope->get_struct_type();
|
||||
} else if (CPPEnumType *enum_type = ext_type->as_enum_type()) {
|
||||
// Special case for anonymous enums.
|
||||
scope = enum_type->_parent_scope;
|
||||
}
|
||||
|
||||
if (struct_type != (CPPStructType *)NULL) {
|
||||
itype._flags |= InterrogateType::F_nested;
|
||||
itype._outer_class = get_type(struct_type, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (scope != (CPPScope *)NULL) {
|
||||
while (scope->as_template_scope() != (CPPTemplateScope *)NULL) {
|
||||
assert(scope->get_parent_scope() != scope);
|
||||
scope = scope->get_parent_scope();
|
||||
assert(scope != (CPPScope *)NULL);
|
||||
}
|
||||
itype._cppscope = scope;
|
||||
|
||||
if (scope != &parser) {
|
||||
// We're scoped!
|
||||
itype._scoped_name =
|
||||
descope(scope->get_local_name(&parser) + "::" + itype._name);
|
||||
CPPStructType *struct_type = scope->get_struct_type();
|
||||
|
||||
if (struct_type != (CPPStructType *)NULL) {
|
||||
itype._flags |= InterrogateType::F_nested;
|
||||
itype._outer_class = get_type(struct_type, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2076,8 +2182,15 @@ get_type(CPPType *type, bool global) {
|
|||
} else if (type->as_extension_type() != (CPPExtensionType *)NULL) {
|
||||
define_extension_type(itype, type->as_extension_type());
|
||||
|
||||
} else if (type->as_typedef_type() != (CPPTypedefType *)NULL) {
|
||||
define_typedef_type(itype, type->as_typedef_type());
|
||||
|
||||
} else if (type->as_array_type() != (CPPArrayType *)NULL) {
|
||||
define_array_type(itype, type->as_array_type());
|
||||
|
||||
} else {
|
||||
// nout << "Attempt to define invalid type " << true_name << "\n";
|
||||
nout << "Attempt to define invalid type " << *type
|
||||
<< " (subtype " << type->get_subtype() << ")\n";
|
||||
|
||||
// Remove the type from the database.
|
||||
InterrogateDatabase::get_ptr()->remove_type(index);
|
||||
|
|
@ -2113,6 +2226,16 @@ define_atomic_type(InterrogateType &itype, CPPSimpleType *cpptype) {
|
|||
itype._atomic_token = AT_int;
|
||||
break;
|
||||
|
||||
case CPPSimpleType::T_char16_t:
|
||||
itype._flags |= InterrogateType::F_unsigned;
|
||||
itype._atomic_token = AT_int;
|
||||
break;
|
||||
|
||||
case CPPSimpleType::T_char32_t:
|
||||
itype._flags |= InterrogateType::F_unsigned;
|
||||
itype._atomic_token = AT_int;
|
||||
break;
|
||||
|
||||
case CPPSimpleType::T_int:
|
||||
if ((cpptype->_flags & CPPSimpleType::F_longlong) != 0) {
|
||||
itype._atomic_token = AT_longlong;
|
||||
|
|
@ -2134,7 +2257,8 @@ define_atomic_type(InterrogateType &itype, CPPSimpleType *cpptype) {
|
|||
break;
|
||||
|
||||
default:
|
||||
nout << "Invalid CPPSimpleType: " << (int)cpptype->_type << "\n";
|
||||
nout << "Type \"" << *cpptype << "\" has invalid CPPSimpleType: "
|
||||
<< (int)cpptype->_type << "\n";
|
||||
itype._atomic_token = AT_not_atomic;
|
||||
}
|
||||
|
||||
|
|
@ -2249,23 +2373,25 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
|
||||
// A struct type should always be global.
|
||||
itype._flags |= InterrogateType::F_global;
|
||||
|
||||
|
||||
CPPScope *scope = cpptype->_scope;
|
||||
|
||||
|
||||
CPPStructType::Derivation::const_iterator bi;
|
||||
for (bi = cpptype->_derivation.begin();
|
||||
bi != cpptype->_derivation.end();
|
||||
++bi) {
|
||||
const CPPStructType::Base &base = (*bi);
|
||||
if (base._vis <= V_public)
|
||||
{
|
||||
|
||||
const CPPStructType::Base &base = (*bi);
|
||||
if (base._vis <= V_public) {
|
||||
CPPType *base_type = TypeManager::resolve_type(base._base, scope);
|
||||
TypeIndex base_index = get_type(base_type, true);
|
||||
|
||||
|
||||
if (base_index == 0) {
|
||||
nout << *cpptype << " reports a derivation from an invalid type.\n";
|
||||
if (base_type != NULL) {
|
||||
nout << *cpptype << " reports a derivation from invalid type " << *base_type << ".\n";
|
||||
} else {
|
||||
nout << *cpptype << " reports a derivation from an invalid type.\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
InterrogateType::Derivation d;
|
||||
|
|
@ -2273,7 +2399,7 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
d._base = base_index;
|
||||
d._upcast = 0;
|
||||
d._downcast = 0;
|
||||
|
||||
|
||||
// Do we need to synthesize upcast and downcast functions?
|
||||
bool generate_casts = false;
|
||||
|
||||
|
|
@ -2281,12 +2407,12 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
if (base._is_virtual) {
|
||||
// We do in the presence of virtual inheritance.
|
||||
generate_casts = true;
|
||||
|
||||
|
||||
} else if (bi != cpptype->_derivation.begin()) {
|
||||
// Or if we're not talking about the leftmost fork of multiple
|
||||
// inheritance.
|
||||
generate_casts = true;
|
||||
|
||||
|
||||
} else if (cpptype->_derivation.size() != 1 &&
|
||||
left_inheritance_requires_upcast) {
|
||||
// Or even if we are the leftmost fork of multiple
|
||||
|
|
@ -2302,13 +2428,11 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
// pointer, while the parent class won't).
|
||||
generate_casts = true;
|
||||
}
|
||||
|
||||
if (generate_casts) {
|
||||
|
||||
|
||||
if (generate_casts) {
|
||||
d._upcast = get_cast_function(base_type, cpptype, "upcast");
|
||||
d._flags |= InterrogateType::DF_upcast;
|
||||
|
||||
|
||||
if (base._is_virtual) {
|
||||
// If this is a virtual inheritance, we can't write a
|
||||
// downcast.
|
||||
|
|
@ -2355,8 +2479,9 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
CPPExtensionType *nested_type = type->as_extension_type();
|
||||
assert(nested_type != (CPPExtensionType *)NULL);
|
||||
|
||||
// Only try to export named types.
|
||||
if (nested_type->_ident != (CPPIdentifier *)NULL) {
|
||||
// For now, we don't allow anonymous structs.
|
||||
if (nested_type->_ident != (CPPIdentifier *)NULL ||
|
||||
nested_type->as_enum_type() != (CPPEnumType *)NULL) {
|
||||
TypeIndex nested_index = get_type(nested_type, false);
|
||||
itype._nested_types.push_back(nested_index);
|
||||
}
|
||||
|
|
@ -2366,11 +2491,31 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
CPPType *type = (*di)->as_enum_type();
|
||||
|
||||
// An anonymous enum type.
|
||||
if ((*di)->_vis <= min_vis) {
|
||||
if (type->_vis <= min_vis) {
|
||||
TypeIndex nested_index = get_type(type, false);
|
||||
itype._nested_types.push_back(nested_index);
|
||||
}
|
||||
|
||||
} else if ((*di)->get_subtype() == CPPDeclaration::ST_typedef) {
|
||||
CPPTypedefType *type = (*di)->as_typedef_type();
|
||||
|
||||
// A nested typedef. Unwrap it to find out what it's pointing to.
|
||||
CPPType *wrapped_type = type->_type;
|
||||
|
||||
while (wrapped_type->get_subtype() == CPPDeclaration::ST_typedef) {
|
||||
wrapped_type = wrapped_type->as_typedef_type()->_type;
|
||||
}
|
||||
|
||||
CPPStructType *struct_type = wrapped_type->as_struct_type();
|
||||
if (struct_type != (CPPStructType *)NULL) {
|
||||
// We only export typedefs to structs, for now.
|
||||
|
||||
if (type->_vis <= min_vis) {
|
||||
TypeIndex nested_index = get_type(type, false);
|
||||
itype._nested_types.push_back(nested_index);
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((*di)->get_subtype() == CPPDeclaration::ST_make_property) {
|
||||
ElementIndex element_index = get_make_property((*di)->as_make_property(), cpptype);
|
||||
itype._elements.push_back(element_index);
|
||||
|
|
@ -2467,7 +2612,7 @@ update_function_comment(CPPInstance *function, CPPScope *scope) {
|
|||
ifunction._comment += comment;
|
||||
|
||||
// Also update the particular wrapper comment.
|
||||
InterrogateFunction::Instances::iterator ii =
|
||||
InterrogateFunction::Instances::iterator ii =
|
||||
ifunction._instances->find(function_signature);
|
||||
if (ii != ifunction._instances->end()) {
|
||||
if ((*ii).second->_leading_comment == NULL ||
|
||||
|
|
@ -2489,8 +2634,7 @@ void InterrogateBuilder::
|
|||
define_method(CPPFunctionGroup *fgroup, InterrogateType &itype,
|
||||
CPPStructType *struct_type, CPPScope *scope) {
|
||||
CPPFunctionGroup::Instances::const_iterator fi;
|
||||
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi)
|
||||
{
|
||||
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
|
||||
CPPInstance *function = (*fi);
|
||||
define_method(function, itype, struct_type, scope);
|
||||
}
|
||||
|
|
@ -2626,7 +2770,7 @@ void InterrogateBuilder::
|
|||
define_enum_type(InterrogateType &itype, CPPEnumType *cpptype) {
|
||||
itype._flags |= InterrogateType::F_enum;
|
||||
|
||||
CPPScope *scope = &parser;
|
||||
CPPScope *scope = cpptype->_parent_scope;
|
||||
if (cpptype->_ident != (CPPIdentifier *)NULL) {
|
||||
scope = cpptype->_ident->get_scope(&parser, &parser);
|
||||
}
|
||||
|
|
@ -2667,7 +2811,15 @@ define_enum_type(InterrogateType &itype, CPPEnumType *cpptype) {
|
|||
|
||||
if (element->_initializer != (CPPExpression *)NULL) {
|
||||
CPPExpression::Result result = element->_initializer->evaluate();
|
||||
next_value = result.as_integer();
|
||||
|
||||
if (result._type == CPPExpression::RT_error) {
|
||||
nout << "enum value ";
|
||||
element->output(nout, 0, &parser, true);
|
||||
nout << " has invalid definition!\n";
|
||||
return;
|
||||
} else {
|
||||
next_value = result.as_integer();
|
||||
}
|
||||
}
|
||||
evalue._value = next_value;
|
||||
itype._enum_values.push_back(evalue);
|
||||
|
|
@ -2676,6 +2828,30 @@ define_enum_type(InterrogateType &itype, CPPEnumType *cpptype) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::define_typedef_type
|
||||
// Access: Private
|
||||
// Description: Builds up a definition for the indicated typedef.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterrogateBuilder::
|
||||
define_typedef_type(InterrogateType &itype, CPPTypedefType *cpptype) {
|
||||
itype._flags |= InterrogateType::F_typedef;
|
||||
itype._wrapped_type = get_type(cpptype->_type, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::define_array_type
|
||||
// Access: Private
|
||||
// Description: Builds up a definition for the indicated wrapped type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InterrogateBuilder::
|
||||
define_array_type(InterrogateType &itype, CPPArrayType *cpptype) {
|
||||
itype._flags |= InterrogateType::F_array;
|
||||
itype._wrapped_type = get_type(cpptype->_element_type, false);
|
||||
|
||||
itype._array_size = cpptype->_bounds->evaluate().as_integer();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::define_extension_type
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ class CPPConstType;
|
|||
class CPPExtensionType;
|
||||
class CPPStructType;
|
||||
class CPPEnumType;
|
||||
class CPPTypedefType;
|
||||
class CPPArrayType;
|
||||
class CPPFunctionType;
|
||||
class CPPScope;
|
||||
class CPPIdentifier;
|
||||
|
|
@ -92,6 +94,7 @@ public:
|
|||
void scan_function(CPPInstance *function);
|
||||
void scan_struct_type(CPPStructType *type);
|
||||
void scan_enum_type(CPPEnumType *type);
|
||||
void scan_typedef_type(CPPTypedefType *type);
|
||||
void scan_manifest(CPPManifest *manifest);
|
||||
ElementIndex scan_element(CPPInstance *element, CPPStructType *struct_type,
|
||||
CPPScope *scope);
|
||||
|
|
@ -128,6 +131,8 @@ public:
|
|||
void define_method(CPPInstance *function, InterrogateType &itype,
|
||||
CPPStructType *struct_type, CPPScope *scope);
|
||||
void define_enum_type(InterrogateType &itype, CPPEnumType *cpptype);
|
||||
void define_typedef_type(InterrogateType &itype, CPPTypedefType *cpptype);
|
||||
void define_array_type(InterrogateType &itype, CPPArrayType *cpptype);
|
||||
void define_extension_type(InterrogateType &itype,
|
||||
CPPExtensionType *cpptype);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include "cppManifest.h"
|
||||
#include "cppStructType.h"
|
||||
#include "cppFunctionGroup.h"
|
||||
#include "cppTypedef.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppExpressionParser.h"
|
||||
#include "cppExpression.h"
|
||||
#include "cppType.h"
|
||||
|
|
@ -166,7 +166,7 @@ show_data_members(const string &str) {
|
|||
}
|
||||
|
||||
void
|
||||
show_typedefs(const string &str) {
|
||||
show_nested_types(const string &str) {
|
||||
CPPType *type = parser.parse_type(str);
|
||||
if (type == NULL) {
|
||||
cerr << "Invalid type: " << str << "\n";
|
||||
|
|
@ -182,12 +182,12 @@ show_typedefs(const string &str) {
|
|||
CPPScope *scope = stype->get_scope();
|
||||
assert(scope != (CPPScope *)NULL);
|
||||
|
||||
cerr << "Typedefs in " << *stype << ":\n";
|
||||
cerr << "Nested types in " << *stype << ":\n";
|
||||
|
||||
CPPScope::Typedefs::const_iterator ti;
|
||||
for (ti = scope->_typedefs.begin(); ti != scope->_typedefs.end(); ++ti) {
|
||||
CPPTypedef *td = (*ti).second;
|
||||
cerr << " " << *td << "\n";
|
||||
CPPScope::Types::const_iterator ti;
|
||||
for (ti = scope->_types.begin(); ti != scope->_types.end(); ++ti) {
|
||||
CPPType *tp = (*ti).second;
|
||||
cerr << " " << *tp << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -286,8 +286,8 @@ main(int argc, char **argv) {
|
|||
show_methods(remainder);
|
||||
} else if (first_word == "members") {
|
||||
show_data_members(remainder);
|
||||
} else if (first_word == "typedefs") {
|
||||
show_typedefs(remainder);
|
||||
} else if (first_word == "types") {
|
||||
show_nested_types(remainder);
|
||||
} else {
|
||||
show_type_or_expression(str);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -50,6 +50,7 @@ public:
|
|||
static bool is_ref_to_anything(CPPType *type);
|
||||
static bool is_const_ref_to_anything(CPPType *type);
|
||||
static bool is_const_pointer_to_anything(CPPType *type);
|
||||
static bool is_const_pointer_or_ref(CPPType *type);
|
||||
static bool is_non_const_pointer_or_ref(CPPType *type);
|
||||
static bool is_pointer(CPPType *type);
|
||||
static bool is_const(CPPType *type);
|
||||
|
|
@ -61,9 +62,15 @@ public:
|
|||
static bool is_const_simple(CPPType *type);
|
||||
static bool is_const_ref_to_simple(CPPType *type);
|
||||
static bool is_ref_to_simple(CPPType *type);
|
||||
static bool is_simple_array(CPPType *type);
|
||||
static bool is_pointer_to_simple(CPPType *type);
|
||||
static bool is_pointable(CPPType *type);
|
||||
static bool is_char(CPPType *type);
|
||||
static bool is_unsigned_char(CPPType *type);
|
||||
static bool is_char_pointer(CPPType *type);
|
||||
static bool is_const_char_pointer(CPPType *type);
|
||||
static bool is_unsigned_char_pointer(CPPType *type);
|
||||
static bool is_const_unsigned_char_pointer(CPPType *type);
|
||||
static bool is_basic_string_char(CPPType *type);
|
||||
static bool is_const_basic_string_char(CPPType *type);
|
||||
static bool is_const_ref_to_basic_string_char(CPPType *type);
|
||||
|
|
@ -80,6 +87,7 @@ public:
|
|||
static bool is_bool(CPPType *type);
|
||||
static bool is_integer(CPPType *type);
|
||||
static bool is_unsigned_integer(CPPType *type);
|
||||
static bool is_size(CPPType *type);
|
||||
static bool is_short(CPPType *type);
|
||||
static bool is_unsigned_short(CPPType *type);
|
||||
static bool is_longlong(CPPType *type);
|
||||
|
|
@ -94,6 +102,8 @@ public:
|
|||
static bool is_const_ref_to_pointer_to_base(CPPType *type);
|
||||
static bool is_pointer_to_PyObject(CPPType *type);
|
||||
static bool is_PyObject(CPPType *type);
|
||||
static bool is_pointer_to_PyTypeObject(CPPType *type);
|
||||
static bool is_PyTypeObject(CPPType *type);
|
||||
static bool is_pointer_to_PyStringObject(CPPType *type);
|
||||
static bool is_PyStringObject(CPPType *type);
|
||||
static bool is_pointer_to_PyUnicodeObject(CPPType *type);
|
||||
|
|
@ -134,7 +144,7 @@ public:
|
|||
|
||||
|
||||
static bool IsExported(CPPType *type);
|
||||
static bool IsLocal(CPPType *type);
|
||||
static bool is_local(CPPType *type);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ static Py_hash_t DTool_HashKey_Methods_DTOOL_SUPER_BASE(PyObject *self) {
|
|||
return (Py_hash_t) local_this;
|
||||
};
|
||||
|
||||
inline void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
|
||||
EXPCL_DTOOLCONFIG void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
|
||||
static bool initdone = false;
|
||||
if (!initdone) {
|
||||
|
||||
|
|
@ -83,9 +83,4 @@ int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int Dtool_InitNoCoerce_DTOOL_SUPER_BASE(PyObject *self, PyObject *args) {
|
||||
PyErr_SetString(PyExc_TypeError, "cannot init super base");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
|
|||
|
|
@ -207,6 +207,16 @@ is_const() const {
|
|||
return (_flags & F_const) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateType::is_typedef
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InterrogateType::
|
||||
is_typedef() const {
|
||||
return (_flags & F_typedef) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateType::get_wrapped_type
|
||||
// Access: Public
|
||||
|
|
@ -217,6 +227,26 @@ get_wrapped_type() const {
|
|||
return _wrapped_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateType::is_array
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InterrogateType::
|
||||
is_array() const {
|
||||
return (_flags & F_array) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateType::get_array_size
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int InterrogateType::
|
||||
get_array_size() const {
|
||||
return _array_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateType::is_enum
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ InterrogateType(InterrogateModuleDef *def) :
|
|||
_outer_class = 0;
|
||||
_atomic_token = AT_not_atomic;
|
||||
_wrapped_type = 0;
|
||||
_array_size = 1;
|
||||
_destructor = 0;
|
||||
|
||||
_cpptype = (CPPType *)NULL;
|
||||
|
|
@ -111,6 +112,7 @@ operator = (const InterrogateType ©) {
|
|||
_outer_class = copy._outer_class;
|
||||
_atomic_token = copy._atomic_token;
|
||||
_wrapped_type = copy._wrapped_type;
|
||||
_array_size = copy._array_size;
|
||||
_constructors = copy._constructors;
|
||||
_destructor = copy._destructor;
|
||||
_elements = copy._elements;
|
||||
|
|
@ -165,6 +167,11 @@ output(ostream &out) const {
|
|||
out << _outer_class << " "
|
||||
<< (int)_atomic_token << " "
|
||||
<< _wrapped_type << " ";
|
||||
|
||||
if (is_array()) {
|
||||
out << _array_size << " ";
|
||||
}
|
||||
|
||||
idf_output_vector(out, _constructors);
|
||||
out << _destructor << " ";
|
||||
idf_output_vector(out, _elements);
|
||||
|
|
@ -197,6 +204,10 @@ input(istream &in) {
|
|||
_atomic_token = (AtomicToken)token;
|
||||
in >> _wrapped_type;
|
||||
|
||||
if (is_array()) {
|
||||
in >> _array_size;
|
||||
}
|
||||
|
||||
idf_input_vector(in, _constructors);
|
||||
in >> _destructor;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,8 +60,12 @@ public:
|
|||
INLINE bool is_wrapped() const;
|
||||
INLINE bool is_pointer() const;
|
||||
INLINE bool is_const() const;
|
||||
INLINE bool is_typedef() const;
|
||||
INLINE TypeIndex get_wrapped_type() const;
|
||||
|
||||
INLINE bool is_array() const;
|
||||
INLINE int get_array_size() const;
|
||||
|
||||
INLINE bool is_enum() const;
|
||||
INLINE int number_of_enum_values() const;
|
||||
INLINE const string &get_enum_value_name(int n) const;
|
||||
|
|
@ -132,6 +136,8 @@ private:
|
|||
F_nested = 0x040000,
|
||||
F_enum = 0x080000,
|
||||
F_unpublished = 0x100000,
|
||||
F_typedef = 0x200000,
|
||||
F_array = 0x400000,
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -143,6 +149,7 @@ public:
|
|||
TypeIndex _outer_class;
|
||||
AtomicToken _atomic_token;
|
||||
TypeIndex _wrapped_type;
|
||||
int _array_size;
|
||||
|
||||
typedef vector<FunctionIndex> Functions;
|
||||
Functions _constructors;
|
||||
|
|
|
|||
|
|
@ -613,6 +613,12 @@ interrogate_type_is_const(TypeIndex type) {
|
|||
return InterrogateDatabase::get_ptr()->get_type(type).is_const();
|
||||
}
|
||||
|
||||
bool
|
||||
interrogate_type_is_typedef(TypeIndex type) {
|
||||
//cerr << "interrogate_type_is_typedef(" << type << ")\n";
|
||||
return InterrogateDatabase::get_ptr()->get_type(type).is_typedef();
|
||||
}
|
||||
|
||||
TypeIndex
|
||||
interrogate_type_wrapped_type(TypeIndex type) {
|
||||
//cerr << "interrogate_type_wrapped_type(" << type << ")\n";
|
||||
|
|
|
|||
|
|
@ -447,6 +447,7 @@ EXPCL_DTOOLCONFIG bool interrogate_type_is_short(TypeIndex type);
|
|||
EXPCL_DTOOLCONFIG bool interrogate_type_is_wrapped(TypeIndex type);
|
||||
EXPCL_DTOOLCONFIG bool interrogate_type_is_pointer(TypeIndex type);
|
||||
EXPCL_DTOOLCONFIG bool interrogate_type_is_const(TypeIndex type);
|
||||
EXPCL_DTOOLCONFIG bool interrogate_type_is_typedef(TypeIndex type);
|
||||
EXPCL_DTOOLCONFIG TypeIndex interrogate_type_wrapped_type(TypeIndex type);
|
||||
|
||||
// If interrogate_type_is_enum() returns true, this is an enumerated
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#ifdef HAVE_PYTHON
|
||||
|
||||
PyMemberDef standard_type_members[] = {
|
||||
{(char *)"this", T_ULONG, offsetof(Dtool_PyInstDef,_ptr_to_object),READONLY, (char *)"C++ 'this' pointer, if any"},
|
||||
{(char *)"this", (sizeof(void*) == sizeof(int)) ? T_UINT : T_ULONGLONG, offsetof(Dtool_PyInstDef, _ptr_to_object), READONLY, (char *)"C++ 'this' pointer, if any"},
|
||||
// {(char *)"this_ownership", T_INT, offsetof(Dtool_PyInstDef, _memory_rules), READONLY, (char *)"C++ 'this' ownership rules"},
|
||||
// {(char *)"this_const", T_INT, offsetof(Dtool_PyInstDef, _is_const), READONLY, (char *)"C++ 'this' const flag"},
|
||||
// {(char *)"this_signature", T_INT, offsetof(Dtool_PyInstDef, _signature), READONLY, (char *)"A type check signature"},
|
||||
|
|
@ -31,6 +31,9 @@ PyMemberDef standard_type_members[] = {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
bool DtoolCanThisBeAPandaInstance(PyObject *self) {
|
||||
// simple sanity check for the class type..size.. will stop basic foobars..
|
||||
// It is arguably better to use something like this:
|
||||
// PyType_IsSubtype(Py_TYPE(self), &Dtool_DTOOL_SUPER_BASE._PyType)
|
||||
// ...but probably not as fast.
|
||||
if (Py_TYPE(self)->tp_basicsize >= (int)sizeof(Dtool_PyInstDef)) {
|
||||
Dtool_PyInstDef *pyself = (Dtool_PyInstDef *) self;
|
||||
if (pyself->_signature == PY_PANDA_SIGNATURE) {
|
||||
|
|
@ -55,104 +58,6 @@ void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *c
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: attempt_coercion
|
||||
// Description: A helper function for DTOOL_Call_GetPointerThisClass,
|
||||
// below. This attempts to coerce the given object to
|
||||
// the indicated Panda object, by creating a temporary
|
||||
// instance of the required Panda object. If
|
||||
// successful, returns the "this" pointer of the
|
||||
// temporary object; otherwise, returns NULL.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static void *
|
||||
attempt_coercion(PyObject *self, Dtool_PyTypedObject *classdef,
|
||||
PyObject **coerced) {
|
||||
// The supplied parameter is not the required type.
|
||||
if (coerced != NULL) {
|
||||
// Attempt coercion: try to create a temporary instance of the
|
||||
// required class using the supplied parameter.
|
||||
// Because we want to use the special InitNoCoerce constructor
|
||||
// here instead of the regular constructor (we don't want to risk
|
||||
// recursive coercion on the nested type we're creating), we have
|
||||
// to call the constructor with a few more steps.
|
||||
PyObject *obj = NULL;
|
||||
if (classdef->_PyType.tp_new != NULL) {
|
||||
obj = classdef->_PyType.tp_new(&classdef->_PyType, self, NULL);
|
||||
assert(obj != NULL);
|
||||
|
||||
if (PyTuple_Check(self)) {
|
||||
// A tuple was passed, which we assume are the constructor arguments.
|
||||
if (classdef->_Dtool_InitNoCoerce(obj, self) != 0) {
|
||||
Py_DECREF(obj);
|
||||
obj = NULL;
|
||||
}
|
||||
} else {
|
||||
// We need to pack the value into an args tuple.
|
||||
PyObject *args = PyTuple_Pack(1, self);
|
||||
if (classdef->_Dtool_InitNoCoerce(obj, args) != 0) {
|
||||
Py_DECREF(obj);
|
||||
obj = NULL;
|
||||
}
|
||||
Py_DECREF(args);
|
||||
}
|
||||
}
|
||||
if (obj == NULL) {
|
||||
// That didn't work; try to call a static "make" method instead.
|
||||
// Presently, we don't bother filtering this for coercion,
|
||||
// because none of our classes suffer from a recursion danger
|
||||
// here. Maybe one day we will need to also construct a
|
||||
// makeNoCoerce wrapper?
|
||||
PyObject *make = PyObject_GetAttrString((PyObject *)classdef, "make");
|
||||
if (make != NULL) {
|
||||
PyErr_Clear();
|
||||
if (PyTuple_Check(self)) {
|
||||
obj = PyObject_CallObject(make, self);
|
||||
} else {
|
||||
obj = PyObject_CallFunctionObjArgs(make, self, NULL);
|
||||
}
|
||||
Py_DECREF(make);
|
||||
}
|
||||
}
|
||||
if (obj != NULL) {
|
||||
// Well, whaddaya know? The supplied parameter(s) suited
|
||||
// the object's constructor. Now we have a temporary object
|
||||
// that we can pass to the function.
|
||||
Dtool_PyTypedObject *my_type = ((Dtool_PyInstDef *)obj)->_My_Type;
|
||||
void *result = my_type->_Dtool_UpcastInterface(obj, classdef);
|
||||
if (result != NULL) {
|
||||
// Successfully coerced. Store the newly-allocated
|
||||
// pointer, so the caller can release the coerced object
|
||||
// at his leisure. We store it in a list, so that other
|
||||
// parameters can accumulate there too.
|
||||
if ((*coerced) == NULL) {
|
||||
(*coerced) = PyList_New(0);
|
||||
}
|
||||
PyList_Append(*coerced, obj);
|
||||
Py_DECREF(obj);
|
||||
return result;
|
||||
}
|
||||
// Some problem getting the C++ pointer from our created
|
||||
// temporary object. Weird.
|
||||
Py_DECREF(obj);
|
||||
}
|
||||
|
||||
// Clear the error returned by the coercion constructor. It's not
|
||||
// the error message we want to report.
|
||||
PyErr_Clear();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Temporary function to preserve backward compatibility.
|
||||
void *
|
||||
DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
|
||||
int param, const string &function_name, bool const_ok,
|
||||
PyObject **coerced) {
|
||||
return DTOOL_Call_GetPointerThisClass(self, classdef,
|
||||
param, function_name, const_ok,
|
||||
coerced, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DTOOL_Call_GetPointerThisClass
|
||||
// Description: Extracts the C++ pointer for an object, given its
|
||||
|
|
@ -176,18 +81,6 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
|
|||
// declared non-const, and can therefore be called with
|
||||
// only a non-const "this" pointer.
|
||||
//
|
||||
// If coerced is non-NULL, parameter coercion will be
|
||||
// attempted. This means the supplied parameter may not
|
||||
// exactly match the required type, but will satisfy the
|
||||
// require type's constructor; and we will create
|
||||
// temporary object(s) of the required type instead. In
|
||||
// this case, coerced is a pointer to a PyList that will
|
||||
// be filled with these temporary objects. If coerced
|
||||
// is a pointer to a NULL PyObject, a new PyList will be
|
||||
// created on the first successful coercion. If coerced
|
||||
// itself is NULL, parameter coercion will not be
|
||||
// attempted.
|
||||
//
|
||||
// The return value is the C++ pointer that was
|
||||
// extracted, or NULL if there was a problem (in which
|
||||
// case the Python exception state will have been set).
|
||||
|
|
@ -195,103 +88,42 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
|
|||
void *
|
||||
DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
|
||||
int param, const string &function_name, bool const_ok,
|
||||
PyObject **coerced, bool report_errors) {
|
||||
if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
if (self != NULL) {
|
||||
if (DtoolCanThisBeAPandaInstance(self)) {
|
||||
Dtool_PyTypedObject *my_type = ((Dtool_PyInstDef *)self)->_My_Type;
|
||||
void *result = my_type->_Dtool_UpcastInterface(self, classdef);
|
||||
if (result != NULL) {
|
||||
if (const_ok || !((Dtool_PyInstDef *)self)->_is_const) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (report_errors) {
|
||||
ostringstream str;
|
||||
str << function_name << "() argument " << param << " may not be const";
|
||||
string msg = str.str();
|
||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||
}
|
||||
|
||||
} else {
|
||||
if (report_errors) {
|
||||
ostringstream str;
|
||||
str << function_name << "() argument " << param << " must be ";
|
||||
|
||||
PyObject *fname = PyObject_GetAttrString((PyObject *)classdef, "__name__");
|
||||
if (fname != (PyObject *)NULL) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
str << PyUnicode_AsUTF8(fname);
|
||||
#else
|
||||
str << PyString_AsString(fname);
|
||||
#endif
|
||||
Py_DECREF(fname);
|
||||
} else {
|
||||
str << classdef->_name;
|
||||
}
|
||||
|
||||
PyObject *tname = PyObject_GetAttrString((PyObject *)Py_TYPE(self), "__name__");
|
||||
if (tname != (PyObject *)NULL) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
str << ", not " << PyUnicode_AsUTF8(tname);
|
||||
#else
|
||||
str << ", not " << PyString_AsString(tname);
|
||||
#endif
|
||||
Py_DECREF(tname);
|
||||
} else {
|
||||
str << ", not " << my_type->_name;
|
||||
}
|
||||
|
||||
string msg = str.str();
|
||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// The parameter was not a Panda type. Can we coerce it to the
|
||||
// appropriate type, by creating a temporary object?
|
||||
void *result = attempt_coercion(self, classdef, coerced);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Coercion failed.
|
||||
if (report_errors) {
|
||||
ostringstream str;
|
||||
str << function_name << "() argument " << param << " must be ";
|
||||
|
||||
PyObject *fname = PyObject_GetAttrString((PyObject *)classdef, "__name__");
|
||||
if (fname != (PyObject *)NULL) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
str << PyUnicode_AsUTF8(fname);
|
||||
#else
|
||||
str << PyString_AsString(fname);
|
||||
#endif
|
||||
Py_DECREF(fname);
|
||||
} else {
|
||||
str << classdef->_name;
|
||||
}
|
||||
|
||||
PyObject *tname = PyObject_GetAttrString((PyObject *)Py_TYPE(self), "__name__");
|
||||
if (tname != (PyObject *)NULL) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
str << ", not " << PyUnicode_AsUTF8(tname);
|
||||
#else
|
||||
str << ", not " << PyString_AsString(tname);
|
||||
#endif
|
||||
Py_DECREF(tname);
|
||||
}
|
||||
|
||||
string msg = str.str();
|
||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool report_errors) {
|
||||
//if (PyErr_Occurred()) {
|
||||
// return NULL;
|
||||
//}
|
||||
if (self == NULL) {
|
||||
if (report_errors) {
|
||||
PyErr_SetString(PyExc_TypeError, "self is NULL");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (DtoolCanThisBeAPandaInstance(self)) {
|
||||
void *result = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, classdef);
|
||||
|
||||
if (result != NULL) {
|
||||
if (const_ok || !((Dtool_PyInstDef *)self)->_is_const) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (report_errors) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s() argument %d may not be const",
|
||||
function_name.c_str(), param);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (report_errors) {
|
||||
PyTypeObject *tp = Py_TYPE(self);
|
||||
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s() argument %d must be %s, not %s",
|
||||
function_name.c_str(), param,
|
||||
classdef->_PyType.tp_name, tp->tp_name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -314,7 +146,7 @@ void *DTOOL_Call_GetPointerThis(PyObject *self) {
|
|||
// this function relies on the behavior of typed objects in the panda system.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, bool is_const, int RunTimeType) {
|
||||
PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int type_index) {
|
||||
if (local_this_in == NULL) {
|
||||
// Let's not be stupid..
|
||||
PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'");
|
||||
|
|
@ -324,11 +156,11 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
|
|||
/////////////////////////////////////////////////////
|
||||
// IF the class is possibly a run time typed object
|
||||
/////////////////////////////////////////////////////
|
||||
if (RunTimeType > 0) {
|
||||
if (type_index > 0) {
|
||||
/////////////////////////////////////////////////////
|
||||
// get best fit class...
|
||||
/////////////////////////////////////////////////////
|
||||
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(RunTimeType);
|
||||
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(type_index);
|
||||
if (target_class != NULL) {
|
||||
/////////////////////////////////////////////////////
|
||||
// cast to the type...
|
||||
|
|
@ -343,7 +175,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
|
|||
self->_ptr_to_object = new_local_this;
|
||||
self->_memory_rules = memory_rules;
|
||||
self->_is_const = is_const;
|
||||
self->_signature = PY_PANDA_SIGNATURE;
|
||||
//self->_signature = PY_PANDA_SIGNATURE;
|
||||
self->_My_Type = target_class;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
|
@ -360,7 +192,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
|
|||
self->_ptr_to_object = local_this_in;
|
||||
self->_memory_rules = memory_rules;
|
||||
self->_is_const = is_const;
|
||||
self->_signature = PY_PANDA_SIGNATURE;
|
||||
//self->_signature = PY_PANDA_SIGNATURE;
|
||||
self->_My_Type = &known_class_type;
|
||||
}
|
||||
return (PyObject *)self;
|
||||
|
|
@ -425,7 +257,7 @@ void
|
|||
RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id) {
|
||||
if (class_id == 0) {
|
||||
interrogatedb_cat.warning()
|
||||
<< "Class " << otype->_name
|
||||
<< "Class " << otype->_PyType.tp_name
|
||||
<< " has a zero TypeHandle value; check that init_type() is called.\n";
|
||||
|
||||
} else if (class_id > 0) {
|
||||
|
|
@ -436,13 +268,14 @@ RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id) {
|
|||
// There was already an entry in the dictionary for class_id.
|
||||
Dtool_PyTypedObject *other_type = (*result.first).second;
|
||||
interrogatedb_cat.warning()
|
||||
<< "Classes " << otype->_name << " and " << other_type->_name
|
||||
<< "Classes " << otype->_PyType.tp_name
|
||||
<< " and " << other_type->_PyType.tp_name
|
||||
<< " share the same TypeHandle value (" << class_id
|
||||
<< "); check class definitions.\n";
|
||||
|
||||
} else {
|
||||
GetRunTimeTypeList().insert(class_id);
|
||||
otype->_Dtool_IsRunTimeCapable = true;
|
||||
otype->_type = TypeRegistry::ptr()->find_type_by_id(class_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -523,18 +356,24 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
|
|||
PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
|
||||
PyObject *from_in = NULL;
|
||||
PyObject *to_in = NULL;
|
||||
if (PyArg_ParseTuple(args, "OO", &to_in, &from_in)) {
|
||||
if (PyArg_UnpackTuple(args, "Dtool_BorrowThisReference", 2, 2, &to_in, &from_in)) {
|
||||
|
||||
if (DtoolCanThisBeAPandaInstance(from_in) && DtoolCanThisBeAPandaInstance(to_in)) {
|
||||
Dtool_PyInstDef * from = (Dtool_PyInstDef *) from_in;
|
||||
Dtool_PyInstDef * to = (Dtool_PyInstDef *) to_in;
|
||||
Dtool_PyInstDef *from = (Dtool_PyInstDef *) from_in;
|
||||
Dtool_PyInstDef *to = (Dtool_PyInstDef *) to_in;
|
||||
|
||||
//if (PyObject_TypeCheck(to_in, Py_TYPE(from_in))) {
|
||||
if (from->_My_Type == to->_My_Type) {
|
||||
to->_memory_rules = false;
|
||||
to->_is_const = from->_is_const;
|
||||
to->_ptr_to_object = from->_ptr_to_object;
|
||||
return Py_BuildValue("");
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "Must Be Same Type??");
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "types %s and %s do not match",
|
||||
Py_TYPE(from)->tp_name, Py_TYPE(to)->tp_name);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "One of these does not appear to be DTOOL Instance ??");
|
||||
}
|
||||
|
|
@ -772,18 +611,15 @@ PyObject *map_deepcopy_to_copy(PyObject *self, PyObject *args) {
|
|||
// either a regular integer or a long integer, according
|
||||
// to whether the indicated value will fit.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
EXPCL_DTOOLCONFIG PyObject *
|
||||
PyLongOrInt_FromUnsignedLong(unsigned long value) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
// Python 3 only has longs.
|
||||
return PyLong_FromUnsignedLong(value);
|
||||
#else
|
||||
if ((long)value < 0) {
|
||||
return PyLong_FromUnsignedLong(value);
|
||||
} else {
|
||||
return PyInt_FromLong((long)value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Too do list ..
|
||||
// We need a better dispatcher for the functions.. The behavior today is
|
||||
// try one till it works or you run out of possibilities.. This is anything but optimal
|
||||
// for performance and is treading on thin ice for function python or c++ will
|
||||
// We need a better dispatcher for the functions.. The behavior today is
|
||||
// try one till it works or you run out of possibilities.. This is anything but optimal
|
||||
// for performance and is treading on thin ice for function python or c++ will
|
||||
// course there types to other types.
|
||||
//
|
||||
// The linking step will produce allot of warnings
|
||||
// The linking step will produce allot of warnings
|
||||
// warning LNK4049: locally defined symbol..
|
||||
//
|
||||
// Get a second coder to review this file and the generated code ..
|
||||
|
|
@ -40,6 +40,8 @@
|
|||
|
||||
#endif
|
||||
|
||||
#include "pnotify.h"
|
||||
|
||||
#if defined(HAVE_PYTHON) && !defined(CPPPARSER)
|
||||
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
|
|
@ -102,21 +104,29 @@ inline PyObject* doPy_RETURN_FALSE()
|
|||
#define Py_TPFLAGS_CHECKTYPES 0
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
// For writing code that will compile in both versions.
|
||||
#define nb_nonzero nb_bool
|
||||
#define nb_divide nb_true_divide
|
||||
#define nb_inplace_divide nb_inplace_true_divide
|
||||
|
||||
#define PyLongOrInt_FromSize_t PyLong_FromSize_t
|
||||
#define PyLongOrInt_FromLong PyLong_FromLong
|
||||
#define PyLongOrInt_FromUnsignedLong PyLong_FromUnsignedLong
|
||||
#define PyInt_Check PyLong_Check
|
||||
#define PyInt_AsLong PyLong_Aslong
|
||||
#define PyInt_AS_LONG PyLong_AS_LONG
|
||||
#else
|
||||
// PyInt_FromSize_t automatically picks the right type.
|
||||
#define PyLongOrInt_FromSize_t PyInt_FromSize_t
|
||||
#define PyLongOrInt_FromLong PyInt_FromLong
|
||||
|
||||
// For more portably defining hash functions.
|
||||
typedef long Py_hash_t;
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define nb_nonzero nb_bool
|
||||
#define nb_divide nb_true_divide
|
||||
#define nb_inplace_divide nb_inplace_true_divide
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define PY_PANDA_SMALLER_FOOTPRINT 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// this is tempory .. untill this is glued better into the panda build system
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -138,43 +148,28 @@ EXPCL_DTOOLCONFIG RunTimeTypeDictionary &GetRunTimeDictionary();
|
|||
EXPCL_DTOOLCONFIG RunTimeTypeList &GetRunTimeTypeList();
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// used to stamp dtool instance..
|
||||
// used to stamp dtool instance..
|
||||
#define PY_PANDA_SIGNATURE 0xbeaf
|
||||
typedef void * ( * ConvertFunctionType )(PyObject *,Dtool_PyTypedObject * );
|
||||
typedef void * ( * ConvertFunctionType1 )(void *, Dtool_PyTypedObject *);
|
||||
typedef void ( *FreeFunction )(PyObject *);
|
||||
typedef void ( *PyModuleClassInit)(PyObject *module);
|
||||
typedef int ( *InitNoCoerce)(PyObject *self, PyObject *args);
|
||||
typedef void *(*UpcastFunction)(PyObject *,Dtool_PyTypedObject *);
|
||||
typedef void *(*DowncastFunction)(void *, Dtool_PyTypedObject *);
|
||||
|
||||
//inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type);
|
||||
inline void Dtool_Deallocate_General(PyObject * self);
|
||||
//inline void Dtool_Deallocate_General(PyObject * self);
|
||||
//inline int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2);
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// THIS IS THE INSTANCE CONTAINER FOR ALL panda py objects....
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifdef PY_PANDA_SMALLER_FOOTPRINT
|
||||
// this should save 8 bytes per object ....
|
||||
struct Dtool_PyInstDef {
|
||||
PyObject_HEAD
|
||||
void *_ptr_to_object;
|
||||
struct Dtool_PyTypedObject *_My_Type;
|
||||
unsigned short _signature ;
|
||||
unsigned short _signature;
|
||||
int _memory_rules : 1; // true if we own the pointer and should delete it or unref it
|
||||
int _is_const : 1; // true if this is a "const" pointer.
|
||||
};
|
||||
|
||||
#else
|
||||
struct Dtool_PyInstDef {
|
||||
PyObject_HEAD
|
||||
void *_ptr_to_object;
|
||||
int _memory_rules; // true if we own the pointer and should delete it or unref it
|
||||
int _is_const; // true if this is a "const" pointer.
|
||||
unsigned long _signature;
|
||||
struct Dtool_PyTypedObject *_My_Type;
|
||||
};
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// A Offset Dictionary Defining How to read the Above Object..
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -188,13 +183,11 @@ struct Dtool_PyTypedObject {
|
|||
PyTypeObject _PyType;
|
||||
|
||||
// My Class Level Features..
|
||||
const char *_name; // cpp name for the object
|
||||
bool _Dtool_IsRunTimeCapable; // derived from TypedObject
|
||||
ConvertFunctionType _Dtool_UpcastInterface; // The Upcast Function By Slot
|
||||
ConvertFunctionType1 _Dtool_DowncastInterface; // The Downcast Function By Slot
|
||||
FreeFunction _Dtool_FreeInstance;
|
||||
PyModuleClassInit _Dtool_ClassInit; // The module init function pointer
|
||||
InitNoCoerce _Dtool_InitNoCoerce; // A variant of the constructor that does not attempt to perform coercion of its arguments.
|
||||
UpcastFunction _Dtool_UpcastInterface; // The Upcast Function By Slot
|
||||
DowncastFunction _Dtool_DowncastInterface; // The Downcast Function By Slot
|
||||
|
||||
// May be TypeHandle::none() to indicate a non-TypedObject class.
|
||||
TypeHandle _type;
|
||||
|
||||
// some convenience functions..
|
||||
inline PyTypeObject &As_PyTypeObject() { return _PyType; };
|
||||
|
|
@ -212,7 +205,7 @@ struct Dtool_PyTypedObject {
|
|||
#MODULE_NAME "." #PUBLIC_NAME, /*type name with module */ \
|
||||
sizeof(Dtool_PyInstDef), /* tp_basicsize */ \
|
||||
0, /* tp_itemsize */ \
|
||||
&Dtool_Deallocate_General, /* tp_dealloc */ \
|
||||
&Dtool_FreeInstance_##CLASS_NAME, /* tp_dealloc */ \
|
||||
0, /* tp_print */ \
|
||||
0, /* tp_getattr */ \
|
||||
0, /* tp_setattr */ \
|
||||
|
|
@ -248,13 +241,9 @@ struct Dtool_PyTypedObject {
|
|||
Dtool_new_##CLASS_NAME, /* tp_new */ \
|
||||
PyObject_Del, /* tp_free */ \
|
||||
}, \
|
||||
#CLASS_NAME, \
|
||||
false, \
|
||||
Dtool_UpcastInterface_##CLASS_NAME, \
|
||||
Dtool_DowncastInterface_##CLASS_NAME, \
|
||||
Dtool_FreeInstance_##CLASS_NAME, \
|
||||
Dtool_PyModuleClassInit_##CLASS_NAME, \
|
||||
Dtool_InitNoCoerce_##CLASS_NAME \
|
||||
TypeHandle::none(), \
|
||||
};
|
||||
|
||||
#define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \
|
||||
|
|
@ -265,67 +254,62 @@ struct Dtool_PyTypedObject {
|
|||
Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// The Fast Deallocator.. for Our instances..
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
inline void Dtool_Deallocate_General(PyObject * self) {
|
||||
((Dtool_PyInstDef *)self)->_My_Type->_Dtool_FreeInstance(self);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// More Macro(s) to Implement class functions.. Usually used if C++ needs type information
|
||||
// More Macro(s) to Implement class functions.. Usually used if C++ needs type information
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#define Define_Dtool_new(CLASS_NAME,CNAME)\
|
||||
PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds)\
|
||||
{\
|
||||
PyObject *self = type->tp_alloc(type, 0);\
|
||||
((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\
|
||||
((Dtool_PyInstDef *)self)->_ptr_to_object = NULL;\
|
||||
((Dtool_PyInstDef *)self)->_memory_rules = false;\
|
||||
((Dtool_PyInstDef *)self)->_is_const = false;\
|
||||
((Dtool_PyInstDef *)self)->_My_Type = &Dtool_##CLASS_NAME;\
|
||||
return self;\
|
||||
PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\
|
||||
(void) args; (void) kwds;\
|
||||
PyObject *self = type->tp_alloc(type, 0);\
|
||||
((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\
|
||||
((Dtool_PyInstDef *)self)->_My_Type = &Dtool_##CLASS_NAME;\
|
||||
return self;\
|
||||
}
|
||||
|
||||
// The following used to be in the above macro, but it doesn't seem to
|
||||
// be necessary as tp_alloc memsets the object to 0.
|
||||
//((Dtool_PyInstDef *)self)->_ptr_to_object = NULL;\
|
||||
//((Dtool_PyInstDef *)self)->_memory_rules = false;\
|
||||
//((Dtool_PyInstDef *)self)->_is_const = false;\
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// Delete functions..
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifdef NDEBUG
|
||||
#define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\
|
||||
{\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
|
||||
Py_TYPE(self)->tp_free(self);\
|
||||
}
|
||||
#else // NDEBUG
|
||||
#define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\
|
||||
{\
|
||||
if(((Dtool_PyInstDef *)self)->_ptr_to_object != NULL)\
|
||||
if(((Dtool_PyInstDef *)self)->_memory_rules)\
|
||||
{\
|
||||
cerr << "Detected leak for " << #CLASS_NAME \
|
||||
<< " which interrogate cannot delete.\n"; \
|
||||
}\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
|
||||
if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
|
||||
if (((Dtool_PyInstDef *)self)->_memory_rules) {\
|
||||
cerr << "Detected leak for " << #CLASS_NAME \
|
||||
<< " which interrogate cannot delete.\n"; \
|
||||
}\
|
||||
}\
|
||||
Py_TYPE(self)->tp_free(self);\
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
#define Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\
|
||||
{\
|
||||
if(((Dtool_PyInstDef *)self)->_ptr_to_object != NULL)\
|
||||
if(((Dtool_PyInstDef *)self)->_memory_rules)\
|
||||
{\
|
||||
delete ((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
|
||||
}\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
|
||||
if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
|
||||
if (((Dtool_PyInstDef *)self)->_memory_rules) {\
|
||||
delete ((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
|
||||
}\
|
||||
}\
|
||||
Py_TYPE(self)->tp_free(self);\
|
||||
}
|
||||
|
||||
#define Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\
|
||||
{\
|
||||
if(((Dtool_PyInstDef *)self)->_ptr_to_object != NULL)\
|
||||
if(((Dtool_PyInstDef *)self)->_memory_rules)\
|
||||
{\
|
||||
unref_delete((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
|
||||
}\
|
||||
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
|
||||
if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
|
||||
if (((Dtool_PyInstDef *)self)->_memory_rules) {\
|
||||
unref_delete((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
|
||||
}\
|
||||
}\
|
||||
Py_TYPE(self)->tp_free(self);\
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -333,38 +317,88 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self)\
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ** HACK ** allert..
|
||||
//
|
||||
// Need to keep a runtime type dictionary ... that is forward declared of typed object.
|
||||
// We rely on the fact that typed objects are uniquly defined by an integer.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPCL_DTOOLCONFIG void RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Function : DTOOL_Call_ExtractThisPointerForType
|
||||
//
|
||||
// These are the wrappers that allow for down and upcast from type ..
|
||||
// These are the wrappers that allow for down and upcast from type ..
|
||||
// needed by the Dtool py interface.. Be very careful if you muck
|
||||
// with these as the generated code depends on how this is set
|
||||
// up..
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer);
|
||||
|
||||
EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced, bool report_errors);
|
||||
|
||||
EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced);
|
||||
EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, bool report_errors);
|
||||
|
||||
EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThis(PyObject *self);
|
||||
|
||||
template<class T> INLINE bool DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into) {
|
||||
if (DtoolCanThisBeAPandaInstance(self)) {
|
||||
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
|
||||
if (target_class != NULL) {
|
||||
into = (T*) ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, target_class);
|
||||
return (into != NULL);
|
||||
}
|
||||
}
|
||||
into = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Function : DTool_CreatePyInstanceTyped
|
||||
//
|
||||
// this function relies on the behavior of typed objects in the panda system.
|
||||
// this function relies on the behavior of typed objects in the panda system.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// DTool_CreatePyInstance .. wrapper function to finalize the existance of a general
|
||||
// DTool_CreatePyInstance .. wrapper function to finalize the existance of a general
|
||||
// dtool py instance..
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
|
||||
|
||||
// These template methods allow use when the Dtool_PyTypedObject is not known.
|
||||
// They require a get_class_type() to be defined for the class.
|
||||
template<class T> INLINE PyObject *DTool_CreatePyInstance(const T *obj, bool memory_rules) {
|
||||
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
|
||||
nassertr(known_class != NULL, NULL);
|
||||
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true);
|
||||
}
|
||||
|
||||
template<class T> INLINE PyObject *DTool_CreatePyInstance(T *obj, bool memory_rules) {
|
||||
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
|
||||
nassertr(known_class != NULL, NULL);
|
||||
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false);
|
||||
}
|
||||
|
||||
template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) {
|
||||
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
|
||||
nassertr(known_class != NULL, NULL);
|
||||
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index());
|
||||
}
|
||||
|
||||
template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
|
||||
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
|
||||
nassertr(known_class != NULL, NULL);
|
||||
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Macro(s) class definition .. Used to allocate storage and
|
||||
// Macro(s) class definition .. Used to allocate storage and
|
||||
// init some values for a Dtool Py Type object.
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -374,11 +408,9 @@ EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTyp
|
|||
extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\
|
||||
extern struct PyMethodDef Dtool_Methods_##CLASS_NAME[];\
|
||||
int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
|
||||
int Dtool_InitNoCoerce_##CLASS_NAME(PyObject *self, PyObject *args);\
|
||||
PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
|
||||
void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
|
||||
void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);\
|
||||
void Dtool_PyModuleClassInit_##CLASS_NAME(PyObject *module);
|
||||
void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define Define_Module_Class(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
|
||||
|
|
@ -415,7 +447,7 @@ Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
|
|||
EXPCL_DTOOLCONFIG int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// A heler function to glu methed definition together .. that can not be done at
|
||||
/// A heler function to glu methed definition together .. that can not be done at
|
||||
// code generation time becouse of multiple generation passes in interigate..
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -424,22 +456,8 @@ typedef std::map<std::string, PyMethodDef *> MethodDefmap;
|
|||
EXPCL_DTOOLCONFIG void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ** HACK ** allert..
|
||||
//
|
||||
// Need to keep a runtime type dictionary ... that is forward declared of typed object.
|
||||
// We rely on the fact that typed objects are uniquly defined by an integer.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPCL_DTOOLCONFIG void RegisterRuntimeClass(Dtool_PyTypedObject * otype, int class_id);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// We need a way to runtime merge compile units into a python "Module" .. this is done with the
|
||||
/// fallowing structors and code.. along with the support of interigate_module
|
||||
//// We need a way to runtime merge compile units into a python "Module" .. this is done with the
|
||||
/// fallowing structors and code.. along with the support of interigate_module
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct LibraryDef {
|
||||
typedef void (*ConstantFunction)(PyObject *);
|
||||
|
|
@ -456,7 +474,7 @@ EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const c
|
|||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// HACK.... Be carefull
|
||||
/// HACK.... Be carefull
|
||||
//
|
||||
// Dtool_BorrowThisReference
|
||||
// This function can be used to grab the "THIS" pointer from an object and use it
|
||||
|
|
@ -476,7 +494,7 @@ EXPCL_DTOOLCONFIG long DTool_HashKey(PyObject * inst)
|
|||
{
|
||||
long outcome = (long)inst;
|
||||
PyObject * func = PyObject_GetAttrString(inst, "__hash__");
|
||||
if (func == NULL)
|
||||
if (func == NULL)
|
||||
{
|
||||
if(DtoolCanThisBeAPandaInstance(inst))
|
||||
if(((Dtool_PyInstDef *)inst)->_ptr_to_object != NULL)
|
||||
|
|
@ -488,13 +506,13 @@ EXPCL_DTOOLCONFIG long DTool_HashKey(PyObject * inst)
|
|||
Py_DECREF(func);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
if (PyInt_Check(res))
|
||||
if (PyInt_Check(res))
|
||||
{
|
||||
outcome = PyInt_AsLong(res);
|
||||
if (outcome == -1)
|
||||
outcome = -2;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"__hash__() should return an int");
|
||||
|
|
@ -531,11 +549,15 @@ copy_from_copy_constructor(PyObject *self);
|
|||
EXPCL_DTOOLCONFIG PyObject *
|
||||
map_deepcopy_to_copy(PyObject *self, PyObject *args);
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
// In the Python 3 case, it is defined as a macro, at the beginning of this file.
|
||||
EXPCL_DTOOLCONFIG PyObject *
|
||||
PyLongOrInt_FromUnsignedLong(unsigned long value);
|
||||
#endif
|
||||
|
||||
EXPCL_DTOOLCONFIG extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
|
||||
EXPCL_DTOOLCONFIG extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
|
||||
|
||||
#endif // HAVE_PYTHON && !CPPPARSER
|
||||
|
||||
#endif // PY_PANDA_H_
|
||||
#endif // PY_PANDA_H_
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ typedef _object PyObject;
|
|||
struct _typeobject;
|
||||
typedef _typeobject PyTypeObject;
|
||||
|
||||
struct PyStringObject;
|
||||
struct PyUnicodeObject;
|
||||
typedef struct {} PyStringObject;
|
||||
typedef struct {} PyUnicodeObject;
|
||||
|
||||
class PyThreadState;
|
||||
typedef int Py_ssize_t;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,6 @@ struct X509;
|
|||
struct X509_STORE;
|
||||
struct X509_NAME;
|
||||
struct SSL;
|
||||
#define STACK_OF(num) STACK
|
||||
#define STACK_OF(type) struct stack_st_##type
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
template<class ctype>
|
||||
class basic_string {
|
||||
public:
|
||||
typedef typename size_t size_type;
|
||||
static const size_t npos = (size_t)-1;
|
||||
|
||||
basic_string();
|
||||
basic_string(const basic_string ©);
|
||||
void operator = (const basic_string ©);
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ extern "C" {
|
|||
EXPCL_PYSTUB int PyLong_AsUnsignedLongLong(...);
|
||||
EXPCL_PYSTUB int PyLong_FromLong(...);
|
||||
EXPCL_PYSTUB int PyLong_FromLongLong(...);
|
||||
EXPCL_PYSTUB int PyLong_FromSize_t(...);
|
||||
EXPCL_PYSTUB int PyLong_FromUnsignedLong(...);
|
||||
EXPCL_PYSTUB int PyLong_FromUnsignedLongLong(...);
|
||||
EXPCL_PYSTUB int PyLong_Type(...);
|
||||
|
|
@ -153,6 +154,7 @@ extern "C" {
|
|||
EXPCL_PYSTUB int PyUnicode_AsUTF8(...);
|
||||
EXPCL_PYSTUB int PyUnicode_AsUTF8AndSize(...);
|
||||
EXPCL_PYSTUB int PyUnicode_AsWideChar(...);
|
||||
EXPCL_PYSTUB int PyUnicode_AsWideCharString(...);
|
||||
EXPCL_PYSTUB int PyUnicode_FromString(...);
|
||||
EXPCL_PYSTUB int PyUnicode_FromStringAndSize(...);
|
||||
EXPCL_PYSTUB int PyUnicode_FromWideChar(...);
|
||||
|
|
@ -263,6 +265,7 @@ int PyLong_AsUnsignedLong(...) { return 0; }
|
|||
int PyLong_AsUnsignedLongLong(...) { return 0; }
|
||||
int PyLong_FromLong(...) { return 0; }
|
||||
int PyLong_FromLongLong(...) { return 0; }
|
||||
int PyLong_FromSize_t(...) { return 0; }
|
||||
int PyLong_FromUnsignedLong(...) { return 0; }
|
||||
int PyLong_FromUnsignedLongLong(...) { return 0; }
|
||||
int PyLong_Type(...) { return 0; }
|
||||
|
|
@ -337,6 +340,7 @@ int PyUnicodeUCS4_GetSize(...) { return 0; }
|
|||
int PyUnicode_AsUTF8(...) { return 0; }
|
||||
int PyUnicode_AsUTF8AndSize(...) { return 0; }
|
||||
int PyUnicode_AsWideChar(...) { return 0; }
|
||||
int PyUnicode_AsWideCharString(...) { return 0; }
|
||||
int PyUnicode_FromString(...) { return 0; }
|
||||
int PyUnicode_FromStringAndSize(...) { return 0; }
|
||||
int PyUnicode_FromWideChar(...) { return 0; }
|
||||
|
|
|
|||
|
|
@ -2416,13 +2416,16 @@ def CopyPythonTree(dstdir, srcdir, lib2to3_fixers=[]):
|
|||
for fixer in lib2to3_fixers:
|
||||
lib2to3_args += ['-f', fixer]
|
||||
|
||||
exclude_files = set(VCS_FILES)
|
||||
exclude_files.add('panda3d.py')
|
||||
|
||||
refactor = []
|
||||
for entry in os.listdir(srcdir):
|
||||
srcpth = os.path.join(srcdir, entry)
|
||||
dstpth = os.path.join(dstdir, entry)
|
||||
if (os.path.isfile(srcpth)):
|
||||
if os.path.isfile(srcpth):
|
||||
base, ext = os.path.splitext(entry)
|
||||
if entry not in VCS_FILES and ext not in SUFFIX_INC + ['.pyc', '.pyo']:
|
||||
if entry not in exclude_files and ext not in SUFFIX_INC + ['.pyc', '.pyo']:
|
||||
if (NeedsBuild([dstpth], [srcpth])):
|
||||
WriteBinaryFile(dstpth, ReadBinaryFile(srcpth))
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ get_num_screens() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
NodePath NonlinearImager::
|
||||
get_screen(int index) const {
|
||||
nassertr(index >= 0 && index < (int)_screens.size(), (ProjectionScreen *)NULL);
|
||||
nassertr(index >= 0 && index < (int)_screens.size(), NodePath());
|
||||
return _screens[index]._screen;
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +215,7 @@ get_buffer(int index) const {
|
|||
void NonlinearImager::
|
||||
set_texture_size(int index, int width, int height) {
|
||||
nassertv(index >= 0 && index < (int)_screens.size());
|
||||
|
||||
|
||||
Screen &screen = _screens[index];
|
||||
|
||||
screen._tex_width = width;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ PUBLISHED:
|
|||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
Curves _curves_on_surface;
|
||||
Trims _trims;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,3 +12,42 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PythonTask::set_delay
|
||||
// Access: Public
|
||||
// Description: If None is passed, calls clear_delay, otherwise
|
||||
// sets the delay time. See AsyncTask::set_delay()
|
||||
// and AsyncTask::clear_delay().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PythonTask::
|
||||
set_delay(PyObject *delay) {
|
||||
if (delay == Py_None) {
|
||||
AsyncTask::clear_delay();
|
||||
return;
|
||||
}
|
||||
|
||||
PyObject *value = PyNumber_Float(delay);
|
||||
if (value == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
AsyncTask::set_delay(PyFloat_AS_DOUBLE(value));
|
||||
Py_DECREF(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PythonTask::get_delay
|
||||
// Access: Public
|
||||
// Description: Returns the delay time if set, None otherwise.
|
||||
// See AsyncTask::has_delay() and AsyncTask::get_delay().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PyObject *PythonTask::
|
||||
get_delay() const {
|
||||
if (AsyncTask::has_delay()) {
|
||||
return PyFloat_FromDouble(AsyncTask::get_delay());
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include "config_event.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#include "py_panda.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
TypeHandle PythonTask::_type_handle;
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ PythonTask(PyObject *function, const string &name) :
|
|||
set_upon_death(Py_None);
|
||||
set_owner(Py_None);
|
||||
|
||||
_dict = PyDict_New();
|
||||
__dict__ = PyDict_New();
|
||||
|
||||
#ifndef SIMPLE_THREADS
|
||||
// Ensure that the Python threading system is initialized and ready
|
||||
|
|
@ -71,7 +71,7 @@ PythonTask::
|
|||
~PythonTask() {
|
||||
Py_DECREF(_function);
|
||||
Py_DECREF(_args);
|
||||
Py_DECREF(_dict);
|
||||
Py_DECREF(__dict__);
|
||||
Py_XDECREF(_generator);
|
||||
Py_XDECREF(_owner);
|
||||
Py_XDECREF(_upon_death);
|
||||
|
|
@ -118,7 +118,7 @@ void PythonTask::
|
|||
set_args(PyObject *args, bool append_task) {
|
||||
Py_XDECREF(_args);
|
||||
_args = NULL;
|
||||
|
||||
|
||||
if (args == Py_None) {
|
||||
// None means no arguments; create an empty tuple.
|
||||
_args = PyTuple_New(0);
|
||||
|
|
@ -249,53 +249,36 @@ get_owner() {
|
|||
// arbitrary data to the Task object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PythonTask::
|
||||
__setattr__(const string &attr_name, PyObject *v) {
|
||||
__setattr__(PyObject *self, PyObject *attr, PyObject *v) {
|
||||
if (PyObject_GenericSetAttr(self, attr, v) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
|
||||
if (task_cat.is_debug()) {
|
||||
PyObject *str = PyObject_Repr(v);
|
||||
task_cat.debug()
|
||||
<< *this << ": task." << attr_name << " = "
|
||||
task_cat.debug()
|
||||
<< *this << ": task."
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
<< PyUnicode_AsUTF8(attr) << " = "
|
||||
<< PyUnicode_AsUTF8(str) << "\n";
|
||||
#else
|
||||
<< PyString_AsString(str) << "\n";
|
||||
<< PyString_AsString(attr) << " = "
|
||||
<< PyString_AsString(str) << "\n";
|
||||
#endif
|
||||
Py_DECREF(str);
|
||||
}
|
||||
|
||||
if (attr_name == "delayTime") {
|
||||
if (v == Py_None) {
|
||||
clear_delay();
|
||||
} else {
|
||||
double delay = PyFloat_AsDouble(v);
|
||||
if (!PyErr_Occurred()) {
|
||||
set_delay(delay);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (attr_name == "name") {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
char *name = PyUnicode_AsUTF8(v);
|
||||
#else
|
||||
char *name = PyString_AsString(v);
|
||||
#endif
|
||||
if (name != (char *)NULL) {
|
||||
set_name(name);
|
||||
}
|
||||
|
||||
} else if (attr_name == "id" || attr_name == "time" ||
|
||||
attr_name == "frame" || attr_name == "wakeTime") {
|
||||
nassert_raise("Cannot set constant value");
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return PyDict_SetItemString(_dict, attr_name.c_str(), v);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PyDict_SetItem(__dict__, attr, v);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PythonTask::__setattr__
|
||||
// Function: PythonTask::__delattr__
|
||||
// Access: Published
|
||||
// Description: Maps from an expression like "del task.attr_name".
|
||||
// This is customized here so we can support some
|
||||
|
|
@ -304,8 +287,32 @@ __setattr__(const string &attr_name, PyObject *v) {
|
|||
// arbitrary data to the Task object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PythonTask::
|
||||
__setattr__(const string &attr_name) {
|
||||
return PyDict_DelItemString(_dict, attr_name.c_str());
|
||||
__delattr__(PyObject *self, PyObject *attr) {
|
||||
if (PyObject_GenericSetAttr(self, attr, NULL) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
|
||||
if (PyDict_DelItem(__dict__, attr) == -1) {
|
||||
// PyDict_DelItem does not raise an exception.
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"'PythonTask' object has no attribute '%.400s'",
|
||||
PyString_AS_STRING(attr));
|
||||
#else
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"'PythonTask' object has no attribute '%U'",
|
||||
attr);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -318,43 +325,32 @@ __setattr__(const string &attr_name) {
|
|||
// arbitrary data to the Task object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *PythonTask::
|
||||
__getattr__(const string &attr_name) const {
|
||||
if (attr_name == "time") {
|
||||
return PyFloat_FromDouble(get_elapsed_time());
|
||||
__getattr__(PyObject *attr) const {
|
||||
// Note that with the new Interrogate behavior, this method
|
||||
// behaves more like the Python __getattr__ rather than being
|
||||
// directly assigned to the tp_getattro slot (a la __getattribute__).
|
||||
// So, we won't get here when the attribute has already been found
|
||||
// via other methods.
|
||||
|
||||
} else if (attr_name == "name") {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyUnicode_FromString(get_name().c_str());
|
||||
PyObject *item = PyDict_GetItem(__dict__, attr);
|
||||
|
||||
if (item == NULL) {
|
||||
// PyDict_GetItem does not raise an exception.
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"'PythonTask' object has no attribute '%.400s'",
|
||||
PyString_AS_STRING(attr));
|
||||
#else
|
||||
return PyString_FromString(get_name().c_str());
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"'PythonTask' object has no attribute '%U'",
|
||||
attr);
|
||||
#endif
|
||||
|
||||
} else if (attr_name == "wakeTime") {
|
||||
return PyFloat_FromDouble(get_wake_time());
|
||||
|
||||
} else if (attr_name == "delayTime") {
|
||||
if (!has_delay()) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return PyFloat_FromDouble(get_delay());
|
||||
|
||||
} else if (attr_name == "frame") {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyLong_FromLong(get_elapsed_frames());
|
||||
#else
|
||||
return PyInt_FromLong(get_elapsed_frames());
|
||||
#endif
|
||||
|
||||
} else if (attr_name == "id") {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyLong_FromLong(_task_id);
|
||||
#else
|
||||
return PyInt_FromLong(_task_id);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
return PyMapping_GetItemString(_dict, (char *)attr_name.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// PyDict_GetItem returns a borrowed reference.
|
||||
Py_INCREF(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -43,9 +43,44 @@ PUBLISHED:
|
|||
void set_owner(PyObject *owner);
|
||||
PyObject *get_owner();
|
||||
|
||||
int __setattr__(const string &attr_name, PyObject *v);
|
||||
int __setattr__(const string &attr_name);
|
||||
PyObject *__getattr__(const string &attr_name) const;
|
||||
int __setattr__(PyObject *self, PyObject *attr, PyObject *v);
|
||||
int __delattr__(PyObject *self, PyObject *attr);
|
||||
PyObject *__getattr__(PyObject *attr) const;
|
||||
|
||||
INLINE void set_delay(PyObject *delay);
|
||||
INLINE PyObject *get_delay() const;
|
||||
|
||||
PUBLISHED:
|
||||
// The name of this task.
|
||||
MAKE_PROPERTY(name, get_name, set_name);
|
||||
|
||||
// The amount of seconds that have elapsed since the task was
|
||||
// started, according to the task manager's clock.
|
||||
MAKE_PROPERTY(time, get_elapsed_time);
|
||||
|
||||
// If this task has been added to an AsyncTaskManager with a delay
|
||||
// in effect, this contains the time at which the task is expected
|
||||
// to awaken. It has no meaning of the task has not yet been added
|
||||
// to a queue, or if there was no delay in effect at the time the
|
||||
// task was added.
|
||||
//
|
||||
// If the task's status is not S_sleeping, this contains 0.0.
|
||||
MAKE_PROPERTY(wake_time, get_wake_time);
|
||||
|
||||
// The delay value that has been set on this task, if any, or None.
|
||||
MAKE_PROPERTY(delay_time, get_delay, set_delay);
|
||||
|
||||
// The number of frames that have elapsed since the task was
|
||||
// started, according to the task manager's clock.
|
||||
MAKE_PROPERTY(frame, get_elapsed_frames);
|
||||
|
||||
// This is a number guaranteed to be unique for each different
|
||||
// AsyncTask object in the universe.
|
||||
MAKE_PROPERTY(id, get_task_id);
|
||||
|
||||
// This is a special variable to hold the instance dictionary in
|
||||
// which custom variables may be stored.
|
||||
PyObject *__dict__;
|
||||
|
||||
protected:
|
||||
virtual bool is_runnable();
|
||||
|
|
@ -67,7 +102,6 @@ private:
|
|||
PyObject *_upon_death;
|
||||
PyObject *_owner;
|
||||
bool _registered_to_owner;
|
||||
PyObject *_dict;
|
||||
|
||||
PyObject *_generator;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
// Filename: filename_ext.cxx
|
||||
// Created by: rdb (17Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "filename_ext.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Extension<Filename>::__reduce__
|
||||
// Access: Published
|
||||
// Description: This special Python method is implement to provide
|
||||
// support for the pickle module.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *Extension<Filename>::
|
||||
__reduce__(PyObject *self) const {
|
||||
// We should return at least a 2-tuple, (Class, (args)): the
|
||||
// necessary class object whose constructor we should call
|
||||
// (e.g. this), and the arguments necessary to reconstruct this
|
||||
// object.
|
||||
PyTypeObject *this_class = Py_TYPE(self);
|
||||
if (this_class == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *result = Py_BuildValue("(O(s))", this_class, _this->c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Extension<Filename>::scan_directory
|
||||
// Access: Published
|
||||
// Description: This variant on scan_directory returns a Python list
|
||||
// of strings on success, or None on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *Extension<Filename>::
|
||||
scan_directory() const {
|
||||
vector_string contents;
|
||||
if (!_this->scan_directory(contents)) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *result = PyList_New(contents.size());
|
||||
for (size_t i = 0; i < contents.size(); ++i) {
|
||||
const string &filename = contents[i];
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
// This function expects UTF-8.
|
||||
PyObject *str = PyUnicode_FromStringAndSize(filename.data(), filename.size());
|
||||
#else
|
||||
PyObject *str = PyString_FromStringAndSize(filename.data(), filename.size());
|
||||
#endif
|
||||
PyList_SET_ITEM(result, i, str);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Filename: filename_ext.h
|
||||
// Created by: rdb (17Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FILENAME_EXT_H
|
||||
#define FILENAME_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "filename.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<Filename>
|
||||
// Description : This class defines the extension methods for
|
||||
// Filename, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<Filename> : public ExtensionBase<Filename> {
|
||||
public:
|
||||
PyObject *__reduce__(PyObject *self) const;
|
||||
PyObject *scan_directory() const;
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // FILENAME_EXT_H
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Filename: globPattern_ext.cxx
|
||||
// Created by: rdb (17Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "globPattern_ext.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Extension<GlobPattern>::match_files
|
||||
// Access: Published
|
||||
// Description: This variant on match_files returns a Python list
|
||||
// of strings.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *Extension<GlobPattern>::
|
||||
match_files(const Filename &cwd) const {
|
||||
vector_string contents;
|
||||
_this->match_files(contents, cwd);
|
||||
|
||||
PyObject *result = PyList_New(contents.size());
|
||||
for (size_t i = 0; i < contents.size(); ++i) {
|
||||
const string &filename = contents[i];
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
// This function expects UTF-8.
|
||||
PyObject *str = PyUnicode_FromStringAndSize(filename.data(), filename.size());
|
||||
#else
|
||||
PyObject *str = PyString_FromStringAndSize(filename.data(), filename.size());
|
||||
#endif
|
||||
PyList_SET_ITEM(result, i, str);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Filename: globPattern_ext.h
|
||||
// Created by: rdb (17Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GLOBPATTERN_EXT_H
|
||||
#define GLOBPATTERN_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "globPattern.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<GlobPattern>
|
||||
// Description : This class defines the extension methods for
|
||||
// GlobPattern, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<GlobPattern> : public ExtensionBase<GlobPattern> {
|
||||
public:
|
||||
PyObject *match_files(const Filename &cwd = Filename()) const;
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // GLOBPATTERN_EXT_H
|
||||
|
|
@ -84,27 +84,14 @@ PUBLISHED:
|
|||
int compression_level);
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
class CertRecord {
|
||||
public:
|
||||
INLINE CertRecord(X509 *cert);
|
||||
INLINE CertRecord(const CertRecord ©);
|
||||
INLINE ~CertRecord();
|
||||
INLINE void operator = (const CertRecord &other);
|
||||
X509 *_cert;
|
||||
};
|
||||
typedef pvector<CertRecord> CertChain;
|
||||
|
||||
bool add_signature(const Filename &certificate,
|
||||
bool add_signature(const Filename &certificate,
|
||||
const Filename &chain,
|
||||
const Filename &pkey,
|
||||
const string &password = "");
|
||||
bool add_signature(const Filename &composite,
|
||||
bool add_signature(const Filename &composite,
|
||||
const string &password = "");
|
||||
bool add_signature(X509 *certificate, STACK_OF(X509) *chain, EVP_PKEY *pkey);
|
||||
bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
|
||||
|
||||
int get_num_signatures() const;
|
||||
const CertChain &get_signature(int n) const;
|
||||
string get_signature_subject_name(int n) const;
|
||||
string get_signature_friendly_name(int n) const;
|
||||
string get_signature_public_key(int n) const;
|
||||
|
|
@ -152,6 +139,23 @@ PUBLISHED:
|
|||
INLINE const string &get_header_prefix() const;
|
||||
|
||||
public:
|
||||
#ifdef HAVE_OPENSSL
|
||||
class CertRecord {
|
||||
public:
|
||||
INLINE CertRecord(X509 *cert);
|
||||
INLINE CertRecord(const CertRecord ©);
|
||||
INLINE ~CertRecord();
|
||||
INLINE void operator = (const CertRecord &other);
|
||||
X509 *_cert;
|
||||
};
|
||||
typedef pvector<CertRecord> CertChain;
|
||||
|
||||
bool add_signature(X509 *certificate, STACK_OF(X509) *chain, EVP_PKEY *pkey);
|
||||
bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
|
||||
|
||||
const CertChain &get_signature(int n) const;
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
bool read_subfile(int index, string &result);
|
||||
bool read_subfile(int index, pvector<unsigned char> &result);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#include "filename_ext.cxx"
|
||||
#include "globPattern_ext.cxx"
|
||||
#include "memoryUsagePointers_ext.cxx"
|
||||
#include "ramfile_ext.cxx"
|
||||
#include "streamReader_ext.cxx"
|
||||
#include "typeHandle_ext.cxx"
|
||||
#include "virtualFileSystem_ext.cxx"
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ PointerToArray(PyObject *self, PyObject *source) :
|
|||
PyErr_SetString(PyExc_ValueError, str.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int num_elements = size / sizeof(Element);
|
||||
insert(begin(), num_elements, Element());
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ PointerToArray(PyObject *self, PyObject *source) :
|
|||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod(self, (char *)"pushBack", (char *)"O", item);
|
||||
PyObject *result = PyObject_CallMethod(self, (char *)"push_back", (char *)"O", item);
|
||||
Py_DECREF(item);
|
||||
if (result == NULL) {
|
||||
// Unable to add item--probably it wasn't of the appropriate type.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// Filename: typeHandle_ext.cxx
|
||||
// Created by: rdb (17Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "typeHandle_ext.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeHandle::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a TypeHandle from a Python class object.
|
||||
// Useful for automatic coercion, to allow a class
|
||||
// object to be passed wherever a TypeHandle is
|
||||
// expected.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypeHandle Extension<TypeHandle>::
|
||||
make(PyTypeObject *tp) {
|
||||
if (!PyType_IsSubtype(tp, &Dtool_DTOOL_SUPER_BASE._PyType)) {
|
||||
PyErr_SetString(PyExc_TypeError, "a Panda type is required");
|
||||
return TypeHandle::none();
|
||||
}
|
||||
|
||||
Dtool_PyTypedObject *dtool_tp = (Dtool_PyTypedObject *) tp;
|
||||
return dtool_tp->_type;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Filename: typeHandle_ext.h
|
||||
// Created by: rdb (17Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TYPEHANDLE_EXT_H
|
||||
#define TYPEHANDLE_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "typeHandle.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<TypeHandle>
|
||||
// Description : This class defines the extension methods for
|
||||
// TypeHandle, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<TypeHandle> : public ExtensionBase<TypeHandle> {
|
||||
public:
|
||||
static TypeHandle make(PyTypeObject *tp);
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // TYPEHANDLE_EXT_H
|
||||
|
|
@ -79,8 +79,6 @@ WindowFramework::
|
|||
WindowFramework(PandaFramework *panda_framework) :
|
||||
_panda_framework(panda_framework)
|
||||
{
|
||||
_alight = (AmbientLight *)NULL;
|
||||
_dlight = (DirectionalLight *)NULL;
|
||||
_got_keyboard = false;
|
||||
_got_trackball = false;
|
||||
_got_lights = false;
|
||||
|
|
@ -106,8 +104,6 @@ WindowFramework(const WindowFramework ©, DisplayRegion *display_region) :
|
|||
_window(copy._window),
|
||||
_display_region_3d(display_region)
|
||||
{
|
||||
_alight = (AmbientLight *)NULL;
|
||||
_dlight = (DirectionalLight *)NULL;
|
||||
_got_keyboard = false;
|
||||
_got_trackball = false;
|
||||
_got_lights = false;
|
||||
|
|
@ -205,8 +201,8 @@ close_window() {
|
|||
_render_2d.remove_node();
|
||||
_mouse.remove_node();
|
||||
|
||||
_alight = (AmbientLight *)NULL;
|
||||
_dlight = (DirectionalLight *)NULL;
|
||||
_alight.clear();
|
||||
_dlight.clear();
|
||||
_got_keyboard = false;
|
||||
_got_trackball = false;
|
||||
_got_lights = false;
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ class FactoryParams;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_GOBJ Material : public TypedWritableReferenceCount, public Namable {
|
||||
PUBLISHED:
|
||||
INLINE Material(const string &name = "");
|
||||
INLINE explicit Material(const string &name = "");
|
||||
INLINE Material(const Material ©);
|
||||
void operator = (const Material ©);
|
||||
INLINE ~Material();
|
||||
|
||||
INLINE static Material *get_default();
|
||||
|
||||
|
||||
INLINE bool has_ambient() const;
|
||||
INLINE const LColor &get_ambient() const;
|
||||
void set_ambient(const LColor &color);
|
||||
|
|
@ -88,7 +88,7 @@ private:
|
|||
PN_stdfloat _shininess;
|
||||
|
||||
static PT(Material) _default;
|
||||
|
||||
|
||||
enum Flags {
|
||||
F_ambient = 0x001,
|
||||
F_diffuse = 0x002,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "cycleDataStageWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "samplerState.h"
|
||||
#include "pnmImage.h"
|
||||
|
||||
class PNMImage;
|
||||
class PfmFile;
|
||||
|
|
@ -208,10 +209,12 @@ PUBLISHED:
|
|||
};
|
||||
|
||||
PUBLISHED:
|
||||
Texture(const string &name = string());
|
||||
explicit Texture(const string &name = string());
|
||||
|
||||
protected:
|
||||
Texture(const Texture ©);
|
||||
void operator = (const Texture ©);
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~Texture();
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#define LCAST(numeric_type, object) lcast_to((numeric_type *)0, object)
|
||||
|
||||
BEGIN_PUBLISH
|
||||
|
||||
// Now we define some handy typedefs for these classes.
|
||||
typedef LPoint3f LVertexf;
|
||||
|
|
@ -185,4 +186,6 @@ typedef LQuaterniond Quat;
|
|||
|
||||
#endif // STDFLOAT_DOUBLE
|
||||
|
||||
END_PUBLISH
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ compose_matrix(FLOATNAME(LMatrix4) &mat,
|
|||
CoordinateSystem cs = CS_default);
|
||||
|
||||
INLINE_LINMATH void
|
||||
compose_matrix(FLOATNAME(LMatrix4) &mat,
|
||||
compose_matrix(FLOATNAME(LMatrix4) &mat,
|
||||
const FLOATTYPE components[num_matrix_components],
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
|
|
@ -50,7 +50,8 @@ decompose_matrix(const FLOATNAME(LMatrix4) &mat,
|
|||
CoordinateSystem cs = CS_default);
|
||||
|
||||
INLINE_LINMATH bool
|
||||
decompose_matrix(const FLOATNAME(LMatrix4) &mat, FLOATTYPE components[num_matrix_components],
|
||||
decompose_matrix(const FLOATNAME(LMatrix4) &mat,
|
||||
FLOATTYPE components[num_matrix_components],
|
||||
CoordinateSystem CS = CS_default);
|
||||
|
||||
|
||||
|
|
@ -106,7 +107,8 @@ compose_matrix_old_hpr(FLOATNAME(LMatrix4) &mat,
|
|||
CoordinateSystem cs = CS_default);
|
||||
|
||||
INLINE_LINMATH void
|
||||
compose_matrix_old_hpr(FLOATNAME(LMatrix4) &mat, const FLOATTYPE components[num_matrix_components],
|
||||
compose_matrix_old_hpr(FLOATNAME(LMatrix4) &mat,
|
||||
const FLOATTYPE components[num_matrix_components],
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
EXPCL_PANDA_LINMATH bool
|
||||
|
|
@ -125,7 +127,8 @@ decompose_matrix_old_hpr(const FLOATNAME(LMatrix4) &mat,
|
|||
CoordinateSystem cs = CS_default);
|
||||
|
||||
INLINE_LINMATH bool
|
||||
decompose_matrix_old_hpr(const FLOATNAME(LMatrix4) &mat, FLOATTYPE components[num_matrix_components],
|
||||
decompose_matrix_old_hpr(const FLOATNAME(LMatrix4) &mat,
|
||||
FLOATTYPE components[num_matrix_components],
|
||||
CoordinateSystem CS = CS_default);
|
||||
|
||||
|
||||
|
|
@ -145,7 +148,8 @@ compose_matrix_new_hpr(FLOATNAME(LMatrix4) &mat,
|
|||
CoordinateSystem cs = CS_default);
|
||||
|
||||
INLINE_LINMATH void
|
||||
compose_matrix_new_hpr(FLOATNAME(LMatrix4) &mat, const FLOATTYPE components[num_matrix_components],
|
||||
compose_matrix_new_hpr(FLOATNAME(LMatrix4) &mat,
|
||||
const FLOATTYPE components[num_matrix_components],
|
||||
CoordinateSystem cs = CS_default);
|
||||
|
||||
EXPCL_PANDA_LINMATH bool
|
||||
|
|
@ -164,7 +168,8 @@ decompose_matrix_new_hpr(const FLOATNAME(LMatrix4) &mat,
|
|||
CoordinateSystem cs = CS_default);
|
||||
|
||||
INLINE_LINMATH bool
|
||||
decompose_matrix_new_hpr(const FLOATNAME(LMatrix4) &mat, FLOATTYPE components[num_matrix_components],
|
||||
decompose_matrix_new_hpr(const FLOATNAME(LMatrix4) &mat,
|
||||
FLOATTYPE components[num_matrix_components],
|
||||
CoordinateSystem CS = CS_default);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,17 +13,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix3::Row::__setitem__
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH void Extension<FLOATNAME(LMatrix3)::Row>::
|
||||
__setitem__(int i, FLOATTYPE v) {
|
||||
nassertv(i >= 0 && i < 3);
|
||||
_this->_row[i] = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix3::__reduce__
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -13,18 +13,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<LMatrix3::Row>
|
||||
// Description : This class defines the extension methods for
|
||||
// LMatrix3::Row, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<FLOATNAME(LMatrix3)::Row> : public ExtensionBase<FLOATNAME(LMatrix3)::Row> {
|
||||
public:
|
||||
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<LMatrix3>
|
||||
// Description : This class defines the extension methods for
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ begin() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)::iterator FLOATNAME(LMatrix3)::
|
||||
end() {
|
||||
return begin() + get_num_components();
|
||||
return begin() + num_components;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -470,7 +470,7 @@ begin() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(LMatrix3)::const_iterator FLOATNAME(LMatrix3)::
|
||||
end() const {
|
||||
return begin() + get_num_components();
|
||||
return begin() + num_components;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -24,10 +24,16 @@ class FLOATNAME(LMatrix4);
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_LINMATH FLOATNAME(LMatrix3) {
|
||||
public:
|
||||
typedef FLOATTYPE numeric_type;
|
||||
typedef const FLOATTYPE *iterator;
|
||||
typedef const FLOATTYPE *const_iterator;
|
||||
|
||||
PUBLISHED:
|
||||
enum {
|
||||
num_components = 9,
|
||||
is_int = 0
|
||||
};
|
||||
|
||||
// These helper classes are used to support two-level operator [].
|
||||
class Row {
|
||||
private:
|
||||
|
|
@ -35,7 +41,6 @@ PUBLISHED:
|
|||
PUBLISHED:
|
||||
INLINE_LINMATH FLOATTYPE operator [](int i) const;
|
||||
INLINE_LINMATH FLOATTYPE &operator [](int i);
|
||||
EXTENSION(INLINE_LINMATH void __setitem__(int i, FLOATTYPE v));
|
||||
INLINE_LINMATH static int size();
|
||||
public:
|
||||
FLOATTYPE *_row;
|
||||
|
|
|
|||
|
|
@ -13,17 +13,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix4::Row::__setitem__
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH void Extension<FLOATNAME(LMatrix4)::Row>::
|
||||
__setitem__(int i, FLOATTYPE v) {
|
||||
nassertv(i >= 0 && i < 4);
|
||||
_this->_row[i] = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LMatrix4::__reduce__
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -13,18 +13,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<LMatrix4::Row>
|
||||
// Description : This class defines the extension methods for
|
||||
// LMatrix4::Row, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<FLOATNAME(LMatrix4)::Row> : public ExtensionBase<FLOATNAME(LMatrix4)::Row> {
|
||||
public:
|
||||
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<LMatrix4>
|
||||
// Description : This class defines the extension methods for
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
|
|||
operator = (const FLOATNAME(UnalignedLMatrix4) ©) {
|
||||
TAU_PROFILE("void LMatrix4::operator = (const UnalignedLMatrix4 &)", " ", TAU_USER);
|
||||
|
||||
memcpy(&_m(0, 0), copy.get_data(), sizeof(FLOATTYPE) * get_num_components());
|
||||
memcpy(&_m(0, 0), copy.get_data(), sizeof(FLOATTYPE) * num_components);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1836,7 +1836,7 @@ FLOATNAME(UnalignedLMatrix4)(const FLOATNAME(UnalignedLMatrix4) ©) : _m(copy
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLMatrix4) &FLOATNAME(UnalignedLMatrix4)::
|
||||
operator = (const FLOATNAME(LMatrix4) ©) {
|
||||
memcpy(&_m(0, 0), copy.get_data(), sizeof(FLOATTYPE) * get_num_components());
|
||||
memcpy(&_m(0, 0), copy.get_data(), sizeof(FLOATTYPE) * num_components);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,16 @@ class FLOATNAME(UnalignedLMatrix4);
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_LINMATH ALIGN_LINMATH FLOATNAME(LMatrix4) {
|
||||
public:
|
||||
typedef FLOATTYPE numeric_type;
|
||||
typedef const FLOATTYPE *iterator;
|
||||
typedef const FLOATTYPE *const_iterator;
|
||||
|
||||
PUBLISHED:
|
||||
enum {
|
||||
num_components = 16,
|
||||
is_int = 0
|
||||
};
|
||||
|
||||
// These helper classes are used to support two-level operator [].
|
||||
class Row {
|
||||
private:
|
||||
|
|
@ -31,7 +37,6 @@ PUBLISHED:
|
|||
PUBLISHED:
|
||||
INLINE_LINMATH FLOATTYPE operator [](int i) const;
|
||||
INLINE_LINMATH FLOATTYPE &operator [](int i);
|
||||
EXTENSION(INLINE_LINMATH void __setitem__(int i, FLOATTYPE v));
|
||||
INLINE_LINMATH static int size();
|
||||
public:
|
||||
FLOATTYPE *_row;
|
||||
|
|
@ -319,6 +324,10 @@ private:
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_LINMATH FLOATNAME(UnalignedLMatrix4) {
|
||||
PUBLISHED:
|
||||
enum {
|
||||
num_components = 16
|
||||
};
|
||||
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLMatrix4)();
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLMatrix4)(const FLOATNAME(LMatrix4) ©);
|
||||
INLINE_LINMATH FLOATNAME(UnalignedLMatrix4)(const FLOATNAME(UnalignedLMatrix4) ©);
|
||||
|
|
|
|||
|
|
@ -35,17 +35,6 @@ IMPORT_THIS struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4);
|
|||
#define PY_AS_FLOATTYPE PyFloat_AsDouble
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVecBase2::__setitem__
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_LINMATH void Extension<FLOATNAME(LVecBase2)>::
|
||||
__setitem__(int i, FLOATTYPE v) {
|
||||
nassertv(i >= 0 && i < 2);
|
||||
_this->_v(i) = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LVecBase2::python_repr
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ public:
|
|||
INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
|
||||
INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
|
||||
INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
|
||||
INLINE_LINMATH void __setitem__(int i, FLOATTYPE v);
|
||||
INLINE_LINMATH void python_repr(ostream &out, const string &class_name) const;
|
||||
|
||||
INLINE_LINMATH FLOATNAME(LVecBase2) __pow__(FLOATTYPE exponent) const;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue