Commit 56252580 authored by Joel E. Denny's avatar Joel E. Denny
Browse files

WIP: [Clacc][OpenACC] Prototype `acc routine seq`

parent a59e21d4
...@@ -240,7 +240,7 @@ Run-Time Environment Variables ...@@ -240,7 +240,7 @@ Run-Time Environment Variables
* Appearing within a `parallel` construct and any number of levels * Appearing within a `parallel` construct and any number of levels
of nesting within other `loop` directives are supported. of nesting within other `loop` directives are supported.
* Appearing outside a `parallel` construct (that is, an orphaned * Appearing outside a `parallel` construct (that is, an orphaned
loop) is not yet supported. `loop` construct) is not yet supported.
* Use without clauses is supported. * Use without clauses is supported.
* Supported partitionability clauses * Supported partitionability clauses
* Implicit `independent` * Implicit `independent`
...@@ -303,6 +303,25 @@ Run-Time Environment Variables ...@@ -303,6 +303,25 @@ Run-Time Environment Variables
* A `reduction` clause implies a `copy` clause (overriding the * A `reduction` clause implies a `copy` clause (overriding the
implicit `firstprivate` clause). implicit `firstprivate` clause).
`routine` Directive
-------------------
* Lexical context
* Appearing at file scope is supported.
* Appearing within a function definition is not supported.
* Supported clauses
* `seq` (required)
* Associated declaration
* A lone function definition or prototype is supported.
* A declaration containing multiple declarators is not supported.
For example, `void foo(), bar();`.
* Function definition body
* Appearance of any OpenACC directive produces a compile-time
error diagnostic. Thus, orphaned `loop` constructs are not yet
supported.
* Declaration of a static local variable produces a compile-time
error diagnostic.
Subarrays Subarrays
--------- ---------
...@@ -317,10 +336,11 @@ Subarrays ...@@ -317,10 +336,11 @@ Subarrays
Device-Side Directives Device-Side Directives
---------------------- ----------------------
Nesting of an `update`, `data`, `parallel`, or `parallel loop` Nesting of an `update`, `enter data`, `exit data`, `data`, `parallel`,
directive inside a `parallel`, `loop`, or `parallel loop` construct is or `parallel loop` directive inside a `parallel`, `loop`, or `parallel
not yet supported. We're not aware of any OpenACC implementation that loop` construct or inside a function attributed with a `routine`
supports this yet. directive is not yet supported. We're not aware of any OpenACC
implementation that supports such cases yet.
OpenACC Runtime Library API and Preprocessor OpenACC Runtime Library API and Preprocessor
-------------------------------------------- --------------------------------------------
......
...@@ -91,7 +91,7 @@ struct PrintingPolicy { ...@@ -91,7 +91,7 @@ struct PrintingPolicy {
MSVCFormatting(false), ConstantsAsWritten(false), MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false), SuppressImplicitBase(false), FullyQualifiedName(false),
PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true), PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true),
OpenACCPrint(OpenACCPrint_ACC) {} OpenACCPrint(OpenACCPrint_ACC) {}
/// Adjust this printing policy for cases where it's known that we're /// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only /// printing C++ code (for instance, if AST dumping reaches a C++-only
......
...@@ -28,9 +28,18 @@ namespace clang { ...@@ -28,9 +28,18 @@ namespace clang {
// AST classes for directives. // AST classes for directives.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// This is a basic class for representing single OpenACC executable /// This is a basic class for representing OpenACC executable directives and
/// directive. /// constructs.
/// ///
/// FIXME: The name should be changed to reflect that it's not just OpenACC
/// executable directives (like acc update). The base class ExecutableDirective
/// should become something more generic too then, but it has to also make sense
/// for OMPExecutableDirective. ActOnOpenACCExecutableDirective should be
/// renamed in Sema accordingly. Perhaps ACCExecutableDirectiveOrConstruct is
/// the right name to distinguish it from declarative directives. Perhaps the
/// base class should be ExecutableDirectiveOrConstruct. Or maybe
/// ACCDirectiveStmt and base class DirectiveStmt is a nice summary of a
/// directive that is more than declarative.
class ACCExecutableDirective : public ExecutableDirective { class ACCExecutableDirective : public ExecutableDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// Kind of the directive. /// Kind of the directive.
......
...@@ -534,6 +534,9 @@ class Attr { ...@@ -534,6 +534,9 @@ class Attr {
// Set to true if this attribute meaningful when applied to or inherited // Set to true if this attribute meaningful when applied to or inherited
// in a class template definition. // in a class template definition.
bit MeaningfulToClassTemplateDefinition = 0; bit MeaningfulToClassTemplateDefinition = 0;
// Set to true if provides a custom implementation of the printPretty
// function.
bit HasCustomPrintPretty = 0;
// Set to true if this attribute can be used with '#pragma clang attribute'. // Set to true if this attribute can be used with '#pragma clang attribute'.
// By default, an attribute is supported by the '#pragma clang attribute' // By default, an attribute is supported by the '#pragma clang attribute'
// only when: // only when:
...@@ -3604,7 +3607,8 @@ def OMPDeclareTargetDecl : InheritableAttr { ...@@ -3604,7 +3607,8 @@ def OMPDeclareTargetDecl : InheritableAttr {
EnumArgument<"DevType", "DevTypeTy", EnumArgument<"DevType", "DevTypeTy",
[ "host", "nohost", "any" ], [ "host", "nohost", "any" ],
[ "DT_Host", "DT_NoHost", "DT_Any" ]>, [ "DT_Host", "DT_NoHost", "DT_Any" ]>,
UnsignedArgument<"Level"> UnsignedArgument<"Level">,
BoolArgument<"IsOpenACCTranslation">
]; ];
let AdditionalMembers = [{ let AdditionalMembers = [{
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const; void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const;
...@@ -3614,6 +3618,7 @@ def OMPDeclareTargetDecl : InheritableAttr { ...@@ -3614,6 +3618,7 @@ def OMPDeclareTargetDecl : InheritableAttr {
static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD); static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD);
static llvm::Optional<SourceLocation> getLocation(const ValueDecl *VD); static llvm::Optional<SourceLocation> getLocation(const ValueDecl *VD);
}]; }];
let HasCustomPrintPretty = 1;
} }
def OMPAllocateDecl : InheritableAttr { def OMPAllocateDecl : InheritableAttr {
...@@ -3659,6 +3664,19 @@ def OMPDeclareVariant : InheritableAttr { ...@@ -3659,6 +3664,19 @@ def OMPDeclareVariant : InheritableAttr {
}]; }];
} }
def ACCRoutineDecl : InheritableAttr {
let Spellings = [Pragma<"acc", "routine">];
let SemaHandler = 0;
let Subjects = SubjectList<[Function]>;
let Args = [
EnumArgument<"Partitioning", "PartitioningTy",
[ "seq" ],
[ "Seq" ]>
];
let Documentation = [Undocumented];
let HasCustomPrintPretty = 1;
}
def Assumption : InheritableAttr { def Assumption : InheritableAttr {
let Spellings = [Clang<"assume">]; let Spellings = [Clang<"assume">];
let Subjects = SubjectList<[Function, ObjCMethod]>; let Subjects = SubjectList<[Function, ObjCMethod]>;
......
...@@ -319,6 +319,15 @@ def err_rewrite_acc_end_in_macro : Error< ...@@ -319,6 +319,15 @@ def err_rewrite_acc_end_in_macro : Error<
def err_rewrite_acc_end_in_pragma_op : Error< def err_rewrite_acc_end_in_pragma_op : Error<
"cannot rewrite OpenACC directive that has no associated statement and that " "cannot rewrite OpenACC directive that has no associated statement and that "
"appears within a _Pragma operator">; "appears within a _Pragma operator">;
def err_rewrite_acc_routine_in_pragma_op : Error<
"cannot rewrite OpenACC routine directive that appears within a _Pragma "
"operator">;
def err_rewrite_acc_routine_function_start_in_macro : Error<
"cannot rewrite OpenACC routine directive whose associated function "
"declaration starts within a macro expansion">;
def err_rewrite_acc_routine_function_end_in_macro : Error<
"cannot rewrite OpenACC routine directive whose associated function "
"declaration ends within a macro expansion">;
} // end of RewriteOpenACC category } // end of RewriteOpenACC category
} }
...@@ -10842,6 +10842,22 @@ def note_acc_disable_diag : Note< ...@@ -10842,6 +10842,22 @@ def note_acc_disable_diag : Note<
def err_acc_no_self_host_device_clause : Error< def err_acc_no_self_host_device_clause : Error<
"expected at least one 'self', 'host', or 'device' clause for '#pragma acc " "expected at least one 'self', 'host', or 'device' clause for '#pragma acc "
"update'">; "update'">;
// TODO: Once the other clauses are supported, this should say:
// "expected at least one 'gang', 'worker', 'vector', or 'seq' clause for "
// "'#pragma acc routine'"
def err_acc_no_gang_worker_vector_seq_clause : Error<
"expected 'seq' clause for '#pragma acc routine'">;
def err_acc_expected_function_after_directive : Error<
"'#pragma acc %0' must be followed by a lone function prototype or "
"definition">;
def err_acc_routine_unexpected_directive : Error<
"'#pragma acc %0' is not permitted within function '%1' because the latter "
"is attributed with '#pragma acc routine'">;
def err_acc_routine_static_local : Error<
"static local variable '%0' is not permitted within function '%1' because "
"the latter is attributed with '#pragma acc routine'">;
def note_acc_routine : Note<
"function '%0' attributed with '#pragma acc routine' here">;
} // end of OpenACC category } // end of OpenACC category
   
let CategoryName = "Related Result Type Issue" in { let CategoryName = "Related Result Type Issue" in {
......
...@@ -112,6 +112,9 @@ ...@@ -112,6 +112,9 @@
#ifndef OPENACC_PARALLEL_LOOP_CLAUSE #ifndef OPENACC_PARALLEL_LOOP_CLAUSE
# define OPENACC_PARALLEL_LOOP_CLAUSE(Name) # define OPENACC_PARALLEL_LOOP_CLAUSE(Name)
#endif #endif
#ifndef OPENACC_ROUTINE_CLAUSE
# define OPENACC_ROUTINE_CLAUSE(Name)
#endif
#ifndef OPENACC_UPDATE_PARENT #ifndef OPENACC_UPDATE_PARENT
# define OPENACC_UPDATE_PARENT(Name) # define OPENACC_UPDATE_PARENT(Name)
#endif #endif
...@@ -133,6 +136,9 @@ ...@@ -133,6 +136,9 @@
#ifndef OPENACC_PARALLEL_LOOP_PARENT #ifndef OPENACC_PARALLEL_LOOP_PARENT
# define OPENACC_PARALLEL_LOOP_PARENT(Name) # define OPENACC_PARALLEL_LOOP_PARENT(Name)
#endif #endif
#ifndef OPENACC_ROUTINE_PARENT
# define OPENACC_ROUTINE_PARENT(Name)
#endif
#define OPENACC_ALIASED_CLAUSE(Def, Name, Class) \ #define OPENACC_ALIASED_CLAUSE(Def, Name, Class) \
Def(Name, Class) \ Def(Name, Class) \
...@@ -173,6 +179,7 @@ OPENACC_DIRECTIVE(data) ...@@ -173,6 +179,7 @@ OPENACC_DIRECTIVE(data)
OPENACC_DIRECTIVE(parallel) OPENACC_DIRECTIVE(parallel)
OPENACC_DIRECTIVE(loop) OPENACC_DIRECTIVE(loop)
OPENACC_DIRECTIVE_EXT(parallel_loop, "parallel loop") OPENACC_DIRECTIVE_EXT(parallel_loop, "parallel loop")
OPENACC_DIRECTIVE(routine)
// Specifying and iterating OpenACC clauses, data attributes (DAs), data // Specifying and iterating OpenACC clauses, data attributes (DAs), data
// mapping attributes (DMAs), data sharing attributes (DSAs), and clause // mapping attributes (DMAs), data sharing attributes (DSAs), and clause
...@@ -407,6 +414,9 @@ OPENACC_PARALLEL_LOOP_CLAUSE(worker) ...@@ -407,6 +414,9 @@ OPENACC_PARALLEL_LOOP_CLAUSE(worker)
OPENACC_PARALLEL_LOOP_CLAUSE(vector) OPENACC_PARALLEL_LOOP_CLAUSE(vector)
OPENACC_PARALLEL_LOOP_CLAUSE(collapse) OPENACC_PARALLEL_LOOP_CLAUSE(collapse)
// Explicit clauses allowed for OpenACC directive 'routine'.
OPENACC_ROUTINE_CLAUSE(seq)
// Parent directives allowed for 'update'. // Parent directives allowed for 'update'.
OPENACC_UPDATE_PARENT(unknown) OPENACC_UPDATE_PARENT(unknown)
OPENACC_UPDATE_PARENT(data) OPENACC_UPDATE_PARENT(data)
...@@ -440,6 +450,9 @@ OPENACC_LOOP_PARENT(parallel_loop) ...@@ -440,6 +450,9 @@ OPENACC_LOOP_PARENT(parallel_loop)
OPENACC_PARALLEL_LOOP_PARENT(unknown) OPENACC_PARALLEL_LOOP_PARENT(unknown)
OPENACC_PARALLEL_LOOP_PARENT(data) OPENACC_PARALLEL_LOOP_PARENT(data)
// Parent directives allowed for 'routine'.
OPENACC_ROUTINE_PARENT(unknown)
#undef OPENACC_DIRECTIVE #undef OPENACC_DIRECTIVE
#undef OPENACC_DIRECTIVE_EXT #undef OPENACC_DIRECTIVE_EXT
#undef OPENACC_DMA #undef OPENACC_DMA
...@@ -473,6 +486,7 @@ OPENACC_PARALLEL_LOOP_PARENT(data) ...@@ -473,6 +486,7 @@ OPENACC_PARALLEL_LOOP_PARENT(data)
#undef OPENACC_PARALLEL_CLAUSE #undef OPENACC_PARALLEL_CLAUSE
#undef OPENACC_LOOP_CLAUSE #undef OPENACC_LOOP_CLAUSE
#undef OPENACC_PARALLEL_LOOP_CLAUSE #undef OPENACC_PARALLEL_LOOP_CLAUSE
#undef OPENACC_ROUTINE_CLAUSE
#undef OPENACC_UPDATE_PARENT #undef OPENACC_UPDATE_PARENT
#undef OPENACC_ENTER_DATA_PARENT #undef OPENACC_ENTER_DATA_PARENT
#undef OPENACC_EXIT_DATA_PARENT #undef OPENACC_EXIT_DATA_PARENT
...@@ -480,6 +494,7 @@ OPENACC_PARALLEL_LOOP_PARENT(data) ...@@ -480,6 +494,7 @@ OPENACC_PARALLEL_LOOP_PARENT(data)
#undef OPENACC_PARALLEL_PARENT #undef OPENACC_PARALLEL_PARENT
#undef OPENACC_LOOP_PARENT #undef OPENACC_LOOP_PARENT
#undef OPENACC_PARALLEL_LOOP_PARENT #undef OPENACC_PARALLEL_LOOP_PARENT
#undef OPENACC_ROUTINE_PARENT
#undef OPENACC_ALIASED_CLAUSE #undef OPENACC_ALIASED_CLAUSE
#undef OPENACC_CLAUSE_AND_DMA #undef OPENACC_CLAUSE_AND_DMA
#undef OPENACC_CLAUSE_AND_DSA_MAPPABLE #undef OPENACC_CLAUSE_AND_DSA_MAPPABLE
......
...@@ -3373,12 +3373,16 @@ public: ...@@ -3373,12 +3373,16 @@ public:
/// Parses declarative OpenACC directives. /// Parses declarative OpenACC directives.
DeclGroupPtrTy ParseOpenACCDeclarativeDirective(); DeclGroupPtrTy ParseOpenACCDeclarativeDirective();
/// Parses declarative or executable OpenACC directive. /// Parses OpenACC executable directives or constructs.
/// ///
/// \param StmtCtx The context in which we're parsing the directive. /// \param StmtCtx The context in which we're parsing the directive.
StmtResult StmtResult ParseOpenACCExecutableDirective(ParsedStmtContext StmtCtx);
ParseOpenACCDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx); /// Parses clauses for directive of kind \a Kind.
/// Parses clause of kind \a CKind for directive of a kind \a Kind. ///
/// \param DKind Kind of current directive.
void ParseOpenACCClauses(OpenACCDirectiveKind DKind,
SmallVectorImpl<ACCClause *> &Clauses);
/// Parses clause of kind \a CKind for directive of kind \a Kind.
/// ///
/// \param DKind Kind of current directive. /// \param DKind Kind of current directive.
/// \param CKind Kind of current clause. /// \param CKind Kind of current clause.
......
...@@ -11254,14 +11254,25 @@ private: ...@@ -11254,14 +11254,25 @@ private:
void DestroyOpenACCDirectiveStack(); void DestroyOpenACCDirectiveStack();
   
public: public:
/// Called on start of new data attribute block. /// Called at start of an OpenACC directive before its clauses. Returns true
void StartOpenACCDABlock(OpenACCDirectiveKind RealDKind, SourceLocation Loc); /// in the case of an error.
/// Start analysis of clauses. bool StartOpenACCDirectiveAndAssociate(OpenACCDirectiveKind RealDKind,
SourceLocation Loc);
/// Called at start of a clause.
void StartOpenACCClause(OpenACCClauseKind K); void StartOpenACCClause(OpenACCClauseKind K);
/// End analysis of clauses. /// Called at end of a clause.
void EndOpenACCClause(); void EndOpenACCClause();
/// Called on end of data attribute block. /// Called at start of an OpenACC directive's associated statement. Returns
void EndOpenACCDABlock(); /// true in the case of an error.
bool StartOpenACCAssociatedStatement(OpenACCDirectiveKind DKind,
ArrayRef<ACCClause *> Clauses,
SourceLocation StartLoc);
/// Called at end of an OpenACC directive's associated statement and before
/// the \c ActOn function for the directive. Returns true in the case of an
/// error.
bool EndOpenACCAssociatedStatement();
/// Called after the \c ActOn function for the directive.
void EndOpenACCDirectiveAndAssociate();
   
/// If the current region is an OpenACC loop region, record any loop control /// If the current region is an OpenACC loop region, record any loop control
/// variables assigned but not declared in \p Init, the init of the attached /// variables assigned but not declared in \p Init, the init of the attached
...@@ -11271,13 +11282,10 @@ public: ...@@ -11271,13 +11282,10 @@ public:
/// directive. /// directive.
void ActOnOpenACCLoopBreakStatement(SourceLocation BreakLoc, void ActOnOpenACCLoopBreakStatement(SourceLocation BreakLoc,
Scope *CurScope); Scope *CurScope);
/// Check a function definition against any OpenACC restrictions (such as any
/// OpenACC routine directive).
void ActOnFunctionDefinitionForOpenACC(FunctionDecl *FD);
   
/// Start of OpenACC region.
bool ActOnOpenACCRegionStart(OpenACCDirectiveKind DKind,
ArrayRef<ACCClause *> Clauses,
SourceLocation StartLoc);
/// End of OpenACC region.
bool ActOnOpenACCRegionEnd();
StmtResult ActOnOpenACCExecutableDirective( StmtResult ActOnOpenACCExecutableDirective(
OpenACCDirectiveKind Kind, ArrayRef<ACCClause *> Clauses, Stmt *AStmt, OpenACCDirectiveKind Kind, ArrayRef<ACCClause *> Clauses, Stmt *AStmt,
SourceLocation StartLoc, SourceLocation EndLoc); SourceLocation StartLoc, SourceLocation EndLoc);
...@@ -11314,6 +11322,10 @@ public: ...@@ -11314,6 +11322,10 @@ public:
StmtResult ActOnOpenACCParallelLoopDirective( StmtResult ActOnOpenACCParallelLoopDirective(
ArrayRef<ACCClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, ArrayRef<ACCClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc); SourceLocation EndLoc);
/// Called on well-formed '\#pragma acc routine'.
void ActOnOpenACCRoutineDirective(ArrayRef<ACCClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc, DeclGroupRef Decl);
   
ACCClause *ActOnOpenACCSingleExprClause(OpenACCClauseKind Kind, ACCClause *ActOnOpenACCSingleExprClause(OpenACCClauseKind Kind,
Expr *Expr, Expr *Expr,
......
...@@ -132,6 +132,32 @@ void OMPDeclareSimdDeclAttr::printPrettyPragma( ...@@ -132,6 +132,32 @@ void OMPDeclareSimdDeclAttr::printPrettyPragma(
} }
} }
void OMPDeclareTargetDeclAttr::printPretty(raw_ostream &OS,
const PrintingPolicy &Policy) const {
// TODO: If this isn't an OpenACC translation, print exactly the way upstream
// prints it to avoid merge conflicts in tests. However, we need to come to
// terms with why inherited attributes should be printed as that seems to
// indicate they weren't specified in the original source. See related todo
// in DeclPrinter::VisitDeclContext.
OpenACCPrintKind PrintMode = OpenACCPrint_OMP;
if (getIsOpenACCTranslation())
PrintMode = isInherited() ? OpenACCPrint_ACC : Policy.OpenACCPrint;
switch (PrintMode) {
case OpenACCPrint_ACC_OMP:
OS << "// ";
LLVM_FALLTHROUGH;
case OpenACCPrint_OMP:
case OpenACCPrint_OMP_ACC:
case OpenACCPrint_OMP_HEAD:
OS << "#pragma omp declare target";
printPrettyPragma(OS, Policy);
OS << '\n';
break;
case OpenACCPrint_ACC:
break;
}
}
void OMPDeclareTargetDeclAttr::printPrettyPragma( void OMPDeclareTargetDeclAttr::printPrettyPragma(
raw_ostream &OS, const PrintingPolicy &Policy) const { raw_ostream &OS, const PrintingPolicy &Policy) const {
// Use fake syntax because it is for testing and debugging purpose only. // Use fake syntax because it is for testing and debugging purpose only.
...@@ -197,4 +223,23 @@ void OMPDeclareVariantAttr::printPrettyPragma( ...@@ -197,4 +223,23 @@ void OMPDeclareVariantAttr::printPrettyPragma(
OS << " match(" << traitInfos << ")"; OS << " match(" << traitInfos << ")";
} }
void ACCRoutineDeclAttr::printPretty(raw_ostream &OS,
const PrintingPolicy &Policy) const {
if (isInherited() || isImplicit())
return;
switch (Policy.OpenACCPrint) {
case OpenACCPrint_OMP_ACC:
OS << "// ";
LLVM_FALLTHROUGH;
case OpenACCPrint_ACC:
case OpenACCPrint_ACC_OMP:
OS << "#pragma acc routine "
<< ConvertPartitioningTyToStr(getPartitioning()) << "\n";
break;
case OpenACCPrint_OMP:
case OpenACCPrint_OMP_HEAD:
break;
}
}
#include "clang/AST/AttrImpl.inc" #include "clang/AST/AttrImpl.inc"
...@@ -488,8 +488,30 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { ...@@ -488,8 +488,30 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
// Declare target attribute is special one, natural spelling for the pragma // Declare target attribute is special one, natural spelling for the pragma
// assumes "ending" construct so print it here. // assumes "ending" construct so print it here.
if (D->hasAttr<OMPDeclareTargetDeclAttr>()) if (OMPDeclareTargetDeclAttr *Attr =
Out << "#pragma omp end declare target\n"; D->getAttr<OMPDeclareTargetDeclAttr>()) {
// TODO: If this isn't an OpenACC translation, print exactly the way
// upstream prints it to avoid merge conflicts in tests. However, we need
// to come to terms with why inherited attributes should be printed as
// that seems to indicate they weren't specified in the original source.
// See related todo in OMPDeclareTargetDeclAttr::printPretty.
OpenACCPrintKind PrintMode = OpenACCPrint_OMP;
if (Attr->getIsOpenACCTranslation())
PrintMode = Attr->isInherited() ? OpenACCPrint_ACC
: Policy.OpenACCPrint;
switch (PrintMode) {
case OpenACCPrint_ACC_OMP:
Out << "// ";
LLVM_FALLTHROUGH;
case OpenACCPrint_OMP:
case OpenACCPrint_OMP_ACC:
case OpenACCPrint_OMP_HEAD:
Out << "#pragma omp end declare target\n";
break;
case OpenACCPrint_ACC:
break;
}
}
} }
if (!Decls.empty()) if (!Decls.empty())
......
...@@ -198,6 +198,8 @@ bool clang::isAllowedDAForDirective(OpenACCDirectiveKind DKind, ...@@ -198,6 +198,8 @@ bool clang::isAllowedDAForDirective(OpenACCDirectiveKind DKind,
break; break;
} }
break; break;
case ACCD_routine:
break;
case ACCD_unknown: case ACCD_unknown:
llvm_unreachable("unexpected unknown directive"); llvm_unreachable("unexpected unknown directive");
} }
...@@ -278,6 +280,8 @@ bool clang::isAllowedDAForDirective(OpenACCDirectiveKind DKind, ...@@ -278,6 +280,8 @@ bool clang::isAllowedDAForDirective(OpenACCDirectiveKind DKind,
break; break;
} }
break; break;
case ACCD_routine:
break;
case ACCD_unknown: case ACCD_unknown:
llvm_unreachable("unexpected unknown directive"); llvm_unreachable("unexpected unknown directive");
} }
...@@ -290,8 +294,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind, ...@@ -290,8 +294,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
switch (DKind) { switch (DKind) {
case ACCD_update: case ACCD_update:
switch (CKind) { switch (CKind) {
#define OPENACC_UPDATE_CLAUSE(Name) \ #define OPENACC_UPDATE_CLAUSE(Name) \
case ACCC_##Name: \ case ACCC_##Name: \
return true; return true;
#include "clang/Basic/OpenACCKinds.def" #include "clang/Basic/OpenACCKinds.def"
default: default:
...@@ -300,8 +304,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind, ...@@ -300,8 +304,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break; break;
case ACCD_enter_data: case ACCD_enter_data:
switch (CKind) { switch (CKind) {
#define OPENACC_ENTER_DATA_CLAUSE(Name) \ #define OPENACC_ENTER_DATA_CLAUSE(Name) \
case ACCC_##Name: \ case ACCC_##Name: \
return true; return true;
#include "clang/Basic/OpenACCKinds.def" #include "clang/Basic/OpenACCKinds.def"
default: default:
...@@ -310,8 +314,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind, ...@@ -310,8 +314,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break; break;
case ACCD_exit_data: case ACCD_exit_data:
switch (CKind) { switch (CKind) {
#define OPENACC_EXIT_DATA_CLAUSE(Name) \ #define OPENACC_EXIT_DATA_CLAUSE(Name) \
case ACCC_##Name: \ case ACCC_##Name: \
return true; return true;
#include "clang/Basic/OpenACCKinds.def" #include "clang/Basic/OpenACCKinds.def"
default: default:
...@@ -320,8 +324,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind, ...@@ -320,8 +324,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break; break;
case ACCD_data: case ACCD_data:
switch (CKind) { switch (CKind) {
#define OPENACC_DATA_CLAUSE(Name) \ #define OPENACC_DATA_CLAUSE(Name) \
case ACCC_##Name: \ case ACCC_##Name: \
return true; return true;
#include "clang/Basic/OpenACCKinds.def" #include "clang/Basic/OpenACCKinds.def"
default: default:
...@@ -330,8 +334,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind, ...@@ -330,8 +334,8 @@ bool clang::isAllowedClauseForDirective(OpenACCDirectiveKind DKind,
break; break;
case ACCD_parallel: case ACCD_parallel:
switch (CKind) { switch (CKind) {
#define OPENACC_PARALLEL_CLAUSE(Name) \ #define OPENACC_PARALLEL_CLAUSE(Name) \
case ACCC_##Name: \ case ACCC_##Name: \
return true; return true;
#include "clang/Basic/OpenACCKinds.def" #include "clang/Basic/OpenACCKinds.def"
default: