nasa / trick

Trick Simulation Environment. Trick provides a common set of simulation capabilities and utilities to build simulations automatically.
Other
34 stars 19 forks source link

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

Closed shaferandrew closed 2 months ago

shaferandrew commented 5 months ago

I have tested this against the latest master (e4f6774) and the issue is still present there. It is first introduced by f8a079ec 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 (14708ca9), 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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

Issue #768 also seems relevant.

hchen99 commented 5 months ago

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 commented 5 months ago

@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 commented 5 months ago

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

sharmeye commented 2 months ago

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