/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in struct attribute_spec.handler. */ static tree avm2_handle_struct_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) { tree *type = NULL; if (DECL_P (*node)) { if (TREE_CODE (*node) == TYPE_DECL) type = &TREE_TYPE (*node); } else type = node; if (!(type && (TREE_CODE (*type) == RECORD_TYPE || TREE_CODE (*type) == UNION_TYPE))) { warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name)); *no_add_attrs = true; } else if ((is_attribute_p ("ms_struct", name) && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type))) || ((is_attribute_p ("gcc_struct", name) && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type))))) { warning (OPT_Wattributes, "%qs incompatible attribute ignored", IDENTIFIER_POINTER (name)); *no_add_attrs = true; } return NULL_TREE; }
void solaris_insert_attributes (tree decl, tree *attributes) { tree *x, next; if (solaris_pending_aligns != NULL && TREE_CODE (decl) == VAR_DECL) for (x = &solaris_pending_aligns; *x; x = &TREE_CHAIN (*x)) { tree name = TREE_PURPOSE (*x); tree value = TREE_VALUE (*x); if (DECL_NAME (decl) == name) { if (lookup_attribute ("aligned", DECL_ATTRIBUTES (decl)) || lookup_attribute ("aligned", *attributes)) warning (0, "ignoring %<#pragma align%> for explicitly " "aligned %q+D", decl); else *attributes = tree_cons (get_identifier ("aligned"), value, *attributes); next = TREE_CHAIN (*x); ggc_free (*x); *x = next; break; } } if (solaris_pending_inits != NULL && TREE_CODE (decl) == FUNCTION_DECL) for (x = &solaris_pending_inits; *x; x = &TREE_CHAIN (*x)) { tree name = TREE_PURPOSE (*x); if (DECL_NAME (decl) == name) { *attributes = tree_cons (get_identifier ("init"), NULL, *attributes); *attributes = tree_cons (get_identifier ("used"), NULL, *attributes); next = TREE_CHAIN (*x); ggc_free (*x); *x = next; break; } } if (solaris_pending_finis != NULL && TREE_CODE (decl) == FUNCTION_DECL) for (x = &solaris_pending_finis; *x; x = &TREE_CHAIN (*x)) { tree name = TREE_PURPOSE (*x); if (DECL_NAME (decl) == name) { *attributes = tree_cons (get_identifier ("fini"), NULL, *attributes); *attributes = tree_cons (get_identifier ("used"), NULL, *attributes); next = TREE_CHAIN (*x); ggc_free (*x); *x = next; break; } } }
int avm2_return_pops_args (tree fundecl, tree funtype, int size) { int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE); /* Cdecl functions override -mrtd, and never pop the stack. */ if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) { /* Stdcall and fastcall functions will pop the stack if not variable args. */ if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)) || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype))) rtd = 1; if (rtd && (TYPE_ARG_TYPES (funtype) == NULL_TREE || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node))) return size; } /* Lose any fake structure return argument if it is passed on the stack. */ if (aggregate_value_p (TREE_TYPE (funtype), fundecl) && !KEEP_AGGREGATE_RETURN_POINTER) { int nregs = avm2_function_regparm (funtype, fundecl); if (!nregs) return GET_MODE_SIZE (Pmode); } return 0; }
void i386_nlm_encode_section_info (tree decl, rtx rtl, int first) { default_encode_section_info (decl, rtl, first); if (first && TREE_CODE (decl) == FUNCTION_DECL && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*' && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), '@')) { tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); tree newid; if (lookup_attribute ("stdcall", type_attributes)) newid = gen_stdcall_or_fastcall_decoration (decl, '_'); else if (lookup_attribute ("fastcall", type_attributes)) newid = gen_stdcall_or_fastcall_decoration (decl, FASTCALL_PREFIX); else if ((newid = lookup_attribute ("regparm", type_attributes)) != NULL_TREE) newid = gen_regparm_prefix (decl, TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (newid)))); if (newid != NULL_TREE) { rtx rtlname = XEXP (rtl, 0); if (GET_CODE (rtlname) == MEM) rtlname = XEXP (rtlname, 0); XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid); /* These attributes must be present on first declaration, change_decl_assembler_name will warn if they are added later and the decl has been referenced, but duplicate_decls should catch the mismatch before this is called. */ change_decl_assembler_name (decl, newid); } } }
bool i386_pe_dllimport_p (tree decl) { if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return false; /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag. We may need to override an earlier decision. */ if (DECL_DLLIMPORT_P (decl) && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl))) { /* Make a final check to see if this is a definition before we generate RTL for an indirect reference. */ if (!DECL_EXTERNAL (decl)) { error ("%q+D: definition is marked as dllimport", decl); DECL_DLLIMPORT_P (decl) = 0; return false; } return true; } /* The DECL_DLLIMPORT_P flag was set for decls in the class definition by targetm.cxx.adjust_class_at_definition. Check again to emit warnings if the class attribute has been overridden by an out-of-class definition. */ else if (associated_type (decl) && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (associated_type (decl)))) return i386_pe_type_dllimport_p (decl); return false; }
static inline bool has_proper_scope_for_analysis (tree t) { /* If the variable has the "used" attribute, treat it as if it had a been touched by the devil. */ if (lookup_attribute ("used", DECL_ATTRIBUTES (t))) return false; /* Do not want to do anything with volatile except mark any function that uses one to be not const or pure. */ if (TREE_THIS_VOLATILE (t)) return false; /* Do not care about a local automatic that is not static. */ if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) return false; if (DECL_EXTERNAL (t) || TREE_PUBLIC (t)) return false; /* This is a variable we care about. Check if we have seen it before, and if not add it the set of variables we care about. */ if (!bitmap_bit_p (all_module_statics, DECL_UID (t))) add_static_var (t); return true; }
nesc_attribute start_attribute_use(word name) { /* Prepare to read an initialiser for the attribute definition specified by name */ nesc_attribute attr = new_nesc_attribute(parse_region, name->location, name, NULL); tag_ref aref = lookup_attribute(name); /* XXX: aref leaks */ type atype = error_type; /* Create new environment so that we can track whether this is a deputy scope or not. Using an environment makes it easy to recover parsing errors: we just call poplevel in the appropriate error production (see nattrib rules in c-parse.y). */ pushlevel(FALSE); attr->tdecl = aref->tdecl; if (aref->tdecl) { atype = make_tagged_type(aref->tdecl); if (aref->tdecl->deputy_scope) current.env->deputy_scope = TRUE; } start_init(NULL, attr); really_start_incremental_init(atype); return attr; }
static PyObject * attr_dir_get(PyObject *_self, PyObject *args) { attr_dir_object *self = (attr_dir_object*)_self; PyObject *key, *failobj; kdump_ctx *ctx; kdump_attr_ref_t ref; kdump_attr_t attr; kdump_status status; int res; failobj = Py_None; if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) return NULL; res = lookup_attribute(self, key, &ref); if (res < 0) return NULL; else if (res == 0) goto notfound; ctx = self->kdumpfile->ctx; status = kdump_attr_ref_get(ctx, &ref, &attr); if (status == kdump_ok) return attr_new(self->kdumpfile, &ref, &attr); if (status != kdump_nodata) { PyErr_SetString(exception_map(status), kdump_err_str(ctx)); return NULL; } notfound: Py_INCREF(failobj); return failobj; }
static bool i386_pe_determine_dllimport_p (tree decl) { tree assoc; if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return false; if (DECL_DLLIMPORT_P (decl)) return true; /* The DECL_DLLIMPORT_P flag was set for decls in the class definition by targetm.cxx.adjust_class_at_definition. Check again to emit error message if the class attribute has been overridden by an out-of-class definition of static data. */ assoc = associated_type (decl); if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)) && TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl) /* vtable's are linkonce constants, so defining a vtable is not an error as long as we don't try to import it too. */ && !DECL_VIRTUAL_P (decl)) error ("definition of static data member %q+D of " "dllimport%'d class", decl); return false; }
const_tree get_attribute(const char* attr_name, const_tree decl) { const_tree attr = lookup_attribute(attr_name, DECL_ATTRIBUTES(decl)); if (attr && TREE_VALUE(attr)) return attr; return NULL_TREE; }
int crx_interrupt_function_p (void) { tree attributes; attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)); return lookup_attribute ("interrupt", attributes) != NULL_TREE; }
static int get_attribute(attr_dir_object *self, PyObject *key, kdump_attr_ref_t *ref) { int ret = lookup_attribute(self, key, ref); if (ret == 0) PyErr_SetObject(PyExc_KeyError, key); return ret; }
void solaris_output_init_fini (FILE *file, tree decl) { if (lookup_attribute ("init", DECL_ATTRIBUTES (decl))) { fprintf (file, "\t.pushsection\t\".init\"\n"); ASM_OUTPUT_CALL (file, decl); fprintf (file, "\t.popsection\n"); } if (lookup_attribute ("fini", DECL_ATTRIBUTES (decl))) { fprintf (file, "\t.pushsection\t\".fini\"\n"); ASM_OUTPUT_CALL (file, decl); fprintf (file, "\t.popsection\n"); } }
static inline void check_decl (funct_state local, tree t, bool checking_write) { /* If the variable has the "used" attribute, treat it as if it had a been touched by the devil. */ if (lookup_attribute ("used", DECL_ATTRIBUTES (t))) { local->pure_const_state = IPA_NEITHER; return; } /* Do not want to do anything with volatile except mark any function that uses one to be not const or pure. */ if (TREE_THIS_VOLATILE (t)) { local->pure_const_state = IPA_NEITHER; return; } /* Do not care about a local automatic that is not static. */ if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) return; /* Since we have dealt with the locals and params cases above, if we are CHECKING_WRITE, this cannot be a pure or constant function. */ if (checking_write) local->pure_const_state = IPA_NEITHER; if (DECL_EXTERNAL (t) || TREE_PUBLIC (t)) { /* If the front end set the variable to be READONLY and constant, we can allow this variable in pure or const functions but the scope is too large for our analysis to set these bits ourselves. */ if (TREE_READONLY (t) && DECL_INITIAL (t) && is_gimple_min_invariant (DECL_INITIAL (t))) ; /* Read of a constant, do not change the function state. */ else { /* Just a regular read. */ if (local->pure_const_state == IPA_CONST) local->pure_const_state = IPA_PURE; } } /* Compilation level statics can be read if they are readonly variables. */ if (TREE_READONLY (t)) return; /* Just a regular read. */ if (local->pure_const_state == IPA_CONST) local->pure_const_state = IPA_PURE; }
static bool decide_is_function_needed (struct cgraph_node *node, tree decl) { if (MAIN_NAME_P (DECL_NAME (decl)) && TREE_PUBLIC (decl)) { node->local.externally_visible = true; return true; } /* If the user told us it is used, then it must be so. */ if (node->local.externally_visible) return true; /* ??? If the assembler name is set by hand, it is possible to assemble the name later after finalizing the function and the fact is noticed in assemble_name then. This is arguably a bug. */ if (DECL_ASSEMBLER_NAME_SET_P (decl) && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) return true; /* With -fkeep-inline-functions we are keeping all inline functions except for extern inline ones. */ if (flag_keep_inline_functions && DECL_DECLARED_INLINE_P (decl) && !DECL_EXTERNAL (decl) && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))) return true; /* If we decided it was needed before, but at the time we didn't have the body of the function available, then it's still needed. We have to go back and re-check its dependencies now. */ if (node->needed) return true; /* Externally visible functions must be output. The exception is COMDAT functions that must be output only when they are needed. When not optimizing, also output the static functions. (see PR24561), but don't do so for always_inline functions, functions declared inline and nested functions. These was optimized out in the original implementation and it is unclear whether we want to change the behavior here. */ if (((TREE_PUBLIC (decl) || (!optimize && !node->local.disregard_inline_limits && !DECL_DECLARED_INLINE_P (decl) && !node->origin)) && !flag_whole_program) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) return true; /* Constructors and destructors are reachable from the runtime by some mechanism. */ if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)) return true; return false; }
int c_disregard_inline_limits (tree fn) { if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL) return 1; return (!flag_really_no_inline && DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn)); }
static unsigned HOST_WIDE_INT alloc_object_size (const_gimple call, int object_size_type) { tree callee, bytes = NULL_TREE; tree alloc_size; int arg1 = -1, arg2 = -1; gcc_assert (is_gimple_call (call)); callee = gimple_call_fndecl (call); if (!callee) return unknown[object_size_type]; alloc_size = lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (TREE_TYPE (callee))); if (alloc_size && TREE_VALUE (alloc_size)) { tree p = TREE_VALUE (alloc_size); arg1 = TREE_INT_CST_LOW (TREE_VALUE (p))-1; if (TREE_CHAIN (p)) arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1; } if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL) switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_CALLOC: arg2 = 1; /* fall through */ case BUILT_IN_MALLOC: case BUILT_IN_ALLOCA: case BUILT_IN_ALLOCA_WITH_ALIGN: arg1 = 0; default: break; } if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call) || TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST || (arg2 >= 0 && (arg2 >= (int)gimple_call_num_args (call) || TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST))) return unknown[object_size_type]; if (arg2 >= 0) bytes = size_binop (MULT_EXPR, fold_convert (sizetype, gimple_call_arg (call, arg1)), fold_convert (sizetype, gimple_call_arg (call, arg2))); else if (arg1 >= 0) bytes = fold_convert (sizetype, gimple_call_arg (call, arg1)); if (bytes && host_integerp (bytes, 1)) return tree_low_cst (bytes, 1); return unknown[object_size_type]; }
bool i386_pe_dllexport_p (tree decl) { if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return false; if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) return true; /* Also mark class members of exported classes with dllexport. */ if (associated_type (decl) && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (associated_type (decl)))) return i386_pe_type_dllexport_p (decl); return false; }
/// AddAnnotateAttrsToGlobal - Adds decls that have a /// annotate attribute to a vector to be emitted later. void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree decl) { // Handle annotate attribute on global. tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); // Get file and line number Constant *lineNo = ConstantInt::get(Type::Int32Ty, DECL_SOURCE_LINE(decl)); Constant *file = ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl)); const Type *SBP= PointerType::get(Type::Int8Ty); file = ConstantExpr::getBitCast(file, SBP); // There may be multiple annotate attributes. Pass return of lookup_attr // to successive lookups. while (annotateAttr) { // Each annotate attribute is a tree list. // Get value of list which is our linked list of args. tree args = TREE_VALUE(annotateAttr); // Each annotate attribute may have multiple args. // Treat each arg as if it were a separate annotate attribute. for (tree a = args; a; a = TREE_CHAIN(a)) { // Each element of the arg list is a tree list, so get value tree val = TREE_VALUE(a); // Assert its a string, and then get that string. assert(TREE_CODE(val) == STRING_CST && "Annotate attribute arg should always be a string"); Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); Constant *Element[4] = {ConstantExpr::getBitCast(GV,SBP), ConstantExpr::getBitCast(strGV,SBP), file, lineNo}; AttributeAnnotateGlobals.push_back(ConstantStruct::get(Element, 4, false)); } // Get next annotate attribute. annotateAttr = TREE_CHAIN(annotateAttr); if (annotateAttr) annotateAttr = lookup_attribute("annotate", annotateAttr); } }
int i386_pe_dllexport_p (tree decl) { if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return 0; /* APPLE LOCAL begin mainline 2005-10-12 */ if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) return 1; /* Also mark class members of exported classes with dllexport. */ if (associated_type (decl) && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (associated_type (decl)))) return i386_pe_type_dllexport_p (decl); /* APPLE LOCAL end mainline 2005-10-12 */ return 0; }
static bool gate_latent_entropy(void) { // don't bother with noreturn functions for now if (TREE_THIS_VOLATILE(current_function_decl)) return false; // gcc-4.5 doesn't discover some trivial noreturn functions if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds) == 0) return false; return lookup_attribute("latent_entropy", DECL_ATTRIBUTES(current_function_decl)) != NULL_TREE; }
static inline void maybe_add_dllexport (tree decl) { if (i386_pe_type_dllexport_p (decl)) { tree decl_attrs = DECL_ATTRIBUTES (decl); if (lookup_attribute ("dllexport", decl_attrs) != NULL_TREE) /* Already done. */ return; DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("dllexport"), NULL_TREE, decl_attrs); } }
/* Return true if FUNC is a isr function. */ bool nds32_isr_function_p (tree func) { tree t_intr; tree t_excp; tree t_reset; tree attrs; if (TREE_CODE (func) != FUNCTION_DECL) abort (); attrs = DECL_ATTRIBUTES (func); t_intr = lookup_attribute ("interrupt", attrs); t_excp = lookup_attribute ("exception", attrs); t_reset = lookup_attribute ("reset", attrs); return ((t_intr != NULL_TREE) || (t_excp != NULL_TREE) || (t_reset != NULL_TREE)); }
static int attr_dir_contains(PyObject *_self, PyObject *key) { attr_dir_object *self = (attr_dir_object*)_self; kdump_attr_ref_t ref; int ret; ret = lookup_attribute(self, key, &ref); if (ret > 0) { ret = kdump_attr_ref_isset(&ref); kdump_attr_unref(self->kdumpfile->ctx, &ref); } return ret; }
static int i386_pe_dllexport_p (tree decl) { tree exp; if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return 0; exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)); if (exp) return 1; /* Class members get the dllexport status of their class. */ if (associated_type (decl)) { exp = lookup_attribute ("dllexport", TYPE_ATTRIBUTES (associated_type (decl))); if (exp) return 1; } return 0; }
static unsigned int instrument_assignments_plugin_exec(void) { #ifdef DEBUG fprintf(stderr, "* Inspecting function `%s'\n", FN_NAME); #endif basic_block bb; FOR_EACH_BB(bb) { gimple_stmt_iterator gsi; for (gsi = gsi_start_bb(bb) ; !gsi_end_p(gsi) ; gsi_next(&gsi)) { gimple curr_stmt = gsi_stmt(gsi); tree lhs = gimple_get_lhs(curr_stmt); // We only care about assignments to “real” variables – i.e. not // variable versions that were created as part of the transformation // to SSA form. if (gimple_code(curr_stmt) == GIMPLE_ASSIGN && lhs != NULL_TREE && TREE_CODE(lhs) != SSA_NAME && DECL_P(lhs)) { tree attrlist = DECL_ATTRIBUTES(lhs); tree attr = lookup_attribute("instrument", attrlist); // the princess is in another castle if (attr == NULL_TREE) continue; // read the variable id that was passed to the `instrument' // attribute const_tree arg = TREE_VALUE(TREE_VALUE(attr)); tree var_id = build_int_cst(NULL_TREE, tree_low_cst (arg, 1)); #ifdef DEBUG fprintf(stderr, " > found assignment to instrumented variable `%s': \n\t", get_name(lhs)); print_gimple_stmt(stderr, curr_stmt, 0, 0); fprintf(stderr, "\tbase address of `%s' is %p\n", get_name(lhs), get_base_address(lhs)); #endif // insert our instrumentation function before the current // statement and pass along the rhs (i.e. the new value) tree rhs = gimple_op(curr_stmt, 1); insert_instrumentation_fn(curr_stmt, var_id, rhs); } } } #ifdef DEBUG fprintf(stderr, "\n"); #endif return 0; }
varpool_node * varpool_create_variable_alias (tree alias, tree decl) { varpool_node *alias_node; gcc_assert (TREE_CODE (decl) == VAR_DECL); gcc_assert (TREE_CODE (alias) == VAR_DECL); alias_node = varpool_node_for_decl (alias); alias_node->alias = true; alias_node->definition = true; alias_node->alias_target = decl; if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL) alias_node->weakref = true; return alias_node; }
static bool i386_pe_determine_dllexport_p (tree decl) { if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return false; /* Don't export local clones of dllexports. */ if (!TREE_PUBLIC (decl)) return false; if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) return true; return false; }
static tree handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), tree args, int ARG_UNUSED (flags), bool * ARG_UNUSED (no_add_attrs)) { tree type = *node; /* If no arguments are specified, all pointer arguments should be non-null. Verify a full prototype is given so that the arguments will have the correct types when we actually check them later. Avoid diagnosing type-generic built-ins since those have no prototype. */ if (!args) { gcc_assert (prototype_p (type) || !TYPE_ATTRIBUTES (type) || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))); return NULL_TREE; } /* Argument list specified. Verify that each argument number references a pointer argument. */ for (; args; args = TREE_CHAIN (args)) { tree argument; unsigned HOST_WIDE_INT arg_num = 0, ck_num; if (!get_nonnull_operand (TREE_VALUE (args), &arg_num)) gcc_unreachable (); argument = TYPE_ARG_TYPES (type); if (argument) { for (ck_num = 1; ; ck_num++) { if (!argument || ck_num == arg_num) break; argument = TREE_CHAIN (argument); } gcc_assert (argument && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE); } } return NULL_TREE; }
/* Function for nds32_merge_decl_attributes() and nds32_insert_attributes() to check if there are any conflict isr-specific attributes being set. We need to check: 1. Only 'save_all' or 'partial_save' in the attributes. 2. Only 'nested', 'not_nested', or 'nested_ready' in the attributes. 3. Only 'interrupt', 'exception', or 'reset' in the attributes. */ void nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs) { int save_all_p, partial_save_p; int nested_p, not_nested_p, nested_ready_p; int intr_p, excp_p, reset_p; /* Initialize variables. */ save_all_p = partial_save_p = 0; nested_p = not_nested_p = nested_ready_p = 0; intr_p = excp_p = reset_p = 0; /* We must check at MOST one attribute to set save-reg. */ if (lookup_attribute ("save_all", func_attrs)) save_all_p = 1; if (lookup_attribute ("partial_save", func_attrs)) partial_save_p = 1; if ((save_all_p + partial_save_p) > 1) error ("multiple save reg attributes to function %qD", func_decl); /* We must check at MOST one attribute to set nested-type. */ if (lookup_attribute ("nested", func_attrs)) nested_p = 1; if (lookup_attribute ("not_nested", func_attrs)) not_nested_p = 1; if (lookup_attribute ("nested_ready", func_attrs)) nested_ready_p = 1; if ((nested_p + not_nested_p + nested_ready_p) > 1) error ("multiple nested types attributes to function %qD", func_decl); /* We must check at MOST one attribute to set interrupt/exception/reset. */ if (lookup_attribute ("interrupt", func_attrs)) intr_p = 1; if (lookup_attribute ("exception", func_attrs)) excp_p = 1; if (lookup_attribute ("reset", func_attrs)) reset_p = 1; if ((intr_p + excp_p + reset_p) > 1) error ("multiple interrupt attributes to function %qD", func_decl); }