Work towards allowing queries of interesting post-optimization information.

Extend the ShadingSystem API to allow a form of getattribute() that
takes the pointer to a specific ShadingGroup. Some possible queries are
about post-optimized state, in which case asking for them will trigger
optimization on that group if it has not yet been performed.

We start out with two sets of interesting group attribute queries (and,
of course, the infrastructure and code by which we record them):

1. Make it possible to extract the names of all textures that it can
determine might be accessed by the group (after all instance value
binding, constant folding, and optimization has been taken into
account), as well as knowing whether additional textures may be
accessed, whose names cannot be determined without actually executing
the shader. (This may be helpful to renderer implementations that simply
are not able to accommodate textures that can't be bound prior to
start of shader execution.)

2. Make it possible to extract the names and types of all "user data"
that might be queried (that is, shader parameters that may, after
optimization, still be expected to take on per-point interpolated
values, supplied by the geometry). (N.B. This is leading toward another
really interesting feature/optimization, which will be part of a later
checkin.)

See testshade.cpp, test_group_attributes(), for examples of these
queries in action.