1    /* 
     2     *  Copyright (c) 2008 Texas Instruments. All rights reserved.
     3     *  This program and the accompanying materials are made available under the
     4     *  terms of the Eclipse Public License v1.0 and Eclipse Distribution License
     5     *  v. 1.0 which accompanies this distribution. The Eclipse Public License is
     6     *  available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
     7     *  Distribution License is available at
     8     *  http://www.eclipse.org/org/documents/edl-v10.php.
     9     *
    10     *  Contributors:
    11     *      Texas Instruments - initial implementation
    12     * */
    13    /*
    14     *  ======== Error.xdc ========
    15     */
    16    
    17    /*!
    18     *  ======== Error ========
    19     *  Runtime error manager
    20     *
    21     *  The `Error` module provides mechanisms for raising, checking, and
    22     *  handling errors in a program. You can configure it via the
    23     *  `{@link Error#policy Error.policy}` and
    24     *  `{@link Error#raiseHook Error.raiseHook}` configuration parameters.
    25     *
    26     *  Modules may define specific error types and reference these when
    27     *  raising an error. Each error type has a custom error message and
    28     *  can be parameterized with up to `{@link #NUMARGS}` arguments. A
    29     *  generic error type is provided for raising errors when not in a module.
    30     *
    31     *  Use the `{@link #check Error_check()}` function to determine if an
    32     *  error has been raised. It is important to understand that it is the
    33     *  caller's responsibility to check the error block after calling a
    34     *  function that takes an error block as an argument. Otherwise, a raised
    35     *  error may go undetected, which could compromise the integrity of the
    36     *  system. For example:
    37     *
    38     *  @p(code)
    39     *  Task_create(..., &eb);
    40     *
    41     *  if (Error_check(&eb)) {
    42     *      ...an error has been raised...
    43     *  }
    44     *  @p
    45     *
    46     *  The `{@link #raiseHook Error.raiseHook}` configuration parameter allows
    47     *  a configured function to be invoked when any error is raised. This
    48     *  function is passed a pointer to the error's error block and makes it
    49     *  easy to manage all errors from a common point. For example, you can
    50     *  trap any error (fatal or not) by simply setting a breakpoint in this
    51     *  function. You can use the following functions to extract information
    52     *  from an error block.
    53     *
    54     *  @p(blist)
    55     *  - `{@link #getData Error_getData()}`
    56     *  - `{@link #getCode Error_getCode()}`
    57     *  - `{@link #getId Error_getId()}`
    58     *  - `{@link #getMsg Error_getMsg()}`
    59     *  - `{@link #getSite Error_getSite()}`
    60     *  @p
    61     *
    62     *  The Error module provides facilities for handling errors, but the Log
    63     *  module also provides features for logging error events. These are separate
    64     *  concepts; however, to ensure that users do not have to both raise and log
    65     *  an error, the Error module will automatically log an error event when one
    66     *  is raised. The Error module logs the standard {@link Log#L_error} event,
    67     *  passing it the error message and arguments.
    68     *
    69     *  The error event is logged to the Error module's logger using the Error
    70     *  module's diags mask. Logging of errors is enabled by default in the diags
    71     *  mask, but the event will not be logged unless a logger is configured for
    72     *  the Error module as well.
    73     *
    74     *  To make the error event appear as though it is coming from the module which
    75     *  called Error_raise, the event is logged with the caller's module id and
    76     *  with the caller's call site information.
    77     *
    78     *  @a(Examples)
    79     *  Example 1: The following example shows how a module, named ModA,
    80     *  defines a custom error type and shows how this error is raised by
    81     *  the module. The module defines an `Id` of `E_notEven` in its module
    82     *  specification file (in this case, `ModA.xdc`). The error's message
    83     *  string takes only one argument. The module also defines a `mayFail()`
    84     *  function that takes an error block. In the module's C source file,
    85     *  the function checks for the error condition and raises the error if
    86     *  needed.
    87     *
    88     *  This is part of ModA's XDC specification file for the module:
    89     *
    90     *  @p(code)
    91     *  config xdc.runtime.Error.Id E_notEven = {
    92     *      msg: "expected an even number (%d)"
    93     *  };
    94     *
    95     *  Void mayFail(Int x, xdc.runtime.Error.Block *eb);
    96     *  @p
    97     *
    98     *  This is part of the C code for the module:
    99     *
   100     *  @p(code)
   101     *  Void ModA_mayFail(Int x, Error_Block *eb)
   102     *  {
   103     *      if ((x % 2) != 0) {
   104     *          Error_raise(eb, ModA_E_notEven, x, 0);
   105     *          ...add error handling code here...
   106     *          return;
   107     *      }
   108     *      ...
   109     *  }
   110     *  @p
   111     *
   112     *  @p(html)
   113     *  <hr />
   114     *  @p
   115     *
   116     *  Example 2: The following C code supplies an error block to a function
   117     *  that requires one and tests the error block to see if the function
   118     *  raised an error. Note that an error block must be initialized before
   119     *  it can be used and same error block may be passed to several functions.
   120     *
   121     *  @p(code)
   122     *  #include <xdc/runtime/Error.h>
   123     *  #include <ti/sysbios/knl/Task.h>
   124     *  Error_Block eb;
   125     *  Task_Handle tsk;
   126     *
   127     *  Error_init(&eb);
   128     *  tsk = Task_create(..., &eb);
   129     *
   130     *  if (Error_check(&eb)) {
   131     *      ...an error has been raised...
   132     *  }
   133     *  @p
   134     *
   135     *  @p(html)
   136     *  <hr />
   137     *  @p
   138     *
   139     *  Example 3: The following C code shows that you may pass `NULL` to a
   140     *  function requiring an error block. In this case, if the function
   141     *  raises an error, the program is aborted (via
   142     *  `{@link System#abort xdc_runtime_System_abort()}`), thus execution
   143     *  control will never return to the caller.
   144     *
   145     *  @p(code)
   146     *  #include <xdc/runtime/Error.h>
   147     *  #include <ti/sysbios/knl/Task.h>
   148     *
   149     *  tsk = Task_create(..., NULL);
   150     *  ...will never get here if an error was raised in Task_create...
   151     *  @p
   152     *
   153     *  @p(html)
   154     *  <hr />
   155     *  @p
   156     *
   157     *  Example 4: The following C code shows how to write a function that
   158     *  is not part of a module and that takes an error block and raises
   159     *  the generic error type provided by the Error module. Note, if the
   160     *  caller passes `NULL` for the error block or if the error policy is
   161     *  `{@link #Policy TERMINATE}`, then the call to
   162     *  `{@link #raise Error_raise()}` will call
   163     *  `{@link System#abort xdc_runtime_System_abort()}` and never return.
   164     *
   165     *  @p(code)
   166     *  #include <xdc/runtime/Error.h>
   167     *
   168     *  Void myFunc(..., Error_Block *eb)
   169     *  {
   170     *      ...
   171     *
   172     *      if (...error condition detected...) {
   173     *          String  myErrorMsg = "my custom error message";
   174     *          Error_raise(eb, Error_E_generic, myErrorMsg, 0);
   175     *          ...add error handling code here...
   176     *          return;
   177     *      }
   178     *  }
   179     *  @p
   180     */
   181    @DirectCall
   182    @RomConsts
   183    
   184    module Error {
   185    
   186        /*!
   187         *  ======== Policy ========
   188         *  Error handling policies
   189         *
   190         *  Regardless of the current policy in use, raising an error by
   191         *  calling `{@link #raise Error_raise}` will always invoke the
   192         *  error raise hook function assigned to the
   193         *  `{@link #raiseHook Error.raiseHook}` configuration parameter.
   194         *
   195         *  @field(TERMINATE) All raised errors are fatal. A call to
   196         *  `{@link #raise Error_raise}` will never return to the caller.
   197         *
   198         *  @field(UNWIND) Errors are returned to the caller. A call to
   199         *  `{@link #raise Error_raise}` will return back to the caller.
   200         */
   201        enum Policy {
   202            TERMINATE,
   203            UNWIND
   204        };
   205    
   206        /*!
   207         *  ======== Desc ========
   208         *  Error descriptor
   209         *
   210         *  Each type of error is defined with an error descriptor. This
   211         *  structure groups common information about the errors of this type.
   212         *
   213         *  @field(msg) The error message using a `printf` style format string, 
   214         *              but limited to `{@link #NUMARGS}` arguments.
   215         *              This format string together with the two arguments passed
   216         *              to `Error_raise`` are used to create a human readable
   217         *              error message.
   218         *
   219         *  @field(code) A user assignable code, 0 by default. The user may
   220         *              optionally set this field during config to give the
   221         *              error a well-known numeric code. 
   222         */
   223        metaonly struct Desc {
   224            String msg;
   225            UInt16 code;
   226        };
   227    
   228        /*!
   229         *  ======== Id ========
   230         *  Error identifier
   231         *
   232         *  Each type of error raised is defined with a metaonly
   233         *  `{@link Error#Desc}`.  An `Error_Id` is a 32-bit target value that
   234         *  encodes the information in the `Desc`.  Target programs use
   235         *  `Error_Id` values to "raise" and check for specific errors.
   236         *
   237         *  @a(Warning) `{@link #Id}` values may vary among different
   238         *  configurations of an application.  For example, the addition of a
   239         *  new module to a program may result in a different absolute value for
   240         *  `{@link #E_generic}`.  If you need error numbers that remain
   241         *  invariant, use the user definable `{@link #Desc Desc.code}` field.
   242         */
   243        @Encoded typedef Desc Id;
   244        
   245        /*!
   246         *  ======== HookFxn ========
   247         *  Function called whenever an error is raised
   248         *
   249         *  The first parameter and only parameter passed to this function is a
   250         *  pointer to an `Error_Block`.  Even if the client passes a `NULL` error
   251         *  block pointer to `{@link #raise Error_raise}`, this parameter passed 
   252         *  to this "hook" function is always `non-NULL`.
   253         */
   254        typedef Void (*HookFxn)(Block *);
   255    
   256        /*!
   257         *  ======== NUMARGS ========
   258         *  Maximum number of arguments supported by an error
   259         */
   260        const Int NUMARGS = 2;
   261    
   262        /*!
   263         *  ======== Data ========
   264         *  Error args
   265         *
   266         *  The two arguments (arg1, arg2) passed to `{@link #raise}` are 
   267         *  stored in one of these arrays within the associated Error_Block.
   268         *  To access these arguments use `{@link #getData}` to obtain a 
   269         *  pointer to the Error_Block's Data array.
   270         *
   271         *  @see #getData
   272         */
   273        struct Data {
   274            IArg arg[NUMARGS];
   275        }
   276    
   277        /*!
   278         *  ======== Block ========
   279         *  Error block
   280         *
   281         *  An opaque structure used to store information about errors once raised.
   282         *  This structure must be initialized via `{@link #init Error_init()}`
   283         *  before being used for the first time.
   284         */
   285        @Opaque struct Block {
   286            UInt16      unused;     /* for backward compatibility (was code) */
   287            Data        data;       /* arguments passed to raise() */
   288            Id          id;         /* id passed to raise() */
   289            String      msg;        /* msg associated with id */
   290            Types.Site  site;       /* info about Error_raise call site */
   291            IArg        xtra[4];    /* future expansion */
   292        };
   293    
   294        /*!
   295         *  ======== PolicyFxn ========
   296         *  Error policy function signature
   297         *
   298         *  @a(Parameters)
   299         *  A policy function is passed the following parameters:
   300         *  @p(dlist)
   301         *      - `eb`
   302         *        A pointer to an `{@link #Block Error_Block}` structure to be
   303         *        initialized using the subsequent arguments.  This pointer may 
   304         *        be `NULL`.
   305         *      - `modId`
   306         *        The module ID of the module calling
   307         *        `{@link #raise Error_raise()}`
   308         *      - `fileName`
   309         *        A string naming the source file which made the call to
   310         *        `{@link #raise Error_raise()}`
   311         *      - `lineNumber`
   312         *        An integer line number within the file named above where
   313         *        the call `{@link #raise Error_raise()}` occured
   314         *      - `errId`
   315         *        The `{@link #Id Error_Id}` of the error being raised
   316         *      - `arg1` and `arg2`
   317         *        Two `IArg` arguments associated with the error being raised
   318         *  @p
   319         */
   320        typedef Void (*PolicyFxn)(Block *, Types.ModuleId, CString, Int, Id,
   321                                  IArg, IArg);
   322    
   323        /*!
   324         *  ======== policyFxn ========
   325         *  Error handler function
   326         *
   327         *  This function is called to handle all raised errors but, unlike
   328         *  `{@link raiseHook}`, this function is responsible for completely
   329         *  handling the error (including calling `{@link #raiseHook raiseHook}`
   330         *  with an appropriately initialized `{@link #Block Error_Block}`, if
   331         *  `raiseHook` functionality is required). 
   332         *
   333         *  The default value is a function which, in addition to calling `raiseHook`
   334         *  with an initialized `Error_Block` structure, logs the error using this
   335         *  module's logger.  
   336         *  
   337         *  Alternately, `{@link #policySpin}`, which simply loops 
   338         *  infinitely, can be used to minimize target footprint.  Note, this function
   339         *  does NOT call `raiseHook`.
   340         */
   341        config PolicyFxn policyFxn = Error.policyDefault;
   342    
   343        /*!
   344         *  ======== E_generic ========
   345         *  Generic error
   346         *
   347         *  This error takes advantage of the $S specifier to allow for recursive
   348         *  formatting of the error message passed to error raise.
   349         *
   350         *  For example, the following is possible:
   351         *  @p(code)
   352         *  Error_raise(eb, Error_E_generic, "Error occurred, code: %d", code);
   353         *  @p
   354         *
   355         *  @see System#extendedFormats
   356         *  @see System#printf
   357         */
   358        config Id E_generic = {msg: "%$S"};
   359    
   360        /*!
   361         *  ======== E_memory ========
   362         *  Out of memory error
   363         *
   364         *  The first parameter must be the heap instance handle. The second
   365         *  parameter is the size of the object for which the allocation failed.
   366         */
   367        config Id E_memory = {msg: "out of memory: heap=0x%x, size=%u"}; 
   368    
   369        /*!
   370         *  ======== E_msgCode ========
   371         *  Generic error that displays a string and a numeric value
   372         */
   373        config Id E_msgCode = {msg: "%s 0x%x"}; 
   374    
   375        /*!
   376         *  ======== policy ========
   377         *  System-wide error handling policy
   378         */
   379        config Policy policy = UNWIND;
   380    
   381        /*!
   382         *  ======== raiseHook ========
   383         *  The function to call whenever an error is raised
   384         *
   385         *  If set to a non-`null` value, the referenced function is always
   386         *  called when an error is raised, even if the `Error` policy is
   387         *  `{@link #Policy TERMINATE}`.  In rare cases, it is possible that a
   388         *  raised error does not trigger a call to `raiseHook`; see
   389         *  `{@link #maxDepth}`.
   390         *
   391         *  By default, this function is set to `{@link #print Error_print}`
   392         *  which causes the error to be formatted and output via
   393         *  `{@link xdc.runtime.System#aprintf System_printf}`.  Setting this
   394         *  configuration parameter to `null` indicates that no function hook
   395         *  should be called.
   396         *
   397         *  @see #maxDepth
   398         *  @see #HookFxn
   399         *  @see #print
   400         */
   401        config HookFxn raiseHook = Error.print;
   402    
   403        /*!
   404         *  ======== maxDepth ========
   405         *  Maximum number of concurrent calls to `{@link #raiseHook}`
   406         *
   407         *  To prevent errors that occur in the raiseHook function from
   408         *  causing an infinite recursion, the maximum number of concurrent
   409         *  calls to `{@link #raiseHook}` is limited by `Error_maxDepth`.  If
   410         *  the number of concurrent calls exceeds `Error_maxDepth`, the
   411         *  `raiseHook` function is not called.
   412         *
   413         *  In multi-threaded systems, errors raised by separate threads may
   414         *  be detected as recursive calls to `raiseHook`.  So, setting
   415         *  `Error.maxDepth` to a small value may - in rare instances - result in
   416         *  `errorHook` not being called for some raised errors.
   417         *
   418         *  If it is important that all raised errors trigger a call to the
   419         *  `raiseHook` function, set `Error.maxDepth` to an impossibly large
   420         *  number (0xffff) and either ensure that the raise hook never calls a
   421         *  function that can raise an error or add checks in `raiseHook` to
   422         *  protect against "double faults".
   423         */
   424        config UInt16 maxDepth = 16;
   425        
   426        /*!
   427         *  ======== check ========
   428         *  Return TRUE if an error was raised
   429         *
   430         *  @param(eb) pointer to an `Error_Block` or `NULL`
   431         *
   432         *  @a(returns)
   433         *  If `eb` is non-`NULL` and `{@link #policy Error.policy} == UNWIND` and
   434         *  an error was raised on `eb`, this function returns `TRUE`.  Otherwise,
   435         *  it returns `FALSE`.
   436         */
   437        Bool check(Block *eb);
   438    
   439        /*!
   440         *  ======== getData ========
   441         *  Get an error's argument list
   442         *
   443         *  @param(eb)      non-`NULL` pointer to an `Error_Block`
   444         *
   445         *  @a(returns)
   446         *  `getData` returns an array of type `{@link #Data}` with
   447         *  `{@link #NUMARGS}` elements containing the arguments provided
   448         *  at the time the error was raised.
   449         *
   450         *  @see #raise
   451         */
   452        Data *getData(Block *eb);
   453    
   454        /*!
   455         *  ======== getCode ========
   456         *  Get an error's code
   457         *
   458         *  @param(eb) non-`NULL` pointer to an `Error_Block`
   459         *
   460         *  @a(returns)
   461         *  `getCode` returns the error code associated with this error block.
   462         *
   463         *  @see #raise
   464         *  @see #Desc
   465         */
   466        UInt16 getCode(Block *eb);
   467    
   468        /*!
   469         *  ======== getId ========
   470         *  Get an error's id
   471         *
   472         *  @param(eb) non-`NULL` pointer to an `Error_Block`
   473         *
   474         *  @a(Warning)
   475         *  `Error_Id` values may vary among different configurations
   476         *  of an application.  For example, the addition of a new module to a
   477         *  program may result in a different absolute value for
   478         *  `{@link #E_generic}`.  If you need error numbers that remain
   479         *  invariant, use the user definable `{@link #Desc Desc.code}` field.
   480         *
   481         *  @see #raise
   482         *  @see #Desc
   483         */
   484        Id getId(Block *eb);
   485    
   486        /*!
   487         *  ======== getMsg ========
   488         *  Get an error's "printf" format string
   489         *
   490         *  @param(eb) non-`NULL` pointer to an `Error_Block`
   491         *
   492         *  @see #raise
   493         *  @see #Desc
   494         */
   495        String getMsg(Block *eb);
   496    
   497        /*!
   498         *  ======== getSite ========
   499         *  Get an error's call site info
   500         *
   501         *  @param(eb) non-`NULL` pointer to an `Error_Block`
   502         *
   503         *  @a(returns)
   504         *  `getSite` returns a pointer to an initialized
   505         *  `{@link Types#Site Types.Site}` structure.  However, in the
   506         *  event that the call site was compiled with `xdc_FILE` defined to
   507         *  be `NULL` (to minimize string space overhead) the `file`
   508         *  field may be set to `NULL`.
   509         *
   510         *  @see #raise
   511         *  @see #Desc
   512         */
   513        Types.Site *getSite(Block *eb);
   514    
   515        /*!
   516         *  ======== idToCode ========
   517         *  Extract the user's error code associated with an `Error_Id`
   518         *
   519         *  @param(id) `Error_Id` from which to extract the user defined
   520         *             code 
   521         *  @_nodoc
   522         */
   523        @Macro UInt16 idToCode(Id id);
   524        
   525        /*!
   526         *  ======== idToUid ========
   527         *  Extract the unique error id associated with an `Error_Id`
   528         *
   529         *  @param(id) `Error_Id` from which to extract the system unique
   530         *             id associated with the specified `Error_Id`
   531         *  @_nodoc
   532         */
   533        @Macro UInt16 idToUid(Id id);
   534    
   535        /*!
   536         *  ======== init ========
   537         *  Put an error block into its initial state
   538         *
   539         *  To ensure reliable error detection, clients must call `init` for
   540         *  an `Error_Block` prior to any use.
   541         *  
   542         *  If the same Error Block is used multiple times, only the last error
   543         *  raised is retained.
   544         *
   545         *  @param(eb) pointer to an `Error_Block` or `NULL`
   546         *
   547         *      If `eb` is `NULL` this function simply returns.
   548         */
   549        Void init(Block *eb);
   550    
   551        /*!
   552         *  ======== print ========
   553         *  Print error using System.printf()
   554         *
   555         *  This function prints the error using `System_printf()`.  The output
   556         *  is on a single line terminated with a new line character and has the
   557         *  following form:
   558         *  @p(code)
   559         *      <site>: <file>, line <line_num>: <err_msg>
   560         *  @p
   561         *  where `<site>` is the module that raised the error, `<file>` and
   562         *  `<line_num>` are the file and line number of the containing the call
   563         *  site of the `Error_raise()`, and `<err_msg>` is the error message
   564         *  rendered with the arguments associated with the error.
   565         *
   566         *  @param(eb) pointer to an `Error_Block` or `NULL`
   567         *
   568         *      If `eb` is `NULL` this function simply returns with no output.
   569         *
   570         *  @a(Warning)
   571         *  This function is not protected by a gate and, as a result,
   572         *  if two threads call this method concurrently, the output of the two
   573         *  calls will be intermingled.  To prevent intermingled error output,
   574         *  you can either wrap all calls to this method with an appropriate
   575         *  `Gate_enter`/`Gate_leave` pair or simply ensure that only one
   576         *  thread in the system ever calls this method.
   577         */
   578        Void print(Block *eb);
   579        
   580        /*!
   581         *  ======== policyDefault ========
   582         *  Default implementation of the policyFxn
   583         *
   584         *  This function is the implementation which is plugged in by default to
   585         *  the `{@link #policyFxn}`. It processes the error and logs it before
   586         *  returning to the caller or aborting - depending on the error policy
   587         *  `{@link #policy}`.
   588         */
   589        Void policyDefault(Block *eb, Types.ModuleId mod, CString file, Int line,
   590            Id id, IArg arg1, IArg arg2);
   591    
   592        /*!
   593         *  ======== policySpin ========
   594         *  Lightweight implementation of the policyFxn
   595         *
   596         *  This function is a lightweight alternative  which can be plugged in to
   597         *  the `{@link #policyFxn}`. It just loops infinitely.
   598         *
   599         *  @a(Warning)
   600         *  This function does not call `{@link #raiseHook}` and never returns to 
   601         *  the caller.  As a result, ANY error raised by the application will cause 
   602         *  it to indefinitly hang.
   603         */
   604        Void policySpin(Block *eb, Types.ModuleId mod, CString file, Int line,
   605            Id id, IArg arg1, IArg arg2);
   606    
   607        /*!
   608         *  ======== raise ========
   609         *  Raise an error
   610         *
   611         *  This function is used to raise an `Error` by writing call site,
   612         *  error ID, and error argument information into the `Error_Block`
   613         *  pointed to by `eb`.
   614         *
   615         *  If `Error_raise` is called more than once on an `Error_Block` object,
   616         *  the previous error information is overwritten; only the last error 
   617         *  is retained in the `Error_Block` object.
   618         *
   619         *  In all cases, any configured `{@link #raiseHook Error.raiseHook}`
   620         *  function is called with a non-`NULL` pointer to a fully
   621         *  initialized `Error_Block` object.
   622         *
   623         *  @param(eb) pointer to an `Error_Block` or `NULL`
   624         *
   625         *      If `eb` is `NULL` or `{@link #policy Error.policy} == TERMINATE`,
   626         *      this function does not return to the caller; after calling any
   627         *      configured `{@link #raiseHook}`, `System_abort` is called with the
   628         *      string `"xdc.runtime.Error.raise: terminating execution\n"`.
   629         *
   630         *  @param(id) the error to raise
   631         *
   632         *      This pointer identifies the class of error being raised;
   633         *      the error class indicates how to interpret any subsequent 
   634         *      arguments passed to `{@link #raise}`.
   635         *
   636         *  @param(arg1) error's first argument
   637         *
   638         *      The argument interpreted by the first control character
   639         *      in the error message format string. It is ignored if not needed.
   640         *
   641         *  @param(arg2) error's second argument
   642         *
   643         *      The argument interpreted by the second control character
   644         *      in the error message format string. It is ignored if not needed.
   645         */
   646        @Macro Void raise(Block *eb, Id id, IArg arg1, IArg arg2);
   647    
   648        /*! @_nodoc */
   649        Void raiseX(Block *eb, Types.ModuleId mod, CString file, Int line,
   650            Id id, IArg arg1, IArg arg2);
   651    
   652        /*! @_nodoc EXPERIMENTAL */
   653        Void setX(Block *eb, Types.ModuleId mod, CString file, Int line,
   654            Id id, IArg arg1, IArg arg2);
   655    
   656    internal:
   657    
   658        struct Module_State {
   659            UInt16      count;
   660        };
   661    
   662    }
   663    /*
   664     *  @(#) xdc.runtime; 2, 1, 0,0; 7-26-2016 11:46:12; /db/ztree/library/trees/xdc/xdc-B21/src/packages/
   665     */
   666