mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Document def.h.
Also remove the extern for current_storage as it belongs in shared.h. I'm not satisfied with the documentation for initialize_def, but it will do for now. I probably have to rewrite the thing as it's a bit of a beast.
This commit is contained in:
parent
fd765f5e62
commit
72108ba0b5
4 changed files with 177 additions and 50 deletions
|
@ -34,21 +34,39 @@
|
||||||
#include "QF/pr_comp.h"
|
#include "QF/pr_comp.h"
|
||||||
#include "QF/pr_debug.h"
|
#include "QF/pr_debug.h"
|
||||||
|
|
||||||
|
/** \defgroup qfcc_def Def handling
|
||||||
|
\ingroup qfcc
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
struct symbol_s;
|
||||||
|
struct expr_s;
|
||||||
|
|
||||||
|
/** Represent a memory location that holds a QuakeC/Ruamoko object.
|
||||||
|
|
||||||
|
The object represented by the def may be of any type (either internally
|
||||||
|
defined by qfcc (float, int, vector, etc) or user defined (structs, arrays
|
||||||
|
etc)).
|
||||||
|
|
||||||
|
Unless the def is external (ie, declared to be in another compilation
|
||||||
|
unit), defs are always attached to a defspace. Storage for the def's
|
||||||
|
object is allocated from that space.
|
||||||
|
*/
|
||||||
typedef struct def_s {
|
typedef struct def_s {
|
||||||
struct def_s *next; ///< general purpose linking
|
struct def_s *next; ///< general purpose linking
|
||||||
|
|
||||||
struct def_s *temp_next; ///< linked list of "free" temp defs
|
struct def_s *temp_next; ///< linked list of "free" temp defs
|
||||||
struct type_s *type;
|
struct type_s *type; ///< QC type of this def
|
||||||
const char *name;
|
const char *name; ///< the def's name
|
||||||
struct defspace_s *space;
|
struct defspace_s *space; ///< defspace to which this def belongs
|
||||||
int offset;
|
int offset; ///< address of this def in its defspace
|
||||||
|
|
||||||
struct def_s *alias;
|
struct def_s *alias; ///< real def which this def aliases
|
||||||
struct reloc_s *relocs; ///< for relocations
|
struct reloc_s *relocs; ///< for relocations
|
||||||
struct expr_s *initializer;///< initialer expression
|
struct expr_s *initializer;///< initialer expression
|
||||||
|
|
||||||
unsigned offset_reloc:1; ///< use *_def_ofs relocs
|
unsigned offset_reloc:1; ///< use *_def_ofs relocs
|
||||||
unsigned initialized:1;
|
unsigned initialized:1; ///< the def has been initialized
|
||||||
unsigned constant:1; ///< stores constant value
|
unsigned constant:1; ///< stores constant value
|
||||||
unsigned global:1; ///< globally declared def
|
unsigned global:1; ///< globally declared def
|
||||||
unsigned external:1; ///< externally declared def
|
unsigned external:1; ///< externally declared def
|
||||||
|
@ -57,39 +75,145 @@ typedef struct def_s {
|
||||||
unsigned system:1; ///< system def
|
unsigned system:1; ///< system def
|
||||||
unsigned nosave:1; ///< don't set DEF_SAVEGLOBAL
|
unsigned nosave:1; ///< don't set DEF_SAVEGLOBAL
|
||||||
|
|
||||||
string_t file; ///< source file
|
string_t file; ///< declaring/defining source file
|
||||||
int line; ///< source line
|
int line; ///< declaring/defining source line
|
||||||
|
|
||||||
int qfo_def; ///< index to def in qfo defs
|
int qfo_def; ///< index to def in qfo defs
|
||||||
|
|
||||||
void *return_addr; ///< who allocated this
|
void *return_addr; ///< who allocated this
|
||||||
} def_t;
|
} def_t;
|
||||||
|
|
||||||
|
/** Specify the storage class of a def.
|
||||||
|
*/
|
||||||
typedef enum storage_class_e {
|
typedef enum storage_class_e {
|
||||||
sc_global,
|
sc_global, ///< def is globally visibil across units
|
||||||
sc_system,
|
sc_system, ///< def may be redefined once
|
||||||
sc_extern,
|
sc_extern, ///< def is externally allocated
|
||||||
sc_static,
|
sc_static, ///< def is private to the current unit
|
||||||
sc_param,
|
sc_param, ///< def is an incoming function parameter
|
||||||
sc_local
|
sc_local ///< def is local to the current function
|
||||||
} storage_class_t;
|
} storage_class_t;
|
||||||
|
|
||||||
extern storage_class_t current_storage;
|
/** Create a new def.
|
||||||
|
|
||||||
|
Defs may be unnamed.
|
||||||
|
|
||||||
|
Untyped defs (used by type encodings) never allocate space for the def.
|
||||||
|
|
||||||
|
If \a storage is not sc_extern and \a type is not null, space of the
|
||||||
|
size specified by \a type will be allocated to the def from the defspace
|
||||||
|
specified by \a space.
|
||||||
|
|
||||||
|
\param name The name for the def. May be null for unnamed defs.
|
||||||
|
\param type The type for the def. May be null for untyped defs.
|
||||||
|
\param space The defspace to which the def belongs. Must not be null
|
||||||
|
for if \a storage is not sc_extern.
|
||||||
|
\param storage The storage class for the def.
|
||||||
|
\return The new def.
|
||||||
|
*/
|
||||||
def_t *new_def (const char *name, struct type_s *type,
|
def_t *new_def (const char *name, struct type_s *type,
|
||||||
struct defspace_s *space, storage_class_t storage);
|
struct defspace_s *space, storage_class_t storage);
|
||||||
|
|
||||||
|
/** Create a def that aliases another def.
|
||||||
|
|
||||||
|
Aliasing a def to the same type is useless, but not checked. Aliasing a
|
||||||
|
def to a type larger than the def's type is a bad idea as another def may
|
||||||
|
be overwritten via the alias, but is not checked.
|
||||||
|
|
||||||
|
\param def The def to be aliased.
|
||||||
|
\param type The type of the alias.
|
||||||
|
\return The def aliasing \a def.
|
||||||
|
|
||||||
|
\todo Check for type size?
|
||||||
|
\todo Make aliasing to the same type a no-op?
|
||||||
|
*/
|
||||||
def_t *alias_def (def_t *def, struct type_s *type);
|
def_t *alias_def (def_t *def, struct type_s *type);
|
||||||
def_t *temp_def (etype_t type, int size);
|
|
||||||
void free_temp_def (def_t *temp);
|
/** Free a def.
|
||||||
|
|
||||||
|
If the def has space allocated to it, the space will be freed.
|
||||||
|
|
||||||
|
\param def The def to be freed.
|
||||||
|
*/
|
||||||
void free_def (def_t *def);
|
void free_def (def_t *def);
|
||||||
|
|
||||||
|
/** \name Temporary defs
|
||||||
|
|
||||||
|
Temporary defs are used for recycling memory for tempary variables. They
|
||||||
|
always have names in the form of <code>.tmpN</code> where N is a
|
||||||
|
non-negative integer. The type of the temporary def can change throughout
|
||||||
|
its life, but the size will never change.
|
||||||
|
|
||||||
|
Temporary defs are bound to the current function (::current_func must
|
||||||
|
be valid). They are always allocated from the funciont's local defspace.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
/** Get a temporary def.
|
||||||
|
|
||||||
|
If the current function has a free temp def of the same size as \a size,
|
||||||
|
then that def will be recycled, otherwise a new temp will be created. When
|
||||||
|
a new temp is created, its name is set to <code>.tmpN</code> where \c N
|
||||||
|
comes from function_t::temp_num, which is then incremented.
|
||||||
|
|
||||||
|
\note ::current_func must be valid.
|
||||||
|
|
||||||
|
\param type The low-level type of the temporary variable.
|
||||||
|
\param size The amount of space to allocate to the temp.
|
||||||
|
\return The def for the temparary variable.
|
||||||
|
|
||||||
|
\bug \a size is not checked for validity (must be 1-4).
|
||||||
|
\todo support arbitrary sizes
|
||||||
|
*/
|
||||||
|
def_t *temp_def (etype_t type, int size);
|
||||||
|
|
||||||
|
/** Free a tempary def so it may be recycled.
|
||||||
|
|
||||||
|
The temp is put into a list of free temp defs maintained by ::current_func.
|
||||||
|
|
||||||
|
\note ::current_func must be valid.
|
||||||
|
|
||||||
|
\param temp The temp def to be recycled.
|
||||||
|
*/
|
||||||
|
void free_temp_def (def_t *temp);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** Initialize a vm def from a qfcc def.
|
||||||
|
|
||||||
|
\param def The qfcc def to copy.
|
||||||
|
\param ddef The vm def to be initialized.
|
||||||
|
\param aux Copy the field object's type rather than the def's.
|
||||||
|
|
||||||
|
\bug The def is not verified to be a field def when \a aux is true.
|
||||||
|
*/
|
||||||
void def_to_ddef (def_t *def, ddef_t *ddef, int aux);
|
void def_to_ddef (def_t *def, ddef_t *ddef, int aux);
|
||||||
|
|
||||||
struct symbol_s;
|
/** Initialize a def referenced by the given symbol.
|
||||||
struct expr_s;
|
|
||||||
|
|
||||||
|
The symbol is checked for redefinition. (FIXME check rules)
|
||||||
|
|
||||||
|
If \a type is null, then the def will be given the default type (as
|
||||||
|
specified by ::type_default).
|
||||||
|
|
||||||
|
If an initializer expressions is given (\a init is not null), then it
|
||||||
|
must be a constant expression (eg, 2 + 3) for non-local defs. Aggregate
|
||||||
|
types (structs, arrays (unions?)) use block expressions where each
|
||||||
|
expression in the block initializes one element of the aggregate. Nested
|
||||||
|
aggregates simply use nested block expressions. As for simple types, each
|
||||||
|
expression in a block expression must also be constant for non-local defs.
|
||||||
|
|
||||||
|
For \a space and \a storage, see new_def().
|
||||||
|
|
||||||
|
\param sym The symbol for which to create and initialize a def.
|
||||||
|
\param type The type of the def. sym_t::type is set to this. If null,
|
||||||
|
the default type is used.
|
||||||
|
\param init If not null, the expressions to use to initialize the def.
|
||||||
|
\param space The space from which to allocate space for the def.
|
||||||
|
\param storage The storage class of the def.
|
||||||
|
*/
|
||||||
void initialize_def (struct symbol_s *sym, struct type_s *type,
|
void initialize_def (struct symbol_s *sym, struct type_s *type,
|
||||||
struct expr_s *init, struct defspace_s *space,
|
struct expr_s *init, struct defspace_s *space,
|
||||||
storage_class_t storage);
|
storage_class_t storage);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
#endif//__def_h
|
#endif//__def_h
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include "method.h"
|
#include "method.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "reloc.h"
|
#include "reloc.h"
|
||||||
|
#include "shared.h"
|
||||||
#include "strpool.h"
|
#include "strpool.h"
|
||||||
#include "struct.h"
|
#include "struct.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include "method.h"
|
#include "method.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "reloc.h"
|
#include "reloc.h"
|
||||||
|
#include "shared.h"
|
||||||
#include "strpool.h"
|
#include "strpool.h"
|
||||||
#include "struct.h"
|
#include "struct.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "reloc.h"
|
#include "reloc.h"
|
||||||
|
#include "shared.h"
|
||||||
#include "statements.h"
|
#include "statements.h"
|
||||||
#include "strpool.h"
|
#include "strpool.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
|
Loading…
Reference in a new issue