Skip to content

Commit 3ecf343

Browse files
committed
Merge from 'main' to 'sycl-web' (#3)
2 parents db88f5a + 41c3b27 commit 3ecf343

File tree

20 files changed

+793
-29
lines changed

20 files changed

+793
-29
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,16 @@ def err_expected_end_declare_target_or_variant : Error<
12911291
def err_expected_begin_declare_variant
12921292
: Error<"'#pragma omp end declare variant' with no matching '#pragma omp "
12931293
"begin declare variant'">;
1294+
def err_expected_begin_assumes
1295+
: Error<"'#pragma omp end assumes' with no matching '#pragma omp begin assumes'">;
1296+
def warn_omp_unknown_assumption_clause_missing_id
1297+
: Warning<"valid %0 clauses start with %1; %select{token|tokens}2 will be ignored">,
1298+
InGroup<OpenMPClauses>;
1299+
def warn_omp_unknown_assumption_clause_without_args
1300+
: Warning<"%0 clause should not be followed by arguments; tokens will be ignored">,
1301+
InGroup<OpenMPClauses>;
1302+
def note_omp_assumption_clause_continue_here
1303+
: Note<"the ignored tokens spans until here">;
12941304
def err_omp_declare_target_unexpected_clause: Error<
12951305
"unexpected '%0' clause, only %select{'to' or 'link'|'to', 'link' or 'device_type'}1 clauses expected">;
12961306
def err_omp_expected_clause: Error<

clang/include/clang/Parse/Parser.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,6 +3113,13 @@ class Parser : public CodeCompletionHandler {
31133113
void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
31143114
SourceLocation Loc);
31153115

3116+
/// Parse 'omp [begin] assume[s]' directive.
3117+
void ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
3118+
SourceLocation Loc);
3119+
3120+
/// Parse 'omp end assumes' directive.
3121+
void ParseOpenMPEndAssumesDirective(SourceLocation Loc);
3122+
31163123
/// Parse clauses for '#pragma omp declare target'.
31173124
DeclGroupPtrTy ParseOMPDeclareTargetClauses();
31183125
/// Parse '#pragma omp end declare target'.

clang/include/clang/Sema/Sema.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10295,6 +10295,13 @@ class Sema final {
1029510295
/// The current `omp begin/end declare variant` scopes.
1029610296
SmallVector<OMPDeclareVariantScope, 4> OMPDeclareVariantScopes;
1029710297

10298+
/// The current `omp begin/end assumes` scopes.
10299+
SmallVector<AssumptionAttr *, 4> OMPAssumeScoped;
10300+
10301+
/// All `omp assumes` we encountered so far.
10302+
SmallVector<AssumptionAttr *, 4> OMPAssumeGlobal;
10303+
10304+
public:
1029810305
/// The declarator \p D defines a function in the scope \p S which is nested
1029910306
/// in an `omp begin/end declare variant` scope. In this method we create a
1030010307
/// declaration for \p D and rename \p D according to the OpenMP context
@@ -10308,10 +10315,11 @@ class Sema final {
1030810315
void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
1030910316
Decl *D, SmallVectorImpl<FunctionDecl *> &Bases);
1031010317

10311-
public:
10318+
/// Act on \p D, a function definition inside of an `omp [begin/end] assumes`.
10319+
void ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D);
1031210320

10313-
/// Can we exit a scope at the moment.
10314-
bool isInOpenMPDeclareVariantScope() {
10321+
/// Can we exit an OpenMP declare variant scope at the moment.
10322+
bool isInOpenMPDeclareVariantScope() const {
1031510323
return !OMPDeclareVariantScopes.empty();
1031610324
}
1031710325

@@ -10427,6 +10435,22 @@ class Sema final {
1042710435
ArrayRef<Expr *> VarList,
1042810436
ArrayRef<OMPClause *> Clauses,
1042910437
DeclContext *Owner = nullptr);
10438+
10439+
/// Called on well-formed '#pragma omp [begin] assume[s]'.
10440+
void ActOnOpenMPAssumesDirective(SourceLocation Loc,
10441+
OpenMPDirectiveKind DKind,
10442+
ArrayRef<StringRef> Assumptions,
10443+
bool SkippedClauses);
10444+
10445+
/// Check if there is an active global `omp begin assumes` directive.
10446+
bool isInOpenMPAssumeScope() const { return !OMPAssumeScoped.empty(); }
10447+
10448+
/// Check if there is an active global `omp assumes` directive.
10449+
bool hasGlobalOpenMPAssumes() const { return !OMPAssumeGlobal.empty(); }
10450+
10451+
/// Called on well-formed '#pragma omp end assumes'.
10452+
void ActOnOpenMPEndAssumesDirective();
10453+
1043010454
/// Called on well-formed '#pragma omp requires'.
1043110455
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
1043210456
ArrayRef<OMPClause *> ClauseList);

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/Parse/RAIIObjectsForParser.h"
2222
#include "clang/Sema/Scope.h"
2323
#include "llvm/ADT/PointerIntPair.h"
24+
#include "llvm/ADT/StringSwitch.h"
2425
#include "llvm/ADT/UniqueVector.h"
2526
#include "llvm/Frontend/OpenMP/OMPContext.h"
2627

@@ -115,7 +116,9 @@ static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
115116
// TODO: add other combined directives in topological order.
116117
static const OpenMPDirectiveKindExWrapper F[][3] = {
117118
{OMPD_begin, OMPD_declare, OMPD_begin_declare},
119+
{OMPD_begin, OMPD_assumes, OMPD_begin_assumes},
118120
{OMPD_end, OMPD_declare, OMPD_end_declare},
121+
{OMPD_end, OMPD_assumes, OMPD_end_assumes},
119122
{OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
120123
{OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
121124
{OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
@@ -1508,6 +1511,103 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
15081511
return false;
15091512
}
15101513

1514+
/// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
1515+
/// where
1516+
///
1517+
/// clause:
1518+
/// 'ext_IMPL_DEFINED'
1519+
/// 'absent' '(' directive-name [, directive-name]* ')'
1520+
/// 'contains' '(' directive-name [, directive-name]* ')'
1521+
/// 'holds' '(' scalar-expression ')'
1522+
/// 'no_openmp'
1523+
/// 'no_openmp_routines'
1524+
/// 'no_parallelism'
1525+
///
1526+
void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
1527+
SourceLocation Loc) {
1528+
SmallVector<StringRef, 4> Assumptions;
1529+
bool SkippedClauses = false;
1530+
1531+
auto SkipBraces = [&](llvm::StringRef Spelling, bool IssueNote) {
1532+
BalancedDelimiterTracker T(*this, tok::l_paren,
1533+
tok::annot_pragma_openmp_end);
1534+
if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1535+
return;
1536+
T.skipToEnd();
1537+
if (IssueNote && T.getCloseLocation().isValid())
1538+
Diag(T.getCloseLocation(),
1539+
diag::note_omp_assumption_clause_continue_here);
1540+
};
1541+
1542+
/// Helper to determine which AssumptionClauseMapping (ACM) in the
1543+
/// AssumptionClauseMappings table matches \p RawString. The return value is
1544+
/// the index of the matching ACM into the table or -1 if there was no match.
1545+
auto MatchACMClause = [&](StringRef RawString) {
1546+
llvm::StringSwitch<int> SS(RawString);
1547+
unsigned ACMIdx = 0;
1548+
for (const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1549+
if (ACMI.StartsWith)
1550+
SS.StartsWith(ACMI.Identifier, ACMIdx++);
1551+
else
1552+
SS.Case(ACMI.Identifier, ACMIdx++);
1553+
}
1554+
return SS.Default(-1);
1555+
};
1556+
1557+
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1558+
IdentifierInfo *II = nullptr;
1559+
SourceLocation StartLoc = Tok.getLocation();
1560+
int Idx = -1;
1561+
if (Tok.isAnyIdentifier()) {
1562+
II = Tok.getIdentifierInfo();
1563+
Idx = MatchACMClause(II->getName());
1564+
}
1565+
ConsumeAnyToken();
1566+
1567+
bool NextIsLPar = Tok.is(tok::l_paren);
1568+
// Handle unknown clauses by skipping them.
1569+
if (Idx == -1) {
1570+
Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1571+
<< llvm::omp::getOpenMPDirectiveName(DKind)
1572+
<< llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1573+
if (NextIsLPar)
1574+
SkipBraces(II ? II->getName() : "", /* IssueNote */ true);
1575+
SkippedClauses = true;
1576+
continue;
1577+
}
1578+
const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1579+
if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1580+
// TODO: We ignore absent, contains, and holds assumptions for now. We
1581+
// also do not verify the content in the parenthesis at all.
1582+
SkippedClauses = true;
1583+
SkipBraces(II->getName(), /* IssueNote */ false);
1584+
continue;
1585+
}
1586+
1587+
if (NextIsLPar) {
1588+
Diag(Tok.getLocation(),
1589+
diag::warn_omp_unknown_assumption_clause_without_args)
1590+
<< II;
1591+
SkipBraces(II->getName(), /* IssueNote */ true);
1592+
}
1593+
1594+
assert(II && "Expected an identifier clause!");
1595+
StringRef Assumption = II->getName();
1596+
if (ACMI.StartsWith)
1597+
Assumption = Assumption.substr(ACMI.Identifier.size());
1598+
Assumptions.push_back(Assumption);
1599+
}
1600+
1601+
Actions.ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions, SkippedClauses);
1602+
}
1603+
1604+
void Parser::ParseOpenMPEndAssumesDirective(SourceLocation Loc) {
1605+
if (Actions.isInOpenMPAssumeScope())
1606+
Actions.ActOnOpenMPEndAssumesDirective();
1607+
else
1608+
Diag(Loc, diag::err_expected_begin_assumes);
1609+
}
1610+
15111611
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
15121612
///
15131613
/// default-clause:
@@ -1716,6 +1816,14 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
17161816
/// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
17171817
/// annot_pragma_openmp_end
17181818
///
1819+
/// assumes directive:
1820+
/// annot_pragma_openmp 'assumes' <clause> [[[,] <clause>] ... ]
1821+
/// annot_pragma_openmp_end
1822+
/// or
1823+
/// annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
1824+
/// annot_pragma_openmp 'end assumes'
1825+
/// annot_pragma_openmp_end
1826+
///
17191827
Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
17201828
AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
17211829
DeclSpec::TST TagType, Decl *Tag) {
@@ -1853,6 +1961,13 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
18531961
ConsumeAnnotationToken();
18541962
return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
18551963
}
1964+
case OMPD_assumes:
1965+
case OMPD_begin_assumes:
1966+
ParseOpenMPAssumesDirective(DKind, ConsumeToken());
1967+
break;
1968+
case OMPD_end_assumes:
1969+
ParseOpenMPEndAssumesDirective(ConsumeToken());
1970+
break;
18561971
case OMPD_declare_reduction:
18571972
ConsumeToken();
18581973
if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10869,6 +10869,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
1086910869
}
1087010870
}
1087110871

10872+
if (LangOpts.OpenMP)
10873+
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(NewFD);
10874+
1087210875
// Semantic checking for this function declaration (in isolation).
1087310876

1087410877
if (getLangOpts().CPlusPlus) {

clang/lib/Sema/SemaLambda.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,10 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
998998
if (getLangOpts().CUDA)
999999
CUDASetLambdaAttrs(Method);
10001000

1001+
// OpenMP lambdas might get assumumption attributes.
1002+
if (LangOpts.OpenMP)
1003+
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Method);
1004+
10011005
// Number the lambda for linkage purposes if necessary.
10021006
handleLambdaNumbering(Class, Method);
10031007

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "llvm/ADT/IndexedMap.h"
3636
#include "llvm/ADT/PointerEmbeddedInt.h"
3737
#include "llvm/ADT/STLExtras.h"
38+
#include "llvm/ADT/StringExtras.h"
3839
#include "llvm/Frontend/OpenMP/OMPConstants.h"
3940
#include <set>
4041

@@ -3195,6 +3196,64 @@ Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
31953196
return DeclGroupPtrTy::make(DeclGroupRef(D));
31963197
}
31973198

3199+
void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3200+
OpenMPDirectiveKind DKind,
3201+
ArrayRef<StringRef> Assumptions,
3202+
bool SkippedClauses) {
3203+
if (!SkippedClauses && Assumptions.empty())
3204+
Diag(Loc, diag::err_omp_no_clause_for_directive)
3205+
<< llvm::omp::getAllAssumeClauseOptions()
3206+
<< llvm::omp::getOpenMPDirectiveName(DKind);
3207+
3208+
auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3209+
if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3210+
OMPAssumeScoped.push_back(AA);
3211+
return;
3212+
}
3213+
3214+
// Global assumes without assumption clauses are ignored.
3215+
if (Assumptions.empty())
3216+
return;
3217+
3218+
assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3219+
"Unexpected omp assumption directive!");
3220+
OMPAssumeGlobal.push_back(AA);
3221+
3222+
// The OMPAssumeGlobal scope above will take care of new declarations but
3223+
// we also want to apply the assumption to existing ones, e.g., to
3224+
// declarations in included headers. To this end, we traverse all existing
3225+
// declaration contexts and annotate function declarations here.
3226+
SmallVector<DeclContext *, 8> DeclContexts;
3227+
auto *Ctx = CurContext;
3228+
while (Ctx->getLexicalParent())
3229+
Ctx = Ctx->getLexicalParent();
3230+
DeclContexts.push_back(Ctx);
3231+
while (!DeclContexts.empty()) {
3232+
DeclContext *DC = DeclContexts.pop_back_val();
3233+
for (auto *SubDC : DC->decls()) {
3234+
if (SubDC->isInvalidDecl())
3235+
continue;
3236+
if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3237+
DeclContexts.push_back(CTD->getTemplatedDecl());
3238+
for (auto *S : CTD->specializations())
3239+
DeclContexts.push_back(S);
3240+
continue;
3241+
}
3242+
if (auto *DC = dyn_cast<DeclContext>(SubDC))
3243+
DeclContexts.push_back(DC);
3244+
if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3245+
F->addAttr(AA);
3246+
continue;
3247+
}
3248+
}
3249+
}
3250+
}
3251+
3252+
void Sema::ActOnOpenMPEndAssumesDirective() {
3253+
assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3254+
OMPAssumeScoped.pop_back();
3255+
}
3256+
31983257
OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
31993258
ArrayRef<OMPClause *> ClauseList) {
32003259
/// For target specific clauses, the requires directive cannot be
@@ -5936,6 +5995,27 @@ static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
59365995
FD->setParams(Params);
59375996
}
59385997

5998+
void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
5999+
if (D->isInvalidDecl())
6000+
return;
6001+
FunctionDecl *FD = nullptr;
6002+
if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6003+
FD = UTemplDecl->getTemplatedDecl();
6004+
else
6005+
FD = cast<FunctionDecl>(D);
6006+
assert(FD && "Expected a function declaration!");
6007+
6008+
// If we are intantiating templates we do *not* apply scoped assumptions but
6009+
// only global ones. We apply scoped assumption to the template definition
6010+
// though.
6011+
if (!inTemplateInstantiation()) {
6012+
for (AssumptionAttr *AA : OMPAssumeScoped)
6013+
FD->addAttr(AA);
6014+
}
6015+
for (AssumptionAttr *AA : OMPAssumeGlobal)
6016+
FD->addAttr(AA);
6017+
}
6018+
59396019
Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
59406020
: TI(&TI), NameSuffix(TI.getMangledName()) {}
59416021

0 commit comments

Comments
 (0)