Add support for parsing C++11 final classes
Such as:
class X final {};
This no longer gives a syntax error.
This change has introduced one more shift-reduce conflict in the parser.
with a conflict with a C style variable declaration with name final:
class X final;
resulting in a syntax error (for C++ not C). This is an an unusual style
for C++ code and more typical declarations do work:
X final;
Closes #672
This commit is contained in:
parent
76f5670fa4
commit
ba279ae939
9 changed files with 267 additions and 24 deletions
|
|
@ -592,6 +592,7 @@ CPP11_TEST_CASES += \
|
|||
cpp11_director_enums \
|
||||
cpp11_directors \
|
||||
cpp11_explicit_conversion_operators \
|
||||
cpp11_final_class \
|
||||
cpp11_final_directors \
|
||||
cpp11_final_override \
|
||||
cpp11_function_objects \
|
||||
|
|
@ -755,6 +756,7 @@ C_TEST_CASES += \
|
|||
enum_macro \
|
||||
enum_missing \
|
||||
extern_declaration \
|
||||
final_c \
|
||||
funcptr \
|
||||
function_typedef \
|
||||
global_functions \
|
||||
|
|
|
|||
129
Examples/test-suite/cpp11_final_class.i
Normal file
129
Examples/test-suite/cpp11_final_class.i
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
%module cpp11_final_class
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
|
||||
%warnfilter(SWIGWARN_PARSE_KEYWORD) override; // 'override' is a C# keyword, renaming to '_override'
|
||||
|
||||
%ignore Space1::final::operator=;
|
||||
#if defined(SWIGPHP)
|
||||
%rename(Space1_final) Space1::final::final;
|
||||
#endif
|
||||
#if defined(SWIGOCAML)
|
||||
%rename(finale) Space2::FinalEnum1::final;
|
||||
#endif
|
||||
|
||||
%inline %{
|
||||
struct FinalBase {
|
||||
virtual ~FinalBase() {}
|
||||
};
|
||||
|
||||
struct FinalClass1 final : FinalBase {
|
||||
void method1() {}
|
||||
};
|
||||
|
||||
class FinalClass2 final : public FinalBase {
|
||||
public:
|
||||
void method2() {}
|
||||
};
|
||||
|
||||
struct FinalClass3 final {
|
||||
void method3() {}
|
||||
};
|
||||
|
||||
struct FinalClass4 {
|
||||
void method4() {}
|
||||
} final;
|
||||
|
||||
struct override final {
|
||||
void omethod() {}
|
||||
};
|
||||
%}
|
||||
|
||||
%rename(Space1_final) Space1::final;
|
||||
|
||||
%inline %{
|
||||
namespace Space1 {
|
||||
struct final final {
|
||||
void finalmethod() {}
|
||||
final() {}
|
||||
final(const final &other) = default;
|
||||
final& operator=(const final &other) = default;
|
||||
};
|
||||
struct FinalClass5 final {
|
||||
void method5() {}
|
||||
final final_member_var;
|
||||
final get_final_member() { return final_member_var; }
|
||||
Space1::final get_final_member2() { return final_member_var; }
|
||||
};
|
||||
struct FinalClass6 {
|
||||
void method6() {}
|
||||
virtual void final() final {}
|
||||
virtual ~FinalClass6() = default;
|
||||
};
|
||||
typedef final Space1_final_typedef1;
|
||||
typedef struct final Space1_final_typedef2;
|
||||
}
|
||||
typedef Space1::final Space1_final_typedef3;
|
||||
typedef struct Space1::final Space1_final_typedef4;
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
namespace Space2 {
|
||||
class Y {
|
||||
public:
|
||||
Y(int i=0) {}
|
||||
};
|
||||
|
||||
struct FinalVar1 {
|
||||
class Y notfinal;
|
||||
// class Y final; // SWIG (C++ only) fails to parse (same for struct and union)
|
||||
};
|
||||
struct FinalVar2 {
|
||||
class Y notfinal = {};
|
||||
// class Y final = {}; // SWIG (C++ only) fails to parse (same for struct and union)
|
||||
};
|
||||
struct FinalVar3 {
|
||||
class Y notfinal = Y();
|
||||
// class Y final = Y(); // SWIG (C++ only) fails to parse (same for struct and union)
|
||||
};
|
||||
struct FinalVar4 {
|
||||
class Y* final;
|
||||
FinalVar4() : final() {}
|
||||
};
|
||||
struct FinalVar5 {
|
||||
Y final;
|
||||
};
|
||||
struct FinalVar6 {
|
||||
Y final = {};
|
||||
};
|
||||
struct FinalVar7 {
|
||||
Y final = Y();
|
||||
};
|
||||
struct FinalVar8 {
|
||||
Y final{};
|
||||
};
|
||||
struct FinalVar9 {
|
||||
Y final{9};
|
||||
};
|
||||
struct FinalVar10 {
|
||||
void a10(class Y final) {}
|
||||
void b10(Y final) {}
|
||||
};
|
||||
struct FinalEnum1 {
|
||||
enum Enum1 { one, two, final };
|
||||
void enum_in(Enum1 e) {}
|
||||
};
|
||||
struct FinalEnum2 {
|
||||
enum Enum2 { one, two, three, four };
|
||||
enum Enum2 final;
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
%rename(Space3_final) Space3::final;
|
||||
%inline %{
|
||||
namespace Space3 {
|
||||
typedef struct final {
|
||||
void fmethod() {}
|
||||
} final;
|
||||
}
|
||||
%}
|
||||
|
|
@ -27,7 +27,7 @@ struct Base {
|
|||
virtual ~Base() {}
|
||||
};
|
||||
|
||||
struct Derived /*final*/ : Base {
|
||||
struct Derived final : Base {
|
||||
virtual void stuff() const noexcept override final {}
|
||||
virtual void override1() const noexcept override;
|
||||
virtual void override2() const noexcept override;
|
||||
|
|
|
|||
11
Examples/test-suite/final_c.i
Normal file
11
Examples/test-suite/final_c.i
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
%module final_c
|
||||
|
||||
%inline %{
|
||||
struct Y {
|
||||
int yval;
|
||||
};
|
||||
struct Y final;
|
||||
void init() {
|
||||
final.yval = 123;
|
||||
}
|
||||
%}
|
||||
62
Examples/test-suite/python/cpp11_final_class_runme.py
Normal file
62
Examples/test-suite/python/cpp11_final_class_runme.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
from cpp11_final_class import *
|
||||
|
||||
fc1 = FinalClass1()
|
||||
fc1.method1()
|
||||
|
||||
fc2 = FinalClass2()
|
||||
fc2.method2()
|
||||
|
||||
fc3 = FinalClass3()
|
||||
fc3.method3()
|
||||
|
||||
fc4 = FinalClass4()
|
||||
fc4.method4()
|
||||
fc4final = cvar.final
|
||||
cvar.final.method4()
|
||||
|
||||
fc5 = FinalClass5()
|
||||
fc5.method5()
|
||||
fc5.final_member_var.finalmethod()
|
||||
fc5final = fc5.get_final_member()
|
||||
fc5final.finalmethod()
|
||||
fc5final = fc5.get_final_member2()
|
||||
fc5final.finalmethod()
|
||||
|
||||
fc6 = FinalClass6()
|
||||
fc6.method6()
|
||||
fc6.final()
|
||||
|
||||
o = override()
|
||||
o.omethod();
|
||||
|
||||
y = Y()
|
||||
fv4 = FinalVar4()
|
||||
yy = fv4.final
|
||||
|
||||
fv5 = FinalVar5()
|
||||
yy = fv5.final
|
||||
|
||||
fv6 = FinalVar6()
|
||||
yy = fv6.final
|
||||
|
||||
fv7 = FinalVar7()
|
||||
yy = fv7.final
|
||||
|
||||
fv8 = FinalVar8()
|
||||
yy = fv8.final
|
||||
|
||||
fv9 = FinalVar9()
|
||||
yy = fv9.final
|
||||
|
||||
fv10 = FinalVar10()
|
||||
fv10.a10(y)
|
||||
fv10.b10(y)
|
||||
|
||||
fe1 = FinalEnum1()
|
||||
fe1.enum_in(FinalEnum1.final)
|
||||
|
||||
fe2 = FinalEnum2()
|
||||
fe2f = fe2.final
|
||||
|
||||
s3f = Space3_final()
|
||||
s3f.fmethod();
|
||||
6
Examples/test-suite/python/final_c_runme.py
Normal file
6
Examples/test-suite/python/final_c_runme.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import final_c
|
||||
|
||||
final_c.init()
|
||||
f = final_c.cvar.final
|
||||
if (f.yval != 123):
|
||||
raise RuntimeError("f.yval fail")
|
||||
Loading…
Add table
Add a link
Reference in a new issue