next up previous
Next: Use of Expressions Up: Program Representation Previous: AssertSchedule

ProgramUnit tag

The string which serves as the key in the Database of ProgramUnits which forms a Program is not the same as the name_ref() of the Symbol representing the ProgramUnit's name.

The Program class is defined as follows:

 class Program : public Database<String,ProgramUnit>

The ProgramUnit tag (or pu_tag) is an arbitrary unique string stored in the Definition object (in field _tag) from which a ProgramUnit publicly inherits. To find out the tag of a ProgramUnit, one can either call tag_ref() (a Definition member function) or pu_tag_ref() (a ProgramUnit member function).

Here's the definition of the latter function (with comment):

    const char     *pu_tag_ref() const;
    // Returns the pu_tag of the program unit (not to be confused with
    // the routine_name).  The pu_tag has nothing to do with the
    // Fortran source, but is just an identifier useful in
    // has tables, etc.

Here's the code fragment in Program::read showing how new tags are created from ProgramUnit objects which are read in from the parser:

            ProgramTag   tag;
            ProgramUnit *pgm = new ProgramUnit( tag, vdl );

Class ProgramTag creates a new, unique String tag each time a ProgramTag object is instantiated. Examples of these tags: "PROGRAM-UNIT-1", "PROGRAM-UNIT-2"... see any Polaris printout listing multiple ProgramUnit objects, and you'll see these tags kicking around.

[You may ask why we don't use a routine name as the tag... well, there is more than one reason. First, alternate entries would require some sort of mapping to one name anyway, so it may as well be to an arbitrary name. Next, if the name of the routine we were using as a key changed, we'd want some hook to change the tag for Program, and that's clumsy to do. Finally, a blank main program and a blank block data routine could be in the same Program object... in a real-life environment, those two names, along with the name of a blank common block, are mangled to different things to avoid link conflicts.]

Since ProgramUnit does not take over ownership of the underlying ProgramTag object (it just copies the inherited String object), one should, as in the code above, create a ProgramTag object on the stack.

Here are two problems involved with this convention:

	Program pgm;
	...
	ProgramUnit & old_pu = ...  // Assume old_pu is owned by pgm
	...
	ProgramUnit * new_pu = new ProgramUnit(old_pu);
	...
	ProgramTag bar;	      // create a new tag for new_pu
	new_pu->rename(bar);  /* rename new_pu while it is not owned by
				 any Collection object */
	foo.absorb(new_pu);   // insert new_pu with new tag into foo

If you try to absorb a cloned ProgramUnit into a Program object without renaming its tag, absorb deletes the other ProgramUnit!



next up previous
Next: Use of Expressions Up: Program Representation Previous: AssertSchedule



Jay Hoeflinger
Mon Apr 21 11:52:18 CDT 1997