Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Error: Extraneous #endif." and Incorrect Namespaces after Trick #1679 #1703

Closed
shaferandrew opened this issue Apr 29, 2024 · 7 comments · Fixed by #1741
Closed

"Error: Extraneous #endif." and Incorrect Namespaces after Trick #1679 #1703

shaferandrew opened this issue Apr 29, 2024 · 7 comments · Fixed by #1741

Comments

@shaferandrew
Copy link

I have tested this against the latest master (e4f6774) and the issue is still present there. It is first introduced by f8a079e in PR #1679 and is similar to PR #1697. In that issue there is a missing #endif but in my issue there is an extraneous #endif.

Attempting to compile many of the subdevices in Trickcat results in the following compilation error:

build/home/ajshafer/dev/trickcat/include/trickcat/EL1002_py.i:115: Error: Extraneous #endif.

Looking at the file in question, there is a missing newline before the #ifndef macro, causing the preprocessor not to see it:

namespace pdos{ #ifndef TRICK_SWIG_TEMPLATE_trickcat__pdos__el1002__Channel_input
#define TRICK_SWIG_TEMPLATE_trickcat__pdos__el1002__Channel_input
%template(trickcat__pdos__el1002__Channel_input) trickcat::InputProcessImageVariable<bool, 1>;
#endif

Without this #ifndef, later there becomes an "extraneous" #endif.

If I manually insert a newline before the #ifndef Trick can proceed but encounters a new issue:

build/home/ajshafer/dev/trickcat/include/trickcat/EL1002_py.i:34: Error: 'trickcat::InputProcessImageVariable' resolves to 'trickcat::InputProcessImageVariable' and was incorrectly instantiated in scope 'trickcat::pdos' instead of within scope 'trickcat'.

The block in question:

namespace trickcat{

namespace pdos{
#ifndef TRICK_SWIG_TEMPLATE_trickcat__pdos__el1002__Channel_input
#define TRICK_SWIG_TEMPLATE_trickcat__pdos__el1002__Channel_input
%template(trickcat__pdos__el1002__Channel_input) trickcat::InputProcessImageVariable<bool, 1>;
#endif

namespace el1002{

If I move the #ifndef block out of the pdos namespace and into the trickcat namespace then Trick can finish compiling:

namespace trickcat{
#ifndef TRICK_SWIG_TEMPLATE_trickcat__pdos__el1002__Channel_input
#define TRICK_SWIG_TEMPLATE_trickcat__pdos__el1002__Channel_input
%template(trickcat__pdos__el1002__Channel_input) trickcat::InputProcessImageVariable<bool, 1>;
#endif

namespace pdos{

namespace el1002{

If I checkout the last "good" commit (14708ca), there are no issues present and the block in question looks like this:

namespace trickcat{

namespace pdos{ namespace el1002{

class Channel : public ProcessDataObject {

  public:

    trickcat::InputProcessImageVariable<bool, 1> input;
#define TRICK_SWIG_TEMPLATE_trickcat__pdos__el1002__Channel_input
@shaferandrew
Copy link
Author

I think there are two issues, one for nested namespaces on the same line and one for putting the %template directive in the correct namespace.

Here's a minimal working example:

S_post.mk

TRICK_CXXFLAGS += -Imodels

S_define

#include "sim_objects/default_trick_sys.sm"
##include "trick/SimObject.hh"
##include "Foo.hh"

class Sandbox : public Trick::SimObject {

    public:

    a::b::c::Foo foo{};

    Sandbox() {}

    void operator=(const Sandbox&) = delete;

};

Sandbox sandbox;

models/Foo.hh

/**
 * @trick_parse{everything}
 */

#ifndef FOO_HH
#define FOO_HH

#include "Bar.hh"

namespace a {
namespace b {
namespace c {

class Foo {
  public:
    a::Bar<double> bar;
};

}
}
}

#endif

models/Bar.hh

/**
 * @trick_parse{everything}
 */

#ifndef BAR_HH
#define BAR_HH

namespace a {

template <class T>
class Bar {
  public:
    T value{};
};

}

#endif

Running trick-CP:

build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.i:29: Error: 'a::Bar' resolves to 'a::Bar' and was incorrectly instantiated in scope 'a::b' instead of within scope 'a'.
make: *** [build/Makefile_swig:54: build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.cpp] Error 1

Relevant portion of Foo_py.i (note that the %template directive should be in namespace a, not just moved out of Foo):

namespace a{
namespace b{
#ifndef TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
#define TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
%template(a__b__c__Foo_bar) a::Bar<double>;
#endif

namespace c{

class Foo {
  public:
    a::Bar<double> bar;
#if SWIG_VERSION > 0x040000
%pythoncode %{
    __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)
%}
#endif

};
#define TRICK_SWIG_DEFINED_a__b__c__Foo

}
}
}

To produce the "Extraneous #endif bug", simply collapse Foo.hh's namespaces onto the same line, from:

namespace a {
namespace b {
namespace c {

to:

namespace a { namespace b { namespace c {

Then running trick-CP produces:

build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.i:48: Error: Extraneous #endif.
make: *** [build/Makefile_swig:54: build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.cpp] Error 1

From Foo_py.i (note the #ifndef needs to be on a new line):

namespace a{ namespace b{ #ifndef TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
#define TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
%template(a__b__c__Foo_bar) a::Bar<double>;
#endif

@hchen99
Copy link
Contributor

hchen99 commented Apr 29, 2024

Thanks all the info. Don't believe Trick supports nested namespaces though according to: https://nasa.github.io/trick/documentation/building_a_simulation/Model-Source-Code.html#namespaces
Will update the comment if otherwise.

@shaferandrew
Copy link
Author

Issue #768 also seems relevant.

@hchen99
Copy link
Contributor

hchen99 commented Apr 30, 2024

The code in #768 doesn't seem to have the stated issue. Able to compile it without any issue with the latest Trick commit.

@shaferandrew
Copy link
Author

@hchen99 I was referring to the work here, which placed any qualified types in the global namespace (not just one namespace up). The commit referenced in that comment used a variable in convert_swig called $global_template_typedefs, which was placed after all of the class contents, outside of the namespace. In the current version of Trick that variable seems unused now. That work also utilized examples in trick/test/SIM_swig_template_scoping, but it doesn't look like that sim gets built for testing. I'll see what other examples I can find to better showcase the issue.

@hchen99
Copy link
Contributor

hchen99 commented May 2, 2024

Thanks for the info. trick/test/SIM_swig_template_scoping doesn't seem to be in ci process. We'll look into this.

@Pherring04 Pherring04 linked a pull request Jun 10, 2024 that will close this issue
@sharmeye sharmeye linked a pull request Jul 23, 2024 that will close this issue
@sharmeye sharmeye removed a link to a pull request Jul 23, 2024
@sharmeye
Copy link
Contributor

We think this is addressed by PR #1741, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants