[Prev][Next][Index]

Re: friend functions in sage++-1.7



Hi Adam,

you wrote:
>I have a sage program which uses the following code to check whether  
a
>member function is a friend function or not.  This used to work  
under
>sage++-1.3 but no longer works with sage++-1.7.

The treatment of "friend" modifier has changed from version 1.3 to  
version 1.7.
While we try hard to keep new versions of Sage compatible with the  
previous ones, sometimes it is not possible. In case of "friend" (as  
well as "extern", "static", and "inline" modifiers) we had to change  
the way those modifiers are stored in the Sage tree.
Here's the relevant excerpt from WHATSNEW-1.7 file that comes (I  
hope!) with the 1.7 distribution:

---------------------------------------------------------------------
*** Friend, extern, static, and inline decl-specifications are
handled differently.

 Until now they were modifiers of type nodes. Now, they are modifiers  
of 

statement (bif) nodes. The side effect of this change is that the  
internal
format of .dep files have changed. You need to regenerate .dep files
in order to be able to use them with the new release of Sage.

The good news is that this change has fixed several parser/unparser  
bugs.

New methods have been added to SgStatement class to deal with those 

decl-specifications:

  inline void addDeclSpec(int type);   //type should be one of  
BIT_EXTERN,
                                      //BIT_INLINE, BIT_FRIEND,  
BIT_STATIC
  inline void clearDeclSpec();   //resets the decl_specs field to  
zero
  inline int isFriend();         //returns non-zero if friend  
modifier set
                                //returns zero otherwise
  inline int isInline();
  inline int isExtern();
  inline int isStatic();

Example:

 #include <sage++user.h>
 main(){
 	SgProject project("demo.proj");
 	for (int i = 0; i < project.numberOfFiles(); i++){
 	    printf (" current file is %s\n", project.fileName(i));
 	    SgFile *f;
 	    f = &(project.file(i));
 	    SgStatement *s; 

 	    for ( s = f->firstStatement(); s; s = s->lexNext()){
                if(s->isFriend())
                     printf("friend found in stmt with id %i-B\n",  
s->id());
                if(s->isInline()) 

                     printf("inline found in stmt with id %i-B\n",  
s->id());
                if(s->isStatic()) 

                     printf("static found in stmt with id %i-B\n",  
s->id());
                if(s->isExtern()) 

                     printf("extern found in stmt with id %i-B\n",  
s->id());
   		s->clearDeclSpec();	  

                }
           f->unparsestdout();
 	   }
 }
________________________________________________________________


In your particular case, you can re-write your code in the following  
way:

  SgStatement * declst;
  SgClassSymb* user_class = isSgClassSymb( symbol );
  if ( user_class ) {
    SgMemberFuncSymb* member_function = 

      isSgMemberFuncSymb( user_class->field( 1 ) );
    if ( member_function ) {
       declst = member_function->declaredInStmt();
       if(declst->isFriend()){
	  cout << "friend function " << endl;
        }
    }
  }

> Printing out
>member_function->type()->variant() shows it to be T_DERIVED_TYPE.   
>It
>is not a derived class and should not be derived from anything as  
>test
>is a simple class.  Unless the fact that a member function is a
>sgDerivedType() is used to mean that the member function is a friend
>function?

This is a slightly different question, independent of the "friend"  
problem. The type of the member function is the type of its returned  
value. In this case this is a user-defined (i.e., derived) type  
"test". Therefore, the type variant is T_DERIVED_TYPE, and if you  
would use the SgDerivedType::typeName() method you would see that it  
returns the SgSymbol corresponding to "test". T_DERIVED_TYPE does not  
mean that the type corresponds to a derived class; rather that it is  
a user-defined type.
In version 1.3 the type of this member function was SgDescriptType,  
whose base type was an SgDerivedType (as described above). In 1.7  
SgDescriptType is gone because the information about the "friend"  
modifier is stored at the statement, not at the symbol, level.

Hope this clarifies things a bit. Sorry for having to change Sage in  
a way that breaks some existing code but we were not able to find a  
solution that would be compatible with the old representation. Let me  
know if you need more information.              --Beata