Fixes for C enums used in an API and the definition of the enum has not been parsed.
For D, this fixes a segfault in SWIG. Java, C#, D, Go now produce code that compiles, although the definition of the enum is needed in order to use the enum properly from the target language.
This commit is contained in:
parent
15f4b3b19d
commit
cd2085aae7
7 changed files with 149 additions and 49 deletions
|
|
@ -5,5 +5,8 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 3.0.1 (in progress)
|
Version 3.0.1 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2014-03-28: wsfulton
|
||||||
|
[Java C# D Go] Fix for usage of snprintf in Lua runtime which Visual Studio does not have.
|
||||||
|
|
||||||
2014-03-23: v-for-vandal
|
2014-03-23: v-for-vandal
|
||||||
[Lua] Fix for usage of snprintf in Lua runtime which Visual Studio does not have.
|
[Lua] Fix for usage of snprintf in Lua runtime which Visual Studio does not have.
|
||||||
|
|
|
||||||
|
|
@ -580,6 +580,7 @@ C_TEST_CASES += \
|
||||||
enums \
|
enums \
|
||||||
enum_forward \
|
enum_forward \
|
||||||
enum_macro \
|
enum_macro \
|
||||||
|
enum_missing \
|
||||||
extern_declaration \
|
extern_declaration \
|
||||||
funcptr \
|
funcptr \
|
||||||
function_typedef \
|
function_typedef \
|
||||||
|
|
|
||||||
39
Examples/test-suite/enum_missing.i
Normal file
39
Examples/test-suite/enum_missing.i
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
%module enum_missing
|
||||||
|
|
||||||
|
// Test when SWIG does not parse the enum definition
|
||||||
|
%{
|
||||||
|
enum AVPixelFormat {
|
||||||
|
AV_PIX_FMT_NONE = -1,
|
||||||
|
AV_PIX_FMT_YUV420P
|
||||||
|
};
|
||||||
|
enum AVPixelFormat2 {
|
||||||
|
AV_PIX_FMT_NONE2 = -1,
|
||||||
|
AV_PIX_FMT_YUV420P2
|
||||||
|
};
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
typedef struct AVCodecContext {
|
||||||
|
enum AVPixelFormat pix_fmt;
|
||||||
|
enum AVPixelFormat2 pix_fmt2;
|
||||||
|
} AVCodecContext;
|
||||||
|
|
||||||
|
enum AVPixelFormat global_fmt;
|
||||||
|
enum AVPixelFormat2 global_fmt2;
|
||||||
|
|
||||||
|
enum AVPixelFormat use_pixel_format(enum AVPixelFormat px) {
|
||||||
|
return px;
|
||||||
|
}
|
||||||
|
enum AVPixelFormat * use_pixel_format_ptr(enum AVPixelFormat *px) {
|
||||||
|
return px;
|
||||||
|
}
|
||||||
|
|
||||||
|
const enum AVPixelFormat2 use_pixel_format2(const enum AVPixelFormat2 px) {
|
||||||
|
return px;
|
||||||
|
}
|
||||||
|
const enum AVPixelFormat2 * use_pixel_format_ptr2(const enum AVPixelFormat2 *px) {
|
||||||
|
return px;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
@ -3165,25 +3165,37 @@ public:
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable) {
|
void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable) {
|
||||||
|
String *replacementname;
|
||||||
if (SwigType_isenum(classnametype)) {
|
if (SwigType_isenum(classnametype)) {
|
||||||
String *enumname = getEnumName(classnametype);
|
String *enumname = getEnumName(classnametype);
|
||||||
if (enumname)
|
if (enumname) {
|
||||||
Replaceall(tm, classnamespecialvariable, enumname);
|
replacementname = Copy(enumname);
|
||||||
else
|
|
||||||
Replaceall(tm, classnamespecialvariable, NewStringf("int"));
|
|
||||||
} else {
|
} else {
|
||||||
String *classname = getProxyName(classnametype);
|
bool anonymous_enum = (Cmp(classnametype, "enum ") == 0);
|
||||||
|
if (anonymous_enum) {
|
||||||
|
replacementname = NewString("int");
|
||||||
|
} else {
|
||||||
|
// An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition)
|
||||||
|
replacementname = SwigType_base(classnametype);
|
||||||
|
Replace(replacementname, "enum ", "", DOH_REPLACE_ANY);
|
||||||
|
Setattr(swig_types_hash, replacementname, classnametype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String *classname = getProxyName(classnametype); // getProxyName() works for pointers to classes too
|
||||||
if (classname) {
|
if (classname) {
|
||||||
Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too
|
replacementname = Copy(classname);
|
||||||
} else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
|
} else {
|
||||||
String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
|
// use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
|
||||||
Replaceall(tm, classnamespecialvariable, descriptor);
|
replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
|
||||||
|
|
||||||
// Add to hash table so that the type wrapper classes can be created later
|
// Add to hash table so that the type wrapper classes can be created later
|
||||||
Setattr(swig_types_hash, descriptor, classnametype);
|
Setattr(swig_types_hash, replacementname, classnametype);
|
||||||
Delete(descriptor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Replaceall(tm, classnamespecialvariable, replacementname);
|
||||||
|
|
||||||
|
Delete(replacementname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
@ -3273,6 +3285,9 @@ public:
|
||||||
Replaceall(swigtype, "$imclassname", imclass_name);
|
Replaceall(swigtype, "$imclassname", imclass_name);
|
||||||
Replaceall(swigtype, "$dllimport", dllimport);
|
Replaceall(swigtype, "$dllimport", dllimport);
|
||||||
|
|
||||||
|
// For unknown enums
|
||||||
|
Replaceall(swigtype, "$enumvalues", "");
|
||||||
|
|
||||||
Printv(f_swigtype, swigtype, NIL);
|
Printv(f_swigtype, swigtype, NIL);
|
||||||
|
|
||||||
addCloseNamespace(0, f_swigtype);
|
addCloseNamespace(0, f_swigtype);
|
||||||
|
|
|
||||||
|
|
@ -568,8 +568,7 @@ public:
|
||||||
writeTypeWrapperClass(swig_type.key, swig_type.item);
|
writeTypeWrapperClass(swig_type.key, swig_type.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the proxy functions (and classes, if they are not written to a
|
// Add the proxy functions (and classes, if they are not written to a separate file).
|
||||||
// seperate file).
|
|
||||||
replaceModuleVariables(proxy_dmodule_code);
|
replaceModuleVariables(proxy_dmodule_code);
|
||||||
Printv(proxy_d_file, proxy_dmodule_code, NIL);
|
Printv(proxy_d_file, proxy_dmodule_code, NIL);
|
||||||
|
|
||||||
|
|
@ -1399,7 +1398,7 @@ public:
|
||||||
// generates a getter function (which is the same as a read only property
|
// generates a getter function (which is the same as a read only property
|
||||||
// in D) which retrieves the value via by calling the C wrapper.
|
// in D) which retrieves the value via by calling the C wrapper.
|
||||||
// Note that this is only called for global constants, static member
|
// Note that this is only called for global constants, static member
|
||||||
// constants are already handeled in staticmemberfunctionHandler().
|
// constants are already handled in staticmemberfunctionHandler().
|
||||||
|
|
||||||
Swig_save("constantWrapper", n, "value", NIL);
|
Swig_save("constantWrapper", n, "value", NIL);
|
||||||
Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", NIL);
|
Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", NIL);
|
||||||
|
|
@ -3602,7 +3601,7 @@ private:
|
||||||
* package if one is set.
|
* package if one is set.
|
||||||
*
|
*
|
||||||
* This is only used for dependencies created in generated code, user-
|
* This is only used for dependencies created in generated code, user-
|
||||||
* (i.e. typemap-) specified import statements are handeled seperately.
|
* (i.e. typemap-) specified import statements are handled separately.
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
void requireDType(const String *nspace, const String *symname) {
|
void requireDType(const String *nspace, const String *symname) {
|
||||||
String *dmodule = createModuleName(nspace, symname);
|
String *dmodule = createModuleName(nspace, symname);
|
||||||
|
|
@ -4054,10 +4053,10 @@ private:
|
||||||
// TODO: Fix const-correctness of methods called in here and make type const.
|
// TODO: Fix const-correctness of methods called in here and make type const.
|
||||||
|
|
||||||
// We make use of the fact that this function is called at least once for
|
// We make use of the fact that this function is called at least once for
|
||||||
// every type encountered which is written to a seperate file, which allows
|
// every type encountered which is written to a separate file, which allows
|
||||||
// us to handle imports here.
|
// us to handle imports here.
|
||||||
// When working in split proxy module mode, each generated proxy class/enum
|
// When working in split proxy module mode, each generated proxy class/enum
|
||||||
// is written to a seperate module. This requires us to add a corresponding
|
// is written to a separate module. This requires us to add a corresponding
|
||||||
// import when a type is used in another generated module. If we are not
|
// import when a type is used in another generated module. If we are not
|
||||||
// working in split proxy module mode, this is not relevant and the
|
// working in split proxy module mode, this is not relevant and the
|
||||||
// generated module name is discarded.
|
// generated module name is discarded.
|
||||||
|
|
@ -4066,6 +4065,7 @@ private:
|
||||||
if (SwigType_isenum(type)) {
|
if (SwigType_isenum(type)) {
|
||||||
// RESEARCH: Make sure that we really cannot get here for anonymous enums.
|
// RESEARCH: Make sure that we really cannot get here for anonymous enums.
|
||||||
Node *n = enumLookup(type);
|
Node *n = enumLookup(type);
|
||||||
|
if (n) {
|
||||||
String *enum_name = Getattr(n, "sym:name");
|
String *enum_name = Getattr(n, "sym:name");
|
||||||
|
|
||||||
Node *p = parentNode(n);
|
Node *p = parentNode(n);
|
||||||
|
|
@ -4074,7 +4074,7 @@ private:
|
||||||
String *parent_name = Getattr(p, "sym:name");
|
String *parent_name = Getattr(p, "sym:name");
|
||||||
String *nspace = Getattr(p, "sym:nspace");
|
String *nspace = Getattr(p, "sym:nspace");
|
||||||
|
|
||||||
// An enum nested in a class is not written to a seperate module (this
|
// An enum nested in a class is not written to a separate module (this
|
||||||
// would not even be possible in D), so just import the parent.
|
// would not even be possible in D), so just import the parent.
|
||||||
requireDType(nspace, parent_name);
|
requireDType(nspace, parent_name);
|
||||||
|
|
||||||
|
|
@ -4085,7 +4085,7 @@ private:
|
||||||
type_name = NewStringf("%s%s.%s.%s", package, module, parent_name, enum_name);
|
type_name = NewStringf("%s%s.%s.%s", package, module, parent_name, enum_name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// A non-nested enum is written to a seperate module, import it.
|
// A non-nested enum is written to a separate module, import it.
|
||||||
String *nspace = Getattr(n, "sym:nspace");
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
requireDType(nspace, enum_name);
|
requireDType(nspace, enum_name);
|
||||||
|
|
||||||
|
|
@ -4096,6 +4096,9 @@ private:
|
||||||
type_name = NewStringf("%s%s.%s", package, module, enum_name);
|
type_name = NewStringf("%s%s.%s", package, module, enum_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
type_name = NewStringf("int");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Node *n = classLookup(type);
|
Node *n = classLookup(type);
|
||||||
if (n) {
|
if (n) {
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,9 @@ class GO:public Language {
|
||||||
bool making_variable_wrappers;
|
bool making_variable_wrappers;
|
||||||
// True when working with a static member function.
|
// True when working with a static member function.
|
||||||
bool is_static_member_function;
|
bool is_static_member_function;
|
||||||
|
// A hash table of enum types that we have seen but which may not have
|
||||||
|
// been defined. The index is a SwigType.
|
||||||
|
Hash *undefined_enum_types;
|
||||||
// A hash table of types that we have seen but which may not have
|
// A hash table of types that we have seen but which may not have
|
||||||
// been defined. The index is a SwigType.
|
// been defined. The index is a SwigType.
|
||||||
Hash *undefined_types;
|
Hash *undefined_types;
|
||||||
|
|
@ -124,6 +127,7 @@ public:
|
||||||
class_methods(NULL),
|
class_methods(NULL),
|
||||||
making_variable_wrappers(false),
|
making_variable_wrappers(false),
|
||||||
is_static_member_function(false),
|
is_static_member_function(false),
|
||||||
|
undefined_enum_types(NULL),
|
||||||
undefined_types(NULL),
|
undefined_types(NULL),
|
||||||
defined_types(NULL),
|
defined_types(NULL),
|
||||||
go_imports(NULL) {
|
go_imports(NULL) {
|
||||||
|
|
@ -451,6 +455,7 @@ private:
|
||||||
|
|
||||||
// Set up the hash table for types not defined by SWIG.
|
// Set up the hash table for types not defined by SWIG.
|
||||||
|
|
||||||
|
undefined_enum_types = NewHash();
|
||||||
undefined_types = NewHash();
|
undefined_types = NewHash();
|
||||||
defined_types = NewHash();
|
defined_types = NewHash();
|
||||||
go_imports = NewHash();
|
go_imports = NewHash();
|
||||||
|
|
@ -463,6 +468,13 @@ private:
|
||||||
|
|
||||||
// Write out definitions for the types not defined by SWIG.
|
// Write out definitions for the types not defined by SWIG.
|
||||||
|
|
||||||
|
if (Len(undefined_enum_types) > 0)
|
||||||
|
Printv(f_go_wrappers, "\n", NULL);
|
||||||
|
for (Iterator p = First(undefined_enum_types); p.key; p = Next(p)) {
|
||||||
|
String *name = p.item;
|
||||||
|
Printv(f_go_wrappers, "type ", name, " int\n", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
Printv(f_go_wrappers, "\n", NULL);
|
Printv(f_go_wrappers, "\n", NULL);
|
||||||
for (Iterator p = First(undefined_types); p.key; p = Next(p)) {
|
for (Iterator p = First(undefined_types); p.key; p = Next(p)) {
|
||||||
String *ty = goType(NULL, p.key);
|
String *ty = goType(NULL, p.key);
|
||||||
|
|
@ -481,6 +493,7 @@ private:
|
||||||
}
|
}
|
||||||
Delete(ty);
|
Delete(ty);
|
||||||
}
|
}
|
||||||
|
Delete(undefined_enum_types);
|
||||||
Delete(undefined_types);
|
Delete(undefined_types);
|
||||||
Delete(defined_types);
|
Delete(defined_types);
|
||||||
|
|
||||||
|
|
@ -4494,11 +4507,18 @@ private:
|
||||||
|
|
||||||
SwigType *t = SwigType_typedef_resolve_all(type);
|
SwigType *t = SwigType_typedef_resolve_all(type);
|
||||||
|
|
||||||
|
if (SwigType_isenum(t)) {
|
||||||
Node *e = Language::enumLookup(t);
|
Node *e = Language::enumLookup(t);
|
||||||
if (e) {
|
if (e) {
|
||||||
ret = goEnumName(e);
|
ret = goEnumName(e);
|
||||||
} else if (Strcmp(t, "enum ") == 0) {
|
} else if (Strcmp(t, "enum ") == 0) {
|
||||||
ret = NewString("int");
|
ret = NewString("int");
|
||||||
|
} else {
|
||||||
|
// An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition)
|
||||||
|
ret = SwigType_base(t);
|
||||||
|
Replace(ret, "enum ", "", DOH_REPLACE_ANY);
|
||||||
|
Setattr(undefined_enum_types, t, ret);
|
||||||
|
}
|
||||||
} else if (SwigType_isfunctionpointer(type) || SwigType_isfunction(type)) {
|
} else if (SwigType_isfunctionpointer(type) || SwigType_isfunction(type)) {
|
||||||
ret = NewString("_swig_fnptr");
|
ret = NewString("_swig_fnptr");
|
||||||
} else if (SwigType_ismemberpointer(type)) {
|
} else if (SwigType_ismemberpointer(type)) {
|
||||||
|
|
@ -4809,8 +4829,13 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Language::enumLookup(t) != NULL || Strcmp(t, "enum ") == 0) {
|
if (Language::enumLookup(t) != NULL) {
|
||||||
is_int = true;
|
is_int = true;
|
||||||
|
} else {
|
||||||
|
SwigType *tstripped = SwigType_strip_qualifiers(t);
|
||||||
|
if (SwigType_isenum(tstripped))
|
||||||
|
is_int = true;
|
||||||
|
Delete(tstripped);
|
||||||
}
|
}
|
||||||
|
|
||||||
Delete(t);
|
Delete(t);
|
||||||
|
|
|
||||||
|
|
@ -3083,10 +3083,19 @@ public:
|
||||||
|
|
||||||
if (SwigType_isenum(classnametype)) {
|
if (SwigType_isenum(classnametype)) {
|
||||||
String *enumname = getEnumName(classnametype, jnidescriptor);
|
String *enumname = getEnumName(classnametype, jnidescriptor);
|
||||||
if (enumname)
|
if (enumname) {
|
||||||
replacementname = Copy(enumname);
|
replacementname = Copy(enumname);
|
||||||
else
|
} else {
|
||||||
|
bool anonymous_enum = (Cmp(classnametype, "enum ") == 0);
|
||||||
|
if (anonymous_enum) {
|
||||||
replacementname = NewString("int");
|
replacementname = NewString("int");
|
||||||
|
} else {
|
||||||
|
// An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition)
|
||||||
|
replacementname = SwigType_base(classnametype);
|
||||||
|
Replace(replacementname, "enum ", "", DOH_REPLACE_ANY);
|
||||||
|
Setattr(swig_types_hash, replacementname, classnametype);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
String *classname = getProxyName(classnametype, jnidescriptor); // getProxyName() works for pointers to classes too
|
String *classname = getProxyName(classnametype, jnidescriptor); // getProxyName() works for pointers to classes too
|
||||||
if (classname) {
|
if (classname) {
|
||||||
|
|
@ -3186,6 +3195,11 @@ public:
|
||||||
Replaceall(swigtype, "$javaclassname", classname);
|
Replaceall(swigtype, "$javaclassname", classname);
|
||||||
Replaceall(swigtype, "$module", module_class_name);
|
Replaceall(swigtype, "$module", module_class_name);
|
||||||
Replaceall(swigtype, "$imclassname", imclass_name);
|
Replaceall(swigtype, "$imclassname", imclass_name);
|
||||||
|
|
||||||
|
// For unknown enums
|
||||||
|
Replaceall(swigtype, "$static ", "");
|
||||||
|
Replaceall(swigtype, "$enumvalues", "");
|
||||||
|
|
||||||
Printv(f_swigtype, swigtype, NIL);
|
Printv(f_swigtype, swigtype, NIL);
|
||||||
|
|
||||||
Delete(f_swigtype);
|
Delete(f_swigtype);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue