OSDN Git Service

PR target/49104
[pf3gnuchains/gcc-fork.git] / libcpp / lex.c
index a94e572..bbce62c 100644 (file)
@@ -294,7 +294,7 @@ static const char repl_chars[4][16] __attribute__((aligned(16))) = {
 /* A version of the fast scanner using MMX vectorized byte compare insns.
 
    This uses the PMOVMSKB instruction which was introduced with "MMX2",
-   which was packaged into SSE1; it is also present in the AMD 3dNOW-A
+   which was packaged into SSE1; it is also present in the AMD MMX
    extension.  Mark the function as using "sse" so that we emit a real
    "emms" instruction, rather than the 3dNOW "femms" instruction.  */
 
@@ -410,6 +410,7 @@ search_line_sse2 (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
   return (const uchar *)p + found;
 }
 
+#ifdef HAVE_SSE4
 /* A version of the fast scanner using SSE 4.2 vectorized string insns.  */
 
 static const uchar *
@@ -464,6 +465,11 @@ search_line_sse42 (const uchar *s, const uchar *end)
   return s + index;
 }
 
+#else
+/* Work around out-dated assemblers without sse4 support.  */
+#define search_line_sse42 search_line_sse2
+#endif
+
 /* Check the CPU capabilities.  */
 
 #include "../gcc/config/i386/cpuid.h"
@@ -482,7 +488,7 @@ init_vectorized_lexer (void)
   minimum = 3;
 #elif defined(__SSE2__)
   minimum = 2;
-#elif defined(__SSE__) || defined(__3dNOW_A__)
+#elif defined(__SSE__)
   minimum = 1;
 #endif
 
@@ -499,14 +505,14 @@ init_vectorized_lexer (void)
     }
   else if (__get_cpuid (0x80000001, &dummy, &dummy, &dummy, &edx))
     {
-      if (minimum == 1 || edx & bit_3DNOWP)
+      if (minimum == 1 || (edx & (bit_MMXEXT | bit_CMOV)))
        impl = search_line_mmx;
     }
 
   search_line_fast = impl;
 }
 
-#elif defined(__GNUC__) && defined(__ALTIVEC__)
+#elif (GCC_VERSION >= 4005) && defined(__ALTIVEC__)
 
 /* A vection of the fast scanner using AltiVec vectorized byte compares.  */
 /* ??? Unfortunately, attribute(target("altivec")) is not yet supported,
@@ -1404,7 +1410,9 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
                                       raw_prefix_len) == 0
                           && cur[raw_prefix_len+1] == '"')
                    {
-                     cur += raw_prefix_len+2;
+                     BUF_APPEND (")", 1);
+                     base++;
+                     cur += raw_prefix_len + 2;
                      goto break_outer_loop;
                    }
                  else
@@ -1635,7 +1643,7 @@ save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from,
              cppchar_t type)
 {
   unsigned char *buffer;
-  unsigned int len, clen;
+  unsigned int len, clen, i;
 
   len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'.  */
 
@@ -1644,13 +1652,14 @@ save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from,
   if (is_vspace (pfile->buffer->cur[-1]))
     len--;
 
-  /* If we are currently in a directive, then we need to store all
-     C++ comments as C comments internally, and so we need to
-     allocate a little extra space in that case.
+  /* If we are currently in a directive or in argument parsing, then
+     we need to store all C++ comments as C comments internally, and
+     so we need to allocate a little extra space in that case.
 
      Note that the only time we encounter a directive here is
      when we are saving comments in a "#define".  */
-  clen = (pfile->state.in_directive && type == '/') ? len + 2 : len;
+  clen = ((pfile->state.in_directive || pfile->state.parsing_args)
+         && type == '/') ? len + 2 : len;
 
   buffer = _cpp_unaligned_alloc (pfile, clen);
 
@@ -1662,11 +1671,16 @@ save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from,
   memcpy (buffer + 1, from, len - 1);
 
   /* Finish conversion to a C comment, if necessary.  */
-  if (pfile->state.in_directive && type == '/')
+  if ((pfile->state.in_directive || pfile->state.parsing_args) && type == '/')
     {
       buffer[1] = '*';
       buffer[clen - 2] = '*';
       buffer[clen - 1] = '/';
+      /* As there can be in a C++ comments illegal sequences for C comments
+         we need to filter them out.  */
+      for (i = 2; i < (clen - 2); i++)
+        if (buffer[i] == '/' && (buffer[i - 1] == '*' || buffer[i + 1] == '*'))
+          buffer[i] = '|';
     }
 
   /* Finally store this comment for use by clients of libcpp. */