diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Sema/SemaStmtAttr.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Vendor import of llvm-project master 2e10b7a39b9, the last commit beforevendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9vendor/llvm-project/master
the llvmorg-12-init tag, from which release/11.x was branched.
Notes
Notes:
svn path=/vendor/llvm-project/master/; revision=363578
svn path=/vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9/; revision=363579; tag=vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9
Diffstat (limited to 'clang/lib/Sema/SemaStmtAttr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaStmtAttr.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 3d91893b4065..e9d3c755eb23 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/EvaluatedExprVisitor.h" #include "clang/Sema/SemaInternal.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/SourceManager.h" @@ -170,6 +171,44 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, return LoopHintAttr::CreateImplicit(S.Context, Option, State, ValueExpr, A); } +namespace { +class CallExprFinder : public ConstEvaluatedExprVisitor<CallExprFinder> { + bool FoundCallExpr = false; + +public: + typedef ConstEvaluatedExprVisitor<CallExprFinder> Inherited; + + CallExprFinder(Sema &S, const Stmt *St) : Inherited(S.Context) { Visit(St); } + + bool foundCallExpr() { return FoundCallExpr; } + + void VisitCallExpr(const CallExpr *E) { FoundCallExpr = true; } + + void Visit(const Stmt *St) { + if (!St) + return; + ConstEvaluatedExprVisitor<CallExprFinder>::Visit(St); + } +}; +} // namespace + +static Attr *handleNoMergeAttr(Sema &S, Stmt *St, const ParsedAttr &A, + SourceRange Range) { + NoMergeAttr NMA(S.Context, A); + if (S.CheckAttrNoArgs(A)) + return nullptr; + + CallExprFinder CEF(S, St); + + if (!CEF.foundCallExpr()) { + S.Diag(St->getBeginLoc(), diag::warn_nomerge_attribute_ignored_in_stmt) + << NMA.getSpelling(); + return nullptr; + } + + return ::new (S.Context) NoMergeAttr(S.Context, A); +} + static void CheckForIncompatibleAttributes(Sema &S, const SmallVectorImpl<const Attr *> &Attrs) { @@ -335,6 +374,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, return handleOpenCLUnrollHint(S, St, A, Range); case ParsedAttr::AT_Suppress: return handleSuppressAttr(S, St, A, Range); + case ParsedAttr::AT_NoMerge: + return handleNoMergeAttr(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 |