示例#1
0
/* 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;
}
示例#2
0
文件: sol2.c 项目: Abioy/gccxml
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;
          }
      }
}
示例#3
0
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;
}
示例#4
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);
	}
    }
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#11
0
int
crx_interrupt_function_p (void)
{
  tree attributes;

  attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
  return lookup_attribute ("interrupt", attributes) != NULL_TREE;
}
示例#12
0
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;
}
示例#13
0
文件: sol2.c 项目: Abioy/gccxml
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");
    }
}
示例#14
0
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;
}
示例#15
0
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;
}
示例#16
0
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));
}
示例#17
0
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];
}
示例#18
0
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);
  }
}
示例#20
0
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;
}
示例#22
0
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);
    }
}
示例#23
0
文件: nds32-isr.c 项目: alcides/gcc
/* 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));
}
示例#24
0
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;
}
示例#25
0
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;
}
示例#27
0
文件: varpool.c 项目: palves/gcc
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;
}
示例#28
0
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;
}
示例#29
0
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;
}
示例#30
0
文件: nds32-isr.c 项目: alcides/gcc
/* 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);
}