示例#1
0
static void
cb_def_pragma (cpp_reader *pfile, source_location loc)
{
  /* Issue a warning message if we have been asked to do so.  Ignore
     unknown pragmas in system headers unless an explicit
     -Wunknown-pragmas has been given.  */
  if (warn_unknown_pragmas > in_system_header)
    {
      const unsigned char *space, *name;
      const cpp_token *s;
#ifndef USE_MAPPED_LOCATION
      location_t fe_loc;
      const struct line_map *map = linemap_lookup (&line_table, loc);
      fe_loc.file = map->to_file;
      fe_loc.line = SOURCE_LINE (map, loc);
#else
      location_t fe_loc = loc;
#endif

      space = name = (const unsigned char *) "";
      s = cpp_get_token (pfile);
      if (s->type != CPP_EOF)
	{
	  space = cpp_token_as_text (pfile, s);
	  s = cpp_get_token (pfile);
	  if (s->type == CPP_NAME)
	    name = cpp_token_as_text (pfile, s);
	}

      warning (OPT_Wunknown_pragmas, "%Hignoring #pragma %s %s",
	       &fe_loc, space, name);
    }
}
示例#2
0
static cpp_hashnode *
spu_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
{
    cpp_hashnode *expand_this = tok->val.node.node;
    cpp_hashnode *ident;

    ident = spu_categorize_keyword (tok);
    if (ident == C_CPP_HASHNODE (__vector_keyword))
    {
        tok = cpp_peek_token (pfile, 0);
        ident = spu_categorize_keyword (tok);

        if (ident)
        {
            enum rid rid_code = (enum rid)(ident->rid_code);
            if (ident->type == NT_MACRO)
            {
                (void) cpp_get_token (pfile);
                tok = cpp_peek_token (pfile, 0);
                ident = spu_categorize_keyword (tok);
                if (ident)
                    rid_code = (enum rid)(ident->rid_code);
            }

            if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
                    || rid_code == RID_SHORT || rid_code == RID_SIGNED
                    || rid_code == RID_INT || rid_code == RID_CHAR
                    || rid_code == RID_FLOAT || rid_code == RID_DOUBLE)
                expand_this = C_CPP_HASHNODE (__vector_keyword);
        }
    }
    return expand_this;
}
示例#3
0
文件: cpplex.c 项目: Fokycnuk/gcc
/* Output all the remaining tokens on the current line, and a newline
   character, to FP.  Leading whitespace is removed.  If there are
   macros, special token padding is not performed.  */
void
cpp_output_line (cpp_reader *pfile, FILE *fp)
{
  const cpp_token *token;

  token = cpp_get_token (pfile);
  while (token->type != CPP_EOF)
    {
      cpp_output_token (token, fp);
      token = cpp_get_token (pfile);
      if (token->flags & PREV_WHITE)
	putc (' ', fp);
    }

  putc ('\n', fp);
}
示例#4
0
文件: scan-decls.c 项目: mmcx/cegcc
/* Get a token but skip padding.  */
static const cpp_token *
get_a_token (cpp_reader *pfile)
{
  for (;;)
    {
      const cpp_token *result = cpp_get_token (pfile);
      if (result->type != CPP_PADDING)
	return result;
    }
}
示例#5
0
int
yy_get_token ()
{
  for (;;)
    {
      parse_in.limit = parse_in.token_buffer;
      cpp_token = cpp_get_token (&parse_in);
      if (cpp_token == CPP_EOF)
	return -1;
      yy_lim = CPP_PWRITTEN (&parse_in);
      yy_cur = parse_in.token_buffer;
      if (yy_cur < yy_lim)
	return *yy_cur++;
    }
}
示例#6
0
文件: c-lex.c 项目: aosm/llvmgcc42
void
iasm_skip_to_eol (void)
{
  const cpp_token *tok;
  int old_lang = CPP_OPTION (parse_in, lang);

  /* Avoid problems with unmatches '" in comments.  */
  CPP_OPTION (parse_in, lang) = CLK_ASM;
  do
    tok = cpp_get_token (parse_in);
  while (tok->type != CPP_EOF && !(tok->flags & BOL));

  CPP_OPTION (parse_in, lang) = old_lang;

  /* Now put it back.  */
  _cpp_backup_tokens (parse_in, 1);
}
示例#7
0
/* Writes out the preprocessed file, handling spacing and paste
   avoidance issues.  */
static void
scan_translation_unit (cpp_reader *pfile)
{
    bool avoid_paste = false;

    print.source = NULL;
    for (;;)
    {
        const cpp_token *token = cpp_get_token (pfile);

        if (token->type == CPP_PADDING)
        {
            avoid_paste = true;
            if (print.source == NULL
                    || (!(print.source->flags & PREV_WHITE)
                        && token->val.source == NULL))
                print.source = token->val.source;
            continue;
        }

        if (token->type == CPP_EOF)
            break;

        /* Subtle logic to output a space if and only if necessary.  */
        if (avoid_paste)
        {
            if (print.source == NULL)
                print.source = token;
            if (print.source->flags & PREV_WHITE
                    || (print.prev
                        && cpp_avoid_paste (pfile, print.prev, token))
                    || (print.prev == NULL && token->type == CPP_HASH))
                putc (' ', print.outf);
        }
        else if (token->flags & PREV_WHITE)
            putc (' ', print.outf);

        avoid_paste = false;
        print.source = NULL;
        print.prev = token;
        cpp_output_token (token, print.outf);

        if (token->type == CPP_COMMENT)
            account_for_newlines (token->val.str.text, token->val.str.len);
    }
}
示例#8
0
static enum cpp_ttype
lex_string (const cpp_token *tok, tree *valp, bool objc_string)
{
  tree value;
  bool wide = false;
  size_t concats = 0;
  struct obstack str_ob;
  cpp_string istr;

  /* Try to avoid the overhead of creating and destroying an obstack
     for the common case of just one string.  */
  cpp_string str = tok->val.str;
  cpp_string *strs = &str;

  if (tok->type == CPP_WSTRING)
    wide = true;

 retry:
  tok = cpp_get_token (parse_in);
  switch (tok->type)
    {
    case CPP_PADDING:
      goto retry;
    case CPP_ATSIGN:
      if (c_dialect_objc ())
	{
	  objc_string = true;
	  goto retry;
	}
      /* FALLTHROUGH */
      
    default:
      break;
      
    case CPP_WSTRING:
      wide = true;
      /* FALLTHROUGH */
      
    case CPP_STRING:
      if (!concats)
	{
	  gcc_obstack_init (&str_ob);
	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
	}
	
      concats++;
      obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
      goto retry;
    }

  /* We have read one more token than we want.  */
  _cpp_backup_tokens (parse_in, 1);
  if (concats)
    strs = XOBFINISH (&str_ob, cpp_string *);

  if (concats && !objc_string && !in_system_header)
    warning (OPT_Wtraditional,
	     "traditional C rejects string constant concatenation");

  if ((c_lex_string_translate
       ? cpp_interpret_string : cpp_interpret_string_notranslate)
      (parse_in, strs, concats + 1, &istr, wide))
    {
      value = build_string (istr.len, (char *) istr.text);
      free ((void *) istr.text);

      if (c_lex_string_translate == -1)
	{
	  int xlated = cpp_interpret_string_notranslate (parse_in, strs,
							 concats + 1,
							 &istr, wide);
	  /* Assume that, if we managed to translate the string above,
	     then the untranslated parsing will always succeed.  */
	  gcc_assert (xlated);
	  
	  if (TREE_STRING_LENGTH (value) != (int) istr.len
	      || 0 != strncmp (TREE_STRING_POINTER (value), (char *) istr.text,
			       istr.len))
	    {
	      /* Arrange for us to return the untranslated string in
		 *valp, but to set up the C type of the translated
		 one.  */
	      *valp = build_string (istr.len, (char *) istr.text);
	      valp = &TREE_CHAIN (*valp);
	    }
	  free ((void *) istr.text);
	}
    }
  else
    {
      /* Callers cannot generally handle error_mark_node in this context,
	 so return the empty string instead.  cpp_interpret_string has
	 issued an error.  */
      if (wide)
	value = build_string (TYPE_PRECISION (wchar_type_node)
			      / TYPE_PRECISION (char_type_node),
			      "\0\0\0");  /* widest supported wchar_t
					     is 32 bits */
      else
	value = build_string (1, "");
    }

  TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
  *valp = fix_string_type (value);

  if (concats)
    obstack_free (&str_ob, 0);

  return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
}
示例#9
0
enum cpp_ttype
c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
{
  static bool no_more_pch;
  const cpp_token *tok;
  enum cpp_ttype type;

  timevar_push (TV_CPP);
 retry:
  tok = cpp_get_token (parse_in);
  type = tok->type;
  
 retry_after_at:
#ifdef USE_MAPPED_LOCATION
  *loc = tok->src_loc;
#else
  *loc = input_location;
#endif
  switch (type)
    {
    case CPP_PADDING:
      goto retry;
      
    case CPP_NAME:
      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
      break;

    case CPP_NUMBER:
      {
	unsigned int flags = cpp_classify_number (parse_in, tok);

	switch (flags & CPP_N_CATEGORY)
	  {
	  case CPP_N_INVALID:
	    /* cpplib has issued an error.  */
	    *value = error_mark_node;
	    errorcount++;
	    break;

	  case CPP_N_INTEGER:
	    *value = interpret_integer (tok, flags);
	    break;

	  case CPP_N_FLOATING:
	    *value = interpret_float (tok, flags);
	    break;

	  default:
	    gcc_unreachable ();
	  }
      }
      break;

    case CPP_ATSIGN:
      /* An @ may give the next token special significance in Objective-C.  */
      if (c_dialect_objc ())
	{
	  location_t atloc = input_location;
	  
	retry_at:
	  tok = cpp_get_token (parse_in);
	  type = tok->type;
	  switch (type)
	    {
	    case CPP_PADDING:
	      goto retry_at;
	      
	    case CPP_STRING:
	    case CPP_WSTRING:
	      type = lex_string (tok, value, true);
	      break;

	    case CPP_NAME:
	      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
	      if (objc_is_reserved_word (*value))
		{
		  type = CPP_AT_NAME;
		  break;
		}
	      /* FALLTHROUGH */

	    default:
	      /* ... or not.  */
	      error ("%Hstray %<@%> in program", &atloc);
	      goto retry_after_at;
	    }
	  break;
	}

      /* FALLTHROUGH */
    case CPP_HASH:
    case CPP_PASTE:
      {
	unsigned char name[4];
	
	*cpp_spell_token (parse_in, tok, name, true) = 0;
	
	error ("stray %qs in program", name);
      }
      
      goto retry;

    case CPP_OTHER:
      {
	cppchar_t c = tok->val.str.text[0];

	if (c == '"' || c == '\'')
	  error ("missing terminating %c character", (int) c);
	else if (ISGRAPH (c))
	  error ("stray %qc in program", (int) c);
	else
	  error ("stray %<\\%o%> in program", (int) c);
      }
      goto retry;

    case CPP_CHAR:
    case CPP_WCHAR:
      *value = lex_charconst (tok);
      break;

    case CPP_STRING:
    case CPP_WSTRING:
      if (!c_lex_return_raw_strings)
	{
	  type = lex_string (tok, value, false);
	  break;
	}
      
      /* FALLTHROUGH */

    case CPP_PRAGMA:
      *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
      break;

      /* These tokens should not be visible outside cpplib.  */
    case CPP_HEADER_NAME:
    case CPP_COMMENT:
    case CPP_MACRO_ARG:
      gcc_unreachable ();

    default:
      *value = NULL_TREE;
      break;
    }

  if (cpp_flags)
    *cpp_flags = tok->flags;

  if (!no_more_pch)
    {
      no_more_pch = true;
      c_common_no_more_pch ();
    }
  
  timevar_pop (TV_CPP);
  
  return type;
}
示例#10
0
文件: c-lex.c 项目: aosm/llvmgcc42
enum cpp_ttype
/* APPLE LOCAL CW asm blocks C++ comments 6338079 */
c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, int defer)
{
  static bool no_more_pch;
  const cpp_token *tok;
  enum cpp_ttype type;
  unsigned char add_flags = 0;
  /* APPLE LOCAL CW asm blocks C++ */
  const cpp_token *lasttok;
  /* APPLE LOCAL begin CW asm blocks */
  /* Make a local copy of the flag for efficiency, since the compiler can't
     figure that it won't change during a compilation.  */
  int flag_iasm_blocks_local = flag_iasm_blocks;
  if (flag_iasm_blocks_local)
    ++c_lex_depth;
  /* APPLE LOCAL end CW asm blocks */

  timevar_push (TV_CPP);
 retry:
  /* APPLE LOCAL begin CW asm blocks */
  /* If there's a token we saved while returning the special BOL
     token, return it now.  */
  if (iasm_saved_token)
    {
      tok = iasm_saved_token;
      type = tok->type;
      iasm_saved_token = NULL;
      goto bypass;
    }
  /* APPLE LOCAL end CW asm blocks */
  tok = cpp_get_token (parse_in);
  type = tok->type;

  /* APPLE LOCAL begin CW asm blocks */
  /* This test should be as efficient as possible, because it affects
       all lexing with or without CW asm enabled.  */
  if (flag_iasm_blocks_local && iasm_state != iasm_none && c_lex_depth == 1
      && type != CPP_PADDING)
    {
      /* "}" switches us out of our special mode.  */
      if (tok->type == CPP_CLOSE_BRACE && iasm_state >= iasm_decls)
	iasm_state = iasm_none;

      /* This is tricky.  We're only ready to start parsing assembly
	 instructions if we're in the asm block, we're not in the
	 middle of parsing a C decl, and the next token is plausibly
	 the beginning of an asm line.  This works because if we have
	 a "typedef int nop", a nop at the beginning of a line should
	 be taken as an instruction rather than a declaration of type
	 nop.  (Doesn't have to go this way, but it's how CW works.)
	 We're not quite as good as CW yet, because CW knows about the
	 complete list of valid opcodes, and will try to take anything
	 as a decl that is not in the opcode list.  */
      if (iasm_state == iasm_decls
	  && !iasm_in_decl)
	{
	  if (tok->type == CPP_ATSIGN
	      || tok->type == CPP_DOT
	      || (tok->type == CPP_SEMICOLON)
	      || (tok->type == CPP_NAME
		  && (*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node)))
		  && !iasm_typename_or_reserved (*value)))
	    {
	      iasm_state = iasm_asm;
	      inside_iasm_block = true;
	    }
	  else
	    {
	      iasm_in_decl = true;
	    }
	}
    }
 bypass:
  /* APPLE LOCAL end CW asm blocks */

 retry_after_at:
#ifdef USE_MAPPED_LOCATION
  *loc = tok->src_loc;
#else
  *loc = input_location;
#endif
  switch (type)
    {
    case CPP_PADDING:
      goto retry;

    case CPP_NAME:
      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
      /* APPLE LOCAL begin CW asm blocks */
      if (iasm_state >= iasm_decls
	  && flag_ms_asms
	  && strcasecmp (IDENTIFIER_POINTER (HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node))),
			 "offset") == 0)
	{
	  type = CPP_AND;
	  *value = NULL_TREE;
	  break;
	}
      /* APPLE LOCAL end CW asm blocks */
      break;

    case CPP_NUMBER:
      {
	/* APPLE LOCAL CW asm blocks C++ comments 6338079 */
	unsigned int flags = cpp_classify_number (parse_in, tok, defer);

	switch (flags & CPP_N_CATEGORY)
	  {
	  case CPP_N_INVALID:
	    /* APPLE LOCAL begin CW asm blocks C++ comments 6338079 */
	    if (flags & CPP_N_DEFER)
	      {
		add_flags = ERROR_DEFERRED;
		*value = error_mark_node;
		break;
	      }
	    /* APPLE LOCAL end CW asm blocks C++ comments 6338079 */

	    /* cpplib has issued an error.  */
	    *value = error_mark_node;
	    errorcount++;
	    break;

	  case CPP_N_INTEGER:
	    /* C++ uses '0' to mark virtual functions as pure.
	       Set PURE_ZERO to pass this information to the C++ parser.  */
	    if (tok->val.str.len == 1 && *tok->val.str.text == '0')
	      add_flags = PURE_ZERO;
	    *value = interpret_integer (tok, flags);
	    break;

	  case CPP_N_FLOATING:
	    *value = interpret_float (tok, flags);
	    break;

	  default:
	    gcc_unreachable ();
	  }
      }
      break;

    case CPP_ATSIGN:
      /* APPLE LOCAL begin CW asm blocks */
      if (iasm_state >= iasm_decls)
	{
	  /* Return the @-sign verbatim.  */
	  *value = NULL_TREE;
	  break;
	}
      lasttok = tok;
      /* APPLE LOCAL end CW asm blocks */

      /* An @ may give the next token special significance in Objective-C.  */
      if (c_dialect_objc ())
	{
	  location_t atloc = input_location;

	  /* APPLE LOCAL CW asm blocks */
	  ++parse_in->keep_tokens;
	retry_at:
	  tok = cpp_get_token (parse_in);
	  type = tok->type;
	  switch (type)
	    {
	    case CPP_PADDING:
	      goto retry_at;

	    case CPP_STRING:
	    case CPP_WSTRING:
	      type = lex_string (tok, value, true);
	      break;

	    case CPP_NAME:
	      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
	      if (objc_is_reserved_word (*value))
		{
		  type = CPP_AT_NAME;
		  break;
		}
	      /* FALLTHROUGH */

	    default:
	      /* APPLE LOCAL begin CW asm blocks C++ */
	      if (flag_iasm_blocks_local)
                {
                  /* This is necessary for C++, as we don't have the tight
                     integration between the lexer and the parser... */
		  _cpp_backup_tokens (parse_in, 1);
                  /* Return the @-sign verbatim.  */
                  *value = NULL;
                  tok = lasttok;
		  type = tok->type;
                  break;
                }
	      /* APPLE LOCAL end CW asm blocks C++ */

	      /* ... or not.  */
	      error ("%Hstray %<@%> in program", &atloc);
	      goto retry_after_at;
	    }
	  /* APPLE LOCAL CW asm blocks */
	  --parse_in->keep_tokens;
	  break;
	}
	/* APPLE LOCAL begin CW asm blocks C++ */
	if (flag_iasm_blocks_local)
	  {
	    /* This is necessary for C++, as we don't have the tight
	       integration between the lexer and the parser... */
	    /* Return the @-sign verbatim.  */
	    *value = NULL;
	    break;
	  }
       /* APPLE LOCAL end CW asm blocks C++ */
	      
      /* FALLTHROUGH */
    case CPP_HASH:
    case CPP_PASTE:
      /* APPLE LOCAL begin CW asm blocks C++ comments 4248139 */
      /* Because we don't recognize inline asm commments during
	 lexing, we have to pass this back to the parser to error out
	 with or eat as a comment as appropriate.  */
      if (flag_iasm_blocks_local)
	{
	  *value = NULL;
	  break;
	}
      /* APPLE LOCAL end CW asm blocks C++ comments 4248139 */
      {
	unsigned char name[4];

	*cpp_spell_token (parse_in, tok, name, true) = 0;

	error ("stray %qs in program", name);
      }

      goto retry;

    case CPP_OTHER:
      {
	cppchar_t c = tok->val.str.text[0];

	/* APPLE LOCAL begin CW asm blocks C++ comments 4248139 */
	/* Because we don't recognize inline asm commments during
	   lexing, we have to pass this back to the parser to error
	   out with or eat as a comment as appropriate.  */
	if (defer && flag_iasm_blocks_local)
	  {
	    *value = build_int_cst_wide (char_type_node, c, 0);
	    break;
	  }
	/* APPLE LOCAL end CW asm blocks C++ comments 4248139 */
	if (c == '"' || c == '\'')
	  error ("missing terminating %c character", (int) c);
	else if (ISGRAPH (c))
	  error ("stray %qc in program", (int) c);
	else
	  error ("stray %<\\%o%> in program", (int) c);
      }
      goto retry;

    case CPP_CHAR:
    case CPP_WCHAR:
      *value = lex_charconst (tok);
      break;

    case CPP_STRING:
    case CPP_WSTRING:
      if (!c_lex_return_raw_strings)
	{
	  type = lex_string (tok, value, false);
	  break;
	}
      *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
      break;
      
    case CPP_PRAGMA:
      *value = build_int_cst (NULL, tok->val.pragma);
      break;

    /* APPLE LOCAL begin CW asm blocks */
    case CPP_MULT:
      if (inside_iasm_block)
        {
	  /* Check and replace use of '*' with '.' if '*' is followed by '-'
	     or '+'. This is to allow "b *+8" which is disallwed by darwin's
	     assembler but nevertheless is needed to be compatible with CW tools. */
  	  lasttok = tok;
	  ++parse_in->keep_tokens;
	  do
              tok = cpp_get_token (parse_in);
          while (tok->type == CPP_PADDING);
	  _cpp_backup_tokens (parse_in, 1);
	  --parse_in->keep_tokens;
	  if (tok->type == CPP_PLUS || tok->type == CPP_MINUS)
	      type = CPP_DOT;
	  tok = lasttok;
        }
      *value = NULL_TREE;
      break;
    /* APPLE LOCAL end CW asm blocks */
    /* APPLE LOCAL begin 4137741 */
    /* For CPP_BINCL and CPP_EINCL tokens, we shall need to propagate
       line number information; the location field shall already include
       the desired file name.  */
    case CPP_BINCL:
    case CPP_EINCL:
      *value = build_int_cst (integer_type_node, (HOST_WIDE_INT) tok->src_loc);
      break;

    /* APPLE LOCAL end 4137741 */
      /* These tokens should not be visible outside cpplib.  */
    case CPP_HEADER_NAME:
    case CPP_COMMENT:
    case CPP_MACRO_ARG:
      gcc_unreachable ();

    default:
      *value = NULL_TREE;
      break;
    }

  if (cpp_flags)
    *cpp_flags = tok->flags | add_flags;

  /* APPLE LOCAL begin CW asm blocks */
  if (flag_iasm_blocks_local)
    --c_lex_depth;
  /* APPLE LOCAL end CW asm blocks */

    /* APPLE LOCAL begin 4137741 */
  if (!no_more_pch
      && type != CPP_BINCL
      && type != CPP_EINCL)
    /* APPLE LOCAL end 4137741 */
    {
      no_more_pch = true;
      c_common_no_more_pch ();
    }

  timevar_pop (TV_CPP);

  return type;
}
示例#11
0
/* handler function for the config pragma */
void
mchp_handle_config_pragma (struct cpp_reader *pfile)
{
  enum cpp_ttype tok;
  tree tok_value;
  static int shown_no_config_warning = 0;

  /* If we're compiling for the default device, we don't process
     configuration words */
  if (!mchp_processor_string)
    {
      error ("#pragma config directive not available for the default generic device, %s", mchp_processor_string);
      CLEAR_REST_OF_INPUT_LINE();
      return;
    }

  if (!mchp_config_data_dir)
    {
      error ("Configuration-word data directory not specified "
             "but required for #pragma config directive");
      CLEAR_REST_OF_INPUT_LINE();
      return;
    }

  /* the first time we see a config pragma, we need to load the
     configuration word data from the definition file. */
  if (!mchp_configuration_values)
    {
      /* alloc space for the filename: directory + '/' + "configuration.data"
       */
      char *fname = (char*)alloca (strlen (mchp_config_data_dir) + 1 +
                            strlen (MCHP_CONFIGURATION_DATA_FILENAME));
      strcpy (fname, mchp_config_data_dir);
      if (fname [strlen (fname) - 1] != '/'
          && fname [strlen (fname) - 1] != '\\')
        strcat (fname, "/");
      strcat (fname, MCHP_CONFIGURATION_DATA_FILENAME);

      if (mchp_load_configuration_definition (fname))
        {
          if (!shown_no_config_warning)
            {
              shown_no_config_warning = 1;
              warning (0, "configuration word information not available for "
                       "this processor. #pragma config is ignored.");
            }
          CLEAR_REST_OF_INPUT_LINE();
          return;
        }
    }

  /* The payload for the config pragma is a comma delimited list of
     "setting = value" pairs. Both the setting and the value must
     be valid C identifiers. */
  tok = pragma_lex (&tok_value);
  while (1)
    {
      const cpp_token *raw_token;
      const char *setting_name;
      const char *value_name;

      /* the current token should be the setting name */
      if (tok != CPP_NAME)
        {
          error ("configuration setting name expected in configuration pragma");
          break;
        }

      setting_name = IDENTIFIER_POINTER (tok_value);
      /* the next token should be the '=' */
      tok = pragma_lex (&tok_value);
      if (tok != CPP_EQ)
        {
          error ("'=' expected in configuration pragma");
          break;
        }
      /* now we have the value name. We don't use pragma_lex() to get this one
         since we don't want the additional interpretation going on there.
         i.e., converting integers from the string. */
      raw_token = cpp_get_token (pfile);

      if (raw_token->type == CPP_NAME)
        {
        /*
          value_name = IDENTIFIER_POINTER (
                         HT_IDENT_TO_GCC_IDENT (
                         HT_NODE (raw_token->val.node)));
           space?              */
          value_name = cpp_token_as_text (pfile, raw_token);

        }
      else if (raw_token->type == CPP_NUMBER)
        {
          value_name = (char*)raw_token->val.str.text;
        }
      else
        {
          error ("configuration value name expected in configuration pragma");
          break;
        }

      mchp_handle_configuration_setting (setting_name, value_name);

      /* if the next token is ',' then we have another setting. */
      tok = pragma_lex (&tok_value);
      if (tok == CPP_COMMA)
        tok = pragma_lex (&tok_value);
      /* if it's EOF, we're done */
      else if (tok == CPP_EOF)
        break;
      /* otherwise, we have spurious input */
      else
        {
          error ("',' or end of line expected in configuration pragma");
          break;
        }
    }
  /* if we ended for any reason other than end of line, we have an error.
     Any needed diagnostic should have already been issued, so just
     clear the rest of the data on the line. */
  if (tok != CPP_EOF)
    CLEAR_REST_OF_INPUT_LINE();
}
示例#12
0
static cpp_hashnode *
s390_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
{
  cpp_hashnode *expand_this = tok->val.node.node;
  cpp_hashnode *ident;
  static bool expand_bool_p = false;
  int idx = 0;
  enum rid rid_code;

  /* The vector keyword is only expanded if the machine actually
     provides hardware support.  */
  if (!TARGET_ZVECTOR)
    return NULL;

  ident = s390_categorize_keyword (tok);

  /* Triggered when we picked a different variant in
     s390_categorize_keyword.  */
  if (ident != expand_this)
    expand_this = NULL;

  /* The vector keyword has been found already and we remembered to
     expand the next bool.  */
  if (expand_bool_p && ident == C_CPP_HASHNODE (__bool_keyword))
    {
      expand_bool_p = false;
      return ident;
    }

  if (ident != C_CPP_HASHNODE (__vector_keyword))
    return expand_this;

  do
    tok = cpp_peek_token (pfile, idx++);
  while (tok->type == CPP_PADDING);
  ident = s390_categorize_keyword (tok);

  if (!ident)
    return expand_this;

  /* vector bool - remember to expand the next bool. */
  if (ident == C_CPP_HASHNODE (__bool_keyword))
    {
      expand_bool_p = true;
      return C_CPP_HASHNODE (__vector_keyword);
    }

  /* The boost libraries have code with Iterator::vector vector in it.
     If we allow the normal handling, this module will be called
     recursively, and the vector will be skipped.; */
  if (ident == C_CPP_HASHNODE (__vector_keyword))
    return expand_this;

  rid_code = (enum rid)(ident->rid_code);

  if (ident->type == NT_MACRO)
    {
      /* Now actually fetch the tokens we "peeked" before and do a
	 lookahead for the next.  */
      do
	(void) cpp_get_token (pfile);
      while (--idx > 0);
      do
	tok = cpp_peek_token (pfile, idx++);
      while (tok->type == CPP_PADDING);
      ident = s390_categorize_keyword (tok);

      if (ident == C_CPP_HASHNODE (__bool_keyword))
	{
	  expand_bool_p = true;
	  return C_CPP_HASHNODE (__vector_keyword);
	}
      else if (ident)
	rid_code = (enum rid)(ident->rid_code);
    }

  /* vector keyword followed by type identifier: vector unsigned,
     vector long, ...
     Types consisting of more than one identifier are not supported by
     zvector e.g. long long, long double, unsigned long int.  */
  if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
      || rid_code == RID_SHORT || rid_code == RID_SIGNED
      || rid_code == RID_INT || rid_code == RID_CHAR
      || rid_code == RID_DOUBLE)
    {
      expand_this = C_CPP_HASHNODE (__vector_keyword);
      /* If the next keyword is bool, it will need to be expanded as
	 well.  */
      do
	tok = cpp_peek_token (pfile, idx++);
      while (tok->type == CPP_PADDING);
      ident = s390_categorize_keyword (tok);

      /* __vector long __bool a; */
      if (ident == C_CPP_HASHNODE (__bool_keyword))
	expand_bool_p = true;
      else
	{
	  /* Triggered with: __vector long long __bool a; */
	  do
	    tok = cpp_peek_token (pfile, idx++);
	  while (tok->type == CPP_PADDING);
	  ident = s390_categorize_keyword (tok);

	  if (ident == C_CPP_HASHNODE (__bool_keyword))
	    expand_bool_p = true;
	}
    }

  return expand_this;
}