aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaStmtAttr.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Sema/SemaStmtAttr.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (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.cpp41
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