PIPS
|
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "ri-util.h"
#include "workspace-util.h"
#include "c_parser_private.h"
#include "c_syntax.h"
#include "text-util.h"
#include "prettyprint.h"
#include "cyacc.h"
#include "resources.h"
#include "database.h"
#include "misc.h"
#include "properties.h"
Go to the source code of this file.
Macros | |
#define | FILE_LOCAL_USER_DEFINED_TYPES_P (true) |
Functions | |
void | c_parser_user_warning_alist (const char *pips_func, const char *pips_file, const int pips_line, const char *format, va_list *args) |
Compared to pips_user_warning(), the name of the calling function is lost, which does not help maintenance but generates more user-friendly messages. More... | |
void | c_parser_user_warning_func (const char *pips_func, const char *pips_file, const int pips_line, const char *format,...) |
static void | set_current_dummy_parameter_number (int n) |
void | reset_current_dummy_parameter_number () |
static int | get_current_dummy_parameter_number (void) |
entity | get_top_level_entity () |
void | MakeTopLevelEntity () |
void | init_c_areas () |
In C we have 4 areas. More... | |
entity | make_C_constant_entity (string name, tag bt, size_t size) |
void | init_c_implicit_variables (entity m) |
entity | get_current_compilation_unit_entity () |
void | MakeCurrentCompilationUnitEntity (const char *name) |
A compilation unit is also considered as a module. More... | |
void | ResetCurrentCompilationUnitEntity (bool is_compilation_unit_parser) |
expression | MakeFunctionExpression (expression e, list le) |
e is now owned by returned expression and must not be used any longer More... | |
expression | MemberDerivedIdentifierToExpression (type t, string m) |
expression | MemberIdentifierToExpression (expression e, string m) |
expression | IdentifierToExpression (string s) |
expression | MakeArrayExpression (expression exp, list lexp) |
FI: this function is called for a bracketed comma expression. More... | |
entity | FindEntityFromLocalName (string name) |
entity | FindOrCreateEntityFromLocalNameAndPrefix (string name, string prefix, bool is_external) |
entity | FindOrCreateEntityFromLocalNameAndPrefixAndScope (string name, string prefix, string scope, bool is_external) |
entity | FindEntityFromLocalNameAndPrefixAndScope (string name, string prefix, string scope) |
The parameter "scope" is potentially destroyed. More... | |
entity | FindEntityFromLocalNameAndPrefix (string name, string prefix) |
entity | CreateEntityFromLocalNameAndPrefix (string name, string prefix, bool is_external) |
bool | CheckExternList () |
void | c_parser_put_new_typedef (const char *name) |
Store named type for the lexical analyzer, which has to decide if a character string is the name of a type or the name of a variable. More... | |
void | put_new_typedef (const char *name) |
This function is used by libraries "step"* and "task_parallelization". More... | |
entity | FindOrCreateCurrentEntity (string name, stack ContextStack __attribute__((__unused__)), stack FormalStack, stack FunctionStack, bool is_external) |
This function finds or creates the current entity. More... | |
void | UpdateParenEntity (entity e, list lq) |
dimension | MakeDimension (list le, list ql) |
type | UpdateFinalPointer (type pt, type t) |
void | UpdatePointerEntity (entity e, type pt, list lq) |
void | UpdateArrayEntity (entity e, list lq, list le) |
entity | RenameFunctionEntity (entity oe) |
Rename function oe if necessary. More... | |
void | UpdateFunctionEntity (entity oe, list la) |
The parser has found out that an entity is a function and partially sets its type. More... | |
type | UpdateType (type t1, type t2) |
This function replaces the undefined field in t1 by t2. More... | |
static bool | referencenodeclfilter (reference r) |
static bool | callnodeclfilter (call c) |
static void | nodecl_p (entity __attribute__((unused)) module, statement stat) |
void | CCompilationUnitMemoryAllocations (entity module, bool first_p) |
This function allocates the memory to the Current Compilation Unit. More... | |
void | CCompilationUnitMemoryAllocation (entity module) |
void | CCompilationUnitMemoryReallocation (entity module) |
void | CModuleMemoryAllocation (entity module) |
This function is for MemoryAllocation for Module of C programs. More... | |
void | UseDummyArguments (entity f) |
If f has regular formal parameters, destroy them. More... | |
void | UseFormalArguments (entity f) |
If f has dummy formal parameters, replace them by standard formal parameters. More... | |
void | RemoveDummyArguments (entity f, list refs) |
To chase formals in type declarations. More... | |
void | SubstituteDummyParameters (entity f, list el) |
void | CreateReturnEntity (entity f) |
If necessary, create the return entity, which is a hidden variable used in PIPS internal representation to carry the value returned by a function. More... | |
void | UpdateEntity2 (entity f, stack FormalStack __attribute__((__unused__)), stack OffsetStack __attribute__((__unused__))) |
A subset of UpdateEntity, used when the function entity is already more defined because the return type is implicit. More... | |
void | UpdateEntity (entity e, stack ContextStack, stack FormalStack, stack FunctionStack, stack OffsetStack, bool is_external, bool is_declaration) |
Update the entity with final type, storage and initial value; and also (sometimes?) declare it at the module level. More... | |
void | UpdateEntities (list le, stack ContextStack, stack FormalStack, stack FunctionStack, stack OffsetStack, bool is_external, bool is_declaration) |
static entity | CleanUpEntity (entity e) |
if returned entity != original entity, e must be freed, otherwise an invalid entity is still tabulated More... | |
void | CleanUpEntities (list le) |
void | UpdateAbstractEntity (entity e, stack ContextStack) |
void | RemoveFromExterns (entity e) |
void | AddToExterns (entity e, entity mod) |
void | AddToDeclarations (entity e, entity mod) |
FI: check the difference with AddEntityToDeclarations() More... | |
void | UpdateDerivedEntity (list ld, entity e, stack ContextStack) |
list | TakeDerivedEntities (list le) |
void | UpdateDerivedEntities (list ld, list le, stack ContextStack) |
void | InitializeEnumMemberValues (list lem) |
entity | MakeDerivedEntity (string name, list members, bool is_external, int i) |
storage | MakeStorageRam (entity v, bool is_external, bool is_static) |
The storage part should not be called twice when reparsing compilation unit. More... | |
string | CreateMemberScope (string derived, bool is_external) |
value | MakeEnumeratorInitialValue (list enum_list, int counter) |
int | ComputeAreaOffset (entity a, entity v) |
list | MakeParameterList (list l1, list l2, stack FunctionStack) |
parameter | FindParameterEntity (string s, int offset, list l) |
void | AddToCalledModules (entity e) |
void | NStackPop (stack s, int n) |
Pop n times the stack s. More... | |
void | StackPop (stack OffsetStack) |
The OffsetStack is poped n times, where n is the number of formal arguments of the actual function. More... | |
void | StackPush (stack OffsetStack) |
The OffsetStack is pushed incrementally. More... | |
void | set_entity_initial (entity v, expression nie) |
Be careful if the initial value has already been set. More... | |
bool | check_declaration_uniqueness_p (statement s) |
This is designed for standard C functions, not for compilation units. More... | |
list | insert_qualifier (list ql, qualifier nq) |
if qualifier "nq" does not already belong to qualifier list "ql", add it in front of the list. More... | |
void | reset_preprocessor_line_analysis (void) |
int | analyze_preprocessor_line (string line, int C_line_number) |
Analyze information about user line number provided by the C preprocessor and by PIPS file splitter and return the C line number in the source file. More... | |
Variables | |
static int | current_dummy_parameter_number =0 |
The data structure to tackle the memory allocation problem due to reparsing of compilation unit. More... | |
static bool | declarationerror_p |
static bool | buffer_initialized_p = false |
#define FILE_LOCAL_USER_DEFINED_TYPES_P (true) |
void AddToCalledModules | ( | entity | e | ) |
Definition at line 3413 of file util.c.
References CalledModules, CONS, entity_local_name(), intrinsic_entity_p(), MAP, pips_debug, strdup(), and STRING.
Referenced by MakeFunctionExpression().
FI: check the difference with AddEntityToDeclarations()
Here, the declared entity is added to the module declarations only.
mod | od |
Definition at line 2924 of file util.c.
References code_declarations, CONS, ENTITY, entity_initial, entity_name, entity_user_name(), gen_in_list_p(), gen_nconc(), NIL, pips_debug, and value_code.
Referenced by CreateReturnEntity(), MakeFunctionExpression(), MakeParameterList(), and UpdateEntity().
mod | od |
Definition at line 2898 of file util.c.
References code_externs, CONS, ENTITY, entity_domain, entity_domain_number, entity_initial, entity_list_p(), entity_user_name(), gen_in_list_p(), gen_nconc(), NIL, pips_assert, pips_debug, and value_code.
Referenced by FindOrCreateCurrentEntity(), and UpdateEntity().
Analyze information about user line number provided by the C preprocessor and by PIPS file splitter and return the C line number in the source file.
We do not have specs and must evolve with C preprocessors such as cpp.
We assume that information about the lines in the included files is only provided for compilation unit.
We assume that information about user line in a module is always related to the user source file, and that the first line has been generated by PIPS file splitter with syntax "x nnn", with no information about the user source file name.
See examples line00.c, line01.c, line02.c and line03.c. And do not forget cominc02 for the compilation unit case. And missing01.c for synthesized code.
More examples needed for include lines placed within a function body, with C code or preprocessor definitions: line04 and line05.
the C preprocessors, such as cpp, and PIPS file splitter provide line information in pragmas which are not line pragmas.
Not too sure about C source code generated by PIPS by passes initializer, clone, outlining, inlinging...
strstr(line, "#line")==line &&
Not to sure about this case
The next lines have been imported from an included file. Ignore information about include files, preserve the current C_line_number.
Not to sure about this case: internal error?
line | ine |
C_line_number | _line_number |
Definition at line 3617 of file util.c.
References buffer, buffer_initialized_p, C_line_increment, C_line_number, compilation_unit_parser_is_running_p, CParserError(), line, pips_debug, pips_user_warning, remove_LFs_from_C_comment(), and same_string_p.
void c_parser_put_new_typedef | ( | const char * | name | ) |
Store named type for the lexical analyzer, which has to decide if a character string is the name of a type or the name of a variable.
See is_c_parser_keyword_typedef() in clex.l
name | ame |
Definition at line 1060 of file util.c.
References concatenate(), get_c_parser_current_scope(), hash_put(), keyword_typedef_table, pips_debug, same_string_p, strdup(), string_undefined, and TK_NAMED_TYPE.
Referenced by FindOrCreateCurrentEntity().
void c_parser_user_warning_alist | ( | const char * | pips_func, |
const char * | pips_file, | ||
const int | pips_line, | ||
const char * | format, | ||
va_list * | args | ||
) |
Compared to pips_user_warning(), the name of the calling function is lost, which does not help maintenance but generates more user-friendly messages.
util.c
Parser warning on C code synthesized by PIPS
pips_func | ips_func |
pips_file | ips_file |
pips_line | ips_line |
format | ormat |
args | rgs |
Definition at line 60 of file util.c.
References asprintf, c_lineno, free(), get_bool_property(), get_c_parser_current_input_file_name(), get_c_parser_current_user_input_file_name(), get_current_C_line_number(), get_pips_current_module(), get_pips_current_pass_name(), get_previous_C_line_number(), get_previous_c_lineno(), pips_assert, pips_log_alist(), safe_get_line_interval(), and warning_log.
Referenced by c_parser_user_warning_func().
void c_parser_user_warning_func | ( | const char * | pips_func, |
const char * | pips_file, | ||
const int | pips_line, | ||
const char * | format, | ||
... | |||
) |
pips_func | ips_func |
pips_file | ips_file |
pips_line | ips_line |
format | ormat |
Definition at line 112 of file util.c.
References c_parser_user_warning_alist().
Here, there is no known dummy parameter entity... unless we build a default dummy parameter, using unique names such as v1, v2, v3,..
Definition at line 1822 of file util.c.
References c_parser_user_warning, call_arguments, call_function, CAR, CONS, cp, DEFAULT_INTEGER_TYPE_SIZE, ENDP, ENTITY, entity_declarations, entity_initial, entity_type, entity_user_name(), EXPRESSION, expression_to_user_type(), free_type(), gen_in_list_p(), gen_nconc(), get_current_compilation_unit_entity(), get_current_module_entity(), get_current_module_name(), is_basic_int, is_type_functional, is_type_variable, list_undefined, make_basic(), make_dummy_unknown(), make_functional(), make_mode_value(), make_parameter(), make_type(), make_variable(), NIL, PARAMETER, POP, type_undefined, and value_code_p.
Referenced by nodecl_p().
void CCompilationUnitMemoryAllocation | ( | entity | module | ) |
module | odule |
Definition at line 1967 of file util.c.
References CCompilationUnitMemoryAllocations(), and module.
Referenced by ResetCurrentCompilationUnitEntity().
This function allocates the memory to the Current Compilation Unit.
Check that all variables used or defined are declared
Allocate variables
We are in trouble
check the type of variable here to avoid conflicting declarations
The C parser is no longer active when this warning is emitted. It is not possible to rely on its line numbers.
No way to know if a pointer is initialized or not
This may happen with variables such as "__morecore" which is a functional pointer to a malloc like function and which is declared in a header file.
It may or not be an error, depending on conflicting initializations or not. It seems better to leave this for gcc or clang to decide before running PIPS.
Do not modify the initial allocation
Do not allocate the memory for external variables: Set the offset of ram -2 which signifies UNKNOWN offset
module | odule |
first_p | irst_p |
Definition at line 1881 of file util.c.
References add_C_variable_to_area(), area_size, CAR, CDR, code_externs, DYNAMIC_RAM_OFFSET, ENDP, ENTITY, entity_declarations, entity_initial, entity_local_name(), entity_storage, entity_type, entity_undefined, entity_user_name(), gen_in_list_p(), module, ModuleStatement, nodecl_p(), pips_debug, pips_internal_error, pips_user_warning, place_holder_variable_p(), ram_offset, ram_section, storage_ram, storage_ram_p, top_level_entity_p(), type_area, type_variable_p, ultimate_type(), UNDEFINED_RAM_OFFSET, UNKNOWN_RAM_OFFSET, value_code, value_code_p, and value_unknown_p.
Referenced by CCompilationUnitMemoryAllocation(), and CCompilationUnitMemoryReallocation().
void CCompilationUnitMemoryReallocation | ( | entity | module | ) |
module | odule |
Definition at line 1972 of file util.c.
References CCompilationUnitMemoryAllocations(), and module.
Referenced by ResetCurrentCompilationUnitEntity().
This is designed for standard C functions, not for compilation units.
e must be a function: they can be declared several times
Definition at line 3540 of file util.c.
References ENTITY, entity_name, entity_type, FOREACH, gen_occurences(), pips_debug, pips_internal_error, statement_declarations, type_functional_p, and ultimate_type().
Referenced by actual_c_parser().
bool CheckExternList | ( | void | ) |
Definition at line 1025 of file util.c.
References cons::car, CAR, cons::cdr, code_externs, code_undefined_p, ENTITY, entity_initial, entity_list_p(), entity_name, entity_undefined_p, f(), gen_last(), gen_length(), get_current_module_entity(), pips_assert, pips_debug, value_code, and value_undefined_p.
void CleanUpEntities | ( | list | le | ) |
update entity in module declarations
Update storage area
Update entity in current entity list
Remove entity from potentially removable externs and add it the new entity
Apparently, formal parameters may have been declared for such an entity and PIPS code dumps when the symbol table is written.
See decl62.c and decl63.c
le | e |
Definition at line 2772 of file util.c.
References area_layout, CAR, CleanUpEntity(), code_declarations, CONS, ENDP, ENTITY, entity_initial, entity_storage, entity_type, gen_remove(), get_current_module_entity(), list_undefined, pips_internal_error, POP, ram_section, removable_extern_entities, storage_ram, storage_ram_p, type_area, and value_code.
if returned entity != original entity, e must be freed, otherwise an invalid entity is still tabulated
The variable name is wrong
Entity e should be removed... but it's pretty dangerous.
let the caller do it
Definition at line 2745 of file util.c.
References copy_storage(), copy_type(), copy_value(), entity_initial, entity_local_name(), entity_module_name(), entity_name, entity_storage, entity_type, FILE_SEP_STRING, FindOrCreateEntity(), pips_assert, pips_debug, static_module_name_p(), type_functional_p, and type_variable_p.
Referenced by CleanUpEntities().
void CModuleMemoryAllocation | ( | entity | module | ) |
This function is for MemoryAllocation for Module of C programs.
module | odule |
Definition at line 1979 of file util.c.
References add_C_variable_to_area(), area_size, CAR, CDR, code_externs, DYNAMIC_RAM_OFFSET, ENDP, ENTITY, entity_declarations, entity_initial, entity_storage, entity_type, entity_undefined, gen_in_list_p(), module, ModuleStatement, nodecl_p(), pips_debug, place_holder_variable_p(), ram_offset, ram_section, StackArea, storage_formal_p, storage_ram, storage_ram_p, type_area, type_variable_p, UNDEFINED_RAM_OFFSET, UNKNOWN_RAM_OFFSET, and value_code.
Referenced by ResetCurrentModule().
Update the size and layout of the area aa. This function is called too earlier, we may not have the size of v. To be changed !!!
FI: who wrote this? when should the offsets be computed? how do we deal with scoping?
area_size(aa) = offset + 0;
Definition at line 3324 of file util.c.
References area_layout, area_size, CONS, CSafeSizeOfArray(), ENTITY, entity_type, gen_nconc(), NIL, offset, pips_assert, and type_area.
We have to know the context:
The entity is created local to the file. For instance, derived and user-named types. This makes type checking more difficult as types such as FILE * vary from C file to C file, but this is consistent with the C standard and the behavior of production compilers: the same local name can be used for two different types in two different files.
These types are created globally, which makes type checking much easier but forbid homonym types in different files.
name | ame |
prefix | refix |
is_external | s_external |
Definition at line 962 of file util.c.
References asprintf, compilation_unit_name, entity_name, entity_undefined, FILE_LOCAL_USER_DEFINED_TYPES_P, FindOrCreateEntity(), free(), get_current_module_entity(), get_current_module_name(), GetScope(), is_external, local_name(), pips_assert, pips_debug, prefix, scope_to_block_scope(), static_module_p(), string_block_scope_p(), and TOP_LEVEL_MODULE_NAME.
Referenced by FindOrCreateCurrentEntity(), FindOrCreateEntityFromLocalNameAndPrefix(), FindOrCreateEntityFromLocalNameAndPrefixAndScope(), and MakeDerivedEntity().
We have to know the context :
The name of the struct/union is then added to the field entity name, with the MEMBER_SEP_STRING
ompilation_unit_name,
derived | erived |
is_external | s_external |
Definition at line 3261 of file util.c.
References compilation_unit_name, concatenate(), get_current_module_entity(), get_current_module_name(), GetScope(), is_external, MEMBER_SEP_STRING, MODULE_SEP_STRING, pips_assert, pips_debug, scope_to_block_scope(), static_module_p(), strdup(), string_block_scope_p(), and string_undefined.
void CreateReturnEntity | ( | entity | f | ) |
If necessary, create the return entity, which is a hidden variable used in PIPS internal representation to carry the value returned by a function.
c_parser_user_warning() should not be called as it may be some times too late to get significant line numbers.
Create the return value
set the language
Definition at line 2382 of file util.c.
References AddToDeclarations(), c_parser_user_warning, copy_type(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_user_name(), f(), FindOrCreateEntity(), functional_result, make_storage_return(), make_value_unknown(), pips_debug, pips_internal_error, type_functional, type_functional_p, type_undefined_p, type_void_p, and ultimate_type().
Referenced by UpdateEntity(), and UpdateEntity2().
Find an entity from its local name. We have to look for all possible prefixes, which are: blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX
How about multiple results ? The order of prefixes ?
Is it a static function? It must have been parsed in the compilation unit
name | ame |
Definition at line 778 of file util.c.
References c_parser_user_warning, compilation_unit_name, concatenate(), entity_undefined, entity_undefined_p, ENUM_PREFIX, FindEntity(), FindEntityFromLocalNameAndPrefix(), free(), prefixes, strdup(), STRUCT_PREFIX, TYPEDEF_PREFIX, and UNION_PREFIX.
Referenced by IdentifierToExpression().
Find an entity from its local name and prefix. We have to look from the most enclosing scope.
Possible name combinations and the looking order:
PREFIXname or MODULE:BLOCK
PREFIXnamewith 5 possible prefixes: blank, STRUCT_PREFIX, UNION_PREFIX, ENUM_PREFIX, TYPEDEF_PREFIX
"!" is FILE_SEP_STRING and ":" is MODULE_SEP_STRING and "`" is BLOCK_SEP_STRING
First, look up the surrounding scopes
Is it a formal parameter not yet converted in the function frame?
Should we change the current dummy parameter number?
Is it a static variable declared in the compilation unit?
we have an issue there : a static function will be declared FILE!MODULE:FILE!name, but a static variable will be declared FILE!MODULE:name so try both ... CleanupEntity has been fixed to remove buggy situations ...
Is it a global variable declared in the compilation unit?
Is it a local type used within a function declaration?
It may be a parser error or a normal behavior when an entity is used before it is defined as, for example, a struct in a typedef: typedef struct foo foo;
CParserError("Variable appears to be undefined\n");
name | ame |
prefix | refix |
Definition at line 877 of file util.c.
References compilation_unit_name, concatenate(), DUMMY_PARAMETER_PREFIX, entity_domain, entity_name, entity_undefined, entity_undefined_p, FindEntityFromLocalNameAndPrefixAndScope(), free(), gen_find_tabulated(), get_current_C_line_number(), get_current_dummy_parameter_number(), GetParentScope(), GetScope(), int2a(), MODULE_SEP_STRING, pips_assert, pips_debug, prefix, scope_to_block_scope(), ScopeStackSize(), strdup(), string_block_scope_p(), string_undefined, and TOP_LEVEL_MODULE_NAME.
Referenced by FindEntityFromLocalName(), FindOrCreateEntityFromLocalNameAndPrefix(), and FindOrCreateEntityFromLocalNameAndPrefixAndScope().
The parameter "scope" is potentially destroyed.
Add block scope case here
ompilation_unit_name,
return values are not C variables... but they are entities.
name | ame |
prefix | refix |
scope | cope |
Definition at line 850 of file util.c.
References concatenate(), entity_domain, entity_storage, entity_undefined, entity_undefined_p, gen_find_tabulated(), get_current_module_entity(), get_current_module_name(), MODULE_SEP_STRING, pop_block_scope(), prefix, static_module_p(), storage_return_p, storage_undefined_p, and string_undefined.
Referenced by FindEntityFromLocalNameAndPrefix().
entity FindOrCreateCurrentEntity | ( | string | name, |
stack ContextStack | __attribute__(__unused__), | ||
stack | FormalStack, | ||
stack | FunctionStack, | ||
bool | is_external | ||
) |
This function finds or creates the current entity.
Only entity full name is created, other fields such as type, storage and initial value are undefined.
function is only used for formal variables
Tell the lexer about the new type names : add to keyword_typedef_table. Because of scopes, different types can have the same name...
Prefix for the current struct: use full_scope
Maybe it would have been better to push "external" in the context
&& strstr(scope,TOP_LEVEL_MODULE_NAME) != NULL
This entity is declared in a compilation unit with keyword EXTERN. Add it to the storage of the compilation unit to help code prettyprint unless if has already been declared earlier in the current compilation unit. See C_syntax/global_extern.c
ent has not been declared earlier
A global entity may already have been seen in a previous compilation unit and so it is already typed but still must be declared as extern. See test case C_syntax/declarations.c
The bad news is: function are not yet fully typed when this is executed and their type is "variable", the future result type; hence, they are declared "extern" no matter what... Do we want to clean up the code_externs list later since the extern keyword is useless for functions? No other simple solution found...
FI: The test above may be stronger than the previous one, but I'm pretty conservative when dealing with the parser.
This variable is declared extern within a function body.
Impossible: this is not detected here
This entity may have already been declared external but is redeclared inside the same module. See C_syntax/global_extern.c
Formal parameter for a function declaration or for a function definition or for a pointer to a function or for a functional typedef
It is too early to define formal parameters. Let's start with dummy parameters
scope = NULL, not extern/typedef/struct/union/enum
This is a variable/function declared outside any module's body
If it is a function, we'd like to increase its name. If it's a variable, we'd like not to increase its name with the compilation unit name. But we do not have much information here to make the decision. Let's assume it's a function and postpone to UpdateEntity()
Depending on the type, we should or not introduce a MODULE_SEP_STRING, but the type is still not fully known. Wait for UpdateFunctionEntity().
We may have to remove it from the extern list: C_syntax/global_extern01.c
code_externs(value_code(entity_initial(com_unit))) =
arguments_rm_entity(el, ent);
This is a variable/function declared inside a module's body: add block scope here Attention, the scope of a function declared in module is the module, not global.
The module name is unambiguous because it is used by pipdbm
FI: why is ct not exploited? Because the information is later destroyed. I guess it is related to the type_stack stored in the entity_ initial field.
entity_type(ent) = copy_type(ct);
Definition at line 1088 of file util.c.
References AddToExterns(), asprintf, basic_pointer_p, BLOCK_SEP_CHAR, c_parser_context_scope, c_parser_context_static, c_parser_context_type, c_parser_context_typedef, c_parser_put_new_typedef(), code_externs, code_undefined_p, compilation_unit_entity_p(), compilation_unit_name, CreateEntityFromLocalNameAndPrefix(), DUMMY_PARAMETER_PREFIX, empty_scope(), entity_domain, entity_domain_number, entity_initial, entity_is_argument_p(), entity_list_p(), entity_name, entity_type, entity_undefined, entity_undefined_p, entity_user_name(), f(), FindOrCreateEntity(), FormalStack, free(), FunctionStack, gen_in_list_p(), get_current_compilation_unit_entity(), get_current_dummy_parameter_number(), get_current_module_entity(), get_current_module_name(), get_from_entity_type_stack_table(), GetContext(), ifdebug, intrinsic_entity_p(), is_external, list_to_string(), local_name(), member_entity_p(), module_name(), NIL, pips_assert, pips_debug, RemoveFromExterns(), safe_c_words_entity(), same_string_p, scope_to_block_scope(), set_current_dummy_parameter_number(), stack_empty_p(), stack_head(), stack_undefined_p, static_module_p(), strdup(), string_block_scope_p(), TOP_LEVEL_MODULE_NAME, type_functional_p, type_undefined, type_undefined_p, type_variable, type_variable_p, typedef_entity_p(), TYPEDEF_PREFIX, value_code, value_undefined_p, and variable_basic.
name | ame |
prefix | refix |
is_external | s_external |
Definition at line 811 of file util.c.
References CreateEntityFromLocalNameAndPrefix(), entity_undefined, FindEntityFromLocalNameAndPrefix(), is_external, and prefix.
entity FindOrCreateEntityFromLocalNameAndPrefixAndScope | ( | string | name, |
string | prefix, | ||
string | scope, | ||
bool | is_external | ||
) |
The current scope will be automatically added
name | ame |
prefix | refix |
scope | cope |
is_external | s_external |
Definition at line 820 of file util.c.
References concatenate(), CreateEntityFromLocalNameAndPrefix(), entity_name, entity_undefined, entity_undefined_p, FindEntityFromLocalNameAndPrefix(), free(), is_external, pips_assert, pips_debug, pop_block_scope(), prefix, strdup(), and string_block_scope_p().
to be verified in C, when by reference, when by value
offset | ffset |
Definition at line 3384 of file util.c.
References ENTITY, entity_storage, entity_type, entity_user_name(), f(), FOREACH, formal_offset, make_dummy_identifier(), make_mode_value(), make_parameter(), offset, parameter_undefined, storage_formal, and storage_formal_p.
Referenced by MakeParameterList().
entity get_current_compilation_unit_entity | ( | void | ) |
Definition at line 320 of file util.c.
References compilation_unit_name, FindOrCreateEntity(), and TOP_LEVEL_MODULE_NAME.
Referenced by callnodeclfilter(), FindOrCreateCurrentEntity(), MakeFunctionExpression(), MakeStorageRam(), and referencenodeclfilter().
|
static |
Definition at line 147 of file util.c.
References current_dummy_parameter_number.
Referenced by FindEntityFromLocalNameAndPrefix(), and FindOrCreateCurrentEntity().
entity get_top_level_entity | ( | void | ) |
Definition at line 152 of file util.c.
References FindOrCreateEntity(), and TOP_LEVEL_MODULE_NAME.
Referenced by MakeStorageRam(), and step_parameter().
expression IdentifierToExpression | ( | string | s | ) |
Could this be non declared variables ?
This identifier has not been passed by the parser. It is probably a function call => try this case now and complete others later. The scope of this function is global
This may be a call or a reference in case a functional pointer is initialized
eturn MakeNullaryCall(ent);
FI: This may happen when a variable is used to initialize another variable within the same declaration statement: see decl29.c. This might not be a general fix as the type could be functional: to be checked. But setting up type earlier would require a huge change in the parser rules. Unless FindOrCreateCurrentEntity() could do a better job? But the information added is later destroyed by the parser.
Generate a call to an enum member
Definition at line 650 of file util.c.
References CParserError(), entity_initial, entity_storage, entity_type, entity_undefined_p, exp, expression_undefined, FindEntityFromLocalName(), FindOrCreateEntity(), is_type_functional, is_type_variable, is_value_code, make_call(), make_code(), make_expression(), make_functional(), make_language_c(), make_reference(), make_sequence(), make_storage_rom(), make_syntax_call(), make_syntax_reference(), make_type_functional(), make_type_unknown(), make_value(), NIL, normalized_undefined, pips_debug, safe_entity_name(), strdup(), TOP_LEVEL_MODULE_NAME, type_tag, type_undefined_p, value_symbolic_p, and value_undefined_p.
Referenced by MemberDerivedIdentifierToExpression().
void init_c_areas | ( | void | ) |
In C we have 4 areas.
Create a hidden pointer in the heap area to modelize malloc and free effects and to keep track of the corresponding abstract state.
FI: I use a complex type to avoid seeing this variable in the transformers and preconditions... OK, it's not a clean way to do it. Should we create another area to allocate this abstract heap state?
FI: I keep the code below, because it may turn useful again if context-insensitive address values must be generated.
This is because of the reparsing of the compilation unit The area is set to zero and all the declarations are overrided and the memory is reallocated The area is reset to only when it is called by same compilation unit twice. The code is dangerous hence it is commented. Please have a look
if( get_current_compilation_unit_entity() == get_current_module_entity() && (get_current_compilation_unit_entity() == previouscompilationunit)) area_size(type_area(entity_type(msae))) = 0;
if( get_current_compilation_unit_entity() == get_current_module_entity() && (get_current_compilation_unit_entity() == previouscompilationunit)) area_size(type_area(entity_type(gsae))) = previoussizeofGlobalArea ;
Definition at line 186 of file util.c.
References ABSTRACT_LOCATION, AddEntityToDeclarations(), compilation_unit_name, DYNAMIC_AREA_LOCAL_NAME, DynamicArea, ENTITY_DYNAMIC_AREA, ENTITY_HEAP_AREA, entity_initial, entity_kind, ENTITY_STACK_AREA, ENTITY_STATIC_AREA, entity_storage, entity_type, FindOrCreateEntity(), get_current_module_entity(), get_current_module_name(), HEAP_AREA_LOCAL_NAME, HeapArea, is_type_area, make_area(), make_storage_rom(), make_type(), make_value_unknown(), NIL, STACK_AREA_LOCAL_NAME, StackArea, STATIC_AREA_LOCAL_NAME, StaticArea, and TOP_LEVEL_MODULE_NAME.
Referenced by MakeCurrentCompilationUnitEntity(), and MakeCurrentModule().
void init_c_implicit_variables | ( | entity | m | ) |
Function name variable function and FUNCTION
Should be static, but not compatible with FREIA inlining.
It is not clear if the encoding is correct or not. It may also be correct but not supported. This could be checked by computing the preconditions for strings and/or by adding initial values to the symbol table display.
Since the declarations are not added to a statement_declarations field, they are not going to be prettyprinted.
Definition at line 277 of file util.c.
References AddEntityToDeclarations(), concatenate(), DynamicArea, entity_initial, entity_local_name(), entity_storage, entity_type, entity_user_name(), FindOrCreateEntity(), free(), IMPLICIT_VARIABLE_NAME_1, IMPLICIT_VARIABLE_NAME_2, is_basic_string, make_C_constant_entity(), make_call_expression(), make_char_array_type(), make_ram(), make_storage_ram(), make_value_expression(), NIL, strdup(), and UNKNOWN_RAM_OFFSET.
Referenced by MakeCurrentModule().
void InitializeEnumMemberValues | ( | list | lem | ) |
The expression evaluation may have been delayed
lem | em |
Definition at line 3104 of file util.c.
References CAR, constant_int, constant_int_p, constant_unknown_p, ENDP, ENTITY, entity_initial, EvalExpression(), expression_undefined_p, int_to_expression(), is_constant_int, list_undefined, make_constant(), make_symbolic(), make_value_symbolic(), pips_assert, POP, symbolic_consistent_p(), symbolic_constant, symbolic_expression, value_constant, value_constant_p, value_symbolic, and value_undefined_p.
if qualifier "nq" does not already belong to qualifier list "ql", add it in front of the list.
The list is probably reversed somewhere else... for instance by the parsing grammar rules
FI: either the context was not stacked or it was not used and emptied...
ql | l |
nq | q |
Definition at line 3567 of file util.c.
References c_parser_user_warning, CONS, FOREACH, QUALIFIER, qualifier_equal_p(), and qualifier_to_string().
name | ame |
bt | t |
size | ize |
Definition at line 269 of file util.c.
References c_parser_error(), and make_C_or_Fortran_constant_entity().
Referenced by init_c_implicit_variables().
expression MakeArrayExpression | ( | expression | exp, |
list | lexp | ||
) |
FI: this function is called for a bracketed comma expression.
The two arguments are (should be) reused within the returned expression
There are two cases:
FI: Memory leak with exp?
FI: we might have preexisting subscript? No, in this context, only one index due to lack of type information?
exp | xp |
lexp | exp |
Definition at line 713 of file util.c.
References CDR, CONS, ENDP, exp, EXPRESSION, expression_syntax, expression_undefined, gen_nconc(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, lexp, make_expression(), make_reference(), make_subscript(), make_syntax_subscript(), MakeCommaExpression(), NIL, normalized_undefined, pips_debug, pips_internal_error, reference_indices, reference_to_expression(), reference_variable, syntax_reference, and syntax_tag.
void MakeCurrentCompilationUnitEntity | ( | const char * | name | ) |
A compilation unit is also considered as a module.
value v = entity_initial(e);
if(value_code_p(v)) {
code c = value_code(v);
language l = code_language(c);
if(language_unknown_p(l))
code_language(c) = make_language_c();
else if(language_fortran_p(l) || language_fortran95_p(l))
pips_internal_error("A compilation unit should have language \"C".
");
}
else
pips_internal_error("A compilation unit should have value \"code".
");
name | ame |
Definition at line 328 of file util.c.
References init_c_areas(), MakeCompilationUnitEntity(), pips_debug, and set_current_module_entity().
Referenced by actual_c_parser().
FI: What should the initial value be?
name | ame |
members | embers |
is_external | s_external |
Definition at line 3140 of file util.c.
References AddEntityToDeclarations(), CreateEntityFromLocalNameAndPrefix(), entity_initial, entity_storage, entity_type, entity_undefined, ENUM_PREFIX, get_current_module_entity(), is_external, is_type_enum, is_type_struct, is_type_union, make_storage_rom(), make_type_enum(), make_type_struct(), make_type_union(), make_value_unknown(), STRUCT_PREFIX, UNION_PREFIX, and value_undefined_p.
Take only the first expression of le, do not know why it can be a list ?
use the integer value
If we do this, we cannot restitute the source code
Build a new expression e' == e-1
le | e |
ql | l |
Definition at line 1389 of file util.c.
References CAR, CreateIntrinsic(), dimension_lower, dimension_upper, EXPRESSION, expression_integer_value(), ifdebug, int_to_expression(), intptr_t, make_dimension(), make_unbounded_expression(), MakeBinaryCall(), MINUS_C_OPERATOR_NAME, NIL, pips_debug, and print_expression().
Referenced by UpdateArrayEntity().
The initial value = 0 if this is the first member in the enumerator list else, it is equal to : intial_value(predecessor) + 1
Find the predecessor of the counter-th member
enum_list | num_list |
counter | ounter |
Definition at line 3299 of file util.c.
References constant_int, constant_int_p, ENTITY, entity_initial, gen_nth(), make_constant_int(), make_value_constant(), value_constant, value_constant_p, and value_undefined.
expression MakeFunctionExpression | ( | expression | e, |
list | le | ||
) |
e is now owned by returned expression and must not be used any longer
There are 2 cases:
The first argument corresponds to a function name (an entity).
In this case, we create a normal call expression and the corresponding entity is added to the list of callees.
Must be a pointer to a function
Undeclared functions return int by default
This cannot be checked unless bootstrap typing is improved for varargs intrinsics, mostly IOs.
le | e |
Definition at line 368 of file util.c.
References AddToCalledModules(), AddToDeclarations(), c_parser_user_warning, call_compatible_type_p(), check_C_function_type(), code_declarations, CParserError(), entity_initial, entity_name, entity_type, entity_user_name(), exp, expression_syntax, expression_undefined, f(), free_expression(), functional_result, gen_in_list_p(), gen_length(), get_current_compilation_unit_entity(), get_current_module_entity(), ifdebug, intrinsic_entity_p(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, make_application(), make_call_expression(), make_expression(), make_syntax_application(), MakeIntegerResult(), normalized_undefined, pips_assert, pips_debug, pips_internal_error, print_expressions(), reference_variable, syntax_reference, syntax_tag, type_functional, type_functional_p, type_unknown_p, ultimate_type(), and value_code.
l1 is a list of parameter names and it represents the exact order in the parameter list l2 is a list of entities with their type, storage,... and the order can be different from l1 In addition, l2 can be incomplete wrt l1, so other entities must be created from l1, with default type : scalar integer variable.
We create the list of parameters with the order of l1, and the parameter type and mode are retrieved from l2.
Since the offset of formal argument in l2 can be false, we have to update it here by using l1
s is not declared in l2, create the corresponding entity/ formal variable and add it to the declaration list, because it cannot be added with par_def in l2
l1 | 1 |
l2 | 2 |
FunctionStack | unctionStack |
Definition at line 3348 of file util.c.
References AddToDeclarations(), CONS, DEFAULT_INTEGER_TYPE_SIZE, entity_storage, entity_type, entity_user_name(), FindOrCreateEntity(), FindParameterEntity(), FOREACH, FunctionStack, gen_nconc(), make_basic_int(), make_dummy_identifier(), make_formal(), make_mode_value(), make_parameter(), make_storage_formal(), make_type_variable(), make_variable(), NIL, offset, PARAMETER, parameter_undefined_p, stack_head(), and STRING.
The storage part should not be called twice when reparsing compilation unit.
We assume that double declarations are dealt with someone else
ComputeAreaOffset(StaticArea,e)
he offset must be recomputed lately, when we know for sure the size of the variables
This must be a variable, not a function/typedef/struct/union/enum. The variable is declared outside any function, and hence is global
ComputeAreaOffset(get_top_level_entity(),e)
the offset must be recomputed lately, when we know for sure the size of the variable
Global variable can be declared in many different file
ADD BLOCK SCOPE
ComputeAreaOffset(StaticArea,e)
he offset must be recomputed lately, when we know for sure the size of the variable
ComputeAreaOffset(DynamicArea,e)
the offset must be recomputed lately, when we know for sure the size of the variable
is_external | s_external |
is_static | s_static |
Definition at line 3177 of file util.c.
References area_layout, compilation_unit_name, CONS, DYNAMIC_RAM_OFFSET, DynamicArea, ENTITY, entity_type, FindOrCreateEntity(), gen_in_list_p(), gen_nconc(), get_current_compilation_unit_entity(), get_current_module_entity(), get_top_level_entity(), is_external, make_ram(), make_storage_ram(), NIL, pips_assert, ram_undefined, SizeOfArray(), StackArea, STATIC_AREA_LOCAL_NAME, StaticArea, TOP_LEVEL_MODULE_NAME, type_area, type_variable_p, and UNKNOWN_RAM_OFFSET.
Referenced by UpdateEntity().
void MakeTopLevelEntity | ( | void | ) |
To be economic, group this top-level entity to it areas
FI: this is not convenient if top-level:top-level is a module. All global variables should be declared there. I need also to generate stubs for global variables... Do I? Yes, because the points-to information is computed bottom-up.
Definition at line 157 of file util.c.
References entity_initial, entity_storage, entity_type, FindOrCreateEntity(), make_code(), make_functional(), make_language_c(), make_sequence(), make_storage_rom(), make_type_functional(), make_type_void(), make_value_code(), NIL, strdup(), and TOP_LEVEL_MODULE_NAME.
Referenced by actual_c_parser().
expression MemberDerivedIdentifierToExpression | ( | type | t, |
string | m | ||
) |
Definition at line 463 of file util.c.
References basic_derived, basic_pointer, basic_tag, basic_typedef, concatenate(), CParserError(), entity_type, entity_user_name(), exp, expression_undefined, free(), IdentifierToExpression(), is_basic_derived, is_basic_pointer, is_basic_typedef, MEMBER_SEP_STRING, MemberDerivedIdentifierToExpression(), pips_debug, strdup(), type_variable, type_variable_p, and variable_basic.
Referenced by MemberDerivedIdentifierToExpression(), and MemberIdentifierToExpression().
expression MemberIdentifierToExpression | ( | expression | e, |
string | m | ||
) |
Find the name of struct/union of m from the type of expression e
The first expression must be a pointer
standard integer arithmetic: why bother? why take the CDR?
FI: seems too simple. No need to remember if you sarted with "." or "->"?
Let use the second argument
More types of call must be taken into account: typedef and pointer to functions
User defined call and intrinsics not processed above
A call must have occured somewhere...
An apply must have occured somewhere...
expression exp = subscript_array(syntax_subscript(s));
pips_debug(6,"Subscripting array expression\n");
return MemberIdentifierToExpression(exp, m);
Definition at line 498 of file util.c.
References application_function, b1, b2, basic_bit_p, basic_int_p, basic_of_expression(), basic_pointer, basic_pointer_p, call_arguments, call_function, call_to_functional_type(), CAR, cast_type, CDR, CParserError(), ENTITY_ADDRESS_OF_P, ENTITY_ASSIGN_P, ENTITY_CONDITIONAL_P, ENTITY_DEREFERENCING_P, ENTITY_FIELD_P, ENTITY_MINUS_C_P, entity_name, ENTITY_PLUS_C_P, ENTITY_PLUS_P, ENTITY_POINT_TO_P, ENTITY_POST_DECREMENT_P, ENTITY_POST_INCREMENT_P, ENTITY_PRE_DECREMENT_P, ENTITY_PRE_INCREMENT_P, entity_type, exp, EXPRESSION, expression_syntax, expression_to_type(), expression_undefined, f(), free_basic(), functional_result, ifdebug, is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, MemberDerivedIdentifierToExpression(), MemberIdentifierToExpression(), overloaded_type_p(), pips_debug, pips_internal_error, print_expression(), reference_variable, syntax_application, syntax_call, syntax_cast, syntax_reference, syntax_tag, type_functional, type_functional_p, type_variable, type_variable_p, ultimate_type(), and variable_basic.
Referenced by MemberIdentifierToExpression().
|
static |
Definition at line 1868 of file util.c.
References call_domain, callnodeclfilter(), CParserError(), declarationerror_p, gen_multi_recurse(), gen_null(), reference_domain, and referencenodeclfilter().
Referenced by CCompilationUnitMemoryAllocations(), and CModuleMemoryAllocation().
Pop n times the stack s.
Definition at line 3442 of file util.c.
References gen_free(), and stack_pop().
Referenced by StackPop().
void put_new_typedef | ( | const char * | name | ) |
This function is used by libraries "step"* and "task_parallelization".
FI: I have no idea why it works although the keyword_typedef_table should not be initialized... It could not be made static, because it might be used by any file in the c_syntax library.
name | ame |
Definition at line 1078 of file util.c.
References hash_put(), keyword_typedef_table, pips_debug, strdup(), and TK_NAMED_TYPE.
Referenced by cast_STEP_ARG(), mpi_initialize(), mpi_type_mpi_comm(), mpi_type_mpi_request(), and mpi_type_mpi_status().
There can be a reference to variable of storage return when a function pointer is assigned a function
FI: this may be a bad decision choice to confuse a function and its return value. It might be better to keep storage "rom" systematically for functions and to restore this test.
Definition at line 1790 of file util.c.
References declarationerror_p, entity_declarations, entity_local_name(), entity_name, gen_in_list_p(), get_current_compilation_unit_entity(), get_current_module_entity(), get_current_module_name(), reference_variable, user_log(), and variable_entity_p().
Referenced by nodecl_p().
To chase formals in type declarations.
If f has dummy formal parameters, replace them by standard formal parameters
make a list of formal dummy parameters
Since the compilation order is not known, the standard formal parameters may already exist and they should not be removed.
Update the "dummy" field of the "parameter" data structure
This special case could be ignored and handled like the next one to avoid cut-and-past and/or the definition of a new function.
no dummy naming information available as in foo(int);
FI: just in case?
Remore the dummy formals from f's declaration list (and from the symbol table?) but keep all pointers towards them in the declarations as in "void foo(n,a[n])"
FI: The storage might point to another dummy argument (although it should not)
Let's hope there are no other pointers towards dummy formal parameters
No, there may be occurences due to dependent types.
refs | efs |
Definition at line 2224 of file util.c.
References CAR, code_declarations, CONS, dummy_identifier, dummy_identifier_p, dummy_parameter_entity_p(), ENDP, ENTITY, entity_formal_p(), entity_initial, entity_name, entity_type, entity_undefined_p, f(), find_ith_parameter(), functional_parameters, gen_free_list(), gen_length(), gen_nconc(), gen_remove(), list_undefined, MAP, NIL, PARAMETER, parameter_dummy, pips_assert, pips_debug, POP, REFERENCE, reference_variable, remove_entity_type_stacks(), type_functional, type_functional_p, typedef_entity_p(), update_dummy_parameter(), value_code, value_code_p, value_intrinsic_p, and value_undefined_p.
Referenced by UpdateEntity().
void RemoveFromExterns | ( | entity | e | ) |
This may happen when functional arguments are dealt with
Definition at line 2884 of file util.c.
References c_parser_user_warning, code_externs, entity_initial, entity_undefined_p, f(), gen_remove(), get_current_module_entity(), and value_code.
Referenced by actual_c_parser(), and FindOrCreateCurrentEntity().
Rename function oe if necessary.
The function name may be wrong because not enough information was available when it was created by FindOrCreateCurrentEntity().
oe must be a function and not a pointer to a function
oe should be added to the declarations of the current block
A C function or intrinsics name should include no scope information. But a functional typedef should.
In fact, we'd like to know if it is found before we create it...
FI I do not understand how formal parameters could be declared before
We assume oe is not already part of a declaration list since its formal parameters have been taken care of
oe | e |
Definition at line 1556 of file util.c.
References code_declarations, copy_storage(), copy_type(), copy_value(), empty_string_p(), ENTITY, entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined_p, entity_user_name(), FindEntity(), FindOrCreateEntity(), FOREACH, formal_function, free(), gen_clear_tabulated_element(), get_from_entity_type_stack_table(), is_value_code, list_undefined, local_name_to_scope(), make_code(), make_language_c(), make_sequence(), make_value(), MODULE_SEP, NIL, pips_debug, put_to_entity_type_stack_table(), stack_copy(), storage_formal, storage_formal_p, strdup(), TOP_LEVEL_MODULE_NAME, typedef_entity_p(), value_code, value_undefined_p, and value_unknown_p.
void reset_current_dummy_parameter_number | ( | void | ) |
Definition at line 144 of file util.c.
References current_dummy_parameter_number.
Referenced by actual_c_parser(), and c_parser_error().
void reset_preprocessor_line_analysis | ( | void | ) |
Definition at line 3592 of file util.c.
References buffer_initialized_p.
Referenced by actual_c_parser().
void ResetCurrentCompilationUnitEntity | ( | bool | is_compilation_unit_parser | ) |
Let's redo the memory allocation for variables whose name has changed:-(
reset_entity_type_stack_table();
is_compilation_unit_parser | s_compilation_unit_parser |
Definition at line 349 of file util.c.
References CCompilationUnitMemoryAllocation(), CCompilationUnitMemoryReallocation(), fprint_C_environment(), get_bool_property(), get_current_module_entity(), get_current_module_name(), pips_debug, and reset_current_module_entity().
Referenced by actual_c_parser().
|
static |
Definition at line 139 of file util.c.
References current_dummy_parameter_number, and get_declaration_counter().
Referenced by FindOrCreateCurrentEntity().
void set_entity_initial | ( | entity | v, |
expression | nie | ||
) |
Be careful if the initial value has already been set.
Detect double definitions when possible
Take care of the special case of pointers to functions.
The compilation unit has already been scanned once for declarations. Double definitions are no surprise...
Generate initializations for pointers to functions and arrays of pointers to functions
A pointer to a function already has value code as initial value. We may not even know yet it's a pointer...
nie | ie |
Definition at line 3469 of file util.c.
References asprintf, basic_pointer, c_parser_user_warning, code_initializations, compilation_unit_p(), CONS, entity_initial, entity_name, entity_type, expression_to_string(), free(), free_value(), get_current_module_name(), make_expression_statement(), make_sequence(), make_value_expression(), NIL, pips_internal_error, pips_user_warning, pointer_type_p(), STATEMENT, type_functional_p, type_undefined, type_undefined_p, type_variable, ultimate_type(), value_code, value_code_p, value_expression, value_expression_p, value_tag, value_undefined, value_undefined_p, value_unknown_p, and variable_basic.
Referenced by freia_is_transpose_call().
void StackPop | ( | stack | OffsetStack | ) |
The OffsetStack is poped n times, where n is the number of formal arguments of the actual function.
OffsetStack | ffsetStack |
Definition at line 3450 of file util.c.
References basic_int, NStackPop(), OffsetStack, and stack_head().
void StackPush | ( | stack | OffsetStack | ) |
The OffsetStack is pushed incrementally.
OffsetStack | ffsetStack |
Definition at line 3457 of file util.c.
References basic_int, make_basic_int(), OffsetStack, stack_head(), and stack_push().
The copy could be avoided by substituting v->s with nv->s
Store type information. Might be useless.
Inherit any attribute you can
el | l |
Definition at line 2351 of file util.c.
References CAR, copy_storage(), copy_type(), copy_value(), dummy_parameter_entity_p(), ENDP, ENTITY, ENTITY_, entity_initial, entity_local_name(), entity_storage, entity_type, entity_user_name(), f(), FindOrCreateEntity(), get_from_entity_type_stack_table(), POP, put_to_entity_type_stack_table(), remove_entity_type_stack(), stack_copy(), storage_undefined_p, type_undefined_p, and value_undefined_p.
To simplify debugging
The list is stored there at line 2087 of cyacc.y (5 August 2009)
e->type==entity_domain
lres = gen_nconc(lres,ltmp);
The ltmp lists seem to be somehow shared as shown in ngspice/main.tpips. The previous implementation of the current function generated cyclic lists. The new implementation is incompatible with a proper memory management.
I do not understand what's done in c_syntax/cyacc.y. The trace obtained from C_syntax/ngspice01.c shows that the same derived entities appear several times when dummy structs and unions are embedded as in ngspice01.c
le | e |
Definition at line 3020 of file util.c.
References check_entity(), CONS, ENDP, ENTITY, entity_domain, entity_initial, entity_name, FOREACH, fprintf(), gen_in_list_p(), gen_list_cyclic_p(), gen_nconc(), ifdebug, NIL, pips_assert, pips_debug, print_entities(), and value_undefined.
Update the entity with final type, storage
tc must have variable type, add lq to its qualifiers
lse const void, void is not of type variable, store const where ????????? CParserError("Entity has qualifier but no type or is not variable type in the context?\n");
Use the type stack in entity_storage to create the final type for the entity
ContextStack | ontextStack |
Definition at line 2842 of file util.c.
References c_parser_context_qualifiers, c_parser_context_type, ContextStack, entity_name, entity_storage, entity_type, get_from_entity_type_stack_table(), NIL, pips_debug, stack_head(), stack_pop(), stack_size(), storage_undefined, tc, type_undefined_p, type_variable, type_variable_p, UpdateType(), and variable_qualifiers.
lq is for what ? e or le ????: lq should be for le
lq | q |
le | e |
Definition at line 1514 of file util.c.
References basic_undefined, CONS, CParserError(), DIMENSION, entity_name, entity_type, gen_nconc(), make_type_variable(), make_variable(), MakeDimension(), NIL, pips_debug, type_undefined_p, type_variable, type_variable_p, variable_dimensions, and variable_qualifiers.
ld | d |
le | e |
ContextStack | ontextStack |
Definition at line 3097 of file util.c.
References ContextStack, ENTITY, FOREACH, and UpdateDerivedEntity().
Update the derived entity with final type and rom storage. If the entity has bit type, do not need to update its type
what about context qualifiers ?
What do we do for functional types for instance?
FI: I assume the qualifiers are carried by the result
What do we do for functional types for instance?
Although it should be popped from the stack, the current context seems to be used later in case of typedef, such as seen in decl24.c
Temporally put the list of struct/union entities defined in decl_psec_list to initial value of ent
ld | d |
ContextStack | ontextStack |
Definition at line 2942 of file util.c.
References basic_pointer, bit_type_p(), c_parser_context_qualifiers, c_parser_context_type, ContextStack, ENDP, entity_initial, entity_name, entity_storage, entity_type, f(), functional_result, get_from_entity_type_stack_table(), make_storage_rom(), NIL, pips_debug, pips_internal_error, pointer_type_p(), stack_head(), stack_pop(), stack_size(), tc, type_functional, type_functional_p, type_variable, type_variable_p, type_void, type_void_p, UpdateType(), variable_basic, and variable_qualifiers.
Referenced by UpdateDerivedEntities().
void UpdateEntities | ( | list | le, |
stack | ContextStack, | ||
stack | FormalStack, | ||
stack | FunctionStack, | ||
stack | OffsetStack, | ||
bool | is_external, | ||
bool | is_declaration | ||
) |
le | e |
ContextStack | ontextStack |
FormalStack | ormalStack |
FunctionStack | unctionStack |
OffsetStack | ffsetStack |
is_external | s_external |
is_declaration | s_declaration |
Definition at line 2733 of file util.c.
References ContextStack, derived_entity_p(), ENTITY, FOREACH, FormalStack, FunctionStack, is_external, OffsetStack, and UpdateEntity().
void UpdateEntity | ( | entity | e, |
stack | ContextStack, | ||
stack | FormalStack, | ||
stack | FunctionStack, | ||
stack | OffsetStack, | ||
bool | is_external, | ||
bool | is_declaration | ||
) |
Update the entity with final type, storage and initial value; and also (sometimes?) declare it at the module level.
Replace dummy arguments by formal arguments for functions
Generate the return variables for functions returning a result
And probably much more...
If e is an intrinsics, nothing should be done, unless you are in the compilation unit: but the intrinsic type has already been put aside in the type stack linked to the entity and destroyed
tc must have variable type, add lq to its qualifiers
lse const void, void is not of type variable, store const where ????????? CParserError("Entity has qualifier but no type or is not variable type in the context?\n");
Use the type stack in entity_storage to create the final type for the entity
The default type is int, or a function returning an int
FI: it might be a good idea to use the type "unknown" or a future type "default" to improve the prettyprinting by not adding implicit "int" declarations.
The default type is int
FI: This elseif branch is apparently useless because the probleme must be dealt with later in the parser
The default return type is int
FI: no longer true, I believe "this field is always pre-defined. It is temporarilly used to store a type. See cyacc.y rule direct-decl:"
FI: Intrinsic do not have formal named parameters in PIPS RI, however such parameters can be named in intrinsic declarations. Problem with Validation/C_syntax/memcof.c
|| type_variable_p(entity_type(function))
Storage does also matter for typedef (and function pointer)
How to access the information about the function type?
FI: This branch should never be executed
The entities for the type_variable is added to the current module and the declarations
It is too early to use extern_entity_p()
Keyword EXTERN has just been encountered
Yes, but this may have been already recognized in FindOrCreateCurrentEntity() and this may not imply the declaration as extern is another declaration of e has already been encountered.
To avoid multiple declarations
Too late to check that the first declaration did not include an initialization
The function should also added to the declarations
We are defining the current module entity
Test case C_syntax/function_name_conflict01.c
Unfortunately, an intrinsics cannot be redefined, just like a user function or subroutine after editing because intrinsics are not handled like user functions or subroutines. They are not added to the called_modules list of other modules, unless the redefining module is parsed FIRST. There is not mechanism in PIPS to control the parsing order.
Be careful if standard arguments are needed: replace the dummy parameters
FI: intrinsic may need to be processed here if they use dynamic typing, a.k.a. dependent types but they do not have a code value!
They cannot be removed in general because they may appear in declarations as in foo(int n, double a[n])
FI: I do not know if refs contains copies of references or just pointer to them
If e is a function pointer, check the storage of its formal parameters
ContextStack | ontextStack |
FormalStack | ormalStack |
FunctionStack | unctionStack |
OffsetStack | ffsetStack |
is_external | s_external |
is_declaration | s_declaration |
Definition at line 2473 of file util.c.
References AddToDeclarations(), AddToExterns(), basic_int, basic_pointer, c_parser_context_qualifiers, c_parser_context_scope, c_parser_context_static, c_parser_context_storage, c_parser_context_type, c_parser_user_warning, CAR, code_declarations, code_externs, code_undefined_p, compilation_unit_entity_p(), compilation_unit_p(), ContextStack, CParserError(), CreateReturnEntity(), DEFAULT_INTEGER_TYPE_SIZE, dummy_parameter_entity_p(), empty_scope_p(), ENDP, ENTITY, entity_consistent_p(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined_p, extract_references_from_declarations(), f(), formal_parameter_p(), FormalStack, free_storage(), functional_result, FunctionStack, gen_free_list(), gen_in_list_p(), get_c_parser_current_input_file_name(), get_current_module_entity(), get_current_module_name(), get_from_entity_type_stack_table(), intrinsic_entity_p(), is_external, list_to_string(), list_undefined, make_basic_int(), make_formal(), make_scalar_integer_type(), make_storage_formal(), make_storage_rom(), make_type_variable(), make_value_unknown(), make_variable(), MakeStorageRam(), NIL, offset, OffsetStack, pips_assert, pips_debug, pips_internal_error, pointer_type_p(), POP, RemoveDummyArguments(), safe_c_words_entity(), stack_empty_p(), stack_head(), stack_pop(), stack_size(), stack_undefined_p, storage_tag, storage_to_string(), storage_undefined_p, tc, TOP_LEVEL_MODULE_NAME, type_functional, type_functional_p, type_undefined_p, type_variable, type_variable_p, type_void, type_void_p, typedef_entity_p(), ultimate_type(), UpdateType(), UseFormalArguments(), user_log(), value_code, value_code_p, value_intrinsic_p, value_undefined_p, variable_basic, and variable_qualifiers.
Referenced by UpdateEntities().
void UpdateEntity2 | ( | entity | f, |
stack FormalStack | __attribute__(__unused__), | ||
stack OffsetStack | __attribute__(__unused__) | ||
) |
A subset of UpdateEntity, used when the function entity is already more defined because the return type is implicit.
See call site cyacc.y
The return value is created when needed.
The dummy parameters are used to create the formal parameters.
Definition at line 2431 of file util.c.
References CAR, code_declarations, copy_type(), CreateReturnEntity(), dummy_parameter_entity_p(), ENDP, ENTITY, ENTITY_, entity_initial, entity_local_name(), entity_storage, entity_type, entity_undefined_p, entity_user_name(), f(), FindEntity(), FindOrCreateEntity(), list_undefined, make_formal(), make_storage_formal(), make_value_unknown(), pips_assert, POP, rank, type_functional_p, ultimate_type(), and value_code.
This function replaces the type pointed by the pointer pt (this can be a pointer of pointer,... so we have to go until the last one) by the type t
pt | t |
Definition at line 1427 of file util.c.
References basic_pointer, basic_pointer_p, CParserError(), make_basic_pointer(), make_type_variable(), make_variable(), NIL, pips_debug, type_tag, type_undefined, type_undefined_p, type_variable, type_variable_p, UpdateFinalPointer(), variable_basic, and variable_qualifiers.
Referenced by UpdateFinalPointer().
The parser has found out that an entity is a function and partially sets its type.
The function may also be an intrinsics and be already fully defined.
If oe is an intrinsics, nothing should be done if we are compiling a function that redeclares intrinsics, because they are usually badly or at least only partly redeclared.
However, il should be updated if it's declared in a compilation unit as the header files may contain more up-to-date information than bootstrap. Or if its type has already been placed in the type stack and been undefined in the entity.
Note that a user function might have the same name as a C intrinsic. Then we are in trouble.
Is oe's name compatible with a function name? Well oe might be a pointer...
FI: We used never to bump into this case...
oe | e |
la | a |
Definition at line 1614 of file util.c.
References compilation_unit_p(), CParserError(), ENDP, entity_name, entity_type, entity_undefined_p, f(), fprintf(), functional_parameters, get_current_module_entity(), get_current_module_name(), ifdebug, intrinsic_entity_p(), list_to_string(), make_functional(), make_type_functional(), MAP, NIL, PARAMETER, parameter_type, pips_debug, pips_internal_error, safe_c_words_entity(), type_functional, type_functional_p, type_undefined, and type_undefined_p.
lq | q |
Definition at line 1368 of file util.c.
References basic_undefined, CParserError(), entity_name, entity_type, gen_nconc(), list_undefined, make_type_variable(), make_variable(), NIL, pips_debug, safe_type_to_string(), type_undefined_p, type_variable, type_variable_p, and variable_qualifiers.
Make e an array of pointers whose type is this of pt
Make e a function returns a pointer
pt | t |
lq | q |
Definition at line 1444 of file util.c.
References c_words_entity(), CParserError(), entity_name, entity_type, f(), functional_parameters, gen_free_list(), gen_nconc(), ifdebug, is_type_functional, is_type_variable, list_to_string(), make_functional(), make_type_functional(), make_type_variable(), make_variable(), NIL, pips_debug, type_functional, type_tag, type_undefined_p, type_variable, variable_basic, variable_dimensions, and variable_qualifiers.
This function replaces the undefined field in t1 by t2.
If t1 is an array type and the basic of t1 is undefined, it is replaced by the basic of t2.
If t1 is a pointer type, if the pointed type is undefined it is replaced by t2.
If t1 is a functional type, if the result type of t1 is undefined, it is replaced by t2.
If t1 is a void type, then either t2 also is a void type or an error is raised.
The function is recursive.
FI: This function used to create sharing between t1 and t2, which creates problems when t2 is later freed. t1 may be updated and returned or a new type may be created.
This may happen when a type is implicitly declared as in "extern m[3];"
We used to use type_unknown when the type was implicit, but type_unknown does not let us store dimension information. We need here a new kind of basic, basic unknown or basic implicit. This would let us be more respectful of the source code, but requires a modification of the internal representation. It is mostly a prettyprint issue. See ticket
Basic pointer
t1 is already fully defined
Redundant update
Could be a pips internal error...
t1 | 1 |
t2 | 2 |
Definition at line 1693 of file util.c.
References basic_pointer, basic_pointer_p, basic_undefined_p, copy_basic(), copy_type(), CParserError(), DEFAULT_INTEGER_TYPE_SIZE, f(), functional_parameters, functional_result, gen_full_copy_list(), gen_nconc(), is_type_functional, is_type_variable, is_type_void, make_basic_pointer(), make_functional(), make_scalar_integer_type(), make_type_functional(), make_type_unknown(), make_type_variable(), make_variable(), overloaded_type_p(), pips_assert, type_equal_p(), type_functional, type_tag, type_undefined, type_undefined_p, type_variable, type_variable_p, type_void_p, UpdateType(), variable_basic, variable_dimensions, and variable_qualifiers.
Referenced by UpdateAbstractEntity(), UpdateDerivedEntity(), UpdateEntity(), and UpdateType().
void UseDummyArguments | ( | entity | f | ) |
If f has regular formal parameters, destroy them.
make a list of formal parameters
Remove the formals from f's declaration list and from the symbol table
FI: The storage might point to another dummy argument (although it should not)
Let's hope there are no other pointers towards dummy formal parameters
Definition at line 2019 of file util.c.
References CAR, code_declarations, CONS, ENDP, ENTITY, entity_formal_p(), entity_initial, entity_name, entity_storage, entity_type, entity_undefined, f(), formal_function, gen_free_list(), gen_nconc(), gen_remove(), list_undefined, NIL, pips_assert, pips_debug, POP, storage_formal, type_functional_p, typedef_entity_p(), value_code, value_code_p, and value_undefined_p.
void UseFormalArguments | ( | entity | f | ) |
If f has dummy formal parameters, replace them by standard formal parameters.
make a list of formal dumy parameters; depending on the kind of function declaration, dummy formal parameters are used (new C function declaration style), or not (old C function declaration style).
FI: Maybe, it would be better to unify the use of summy formal parameter in the parser?
Is it a local function or global function?
mn = strdup(concatenate(entity_module_name(f),entity_local_name(f), NULL));
Remore the dummy formals from f's declaration list (and from the symbol table?) and replace them by equivalent regular formal parameters
Substitute p by new_p in the declaration references for cases such as "foo(n, double a[n])"
This only works if the refs list points to the actual references and not to copies...
sg: this test used to be if e == p, but it missed some cases because reference_variable may have been generated incorectly before using a TOP_LEVEL variable instead of the dummy
A substitution could be performed instead...
FI: The storage might point to another dummy argument (although it should not)
Let's hope there are no other pointers towards dummy formal parameters
Check substitution in formal parameter declarations
FI: just in case?
Do not free the dummy formal parameter variable as they are preserved in the dummy field for accurate prettyprinting
Definition at line 2063 of file util.c.
References CAR, code_declarations, CONS, copy_storage(), copy_type(), copy_value(), declaration_supporting_references(), dummy_parameter_entity_p(), ENDP, ENTITY, entity_formal_p(), entity_initial, entity_local_name(), entity_name, entity_storage, entity_type, entity_undefined, entity_user_name(), f(), FindOrCreateEntity(), FOREACH, fprintf(), free(), gen_free_list(), gen_length(), gen_nconc(), gen_remove(), get_from_entity_type_stack_table(), ifdebug, list_undefined, MAP, module_all_declarations(), NIL, pips_assert, pips_debug, pips_internal_error, POP, print_entities(), print_references(), REFERENCE, reference_variable, remove_entity_type_stacks(), same_entity_lname_p(), stack_undefined_p, strdup(), string_undefined, top_level_entity_p(), type_functional_p, typedef_entity_p(), value_code, value_code_p, and value_undefined_p.
Referenced by UpdateEntity().
Definition at line 3590 of file util.c.
Referenced by analyze_preprocessor_line(), and reset_preprocessor_line_analysis().
|
static |
The data structure to tackle the memory allocation problem due to reparsing of compilation unit.
static int previoussizeofGlobalArea; entity previouscompunit; To keep track of the current dummy parameter naming. A function can be redeclared and it is difficult to make a difference between "void foo(int u, int u);", which not in the standard, and "void foo(int u); void foo(int u); which is fine"
Definition at line 137 of file util.c.
Referenced by get_current_dummy_parameter_number(), reset_current_dummy_parameter_number(), and set_current_dummy_parameter_number().
|
static |
Definition at line 1788 of file util.c.
Referenced by nodecl_p(), and referencenodeclfilter().