// { dg-additional-options "-fmodules-ts" }
-#define malcolm kevin
-export module malcolm;
+export module kevin;
// { dg-module-cmi kevin }
export class X;
export module NAME(bob)
+// { dg-error "module name followed by '\\\('" "" { target *-*-* } .-2 }
+// { dg-error "expected ';' before '\\\(' token" "" { target *-*-* } .-3 }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+#define NAME(X) ;
+
+export module bob NAME(bob)
+
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob fred;
+export module foo:bob; // { dg-error "module partition 'bob' cannot be an object-like macro" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob fred;
+export module foo:bar.bob; // { dg-error "module partition 'bob' cannot be an object-like macro" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz .qux // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" }
+export module foo:bar baz;
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz :qux.garply // { dg-error "':' in module name or partition comes from or after macro expansion" }
+export module foo.bar baz;
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz [[]]
+export module foo.bar baz;
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz
+#define qux
+export module foo.bar baz . garply qux; // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz
+#define qux
+export module foo.bar baz : garply qux; // { dg-error "':' in module name or partition comes from or after macro expansion" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz(x) x qux
+export module foo:bar baz(.); // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz(x) x qux.garply
+export module foo.bar baz(:); // { dg-error "':' in module name or partition comes from or after macro expansion" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz(x)
+#define qux(x)
+export module foo.bar baz(.) . garply qux(:); // { dg-error "'\\\.' in module name or partition comes from or after macro expansion" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define baz(x)
+#define qux(x)
+export module foo.bar baz(:) : garply qux(.); // { dg-error "':' in module name or partition comes from or after macro expansion" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define NAME(X) X;
+
+export module NAME(bob) // { dg-error "module name followed by '\\\('" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob fred;
+export module bob; // { dg-error "module name 'bob' cannot be an object-like macro" }
+
+int i;
--- /dev/null
+// { dg-do preprocess }
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob fred;
+export module foo.bob; // { dg-error "module name 'bob' cannot be an object-like macro" }
+
+int i;
# 32 "<command-line>" 2
# 1 "dir-only-3.C"
// { dg-additional-options {-fmodules-ts -fpreprocessed -fdirectives-only} }
-// { dg-module-cmi foo }
+// { dg-module-cmi !foo }
module;
#define foo baz
export module foo;
+// { dg-error "module name 'foo' cannot be an object-like macro" "" { target *-*-* } 5 }
+// { dg-prune-output "not writing module" }
class import {};
// { dg-module-cmi !foo }
module;
#define foo baz
-export module foo;
+export module foo; // { dg-error "module name 'foo' cannot be an object-like macro" }
class import {};
--- /dev/null
+// { dg-additional-options {-fmodules-ts -fpreprocessed -fdirectives-only} }
+// { dg-module-cmi !baz }
+module;
+#define foo baz
+export module baz;
+
+class import {};
+
+import x; // { dg-error "post-module-declaration" }
--- /dev/null
+// { dg-additional-options -fmodules-ts }
+
+export module bob;
+// { dg-module-cmi bob }
+
+#define PRIVATE private
+
+module :PRIVATE; // { dg-message "sorry, unimplemented: private module fragment" }
+int i;
--- /dev/null
+// { dg-additional-options -fmodules-ts }
+
+export module bob;
+// { dg-module-cmi bob }
+
+#define PRIVATE_SEMI private ;
+
+module :PRIVATE_SEMI // { dg-message "sorry, unimplemented: private module fragment" }
+int i;
--- /dev/null
+// { dg-additional-options -fmodules-ts }
+
+export module bob;
+// { dg-module-cmi bob }
+
+#define SEMI ;
+
+module :private SEMI // { dg-message "sorry, unimplemented: private module fragment" }
+int i;
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define semi ;
+export module foo.bar:baz.bob semi
+
+// { dg-module-cmi foo.bar:baz.bob }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define attr [[]]
+export module foo.bar:baz.bob attr ;
+
+// { dg-module-cmi foo.bar:baz.bob }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob() fred
+export module bob;
+
+// { dg-module-cmi bob }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob() fred
+export module foo.bar.bob;
+
+// { dg-module-cmi foo.bar.bob }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob(n) fred
+export module foo.bar:bob;
+
+// { dg-module-cmi foo.bar:bob }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob() fred
+export module foo.bar:baz.bob;
+
+// { dg-module-cmi foo.bar:baz.bob }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob() fred
+export module foo.bar:baz.bob ();
+// { dg-error "module partition followed by '\\\('" "" { target *-*-* } .-1 }
+// { dg-error "expected" "" { target *-*-* } .-2 }
+
+// { dg-module-cmi !foo.bar:baz.bob }
+// { dg-module-cmi !foo.bar:baz.fred }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob fred
+export module bob;
+// { dg-error "module name 'bob' cannot be an object-like macro" "" { target *-*-* } .-1 }
+
+// { dg-module-cmi !bob }
+// { dg-module-cmi !fred }
+// { dg-prune-output "not writing module" }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob fred
+export module foo.bar.bob;
+// { dg-error "module name 'bob' cannot be an object-like macro" "" { target *-*-* } .-1 }
+
+// { dg-module-cmi !foo.bar.bob }
+// { dg-module-cmi !foo.bar.fred }
+// { dg-prune-output "not writing module" }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define bob fred
+export module foo.bar:bob;
+// { dg-error "module partition 'bob' cannot be an object-like macro" "" { target *-*-* } .-1 }
+
+// { dg-module-cmi !foo.bar:bob }
+// { dg-module-cmi !foo.bar:fred }
+// { dg-prune-output "not writing module" }
--- /dev/null
+// { dg-additional-options "-fmodules-ts" }
+
+#define garply fred
+export module foo.bar:baz.garply;
+// { dg-error "module partition 'garply' cannot be an object-like macro" "" { target *-*-* } .-1 }
+
+// { dg-module-cmi !foo.bar:baz.garply }
+// { dg-module-cmi !foo.bar:baz.fred }
+// { dg-prune-output "not writing module" }
#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend,
set in c-lex.cc. */
#define COLON_SCOPE PURE_ZERO /* Adjacent colons in C < 23. */
+#define NO_DOT_COLON PURE_ZERO /* Set on CPP_NAME tokens whose expansion
+ shouldn't start with CPP_DOT or CPP_COLON
+ after optional CPP_PADDING. */
#define SP_DIGRAPH (1 << 8) /* # or ## token was a digraph. */
#define SP_PREV_WHITE (1 << 9) /* If whitespace before a ##
operator, or before this token
one. */
bool about_to_expand_macro_p;
+ /* True if the preprocessor should diagnose CPP_DOT or CPP_COLON
+ tokens as the first ones coming from macro expansion. */
+ bool diagnose_dot_colon_from_macro_p;
+
/* Search paths for include files. */
struct cpp_dir *quote_include; /* "" */
struct cpp_dir *bracket_include; /* <> */
/* Maybe tell the tokenizer we expect a header-name down the
road. */
pfile->state.directive_file_token = header_count;
+
+ /* According to P3034R1, pp-module-name and pp-module-partition tokens
+ if any shouldn't be macro expanded and identifiers shouldn't be
+ defined as object-like macro. */
+ if (!header_count && peek->type == CPP_NAME)
+ {
+ int state = 0;
+ do
+ {
+ cpp_token *tok = peek;
+ if (tok->type == CPP_NAME)
+ {
+ cpp_hashnode *node = tok->val.node.node;
+ /* Don't attempt to expand the token. */
+ tok->flags |= NO_EXPAND;
+ if (_cpp_defined_macro_p (node)
+ && _cpp_maybe_notify_macro_use (pfile, node,
+ tok->src_loc)
+ && !cpp_fun_like_macro_p (node))
+ {
+ if (state == 0)
+ cpp_error_with_line (pfile, CPP_DL_ERROR,
+ tok->src_loc, 0,
+ "module name %qs cannot "
+ "be an object-like macro",
+ NODE_NAME (node));
+ else
+ cpp_error_with_line (pfile, CPP_DL_ERROR,
+ tok->src_loc, 0,
+ "module partition %qs cannot "
+ "be an object-like macro",
+ NODE_NAME (node));
+ }
+ }
+ peek = _cpp_lex_direct (pfile);
+ backup++;
+ if (tok->type == CPP_NAME)
+ {
+ if (peek->type == CPP_DOT)
+ continue;
+ else if (peek->type == CPP_COLON && state == 0)
+ {
+ ++state;
+ continue;
+ }
+ else if (peek->type == CPP_OPEN_PAREN)
+ {
+ if (state == 0)
+ cpp_error_with_line (pfile, CPP_DL_ERROR,
+ peek->src_loc, 0,
+ "module name followed by %<(%>");
+ else
+ cpp_error_with_line (pfile, CPP_DL_ERROR,
+ peek->src_loc, 0,
+ "module partition followed by "
+ "%<(%>");
+ break;
+ }
+ else if (peek->type == CPP_NAME
+ && _cpp_defined_macro_p (peek->val.node.node))
+ {
+ peek->flags |= NO_DOT_COLON;
+ break;
+ }
+ else
+ break;
+ }
+ else if (peek->type != CPP_NAME)
+ break;
+ }
+ while (true);
+ }
}
else
{
if (pfile->state.prevent_expansion)
break;
+ if ((result->flags & NO_DOT_COLON) != 0)
+ pfile->diagnose_dot_colon_from_macro_p = true;
+
/* Conditional macros require that a predicate be evaluated
first. */
if ((node->flags & NODE_CONDITIONAL) != 0)
}
}
+ if (pfile->diagnose_dot_colon_from_macro_p
+ && !pfile->about_to_expand_macro_p
+ && result->type != CPP_PADDING
+ && result->type != CPP_COMMENT)
+ {
+ if (result->type == CPP_DOT || result->type == CPP_COLON)
+ cpp_error_with_line (pfile, CPP_DL_ERROR,
+ result->src_loc, 0,
+ "%qc in module name or partition "
+ "comes from or after macro expansion",
+ result->type == CPP_DOT ? '.' : ':');
+ pfile->diagnose_dot_colon_from_macro_p = false;
+ }
+
return result;
}