summaryrefslogtreecommitdiffstats
path: root/Include/internal/pycore_symtable.h
blob: ac6c499c08264e82694cc38639443126d2c7f61c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#ifndef Py_INTERNAL_SYMTABLE_H
#define Py_INTERNAL_SYMTABLE_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_BUILD_CORE
#  error "this header requires Py_BUILD_CORE define"
#endif

struct _mod;   // Type defined in pycore_ast.h

typedef enum _block_type {
    FunctionBlock, ClassBlock, ModuleBlock,
    // Used for annotations if 'from __future__ import annotations' is active.
    // Annotation blocks cannot bind names and are not evaluated.
    AnnotationBlock,
    // Used for generics and type aliases. These work mostly like functions
    // (see PEP 695 for details). The three different blocks function identically;
    // they are different enum entries only so that error messages can be more
    // precise.
    TypeVarBoundBlock, TypeAliasBlock, TypeParamBlock
} _Py_block_ty;

typedef enum _comprehension_type {
    NoComprehension = 0,
    ListComprehension = 1,
    DictComprehension = 2,
    SetComprehension = 3,
    GeneratorExpression = 4 } _Py_comprehension_ty;

/* source location information */
typedef struct {
    int lineno;
    int end_lineno;
    int col_offset;
    int end_col_offset;
} _Py_SourceLocation;

#define SRC_LOCATION_FROM_AST(n) \
    (_Py_SourceLocation){ \
               .lineno = (n)->lineno, \
               .end_lineno = (n)->end_lineno, \
               .col_offset = (n)->col_offset, \
               .end_col_offset = (n)->end_col_offset }

static const _Py_SourceLocation NO_LOCATION = {-1, -1, -1, -1};

/* __future__ information */
typedef struct {
    int ff_features;                    /* flags set by future statements */
    _Py_SourceLocation ff_location;     /* location of last future statement */
} _PyFutureFeatures;

struct _symtable_entry;

struct symtable {
    PyObject *st_filename;          /* name of file being compiled,
                                       decoded from the filesystem encoding */
    struct _symtable_entry *st_cur; /* current symbol table entry */
    struct _symtable_entry *st_top; /* symbol table entry for module */
    PyObject *st_blocks;            /* dict: map AST node addresses
                                     *       to symbol table entries */
    PyObject *st_stack;             /* list: stack of namespace info */
    PyObject *st_global;            /* borrowed ref to st_top->ste_symbols */
    int st_nblocks;                 /* number of blocks used. kept for
                                       consistency with the corresponding
                                       compiler structure */
    PyObject *st_private;           /* name of current class or NULL */
    _PyFutureFeatures *st_future;   /* module's future features that affect
                                       the symbol table */
    int recursion_depth;            /* current recursion depth */
    int recursion_limit;            /* recursion limit */
};

typedef struct _symtable_entry {
    PyObject_HEAD
    PyObject *ste_id;        /* int: key in ste_table->st_blocks */
    PyObject *ste_symbols;   /* dict: variable names to flags */
    PyObject *ste_name;      /* string: name of current block */
    PyObject *ste_varnames;  /* list of function parameters */
    PyObject *ste_children;  /* list of child blocks */
    PyObject *ste_directives;/* locations of global and nonlocal statements */
    PyObject *ste_mangled_names; /* set of names for which mangling should be applied */
    _Py_block_ty ste_type;
    int ste_nested;      /* true if block is nested */
    unsigned ste_free : 1;        /* true if block has free variables */
    unsigned ste_child_free : 1;  /* true if a child block has free vars,
                                     including free refs to globals */
    unsigned ste_generator : 1;   /* true if namespace is a generator */
    unsigned ste_coroutine : 1;   /* true if namespace is a coroutine */
    _Py_comprehension_ty ste_comprehension;  /* Kind of comprehension (if any) */
    unsigned ste_varargs : 1;     /* true if block has varargs */
    unsigned ste_varkeywords : 1; /* true if block has varkeywords */
    unsigned ste_returns_value : 1;  /* true if namespace uses return with
                                        an argument */
    unsigned ste_needs_class_closure : 1; /* for class scopes, true if a
                                             closure over __class__
                                             should be created */
    unsigned ste_needs_classdict : 1; /* for class scopes, true if a closure
                                         over the class dict should be created */
    unsigned ste_comp_inlined : 1; /* true if this comprehension is inlined */
    unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */
    unsigned ste_can_see_class_scope : 1; /* true if this block can see names bound in an
                                             enclosing class scope */
    int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */
    int ste_lineno;          /* first line of block */
    int ste_col_offset;      /* offset of first line of block */
    int ste_end_lineno;      /* end line of block */
    int ste_end_col_offset;  /* end offset of first line of block */
    int ste_opt_lineno;      /* lineno of last exec or import * */
    int ste_opt_col_offset;  /* offset of last exec or import * */
    struct symtable *ste_table;
} PySTEntryObject;

extern PyTypeObject PySTEntry_Type;

#define PySTEntry_Check(op) Py_IS_TYPE((op), &PySTEntry_Type)

extern long _PyST_GetSymbol(PySTEntryObject *, PyObject *);
extern int _PyST_GetScope(PySTEntryObject *, PyObject *);
extern int _PyST_IsFunctionLike(PySTEntryObject *);

extern struct symtable* _PySymtable_Build(
    struct _mod *mod,
    PyObject *filename,
    _PyFutureFeatures *future);
extern PySTEntryObject* _PySymtable_Lookup(struct symtable *, void *);

extern void _PySymtable_Free(struct symtable *);

extern PyObject *_Py_MaybeMangle(PyObject *privateobj, PySTEntryObject *ste, PyObject *name);
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);

/* Flags for def-use information */

#define DEF_GLOBAL 1             /* global stmt */
#define DEF_LOCAL 2              /* assignment in code block */
#define DEF_PARAM (2<<1)         /* formal parameter */
#define DEF_NONLOCAL (2<<2)      /* nonlocal stmt */
#define USE (2<<3)               /* name is used */
#define DEF_FREE (2<<4)          /* name used but not defined in nested block */
#define DEF_FREE_CLASS (2<<5)    /* free variable from class's method */
#define DEF_IMPORT (2<<6)        /* assignment occurred via import */
#define DEF_ANNOT (2<<7)         /* this name is annotated */
#define DEF_COMP_ITER (2<<8)     /* this name is a comprehension iteration variable */
#define DEF_TYPE_PARAM (2<<9)    /* this name is a type parameter */
#define DEF_COMP_CELL (2<<10)    /* this name is a cell in an inlined comprehension */

#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT)

/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol
   table.  GLOBAL is returned from PyST_GetScope() for either of them.
   It is stored in ste_symbols at bits 13-16.
*/
#define SCOPE_OFFSET 12
#define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL)

#define LOCAL 1
#define GLOBAL_EXPLICIT 2
#define GLOBAL_IMPLICIT 3
#define FREE 4
#define CELL 5

#define GENERATOR 1
#define GENERATOR_EXPRESSION 2

// Used by symtablemodule.c
extern struct symtable* _Py_SymtableStringObjectFlags(
    const char *str,
    PyObject *filename,
    int start,
    PyCompilerFlags *flags);

int _PyFuture_FromAST(
    struct _mod * mod,
    PyObject *filename,
    _PyFutureFeatures* futures);

#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_SYMTABLE_H */