//===--- ParseOpenACC.cpp - OpenACC-specific parsing support --------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the parsing logic for OpenACC language features. // //===----------------------------------------------------------------------===// #include "clang/AST/OpenACCClause.h" #include "clang/Basic/OpenACCKinds.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/SemaOpenACC.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" usingnamespaceclang; usingnamespacellvm; namespace { // An enum that contains the extended 'partial' parsed variants. This type // should never escape the initial parse functionality, but is useful for // simplifying the implementation. enum class OpenACCDirectiveKindEx { … }; // Translate single-token string representations to the OpenACC Directive Kind. // This doesn't completely comprehend 'Compound Constructs' (as it just // identifies the first token), and doesn't fully handle 'enter data', 'exit // data', nor any of the 'atomic' variants, just the first token of each. So // this should only be used by `ParseOpenACCDirectiveKind`. OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) { … } // Translate single-token string representations to the OpenCC Clause Kind. OpenACCClauseKind getOpenACCClauseKind(Token Tok) { … } // Since 'atomic' is effectively a compound directive, this will decode the // second part of the directive. OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) { … } OpenACCDefaultClauseKind getOpenACCDefaultClauseKind(Token Tok) { … } enum class OpenACCSpecialTokenKind { … }; bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) { … } /// Used for cases where we have a token we want to check against an /// 'identifier-like' token, but don't want to give awkward error messages in /// cases where it is accidentially a keyword. bool isTokenIdentifierOrKeyword(Parser &P, Token Tok) { … } /// Parses and consumes an identifer followed immediately by a single colon, and /// diagnoses if it is not the 'special token' kind that we require. Used when /// the tag is the only valid value. /// Return 'true' if the special token was matched, false if no special token, /// or an invalid special token was found. template <typename DirOrClauseTy> bool tryParseAndConsumeSpecialTokenKind(Parser &P, OpenACCSpecialTokenKind Kind, DirOrClauseTy DirOrClause) { … } bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) { … } OpenACCReductionOperator ParseReductionOperator(Parser &P) { … } /// Used for cases where we expect an identifier-like token, but don't want to /// give awkward error messages in cases where it is accidentially a keyword. bool expectIdentifierOrKeyword(Parser &P) { … } OpenACCDirectiveKind ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok, OpenACCDirectiveKindEx ExtDirKind) { … } OpenACCAtomicKind ParseOpenACCAtomicKind(Parser &P) { … } // Parse and consume the tokens for OpenACC Directive/Construct kinds. OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) { … } enum ClauseParensKind { … }; ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind, OpenACCClauseKind Kind) { … } bool ClauseHasOptionalParens(OpenACCDirectiveKind DirKind, OpenACCClauseKind Kind) { … } bool ClauseHasRequiredParens(OpenACCDirectiveKind DirKind, OpenACCClauseKind Kind) { … } // Skip until we see the end of pragma token, but don't consume it. This is us // just giving up on the rest of the pragma so we can continue executing. We // have to do this because 'SkipUntil' considers paren balancing, which isn't // what we want. void SkipUntilEndOfDirective(Parser &P) { … } bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) { … } unsigned getOpenACCScopeFlags(OpenACCDirectiveKind DirKind) { … } } // namespace Parser::OpenACCClauseParseResult Parser::OpenACCCanContinue() { … } Parser::OpenACCClauseParseResult Parser::OpenACCCannotContinue() { … } Parser::OpenACCClauseParseResult Parser::OpenACCSuccess(OpenACCClause *Clause) { … } ExprResult Parser::ParseOpenACCConditionExpr() { … } // OpenACC 3.3, section 1.7: // To simplify the specification and convey appropriate constraint information, // a pqr-list is a comma-separated list of pdr items. The one exception is a // clause-list, which is a list of one or more clauses optionally separated by // commas. SmallVector<OpenACCClause *> Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) { … } Parser::OpenACCIntExprParseResult Parser::ParseOpenACCIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc) { … } bool Parser::ParseOpenACCIntExprList(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, llvm::SmallVectorImpl<Expr *> &IntExprs) { … } /// OpenACC 3.3 Section 2.4: /// The argument to the device_type clause is a comma-separated list of one or /// more device architecture name identifiers, or an asterisk. /// /// The syntax of the device_type clause is /// device_type( * ) /// device_type( device-type-list ) /// /// The device_type clause may be abbreviated to dtype. bool Parser::ParseOpenACCDeviceTypeList( llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>> &Archs) { … } /// OpenACC 3.3 Section 2.9: /// size-expr is one of: // * // int-expr // Note that this is specified under 'gang-arg-list', but also applies to 'tile' // via reference. ExprResult Parser::ParseOpenACCSizeExpr(OpenACCClauseKind CK) { … } bool Parser::ParseOpenACCSizeExprList( OpenACCClauseKind CK, llvm::SmallVectorImpl<Expr *> &SizeExprs) { … } /// OpenACC 3.3 Section 2.9: /// /// where gang-arg is one of: /// [num:]int-expr /// dim:int-expr /// static:size-expr Parser::OpenACCGangArgRes Parser::ParseOpenACCGangArg(SourceLocation GangLoc) { … } bool Parser::ParseOpenACCGangArgList( SourceLocation GangLoc, llvm::SmallVectorImpl<OpenACCGangKind> &GKs, llvm::SmallVectorImpl<Expr *> &IntExprs) { … } // The OpenACC Clause List is a comma or space-delimited list of clauses (see // the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't // really have its owner grammar and each individual one has its own definition. // However, they all are named with a single-identifier (or auto/default!) // token, followed in some cases by either braces or parens. Parser::OpenACCClauseParseResult Parser::ParseOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses, OpenACCDirectiveKind DirKind) { … } Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( ArrayRef<const OpenACCClause *> ExistingClauses, OpenACCDirectiveKind DirKind, OpenACCClauseKind ClauseKind, SourceLocation ClauseLoc) { … } /// OpenACC 3.3 section 2.16: /// In this section and throughout the specification, the term async-argument /// means a nonnegative scalar integer expression (int for C or C++, integer for /// Fortran), or one of the special values acc_async_noval or acc_async_sync, as /// defined in the C header file and the Fortran openacc module. The special /// values are negative values, so as not to conflict with a user-specified /// nonnegative async-argument. Parser::OpenACCIntExprParseResult Parser::ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc) { … } /// OpenACC 3.3, section 2.16: /// In this section and throughout the specification, the term wait-argument /// means: /// [ devnum : int-expr : ] [ queues : ] async-argument-list Parser::OpenACCWaitParseInfo Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) { … } ExprResult Parser::ParseOpenACCIDExpression() { … } ExprResult Parser::ParseOpenACCBindClauseArgument() { … } /// OpenACC 3.3, section 1.6: /// In this spec, a 'var' (in italics) is one of the following: /// - a variable name (a scalar, array, or composite variable name) /// - a subarray specification with subscript ranges /// - an array element /// - a member of a composite variable /// - a common block name between slashes (fortran only) Parser::OpenACCVarParseResult Parser::ParseOpenACCVar(OpenACCClauseKind CK) { … } llvm::SmallVector<Expr *> Parser::ParseOpenACCVarList(OpenACCClauseKind CK) { … } /// OpenACC 3.3, section 2.10: /// In C and C++, the syntax of the cache directive is: /// /// #pragma acc cache ([readonly:]var-list) new-line void Parser::ParseOpenACCCacheVarList() { … } Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() { … } // Parse OpenACC directive on a declaration. Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() { … } // Parse OpenACC Directive on a Statement. StmtResult Parser::ParseOpenACCDirectiveStmt() { … }