summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Stmt.cpp5
-rw-r--r--clang/lib/AST/StmtPrinter.cpp6
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp17
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp32
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp25
-rw-r--r--clang/lib/Sema/TreeTransform.h11
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp2
8 files changed, 78 insertions, 22 deletions
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 175526a9313..e8a02eee7f8 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -1343,6 +1343,7 @@ void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
OMPLinearClause *OMPLinearClause::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep) {
// Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
@@ -1350,8 +1351,8 @@ OMPLinearClause *OMPLinearClause::Create(
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
llvm::alignOf<Expr *>()) +
(5 * VL.size() + 2) * sizeof(Expr *));
- OMPLinearClause *Clause = new (Mem)
- OMPLinearClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+ OMPLinearClause *Clause = new (Mem) OMPLinearClause(
+ StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
Clause->setPrivates(PL);
Clause->setInits(IL);
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 64f90ba951d..fb5fcc4902d 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -767,7 +767,13 @@ void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
if (!Node->varlist_empty()) {
OS << "linear";
+ if (Node->getModifierLoc().isValid()) {
+ OS << '('
+ << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
+ }
VisitOMPClauseList(Node, '(');
+ if (Node->getModifierLoc().isValid())
+ OS << ')';
if (Node->getStep() != nullptr) {
OS << ": ";
Node->getStep()->printPretty(OS, nullptr, Policy, 0);
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index b431598191a..3262eec9c2c 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -96,6 +96,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_DEPEND_unknown);
+ case OMPC_linear:
+ return llvm::StringSwitch<OpenMPLinearClauseKind>(Str)
+#define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_LINEAR_unknown);
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -108,7 +113,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
- case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
case OMPC_copyprivate:
@@ -170,6 +174,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'schedule' clause type");
+ case OMPC_linear:
+ switch (Type) {
+ case OMPC_LINEAR_unknown:
+ return "unknown";
+#define OPENMP_LINEAR_KIND(Name) \
+ case OMPC_LINEAR_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'linear' clause type");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -182,7 +196,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
- case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
case OMPC_copyprivate:
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index fb348ef55d8..e7966d42a50 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -708,7 +708,7 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
/// shared-clause:
/// 'shared' '(' list ')'
/// linear-clause:
-/// 'linear' '(' list [ ':' linear-step ] ')'
+/// 'linear' '(' linear-list [ ':' linear-step ] ')'
/// aligned-clause:
/// 'aligned' '(' list [ ':' alignment ] ')'
/// reduction-clause:
@@ -720,6 +720,10 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
/// depend-clause:
/// 'depend' '(' in | out | inout : list ')'
///
+/// For 'linear' clause linear-list may have the following forms:
+/// list
+/// modifier(list)
+/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
SourceLocation Loc = Tok.getLocation();
SourceLocation LOpen = ConsumeToken();
@@ -729,7 +733,10 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
UnqualifiedId ReductionId;
bool InvalidReductionId = false;
OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
- SourceLocation DepLoc;
+ // OpenMP 4.1 [2.15.3.7, linear Clause]
+ // If no modifier is specified it is assumed to be val.
+ OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
+ SourceLocation DepLinLoc;
// Parse '('.
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
@@ -737,6 +744,9 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
getOpenMPClauseName(Kind)))
return nullptr;
+ bool NeedRParenForLinear = false;
+ BalancedDelimiterTracker LinearT(*this, tok::l_paren,
+ tok::annot_pragma_openmp_end);
// Handle reduction-identifier for reduction clause.
if (Kind == OMPC_reduction) {
ColonProtectionRAIIObject ColonRAII(*this);
@@ -759,7 +769,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
ColonProtectionRAIIObject ColonRAII(*this);
DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
- DepLoc = Tok.getLocation();
+ DepLinLoc = Tok.getLocation();
if (DepKind == OMPC_DEPEND_unknown) {
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
@@ -772,6 +782,16 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
} else {
Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type";
}
+ } else if (Kind == OMPC_linear) {
+ // Try to parse modifier if any.
+ if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
+ StringRef TokSpelling = PP.getSpelling(Tok);
+ LinearModifier = static_cast<OpenMPLinearClauseKind>(
+ getOpenMPSimpleClauseType(Kind, TokSpelling));
+ DepLinLoc = ConsumeToken();
+ LinearT.consumeOpen();
+ NeedRParenForLinear = true;
+ }
}
SmallVector<Expr *, 5> Vars;
@@ -804,6 +824,10 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
<< (Kind == OMPC_flush);
}
+ // Parse ')' for linear clause with modifier.
+ if (NeedRParenForLinear)
+ LinearT.consumeClose();
+
// Parse ':' linear-step (or ':' alignment).
Expr *TailExpr = nullptr;
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
@@ -831,6 +855,6 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
ReductionIdScopeSpec,
ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
: DeclarationNameInfo(),
- DepKind, DepLoc);
+ DepKind, LinearModifier, DepLinLoc);
}
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ddfb2d246e2..33bc621afab 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5254,7 +5254,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
- SourceLocation DepLoc) {
+ OpenMPLinearClauseKind LinKind, SourceLocation DepLinLoc) {
OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_private:
@@ -5275,7 +5275,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
break;
case OMPC_linear:
Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
- ColonLoc, EndLoc);
+ LinKind, DepLinLoc, ColonLoc, EndLoc);
break;
case OMPC_aligned:
Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
@@ -5291,7 +5291,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_depend:
- Res = ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, StartLoc,
+ Res = ActOnOpenMPDependClause(DepKind, DepLinLoc, ColonLoc, VarList, StartLoc,
LParenLoc, EndLoc);
break;
case OMPC_if:
@@ -6313,14 +6313,18 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
RHSs, ReductionOps);
}
-OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation ColonLoc,
- SourceLocation EndLoc) {
+OMPClause *Sema::ActOnOpenMPLinearClause(
+ ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
+ SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
+ SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
SmallVector<Expr *, 8> Vars;
SmallVector<Expr *, 8> Privates;
SmallVector<Expr *, 8> Inits;
+ if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
+ LinKind == OMPC_LINEAR_unknown) {
+ Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
+ LinKind = OMPC_LINEAR_val;
+ }
for (auto &RefExpr : VarList) {
assert(RefExpr && "NULL expr in OpenMP linear clause.");
if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
@@ -6459,8 +6463,9 @@ OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
}
}
- return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc,
- Vars, Privates, Inits, StepExpr, CalcStepExpr);
+ return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
+ ColonLoc, EndLoc, Vars, Privates, Inits,
+ StepExpr, CalcStepExpr);
}
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index d285db597c4..7cc7b779724 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1528,10 +1528,13 @@ public:
OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
SourceLocation StartLoc,
SourceLocation LParenLoc,
+ OpenMPLinearClauseKind Modifier,
+ SourceLocation ModifierLoc,
SourceLocation ColonLoc,
SourceLocation EndLoc) {
return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
- ColonLoc, EndLoc);
+ Modifier, ModifierLoc, ColonLoc,
+ EndLoc);
}
/// \brief Build a new OpenMP 'aligned' clause.
@@ -7419,9 +7422,9 @@ TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
ExprResult Step = getDerived().TransformExpr(C->getStep());
if (Step.isInvalid())
return nullptr;
- return getDerived().RebuildOMPLinearClause(Vars, Step.get(), C->getLocStart(),
- C->getLParenLoc(),
- C->getColonLoc(), C->getLocEnd());
+ return getDerived().RebuildOMPLinearClause(
+ Vars, Step.get(), C->getLocStart(), C->getLParenLoc(), C->getModifier(),
+ C->getModifierLoc(), C->getColonLoc(), C->getLocEnd());
}
template <typename Derived>
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index a04f4e56e0b..18b1051d177 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1970,6 +1970,8 @@ void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+ C->setModifier(static_cast<OpenMPLinearClauseKind>(Record[Idx++]));
+ C->setModifierLoc(Reader->ReadSourceLocation(Record, Idx));
unsigned NumVars = C->varlist_size();
SmallVector<Expr *, 16> Vars;
Vars.reserve(NumVars);
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index d9dc9e0e904..c91db223d96 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1851,6 +1851,8 @@ void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
Record.push_back(C->varlist_size());
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
+ Record.push_back(C->getModifier());
+ Writer->Writer.AddSourceLocation(C->getModifierLoc(), Record);
for (auto *VE : C->varlists()) {
Writer->Writer.AddStmt(VE);
}
OpenPOWER on IntegriCloud