diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -2633,8 +2633,12 @@ // Forbid C++11 and C2x attributes that appear on certain syntactic locations // which standard permits but we don't supported yet, for example, attributes // appertain to decl specifiers. + // For the most cases we don't want to warn on unknown attributes, but left + // them to later diagnoses. However, for a few cases like module declarations + // and module import declarations, we should do it. void ProhibitCXX11Attributes(ParsedAttributes &Attrs, unsigned DiagID, - bool DiagnoseEmptyAttrs = false); + bool DiagnoseEmptyAttrs = false, + bool WarnOnUnknownAttr = false); /// Skip C++11 and C2x attributes and return the end location of the /// last one. diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1658,7 +1658,8 @@ } void Parser::ProhibitCXX11Attributes(ParsedAttributes &Attrs, unsigned DiagID, - bool DiagnoseEmptyAttrs) { + bool DiagnoseEmptyAttrs, + bool WarnOnUnknownAttr) { if (DiagnoseEmptyAttrs && Attrs.empty() && Attrs.Range.isValid()) { // An attribute list has been parsed, but it was empty. @@ -1685,10 +1686,11 @@ for (const ParsedAttr &AL : Attrs) { if (!AL.isCXX11Attribute() && !AL.isC2xAttribute()) continue; - if (AL.getKind() == ParsedAttr::UnknownAttribute) - Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) - << AL << AL.getRange(); - else { + if (AL.getKind() == ParsedAttr::UnknownAttribute) { + if (WarnOnUnknownAttr) + Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored) + << AL << AL.getRange(); + } else { Diag(AL.getLoc(), DiagID) << AL; AL.setInvalid(); } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -2377,7 +2377,9 @@ // We don't support any module attributes yet; just parse them and diagnose. ParsedAttributes Attrs(AttrFactory); MaybeParseCXX11Attributes(Attrs); - ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr); + ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr, + /*DiagnoseEmptyAttrs=*/false, + /*WarnOnUnknownAttr=*/true); ExpectAndConsumeSemi(diag::err_module_expected_semi); @@ -2444,7 +2446,9 @@ ParsedAttributes Attrs(AttrFactory); MaybeParseCXX11Attributes(Attrs); // We don't support any module import attributes yet. - ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr); + ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr, + /*DiagnoseEmptyAttrs=*/false, + /*WarnOnUnknownAttr=*/true); if (PP.hadModuleLoaderFatalFailure()) { // With a fatal failure in the module loader, we abort parsing.