Skip to content

Commit

Permalink
Add C++11 virtual specifier sequences (final and/or override on methods)
Browse files Browse the repository at this point in the history
Parsing support added. The final and override information is not used or
added to the parse tree atm.
  • Loading branch information
wsfulton committed Jan 3, 2014
1 parent fc3098e commit 6a72e16
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 35 deletions.
23 changes: 23 additions & 0 deletions Doc/Manual/CPlusPlus11.html
Expand Up @@ -414,6 +414,29 @@ <H3><a name="CPlusPlus11_object_construction_improvement"></a>7.2.10 Object cons
};
</pre></div>

<H3><a name="CPlusPlus11_explicit_overrides_final"></a>Explicit overrides and final</H3>

<p>
The special identifiers <tt>final</tt> and <tt>override</tt> can be used on methods and destructors,
such as in the following example:
</p>

<div class="code"><pre>
struct BaseStruct {
virtual void ab() const = 0;
virtual void cd();
virtual void ef();
virtual ~BaseStruct();
};
struct DerivedStruct : BaseStruct {
virtual void ab() const override;
virtual void cd() final;
virtual void ef() final override;
virtual ~DerivedStruct() override;
};
</pre></div>


<H3><a name="CPlusPlus11_null_pointer_constant"></a>7.2.11 Null pointer constant</H3>


Expand Down
1 change: 1 addition & 0 deletions Examples/test-suite/common.mk
Expand Up @@ -490,6 +490,7 @@ CPP11_TEST_CASES = \
cpp11_default_delete \
cpp11_delegating_constructors \
cpp11_explicit_conversion_operators \
cpp11_final_override \
cpp11_function_objects \
cpp11_inheriting_constructors \
cpp11_initializer_list \
Expand Down
128 changes: 128 additions & 0 deletions Examples/test-suite/cpp11_final_override.i
@@ -0,0 +1,128 @@
// Test C++11 virtual specifier sequences (final and/or override on methods)
// Also check final/override - the two 'identifiers with special meaning' work as normal identifiers

%module cpp11_final_override

%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'

%inline %{

struct Base {
virtual void stuff() const {}
virtual void override1() const {}
virtual void override2() const {}
virtual void finaloverride1() {}
virtual void finaloverride2() {}
virtual void finaloverride3() {}
virtual void finaloverride4() const {}
virtual ~Base() {}
};

struct Derived /*final*/ : Base {
virtual void stuff() const noexcept override final {}
virtual void override1() const noexcept override;
virtual void override2() const noexcept override;
virtual void final1() final {}
virtual void final2() noexcept final {}
virtual void final4() const final {}
virtual void final5() const noexcept final {}
virtual void finaloverride1() final override {}
virtual void finaloverride2() override final {}
virtual void finaloverride3() noexcept override final {}
virtual void finaloverride4() const noexcept override final {}
virtual ~Derived() override final {}
};
void Derived::override2() const noexcept {}

// Pure virtual methods
struct PureBase {
virtual void pure1(int) const = 0;
virtual void pure2(int) const = 0;
virtual void pure3(int) const = 0;
virtual void pure4(int) const = 0;
virtual void pure5(int) const = 0;
virtual ~PureBase() {}
};

struct PureDerived : PureBase {
virtual void pure1(int) const override = 0;
virtual void pure2(int) const final = 0;
virtual void pure3(int) const override final = 0;
virtual void pure4(int) const final override = 0;
virtual void pure5(int) const noexcept final override = 0;
virtual ~PureDerived() override final;
};
void PureDerived::pure1(int) const {}
void PureDerived::pure2(int) const {}
void PureDerived::pure3(int) const {}
void PureDerived::pure4(int) const {}
void PureDerived::pure5(int) const noexcept {}
PureDerived::~PureDerived() {}

// Destructors and virtual specifier sequences (final/override)
struct Destructors1 : Base {
virtual ~Destructors1() override {}
};
struct Destructors2 : Base {
virtual ~Destructors2() final {}
};
struct Destructors3 : Base {
virtual ~Destructors3() noexcept final override {}
};
struct Destructors4 : Base {
virtual ~Destructors4() noexcept override final {}
};

// Check the two 'identifiers with special meaning' work as normal identifiers
struct FinalOverrideMethods {
virtual void final() {}
virtual void override(int) {}
};
struct FinalOverrideVariables {
int final;
double override;
};
void final(int) {}
void override() {}
%}

%{
void Derived::override1() const noexcept {}
%}

// Example in documentation ... declarations only
%inline %{
struct BaseStruct {
virtual void ab() const = 0;
virtual void cd();
virtual void ef();
virtual ~BaseStruct();
};
struct DerivedStruct : BaseStruct {
virtual void ab() const override;
virtual void cd() final;
virtual void ef() final override;
virtual ~DerivedStruct() override;
};
struct DerivedNoVirtualStruct : BaseStruct {
void ab() const override;
void cd() final;
void ef() final override;
~DerivedNoVirtualStruct() override;
};
%}

%{
void BaseStruct::cd() {}
void BaseStruct::ef() {}
BaseStruct::~BaseStruct() {}
void DerivedStruct::ab() const {}
void DerivedStruct::cd() {}
void DerivedStruct::ef() {}
DerivedStruct::~DerivedStruct() {}
void DerivedNoVirtualStruct::ab() const {}
void DerivedNoVirtualStruct::cd() {}
void DerivedNoVirtualStruct::ef() {}
DerivedNoVirtualStruct::~DerivedNoVirtualStruct() {}
%}
16 changes: 8 additions & 8 deletions Source/CParse/cscanner.c
Expand Up @@ -748,18 +748,18 @@ int yylex(void) {
yylval.intvalue = cparse_line;
return (TEMPLATE);
}
if (strcmp(yytext, "delete") == 0) {
if (strcmp(yytext, "delete") == 0)
return (DELETE_KW);
}
if (strcmp(yytext, "default") == 0) {
if (strcmp(yytext, "default") == 0)
return (DEFAULT);
}
if (strcmp(yytext, "using") == 0) {
if (strcmp(yytext, "using") == 0)
return (USING);
}
if (strcmp(yytext, "namespace") == 0) {
if (strcmp(yytext, "namespace") == 0)
return (NAMESPACE);
}
if (strcmp(yytext, "override") == 0)
return (OVERRIDE);
if (strcmp(yytext, "final") == 0)
return (FINAL);
} else {
if (strcmp(yytext, "class") == 0) {
Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n");
Expand Down

0 comments on commit 6a72e16

Please sign in to comment.