Handle :: tokens in C for C2x.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 2 Oct 2019 00:08:40 +0000 (01:08 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 2 Oct 2019 00:08:40 +0000 (01:08 +0100)
As part of adding [[]]-style attributes, C2x adds the token :: for use
in scoped attribute names.

This patch adds corresponding support for that token in C to GCC.  The
token is supported both for C2x and for older gnu* standards (on the
basis that extensions are normally supported in older gnu* versions;
people will expect to be able to use [[]] attributes, before C2x is
the default, without needing to use -std=gnu2x).

There are no cases in older C standards where the token : can be
followed by a token starting with : in syntactically valid sources;
the only cases the :: token could break in older standard C thus are
ones involving concatenation of pp-tokens where the result does not
end up as tokens (e.g., gets stringized).  In GNU C extensions, the
main case where :: might appear in existing sources is in asm
statements, and the C parser is thus made to handle it like two
consecutive : tokens, which the C++ parser already does.  A limited
test of various positionings of :: in asm statements is added to the
testsuite (in particular, to cover the syntax error when :: means too
many colons but a single : would be OK), but existing tests cover a
variety of styles there anyway.

Technically there are cases in Objective-C and OpenMP for which this
also changes how previously valid code is lexed: the objc-selector-arg
syntax allows multiple consecutive : tokens (although I don't think
they are particularly useful there), while OpenMP syntax includes
array section syntax such as [:] which, before :: was a token, could
also be written as [::> (there might be other OpenMP cases potentially
affected, I didn't check all the OpenMP syntax in detail).  I don't
think either of those cases affects the basis for supporting the ::
token in all -std=gnu* modes, or that there is any obvious need to
special-case handling of CPP_SCOPE tokens for those constructs the way
there is for asm statements.

cpp_avoid_paste, which determines when spaces need adding between
tokens in preprocessed output where there wouldn't otherwise be
whitespace between them (e.g. if stringized), already inserts space
between : and : unconditionally, rather than only for C++, so no
change is needed there (but a C2x test is added that such space is
indeed inserted).

Bootstrapped with no regressions on x86-64-pc-linux-gnu.

gcc/c:
* c-parser.c (c_parser_asm_statement): Handle CPP_SCOPE like two
CPP_COLON tokens.

gcc/testsuite:
* gcc.dg/asm-scope-1.c, gcc.dg/cpp/c11-scope-1.c,
gcc.dg/cpp/c17-scope-1.c, gcc.dg/cpp/c2x-scope-1.c,
gcc.dg/cpp/c2x-scope-2.c, gcc.dg/cpp/c90-scope-1.c,
gcc.dg/cpp/c94-scope-1.c, gcc.dg/cpp/c99-scope-1.c,
gcc.dg/cpp/gnu11-scope-1.c, gcc.dg/cpp/gnu17-scope-1.c,
gcc.dg/cpp/gnu89-scope-1.c, gcc.dg/cpp/gnu99-scope-1.c: New tests.

libcpp:
* include/cpplib.h (struct cpp_options): Add member scope.
* init.c (struct lang_flags, lang_defaults): Likewise.
(cpp_set_lang): Set scope member of pfile.
* lex.c (_cpp_lex_direct): Test CPP_OPTION (pfile, scope) not
CPP_OPTION (pfile, cplusplus) for creating CPP_SCOPE tokens.

From-SVN: r276434

19 files changed:
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/asm-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c11-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c17-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c2x-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c2x-scope-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c90-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c94-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c99-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/gnu11-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/gnu17-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/gnu89-scope-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/gnu99-scope-1.c [new file with mode: 0644]
libcpp/ChangeLog
libcpp/include/cpplib.h
libcpp/init.c
libcpp/lex.c

index 3156e35f39becb95615d436d4424efae07b68e16..0f263f78e4b2d18b5691e3187e99078b7ed4b2e0 100644 (file)
@@ -1,3 +1,8 @@
+2019-10-02  Joseph Myers  <joseph@codesourcery.com>
+
+       * c-parser.c (c_parser_asm_statement): Handle CPP_SCOPE like two
+       CPP_COLON tokens.
+
 2019-10-01  Richard Sandiford  <richard.sandiford@arm.com>
 
        * c-objc-common.c (useful_aka_type_p): New function.
index c8afab2bc2ea4d549cb842156fb64a517a67fdda..6957297b3a52e5fb8ea0c29781321c7a0b1098ac 100644 (file)
@@ -6411,7 +6411,9 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
 
    The form with asm-goto-operands is valid if and only if the
    asm-qualifier-list contains goto, and is the only allowed form in that case.
-   Duplicate asm-qualifiers are not allowed.  */
+   Duplicate asm-qualifiers are not allowed.
+
+   The :: token is considered equivalent to two consecutive : tokens.  */
 
 static tree
 c_parser_asm_statement (c_parser *parser)
@@ -6509,17 +6511,28 @@ c_parser_asm_statement (c_parser *parser)
   nsections = 3 + is_goto;
   for (section = 0; section < nsections; ++section)
     {
-      if (!c_parser_require (parser, CPP_COLON,
-                            is_goto
-                            ? G_("expected %<:%>")
-                            : G_("expected %<:%> or %<)%>"),
-                            UNKNOWN_LOCATION, is_goto))
+      if (c_parser_next_token_is (parser, CPP_SCOPE))
+       {
+         ++section;
+         if (section == nsections)
+           {
+             c_parser_error (parser, "expected %<)%>");
+             goto error_close_paren;
+           }
+         c_parser_consume_token (parser);
+       }
+      else if (!c_parser_require (parser, CPP_COLON,
+                                 is_goto
+                                 ? G_("expected %<:%>")
+                                 : G_("expected %<:%> or %<)%>"),
+                                 UNKNOWN_LOCATION, is_goto))
        goto error_close_paren;
 
       /* Once past any colon, we're no longer a simple asm.  */
       simple = false;
 
       if ((!c_parser_next_token_is (parser, CPP_COLON)
+          && !c_parser_next_token_is (parser, CPP_SCOPE)
           && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
          || section == 3)
        switch (section)
index 5949f0a215fd1c3b04ae808b08aba51c98edfd92..834ee454f9aa1180b816e53c1480345401459b9e 100644 (file)
@@ -1,3 +1,12 @@
+2019-10-02  Joseph Myers  <joseph@codesourcery.com>
+
+       * gcc.dg/asm-scope-1.c, gcc.dg/cpp/c11-scope-1.c,
+       gcc.dg/cpp/c17-scope-1.c, gcc.dg/cpp/c2x-scope-1.c,
+       gcc.dg/cpp/c2x-scope-2.c, gcc.dg/cpp/c90-scope-1.c,
+       gcc.dg/cpp/c94-scope-1.c, gcc.dg/cpp/c99-scope-1.c,
+       gcc.dg/cpp/gnu11-scope-1.c, gcc.dg/cpp/gnu17-scope-1.c,
+       gcc.dg/cpp/gnu89-scope-1.c, gcc.dg/cpp/gnu99-scope-1.c: New tests.
+
 2019-10-01  David Malcolm  <dmalcolm@redhat.com>
 
        * gcc.dg/plugin/diagnostic_group_plugin.c (test_begin_group_cb):
diff --git a/gcc/testsuite/gcc.dg/asm-scope-1.c b/gcc/testsuite/gcc.dg/asm-scope-1.c
new file mode 100644 (file)
index 0000000..6439104
--- /dev/null
@@ -0,0 +1,27 @@
+/* Test :: token handling in asm.  */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu2x" } */
+
+void
+f (void)
+{
+  asm ("");
+  asm ("" : );
+  asm ("" : :);
+  asm ("" ::);
+  asm ("" : : :);
+  asm ("" :: :);
+  asm ("" : ::);
+  asm goto ("" : : : : lab);
+  asm goto ("" :: : : lab);
+  asm goto ("" : :: : lab);
+  asm goto ("" : : :: lab);
+  asm goto ("" :: :: lab);
+ lab: ;
+  /* Test errors when :: is at the end of asm and only one : allowed.  */
+  asm ("" : : ::); /* { dg-error "expected" } */
+  asm ("" :: ::); /* { dg-error "expected" } */
+  asm goto ("" : : : :: lab); /* { dg-error "expected" } */
+  asm goto ("" :: : :: lab); /* { dg-error "expected" } */
+  asm goto ("" : :: :: lab); /* { dg-error "expected" } */
+}
diff --git a/gcc/testsuite/gcc.dg/cpp/c11-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c11-scope-1.c
new file mode 100644 (file)
index 0000000..2db0516
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token not in C11.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */
+CONCAT (::, >)
diff --git a/gcc/testsuite/gcc.dg/cpp/c17-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c17-scope-1.c
new file mode 100644 (file)
index 0000000..b5b366b
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token not in C17.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c17 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */
+CONCAT (::, >)
diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c2x-scope-1.c
new file mode 100644 (file)
index 0000000..8337ba7
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token in C2x.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :)
+CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-scope-2.c b/gcc/testsuite/gcc.dg/cpp/c2x-scope-2.c
new file mode 100644 (file)
index 0000000..73b36e7
--- /dev/null
@@ -0,0 +1,11 @@
+/* Test :: token in C2x: preprocessed output.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors -P" } */
+
+#define COLON() :
+#define TEST() ABC
+
+/* This must have a space inserted between the two ':' tokens in
+   preprocessed output.  */
+TEST()COLON()COLON()TEST()
+/* { dg-final { scan-file c2x-scope-2.i "ABC: :ABC" } } */
diff --git a/gcc/testsuite/gcc.dg/cpp/c90-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c90-scope-1.c
new file mode 100644 (file)
index 0000000..4c23e21
--- /dev/null
@@ -0,0 +1,7 @@
+/* Test :: token not in C90.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c90 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/c94-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c94-scope-1.c
new file mode 100644 (file)
index 0000000..0e6da01
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token not in C94.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=iso9899:199409 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */
+CONCAT (::, >)
diff --git a/gcc/testsuite/gcc.dg/cpp/c99-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c99-scope-1.c
new file mode 100644 (file)
index 0000000..e878286
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token not in C99.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */
+CONCAT (::, >)
diff --git a/gcc/testsuite/gcc.dg/cpp/gnu11-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu11-scope-1.c
new file mode 100644 (file)
index 0000000..2dea391
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token in gnu11.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=gnu11 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :)
+CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/gnu17-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu17-scope-1.c
new file mode 100644 (file)
index 0000000..0c5f20d
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token in gnu17.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=gnu17 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :)
+CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/gnu89-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu89-scope-1.c
new file mode 100644 (file)
index 0000000..812e62f
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token in gnu89.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=gnu89 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :)
+CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/gnu99-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu99-scope-1.c
new file mode 100644 (file)
index 0000000..5ba871d
--- /dev/null
@@ -0,0 +1,8 @@
+/* Test :: token in gnu99.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=gnu99 -pedantic-errors" } */
+
+#define CONCAT(x, y) x ## y
+
+CONCAT (:, :)
+CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */
index 1ca622df6fda1a7f30a3ef7b41f125651d740f1f..682caaccd969e1efb94fc0d102745d821fc5cd88 100644 (file)
@@ -1,3 +1,11 @@
+2019-10-02  Joseph Myers  <joseph@codesourcery.com>
+
+       * include/cpplib.h (struct cpp_options): Add member scope.
+       * init.c (struct lang_flags, lang_defaults): Likewise.
+       (cpp_set_lang): Set scope member of pfile.
+       * lex.c (_cpp_lex_direct): Test CPP_OPTION (pfile, scope) not
+       CPP_OPTION (pfile, cplusplus) for creating CPP_SCOPE tokens.
+
 2019-09-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * charset.c (UCS_LIMIT): New macro.
index a645f8136a6567b4cc28be3bf575d674b95be0ed..ccbcfde6dc452cf59da63dbab023315ee7e0be38 100644 (file)
@@ -483,6 +483,9 @@ struct cpp_options
   /* Nonzero for C++2a __VA_OPT__ feature.  */
   unsigned char va_opt;
 
+  /* Nonzero for the '::' token.  */
+  unsigned char scope;
+
   /* Holds the name of the target (execution) character set.  */
   const char *narrow_charset;
 
index ccbfc96489d918bb544dac99f96192ea17d6c907..c932598b5fbad0543be014ec59e693c564456889 100644 (file)
@@ -92,32 +92,33 @@ struct lang_flags
   char trigraphs;
   char utf8_char_literals;
   char va_opt;
+  char scope;
 };
 
 static const struct lang_flags lang_defaults[] =
-{ /*              c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt */
-  /* GNUC89   */  { 0,  0,  1,  0,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1 },
-  /* GNUC99   */  { 1,  0,  1,  1,  0,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1 },
-  /* GNUC11   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1 },
-  /* GNUC17   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1 },
-  /* GNUC2X   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1 },
-  /* STDC89   */  { 0,  0,  0,  0,  0,  1,  0,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC94   */  { 0,  0,  0,  0,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC99   */  { 1,  0,  1,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC11   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC17   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC2X   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0 },
-  /* GNUCXX   */  { 0,  1,  1,  1,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1 },
-  /* CXX98    */  { 0,  1,  0,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* GNUCXX11 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    0,     0,     0,   0,      1 },
-  /* CXX11    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    0,     0,     1,   0,      0 },
-  /* GNUCXX14 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   0,      1 },
-  /* CXX14    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    1,     1,     1,   0,      0 },
-  /* GNUCXX17 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1 },
-  /* CXX17    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      0 },
-  /* GNUCXX2A */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1 },
-  /* CXX2A    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1 },
-  /* ASM      */  { 0,  0,  1,  0,  0,  0,  0,   0,   0,   0,    0,     0,     0,   0,      0 }
+{ /*              c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt scope*/
+  /* GNUC89   */  { 0,  0,  1,  0,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   1 },
+  /* GNUC99   */  { 1,  0,  1,  1,  0,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1 },
+  /* GNUC11   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1 },
+  /* GNUC17   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1 },
+  /* GNUC2X   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   1 },
+  /* STDC89   */  { 0,  0,  0,  0,  0,  1,  0,   0,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC94   */  { 0,  0,  0,  0,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC99   */  { 1,  0,  1,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC11   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC17   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC2X   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   1 },
+  /* GNUCXX   */  { 0,  1,  1,  1,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   1 },
+  /* CXX98    */  { 0,  1,  0,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   1 },
+  /* GNUCXX11 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    0,     0,     0,   0,      1,   1 },
+  /* CXX11    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    0,     0,     1,   0,      0,   1 },
+  /* GNUCXX14 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   0,      1,   1 },
+  /* CXX14    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    1,     1,     1,   0,      0,   1 },
+  /* GNUCXX17 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1 },
+  /* CXX17    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      0,   1 },
+  /* GNUCXX2A */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1 },
+  /* CXX2A    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1 },
+  /* ASM      */  { 0,  0,  1,  0,  0,  0,  0,   0,   0,   0,    0,     0,     0,   0,      0,   0 }
 };
 
 /* Sets internal flags correctly for a given language.  */
@@ -143,6 +144,7 @@ cpp_set_lang (cpp_reader *pfile, enum c_lang lang)
   CPP_OPTION (pfile, trigraphs)                         = l->trigraphs;
   CPP_OPTION (pfile, utf8_char_literals)        = l->utf8_char_literals;
   CPP_OPTION (pfile, va_opt)                    = l->va_opt;
+  CPP_OPTION (pfile, scope)                     = l->scope;
 }
 
 /* Initialize library global state.  */
index 0e8de3807b3c38b18c27255eeea7b5e83f457ba5..3e7d1c37ff5edb83da573b2f47e7b65e39667905 100644 (file)
@@ -3104,7 +3104,7 @@ _cpp_lex_direct (cpp_reader *pfile)
 
     case ':':
       result->type = CPP_COLON;
-      if (*buffer->cur == ':' && CPP_OPTION (pfile, cplusplus))
+      if (*buffer->cur == ':' && CPP_OPTION (pfile, scope))
        buffer->cur++, result->type = CPP_SCOPE;
       else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs))
        {