Bug 2071 - tao_idl: Any Insertion Operator Dcls for Forward-declared Interfaces
Summary: tao_idl: Any Insertion Operator Dcls for Forward-declared Interfaces
Status: ASSIGNED
Alias: None
Product: TAO
Classification: Unclassified
Component: IDL Compiler (show other bugs)
Version: 1.4.4
Hardware: other other
: P3 normal
Assignee: Gary Maxey
URL:
Depends on:
Blocks:
 
Reported: 2005-03-22 13:50 CST by Brian O'Connor
Modified: 2006-04-20 13:23 CDT (History)
0 users

See Also:


Attachments
Namespace change for fullC.h (808 bytes, patch)
2005-03-23 14:26 CST, Brian O'Connor
Details
Namespace change for fwdC.h (854 bytes, patch)
2005-03-23 14:27 CST, Brian O'Connor
Details
Namespace change for fullA.cpp (2.90 KB, patch)
2005-03-23 14:28 CST, Brian O'Connor
Details
Namespace change for fwdA.cpp (2.89 KB, patch)
2005-03-23 14:29 CST, Brian O'Connor
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Brian O'Connor 2005-03-22 13:50:20 CST
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.
Comment 1 Johnny Willemsen 2005-03-22 15:05:50 CST
I have seen the same problem in the Tru64 build and it happens now also in the 
PolicyS.cpp file in the PortableServer library.
Comment 2 Johnny Willemsen 2005-03-23 04:42:49 CST
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.
Comment 3 Brian O'Connor 2005-03-23 14:26:58 CST
Created attachment 306 [details]
Namespace change for fullC.h
Comment 4 Brian O'Connor 2005-03-23 14:27:56 CST
Created attachment 307 [details]
Namespace change for fwdC.h
Comment 5 Brian O'Connor 2005-03-23 14:28:46 CST
Created attachment 308 [details]
Namespace change for fullA.cpp
Comment 6 Brian O'Connor 2005-03-23 14:29:24 CST
Created attachment 309 [details]
Namespace change for fwdA.cpp
Comment 7 Jeff Parsons 2005-03-31 12:54:35 CST
accepted
Comment 8 Johnny Willemsen 2005-04-25 14:40:23 CDT
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
}
Comment 9 Johnny Willemsen 2005-06-26 05:54:08 CDT
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.
Comment 10 Ossama Othman 2005-07-28 03:19:38 CDT
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.
Comment 11 Johnny Willemsen 2005-08-06 06:08:11 CDT
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.
Comment 12 Gary Maxey 2005-10-18 17:16:59 CDT
Accepting
Comment 13 Johnny Willemsen 2006-04-19 03:04:26 CDT
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 
Comment 14 Johnny Willemsen 2006-04-20 13:23:49 CDT
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.