@@ -537,6 +537,20 @@ void Parser::LateTemplateParserCleanupCallback(void *P) {
537
537
DestroyTemplateIdAnnotationsRAIIObj CleanupRAII (((Parser *)P)->TemplateIds );
538
538
}
539
539
540
+ bool Parser::ParseFirstTopLevelDecl (DeclGroupPtrTy &Result) {
541
+ // C++ Modules TS: module-declaration must be the first declaration in the
542
+ // file. (There can be no preceding preprocessor directives, but we expect
543
+ // the lexer to check that.)
544
+ if (Tok.is (tok::kw_module)) {
545
+ Result = ParseModuleDecl ();
546
+ return false ;
547
+ }
548
+ // FIXME: If we're parsing a module interface and we don't have a module
549
+ // declaration here, diagnose.
550
+
551
+ return ParseTopLevelDecl (Result);
552
+ }
553
+
540
554
// / ParseTopLevelDecl - Parse one top-level declaration, return whatever the
541
555
// / action tells us to. This returns true if the EOF was encountered.
542
556
bool Parser::ParseTopLevelDecl (DeclGroupPtrTy &Result) {
@@ -2000,18 +2014,58 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
2000
2014
Braces.consumeClose ();
2001
2015
}
2002
2016
2017
+ // / Parse a C++ Modules TS module declaration, which appears at the beginning
2018
+ // / of a module interface, module partition, or module implementation file.
2019
+ // /
2020
+ // / module-declaration: [Modules TS + P0273R0]
2021
+ // / 'module' module-kind[opt] module-name attribute-specifier-seq[opt] ';'
2022
+ // / module-kind:
2023
+ // / 'implementation'
2024
+ // / 'partition'
2025
+ // /
2026
+ // / Note that the module-kind values are context-sensitive keywords.
2027
+ Parser::DeclGroupPtrTy Parser::ParseModuleDecl () {
2028
+ assert (Tok.is (tok::kw_module) && getLangOpts ().ModulesTS &&
2029
+ " should not be parsing a module declaration" );
2030
+ SourceLocation ModuleLoc = ConsumeToken ();
2031
+
2032
+ // Check for a module-kind.
2033
+ Sema::ModuleDeclKind MDK = Sema::ModuleDeclKind::Module;
2034
+ if (Tok.is (tok::identifier) && NextToken ().is (tok::identifier)) {
2035
+ if (Tok.getIdentifierInfo ()->isStr (" implementation" ))
2036
+ MDK = Sema::ModuleDeclKind::Implementation;
2037
+ else if (Tok.getIdentifierInfo ()->isStr (" partition" ))
2038
+ MDK = Sema::ModuleDeclKind::Partition;
2039
+ else {
2040
+ Diag (Tok, diag::err_unexpected_module_kind) << Tok.getIdentifierInfo ();
2041
+ SkipUntil (tok::semi);
2042
+ return nullptr ;
2043
+ }
2044
+ ConsumeToken ();
2045
+ }
2046
+
2047
+ SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2 > Path;
2048
+ if (ParseModuleName (ModuleLoc, Path, /* IsImport*/ false ))
2049
+ return nullptr ;
2050
+
2051
+ ParsedAttributesWithRange Attrs (AttrFactory);
2052
+ MaybeParseCXX11Attributes (Attrs);
2053
+ // We don't support any module attributes yet.
2054
+ ProhibitCXX11Attributes (Attrs, diag::err_attribute_not_module_attr);
2055
+
2056
+ ExpectAndConsumeSemi (diag::err_module_expected_semi);
2057
+
2058
+ return Actions.ActOnModuleDecl (ModuleLoc, MDK, Path);
2059
+ }
2060
+
2003
2061
// / Parse a module import declaration. This is essentially the same for
2004
2062
// / Objective-C and the C++ Modules TS, except for the leading '@' (in ObjC)
2005
2063
// / and the trailing optional attributes (in C++).
2006
2064
// /
2007
2065
// / [ObjC] @import declaration:
2008
- // / '@' 'import' (identifier '.')* ';'
2066
+ // / '@' 'import' module-name ';'
2009
2067
// / [ModTS] module-import-declaration:
2010
- // / 'module' module-name attribute-specifier-seq[opt] ';'
2011
- // / module-name:
2012
- // / module-name-qualifier[opt] identifier
2013
- // / module-name-qualifier:
2014
- // / module-name-qualifier[opt] identifier '.'
2068
+ // / 'import' module-name attribute-specifier-seq[opt] ';'
2015
2069
Parser::DeclGroupPtrTy Parser::ParseModuleImport (SourceLocation AtLoc) {
2016
2070
assert ((AtLoc.isInvalid () ? Tok.is (tok::kw_import)
2017
2071
: Tok.isObjCAtKeyword (tok::objc_import)) &&
@@ -2020,30 +2074,8 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) {
2020
2074
SourceLocation StartLoc = AtLoc.isInvalid () ? ImportLoc : AtLoc;
2021
2075
2022
2076
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2 > Path;
2023
-
2024
- // Parse the module path.
2025
- while (true ) {
2026
- if (!Tok.is (tok::identifier)) {
2027
- if (Tok.is (tok::code_completion)) {
2028
- Actions.CodeCompleteModuleImport (ImportLoc, Path);
2029
- cutOffParsing ();
2030
- return nullptr ;
2031
- }
2032
-
2033
- Diag (Tok, diag::err_module_expected_ident);
2034
- SkipUntil (tok::semi);
2035
- return nullptr ;
2036
- }
2037
-
2038
- // Record this part of the module path.
2039
- Path.push_back (std::make_pair (Tok.getIdentifierInfo (), Tok.getLocation ()));
2040
- ConsumeToken ();
2041
-
2042
- if (Tok.isNot (tok::period))
2043
- break ;
2044
-
2045
- ConsumeToken ();
2046
- }
2077
+ if (ParseModuleName (ImportLoc, Path, /* IsImport*/ true ))
2078
+ return nullptr ;
2047
2079
2048
2080
ParsedAttributesWithRange Attrs (AttrFactory);
2049
2081
MaybeParseCXX11Attributes (Attrs);
@@ -2064,6 +2096,42 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) {
2064
2096
return Actions.ConvertDeclToDeclGroup (Import.get ());
2065
2097
}
2066
2098
2099
+ // / Parse a C++ Modules TS / Objective-C module name (both forms use the same
2100
+ // / grammar).
2101
+ // /
2102
+ // / module-name:
2103
+ // / module-name-qualifier[opt] identifier
2104
+ // / module-name-qualifier:
2105
+ // / module-name-qualifier[opt] identifier '.'
2106
+ bool Parser::ParseModuleName (
2107
+ SourceLocation UseLoc,
2108
+ SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
2109
+ bool IsImport) {
2110
+ // Parse the module path.
2111
+ while (true ) {
2112
+ if (!Tok.is (tok::identifier)) {
2113
+ if (Tok.is (tok::code_completion)) {
2114
+ Actions.CodeCompleteModuleImport (UseLoc, Path);
2115
+ cutOffParsing ();
2116
+ return true ;
2117
+ }
2118
+
2119
+ Diag (Tok, diag::err_module_expected_ident) << IsImport;
2120
+ SkipUntil (tok::semi);
2121
+ return true ;
2122
+ }
2123
+
2124
+ // Record this part of the module path.
2125
+ Path.push_back (std::make_pair (Tok.getIdentifierInfo (), Tok.getLocation ()));
2126
+ ConsumeToken ();
2127
+
2128
+ if (Tok.isNot (tok::period))
2129
+ return false ;
2130
+
2131
+ ConsumeToken ();
2132
+ }
2133
+ }
2134
+
2067
2135
// / \brief Try recover parser when module annotation appears where it must not
2068
2136
// / be found.
2069
2137
// / \returns false if the recover was successful and parsing may be continued, or
0 commit comments