/* @(#)39	1.3  src/somk/somapi.h, somk.api, som2.1.1 6/14/95 10:44:26  */
/*
 *   COMPONENT_NAME: somk
 *
 *   ORIGINS: 27
 *
 *
 *   10H9767, 10H9769  (C) COPYRIGHT International Business Machines Corp. 1994
 *   All Rights Reserved
 *   Licensed Materials - Property of IBM
 *   US Government Users Restricted Rights - Use, duplication or
 *   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 */
/*
 *  SOMAPI.H
 *
 *  This file documents the data structures and public functions
 *  of the SOM API (Application Programming Interface).  Public methods
 *  are documented in the SOMOBJ, SOMCLS, & SOMCM IDL files.
 *
 *  Note: the typedefs & prototypes in this file explicitly show pointers
 *  to objects that support an interface described by IDL. Thus, these are
 *  not IDL typedefs; they are C/C++ typedefs that reflect the implementation
 *  of object references in SOM as pointers to structures in memory.
 */

#ifndef somapi_h
#define somapi_h

#include <somplatf.h>  /* Platform-specific portion of the SOM API */

/*  SOM Version Numbers  */
SOMEXTERN long SOMDLINK SOM_MajorVersion;
SOMEXTERN long SOMDLINK SOM_MinorVersion;

/*  SOM Thread Support  */
SOMEXTERN long SOMDLINK SOM_MaxThreads;

/*----------------------------------------------------------------------
 * SOM Common Typedefs & Data Structures Section
 *---------------------------------------------------------------------*/

#ifndef SOM_MDT_DEFINED
/* -- Method/Data Tokens -- For locating methods and data members. */
typedef somToken somMToken;
typedef somToken somDToken;
#endif

/*
 *  Typedefs for pointers to functions
 */
typedef int SOMLINK somTD_SOMOutCharRoutine (IN char);
typedef int SOMLINK somTD_SOMLoadModule (
    IN string /* className */,
    IN string /* fileName */,
    IN string /* functionName */,
    IN long   /* majorVersion */,
    IN long   /* minorVersion */,
    OUT somToken * /* modHandle */);
typedef int SOMLINK somTD_SOMDeleteModule (IN somToken /* modHandle */);
typedef string SOMLINK somTD_SOMClassInitFuncName (void);
typedef somToken SOMLINK somTD_SOMMalloc (IN size_t /* nbytes */);
typedef somToken SOMLINK somTD_SOMCalloc (
    IN size_t /* element_count */,
    IN size_t /* element_size */);
typedef somToken SOMLINK somTD_SOMRealloc (
    IN somToken /* memory */,
    IN size_t	/* nbytes */);
typedef void SOMLINK somTD_SOMFree (IN somToken /* memory */);
typedef void SOMLINK somTD_SOMError (
    IN int     /* code */,
    IN string  /* fileName */,
    IN int     /* lineNum */);
typedef unsigned long SOMLINK somTD_SOMCreateMutexSem (OUT somToken *sem);
typedef unsigned long SOMLINK somTD_SOMRequestMutexSem (IN somToken sem);
typedef unsigned long SOMLINK somTD_SOMReleaseMutexSem (IN somToken sem);
typedef unsigned long SOMLINK somTD_SOMDestroyMutexSem (IN somToken sem);
typedef unsigned long SOMLINK somTD_SOMGetThreadId (void);

/*
 *  The Method Table Structure
 */
#ifndef SOM_MTAB_DEFINED
/* -- to specify an embedded object (or array of objects). */
typedef struct {
    SOMClass	 **copp; /* address of class of object ptr */
    long	 cnt;	 /* object count */
    long	 offset; /* Offset to pointer (to embedded objs) */
} somEmbeddedObjStruct;

#ifndef SOM_CLASSINFO_DEFINED
typedef somToken somClassInfo;
#endif

typedef struct somMethodTabStruct {
    SOMClass	    *classObject;
    somClassInfo    *classInfo;
    char	    *className;
    long	    instanceSize;
    long	    dataAlignment;
    long	    mtabSize;
    long	    protectedDataOffset; /* from class's introduced data */
    somDToken	    protectedDataToken;
    somEmbeddedObjStruct *embeddedObjs;
    /* remaining structure is opaque */
    somMethodProc* entries[1];
} somMethodTab, *somMethodTabPtr;
#endif

/* -- For building lists of method tables */
typedef struct somMethodTabList {
    somMethodTab	     *mtab;
    struct somMethodTabList  *next;
} somMethodTabList, *somMethodTabs;

/* -- For building lists of class objects */
typedef struct somClassList {
    SOMClass   *cls;
    struct somClassList *next;
} somClassList, *somClasses;

/*
 * C++-style constructors are called initializers in SOM. Initializers
 * are methods that receive a pointer to a somCtrlStruct as an argument.
 */

typedef  struct  {
    SOMClass	  *cls; /* class whose introduced data is to be initialized */
    somMethodProc *defaultInit;
    somMethodProc *defaultCopyInit;
    somMethodProc *defaultConstCopyInit;
    somMethodProc *defaultNCArgCopyInit;
    long	  dataOffset;
    somMethodProc *legacyInit;
} somInitInfo;

typedef struct {
    SOMClass	  *cls; /* class whose introduced data is to be destroyed */
    somMethodProc *defaultDestruct;
    long	  dataOffset;
    somMethodProc *legacyUninit;
} somDestructInfo;

typedef struct {
    SOMClass	  *cls; /* class whose introduced data is to be assigned */
    somMethodProc *defaultAssign;
    somMethodProc *defaultConstAssign;
    somMethodProc *defaultNCArgAssign;
    somMethodProc *udaAssign;
    somMethodProc *udaConstAssign;
    long	  dataOffset;
} somAssignInfo;

typedef octet *somBooleanVector;
#ifndef SOM_CTI_DEFINED
typedef somToken somCtrlInfo;
#endif

typedef struct somInitCtrlStruct {
    somBooleanVector mask; /* an array of booleans to control ancestor calls */
    somInitInfo     *info; /* an array of structs */
    int 	     infoSize; /* increment for info access */
    somCtrlInfo      ctrlInfo;
} somInitCtrl;

typedef struct somDestructCtrlStruct {
    somBooleanVector  mask; /* an array of booleans to control ancestor calls */
    somDestructInfo  *info; /* an array of structs */
    int 	      infoSize; /* increment for info access */
    somCtrlInfo       ctrlInfo;
} somDestructCtrl;

typedef struct somAssignCtrlStruct {
    somBooleanVector  mask; /* an array of booleans to control ancestor calls */
    somAssignInfo    *info; /* an array of structs */
    int 	      infoSize; /* increment for info access */
    somCtrlInfo       ctrlInfo;
} somAssignCtrl;

typedef void SOMLINK somTP_somRenewNoInitNoZeroThunk(void*);
typedef somTP_somRenewNoInitNoZeroThunk *somTD_somRenewNoInitNoZeroThunk;

/*
 * The Class Data Structures -- these are used to implement static
 * method and data interfaces to SOM objects.
 */

/* -- (Generic) Class data Structure */
typedef struct {
    SOMClass *classObject; /* changed by shadowing */
    somToken tokens[1];    /* method tokens, etc. */
} somClassDataStructure, *somClassDataStructurePtr;

/*
 * A special info access structure pointed to by
 * the parentMtab entry of somCClassDataStructure.
 */
typedef struct {
    somMethodTab    *mtab; /* this class' mtab -- changed by shadowing */
    somMethodTabs   next;  /* the parent mtabs -- unchanged by shadowing */
    SOMClass	    *classObject; /* unchanged by shadowing */
    somTD_somRenewNoInitNoZeroThunk somRenewNoInitNoZeroThunk; /* changed by shadowing */
    long	    instanceSize; /* changed by shadowing */
    somMethodProc   **initializers; /* resolved initializer array in releaseorder */
    somMethodProc   **resolvedMTokens;	/* resolved methods */
    somInitCtrl     initCtrl; /* these fields are filled in if somDTSClass&2 is on */
    somDestructCtrl destructCtrl;
    somAssignCtrl   assignCtrl;
    long	    embeddedTotalCount;
    long	    hierarchyTotalCount;
    long	    unused;
} somParentMtabStruct, *somParentMtabStructPtr;

/*
 * (Generic) Auxiliary Class Data Structure
 */
typedef struct {
    somParentMtabStructPtr parentMtab;
    somDToken		   instanceDataToken;
    somMethodProc	   *wrappers[1]; /* for valist methods */
} somCClassDataStructure, *somCClassDataStructurePtr;


/*----------------------------------------------------------------------
 * Method & Data Resolution Section
 *---------------------------------------------------------------------*/

/*
 * Offset-based method resolution functions
 */
SOMEXTERN somMethodProc * SOMLINK somResolve (
    SOMObject *obj,
    somMToken mdata);
SOMEXTERN somMethodProc * SOMLINK somParentResolve (
    somMethodTabs parentMtabs,
    somMToken mToken);
SOMEXTERN somMethodProc * SOMLINK somParentNumResolve (
    somMethodTabs parentMtabs,
    int parentNum,
    somMToken mToken);
SOMEXTERN somMethodProc * SOMLINK somClassResolve (
    SOMClass *,
    somMToken mdata);
SOMEXTERN somMethodProc * SOMLINK somAncestorResolve (
    SOMObject *obj,		  /* the object */
    somCClassDataStructure *ccds, /* id the ancestor */
    somMToken mToken);
SOMEXTERN somMethodProc * SOMLINK somResolveByName (
    SOMObject *obj,
    char *methodName);

/*
 * Offset-based data resolution functions
 */
SOMEXTERN somToken SOMLINK somDataResolve (
    SOMObject *obj,
    somDToken dataId);
SOMEXTERN somToken SOMLINK somDataResolveChk (
    SOMObject *obj,
    somDToken dataId);


/*----------------------------------------------------------------------
 * somApply Section
 *---------------------------------------------------------------------*/

#ifndef SOM_SMD_DEFINED
typedef somToken somSharedMethodData;
#endif

typedef struct somMethodDataStruct {
    somId id;
    long type;			   /* 0=static, 1=dynamic 2=nonstatic */
    somId descriptor;		   /* for use with IR interfaces */
    somMToken mToken;		   /* NULL for dynamic methods */
    somMethodPtr method;	   /* depends on resolution context */
    somSharedMethodData *shared;
} somMethodData, *somMethodDataPtr;

/*
 * This routine replaces direct use of applyStubs in SOMr1. The reason
 * for the replacement is that the SOMr1 style of applyStub is not
 * generally available in SOMr2, which uses a fixed set of applyStubs,
 * according to method information in the somMethodData. In particular,
 * neither the redispatch stub nor the apply stub found in the method
 * data structure are necessarily useful as such. The method somGetRdStub
 * is the way to get a redispatch stub, and the above function is the
 * way to call an apply stub. If an appropriate apply stub for the
 * method indicated by md is available, then this is invoked and TRUE is
 * returned; otherwise FALSE is returned.
 *
 * The va_list passed to somApply *must* include the target object,
 * somSelf, as its first entry, and any single precision floating point
 * arguments being passed to the the method procedure must be
 * represented on the va_list using double precision values. retVal cannot
 * be NULL.
 */
SOMEXTERN boolean SOMLINK somApply (
    SOMObject *somSelf,
    somToken *retVal,
    somMethodDataPtr mdPtr,
    va_list ap);


/*----------------------------------------------------------------------
 * Utility Functions Section
 *---------------------------------------------------------------------*/

/*
 * Test whether <obj> is a valid SOM object.  This test is based solely
 * on the fact that (on this architecture) the first word of a SOM
 * object is a pointer to its method table.  The test is therefore most
 * correctly understood as returning true if and only if <obj> is a
 * pointer to a pointer to a valid SOM method table.  If so, then
 * methods can be invoked on <obj>.
 */
SOMEXTERN boolean SOMLINK somIsObj (somToken obj);

/*
 * Verifies that the passed object is a valid instance of the passed
 * class.  A detected failure generates an error message and causes
 * program termination.  This call is automatically employed as part
 * of the C method resolution macros if the preprocessor variable
 * SOM_TestOn is defined.
 */
SOMEXTERN SOMObject * SOMLINK somTestCls (
    SOMObject *obj,
    SOMClass *classObj,
    string fileName,
    int lineNumber);

/*
 * Return the class that introduced the method represented by a given
 * method token.
 */
SOMEXTERN SOMClass* SOMLINK somGetClassFromMToken (somMToken mToken);


/*----------------------------------------------------------------------
 * SOM Environment Section
 *---------------------------------------------------------------------*/

/*
 *  Create and initialize the SOM environment.
 *
 *  This function is idempotent (may be invoked redundantly)
 *
 *  Will be called automatically when first object (including a class
 *  object) is created, if it has not already been done.
 *
 *  Returns the SOMClassMgrObject
 */
SOMEXTERN SOMClassMgr * SOMLINK somEnvironmentNew (void);

SOMEXTERN void		SOMLINK somEnvironmentEnd (void);
SOMEXTERN SOMClassMgr * SOMLINK somMainProgram (void);
SOMEXTERN boolean	SOMLINK somAbnormalEnd (void);

/*
 *  Replaceable SOM Memory Management Interfaces
 *
 *  External procedure variables SOMCalloc, SOMFree, SOMMalloc, SOMRealloc
 *  have the same interface as their standard C-library analogs.
 */
SOMEXTERN somTD_SOMCalloc  * SOMDLINK SOMCalloc;
SOMEXTERN somTD_SOMFree    * SOMDLINK SOMFree;
SOMEXTERN somTD_SOMMalloc  * SOMDLINK SOMMalloc;
SOMEXTERN somTD_SOMRealloc * SOMDLINK SOMRealloc;

/*
 *  Replaceable SOM Error handler
 */
SOMEXTERN somTD_SOMError * SOMDLINK SOMError;

/*
 *  Replaceable SOM Semaphore Operations
 *
 *  These operations are used by the SOM Kernel to make thread-safe
 *  state changes to internal resources.
 */
SOMEXTERN somTD_SOMCreateMutexSem  * SOMDLINK SOMCreateMutexSem; 
SOMEXTERN somTD_SOMRequestMutexSem * SOMDLINK SOMRequestMutexSem; 
SOMEXTERN somTD_SOMReleaseMutexSem * SOMDLINK SOMReleaseMutexSem;
SOMEXTERN somTD_SOMDestroyMutexSem * SOMDLINK SOMDestroyMutexSem;

/*
 *  Replaceable SOM Thread Identifier Operation
 *
 *  This operation is used by the SOM Kernel to index data unique to the
 *  currently executing thread.  It must return a small integer that 
 *  uniquely represents the current thread within the current process.
 */
SOMEXTERN somTD_SOMGetThreadId * SOMDLINK SOMGetThreadId;


/*----------------------------------------------------------------------
 *  SOM Id Manager Section
 *---------------------------------------------------------------------*/

/*
 * Makes certain that the id is registered and in normal form, returns
 * the passed somId as a result.
 */
SOMEXTERN somId SOMLINK somCheckId (somId id);

/*
 * Same as somCheckId except returns 1 (true) if this is the first time
 * the string associated with this id has been registered, returns 0
 * (false) otherwise.
 */
SOMEXTERN int SOMLINK somRegisterId (somId id);

/*
 * Returns a somId that must be freed (using SOMFree) when the user
 * has finished with it.
 */
SOMEXTERN somId SOMLINK somIdFromString (string aString);

/*
 * Returns a string that must never be freed.
 */
SOMEXTERN string SOMLINK somStringFromId (somId id);

/*
 * Returns true (1) if the two ids are equal, else false (0).
 */
SOMEXTERN int SOMLINK somCompareIds (somId id1, somId id2);

/*
 * Returns the total number of ids that have been registered so far, you
 * can use this to advise the SOM runtime concerning expected number of
 * ids in later executions of your program, via a call to
 * somSetExpectedIds defined below
 */
SOMEXTERN unsigned long SOMLINK somTotalRegIds (void);

/*
 * Tells the SOM runtime how many unique ids you expect to use during
 * the execution of your program, this can improve space and time
 * utilization slightly, this routine must be called before the SOM
 * environment is created to have any effect
 */
SOMEXTERN void SOMLINK somSetExpectedIds (unsigned long numIds);

/*
 * Returns the unique key for this id, this key will be the same as the
 * key in another id if and only if the other id refers to the same name
 * as this one
 */
SOMEXTERN unsigned long SOMLINK somUniqueKey (somId id);

/*
 * Tells the id manager that strings for any new ids that are registered
 * will never be freed or otherwise modified.  This allows the id
 * manager to just use a pointer to the string in the unregistered id as
 * the master copy of the ids string.  Thus saving space Under normal
 * use (where ids are static varibles) the string associated with an id
 * would only be freed if the code module in which it occured was
 * unloaded
 */
SOMEXTERN void SOMLINK somBeginPersistentIds (void);

/*
 * Tells the id manager that strings for any new ids that are
 * registered may be freed or otherwise modified.  Therefore the id
 * manager must copy the strings inorder to remember the name of an
 * id.
 */
SOMEXTERN void SOMLINK somEndPersistentIds (void);


/*----------------------------------------------------------------------
 * SOM Class Manager Section
 *---------------------------------------------------------------------*/

/*
 * Global class manager object
 */
SOMEXTERN SOMClassMgr * SOMDLINK SOMClassMgrObject;

/*
 * The somRegisterClassLibrary function is provided for use in SOM class
 * libraries on platforms that have loader-invoked entry points
 * associated with shared libraries (DLLs).
 *
 * This function registers a SOM Class Library with the SOM Kernel.
 * The library is identified by its file name and a pointer to its
 * initialization routine.  Since this call may occur prior to the
 * invocation of somEnvironmentNew, its actions are deferred until the
 * SOM environment has been initialized.  At that time, the
 * SOMClassMgrObject is informed of all pending library initializations
 * via the _somRegisterClassLibrary method.  The actual invocation of
 * the library's initialization routine will occur during the execution
 * of the SOM_MainProgram macro (for statically linked libraries), or
 * during the _somFindClass method (for libraries that are dynamically
 * loaded).
 */
SOMEXTERN void SOMLINK somRegisterClassLibrary (
    string libraryName,
    somMethodProc *libraryInitRtn);

/*
 * Pointers to routines used to do dynamic code loading and deleting
 */
SOMEXTERN somTD_SOMLoadModule	     * SOMDLINK SOMLoadModule;
SOMEXTERN somTD_SOMDeleteModule      * SOMDLINK SOMDeleteModule;
SOMEXTERN somTD_SOMClassInitFuncName * SOMDLINK SOMClassInitFuncName;


/*----------------------------------------------------------------------
 * SOM Class Construction Section
 *---------------------------------------------------------------------*/

#define SOM_SCILEVEL 4

/* The SCI includes the following information:
 *
 * The address of a class's ClassData structure is passed.
 * This structure should have the external name,
 * <className>ClassData. The classObject field should be NULL
 * (if it is not NULL, then a new class will not be built). somBuildClass will
 * set this field to the address of the new class object when it is built.
 *
 * The address of the class's auxiliary ClassData structure is passed.
 * Thi structure should have the external name,
 * <className>CClassData. The parentMtab field will be set by somBuildClass.
 * This field often allows method calls to a class object to be avoided.
 *
 * The other structures referenced by the static class information (SCI)
 * are used to:
 *
 *   Specify a static method. The methodId used here must be
 *   a simple name (i.e., no colons). In all other cases,
 *   where a somId is used to identify a registered method,
 *   the somId can include explicit scoping. An explicitly-scoped
 *   method name is called a method descriptor. For example,
 *   the method introduced by SOMObject as somGetClass has the
 *   method descriptor "SOMObject::somGetClass". When a
 *   class is contained in an IDL module, the descriptor syntax
 *   <moduleName>::<className>::<methodName> can be used. Method
 *   descriptors can be useful when a class supports different methods
 *   that have the same name (note: IDL prevents this from occuring
 *   statically, but SOM itself has no problems with this).
 */
typedef struct somStaticMethodStruct {
    somMToken *classData;
    somId *methodId; /* this must be a simple name (no colons) */
    somId *methodDescriptor;
    somMethodProc *method;
    somMethodProc *redispatchStub;
    somMethodProc *applyStub;
} somStaticMethod_t;

/* to specify an overridden method */
typedef struct somOverideMethodStruct {
    somId *methodId; /* this can be a method descriptor */
    somMethodProc *method;
} somOverrideMethod_t;

/* to inherit a specific parent's method implementation */
typedef struct somInheritedMethodStruct {
    somId     *methodId;  /* identify the method */
    long parentNum;	  /* identify the parent */
    somMToken *mToken;	  /* for parentNumresolve */
} somInheritedMethod_t;

/* to register a method that has been moved from this */
/* class <cls> upwards in the class hierachy to class <dest> */
typedef struct somMigratedMethodStruct {
    somMToken *clsMToken; /* points into the <cls> classdata structure */
			  /* the method token in <dest> will copied here */
    somMToken *destMToken;/* points into the <dest> classdata structure */
			  /* the method token here will be copied to <cls> */
} somMigratedMethod_t;

/* to specify non-internal data */
typedef struct somNonInternalDataStruct {
    somDToken *classData;
    char *basisForDataOffset;
} somNonInternalData_t;

/* to specify a "procedure" or "classdata" */
typedef struct somProcMethodsStruct {
    somMethodProc **classData, *pEntry;
} somProcMethods_t;

/*
 * to specify a general method "action" using somMethodStruct the
 * type of action is specified by loading the type field of the
 * somMethodStruct. There are three bit fields in the overall type:
 *
 * action (in type & 0xFF)
 *  0: static -- (i.e., virtual) uses somAddStaticMethod
 *  1: dynamic -- uses somAddDynamicMethod (classData==0)
 *  2: nonstatic -- (i.e., nonvirtual) uses somAddMethod
 *  3: udaAssign -- registers a method as the udaAssign
 *		    (but doesn't add the method)
 *  4: udaConstAssign -- like 3, this doesn't add the method
 *  5: somClassResolve Override (using the class pointed to by *classData)
 *  6: somMToken Override (using the method token pointed to by methodId)
 *			  (note: classData==0 for this)
 *  7: classAllocate -- indicates the default heap allocator for this class.
 *		   If classData == 0, then method is the code address (or NULL)
 *		   If classData != 0, then *classData is the code address.
 *		   No other info required (or used)
 *  8: classDeallocate -- like 7, but indicates the default heap deallocator.
 *  9: classAllocator -- indicates a non default heap allocator for this class.
 *			 like 7, but a methodDescriptor can be given.
 *
 * === the following fields are not currently supported ===
 *
 * binary data access -- in (type & 0x100),
 *			 (valid for actions 0,1,2,5,6)
 *  0: the method procedure doesn't want binary data access
 *  1: the method procedure does want binary data access
 *
 * aggregate return   -- in (type & 0x200),
 *			 (used when binary data access requested)
 *  0: method procedure doesn't return a structure
 *  1: method procedure does return a structure
 */
typedef struct somMethodStruct {
    unsigned long type;
    somMToken *classData;
    somId *methodId;
    somId *methodDescriptor;
    somMethodProc *method;
    somMethodProc *redispatchStub;
    somMethodProc *applyStub;
} somMethods_t;

/* to specify a varargs function */
typedef struct somVarargsFuncsStruct {
    somMethodProc **classData, *vEntry;
} somVarargsFuncs_t;

/* to specify dynamically computed information (incl. embbeded objs) */
typedef struct {
    int   version;			/* 1 for now */
    long  instanceDataSize;		/* true size (incl. embedded objs) */
    long  dataAlignment;		/* true alignment */
    somEmbeddedObjStruct *embeddedObjs; /* array end == null copp */
} somDynamicSCI;

/*
 * to specify a DTS class, use the somDTSClass entry in the following
 * data structure. This entry is a bit vector interpreted as follows:
 *
 * (somDTSClass & 0x0001) == the class is a DTS C++ class
 * (somDTSClass & 0x0002) == the class wants the initCtrl entries
 *			     of the somParentMtabStruct filled in.
 */

/*
 *  The Static Class Info Structure passed to somBuildClass
 */
typedef struct somStaticClassInfoStruct {
    unsigned long layoutVersion;  /* this struct defines layout version SOM_SCILEVEL */
    unsigned long numStaticMethods;   /* count of smt entries */
    unsigned long numStaticOverrides; /* count of omt entries */
    unsigned long numNonInternalData; /* count of nit entries */
    unsigned long numProcMethods;     /* count of pmt entries */
    unsigned long numVarargsFuncs;    /* count of vft entries */
    unsigned long majorVersion;
    unsigned long minorVersion;
    unsigned long instanceDataSize;   /* instance data introduced by this class */
    unsigned long maxMethods;	      /* count numStaticMethods and numMethods */
    unsigned long numParents;
    somId    classId;
    somId    explicitMetaId;
    long implicitParentMeta;
    somId		   *parents;
    somClassDataStructure  *cds;
    somCClassDataStructure *ccds;
    somStaticMethod_t	   *smt; /* basic "static" methods for mtab */
    somOverrideMethod_t    *omt; /* overrides for mtab */
    char		   *nitReferenceBase;
    somNonInternalData_t   *nit; /* datatokens for instance data */
    somProcMethods_t	   *pmt; /* Arbitrary ClassData members */
    somVarargsFuncs_t	   *vft; /* varargs stubs */
    somTP_somClassInitFunc *cif; /* class init function */
    /* end of layout version 1 */

    /* begin layout version 2 extensions */
    long dataAlignment; /* the desired byte alignment for instance data */
    /* end of layout version 2 */

#define SOMSCIVERSION 1

    /* begin layout version 3 extensions */
    long numDirectInitClasses;
    somId *directInitClasses;
    unsigned long numMethods; /* general (including nonstatic) methods for mtab */
    somMethods_t       *mt;
    unsigned long protectedDataOffset; /* access = resolve(instanceDataToken) + offset */
    unsigned long somSCIVersion;  /* used during development. currently = 1 */
    unsigned long numInheritedMethods;
    somInheritedMethod_t *imt; /* inherited method implementations */
    unsigned long numClassDataEntries; /* should always be filled in */
    somId *classDataEntryNames; /* either NULL or ptr to an array of somIds */
    unsigned long numMigratedMethods;
    somMigratedMethod_t *mmt; /* migrated method implementations */
    unsigned long numInitializers; /* the initializers for this class */
    somId *initializers;     /* in order of release */
    unsigned long somDTSClass; /* used to identify a DirectToSOM class */
    somDynamicSCI *dsci;  /* used to register dynamically computed info */
    /* end of layout version 3 */

} somStaticClassInfo, *somStaticClassInfoPtr;

/*
 * This procedure automates construction of a new class object. A variety of
 * special structures are used to allow language bindings to statically define
 * the information necessary to specify a class. Pointers to these static
 * structures are accumulated into an overall "static class information"
 * structure or SCI, passed to somBuildClass. The SCI has evolved over time.
 * The current version is defined here.
 *
 * The arguments to somBuildClass are as follows:
 *
 *   inherit_vars: a bit mask used to control inheritance of
 *		   implementation. Implementation is inherited from
 *		   parent i iff the bit 1<<i is on, or i>=32.
 *
 *   sci:	   the somStaticClassInfo defined above.
 *
 *   majorVersion, minorVersion: the version of the class implementation.
 */
SOMEXTERN SOMClass * SOMLINK somBuildClass (
    IN long inherit_vars,
    IN somStaticClassInfo *sci,
    IN long majorVersion,
    IN long minorVersion);

/*
 *  Used by old single-inheritance emitters to make class creation
 *  an atomic operation. Kept for backwards compatability only.
 */
typedef void	 SOMLINK somTD_classInitRoutine  (
    IN SOMClass * /* parent class */,
    IN SOMClass * /* metaclass */);
SOMEXTERN void SOMLINK somConstructClass (
    IN somTD_classInitRoutine *classInitRoutine,
    IN SOMClass *parentClass,
    IN SOMClass *metaClass,
    IN somClassDataStructure *cds);


/*----------------------------------------------------------------------
 * SOM Stream Output Section
 *---------------------------------------------------------------------*/

/*
 * Uses <SOMOutCharRoutine> to output its arguments under control of the
 * ANSI C style format.  Returns the number of characters output.
 */
SOMEXTERN int SOMLINK somPrintf (string fmt, ...);

/*
 * vprint form of somPrintf
 */
SOMEXTERN int SOMLINK somVprintf (string fmt, va_list ap);

/*
 * Outputs (via somPrintf) blanks to prefix a line at the indicated level
 */
SOMEXTERN void SOMLINK somPrefixLevel (long level);

/*
 * Combines somPrefixLevel and somPrintf
 */
SOMEXTERN int SOMLINK somLPrintf (int level, string fmt, ...);

/*
 * Specify a thread-specific user-defined SOMOutCharRoutine
 */
SOMEXTERN void SOMLINK somSetOutChar (somTD_SOMOutCharRoutine *outch);

/*
 *  Replaceable character output handler.
 *  Points to the character output routine to be used in development
 *  support.  Initialized to <somOutChar>, but may be reset at anytime.
 *  Should return 0 (false) if an error occurs and 1 (true) otherwise.
 */
SOMEXTERN somTD_SOMOutCharRoutine * SOMDLINK SOMOutCharRoutine;


/*----------------------------------------------------------------------
 * SOM Implementation Section
 *---------------------------------------------------------------------*/

/*
 * Externals used in the implementation of SOM, but not part of the
 * SOM API.
 */
SOMEXTERN void SOMLINK somTest (
    IN int condition,
    IN int severity,
    IN string fileName,
    IN int lineNum,
    IN string msg);

SOMEXTERN void SOMLINK somAssert (
    IN int condition,
    IN int ecode,
    IN string fileName,
    IN int lineNum,
    IN string msg);

#endif /* somapi_h */
