diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 43 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 |
4 files changed, 55 insertions, 27 deletions
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 73039373824..096a6107a95 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -712,9 +712,12 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { // Note that we do not treat 'import' as a contextual // keyword when we're in a caching lexer, because caching lexers only get // used in contexts where import declarations are disallowed. - if (LastTokenWasAt && II.isModulesImport() && !InMacroArgs && - !DisableMacroExpansion && - (getLangOpts().Modules || getLangOpts().DebuggerSupport) && + // + // Likewise if this is the C++ Modules TS import keyword. + if (((LastTokenWasAt && II.isModulesImport()) || + Identifier.is(tok::kw_import)) && + !InMacroArgs && !DisableMacroExpansion && + (getLangOpts().Modules || getLangOpts().DebuggerSupport) && CurLexerKind != CLK_CachingLexer) { ModuleImportLoc = Identifier.getLocation(); ModuleImportPath.clear(); @@ -782,7 +785,8 @@ void Preprocessor::LexAfterModuleImport(Token &Result) { } // If we're expecting a '.' or a ';', and we got a '.', then wait until we - // see the next identifier. + // see the next identifier. (We can also see a '[[' that begins an + // attribute-specifier-seq here under the C++ Modules TS.) if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) { ModuleImportExpectsIdentifier = true; CurLexerKind = CLK_LexAfterModuleImport; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 91a3effe426..0459cb7fe6b 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1407,15 +1407,19 @@ void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { << attrs.Range; } -void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) { - AttributeList *AttrList = attrs.getList(); - while (AttrList) { - if (AttrList->isCXX11Attribute()) { - Diag(AttrList->getLoc(), diag::err_attribute_not_type_attr) - << AttrList->getName(); - AttrList->setInvalid(); +void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, + unsigned DiagID) { + for (AttributeList *Attr = Attrs.getList(); Attr; Attr = Attr->getNext()) { + if (!Attr->isCXX11Attribute()) + continue; + if (Attr->getKind() == AttributeList::UnknownAttribute) + Diag(Attr->getLoc(), diag::warn_unknown_attribute_ignored) + << Attr->getName(); + else { + Diag(Attr->getLoc(), DiagID) + << Attr->getName(); + Attr->setInvalid(); } - AttrList = AttrList->getNext(); } } @@ -2717,7 +2721,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // Reject C++11 attributes that appertain to decl specifiers as // we don't support any C++11 attributes that appertain to decl // specifiers. This also conforms to what g++ 4.8 is doing. - ProhibitCXX11Attributes(attrs); + ProhibitCXX11Attributes(attrs, diag::err_attribute_not_type_attr); DS.takeAttributesFrom(attrs); } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index f442bd74742..9f941f40da1 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -553,6 +553,10 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) { HandlePragmaUnused(); return false; + case tok::kw_import: + Result = ParseModuleImport(SourceLocation()); + return false; + case tok::annot_module_include: Actions.ActOnModuleInclude(Tok.getLocation(), reinterpret_cast<Module *>( @@ -1996,15 +2000,29 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() { Braces.consumeClose(); } +/// Parse a module import declaration. This is essentially the same for +/// Objective-C and the C++ Modules TS, except for the leading '@' (in ObjC) +/// and the trailing optional attributes (in C++). +/// +/// [ObjC] @import declaration: +/// '@' 'import' (identifier '.')* ';' +/// [ModTS] module-import-declaration: +/// 'module' module-name attribute-specifier-seq[opt] ';' +/// module-name: +/// module-name-qualifier[opt] identifier +/// module-name-qualifier: +/// module-name-qualifier[opt] identifier '.' Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) { - assert(Tok.isObjCAtKeyword(tok::objc_import) && + assert((AtLoc.isInvalid() ? Tok.is(tok::kw_import) + : Tok.isObjCAtKeyword(tok::objc_import)) && "Improper start to module import"); SourceLocation ImportLoc = ConsumeToken(); + SourceLocation StartLoc = AtLoc.isInvalid() ? ImportLoc : AtLoc; SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; // Parse the module path. - do { + while (true) { if (!Tok.is(tok::identifier)) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteModuleImport(ImportLoc, Path); @@ -2020,14 +2038,17 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) { // Record this part of the module path. Path.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation())); ConsumeToken(); - - if (Tok.is(tok::period)) { - ConsumeToken(); - continue; - } - - break; - } while (true); + + if (Tok.isNot(tok::period)) + break; + + ConsumeToken(); + } + + ParsedAttributesWithRange Attrs(AttrFactory); + MaybeParseCXX11Attributes(Attrs); + // We don't support any module import attributes yet. + ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr); if (PP.hadModuleLoaderFatalFailure()) { // With a fatal failure in the module loader, we abort parsing. @@ -2035,7 +2056,7 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) { return nullptr; } - DeclResult Import = Actions.ActOnModuleImport(AtLoc, ImportLoc, Path); + DeclResult Import = Actions.ActOnModuleImport(StartLoc, ImportLoc, Path); ExpectAndConsumeSemi(diag::err_module_expected_semi); if (Import.isInvalid()) return nullptr; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 42f8dea6f6b..5dab15a8d66 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15178,7 +15178,7 @@ void Sema::diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc) { return checkModuleImportContext(*this, M, ImportLoc, CurContext); } -DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, +DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, SourceLocation ImportLoc, ModuleIdPath Path) { Module *Mod = @@ -15213,8 +15213,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, } TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); - ImportDecl *Import = ImportDecl::Create(Context, TU, - AtLoc.isValid()? AtLoc : ImportLoc, + ImportDecl *Import = ImportDecl::Create(Context, TU, StartLoc, Mod, IdentifierLocs); if (!ModuleScopes.empty()) Context.addModuleInitializer(ModuleScopes.back().Module, Import); |

