Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -1451,6 +1451,12 @@ let Documentation = [SwiftIndirectResultDocs]; } +def Suppress : StmtAttr { + let Spellings = [CXX11<"clang", "suppress">]; + let Args = [VariadicStringArgument<"Rules">]; + let Documentation = [Undocumented]; +} + def SysVABI : InheritableAttr { let Spellings = [GCC<"sysv_abi">]; // let Subjects = [Function, ObjCMethod]; Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -3838,6 +3838,24 @@ } } +static void handleSuppressAttr(Sema &S, Decl *D, const AttributeList &Attr) { + std::vector Rules; + + for (unsigned I = 0, E = Attr.getNumArgs(); I != E; ++I) { + StringRef RuleName; + SourceLocation LiteralLoc; + + if (!S.checkStringLiteralArgumentAttr(Attr, I, RuleName, &LiteralLoc)) + return; + + Rules.push_back(RuleName); + } + D->addAttr(::new (S.Context) SuppressAttr( + Attr.getRange(), S.Context, Rules.data(), Rules.size(), + Attr.getAttributeSpellingListIndex())); +} + + bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const FunctionDecl *FD) { if (attr.isInvalid()) @@ -5768,6 +5786,9 @@ case AttributeList::AT_PreserveAll: handleCallConvAttr(S, D, Attr); break; + case AttributeList::AT_Suppress: + handleSuppressAttr(S, D, Attr); + break; case AttributeList::AT_OpenCLKernel: handleSimpleAttribute(S, D, Attr); break; Index: lib/Sema/SemaStmtAttr.cpp =================================================================== --- lib/Sema/SemaStmtAttr.cpp +++ lib/Sema/SemaStmtAttr.cpp @@ -53,6 +53,25 @@ return ::new (S.Context) auto(Attr); } +static Attr *handleSuppressAttr(Sema &S, Stmt *St, const AttributeList &A, + SourceRange Range) { + std::vector Rules; + + for (unsigned I = 0, E = A.getNumArgs(); I != E; ++I) { + StringRef RuleName; + SourceLocation LiteralLoc; + + if (!S.checkStringLiteralArgumentAttr(A, I, RuleName, &LiteralLoc)) + return nullptr; + + Rules.push_back(RuleName); + } + + SuppressAttr Attr(A.getRange(), S.Context, Rules.data(), Rules.size(), + A.getAttributeSpellingListIndex()); + return ::new (S.Context) auto(Attr); +} + static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange) { IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0); @@ -283,6 +302,8 @@ return handleLoopHintAttr(S, St, A, Range); case AttributeList::AT_OpenCLUnrollHint: return handleOpenCLUnrollHint(S, St, A, Range); + case AttributeList::AT_Suppress: + return handleSuppressAttr(S, St, A, Range); default: // if we're here, then we parsed a known attribute, but didn't recognize // it as a statement attribute => it is declaration attribute