A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/ParseOpenMP_8cpp_source.html below:

clang: lib/Parse/ParseOpenMP.cpp Source File

27#include "llvm/ADT/SmallBitVector.h" 28#include "llvm/ADT/StringSwitch.h" 29#include "llvm/Frontend/OpenMP/OMPAssume.h" 30#include "llvm/Frontend/OpenMP/OMPContext.h" 33using namespace clang

;

34using namespace

llvm::omp;

41enum

OpenMPDirectiveKindEx {

42

OMPD_cancellation = llvm::omp::Directive_enumSize + 1,

54

OMPD_distribute_parallel,

55

OMPD_teams_distribute_parallel,

56

OMPD_target_teams_distribute_parallel,

66struct

OpenMPDirectiveKindExWrapper {

69 bool operator==

(OpenMPDirectiveKindExWrapper

V

)

const

{

72 bool operator!=

(OpenMPDirectiveKindExWrapper

V

)

const

{

83class

DeclDirectiveListParserHelper final {

92 ExprResult

Res =

P

->getActions().OpenMP().ActOnOpenMPIdExpression(

93 P

->getCurScope(), SS, NameInfo, Kind);

95

Identifiers.push_back(Res.

get

());

104

OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);

105 if

(DKind != OMPD_unknown)

108 return

llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)

109

.Case(

"cancellation"

, OMPD_cancellation)

110

.Case(

"data"

, OMPD_data)

111

.Case(

"declare"

, OMPD_declare)

112

.Case(

"end"

, OMPD_end)

113

.Case(

"enter"

, OMPD_enter)

114

.Case(

"exit"

, OMPD_exit)

115

.Case(

"point"

, OMPD_point)

116

.Case(

"reduction"

, OMPD_reduction)

117

.Case(

"update"

, OMPD_update)

118

.Case(

"mapper"

, OMPD_mapper)

119

.Case(

"variant"

, OMPD_variant)

120

.Case(

"begin"

, OMPD_begin)

121

.Default(OMPD_unknown);

128 static const

OpenMPDirectiveKindExWrapper F[][3] = {

129

{OMPD_begin, OMPD_declare, OMPD_begin_declare},

130

{OMPD_begin, OMPD_assumes, OMPD_begin_assumes},

131

{OMPD_end, OMPD_declare, OMPD_end_declare},

132

{OMPD_end, OMPD_assumes, OMPD_end_assumes},

133

{OMPD_cancellation, OMPD_point, OMPD_cancellation_point},

134

{OMPD_declare, OMPD_reduction, OMPD_declare_reduction},

135

{OMPD_declare, OMPD_mapper, OMPD_declare_mapper},

136

{OMPD_declare, OMPD_simd, OMPD_declare_simd},

137

{OMPD_declare, OMPD_target, OMPD_declare_target},

138

{OMPD_declare, OMPD_variant, OMPD_declare_variant},

139

{OMPD_begin_declare, OMPD_target, OMPD_begin_declare_target},

140

{OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},

141

{OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},

142

{OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},

143

{OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},

144

{OMPD_distribute_parallel_for, OMPD_simd,

145

OMPD_distribute_parallel_for_simd},

146

{OMPD_distribute, OMPD_simd, OMPD_distribute_simd},

147

{OMPD_end_declare, OMPD_target, OMPD_end_declare_target},

148

{OMPD_target, OMPD_data, OMPD_target_data},

149

{OMPD_target, OMPD_enter, OMPD_target_enter},

150

{OMPD_target, OMPD_exit, OMPD_target_exit},

151

{OMPD_target, OMPD_update, OMPD_target_update},

152

{OMPD_target_enter, OMPD_data, OMPD_target_enter_data},

153

{OMPD_target_exit, OMPD_data, OMPD_target_exit_data},

154

{OMPD_for, OMPD_simd, OMPD_for_simd},

155

{OMPD_parallel, OMPD_for, OMPD_parallel_for},

156

{OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},

157

{OMPD_parallel, OMPD_loop, OMPD_parallel_loop},

158

{OMPD_parallel, OMPD_sections, OMPD_parallel_sections},

159

{OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},

160

{OMPD_target, OMPD_parallel, OMPD_target_parallel},

161

{OMPD_target, OMPD_simd, OMPD_target_simd},

162

{OMPD_target_parallel, OMPD_loop, OMPD_target_parallel_loop},

163

{OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},

164

{OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},

165

{OMPD_teams, OMPD_distribute, OMPD_teams_distribute},

166

{OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},

167

{OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},

168

{OMPD_teams_distribute_parallel, OMPD_for,

169

OMPD_teams_distribute_parallel_for},

170

{OMPD_teams_distribute_parallel_for, OMPD_simd,

171

OMPD_teams_distribute_parallel_for_simd},

172

{OMPD_teams, OMPD_loop, OMPD_teams_loop},

173

{OMPD_target, OMPD_teams, OMPD_target_teams},

174

{OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},

175

{OMPD_target_teams, OMPD_loop, OMPD_target_teams_loop},

176

{OMPD_target_teams_distribute, OMPD_parallel,

177

OMPD_target_teams_distribute_parallel},

178

{OMPD_target_teams_distribute, OMPD_simd,

179

OMPD_target_teams_distribute_simd},

180

{OMPD_target_teams_distribute_parallel, OMPD_for,

181

OMPD_target_teams_distribute_parallel_for},

182

{OMPD_target_teams_distribute_parallel_for, OMPD_simd,

183

OMPD_target_teams_distribute_parallel_for_simd},

184

{OMPD_master, OMPD_taskloop, OMPD_master_taskloop},

185

{OMPD_masked, OMPD_taskloop, OMPD_masked_taskloop},

186

{OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},

187

{OMPD_masked_taskloop, OMPD_simd, OMPD_masked_taskloop_simd},

188

{OMPD_parallel, OMPD_master, OMPD_parallel_master},

189

{OMPD_parallel, OMPD_masked, OMPD_parallel_masked},

190

{OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},

191

{OMPD_parallel_masked, OMPD_taskloop, OMPD_parallel_masked_taskloop},

192

{OMPD_parallel_master_taskloop, OMPD_simd,

193

OMPD_parallel_master_taskloop_simd},

194

{OMPD_parallel_masked_taskloop, OMPD_simd,

195

OMPD_parallel_masked_taskloop_simd}};

196 enum

{ CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };

197 Token

Tok =

P

.getCurToken();

198

OpenMPDirectiveKindExWrapper DKind =

200

?

static_cast<unsigned>

(OMPD_unknown)

202 if

(DKind == OMPD_unknown)

205 for

(

const auto

&I : F) {

209

Tok =

P

.getPreprocessor().LookAhead(0);

210

OpenMPDirectiveKindExWrapper SDKind =

212

?

static_cast<unsigned>

(OMPD_unknown)

214 if

(SDKind == OMPD_unknown)

217 if

(SDKind == I[1]) {

222 return unsigned

(DKind) < llvm::omp::Directive_enumSize

228 Token

Tok =

P

.getCurToken();

229 Sema

&Actions =

P

.getActions();

232 bool

WithOperator =

false

;

233 if

(Tok.

is

(tok::kw_operator)) {

235

Tok =

P

.getCurToken();

236

WithOperator =

true

;

263 case

tok::identifier:

268 P

.Diag(Tok.

getLocation

(), diag::err_omp_expected_reduction_identifier);

269 P

.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,

276

: DeclNames.getCXXOperatorName(OOK);

293 if

(

T

.expectAndConsume(

294

diag::err_expected_lparen_after,

295

getOpenMPDirectiveName(OMPD_declare_reduction).data())) {

301 if

(Name.isEmpty() && Tok.

is

(tok::annot_pragma_openmp_end))

305 bool

IsCorrect = !ExpectAndConsume(tok::colon);

307 if

(!IsCorrect && Tok.

is

(tok::annot_pragma_openmp_end))

310

IsCorrect = IsCorrect && !Name.isEmpty();

312 if

(Tok.

is

(tok::colon) || Tok.

is

(tok::annot_pragma_openmp_end)) {

317 if

(!IsCorrect && Tok.

is

(tok::annot_pragma_openmp_end))

329 if

(!ReductionType.

isNull

()) {

330

ReductionTypes.push_back(

334 SkipUntil

(tok::comma, tok::colon, tok::annot_pragma_openmp_end,

338 if

(Tok.

is

(tok::colon) || Tok.

is

(tok::annot_pragma_openmp_end))

342 if

(ExpectAndConsume(tok::comma)) {

344 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

349

}

while

(Tok.

isNot

(tok::annot_pragma_openmp_end));

351 if

(ReductionTypes.empty()) {

356 if

(!IsCorrect && Tok.

is

(tok::annot_pragma_openmp_end))

360 if

(ExpectAndConsume(tok::colon))

363 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

375 unsigned

I = 0,

E

= ReductionTypes.size();

376 for

(

Decl

*

D

: DRD.get()) {

377

TentativeParsingAction TPA(*

this

);

386 D

, CombinerResult.

get

());

389

Tok.

isNot

(tok::annot_pragma_openmp_end)) {

394

IsCorrect = !

T

.consumeClose() && IsCorrect && CombinerResult.

isUsable

();

396 if

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

398 if

(Tok.

is

(tok::identifier) &&

409

tok::annot_pragma_openmp_end);

411

!

T

.expectAndConsume(diag::err_expected_lparen_after,

"initializer"

) &&

413 if

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

422 if

(Tok.

is

(tok::identifier) &&

425

ParseOpenMPReductionInitializerForDecl(OmpPrivParm);

432 D

, InitializerResult.

get

(), OmpPrivParm);

433 if

(InitializerResult.

isInvalid

() && Tok.

isNot

(tok::r_paren) &&

434

Tok.

isNot

(tok::annot_pragma_openmp_end)) {

440

!

T

.consumeClose() && IsCorrect && !InitializerResult.

isInvalid

();

456void

Parser::ParseOpenMPReductionInitializerForDecl(

VarDecl

*OmpPrivParm) {

459 if

(isTokenEqualOrEqualTypo()) {

462 if

(Tok.

is

(tok::code_completion)) {

473 if

(

Init

.isInvalid()) {

480

}

else if

(Tok.

is

(tok::l_paren)) {

488 auto

RunSignatureHelp = [

this

, OmpPrivParm, LParLoc, &Exprs]() {

492

OmpPrivParm->

getLocation

(), Exprs, LParLoc,

false

);

493

CalledSignatureHelp =

true

;

494 return

PreferredType;

496 if

(ParseExpressionList(Exprs, [&] {

497

PreferredType.enterFunctionArgument(Tok.

getLocation

(),

507 if

(!

T

.consumeClose())

508

RLoc =

T

.getCloseLocation();

517 Diag

(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);

521 if

(

Init

.isInvalid()) {

542 bool

IsCorrect =

true

;

545 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

546

getOpenMPDirectiveName(OMPD_declare_mapper).data())) {

555 if

(Tok.

isNot

(tok::identifier) && Tok.

isNot

(tok::kw_default)) {

563

ExpectAndConsume(tok::colon);

570 if

(!IsCorrect && Tok.

is

(tok::annot_pragma_openmp_end))

581 if

(MapperType.

isNull

())

589

IsCorrect &= !

T

.consumeClose();

600

ParseScope OMPDirectiveScope(

this

, ScopeFlags);

611 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

617

ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());

619

Clauses.push_back(Clause);

623 if

(Tok.

is

(tok::comma))

627 if

(Clauses.empty()) {

628 Diag

(Tok, diag::err_omp_expected_clause)

629

<< getOpenMPDirectiveName(OMPD_declare_mapper);

635

OMPDirectiveScope.Exit();

649

Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;

651

ParseSpecifierQualifierList(DS, AS, DSC);

656

ParseDeclarator(DeclaratorInfo);

657 Range

= DeclaratorInfo.getSourceRange();

658 if

(DeclaratorInfo.getIdentifier() ==

nullptr

) {

674class

FNContextRAII final {

678 bool

HasFunScope =

false

;

679

FNContextRAII() =

delete

;

680

FNContextRAII(

const

FNContextRAII &) =

delete

;

681

FNContextRAII &operator=(

const

FNContextRAII &) =

delete

;

688 Sema

&Actions =

P

.getActions();

696 P

.ReenterTemplateScopes(Scopes,

D

);

708 P

.getActions().ActOnExitFunctionContext();

727 const Token

&Tok =

P

.getCurToken();

728 bool

IsError =

false

;

729 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

730 if

(Tok.

isNot

(tok::identifier))

732

OMPDeclareSimdDeclAttr::BranchStateTy Out;

734

StringRef ClauseName = II->

getName

();

736 if

(OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {

737 if

(BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {

738 P

.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)

740

<< OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;

746

}

else if

(ClauseName ==

"simdlen"

) {

748 P

.Diag(Tok, diag::err_omp_more_one_clause)

749

<< getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;

754

SimdLen =

P

.ParseOpenMPParensExpr(ClauseName, RLoc);

759 if

(CKind == OMPC_uniform || CKind == OMPC_aligned ||

760

CKind == OMPC_linear) {

763 if

(CKind == OMPC_aligned) {

765

}

else if

(CKind == OMPC_linear) {

766 Data

.ExtraModifier = OMPC_LINEAR_val;

771 if

(

P

.ParseOpenMPVarList(OMPD_declare_simd,

772

getOpenMPClauseKind(ClauseName), *Vars,

Data

))

774 if

(CKind == OMPC_aligned) {

775

Alignments.append(Aligneds.size() - Alignments.size(),

776 Data

.DepModOrTailExpr);

777

}

else if

(CKind == OMPC_linear) {

778

assert(0 <=

Data

.ExtraModifier &&

780 "Unexpected linear modifier."

);

781 if

(

P

.getActions().OpenMP().CheckOpenMPLinearModifier(

783 Data

.ExtraModifierLoc))

784 Data

.ExtraModifier = OMPC_LINEAR_val;

785

LinModifiers.append(Linears.size() - LinModifiers.size(),

786 Data

.ExtraModifier);

787

Steps.append(Linears.size() - Steps.size(),

Data

.DepModOrTailExpr);

794 if

(Tok.

is

(tok::comma))

805

PP.EnterTokenStream(Toks,

true

,

811

FNContextRAII FnContext(*

this

, Ptr);

812

OMPDeclareSimdDeclAttr::BranchStateTy BS =

813

OMPDeclareSimdDeclAttr::BS_Undefined;

823

Alignments, Linears, LinModifiers, Steps);

824

skipUntilPragmaOpenMPEnd(OMPD_declare_simd);

830

Ptr, BS, Simdlen.

get

(), Uniforms, Aligneds, Alignments, Linears,

838

CONTEXT_SELECTOR_SET_LVL = 0,

839

CONTEXT_SELECTOR_LVL = 1,

840

CONTEXT_TRAIT_LVL = 2,

843static

StringRef stringLiteralParser(

Parser

&

P

) {

844 ExprResult

Res =

P

.ParseStringLiteralExpression(

true

);

848static

StringRef getNameFromIdOrString(

Parser

&

P

,

Token

&Tok,

850 if

(Tok.

is

(tok::identifier) || Tok.

is

(tok::kw_for)) {

852

StringRef Name =

P

.getPreprocessor().getSpelling(Tok, Buffer);

853

(void)

P

.ConsumeToken();

858 return

stringLiteralParser(

P

);

861

diag::warn_omp_declare_variant_string_literal_or_identifier)

866static bool

checkForDuplicates(

Parser

&

P

, StringRef Name,

868

llvm::StringMap<SourceLocation> &Seen,

870 auto

Res = Seen.try_emplace(Name, NameLoc);

876 P

.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)

878 P

.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)

885

llvm::omp::TraitSet

Set

,

887

llvm::StringMap<SourceLocation> &Seen) {

888

TIProperty.

Kind

= TraitProperty::invalid;

891

StringRef Name = getNameFromIdOrString(*

this

, Tok, CONTEXT_TRAIT_LVL);

894

<< CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(

Set

,

Selector

);

899

TIProperty.

Kind

= getOpenMPContextTraitPropertyKind(

Set

,

Selector

, Name);

900 if

(TIProperty.

Kind

!= TraitProperty::invalid) {

901 if

(checkForDuplicates(*

this

, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))

902

TIProperty.

Kind

= TraitProperty::invalid;

908 Diag

(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)

909

<< Name << getOpenMPContextTraitSelectorName(

Selector

)

910

<< getOpenMPContextTraitSetName(

Set

);

912

TraitSet SetForName = getOpenMPContextTraitSetKind(Name);

913 if

(SetForName != TraitSet::invalid) {

914 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_is_a)

915

<< Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;

916 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_try)

917

<< Name <<

"<selector-name>" 918

<<

"(<property-name>)"

;

921

TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);

922 if

(SelectorForName != TraitSelector::invalid) {

923 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_is_a)

924

<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;

925 bool

AllowsTraitScore =

false

;

926 bool

RequiresProperty =

false

;

927

isValidTraitSelectorForTraitSet(

928

SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),

929

AllowsTraitScore, RequiresProperty);

930 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_try)

931

<< getOpenMPContextTraitSetName(

932

getOpenMPContextTraitSetForSelector(SelectorForName))

933

<< Name << (RequiresProperty ?

"(<property-name>)"

:

""

);

936 for

(

const auto

&PotentialSet :

937

{TraitSet::construct, TraitSet::user, TraitSet::implementation,

939

TraitProperty PropertyForName =

940

getOpenMPContextTraitPropertyKind(PotentialSet,

Selector

, Name);

941 if

(PropertyForName == TraitProperty::invalid)

943 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_try)

944

<< getOpenMPContextTraitSetName(

945

getOpenMPContextTraitSetForProperty(PropertyForName))

946

<< getOpenMPContextTraitSelectorName(

947

getOpenMPContextTraitSelectorForProperty(PropertyForName))

948

<< (

"("

+ Name +

")"

).str();

951 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_options)

952

<< CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(

Set

,

Selector

);

958

llvm::StringMap<SourceLocation> &Seen) {

959

assert(TISelector.

Kind

==

960

llvm::omp::TraitSelector::implementation_extension &&

961 "Only for extension properties, e.g., " 962 "`implementation={extension(PROPERTY)}`"

);

963 if

(TIProperty.

Kind

== TraitProperty::invalid)

966 if

(TIProperty.

Kind

==

967

TraitProperty::implementation_extension_disable_implicit_base)

970 if

(TIProperty.

Kind

==

971

TraitProperty::implementation_extension_allow_templates)

974 if

(TIProperty.

Kind

==

975

TraitProperty::implementation_extension_bind_to_declaration)

980

llvm::omp::TraitProperty::implementation_extension_match_all ||

982

llvm::omp::TraitProperty::implementation_extension_match_any ||

984

llvm::omp::TraitProperty::implementation_extension_match_none);

987 if

(IsMatchExtension(TIProperty)) {

989 if

(IsMatchExtension(SeenProp)) {

990 P

.Diag(

Loc

, diag::err_omp_variant_ctx_second_match_extension);

991

StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(

994 P

.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)

995

<< CONTEXT_TRAIT_LVL << SeenName;

1001

llvm_unreachable(

"Unknown extension property!"

);

1005

llvm::omp::TraitSet

Set

,

1006

llvm::StringMap<SourceLocation> &Seen) {

1007

assert(TISelector.

Kind

!= TraitSelector::user_condition &&

1008 "User conditions are special properties not handled here!"

);

1012

parseOMPTraitPropertyKind(TIProperty,

Set

, TISelector.

Kind

, Seen);

1014 if

(TISelector.

Kind

== llvm::omp::TraitSelector::implementation_extension)

1017

TIProperty.

Kind

= TraitProperty::invalid;

1020 if

(TIProperty.

Kind

== TraitProperty::invalid) {

1022 Diag

(Tok.

getLocation

(), diag::note_omp_declare_variant_ctx_continue_here)

1023

<< CONTEXT_TRAIT_LVL;

1027 if

(isValidTraitPropertyForTraitSetAndSelector(TIProperty.

Kind

,

1032

TISelector.

Properties

.push_back(TIProperty);

1036 Diag

(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)

1037

<< getOpenMPContextTraitPropertyName(TIProperty.

Kind

,

1039

<< getOpenMPContextTraitSelectorName(TISelector.

Kind

)

1040

<< getOpenMPContextTraitSetName(

Set

);

1041 Diag

(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)

1042

<< getOpenMPContextTraitPropertyName(TIProperty.

Kind

,

1044

<< getOpenMPContextTraitSelectorName(

1045

getOpenMPContextTraitSelectorForProperty(TIProperty.

Kind

))

1046

<< getOpenMPContextTraitSetName(

1047

getOpenMPContextTraitSetForProperty(TIProperty.

Kind

));

1048 Diag

(Tok.

getLocation

(), diag::note_omp_declare_variant_ctx_continue_here)

1049

<< CONTEXT_TRAIT_LVL;

1053

llvm::omp::TraitSet

Set

,

1054

llvm::StringMap<SourceLocation> &Seen) {

1055

TISelector.

Kind

= TraitSelector::invalid;

1058

StringRef Name = getNameFromIdOrString(*

this

, Tok, CONTEXT_SELECTOR_LVL);

1060 Diag

(Tok.

getLocation

(), diag::note_omp_declare_variant_ctx_options)

1061

<< CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(

Set

);

1065

TISelector.

Kind

= getOpenMPContextTraitSelectorKind(Name);

1066 if

(TISelector.

Kind

!= TraitSelector::invalid) {

1067 if

(checkForDuplicates(*

this

, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))

1068

TISelector.

Kind

= TraitSelector::invalid;

1073 Diag

(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)

1074

<< Name << getOpenMPContextTraitSetName(

Set

);

1076

TraitSet SetForName = getOpenMPContextTraitSetKind(Name);

1077 if

(SetForName != TraitSet::invalid) {

1078 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_is_a)

1079

<< Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;

1080 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_try)

1081

<< Name <<

"<selector-name>" 1082

<<

"<property-name>"

;

1085 for

(

const auto

&PotentialSet :

1086

{TraitSet::construct, TraitSet::user, TraitSet::implementation,

1087

TraitSet::device}) {

1088

TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(

1089

PotentialSet, TraitSelector::invalid, Name);

1090 if

(PropertyForName == TraitProperty::invalid)

1092 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_is_a)

1093

<< Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;

1094 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_try)

1095

<< getOpenMPContextTraitSetName(

1096

getOpenMPContextTraitSetForProperty(PropertyForName))

1097

<< getOpenMPContextTraitSelectorName(

1098

getOpenMPContextTraitSelectorForProperty(PropertyForName))

1099

<< (

"("

+ Name +

")"

).str();

1102 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_options)

1103

<< CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(

Set

);

1110

StringRef SelectorName =

1111 P

.getPreprocessor().getSpelling(

P

.getCurToken(), Buffer);

1112 if

(SelectorName !=

"score"

)

1114

(void)

P

.ConsumeToken();

1116

ScoreExpr =

P

.ParseOpenMPParensExpr(SelectorName, RLoc);

1118 if

(

P

.getCurToken().is(tok::colon))

1119

(

void

)

P

.ConsumeAnyToken();

1121 P

.Diag(

P

.getCurToken(), diag::warn_omp_declare_variant_expected)

1123

<<

"score expression"

;

1130void

Parser::parseOMPContextSelector(

1132

llvm::StringMap<SourceLocation> &SeenSelectors) {

1133 unsigned short

OuterPC = ParenCount;

1138 auto

FinishSelector = [OuterPC,

this

]() ->

void

{

1141 while

(!

SkipUntil

({tok::r_brace, tok::r_paren, tok::comma,

1142

tok::annot_pragma_openmp_end},

1145 if

(Tok.

is

(tok::r_paren) && OuterPC > ParenCount)

1146

(

void

)ConsumeParen();

1147 if

(OuterPC <= ParenCount) {

1151 if

(!Tok.

is

(tok::comma) && !Tok.

is

(tok::r_paren)) {

1157 Diag

(Tok.

getLocation

(), diag::note_omp_declare_variant_ctx_continue_here)

1158

<< CONTEXT_SELECTOR_LVL;

1162

parseOMPTraitSelectorKind(TISelector,

Set

, SeenSelectors);

1163 if

(TISelector.

Kind

== TraitSelector::invalid)

1164 return

FinishSelector();

1166 bool

AllowsTraitScore =

false

;

1167 bool

RequiresProperty =

false

;

1168 if

(!isValidTraitSelectorForTraitSet(TISelector.

Kind

,

Set

, AllowsTraitScore,

1169

RequiresProperty)) {

1170 Diag

(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)

1171

<< getOpenMPContextTraitSelectorName(TISelector.

Kind

)

1172

<< getOpenMPContextTraitSetName(

Set

);

1173 Diag

(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)

1174

<< getOpenMPContextTraitSelectorName(TISelector.

Kind

)

1175

<< getOpenMPContextTraitSetName(

1176

getOpenMPContextTraitSetForSelector(TISelector.

Kind

))

1177

<< RequiresProperty;

1178 return

FinishSelector();

1181 if

(!RequiresProperty) {

1183

{getOpenMPContextTraitPropertyForSelector(TISelector.

Kind

),

1184

getOpenMPContextTraitSelectorName(TISelector.

Kind

)});

1188 if

(!Tok.

is

(tok::l_paren)) {

1189 Diag

(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)

1190

<< getOpenMPContextTraitSelectorName(TISelector.

Kind

)

1191

<< getOpenMPContextTraitSetName(

Set

);

1192 return

FinishSelector();

1195 if

(TISelector.

Kind

== TraitSelector::user_condition) {

1199 return

FinishSelector();

1202

{TraitProperty::user_condition_unknown,

"<condition>"

});

1207

tok::annot_pragma_openmp_end);

1209

(void)BDT.consumeOpen();

1214 if

(!AllowsTraitScore && !Score.

isUnset

()) {

1216 Diag

(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)

1217

<< getOpenMPContextTraitSelectorName(TISelector.

Kind

)

1218

<< getOpenMPContextTraitSetName(

Set

) << Score.

get

();

1220 Diag

(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)

1221

<< getOpenMPContextTraitSelectorName(TISelector.

Kind

)

1222

<< getOpenMPContextTraitSetName(

Set

) <<

"<invalid>"

;

1230

llvm::StringMap<SourceLocation> SeenProperties;

1232

parseOMPContextProperty(TISelector,

Set

, SeenProperties);

1239void

Parser::parseOMPTraitSetKind(

OMPTraitSet

&TISet,

1240

llvm::StringMap<SourceLocation> &Seen) {

1241

TISet.

Kind

= TraitSet::invalid;

1244

StringRef Name = getNameFromIdOrString(*

this

, Tok, CONTEXT_SELECTOR_SET_LVL);

1246 Diag

(Tok.

getLocation

(), diag::note_omp_declare_variant_ctx_options)

1247

<< CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();

1251

TISet.

Kind

= getOpenMPContextTraitSetKind(Name);

1252 if

(TISet.

Kind

!= TraitSet::invalid) {

1253 if

(checkForDuplicates(*

this

, Name, NameLoc, Seen,

1254

CONTEXT_SELECTOR_SET_LVL))

1255

TISet.

Kind

= TraitSet::invalid;

1260 Diag

(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;

1262

TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);

1263 if

(SelectorForName != TraitSelector::invalid) {

1264 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_is_a)

1265

<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;

1266 bool

AllowsTraitScore =

false

;

1267 bool

RequiresProperty =

false

;

1268

isValidTraitSelectorForTraitSet(

1269

SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),

1270

AllowsTraitScore, RequiresProperty);

1271 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_try)

1272

<< getOpenMPContextTraitSetName(

1273

getOpenMPContextTraitSetForSelector(SelectorForName))

1274

<< Name << (RequiresProperty ?

"(<property-name>)"

:

""

);

1277 for

(

const auto

&PotentialSet :

1278

{TraitSet::construct, TraitSet::user, TraitSet::implementation,

1279

TraitSet::device}) {

1280

TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(

1281

PotentialSet, TraitSelector::invalid, Name);

1282 if

(PropertyForName == TraitProperty::invalid)

1284 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_is_a)

1285

<< Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;

1286 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_try)

1287

<< getOpenMPContextTraitSetName(

1288

getOpenMPContextTraitSetForProperty(PropertyForName))

1289

<< getOpenMPContextTraitSelectorName(

1290

getOpenMPContextTraitSelectorForProperty(PropertyForName))

1291

<< (

"("

+ Name +

")"

).str();

1294 Diag

(NameLoc, diag::note_omp_declare_variant_ctx_options)

1295

<< CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();

1301void

Parser::parseOMPContextSelectorSet(

1302 OMPTraitSet

&TISet, llvm::StringMap<SourceLocation> &SeenSets) {

1303 auto

OuterBC = BraceCount;

1308 auto

FinishSelectorSet = [

this

, OuterBC]() ->

void

{

1311 while

(!

SkipUntil

({tok::comma, tok::r_brace, tok::r_paren,

1312

tok::annot_pragma_openmp_end},

1315 if

(Tok.

is

(tok::r_brace) && OuterBC > BraceCount)

1316

(

void

)ConsumeBrace();

1317 if

(OuterBC <= BraceCount) {

1321 if

(!Tok.

is

(tok::comma) && !Tok.

is

(tok::r_brace)) {

1327 Diag

(Tok.

getLocation

(), diag::note_omp_declare_variant_ctx_continue_here)

1328

<< CONTEXT_SELECTOR_SET_LVL;

1331

parseOMPTraitSetKind(TISet, SeenSets);

1332 if

(TISet.

Kind

== TraitSet::invalid)

1333 return

FinishSelectorSet();

1339

<< (

"context set name \""

+ getOpenMPContextTraitSetName(TISet.

Kind

) +

1344 if

(Tok.

is

(tok::l_brace)) {

1345

(void)ConsumeBrace();

1349

<< (

"'=' that follows the context set name \""

+

1350

getOpenMPContextTraitSetName(TISet.

Kind

) +

"\""

)

1354

llvm::StringMap<SourceLocation> SeenSelectors;

1357

parseOMPContextSelector(TISelector, TISet.

Kind

, SeenSelectors);

1358 if

(TISelector.

Kind

!= TraitSelector::invalid &&

1360

TISet.

Selectors

.push_back(TISelector);

1364 if

(Tok.

is

(tok::r_brace)) {

1365

(void)ConsumeBrace();

1369

<< (

"context selectors for the context set \""

+

1370

getOpenMPContextTraitSetName(TISet.

Kind

) +

"\""

)

1379

llvm::StringMap<SourceLocation> SeenSets;

1382

parseOMPContextSelectorSet(TISet, SeenSets);

1383 if

(TISet.

Kind

!= TraitSet::invalid && !TISet.

Selectors

.empty())

1384

TI.

Sets

.push_back(TISet);

1395

PP.EnterTokenStream(Toks,

true

,

1401

FNContextRAII FnContext(*

this

, Ptr);

1413

getOpenMPDirectiveName(OMPD_declare_variant), RLoc,

1416 if

(!AssociatedFunction.

isUsable

()) {

1417 if

(!Tok.

is

(tok::annot_pragma_openmp_end))

1421

(void)ConsumeAnnotationToken();

1426

Actions.

OpenMP

().getOMPTraitInfoForSurroundingScope();

1435 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

1436 Diag

(Tok.

getLocation

(), diag::err_omp_declare_variant_wrong_clause)

1440 bool

IsError =

false

;

1441 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

1445 if

(!isAllowedClauseForDirective(OMPD_declare_variant, CKind,

1447 Diag

(Tok.

getLocation

(), diag::err_omp_declare_variant_wrong_clause)

1454

IsError = parseOMPDeclareVariantMatchClause(

Loc

, TI, ParentTI);

1456 case

OMPC_adjust_args: {

1464

llvm::append_range(

Data

.ExtraModifier == OMPC_ADJUST_ARGS_nothing

1466

: AdjustNeedDevicePtr,

1470 case

OMPC_append_args:

1471 if

(!AppendArgs.empty()) {

1472 Diag

(AppendArgsLoc, diag::err_omp_more_one_clause)

1473

<< getOpenMPDirectiveName(OMPD_declare_variant)

1474

<< getOpenMPClauseName(CKind) << 0;

1480

IsError = parseOpenMPAppendArgs(AppendArgs);

1484

llvm_unreachable(

"Unexpected clause for declare variant."

);

1491

(void)ConsumeAnnotationToken();

1495 if

(Tok.

is

(tok::comma))

1499

std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =

1501

Ptr, AssociatedFunction.

get

(), TI, AppendArgs.size(),

1504 if

(DeclVarData && !TI.

Sets

.empty())

1506

DeclVarData->first, DeclVarData->second, TI, AdjustNothing,

1507

AdjustNeedDevicePtr, AppendArgs, AdjustArgsLoc, AppendArgsLoc,

1511

(void)ConsumeAnnotationToken();

1514bool

Parser::parseOpenMPAppendArgs(

1516 bool

HasError =

false

;

1519 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

1520

getOpenMPClauseName(OMPC_append_args).data()))

1528

tok::annot_pragma_openmp_end);

1529 if

(IT.expectAndConsume(diag::err_expected_lparen_after,

"interop"

))

1533 if

(ParseOMPInteropInfo(InteropInfo, OMPC_append_args))

1536

InteropInfos.push_back(InteropInfo);

1539 if

(Tok.

is

(tok::comma))

1542 if

(!HasError && InteropInfos.empty()) {

1545 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

1548

HasError =

T

.consumeClose() || HasError;

1559 if

(CKind != OMPC_match) {

1560 Diag

(Tok.

getLocation

(), diag::err_omp_declare_variant_wrong_clause)

1567 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

1568

getOpenMPClauseName(OMPC_match).data()))

1572

parseOMPContextSelectors(

Loc

, TI);

1575

(void)

T

.consumeClose();

1586 bool

MergedSet =

false

;

1588 if

(

Set

.Kind != ParentSet.

Kind

)

1592 bool

MergedSelector =

false

;

1596

MergedSelector =

true

;

1599 bool

MergedProperty =

false

;

1613 if

(

Selector

.Kind == llvm::omp::TraitSelector::user_condition) {

1614 Diag

(

Loc

, diag::err_omp_declare_variant_nested_user_condition);

1615

}

else if

(

Selector

.ScoreOrCondition !=

1617 Diag

(

Loc

, diag::err_omp_declare_variant_duplicate_nested_trait)

1618

<< getOpenMPContextTraitPropertyName(

1620

<< getOpenMPContextTraitSelectorName(ParentSelector.

Kind

)

1621

<< getOpenMPContextTraitSetName(ParentSet.

Kind

);

1624 if

(!MergedProperty)

1625 Selector

.Properties.push_back(ParentProperty);

1628 if

(!MergedSelector)

1629 Set

.Selectors.push_back(ParentSelector);

1633

TI.

Sets

.push_back(ParentSet);

1649

std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;

1650 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

1656

ParseOpenMPClause(DKind, CKind, !SeenClauses[

unsigned

(CKind)]);

1657 SkipUntil

(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,

1659

SeenClauses[

unsigned

(CKind)] =

true

;

1660 if

(Clause !=

nullptr

)

1661

Clauses.push_back(Clause);

1662 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

1667 if

(Tok.

is

(tok::comma))

1688 bool

SkippedClauses =

false

;

1690 auto

SkipBraces = [&](llvm::StringRef Spelling,

bool

IssueNote) {

1692

tok::annot_pragma_openmp_end);

1693 if

(

T

.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))

1696 if

(IssueNote &&

T

.getCloseLocation().isValid())

1697 Diag

(

T

.getCloseLocation(),

1698

diag::note_omp_assumption_clause_continue_here);

1704 auto

MatchACMClause = [&](StringRef RawString) {

1705

llvm::StringSwitch<int> SS(RawString);

1706 unsigned

ACMIdx = 0;

1707 for

(

const

AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {

1708 if

(ACMI.StartsWith)

1709

SS.StartsWith(ACMI.Identifier, ACMIdx++);

1711

SS.Case(ACMI.Identifier, ACMIdx++);

1713 return

SS.Default(-1);

1716 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

1722

Idx = MatchACMClause(II->

getName

());

1726 bool

NextIsLPar = Tok.

is

(tok::l_paren);

1729 Diag

(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)

1730

<< llvm::omp::getOpenMPDirectiveName(DKind)

1731

<< llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;

1733

SkipBraces(II ? II->

getName

() :

""

,

true

);

1734

SkippedClauses =

true

;

1737 const

AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];

1738 if

(ACMI.HasDirectiveList || ACMI.HasExpression) {

1741

SkippedClauses =

true

;

1742

SkipBraces(II->

getName

(),

false

);

1748

diag::warn_omp_unknown_assumption_clause_without_args)

1750

SkipBraces(II->

getName

(),

true

);

1753

assert(II &&

"Expected an identifier clause!"

);

1754

std::string Assumption = II->

getName

().str();

1755 if

(ACMI.StartsWith)

1756

Assumption =

"ompx_"

+ Assumption.substr(ACMI.Identifier.size());

1758

Assumption =

"omp_"

+ Assumption;

1759

Assumptions.push_back(Assumption);

1770 Diag

(

Loc

, diag::err_expected_begin_assumes);

1784struct

SimpleClauseData {

1796static

std::optional<SimpleClauseData>

1798 const Token

&Tok =

P

.getCurToken();

1803 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

1804

getOpenMPClauseName(Kind).data()))

1805 return

std::nullopt;

1808

Kind, Tok.

isAnnotation

() ?

""

:

P

.getPreprocessor().getSpelling(Tok),

1811 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

1812

Tok.

isNot

(tok::annot_pragma_openmp_end))

1813 P

.ConsumeAnyToken();

1817 if

(!

T

.consumeClose())

1818

RLoc =

T

.getCloseLocation();

1823void

Parser::ParseOMPDeclareTargetClauses(

1826 bool

RequiresToOrLinkOrIndirectClause =

false

;

1827 bool

HasToOrLinkOrIndirectClause =

false

;

1828 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

1829

OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;

1830 bool

HasIdentifier = Tok.

is

(tok::identifier);

1831 if

(HasIdentifier) {

1833

RequiresToOrLinkOrIndirectClause =

true

;

1835

StringRef ClauseName = II->

getName

();

1836 bool

IsDeviceTypeClause =

1838

getOpenMPClauseKind(ClauseName) == OMPC_device_type;

1840 bool

IsIndirectClause =

getLangOpts

().OpenMP >= 51 &&

1841

getOpenMPClauseKind(ClauseName) == OMPC_indirect;

1842 if

(DTCI.

Indirect

&& IsIndirectClause) {

1843 Diag

(Tok, diag::err_omp_more_one_clause)

1844

<< getOpenMPDirectiveName(OMPD_declare_target)

1845

<< getOpenMPClauseName(OMPC_indirect) << 0;

1848 bool

IsToEnterOrLinkClause =

1849

OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);

1850

assert((!IsDeviceTypeClause || !IsToEnterOrLinkClause) &&

1851 "Cannot be both!"

);

1855 if

(

getLangOpts

().OpenMP >= 52 && ClauseName ==

"to"

) {

1856 Diag

(Tok, diag::err_omp_declare_target_unexpected_to_clause);

1859 if

(

getLangOpts

().OpenMP <= 51 && ClauseName ==

"enter"

) {

1860 Diag

(Tok, diag::err_omp_declare_target_unexpected_enter_clause);

1864 if

(!IsDeviceTypeClause && !IsIndirectClause &&

1865

DTCI.

Kind

== OMPD_begin_declare_target) {

1866 Diag

(Tok, diag::err_omp_declare_target_unexpected_clause)

1867

<< ClauseName << (

getLangOpts

().OpenMP >= 51 ? 3 : 0);

1870 if

(!IsDeviceTypeClause && !IsToEnterOrLinkClause && !IsIndirectClause) {

1872

? diag::err_omp_declare_target_unexpected_clause_52

1873

: diag::err_omp_declare_target_unexpected_clause)

1881 if

(IsToEnterOrLinkClause || IsIndirectClause)

1882

HasToOrLinkOrIndirectClause =

true

;

1884 if

(IsIndirectClause) {

1885 if

(!ParseOpenMPIndirectClause(DTCI,

false

))

1890 if

(IsDeviceTypeClause) {

1891

std::optional<SimpleClauseData> DevTypeData =

1894 if

(DeviceTypeLoc.

isValid

()) {

1896 Diag

(DevTypeData->Loc,

1897

diag::warn_omp_more_one_device_type_clause);

1901 case

OMPC_DEVICE_TYPE_any:

1902

DTCI.

DT

= OMPDeclareTargetDeclAttr::DT_Any;

1904 case

OMPC_DEVICE_TYPE_host:

1905

DTCI.

DT

= OMPDeclareTargetDeclAttr::DT_Host;

1907 case

OMPC_DEVICE_TYPE_nohost:

1908

DTCI.

DT

= OMPDeclareTargetDeclAttr::DT_NoHost;

1911

llvm_unreachable(

"Unexpected device_type"

);

1913

DeviceTypeLoc = DevTypeData->Loc;

1920 if

(DTCI.

Kind

== OMPD_declare_target || HasIdentifier) {

1921 auto

&&Callback = [

this

, MT, &DTCI](

CXXScopeSpec

&SS,

1930 Diag

(NameInfo.

getLoc

(), diag::err_omp_declare_target_multiple)

1933 if

(ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,

1938 if

(Tok.

is

(tok::l_paren)) {

1940

diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);

1943 if

(!HasIdentifier && Tok.

isNot

(tok::annot_pragma_openmp_end)) {

1946

? diag::err_omp_declare_target_wrong_clause_after_implicit_enter

1947

: diag::err_omp_declare_target_wrong_clause_after_implicit_to);

1952 if

(Tok.

is

(tok::comma))

1956 if

(DTCI.

Indirect

&& DTCI.

DT

!= OMPDeclareTargetDeclAttr::DT_Any)

1957 Diag

(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);

1960 if

(DTCI.

Kind

== OMPD_declare_target && RequiresToOrLinkOrIndirectClause &&

1961

!HasToOrLinkOrIndirectClause)

1964

? diag::err_omp_declare_target_missing_enter_or_link_clause

1965

: diag::err_omp_declare_target_missing_to_or_link_clause)

1974 if

(Tok.

is

(tok::annot_pragma_openmp_end))

1977 Diag

(Tok, diag::warn_omp_extra_tokens_at_eol)

1978

<< getOpenMPDirectiveName(DKind);

1979 while

(Tok.

isNot

(tok::annot_pragma_openmp_end))

1988 bool

SkipUntilOpenMPEnd) {

1989 int

DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;

1991 if

(FoundKind == ExpectedKind) {

1993

skipUntilPragmaOpenMPEnd(ExpectedKind);

1997 Diag

(FoundLoc, diag::err_expected_end_declare_target_or_variant)

1999 Diag

(BeginLoc, diag::note_matching)

2000

<< (

"'#pragma omp "

+ getOpenMPDirectiveName(BeginKind) +

"'"

).str();

2001 if

(SkipUntilOpenMPEnd)

2008

parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,

2012 if

(Tok.

is

(tok::annot_pragma_openmp_end))

2013

ConsumeAnnotationToken();

2055

assert(Tok.

isOneOf

(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&

2056 "Not an OpenMP directive!"

);

2063

TentativeParsingAction TPA(*

this

);

2064 Loc

= ConsumeAnnotationToken();

2066 if

(DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {

2071

Toks.push_back(Tok);

2072 while

(Cnt && Tok.

isNot

(tok::eof)) {

2074 if

(Tok.

isOneOf

(tok::annot_pragma_openmp, tok::annot_attr_openmp))

2076 else if

(Tok.

is

(tok::annot_pragma_openmp_end))

2078

Toks.push_back(Tok);

2083 auto

*LP =

new

LateParsedPragma(

this

, AS);

2085

getCurrentClass().LateParsedDeclarations.push_back(LP);

2090 Loc

= ConsumeAnnotationToken();

2095 case

OMPD_threadprivate: {

2097

DeclDirectiveListParserHelper Helper(

this

, DKind);

2098 if

(!ParseOpenMPSimpleVarList(DKind, Helper,

2100

skipUntilPragmaOpenMPEnd(DKind);

2102

ConsumeAnnotationToken();

2104 Loc

, Helper.getIdentifiers());

2108 case

OMPD_allocate: {

2110

DeclDirectiveListParserHelper Helper(

this

, DKind);

2111 if

(!ParseOpenMPSimpleVarList(DKind, Helper,

2114 if

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2115

std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;

2116 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2121 OMPClause

*Clause = ParseOpenMPClause(OMPD_allocate, CKind,

2122

!SeenClauses[

unsigned

(CKind)]);

2123 SkipUntil

(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,

2125

SeenClauses[

unsigned

(CKind)] =

true

;

2126 if

(Clause !=

nullptr

)

2127

Clauses.push_back(Clause);

2128 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

2133 if

(Tok.

is

(tok::comma))

2137

skipUntilPragmaOpenMPEnd(DKind);

2140

ConsumeAnnotationToken();

2142 Loc

, Helper.getIdentifiers(), Clauses);

2146 case

OMPD_requires: {

2149

llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);

2150 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

2151 Diag

(Tok, diag::err_omp_expected_clause)

2152

<< getOpenMPDirectiveName(OMPD_requires);

2155 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2160 OMPClause

*Clause = ParseOpenMPClause(OMPD_requires, CKind,

2161

!SeenClauses[

unsigned

(CKind)]);

2162 SkipUntil

(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,

2164

SeenClauses[

unsigned

(CKind)] =

true

;

2165 if

(Clause !=

nullptr

)

2166

Clauses.push_back(Clause);

2167 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

2172 if

(Tok.

is

(tok::comma))

2177 if

(Clauses.empty()) {

2178 Diag

(Tok, diag::err_omp_expected_clause)

2179

<< getOpenMPDirectiveName(OMPD_requires);

2180

ConsumeAnnotationToken();

2183

ConsumeAnnotationToken();

2189

ParseOpenMPClauses(DKind, Clauses, StartLoc);

2196 case

OMPD_begin_assumes:

2199 case

OMPD_end_assumes:

2202 case

OMPD_declare_reduction:

2204 if

(

DeclGroupPtrTy

Res = ParseOpenMPDeclareReductionDirective(AS)) {

2205

skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);

2207

ConsumeAnnotationToken();

2211 case

OMPD_declare_mapper: {

2213 if

(

DeclGroupPtrTy

Res = ParseOpenMPDeclareMapperDirective(AS)) {

2215

ConsumeAnnotationToken();

2220 case

OMPD_begin_declare_variant: {

2228

Actions.

OpenMP

().getOMPTraitInfoForSurroundingScope();

2231 if

(parseOMPDeclareVariantMatchClause(

Loc

, TI, ParentTI)) {

2235

(void)ConsumeAnnotationToken();

2240

skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);

2244

VariantMatchInfo VMI;

2247

std::function<void(StringRef)> DiagUnknownTrait =

2248

[

this

,

Loc

](StringRef ISATrait) {

2251 Diag

(

Loc

, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;

2254

ASTCtx, std::move(DiagUnknownTrait),

2258 if

(isVariantApplicableInContext(VMI, OMPCtx,

true

)) {

2264 unsigned

Nesting = 1;

2270 if

(DK == OMPD_end_declare_variant)

2272 else if

(DK == OMPD_begin_declare_variant)

2274 if

(!Nesting || isEofOrEom())

2279

parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,

2280

DK,

Loc

, DKLoc,

true

);

2285 case

OMPD_end_declare_variant: {

2289 Diag

(

Loc

, diag::err_expected_begin_declare_variant);

2293 case

OMPD_declare_variant:

2294 case

OMPD_declare_simd: {

2300

Toks.push_back(Tok);

2302 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2303

Toks.push_back(Tok);

2306

Toks.push_back(Tok);

2310 if

(Tok.

isOneOf

(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {

2311

Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,

2313

}

else if

(Tok.

isNot

(tok::r_brace) && !isEofOrEom()) {

2318

MaybeParseCXX11Attributes(Attrs);

2320

Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);

2323

ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs,

TagType

, Tag);

2327 Diag

(

Loc

, diag::err_omp_decl_in_declare_simd_variant)

2328

<< (DKind == OMPD_declare_simd ? 0 : 1);

2331 if

(DKind == OMPD_declare_simd)

2332 return

ParseOMPDeclareSimdClauses(Ptr, Toks,

Loc

);

2333

assert(DKind == OMPD_declare_variant &&

2334 "Expected declare variant directive only"

);

2335

ParseOMPDeclareVariantClauses(Ptr, Toks,

Loc

);

2338 case

OMPD_begin_declare_target:

2339 case

OMPD_declare_target: {

2341 bool

HasClauses = Tok.

isNot

(tok::annot_pragma_openmp_end);

2344

ParseOMPDeclareTargetClauses(DTCI);

2345 bool

HasImplicitMappings = DKind == OMPD_begin_declare_target ||

2352 if

(HasImplicitMappings) {

2360

Decls.push_back(It.first);

2363 case

OMPD_end_declare_target: {

2365 Diag

(Tok, diag::err_omp_unexpected_directive)

2366

<< 1 << getOpenMPDirectiveName(DKind);

2371

ParseOMPEndDeclareTargetDirective(DTCI.

Kind

, DKind, DTCI.

Loc

);

2375 Diag

(Tok, diag::err_omp_unexpected_directive)

2376

<< 1 << getOpenMPDirectiveName(DKind);

2380 Diag

(Tok, diag::err_omp_unknown_directive);

2383 switch

(getDirectiveCategory(DKind)) {

2384 case

Category::Executable:

2385 case

Category::Meta:

2386 case

Category::Subsidiary:

2387 case

Category::Utility:

2388 Diag

(Tok, diag::err_omp_unexpected_directive)

2389

<< 1 << getOpenMPDirectiveName(DKind);

2391 case

Category::Declarative:

2392 case

Category::Informational:

2396 while

(Tok.

isNot

(tok::annot_pragma_openmp_end))

2402StmtResult

Parser::ParseOpenMPExecutableDirective(

2404 bool

ReadDirectiveWithinMetadirective) {

2407 bool

HasAssociatedStatement =

true

;

2408 Association

Assoc = getDirectiveAssociation(DKind);

2414 if

(DKind != OMPD_ordered && DKind != OMPD_section &&

2415

(Assoc == Association::None || Assoc == Association::Separating)) {

2416 if

((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==

2417

ParsedStmtContext()) {

2418 Diag

(Tok, diag::err_omp_immediate_directive)

2419

<< getOpenMPDirectiveName(DKind) << 0;

2420 if

(DKind == OMPD_error) {

2421 SkipUntil

(tok::annot_pragma_openmp_end);

2425

HasAssociatedStatement =

false

;

2430

llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);

2438 bool

ImplicitClauseAllowed =

false

;

2439 if

(DKind == OMPD_flush || DKind == OMPD_depobj) {

2441

ImplicitClauseAllowed =

true

;

2445 if

(DKind == OMPD_critical) {

2447

tok::annot_pragma_openmp_end);

2448 if

(!

T

.consumeOpen()) {

2454 Diag

(Tok, diag::err_omp_expected_identifier_for_critical);

2458

}

else if

(DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {

2460 if

(Tok.

isNot

(tok::annot_pragma_openmp_end))

2468

ParseScope OMPDirectiveScope(

this

, ScopeFlags);

2472 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2475 if

(ReadDirectiveWithinMetadirective && Tok.

is

(tok::r_paren)) {

2476 while

(Tok.

isNot

(tok::annot_pragma_openmp_end))

2480 bool

HasImplicitClause =

false

;

2481 if

(ImplicitClauseAllowed && Tok.

is

(tok::l_paren)) {

2482

HasImplicitClause =

true

;

2492 if

(HasImplicitClause) {

2493

assert(CKind == OMPC_unknown &&

"Must be unknown implicit clause."

);

2494 if

(DKind == OMPD_flush) {

2497

assert(DKind == OMPD_depobj &&

"Expected flush or depobj directives."

);

2498

CKind = OMPC_depobj;

2502

ImplicitClauseAllowed =

false

;

2504

HasImplicitClause =

false

;

2506

ParseOpenMPClause(DKind, CKind, !SeenClauses[

unsigned

(CKind)]);

2507

SeenClauses[

unsigned

(CKind)] =

true

;

2509

Clauses.push_back(Clause);

2512 if

(Tok.

is

(tok::comma))

2519

ConsumeAnnotationToken();

2521 if

(DKind == OMPD_ordered) {

2524 for

(

auto

CK : {OMPC_depend, OMPC_doacross}) {

2525 if

(SeenClauses[

unsigned

(CK)]) {

2526 if

((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==

2527

ParsedStmtContext()) {

2528 Diag

(

Loc

, diag::err_omp_immediate_directive)

2529

<< getOpenMPDirectiveName(DKind) << 1 << getOpenMPClauseName(CK);

2531

HasAssociatedStatement =

false

;

2536 if

(DKind == OMPD_tile && !SeenClauses[

unsigned

(OMPC_sizes)]) {

2537 Diag

(

Loc

, diag::err_omp_required_clause)

2538

<< getOpenMPDirectiveName(OMPD_tile) <<

"sizes"

;

2542 if

(HasAssociatedStatement) {

2551

AssociatedStmt = ParseStatement();

2560

}

else if

(DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||

2561

DKind == OMPD_target_exit_data) {

2571

DKind, DirName, CancelRegion, Clauses, AssociatedStmt.

get

(),

Loc

, EndLoc);

2575

OMPDirectiveScope.Exit();

2580StmtResult

Parser::ParseOpenMPInformationalDirective(

2582 bool

ReadDirectiveWithinMetadirective) {

2584 "Unexpected directive category"

);

2586 bool

HasAssociatedStatement =

true

;

2589

llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);

2593

ParseScope OMPDirectiveScope(

this

, ScopeFlags);

2598 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2599 if

(ReadDirectiveWithinMetadirective && Tok.

is

(tok::r_paren)) {

2600 while

(Tok.

isNot

(tok::annot_pragma_openmp_end))

2610

ParseOpenMPClause(DKind, CKind, !SeenClauses[

unsigned

(CKind)]);

2611

SeenClauses[

unsigned

(CKind)] =

true

;

2613

Clauses.push_back(Clause);

2615 if

(Tok.

is

(tok::comma))

2621

ConsumeAnnotationToken();

2624 if

(HasAssociatedStatement) {

2629

AssociatedStmt = ParseStatement();

2636

DKind, DirName, Clauses, AssociatedStmt.

get

(),

Loc

, EndLoc);

2639

OMPDirectiveScope.Exit();

2684StmtResult

Parser::ParseOpenMPDeclarativeOrExecutableDirective(

2685

ParsedStmtContext StmtCtx,

bool

ReadDirectiveWithinMetadirective) {

2686 if

(!ReadDirectiveWithinMetadirective)

2687

assert(Tok.

isOneOf

(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&

2688 "Not an OpenMP directive!"

);

2693

: ConsumeAnnotationToken();

2695 if

(ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {

2696 Diag

(Tok, diag::err_omp_unknown_directive);

2702 bool

IsExecutable = [&]() {

2703 if

(DKind == OMPD_error)

2705 auto

Res = getDirectiveCategory(DKind);

2706 return

Res == Category::Executable || Res == Category::Subsidiary;

2710 Directive

= ParseOpenMPExecutableDirective(

2711

StmtCtx, DKind,

Loc

, ReadDirectiveWithinMetadirective);

2712

assert(!

Directive

.isUnset() &&

"Executable directive remained unprocessed"

);

2721 if

(ReadDirectiveWithinMetadirective && Tok.

is

(tok::r_paren))

2722 while

(Tok.

isNot

(tok::annot_pragma_openmp_end))

2725

skipUntilPragmaOpenMPEnd(DKind);

2726 if

(Tok.

is

(tok::annot_pragma_openmp_end))

2727

ConsumeAnnotationToken();

2730 case

OMPD_metadirective: {

2737

TentativeParsingAction TPA(*

this

);

2741

tok::annot_pragma_openmp_end);

2742 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2749 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

2750

getOpenMPClauseName(CKind).data()))

2754 if

(CKind == OMPC_when) {

2756

parseOMPContextSelectors(

Loc

, TI);

2757 if

(TI.

Sets

.size() == 0) {

2758 Diag

(Tok, diag::err_omp_expected_context_selector) <<

"when clause"

;

2764 if

(Tok.

is

(tok::colon))

2767 Diag

(Tok, diag::err_omp_expected_colon) <<

"when clause"

;

2774 while

(Tok.

isNot

(tok::r_paren) || paren != 0) {

2775 if

(Tok.

is

(tok::l_paren))

2777 if

(Tok.

is

(tok::r_paren))

2779 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

2780 Diag

(Tok, diag::err_omp_expected_punc)

2781

<< getOpenMPClauseName(CKind) << 0;

2788 if

(Tok.

is

(tok::r_paren))

2791

VariantMatchInfo VMI;

2794

VMIs.push_back(VMI);

2800

std::function<void(StringRef)> DiagUnknownTrait =

2801

[

this

,

Loc

](StringRef ISATrait) {

2804 Diag

(

Loc

, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;

2811 int

BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);

2818 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2820 if

(Idx++ != BestIdx) {

2825 while

(Tok.

isNot

(tok::r_paren) || paren != 0) {

2826 if

(Tok.

is

(tok::l_paren))

2828 if

(Tok.

is

(tok::r_paren))

2833 if

(Tok.

is

(tok::r_paren))

2847 if

(CKind == OMPC_when) {

2850

parseOMPContextSelectors(

Loc

, TI);

2858 if

(Tok.

is

(tok::r_paren)) {

2859 SkipUntil

(tok::annot_pragma_openmp_end);

2864 Directive

= ParseOpenMPDeclarativeOrExecutableDirective(

2871 case

OMPD_threadprivate: {

2873 if

((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==

2874

ParsedStmtContext()) {

2875 Diag

(Tok, diag::err_omp_immediate_directive)

2876

<< getOpenMPDirectiveName(DKind) << 0;

2879

DeclDirectiveListParserHelper Helper(

this

, DKind);

2880 if

(!ParseOpenMPSimpleVarList(DKind, Helper,

2882

skipUntilPragmaOpenMPEnd(DKind);

2884 Loc

, Helper.getIdentifiers());

2887 SkipUntil

(tok::annot_pragma_openmp_end);

2890 case

OMPD_allocate: {

2892 if

((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==

2893

ParsedStmtContext()) {

2894 Diag

(Tok, diag::err_omp_immediate_directive)

2895

<< getOpenMPDirectiveName(DKind) << 0;

2898

DeclDirectiveListParserHelper Helper(

this

, DKind);

2899 if

(!ParseOpenMPSimpleVarList(DKind, Helper,

2902 if

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2903

llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);

2904 while

(Tok.

isNot

(tok::annot_pragma_openmp_end)) {

2909 OMPClause

*Clause = ParseOpenMPClause(OMPD_allocate, CKind,

2910

!SeenClauses[

unsigned

(CKind)]);

2911 SkipUntil

(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,

2913

SeenClauses[

unsigned

(CKind)] =

true

;

2914 if

(Clause !=

nullptr

)

2915

Clauses.push_back(Clause);

2916 if

(Tok.

is

(tok::annot_pragma_openmp_end)) {

2921 if

(Tok.

is

(tok::comma))

2925

skipUntilPragmaOpenMPEnd(DKind);

2928 Loc

, Helper.getIdentifiers(), Clauses);

2931 SkipUntil

(tok::annot_pragma_openmp_end);

2934 case

OMPD_declare_reduction:

2937

ParseOpenMPDeclareReductionDirective(

AS_none

)) {

2938

skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);

2942 SkipUntil

(tok::annot_pragma_openmp_end);

2945 case

OMPD_declare_mapper: {

2948

ParseOpenMPDeclareMapperDirective(

AS_none

)) {

2950

ConsumeAnnotationToken();

2953 SkipUntil

(tok::annot_pragma_openmp_end);

2957 case

OMPD_declare_target: {

2959 bool

HasClauses = Tok.

isNot

(tok::annot_pragma_openmp_end);

2962

ParseOMPDeclareTargetClauses(DTCI);

2963 bool

HasImplicitMappings =

2966 if

(HasImplicitMappings) {

2967 Diag

(Tok, diag::err_omp_unexpected_directive)

2968

<< 1 << getOpenMPDirectiveName(DKind);

2969 SkipUntil

(tok::annot_pragma_openmp_end);

2979 case

OMPD_declare_simd:

2980 case

OMPD_begin_declare_target:

2981 case

OMPD_end_declare_target:

2983 case

OMPD_begin_declare_variant:

2984 case

OMPD_end_declare_variant:

2985 case

OMPD_declare_variant:

2986 Diag

(Tok, diag::err_omp_unexpected_directive)

2987

<< 1 << getOpenMPDirectiveName(DKind);

2988 SkipUntil

(tok::annot_pragma_openmp_end);

2992 Directive

= ParseOpenMPInformationalDirective(

2993

StmtCtx, DKind,

Loc

, ReadDirectiveWithinMetadirective);

2995 "Informational directive remains unprocessed"

);

3000 Diag

(Tok, diag::err_omp_unknown_directive);

3001 SkipUntil

(tok::annot_pragma_openmp_end);

3011bool

Parser::ParseOpenMPSimpleVarList(

3015 bool

AllowScopeSpecifier) {

3018 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

3019

getOpenMPDirectiveName(Kind).data()))

3021 bool

IsCorrect =

true

;

3022 bool

NoIdentIsFound =

true

;

3025 while

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::annot_pragma_openmp_end)) {

3029 Token

PrevTok = Tok;

3030

NoIdentIsFound =

false

;

3033

ParseOptionalCXXScopeSpecifier(SS,

nullptr

,

3036 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

3039 false

,

false

,

false

,

3040 false

,

false

,

nullptr

, Name)) {

3042 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

3044

}

else if

(Tok.

isNot

(tok::comma) && Tok.

isNot

(tok::r_paren) &&

3045

Tok.

isNot

(tok::annot_pragma_openmp_end)) {

3047 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

3056 if

(Tok.

is

(tok::comma)) {

3061 if

(NoIdentIsFound) {

3062 Diag

(Tok, diag::err_expected) << tok::identifier;

3067

IsCorrect = !

T

.consumeClose() && IsCorrect;

3072OMPClause

*Parser::ParseOpenMPSizesClause() {

3075 if

(ParseOpenMPExprListClause(OMPC_sizes, ClauseNameLoc, OpenLoc, CloseLoc,

3083OMPClause

*Parser::ParseOpenMPPermutationClause() {

3086 if

(ParseOpenMPExprListClause(OMPC_permutation, ClauseNameLoc, OpenLoc,

3101 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

"uses_allocator"

))

3109

? ParseCXXIdExpression()

3110

: tryParseCXXIdExpression(SS,

false

,

3112 if

(Allocator.isInvalid()) {

3113 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

3118 D

.Allocator = Allocator.get();

3119 if

(Tok.

is

(tok::l_paren)) {

3121

tok::annot_pragma_openmp_end);

3127 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

3131 D

.AllocatorTraits = AllocatorTraits.

get

();

3132 D

.LParenLoc =

T

.getOpenLocation();

3133 D

.RParenLoc =

T

.getCloseLocation();

3135 if

(Tok.

isNot

(tok::comma) && Tok.

isNot

(tok::r_paren))

3136 Diag

(Tok, diag::err_omp_expected_punc) <<

"uses_allocators"

<< 0;

3138 if

(Tok.

is

(tok::comma))

3140

}

while

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::annot_pragma_openmp_end));

3143 Loc

,

T

.getOpenLocation(),

T

.getCloseLocation(),

Data

);

3168

OMPClauseKind = CKind;

3170 bool

ErrorFound =

false

;

3171 bool

WrongDirective =

false

;

3173 if

(CKind != OMPC_unknown &&

3174

!isAllowedClauseForDirective(DKind, CKind,

getLangOpts

().OpenMP)) {

3175 Diag

(Tok, diag::err_omp_unexpected_clause)

3176

<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);

3178

WrongDirective =

true

;

3183 case

OMPC_num_threads:

3189 case

OMPC_grainsize:

3190 case

OMPC_num_tasks:

3192 case

OMPC_allocator:

3195 case

OMPC_novariants:

3196 case

OMPC_nocontext:

3201 case

OMPC_ompx_dyn_cgroup_mem:

3230 Diag

(Tok, diag::err_omp_more_one_clause)

3231

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3235 if

((CKind == OMPC_ordered || CKind == OMPC_partial) &&

3237

Clause = ParseOpenMPClause(CKind, WrongDirective);

3238 else if

(CKind == OMPC_grainsize || CKind == OMPC_num_tasks)

3239

Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);

3241

Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);

3245 case

OMPC_proc_bind:

3246 case

OMPC_atomic_default_mem_order:

3264 Diag

(Tok, diag::err_omp_more_one_clause)

3265

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3269

Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);

3273 case

OMPC_dist_schedule:

3274 case

OMPC_defaultmap:

3284 if

((

getLangOpts

().OpenMP < 50 || CKind != OMPC_defaultmap) &&

3285

(CKind != OMPC_order ||

getLangOpts

().OpenMP >= 51) && !FirstClause) {

3286 Diag

(Tok, diag::err_omp_more_one_clause)

3287

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3292

Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);

3295

Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);

3299 case

OMPC_mergeable:

3313 case

OMPC_unified_address:

3314 case

OMPC_unified_shared_memory:

3315 case

OMPC_reverse_offload:

3316 case

OMPC_dynamic_allocators:

3325 Diag

(Tok, diag::err_omp_more_one_clause)

3326

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3330

Clause = ParseOpenMPClause(CKind, WrongDirective);

3334 Diag

(Tok, diag::err_omp_more_one_clause)

3335

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3339

Clause = (DKind == OMPD_depobj)

3340

? ParseOpenMPSimpleClause(CKind, WrongDirective)

3341

: ParseOpenMPClause(CKind, WrongDirective);

3343 case

OMPC_num_teams:

3344 case

OMPC_thread_limit:

3346 Diag

(Tok, diag::err_omp_more_one_clause)

3347

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3352 case

OMPC_firstprivate:

3353 case

OMPC_lastprivate:

3355 case

OMPC_reduction:

3356 case

OMPC_task_reduction:

3357 case

OMPC_in_reduction:

3361 case

OMPC_copyprivate:

3367 case

OMPC_use_device_ptr:

3368 case

OMPC_use_device_addr:

3369 case

OMPC_is_device_ptr:

3370 case

OMPC_has_device_addr:

3372 case

OMPC_nontemporal:

3373 case

OMPC_inclusive:

3374 case

OMPC_exclusive:

3378 if

(

getLangOpts

().OpenMP >= 52 && DKind == OMPD_ordered &&

3379

CKind == OMPC_depend)

3380 Diag

(Tok, diag::warn_omp_depend_in_ordered_deprecated);

3381

Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);

3385 Diag

(Tok, diag::err_omp_more_one_clause)

3386

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3390

Clause = ParseOpenMPSizesClause();

3392 case

OMPC_permutation:

3394 Diag

(Tok, diag::err_omp_more_one_clause)

3395

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3398

Clause = ParseOpenMPPermutationClause();

3400 case

OMPC_uses_allocators:

3401

Clause = ParseOpenMPUsesAllocatorClause(DKind);

3404 if

(DKind != OMPD_interop) {

3406 Diag

(Tok, diag::err_omp_more_one_clause)

3407

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3410

Clause = ParseOpenMPClause(CKind, WrongDirective);

3416

Clause = ParseOpenMPInteropClause(CKind, WrongDirective);

3418 case

OMPC_device_type:

3420

skipUntilPragmaOpenMPEnd(DKind);

3422 case

OMPC_threadprivate:

3425 if

(!WrongDirective)

3426 Diag

(Tok, diag::err_omp_unexpected_clause)

3427

<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);

3431 case

OMPC_contains: {

3440 if

(DK == OMPD_unknown) {

3441

skipUntilPragmaOpenMPEnd(OMPD_assume);

3442 Diag

(Tok, diag::err_omp_unexpected_clause)

3443

<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);

3447

DKVec.push_back(DK);

3450 Diag

(Tok, diag::err_omp_unexpected_clause)

3451

<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);

3457

CKind, DKVec,

Loc

, LLoc, RLoc);

3460 case

OMPC_no_openmp:

3461 case

OMPC_no_openmp_routines:

3462 case

OMPC_no_parallelism: {

3464 Diag

(Tok, diag::err_omp_more_one_clause)

3465

<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;

3473 case

OMPC_ompx_attribute:

3474

Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);

3476 case

OMPC_ompx_bare:

3477 if

(DKind == llvm::omp::Directive::OMPD_target) {

3482 Diag

(Tok, diag::err_omp_unexpected_clause)

3483

<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);

3485

WrongDirective =

true

;

3488 Diag

(Tok, diag::note_ompx_bare_clause)

3489

<< getOpenMPClauseName(CKind) <<

"target teams"

;

3490 if

(!ErrorFound && !

getLangOpts

().OpenMPExtensions) {

3491 Diag

(Tok, diag::err_omp_unexpected_clause_extension_only)

3492

<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);

3495

Clause = ParseOpenMPClause(CKind, WrongDirective);

3500 return

ErrorFound ? nullptr : Clause;

3508 bool

IsAddressOfOperand) {

3510 if

(

T

.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))

3515

ParseCastExpression(AnyCastExpr, IsAddressOfOperand,

NotTypeCast

));

3521 if

(!

T

.consumeClose())

3522

RLoc =

T

.getCloseLocation();

3592bool

Parser::ParseOpenMPIndirectClause(

3597 if

(Tok.

isNot

(tok::l_paren)) {

3616 if

(

Ret

.isInvalid())

3621 if

(

Ret

.isInvalid())

3634 bool

HasError =

false

;

3635 bool

IsTarget =

false

;

3636 bool

IsTargetSync =

false

;

3638 while

(Tok.

is

(tok::identifier)) {

3640 bool

PreferTypeAllowed =

Kind

== OMPC_init &&

3648 Diag

(Tok, diag::warn_omp_more_one_interop_type) <<

"target"

;

3653 Diag

(Tok, diag::warn_omp_more_one_interop_type) <<

"targetsync"

;

3654

IsTargetSync =

true

;

3657

PreferTypeAllowed) {

3660

tok::annot_pragma_openmp_end);

3661 if

(PT.expectAndConsume(diag::err_expected_lparen_after,

"prefer_type"

))

3664 while

(Tok.

isNot

(tok::r_paren)) {

3666 ExprResult

LHS = ParseCastExpression(AnyCastExpr);

3675 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

3679 if

(Tok.

is

(tok::comma))

3685 Diag

(Tok, diag::err_omp_expected_interop_type);

3688 if

(!Tok.

is

(tok::comma))

3693 if

(!HasError && !IsTarget && !IsTargetSync) {

3694 Diag

(Tok, diag::err_omp_expected_interop_type);

3698 if

(Kind == OMPC_init) {

3699 if

(Tok.

isNot

(tok::colon) && (IsTarget || IsTargetSync))

3700 Diag

(Tok, diag::warn_pragma_expected_colon) <<

"interop types"

;

3701 if

(Tok.

is

(tok::colon))

3741 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

3742

getOpenMPClauseName(Kind).data()))

3745 bool

InteropError =

false

;

3747 if

(Kind == OMPC_init)

3748

InteropError = ParseOMPInteropInfo(InteropInfo, OMPC_init);

3754 if

(!InteropVarExpr.

isUsable

()) {

3755 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

3761 if

(!

T

.consumeClose())

3762

RLoc =

T

.getCloseLocation();

3764 if

(ParseOnly || !InteropVarExpr.

isUsable

() || InteropError)

3767 if

(Kind == OMPC_init)

3769

InteropVarExpr.

get

(), InteropInfo,

Loc

,

T

.getOpenLocation(), VarLoc,

3771 if

(Kind == OMPC_use)

3773

InteropVarExpr.

get

(),

Loc

,

T

.getOpenLocation(), VarLoc, RLoc);

3775 if

(Kind == OMPC_destroy)

3777

InteropVarExpr.

get

(),

Loc

,

T

.getOpenLocation(), VarLoc, RLoc);

3779

llvm_unreachable(

"Unexpected interop variable clause."

);

3782OMPClause

*Parser::ParseOpenMPOMPXAttributesClause(

bool

ParseOnly) {

3786 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

3787

getOpenMPClauseName(OMPC_ompx_attribute).data()))

3791

ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);

3794 if

(

T

.consumeClose())

3802 switch

(PA.getKind()) {

3803 case

ParsedAttr::AT_AMDGPUFlatWorkGroupSize:

3804 if

(!PA.checkExactlyNumArgs(Actions, 2))

3807

PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))

3810 case

ParsedAttr::AT_AMDGPUWavesPerEU:

3811 if

(!PA.checkAtLeastNumArgs(Actions, 1) ||

3812

!PA.checkAtMostNumArgs(Actions, 2))

3815

PA, PA.getArgAsExpr(0),

3816

PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :

nullptr

))

3819 case

ParsedAttr::AT_CUDALaunchBounds:

3820 if

(!PA.checkAtLeastNumArgs(Actions, 1) ||

3821

!PA.checkAtMostNumArgs(Actions, 2))

3824

PA, PA.getArgAsExpr(0),

3825

PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) :

nullptr

,

3826

PA.getNumArgs() > 2 ? PA.getArgAsExpr(2) :

nullptr

))

3830 Diag

(

Loc

, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;

3836

Attrs,

Loc

,

T

.getOpenLocation(),

T

.getCloseLocation());

3857 if

(!Val || ParseOnly)

3859 if

(

getLangOpts

().OpenMP < 51 && Kind == OMPC_default &&

3860

(

static_cast<

DefaultKind

>

(Val->Type) == OMP_DEFAULT_private ||

3861 static_cast<

DefaultKind

>

(Val->Type) ==

3862

OMP_DEFAULT_firstprivate)) {

3863 Diag

(Val->LOpen, diag::err_omp_invalid_dsa)

3864

<< getOpenMPClauseName(

static_cast<

DefaultKind

>

(Val->Type) ==

3867

: OMPC_firstprivate)

3868

<< getOpenMPClauseName(OMPC_default) <<

"5.1"

;

3872

Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);

3933 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

3934

getOpenMPClauseName(Kind).data()))

3940 if

(Kind == OMPC_schedule) {

3941 enum

{ Modifier1, Modifier2, ScheduleKind, NumberOfElements };

3942

Arg.resize(NumberOfElements);

3943

KLoc.resize(NumberOfElements);

3951

Arg[Modifier1] = KindModifier;

3953 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

3954

Tok.

isNot

(tok::annot_pragma_openmp_end))

3956 if

(Tok.

is

(tok::comma)) {

3965 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

3966

Tok.

isNot

(tok::annot_pragma_openmp_end))

3970 if

(Tok.

is

(tok::colon))

3973 Diag

(Tok, diag::warn_pragma_expected_colon) <<

"schedule modifier"

;

3977

Arg[ScheduleKind] = KindModifier;

3979 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

3980

Tok.

isNot

(tok::annot_pragma_openmp_end))

3982 if

((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||

3983

Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||

3984

Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&

3985

Tok.

is

(tok::comma))

3987

}

else if

(Kind == OMPC_dist_schedule) {

3991 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

3992

Tok.

isNot

(tok::annot_pragma_openmp_end))

3994 if

(Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.

is

(tok::comma))

3996

}

else if

(Kind == OMPC_defaultmap) {

4005

Arg.push_back(Modifier);

4007 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

4008

Tok.

isNot

(tok::annot_pragma_openmp_end))

4012 if

(Tok.

is

(tok::colon))

4015 Diag

(Tok, diag::warn_pragma_expected_colon) <<

"defaultmap modifier"

;

4020 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

4021

Tok.

isNot

(tok::annot_pragma_openmp_end))

4027

}

else if

(Kind == OMPC_order) {

4028 enum

{ Modifier, OrderKind, NumberOfElements };

4029

Arg.resize(NumberOfElements);

4030

KLoc.resize(NumberOfElements);

4037

Arg[Modifier] = KindModifier;

4039 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

4040

Tok.

isNot

(tok::annot_pragma_openmp_end))

4043 if

(Tok.

is

(tok::colon))

4046 Diag

(Tok, diag::warn_pragma_expected_colon) <<

"order modifier"

;

4050

Arg[OrderKind] = KindModifier;

4052 if

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::comma) &&

4053

Tok.

isNot

(tok::annot_pragma_openmp_end))

4055

}

else if

(Kind == OMPC_device) {

4068

KLoc.emplace_back();

4070

}

else if

(Kind == OMPC_grainsize) {

4078

Arg.push_back(Modifier);

4085 if

(Modifier == OMPC_GRAINSIZE_strict) {

4086 Diag

(Tok, diag::err_modifier_expected_colon) <<

"strict"

;

4091

KLoc.emplace_back();

4095

KLoc.emplace_back();

4097

}

else if

(Kind == OMPC_num_tasks) {

4105

Arg.push_back(Modifier);

4112 if

(Modifier == OMPC_NUMTASKS_strict) {

4113 Diag

(Tok, diag::err_modifier_expected_colon) <<

"strict"

;

4118

KLoc.emplace_back();

4122

KLoc.emplace_back();

4125

assert(Kind == OMPC_if);

4127

TentativeParsingAction TPA(*

this

);

4130 if

(DK != OMPD_unknown) {

4137

Arg.back() =

unsigned

(OMPD_unknown);

4144 bool

NeedAnExpression = (

Kind

== OMPC_schedule && DelimLoc.

isValid

()) ||

4145

(Kind == OMPC_dist_schedule && DelimLoc.

isValid

()) ||

4146

Kind == OMPC_if || Kind == OMPC_device ||

4147

Kind == OMPC_grainsize || Kind == OMPC_num_tasks;

4148 if

(NeedAnExpression) {

4158 if

(!

T

.consumeClose())

4159

RLoc =

T

.getCloseLocation();

4161 if

(NeedAnExpression && Val.

isInvalid

())

4167

Kind, Arg, Val.

get

(),

Loc

,

T

.getOpenLocation(), KLoc, DelimLoc, RLoc);

4172 if

(ReductionIdScopeSpec.

isEmpty

()) {

4174 switch

(

P

.getCurToken().getKind()) {

4209 return P

.ParseUnqualifiedId(

4210

ReductionIdScopeSpec,

nullptr

,

4214 false

,

nullptr

, ReductionId);

4220 Token

Tok =

P

.getCurToken();

4221 if

(!Tok.

is

(tok::identifier))

4228 return

TypeModifier;

4235 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

"mapper"

)) {

4236 SkipUntil

(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,

4242

ParseOptionalCXXScopeSpecifier(

Data

.ReductionOrMapperIdScopeSpec,

4246 if

(Tok.

isNot

(tok::identifier) && Tok.

isNot

(tok::kw_default)) {

4248 SkipUntil

(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,

4257 return T

.consumeClose();

4268 bool

HasMapType =

false

;

4270

StringRef PreMapName =

""

;

4274 if

(TypeModifier == OMPC_MAP_MODIFIER_always ||

4275

TypeModifier == OMPC_MAP_MODIFIER_close ||

4276

TypeModifier == OMPC_MAP_MODIFIER_present ||

4277

TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {

4278 Data

.MapTypeModifiers.push_back(TypeModifier);

4283

<<

"map type modifier"

;

4285

}

else if

(TypeModifier == OMPC_MAP_MODIFIER_mapper) {

4286 Data

.MapTypeModifiers.push_back(TypeModifier);

4291 if

(Tok.

isNot

(tok::comma) && Tok.

isNot

(tok::colon) &&

4293 Diag

(

Data

.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)

4294

<<

"map type modifier"

;

4299 Data

.ExtraModifier = MapKind;

4304 Diag

(Tok, diag::err_omp_more_one_map_type);

4305 Diag

(PreMapLoc, diag::note_previous_map_type_specified_here)

4313 if

(Tok.

is

(tok::comma)) {

4314 Diag

(Tok, diag::err_omp_map_type_modifier_missing);

4327 Diag

(Tok, diag::err_omp_unknown_map_type_modifier)

4336 if

(

getLangOpts

().OpenMP >= 60 && !HasMapType) {

4337 if

(!Tok.

is

(tok::colon)) {

4338 Diag

(Tok, diag::err_omp_unknown_map_type);

4350 Token

Tok =

P

.getCurToken();

4352 if

(!Tok.

isOneOf

(tok::identifier, tok::kw_delete))

4357 if

(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||

4358

MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc ||

4359

MapType == OMPC_MAP_delete || MapType == OMPC_MAP_release)

4368 Token

Tok =

P

.getCurToken();

4369 if

(Tok.

is

(tok::colon)) {

4370 P

.Diag(Tok, diag::err_omp_map_type_missing);

4375 P

.Diag(Tok, diag::err_omp_unknown_map_type);

4381ExprResult

Parser::ParseOpenMPIteratorsExpr() {

4382

assert(Tok.

is

(tok::identifier) && PP.

getSpelling

(Tok) ==

"iterator"

&&

4383 "Expected 'iterator' token."

);

4387 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

"iterator"

))

4392 while

(Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::annot_pragma_openmp_end)) {

4395 if

(Tok.

isNot

(tok::identifier) ||

NextToken

().isNot(tok::equal)) {

4402

IteratorType = TR.

get

();

4408 if

(Tok.

is

(tok::identifier)) {

4412 Diag

(Tok, diag::err_expected_unqualified_id) << 0;

4417 if

(Tok.

is

(tok::equal))

4420 Diag

(Tok, diag::err_omp_expected_equal_in_iterator);

4426 ExprResult

LHS = ParseCastExpression(AnyCastExpr);

4433 if

(Tok.

is

(tok::colon))

4438

LHS = ParseCastExpression(AnyCastExpr);

4447 if

(Tok.

is

(tok::colon)) {

4452

LHS = ParseCastExpression(AnyCastExpr);

4460 if

(Tok.

isNot

(tok::comma) && Tok.

isNot

(tok::r_paren))

4461 Diag

(Tok, diag::err_omp_expected_punc_after_iterator);

4462 if

(Tok.

is

(tok::comma))

4467 D

.DeclIdentLoc = IdLoc;

4468 D

.Type = IteratorType;

4469 D

.AssignLoc = AssignLoc;

4470 D

.ColonLoc = ColonLoc;

4471 D

.SecColonLoc = SecColonLoc;

4472 D

.Range.Begin =

Begin

.get();

4473 D

.Range.End = End.get();

4474 D

.Range.Step = Step.

get

();

4479 if

(!

T

.consumeClose())

4480

RLoc =

T

.getCloseLocation();

4491 if

(Kind != OMPC_depend || LangOpts.OpenMP < 51)

4494 if

(Tok.

is

(tok::identifier) &&

4497 if

(

Data

.ExtraModifier == OMPC_DEPEND_outallmemory ||

4498 Data

.ExtraModifier == OMPC_DEPEND_inoutallmemory)

4499 Diag

(Tok, diag::warn_omp_more_one_omp_all_memory);

4500 else if

(

Data

.ExtraModifier != OMPC_DEPEND_out &&

4501 Data

.ExtraModifier != OMPC_DEPEND_inout)

4502 Diag

(Tok, diag::err_omp_requires_out_inout_depend_type);

4504 Data

.ExtraModifier =

Data

.ExtraModifier == OMPC_DEPEND_out

4505

? OMPC_DEPEND_outallmemory

4506

: OMPC_DEPEND_inoutallmemory;

4518 Sema

&Actions =

P

.getActions();

4522 Data

.DepModOrTailExpr = Tail.

get

();

4523 Token

CurTok =

P

.getCurToken();

4524 if

(CurTok.

isNot

(tok::r_paren) && CurTok.

isNot

(tok::comma)) {

4525 P

.Diag(CurTok, diag::err_expected_punc) <<

"step expression"

;

4538 const Token

&Tok =

P

.getCurToken();

4543 bool

AllocatorSeen =

false

;

4544 bool

AlignSeen =

false

;

4550 if

(

P

.getLangOpts().OpenMP < 51)

4551 return P

.ParseAssignmentExpression();

4559 return P

.ParseAssignmentExpression();

4563 if

(Tok.

is

(tok::l_paren)) {

4564 switch

(CurrentModifier) {

4565 case

OMPC_ALLOCATE_allocator: {

4566 if

(AllocatorSeen) {

4567 P

.Diag(Tok, diag::err_omp_duplicate_modifier)

4569

<< getOpenMPClauseName(Kind);

4571 Data

.AllocClauseModifiers.push_back(CurrentModifier);

4572 Data

.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);

4575

tok::annot_pragma_openmp_end);

4577

Tail =

P

.ParseAssignmentExpression();

4579

AllocatorSeen =

true

;

4582 case

OMPC_ALLOCATE_align: {

4584 P

.Diag(Tok, diag::err_omp_duplicate_modifier)

4586

<< getOpenMPClauseName(Kind);

4588 Data

.AllocClauseModifiers.push_back(CurrentModifier);

4589 Data

.AllocClauseModifiersLoc.push_back(CurrentModifierLoc);

4591

Val =

P

.ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);

4593 Data

.AllocateAlignment = Val.

get

();

4598

llvm_unreachable(

"Unexpected allocate modifier"

);

4601 P

.Diag(Tok, diag::err_expected) << tok::l_paren;

4603 if

(Tok.

isNot

(tok::comma))

4611 P

.Diag(Tok, diag::err_omp_expected_modifier) << getOpenMPClauseName(Kind);

4614

}

while

(!AllocatorSeen || !AlignSeen);

4624 bool

InvalidReductionId =

false

;

4625 bool

IsInvalidMapperModifier =

false

;

4629 if

(

T

.expectAndConsume(diag::err_expected_lparen_after,

4630

getOpenMPClauseName(Kind).data()))

4633 bool

HasIterator =

false

;

4634 bool

InvalidIterator =

false

;

4635 bool

NeedRParenForLinear =

false

;

4637

tok::annot_pragma_openmp_end);

4639 if

(Kind == OMPC_reduction || Kind == OMPC_task_reduction ||

4640

Kind == OMPC_in_reduction) {

4642 if

(Kind == OMPC_reduction &&

getLangOpts

().OpenMP >= 50 &&

4643

(Tok.

is

(tok::identifier) || Tok.

is

(tok::kw_default)) &&

4646 Data

.ExtraModifier =

4650

assert(Tok.

is

(tok::comma) &&

"Expected comma."

);

4655

ParseOptionalCXXScopeSpecifier(

Data

.ReductionOrMapperIdScopeSpec,

4660

*

this

,

Data

.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);

4661 if

(InvalidReductionId) {

4662 SkipUntil

(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,

4665 if

(Tok.

is

(tok::colon))

4668 Diag

(Tok, diag::warn_pragma_expected_colon) <<

"reduction identifier"

;

4669 if

(!InvalidReductionId)

4670 Data

.ReductionOrMapperId =

4672

}

else if

(Kind == OMPC_depend || Kind == OMPC_doacross) {

4674 if

(Tok.

is

(tok::identifier) && PP.

getSpelling

(Tok) ==

"iterator"

) {

4681

HasIterator =

true

;

4683 ExprResult

IteratorRes = ParseOpenMPIteratorsExpr();

4684 Data

.DepModOrTailExpr = IteratorRes.

get

();

4686

ExpectAndConsume(tok::comma);

4692

Kind, Tok.

is

(tok::identifier) ? PP.

getSpelling

(Tok) :

""

,

4696

(Kind == OMPC_doacross &&

4698 SkipUntil

(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,

4703 if

(DKind == OMPD_ordered && Kind == OMPC_depend &&

4704 Data

.ExtraModifier == OMPC_DEPEND_source) {

4710 if

(Tok.

is

(tok::colon)) {

4712

}

else if

(Kind != OMPC_doacross || Tok.

isNot

(tok::r_paren)) {

4713 Diag

(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren

4714

: diag::warn_pragma_expected_colon)

4715

<< (Kind == OMPC_depend ?

"dependency type"

:

"dependence-type"

);

4717 if

(Kind == OMPC_doacross) {

4718 if

(Tok.

is

(tok::identifier) &&

4720 Data

.ExtraModifier =

Data

.ExtraModifier == OMPC_DOACROSS_source

4721

? OMPC_DOACROSS_source_omp_cur_iteration

4722

: OMPC_DOACROSS_sink_omp_cur_iteration;

4725 if

(

Data

.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {

4726 if

(Tok.

isNot

(tok::minus)) {

4727 Diag

(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)

4728

<< getOpenMPClauseName(Kind) << 0 << 0;

4735 if

(Tok.

isNot

(tok::numeric_constant) ||

4737 Diag

(

Loc

, diag::err_omp_sink_and_source_iteration_not_allowd)

4738

<< getOpenMPClauseName(Kind) << 0 << 0;

4744 if

(

Data

.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {

4745 if

(Tok.

isNot

(tok::r_paren)) {

4746 Diag

(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)

4747

<< getOpenMPClauseName(Kind) << 1 << 1;

4753 if

(Kind == OMPC_doacross &&

4754

(

Data

.ExtraModifier == OMPC_DOACROSS_source ||

4755 Data

.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||

4756 Data

.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {

4762

}

else if

(Kind == OMPC_linear) {

4764 Data

.ExtraModifier = OMPC_LINEAR_val;

4765 if

(Tok.

is

(tok::identifier) && PP.

LookAhead

(0).

is

(tok::l_paren)) {

4766 Data

.ExtraModifier =

4770

NeedRParenForLinear =

true

;

4772 Diag

(

Data

.ExtraModifierLoc, diag::err_omp_deprecate_old_syntax)

4773

<<

"linear-modifier(list)"

<< getOpenMPClauseName(Kind)

4774

<<

"linear(list: [linear-modifier,] step(step-size))"

;

4776

}

else if

(Kind == OMPC_lastprivate) {

4783

Tok.

is

(tok::identifier) && PP.

LookAhead

(0).

is

(tok::colon)) {

4784 Data

.ExtraModifier =

4788

assert(Tok.

is

(tok::colon) &&

"Expected colon."

);

4791

}

else if

(Kind == OMPC_map) {

4793 if

(Tok.

is

(tok::identifier) && PP.

getSpelling

(Tok) ==

"iterator"

) {

4794

HasIterator =

true

;

4796 Data

.MapTypeModifiers.push_back(OMPC_MAP_MODIFIER_iterator);

4798 ExprResult

IteratorRes = ParseOpenMPIteratorsExpr();

4799 Data

.IteratorExpr = IteratorRes.

get

();

4801

ExpectAndConsume(tok::comma);

4803 Diag

(Tok, diag::err_omp_unknown_map_type_modifier)

4806

InvalidIterator =

true

;

4819

TentativeParsingAction TPA(*

this

);

4820 bool

ColonPresent =

false

;

4821 if

(

SkipUntil

(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,

4823 if

(Tok.

is

(tok::colon))

4824

ColonPresent =

true

;

4831 Diag

(Tok, diag::err_omp_map_modifier_specification_list);

4833 if

(

getLangOpts

().OpenMP < 60 && !IsInvalidMapperModifier)

4839 Data

.ExtraModifier = OMPC_MAP_tofrom;

4841 if

(DKind == OMPD_target_enter_data)

4842 Data

.ExtraModifier = OMPC_MAP_to;

4843 else if

(DKind == OMPD_target_exit_data)

4844 Data

.ExtraModifier = OMPC_MAP_from;

4846 Data

.IsMapTypeImplicit =

true

;

4849 if

(Tok.

is

(tok::colon))

4851

}

else if

(Kind == OMPC_to || Kind == OMPC_from) {

4852 while

(Tok.

is

(tok::identifier)) {

4857 Data

.MotionModifiers.push_back(Modifier);

4860 if

(Modifier == OMPC_MOTION_MODIFIER_mapper) {

4862 if

(IsInvalidMapperModifier)

4870 if

(Tok.

is

(tok::comma))

4873 if

(!

Data

.MotionModifiers.empty() && Tok.

isNot

(tok::colon)) {

4874 if

(!IsInvalidMapperModifier) {

4876 Diag

(Tok, diag::warn_pragma_expected_colon) <<

")"

;

4878 Diag

(Tok, diag::warn_pragma_expected_colon) <<

"motion modifier"

;

4880 SkipUntil

(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,

4885 if

((!

Data

.MotionModifiers.empty() ||

getLangOpts

().OpenMP >= 51) &&

4886

Tok.

is

(tok::colon))

4888

}

else if

(Kind == OMPC_allocate ||

4889

(Kind == OMPC_affinity && Tok.

is

(tok::identifier) &&

4894

TentativeParsingAction TPA(*

this

);

4899 if

(Kind == OMPC_allocate) {

4902

HasIterator =

true

;

4904

Tail = ParseOpenMPIteratorsExpr();

4910 if

(Tok.

is

(tok::colon)) {

4917 if

(Kind == OMPC_allocate &&

Data

.AllocClauseModifiers.size()) {

4918 SkipUntil

(tok::r_paren, tok::annot_pragma_openmp_end,

4920 Diag

(Tok, diag::err_modifier_expected_colon) <<

"allocate clause"

;

4927 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

4930

}

else if

(Kind == OMPC_adjust_args) {

4934

Kind, Tok.

is

(tok::identifier) ? PP.

getSpelling

(Tok) :

""

,

4938 Diag

(Tok, diag::err_omp_unknown_adjust_args_op);

4942 if

(Tok.

is

(tok::colon))

4944

ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,

4950

(Kind != OMPC_reduction && Kind != OMPC_task_reduction &&

4951

Kind != OMPC_in_reduction && Kind != OMPC_depend &&

4952

Kind != OMPC_doacross && Kind != OMPC_map && Kind != OMPC_adjust_args) ||

4953

(Kind == OMPC_reduction && !InvalidReductionId) ||

4957

(Kind == OMPC_adjust_args &&

4959 const bool

MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);

4960 while

(IsComma || (Tok.

isNot

(tok::r_paren) && Tok.

isNot

(tok::colon) &&

4961

Tok.

isNot

(tok::annot_pragma_openmp_end))) {

4969

Vars.push_back(VarExpr.

get

());

4971 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

4976

IsComma = Tok.

is

(tok::comma);

4979 else if

(Tok.

isNot

(tok::r_paren) &&

4980

Tok.

isNot

(tok::annot_pragma_openmp_end) &&

4981

(!MayHaveTail || Tok.

isNot

(tok::colon)))

4982 Diag

(Tok, diag::err_omp_expected_punc)

4983

<< ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)

4984

: getOpenMPClauseName(Kind))

4985

<< (Kind == OMPC_flush);

4989 if

(NeedRParenForLinear)

4993 const bool

MustHaveTail = MayHaveTail && Tok.

is

(tok::colon);

4994 bool

StepFound =

false

;

4995 bool

ModifierFound =

false

;

5000 if

(

getLangOpts

().OpenMP >= 52 && Kind == OMPC_linear) {

5001 while

(Tok.

isNot

(tok::r_paren)) {

5002 if

(Tok.

is

(tok::identifier)) {

5010 if

(LinKind == OMPC_LINEAR_step) {

5012 Diag

(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;

5015

tok::annot_pragma_openmp_end);

5019 Diag

(StepModifierLoc, diag::err_expected_lparen_after) <<

"step"

;

5024 Data

.StepModifierLoc = StepModifierLoc;

5028

}

else if

(LinKind >= 0 && LinKind < OMPC_LINEAR_step) {

5030 Diag

(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;

5032 Data

.ExtraModifier = LinKind;

5034

ModifierFound =

true

;

5043 if

(Tok.

is

(tok::comma))

5045 if

(Tok.

is

(tok::r_paren) || Tok.

is

(tok::annot_pragma_openmp_end))

5048 if

(!StepFound && !ModifierFound)

5049 Diag

(ELoc, diag::err_expected_expression);

5056 Data

.DepModOrTailExpr = Tail.

get

();

5058 SkipUntil

(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,

5065 if

(!

T

.consumeClose())

5066 Data

.RLoc =

T

.getCloseLocation();

5070 return

(Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&

5072

(MustHaveTail && !

Data

.DepModOrTailExpr && StepFound) ||

5073

InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;

5159

assert(getOpenMPClauseName(Kind) == PP.

getSpelling

(Tok) &&

5160 "Expected parsing to start at clause name"

);

5165 if

(

T

.consumeOpen()) {

5166 Diag

(Tok, diag::err_expected) << tok::l_paren;

5179

Exprs.push_back(Val.

get

());

5182 bool Result

=

T

.consumeClose();

5183

OpenLoc =

T

.getOpenLocation();

5184

CloseLoc =

T

.getCloseLocation();

Defines the clang::ASTContext interface.

This file defines OpenMP AST classes for clauses.

Defines some OpenMP-specific enums and functions.

static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P)

static OpenMPMapModifierKind isMapModifier(Parser &P)

Checks if the token is a valid map-type-modifier.

static std::optional< SimpleClauseData > parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind)

static unsigned getOpenMPDirectiveKindEx(StringRef S)

static bool checkExtensionProperty(Parser &P, SourceLocation Loc, OMPTraitProperty &TIProperty, OMPTraitSelector &TISelector, llvm::StringMap< SourceLocation > &Seen)

static ExprResult parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data)

Parse 'allocate' clause modifiers.

static DeclarationName parseOpenMPReductionId(Parser &P)

static ExprResult parseContextScore(Parser &P)

Parse optional 'score' '(' <expr> ')' ':'.

static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)

static bool parseStepSize(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data, OpenMPClauseKind CKind, SourceLocation ELoc)

Parse step size expression.

static void parseMapType(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data)

Parse map-type in map clause.

static bool parseDeclareSimdClauses(Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, SmallVectorImpl< Expr * > &Uniforms, SmallVectorImpl< Expr * > &Aligneds, SmallVectorImpl< Expr * > &Alignments, SmallVectorImpl< Expr * > &Linears, SmallVectorImpl< unsigned > &LinModifiers, SmallVectorImpl< Expr * > &Steps)

Parses clauses for 'declare simd' directive.

static OpenMPMapClauseKind isMapType(Parser &P)

Checks if the token is a valid map-type.

This file declares semantic analysis functions specific to AMDGPU.

This file declares facilities that support code completion.

This file declares semantic analysis for OpenMP constructs and clauses.

This file defines OpenMP AST classes for executable directives and clauses.

Defines the clang::TokenKind enum and support functions.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

DeclarationNameTable DeclarationNames

OMPTraitInfo & getNewOMPTraitInfo()

Return a new OMPTraitInfo object owned by this context.

RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....

Represents a C++ nested-name-specifier or a global scope specifier.

bool isEmpty() const

No scope specifier.

ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.

Captures information about "declaration specifiers".

static const TST TST_unspecified

Decl - This represents one declaration (or definition), e.g.

bool isFunctionOrFunctionTemplate() const

Whether this declaration is a function or function template.

SourceLocation getLocation() const

DeclContext * getDeclContext()

The name of a declaration.

Information about one declarator, including the parsed type information and the identifier.

RAII object that enters a new expression evaluation context.

bool isValueDependent() const

Determines whether the value of this expression depends on.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

bool containsUnexpandedParameterPack() const

Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).

bool isInstantiationDependent() const

Whether this expression is instantiation-dependent, meaning that it depends in some way on.

One of these records is kept for each identifier that is lexed.

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

StringRef getName() const

Return the actual identifier string.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

This represents a decl that may have a name.

bool isCXXInstanceMember() const

Determine whether the given declaration is an instance member of a C++ class.

This is a basic class for representing single OpenMP clause.

Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...

void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const

Create a variant match info object from this trait info object.

llvm::SmallVector< OMPTraitSet, 2 > Sets

The outermost level of selector sets.

Wrapper for void* pointer.

RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...

ParsedAttr - Represents a syntactic attribute.

static const ParsedAttributesView & none()

ParsedAttributes - A collection of parsed attributes.

Introduces zero or more scopes for parsing.

ParseScope - Introduces a new scope for parsing.

Parser - This implements a parser for the C family of languages.

bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl< Expr * > &Vars, SemaOpenMP::OpenMPVarListDataTy &Data)

Parses clauses with list.

TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)

ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data)

Parses map-type-modifiers in map clause.

SourceLocation ConsumeToken()

ConsumeToken - Consume the current 'peek token' and lex the next one.

void EnterScope(unsigned ScopeFlags)

EnterScope - Start a new scope.

bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data)

Parses the mapper modifier in map, to, and from clauses.

bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)

Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.

SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)

ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.

ExprResult ParseConstantExpression()

bool TryConsumeToken(tok::TokenKind Expected)

OpaquePtr< DeclGroupRef > DeclGroupPtrTy

Scope * getCurScope() const

bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))

SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...

const Token & getCurToken() const

void ExitScope()

ExitScope - Pop a scope off the scope stack.

ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)

Parse an expr that doesn't include (top-level) commas.

ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc, bool IsAddressOfOperand=false)

Parses simple expression in parens for single-expression clauses of OpenMP constructs.

const LangOptions & getLangOpts() const

ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)

Simple precedence-based parser for binary/ternary operators.

@ StopBeforeMatch

Stop skipping at specified token, but don't skip the token itself.

bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind, SemaOpenMP::OpenMPVarListDataTy &Data, const LangOptions &LangOpts)

Parses a reserved locator like 'omp_all_memory'.

const Token & NextToken()

NextToken - This peeks ahead one token and returns it without consuming it.

A class for parsing a DeclSpec.

Activates OpenMP parsing mode to preseve OpenMP specific annotation tokens.

void enterVariableInit(SourceLocation Tok, Decl *D)

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

void EnterToken(const Token &Tok, bool IsReinject)

Enters a token in the token stream to be lexed next.

const Token & LookAhead(unsigned N)

Peeks ahead N tokens and returns that token without consuming any tokens.

bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)

Parses a simple integer literal to get its numeric value.

StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const

Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...

bool isCodeCompletionReached() const

Returns true if code-completion is enabled and we have hit the code-completion point.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

The collection of all-type qualifiers we support.

Represents a struct/union/class.

Scope - A scope is a transient data structure that is used while parsing the program.

@ OpenMPDirectiveScope

This is the scope of OpenMP executable directive.

@ CompoundStmtScope

This is a compound statement scope.

@ OpenMPSimdDirectiveScope

This is the scope of some OpenMP simd directive.

@ FnScope

This indicates that the scope corresponds to a function, which means that labels are set here.

@ OpenMPLoopDirectiveScope

This is the scope of some OpenMP loop directive.

@ DeclScope

This is a scope that can contain a declaration.

Smart pointer class that efficiently represents Objective-C method names.

AMDGPUWavesPerEUAttr * CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)

Create an AMDGPUWavesPerEUAttr attribute.

AMDGPUFlatWorkGroupSizeAttr * CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, Expr *Max)

Create an AMDGPUWavesPerEUAttr attribute.

QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)

void CodeCompleteInitializer(Scope *S, Decl *D)

DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)

Called at the end of '#pragma omp declare reduction'.

void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)

Finish current declare reduction construct initializer.

OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)

Called on well-formed 'use' clause.

void ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)

Called once a target context is completed, that can be when a '#pragma omp end declare target' was en...

OMPClause * ActOnOpenMPDirectivePresenceClause(OpenMPClauseKind CK, llvm::ArrayRef< OpenMPDirectiveKind > DKVec, SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc)

Called on well-formed 'absent' or 'contains' clauses.

void StartOpenMPClause(OpenMPClauseKind K)

Start analysis of clauses.

ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)

Build the mapper variable of '#pragma omp declare mapper'.

StmtResult ActOnOpenMPErrorDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, bool InExContext=true)

Called on well-formed '#pragma omp error'.

DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)

Called on well-formed '#pragma omp requires'.

OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)

OMPClause * ActOnOpenMPPermutationClause(ArrayRef< Expr * > PermExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

Called on well-form 'permutation' clause after parsing its arguments.

OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)

Called on well-formed 'destroy' clause.

VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)

Initialize declare reduction construct initializer.

void ActOnOpenMPEndAssumesDirective()

Called on well-formed '#pragma omp end assumes'.

QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)

Check if the specified type is allowed to be used in 'omp declare reduction' construct.

DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)

Called on well-formed '#pragma omp allocate'.

OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

bool isInOpenMPDeclareVariantScope() const

Can we exit an OpenMP declare variant scope at the moment.

TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)

Check variable declaration in 'omp declare mapper' construct.

ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, ArrayRef< OMPIteratorData > Data)

OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)

Called on well-formed 'uses_allocators' clause.

StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)

End of OpenMP region.

DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation > > ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)

Called on start of '#pragma omp declare reduction'.

void ActOnOpenMPEndDeclareVariant()

Handle a omp end declare variant.

void EndOpenMPDSABlock(Stmt *CurDirective)

Called on end of data sharing attribute block.

OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

Called on well-form 'sizes' clause.

bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)

Called on the start of target region i.e. '#pragma omp declare target'.

StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)

void EndOpenMPClause()

End analysis of clauses.

bool isInOpenMPAssumeScope() const

Check if there is an active global omp begin assumes directive.

QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)

Check if the specified type is allowed to be used in 'omp declare mapper' construct.

std::optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, unsigned NumAppendArgs, SourceRange SR)

Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...

StmtResult ActOnOpenMPInformationalDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)

Process an OpenMP informational directive.

OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

OMPClause * ActOnOpenMPNullaryAssumptionClause(OpenMPClauseKind CK, SourceLocation Loc, SourceLocation RLoc)

OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)

Called on well-formed 'init' clause.

void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)

Initialize declare reduction construct initializer.

bool isInOpenMPDeclareTargetContext() const

Return true inside OpenMP declare target region.

OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)

void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)

Called on start of new data sharing attribute block.

void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, ArrayRef< Expr * > AdjustArgsNothing, ArrayRef< Expr * > AdjustArgsNeedDevicePtr, ArrayRef< OMPInteropInfo > AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR)

Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function.

void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)

Finish current declare reduction construct initializer.

DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)

Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.

OMPClause * ActOnOpenMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

Called on a well-formed 'ompx_attribute' clause.

DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)

Called on well-formed '#pragma omp threadprivate'.

void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)

Initialization of captured region for OpenMP region.

NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)

Searches for the provided declaration name for OpenMP declare target directive.

void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)

Called on well-formed '#pragma omp [begin] assume[s]'.

void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)

Handle a omp begin declare variant.

StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)

Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...

const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()

Called at the end of target region i.e. '#pragma omp end declare target'.

OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)

DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Expr *MapperVarRef, ArrayRef< OMPClause * > Clauses, Decl *PrevDeclInScope=nullptr)

Called on start of '#pragma omp declare mapper'.

RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...

A RAII object to enter scope of a compound statement.

Sema - This implements semantic analysis and AST building for C.

Scope * getCurScope() const

Retrieve the parser's current scope.

ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)

CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...

ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)

VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...

void ActOnReenterFunctionContext(Scope *S, Decl *D)

Push the parameters of D, which must be a function, into scope.

void FinalizeDeclaration(Decl *D)

FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...

DeclarationNameInfo GetNameForDeclarator(Declarator &D)

GetNameForDeclarator - Determine the full declaration name for the given Declarator.

ASTContext & getASTContext() const

ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)

SemaCodeCompletion & CodeCompletion()

DeclContext * getCurLexicalContext() const

DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)

BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...

DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)

Retrieves the declaration name from a parsed unqualified-id.

void ActOnInitializerError(Decl *Dcl)

ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...

@ Unevaluated

The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...

StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)

void ActOnUninitializedDecl(Decl *dcl)

void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)

AddInitializerToDecl - Adds the initializer Init to the declaration dcl.

CUDALaunchBoundsAttr * CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks)

Create an CUDALaunchBoundsAttr attribute.

StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)

ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})

Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...

ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

StringLiteral - This represents a string literal expression, e.g.

Token - This structure provides full information about a lexed token.

IdentifierInfo * getIdentifierInfo() const

bool isAnyIdentifier() const

Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...

SourceLocation getEndLoc() const

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

tok::TokenKind getKind() const

bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const

bool isNot(tok::TokenKind K) const

bool isAnnotation() const

Return true if this is any of tok::annot_* kind tokens.

Base wrapper for a particular "section" of type source info.

The base class of the type hierarchy.

QualType getCanonicalTypeInternal() const

Represents a C++ unqualified-id that has been parsed.

void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])

Specify that this unqualified-id was parsed as an operator-function-id.

Represents a variable declaration or definition.

Directive - Abstract class representing a parsed verify directive.

Defines the clang::TargetInfo interface.

bool Ret(InterpState &S, CodePtr &PC)

bool isStringLiteral(TokenKind K)

Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.

The JSON file list parser is used to communicate input to InstallAPI.

TypeSpecifierType

Specifies the kind of type.

OverloadedOperatorKind

Enumeration specifying the different kinds of C++ overloaded operators.

@ OO_None

Not an overloaded operator.

llvm::omp::Directive OpenMPDirectiveKind

OpenMP directives.

@ OMPC_DEFAULTMAP_MODIFIER_unknown

@ OMPC_ORDER_MODIFIER_unknown

@ OMPC_ADJUST_ARGS_unknown

bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a distribute directive.

bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)

OpenMPDeviceType

OpenMP device type for 'device_type' clause.

@ OMPC_DEVICE_TYPE_unknown

@ OMPC_SCHEDULE_MODIFIER_unknown

llvm::omp::Clause OpenMPClauseKind

OpenMP clauses.

const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)

bool operator<(DeclarationName LHS, DeclarationName RHS)

Ordering on two declaration names.

bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a target code offload directive.

@ Property

The type of a property.

@ Result

The result type of a method or function.

@ OMPC_LASTPRIVATE_unknown

OpenMPGrainsizeClauseModifier

unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str, const LangOptions &LangOpts)

OpenMPNumTasksClauseModifier

ActionResult< Expr * > ExprResult

bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a directive with an associated loop construct.

OpenMPMotionModifierKind

OpenMP modifier kind for 'to' or 'from' clause.

@ OMPC_MOTION_MODIFIER_unknown

bool operator!=(CanQual< T > x, CanQual< U > y)

@ OMPC_DEFAULTMAP_unknown

OpenMPAllocateClauseModifier

OpenMP modifiers for 'allocate' clause.

OpenMPLinearClauseKind

OpenMP attributes for 'linear' clause.

bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is considered as "executable".

bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is considered as "informational".

bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a simd directive.

const FunctionProtoType * T

OpenMPMapModifierKind

OpenMP modifier kind for 'map' clause.

@ OMPC_MAP_MODIFIER_unknown

AccessSpecifier

A C++ access specifier (public, private, protected), plus the special value "none" which means differ...

bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a taskloop directive.

OpenMPMapClauseKind

OpenMP mapping kind for 'map' clause.

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

SourceLocation getLoc() const

getLoc - Returns the main location of the declaration name.

DeclarationName getName() const

getName - Returns the embedded declaration name.

llvm::SmallVector< Expr *, 4 > PreferTypes

llvm::omp::TraitProperty Kind

StringRef RawString

The raw string as we parsed it.

llvm::omp::TraitSelector Kind

llvm::SmallVector< OMPTraitProperty, 1 > Properties

llvm::SmallVector< OMPTraitSelector, 2 > Selectors

This structure contains most locations needed for by an OMPVarListClause.

std::optional< Expr * > Indirect

The directive with indirect clause.

OpenMPDirectiveKind Kind

The directive kind, begin declare target or declare target.

OMPDeclareTargetDeclAttr::DevTypeTy DT

The 'device_type' as parsed from the clause.

SourceLocation Loc

The directive location.

llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped

Explicitly listed variables and functions in a 'to' or 'link' clause.

Data structure for iterator expression.

Data used for processing a list of variables in OpenMP clauses.

Data for list of allocators.

Clang specific specialization of the OMPContext to lookup target features.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4