6 changes: 6 additions & 0 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5026,6 +5026,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
auto *A = D->getAttr<OMPAllocateDeclAttr>();
Record.push_back(A->getAllocatorType());
Record.AddStmt(A->getAllocator());
Record.AddStmt(A->getAlignment());
Record.AddSourceRange(A->getRange());
break;
}
Expand Down Expand Up @@ -6230,6 +6231,11 @@ void OMPClauseWriter::VisitOMPFilterClause(OMPFilterClause *C) {
Record.AddSourceLocation(C->getLParenLoc());
}

void OMPClauseWriter::VisitOMPAlignClause(OMPAlignClause *C) {
Record.AddStmt(C->getAlignment());
Record.AddSourceLocation(C->getLParenLoc());
}

void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
Record.push_back(C->varlist_size());
Record.AddSourceLocation(C->getLParenLoc());
Expand Down
134 changes: 134 additions & 0 deletions clang/test/OpenMP/align_clause_ast_print.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// expected-no-diagnostics

//RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
//RUN: -x c++ -std=c++14 -fexceptions -fcxx-exceptions \
//RUN: -Wno-source-uses-openmp -Wno-openmp-clauses \
//RUN: -ast-print %s | FileCheck %s --check-prefix=PRINT

//RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
//RUN: -x c++ -std=c++14 -fexceptions -fcxx-exceptions \
//RUN: -Wno-source-uses-openmp -Wno-openmp-clauses \
//RUN: -ast-dump %s | FileCheck %s --check-prefix=DUMP

//RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
//RUN: -x c++ -std=c++14 -fexceptions -fcxx-exceptions \
//RUN: -Wno-source-uses-openmp -Wno-openmp-clauses \
//RUN: -emit-pch -o %t %s

//RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
//RUN: -x c++ -std=c++14 -fexceptions -fcxx-exceptions \
//RUN: -Wno-source-uses-openmp -Wno-openmp-clauses \
//RUN: -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT

//RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
//RUN: -x c++ -std=c++14 -fexceptions -fcxx-exceptions \
//RUN: -Wno-source-uses-openmp -Wno-openmp-clauses \
//RUN: -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP

#ifndef HEADER
#define HEADER

typedef enum omp_allocator_handle_t {
omp_null_allocator = 0,
omp_default_mem_alloc = 1,
omp_large_cap_mem_alloc = 2,
omp_const_mem_alloc = 3,
omp_high_bw_mem_alloc = 4,
omp_low_lat_mem_alloc = 5,
omp_cgroup_mem_alloc = 6,
omp_pteam_mem_alloc = 7,
omp_thread_mem_alloc = 8,
KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
} omp_allocator_handle_t;

int foo1() {
char a;
#pragma omp allocate(a) align(4) allocator(omp_pteam_mem_alloc)
return a;
}
// DUMP: FunctionDecl {{.*}}
// DUMP: DeclStmt {{.*}}
// DUMP: VarDecl {{.*}}a 'char'
// DUMP: OMPAllocateDeclAttr {{.*}}OMPPTeamMemAlloc
// DUMP: DeclRefExpr {{.*}}'omp_allocator_handle_t' EnumConstant {{.*}} 'omp_pteam_mem_alloc' 'omp_allocator_handle_t'
// DUMP: ConstantExpr {{.*}}'int'
// DUMP: value: Int 4
// DUMP: IntegerLiteral {{.*}}'int' 4
// DUMP: DeclStmt {{.*}}
// DUMP: OMPAllocateDecl {{.*}}
// DUMP: DeclRefExpr {{.*}}'char' lvalue Var {{.*}} 'a' 'char'
// DUMP: OMPAlignClause {{.*}}
// DUMP: ConstantExpr {{.*}}'int'
// DUMP: value: Int 4
// DUMP: IntegerLiteral {{.*}}'int' 4
// DUMP: OMPAllocatorClause {{.*}}
// DUMP: DeclRefExpr {{.*}}'omp_allocator_handle_t' EnumConstant {{.*}}'omp_pteam_mem_alloc' 'omp_allocator_handle_t'
// PRINT: #pragma omp allocate(a) align(4) allocator(omp_pteam_mem_alloc)

int foo2() {
char b;
#pragma omp allocate(b) allocator(omp_low_lat_mem_alloc) align(2)
return b;
}
// DUMP: FunctionDecl {{.*}}
// DUMP: DeclStmt {{.*}}
// DUMP: VarDecl {{.*}}b 'char'
// DUMP: OMPAllocateDeclAttr {{.*}}Implicit OMPLowLatMemAlloc
// DUMP: DeclRefExpr {{.*}}'omp_allocator_handle_t' EnumConstant {{.*}} 'omp_low_lat_mem_alloc' 'omp_allocator_handle_t'
// DUMP: ConstantExpr {{.*}}'int'
// DUMP: value: Int 2
// DUMP: IntegerLiteral {{.*}}'int' 2
// DUMP: DeclStmt {{.*}}
// DUMP: OMPAllocateDecl {{.*}}
// DUMP: DeclRefExpr {{.*}}'char' lvalue Var {{.*}} 'b' 'char'
// DUMP: OMPAllocatorClause {{.*}}
// DUMP: DeclRefExpr {{.*}}'omp_allocator_handle_t' EnumConstant {{.*}} 'omp_low_lat_mem_alloc' 'omp_allocator_handle_t'
// DUMP: OMPAlignClause {{.*}}
// DUMP: ConstantExpr {{.*}}'int'
// DUMP: value: Int 2
// DUMP: IntegerLiteral {{.*}}'int' 2
// PRINT: #pragma omp allocate(b) allocator(omp_low_lat_mem_alloc) align(2)

template <typename T, unsigned size>
T run() {
T foo;
#pragma omp allocate(foo) align(size)
return size;
}

int template_test() {
double d;
d = run<double, 1>();
return 0;
}

// DUMP: FunctionTemplateDecl {{.*}}
// DUMP: TemplateTypeParmDecl {{.*}}
// DUMP: NonTypeTemplateParmDecl {{.*}}'unsigned int' depth 0 index 1 size
// DUMP: FunctionDecl {{.*}}'T ()'
// DUMP: DeclStmt {{.*}}
// DUMP: OMPAllocateDecl {{.*}}
// DUMP: DeclRefExpr {{.*}}'T' lvalue Var {{.*}} 'foo' 'T'
// DUMP: OMPAlignClause {{.*}}
// DUMP: DeclRefExpr {{.*}}'unsigned int' NonTypeTemplateParm {{.*}} 'size' 'unsigned int'
// DUMP: FunctionDecl {{.*}}run 'double ()'
// DUMP: TemplateArgument type 'double'
// DUMP: BuiltinType {{.*}}'double'
// DUMP: TemplateArgument integral 1
// DUMP: OMPAllocateDeclAttr {{.*}}Implicit OMPNullMemAlloc
// DUMP: ConstantExpr {{.*}}'unsigned int'
// DUMP: value: Int 1
// DUMP: SubstNonTypeTemplateParmExpr {{.*}}'unsigned int'
// DUMP: NonTypeTemplateParmDecl {{.*}}'unsigned int' depth 0 index 1 size
// DUMP: IntegerLiteral {{.*}}'unsigned int' 1
// DUMP: OMPAllocateDecl {{.*}}
// DUMP: DeclRefExpr {{.*}}'double':'double' lvalue Var {{.*}} 'foo' 'double':'double'
// DUMP: OMPAlignClause {{.*}}
// DUMP: ConstantExpr {{.*}}'unsigned int'
// DUMP: value: Int 1
// DUMP: SubstNonTypeTemplateParmExpr {{.*}}'unsigned int'
// DUMP: NonTypeTemplateParmDecl {{.*}}'unsigned int' depth 0 index 1 size
// DUMP: IntegerLiteral {{.*}}'unsigned int' 1
// PRINT: #pragma omp allocate(foo) align(size)
// PRINT: #pragma omp allocate(foo) align(1U)
#endif // HEADER
60 changes: 60 additions & 0 deletions clang/test/OpenMP/align_clause_messages.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 %s -verify

int foobar() {
return 1;
}

int main(int argc, char *argv[]) {
// expected-note@+1 {{declared here}}
int a;
// expected-note@+1 {{declared here}}
int b;
// expected-note@+1 {{declared here}}
int c;
double f;
int foo2[10];

// expected-error@+1 {{expected '(' after 'align'}}
#pragma omp allocate(a) align
// expected-error@+3 {{expected expression}}
// expected-error@+2 {{expected ')'}}
// expected-note@+1 {{to match this '('}}
#pragma omp allocate(a) align(
// expected-error@+1 {{expected expression}}
#pragma omp allocate(a) align()
// expected-error@+4 {{expected ')'}}
// expected-note@+3 {{to match this '('}}
// expected-error@+2 {{expression is not an integral constant expression}}
// expected-note@+1 {{read of non-const variable 'a' is not allowed in a constant expression}}
#pragma omp allocate(a) align(a
// expected-error@+2 {{expression is not an integral constant expression}}
// expected-note@+1 {{read of non-const variable 'b' is not allowed in a constant expression}}
#pragma omp allocate(a) align(b)
// expected-error@+2 {{expression is not an integral constant expression}}
// expected-note@+1 {{read of non-const variable 'c' is not allowed in a constant expression}}
#pragma omp allocate(a) align(c + 1)
// expected-error@+1 {{expected an OpenMP directive}}
#pragma omp align(2) allocate(a)
// expected-error@+1 {{directive '#pragma omp allocate' cannot contain more than one 'align' clause}}
#pragma omp allocate(a) align(2) align(4)
// expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}}
#pragma omp allocate(a) align(9)
// expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'double'}}
#pragma omp allocate(a) align(f)
}

// Verify appropriate errors when using templates.
template <typename T, unsigned size, unsigned align>
T run() {
T foo[size];
// expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}}
#pragma omp allocate(foo) align(align)
return foo[0];
}

int template_test() {
double d;
// expected-note@+1 {{in instantiation of function template specialization 'run<double, 10U, 3U>' requested here}}
d = run<double, 10, 3>();
return 0;
}
4 changes: 4 additions & 0 deletions clang/tools/libclang/CIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2315,6 +2315,10 @@ void OMPClauseEnqueue::VisitOMPFilterClause(const OMPFilterClause *C) {
Visitor->AddStmt(C->getThreadID());
}

void OMPClauseEnqueue::VisitOMPAlignClause(const OMPAlignClause *C) {
Visitor->AddStmt(C->getAlignment());
}

void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
const OMPUnifiedAddressClause *) {}

Expand Down
1 change: 1 addition & 0 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,7 @@ CHECK_SIMPLE_CLAUSE(AdjustArgs, OMPC_adjust_args)
CHECK_SIMPLE_CLAUSE(AppendArgs, OMPC_append_args)
CHECK_SIMPLE_CLAUSE(MemoryOrder, OMPC_memory_order)
CHECK_SIMPLE_CLAUSE(Bind, OMPC_bind)
CHECK_SIMPLE_CLAUSE(Align, OMPC_align)

CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize)
CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks)
Expand Down
6 changes: 5 additions & 1 deletion llvm/include/llvm/Frontend/OpenMP/OMP.td
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ def OMPC_Filter : Clause<"filter"> {
let clangClass = "OMPFilterClause";
let flangClass = "ScalarIntExpr";
}
def OMPC_Align : Clause<"align"> {
let clangClass = "OMPAlignClause";
}
def OMPC_When: Clause<"when"> {}

def OMPC_Bind : Clause<"bind"> {
Expand Down Expand Up @@ -1539,7 +1542,8 @@ def OMP_TargetTeamsDistributeSimd :
}
def OMP_Allocate : Directive<"allocate"> {
let allowedOnceClauses = [
VersionedClause<OMPC_Allocator>
VersionedClause<OMPC_Allocator>,
VersionedClause<OMPC_Align, 51>
];
}
def OMP_DeclareVariant : Directive<"declare variant"> {
Expand Down