Exemplo n.º 1
0
void
oacc_replace_fn_attrib (tree fn, tree dims)
{
  tree ident = get_identifier (OACC_FN_ATTRIB);
  tree attribs = DECL_ATTRIBUTES (fn);

  /* If we happen to be present as the first attrib, drop it.  */
  if (attribs && TREE_PURPOSE (attribs) == ident)
    attribs = TREE_CHAIN (attribs);
  DECL_ATTRIBUTES (fn) = tree_cons (ident, dims, attribs);
}
Exemplo n.º 2
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);
    }
}
Exemplo n.º 3
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;
}
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
static void
write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
				    bool ref_p)
{
  stream_write_tree (ob, DECL_SIZE (expr), ref_p);
  stream_write_tree (ob, DECL_SIZE_UNIT (expr), ref_p);

  /* Note, DECL_INITIAL is not handled here.  Since DECL_INITIAL needs
     special handling in LTO, it must be handled by streamer hooks.  */

  stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);

  /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
     for early inlining so drop it on the floor instead of ICEing in
     dwarf2out.c.  */

  if (TREE_CODE (expr) == PARM_DECL)
    streamer_write_chain (ob, TREE_CHAIN (expr), ref_p);

  if ((TREE_CODE (expr) == VAR_DECL
       || TREE_CODE (expr) == PARM_DECL)
      && DECL_HAS_VALUE_EXPR_P (expr))
    stream_write_tree (ob, DECL_VALUE_EXPR (expr), ref_p);

  if (TREE_CODE (expr) == VAR_DECL)
    stream_write_tree (ob, DECL_DEBUG_EXPR (expr), ref_p);
}
Exemplo n.º 7
0
Arquivo: sol2.c Projeto: 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;
          }
      }
}
Exemplo n.º 8
0
static void
lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
					struct data_in *data_in, tree expr)
{
  DECL_SIZE (expr) = stream_read_tree (ib, data_in);
  DECL_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
  DECL_ATTRIBUTES (expr) = stream_read_tree (ib, data_in);

  /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
     for early inlining so drop it on the floor instead of ICEing in
     dwarf2out.c.  */

  if (TREE_CODE (expr) == PARM_DECL)
    TREE_CHAIN (expr) = streamer_read_chain (ib, data_in);

  if ((TREE_CODE (expr) == VAR_DECL
       || TREE_CODE (expr) == PARM_DECL)
      && DECL_HAS_VALUE_EXPR_P (expr))
    SET_DECL_VALUE_EXPR (expr, stream_read_tree (ib, data_in));

  if (TREE_CODE (expr) == VAR_DECL)
    {
      tree dexpr = stream_read_tree (ib, data_in);
      if (dexpr)
	SET_DECL_DEBUG_EXPR (expr, dexpr);
    }
}
Exemplo n.º 9
0
Arquivo: sol2.c Projeto: 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");
    }
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
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));
}
Exemplo n.º 13
0
tree
copy_var_decl (tree var, tree name, tree type)
{
  tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);

  TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
  TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
  DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
  DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
  DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
  DECL_CONTEXT (copy) = DECL_CONTEXT (var);
  TREE_NO_WARNING (copy) = TREE_NO_WARNING (var);
  TREE_USED (copy) = 1;
  DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
  DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var);

  return copy;
}
Exemplo n.º 14
0
void
build_module_descriptor (long vers, tree attr)
{
  tree decls, *chain = NULL;

#ifdef OBJCPLUS
  push_lang_context (lang_name_c); /* extern "C" */
#endif

  objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));

  /* long version; */
  decls = add_field_decl (long_integer_type_node, "version", &chain);

  /* long size; */
  add_field_decl (long_integer_type_node, "size", &chain);

  /* char *name; */
  add_field_decl (string_type_node, "name", &chain);

  /* struct _objc_symtab *symtab; */
  add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
						get_identifier (UTAG_SYMTAB))),
		  "symtab", &chain);

  objc_finish_struct (objc_module_template, decls);

  /* Create an instance of "_objc_module".  */
  UOBJC_MODULES_decl = start_var_decl (objc_module_template,
				       /* FIXME - why the conditional
					  if the symbol is the
					  same.  */
				       flag_next_runtime ? "_OBJC_Module" :  "_OBJC_Module");

  /* This is the root of the metadata for defined classes and categories, it
     is referenced by the runtime and, therefore, needed.  */
  DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;

  /* Squash `defined but not used' warning.  */
  TREE_USED (UOBJC_MODULES_decl) = 1;

  /* Allow the runtime to mark meta-data such that it can be assigned to target
     specific sections by the back-end.  */
  if (attr)
    DECL_ATTRIBUTES (UOBJC_MODULES_decl) = attr;

  finish_var_decl (UOBJC_MODULES_decl,
		   init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl),
					   vers));

#ifdef OBJCPLUS
  pop_lang_context ();
#endif
}
Exemplo n.º 15
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 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;
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
0
Arquivo: varpool.c Projeto: 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;
}
Exemplo n.º 19
0
unsigned int
i386_pe_section_type_flags (tree decl, const char *name, int reloc)
{
  static htab_t htab;
  unsigned int flags;
  unsigned int **slot;

  /* The names we put in the hashtable will always be the unique
     versions given to us by the stringtable, so we can just use
     their addresses as the keys.  */
  if (!htab)
    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);

  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
    flags = SECTION_CODE;
  else if (decl && decl_readonly_section (decl, reloc))
    flags = 0;
  else
    {
      flags = SECTION_WRITE;

      if (decl && TREE_CODE (decl) == VAR_DECL
 /* APPLE LOCAL begin mainline 2005-04-01 */
          && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
        flags |= SECTION_PE_SHARED;
 /* APPLE LOCAL end mainline 2005-04-01 */
    }

  if (decl && DECL_ONE_ONLY (decl))
    flags |= SECTION_LINKONCE;

  /* See if we already have an entry for this section.  */
  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
  if (!*slot)
    {
      *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
      **slot = flags;
    }
  else
    {
      if (decl && **slot != flags)
        error ("%J'%D' causes a section type conflict", decl, decl);
    }

  return flags;
}
Exemplo n.º 20
0
static bool kernexec_cmodel_check(void)
{
	tree section;

	if (ix86_cmodel != CM_KERNEL)
		return false;

	section = lookup_attribute("section", DECL_ATTRIBUTES(current_function_decl));
	if (!section || !TREE_VALUE(section))
		return true;

	section = TREE_VALUE(TREE_VALUE(section));
	if (strncmp(TREE_STRING_POINTER(section), ".vsyscall_", 10))
		return true;

	return false;
}
Exemplo n.º 21
0
void gcc_plugin_pre_genericize(void *gcc_data, void *user_data)
{
    tree decl = (tree) gcc_data;

    // check for __base_ctor/__comp_ctor fake constructors. these correspond
    // directly to another constructor for the type, and we will replace
    // references to these with references to that other constructor.
    // we will see the other constructor first, and its TREE_CHAINs will
    // have the __base_ctor and __comp_ctor.
    tree chain = TREE_CHAIN(decl);
    if (chain && TREE_CODE(chain) == FUNCTION_DECL) {
        const char *chain_name = IDENTIFIER_POINTER(DECL_NAME(chain));
        if (!strncmp(chain_name,"__base_ctor",11) ||
                !strncmp(chain_name,"__base_dtor",11)) {
            bool *skip_info = (bool*) XIL_Associate(XIL_AscGlobal, "func_skip",chain);
            *skip_info = true;

            chain = TREE_CHAIN(chain);
            if (chain && TREE_CODE(chain) == FUNCTION_DECL) {
                const char *chain_name = IDENTIFIER_POINTER(DECL_NAME(chain));
                if (!strncmp(chain_name,"__comp_ctor",11) ||
                        !strncmp(chain_name,"__comp_dtor",11)) {
                    skip_info = (bool*) XIL_Associate(XIL_AscGlobal, "func_skip",chain);
                    *skip_info = true;
                }
            }
        }
    }

    // if this is the __base_ctor or __comp_ctor, skip it.
    bool *skip_info = (bool*) XIL_Associate(XIL_AscGlobal, "func_skip",decl);
    if (*skip_info)
        return;

    // check for annotations on this function.
    tree attr = DECL_ATTRIBUTES(decl);
    while (attr) {
        XIL_ProcessAnnotationAttr(decl, attr, NULL, NULL);
        attr = TREE_CHAIN(attr);
    }

    XIL_GenerateBlock(decl);

    // future parameter declarations will be for a different function.
    xil_pending_param_decls = NULL;
}
Exemplo n.º 22
0
static tree handle_nocapture_attribute(tree *node, tree __unused name, tree args, int __unused flags, bool *no_add_attrs)
{
	tree orig_attr, arg;

	*no_add_attrs = true;
	switch (TREE_CODE(*node)) {
	case FUNCTION_DECL:
	case FUNCTION_TYPE:
	case METHOD_TYPE:
		break;

	case TYPE_DECL: {
		const_tree fntype = TREE_TYPE(*node);

		if (TREE_CODE(fntype) == POINTER_TYPE)
			fntype = TREE_TYPE(fntype);
		if (TREE_CODE(fntype) == FUNCTION_TYPE || TREE_CODE(fntype) == METHOD_TYPE)
			break;
		// FALLTHROUGH
	}

	default:
		error("%s: %qE attribute only applies to functions", __func__, name);
		debug_tree(*node);
		return NULL_TREE;
	}

	for (arg = args; arg; arg = TREE_CHAIN(arg)) {
		tree position = TREE_VALUE(arg);

		if (TREE_CODE(position) != INTEGER_CST) {
			error("%s: parameter isn't an integer", __func__);
			debug_tree(arg);
			return NULL_TREE;
		}
	}

	orig_attr = lookup_attribute("nocapture", DECL_ATTRIBUTES(*node));
	if (orig_attr)
		chainon(TREE_VALUE(orig_attr), args);
	else
		*no_add_attrs = false;

	return NULL_TREE;
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
0
void
handle_pre_generic (void *event_data, void *data)
{
  tree fndecl = (tree) event_data;
  tree arg;
  for (arg = DECL_ARGUMENTS(fndecl); arg; arg = DECL_CHAIN (arg)) {
      tree attr;
      for (attr = DECL_ATTRIBUTES (arg); attr; attr = TREE_CHAIN (attr)) {
          tree attrname = TREE_PURPOSE (attr);
          tree attrargs = TREE_VALUE (attr);
          warning (0, G_("attribute '%s' on param '%s' of function %s"),
                   IDENTIFIER_POINTER (attrname),
                   IDENTIFIER_POINTER (DECL_NAME (arg)),
                   IDENTIFIER_POINTER (DECL_NAME (fndecl))
                   );
      }
  }
}
Exemplo n.º 25
0
static int msp430_get_stack_reserve(void)
{
    int stack_reserve = 0;
    tree ss = lookup_attribute ("reserve", DECL_ATTRIBUTES (current_function_decl));
    if (ss)
    {
        ss = TREE_VALUE (ss);
        if (ss)
        {
            ss = TREE_VALUE (ss);
            if (ss)
                stack_reserve = TREE_INT_CST_LOW (ss);
            stack_reserve++;
            stack_reserve &= ~1;
        }
    }
    return stack_reserve;
}
/// 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);
  }
}
Exemplo n.º 27
0
void
i386_pe_asm_named_section (const char *name, unsigned int flags, 
			   tree decl)
{
  char flagchars[8], *f = flagchars;

  if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
    /* readonly data */
    {
      *f++ ='d';  /* This is necessary for older versions of gas.  */
      *f++ ='r';
    }
  else	
    {
      if (flags & SECTION_CODE)
        *f++ = 'x';
      if (flags & SECTION_WRITE)
        *f++ = 'w';
      if (flags & SECTION_PE_SHARED)
        *f++ = 's';
    }

  *f = '\0';

  fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);

  if (flags & SECTION_LINKONCE)
    {
      /* Functions may have been compiled at various levels of
	 optimization so we can't use `same_size' here.
	 Instead, have the linker pick one, without warning.
	 If 'selectany' attibute has been specified,  MS compiler
	 sets 'discard' characteristic, rather than telling linker
	 to warn of size or content mismatch, so do the same.  */ 
 /* APPLE LOCAL begin mainline 2005-04-01 */
      bool discard = (flags & SECTION_CODE)
		      || lookup_attribute ("selectany",
					   DECL_ATTRIBUTES (decl));	 
      fprintf (asm_out_file, "\t.linkonce %s\n",
	       (discard  ? "discard" : "same_size"));
 /* APPLE LOCAL end mainline 2005-10-12 */
    }
}
Exemplo n.º 28
0
int
c_cannot_inline_tree_fn (tree *fnp)
{
  tree fn = *fnp;
  bool do_warning = (warn_inline
                     && DECL_INLINE (fn)
                     && DECL_DECLARED_INLINE_P (fn)
                     && !DECL_IN_SYSTEM_HEADER (fn));

  if (flag_really_no_inline
      && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
    {
      if (do_warning)
        warning (OPT_Winline, "function %q+F can never be inlined because it "
                 "is suppressed using -fno-inline", fn);
      goto cannot_inline;
    }

  /* Don't auto-inline anything that might not be bound within
     this unit of translation.  */
  if (!DECL_DECLARED_INLINE_P (fn) && !targetm.binds_local_p (fn))
    {
      if (do_warning)
        warning (OPT_Winline, "function %q+F can never be inlined because it "
                 "might not be bound within this unit of translation", fn);
      goto cannot_inline;
    }

  if (!function_attribute_inlinable_p (fn))
    {
      if (do_warning)
        warning (OPT_Winline, "function %q+F can never be inlined because it "
                 "uses attributes conflicting with inlining", fn);
      goto cannot_inline;
    }

  return 0;

 cannot_inline:
  DECL_UNINLINABLE (fn) = 1;
  return 1;
}
Exemplo n.º 29
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;
}
Exemplo n.º 30
0
/* Return false if the function FNDECL cannot be inlined on account of its
   attributes, true otherwise.  */
bool
function_attribute_inlinable_p (const_tree fndecl)
{
  if (targetm.attribute_table)
    {
      const_tree a;

      for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a))
	{
	  const_tree name = TREE_PURPOSE (a);
	  int i;

	  for (i = 0; targetm.attribute_table[i].name != NULL; i++)
	    if (is_attribute_p (targetm.attribute_table[i].name, name))
	      return targetm.function_attribute_inlinable_p (fndecl);
	}
    }

  return true;
}