Please report new issues athttps://github.com/DOCGroup
This problem affects TAO applications with IDL that uses an operation parameter that is a forward-declared interface defined in a separate IDL file. SYNOPSIS: Any insertion operator declarations generated for forward-declared interfaces defined in a separate IDL file do not appear to conform to a strict interpretation of ANSI C++ (ISO/IEC 14882:1998) template name lookup. The HP NonStop C++ compiler's unqualified dependent name lookup doesn't find the CORBA::Any insertion operator declarations that are emitted in the client header file by be_visitor_interface_fwd_any_op_ch::visit_interface_fwd [tao_idl/be/be_visitor_interface_fwd/any_op_ch.cpp]. DESCRIPTION: The fullC.cpp source file generated for the TAO/tests/IDL_Test demonstrates this problem. The Any insertion operator that takes a mod2::full_ptr argument is not found when instantiating TAO::Arg_Traits<mod2::full>. TAO::Arg_Traits<mod2::full> is a full specialization of TAO::Arg_Traits which inherits from Object_Arg_Traits_T<mod2::full_ptr>. The Object_Arg_Traits_T class template declares an inout_arg_val typedef as TAO::Inout_Object_Argument_T<T_ptr>. The Inout_Object_Argument_T template declares an interceptor_param method which inserts this->x_ into the Any contained in its Dynamic::Parameter argument. Ordinary lookup for unqualified names does not find the Any insertion operator for mod2::full_ptr, because this insertion operator is declared after the definition of TAO::Inout_Object_Argument_T<S_ptr>::interceptor_param(Dynamic::Parameter& p). When the Object_Arg_Traits_T template is instantiated for the template parameter mod2::full_ptr, argument-dependent lookup for unqualified dependent names does not find the insertion operator, because the insertion operator is declared in the global namespace. REPEAT BY: Attempt to compile TAO/tests/IDL_Test/fullC.cpp with a C++ compiler that strictly implements the ANSI C++ 1998 standard by performing ordinary lookup at the point of definition. This problem was discovered using the HP NonStop C++ compiler. This problem is not encountered when compiling fullC.cpp with the Microsoft Visual C++ 7.1 compiler or the GNU g++ 3.4.1 compiler. SAMPLE FIX/WORKAROUND: Declaring the Any insertion operator within the interface's namespace would allow the appropriate Any insertion operator declaration to be found by argument-dependent lookup. In the case of IDL_Test/fullC.h, putting namespace mod2 { } around the Any insertion declarations allows the fullC.cpp file to compile. The mod2:: namespace qualifier would also need to be added to the Any insertion operator definitions in fullA.cpp so that the definitions matched the declarations. Changing code generation order so that the Any insertion operator can be found by ordinary name lookup might be an alternative solution, but is likely to require a larger, more intrusive change to the IDL compiler.
I have seen the same problem in the Tru64 build and it happens now also in the PolicyS.cpp file in the PortableServer library.
Brian, could you maybe patch the generated files and make a unified diff of before and after you patches and add them to this report so that we can see what the changes are exactly.
Created attachment 306 [details] Namespace change for fullC.h
Created attachment 307 [details] Namespace change for fwdC.h
Created attachment 308 [details] Namespace change for fullA.cpp
Created attachment 309 [details] Namespace change for fwdA.cpp
accepted
I had a quick look at the patches. Wouldn't it work to generate the following in the header. We should check what happens when we have multiple nested namespaces namespace mod2 { void operator<<= (CORBA::Any &, const scope_struct &); // copying version } and in the cpp namespace mod2 { //operator }
I don't see any real problems but make sure you test a few other compilers before committing this to the repo. All generated files in the repo need to be regenerated because of this. I have personally some batch files that can help but a manual check is needed always.
I see that a number of changes were committed. ********** Bugzilla report #2071. Since some compilers do not implement symbol lookup correctly the changed code is controlled by the ACE_ANY_OPS_USE_NAMESPACE macro. Use this macro in config*.h if your compiler implements symbol lookup correctly. Without the macro the IDL generated code is as it was. ********* Rather than undefine this macro by default, I think it would be better to define a macro that is defined for broken compilers so that we don't punish working compilers by not defining your macro. Two more things: (1) This is a TAO-specific macro. Shouldn't it be prefixed by a "TAO_"? (2) Please try to make the macro conform to ACE macro naming conventions (e.g. {ACE,TAO}_{HAS,LACKS,USES}_FOO). I realize that there are number of existing macros that do not conform. They should be fixed, too, but it would be nice to avoid introducing any new macros that do not conform to ACE/TAO macro naming conventions.
I agree with Ossama that a macro should just be defined for broken compilers. That way when we drop the broken compilers in the future we can more easily remove the old code. Reassing this bug to Gary because he added this.
Accepting
as test I have set ACE_ANY_OPS_USE_NAMESPACE in ace/config-macros.h. What I remember is that vc6 had problems, that is dropped, if no other compilers have issues we can just remove ACE_ANY_OPS_USE_NAMESPACE and use always the namespace way
Setting ACE_ANY_OPS_USE_NAMESPACE will cause compile errors in CIAO. At least icc, gcc, vc71 and vc8 then can't build CIAO anymore. Jeff Parsons helped me to sort out why CIAO building failed, see below. *** I found it. The culprit is the ACE_ANY_OPS_USE_NAMESPACE flag. This recently got #defined for all compilers. The Any operator use cases that are producing the errors are in methods defined in the CIAO namespace. With the flag turned on, some CIAO types have their Any operators defined also in the CIAO namespace. For some reason, my compiler (VC 7.1) is looking no further up than this namespace for a match. For example, in the NodeApplication build, in Container_Impl.cpp, in Container_Impl::install, there are the lines const char * path; impl_infos[i].component_config[prop_len].value >>= path; which produce one of the errors. If I change this to CORBA::Boolean good = operator>>= (impl_infos[i].component_config[prop_len].value, path); the compiler then says there's no match with the first extraction operators (defined in namespace CIAO) it finds, which are in CIAO_EventsC.h. It only checks against the operators in a single opening of the namespace however - strange. If I comment out those decls, the compiler will report no match with the next set found in the next opening of namespace CIAO. Anyway, if I change the line slightly to CORBA::Boolean good = ::operator>>= (impl_infos[i].component_config[prop_len].value, path); the error disappears. It likewise disappears if I comment out the defintion of the flag in config-macros.h. My suggestion for fixing this problem is to forget we ever throught about Any operators in namespaces. I think it will create more problems than in it solves. But if there is some reason for keeping the feature, better than the reasons for ditching it, then we'll have to find another approach.