diff options
Diffstat (limited to 'clang/lib/Parse')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 43 |
2 files changed, 45 insertions, 20 deletions
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; |

