forked from OSchip/llvm-project
Revert back r219295.
To fix issues with test OpenMP/parallel_firstprivate_codegen.cpp llvm-svn: 219296
This commit is contained in:
parent
e7a5517a58
commit
bdef50e1ad
|
@ -2482,12 +2482,6 @@ template <typename Derived>
|
|||
bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
|
||||
OMPFirstprivateClause *C) {
|
||||
TRY_TO(VisitOMPClauseList(C));
|
||||
for (auto *E : C->private_copies()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
for (auto *E : C->inits()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -986,8 +986,6 @@ public:
|
|||
/// with the variables 'a' and 'b'.
|
||||
///
|
||||
class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
|
||||
friend class OMPClauseReader;
|
||||
|
||||
/// \brief Build clause with number of variables \a N.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
|
@ -1008,33 +1006,6 @@ class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
|
|||
: OMPVarListClause<OMPFirstprivateClause>(
|
||||
OMPC_firstprivate, SourceLocation(), SourceLocation(),
|
||||
SourceLocation(), N) {}
|
||||
/// \brief Sets the list of references to private copies with initializers for
|
||||
/// new private variables.
|
||||
/// \param VL List of references.
|
||||
void setPrivateCopies(ArrayRef<Expr *> VL);
|
||||
|
||||
/// \brief Gets the list of references to private copies with initializers for
|
||||
/// new private variables.
|
||||
MutableArrayRef<Expr *> getPrivateCopies() {
|
||||
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
|
||||
}
|
||||
ArrayRef<const Expr *> getPrivateCopies() const {
|
||||
return llvm::makeArrayRef(varlist_end(), varlist_size());
|
||||
}
|
||||
|
||||
/// \brief Sets the list of references to initializer variables for new
|
||||
/// private variables.
|
||||
/// \param VL List of references.
|
||||
void setInits(ArrayRef<Expr *> VL);
|
||||
|
||||
/// \brief Gets the list of references to initializer variables for new
|
||||
/// private variables.
|
||||
MutableArrayRef<Expr *> getInits() {
|
||||
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
|
||||
}
|
||||
ArrayRef<const Expr *> getInits() const {
|
||||
return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Creates clause with a list of variables \a VL.
|
||||
|
@ -1043,16 +1014,11 @@ public:
|
|||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
/// \param VL List of references to the original variables.
|
||||
/// \param PrivateVL List of references to private copies with initializers.
|
||||
/// \param InitVL List of references to auto generated variables used for
|
||||
/// initialization of a single array element. Used if firstprivate variable is
|
||||
/// of array type.
|
||||
/// \param VL List of references to the variables.
|
||||
///
|
||||
static OMPFirstprivateClause *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
|
||||
ArrayRef<Expr *> InitVL);
|
||||
SourceLocation EndLoc, ArrayRef<Expr *> VL);
|
||||
/// \brief Creates an empty clause with the place for \a N variables.
|
||||
///
|
||||
/// \param C AST context.
|
||||
|
@ -1060,33 +1026,6 @@ public:
|
|||
///
|
||||
static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
|
||||
|
||||
typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
|
||||
typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
|
||||
typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
|
||||
typedef llvm::iterator_range<private_copies_const_iterator>
|
||||
private_copies_const_range;
|
||||
|
||||
private_copies_range private_copies() {
|
||||
return private_copies_range(getPrivateCopies().begin(),
|
||||
getPrivateCopies().end());
|
||||
}
|
||||
private_copies_const_range private_copies() const {
|
||||
return private_copies_const_range(getPrivateCopies().begin(),
|
||||
getPrivateCopies().end());
|
||||
}
|
||||
|
||||
typedef MutableArrayRef<Expr *>::iterator inits_iterator;
|
||||
typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
|
||||
typedef llvm::iterator_range<inits_iterator> inits_range;
|
||||
typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
|
||||
|
||||
inits_range inits() {
|
||||
return inits_range(getInits().begin(), getInits().end());
|
||||
}
|
||||
inits_const_range inits() const {
|
||||
return inits_const_range(getInits().begin(), getInits().end());
|
||||
}
|
||||
|
||||
StmtRange children() {
|
||||
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
|
||||
reinterpret_cast<Stmt **>(varlist_end()));
|
||||
|
|
|
@ -2504,12 +2504,6 @@ template <typename Derived>
|
|||
bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
|
||||
OMPFirstprivateClause *C) {
|
||||
TRY_TO(VisitOMPClauseList(C));
|
||||
for (auto *E : C->private_copies()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
for (auto *E : C->inits()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -7141,8 +7141,8 @@ def err_omp_expected_var_name : Error<
|
|||
"expected variable name">;
|
||||
def err_omp_required_method : Error<
|
||||
"%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1">;
|
||||
def note_omp_task_predetermined_firstprivate_here : Note<
|
||||
"predetermined as a firstprivate in a task construct here">;
|
||||
def err_omp_task_predetermined_firstprivate_required_method : Error<
|
||||
"predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous %select{copy constructor|destructor}0">;
|
||||
def err_omp_clause_ref_type_arg : Error<
|
||||
"arguments of OpenMP clause '%0' cannot be of reference type %1">;
|
||||
def err_omp_task_predetermined_firstprivate_ref_type_arg : Error<
|
||||
|
|
|
@ -1198,31 +1198,19 @@ OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
|
|||
return new (Mem) OMPPrivateClause(N);
|
||||
}
|
||||
|
||||
void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
|
||||
assert(VL.size() == varlist_size() &&
|
||||
"Number of private copies is not the same as the preallocated buffer");
|
||||
std::copy(VL.begin(), VL.end(), varlist_end());
|
||||
}
|
||||
|
||||
void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
|
||||
assert(VL.size() == varlist_size() &&
|
||||
"Number of inits is not the same as the preallocated buffer");
|
||||
std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
|
||||
}
|
||||
|
||||
OMPFirstprivateClause *
|
||||
OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc,
|
||||
ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
|
||||
ArrayRef<Expr *> InitVL) {
|
||||
OMPFirstprivateClause *OMPFirstprivateClause::Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc,
|
||||
ArrayRef<Expr *> VL) {
|
||||
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
|
||||
llvm::alignOf<Expr *>()) +
|
||||
3 * sizeof(Expr *) * VL.size());
|
||||
OMPFirstprivateClause *Clause =
|
||||
new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
||||
sizeof(Expr *) * VL.size());
|
||||
OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc,
|
||||
LParenLoc,
|
||||
EndLoc,
|
||||
VL.size());
|
||||
Clause->setVarRefs(VL);
|
||||
Clause->setPrivateCopies(PrivateVL);
|
||||
Clause->setInits(InitVL);
|
||||
return Clause;
|
||||
}
|
||||
|
||||
|
@ -1230,7 +1218,7 @@ OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
|
|||
unsigned N) {
|
||||
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
|
||||
llvm::alignOf<Expr *>()) +
|
||||
3 * sizeof(Expr *) * N);
|
||||
sizeof(Expr *) * N);
|
||||
return new (Mem) OMPFirstprivateClause(N);
|
||||
}
|
||||
|
||||
|
|
|
@ -329,15 +329,9 @@ void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
|
|||
void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
void
|
||||
OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) {
|
||||
void OMPClauseProfiler::VisitOMPFirstprivateClause(
|
||||
const OMPFirstprivateClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
for (auto *E : C->private_copies()) {
|
||||
Profiler->VisitStmt(E);
|
||||
}
|
||||
for (auto *E : C->inits()) {
|
||||
Profiler->VisitStmt(E);
|
||||
}
|
||||
}
|
||||
void
|
||||
OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
|
||||
|
|
|
@ -1073,7 +1073,7 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) {
|
|||
|
||||
/// \brief Determine whether the given initializer is trivial in the sense
|
||||
/// that it requires no code to be generated.
|
||||
bool CodeGenFunction::isTrivialInitializer(const Expr *Init) {
|
||||
static bool isTrivialInitializer(const Expr *Init) {
|
||||
if (!Init)
|
||||
return true;
|
||||
|
||||
|
|
|
@ -24,29 +24,6 @@
|
|||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, Stmt *S) {
|
||||
CodeGenFunction::OuterDeclMapTy OuterDeclMap;
|
||||
CGF.EmitOMPFirstprivateClause(Directive, OuterDeclMap);
|
||||
if (!OuterDeclMap.empty()) {
|
||||
// Emit implicit barrier to synchronize threads and avoid data races.
|
||||
auto Flags = static_cast<CGOpenMPRuntime::OpenMPLocationFlags>(
|
||||
CGOpenMPRuntime::OMP_IDENT_KMPC |
|
||||
CGOpenMPRuntime::OMP_IDENT_BARRIER_IMPL);
|
||||
CGF.CGM.getOpenMPRuntime().EmitOMPBarrierCall(CGF, Directive.getLocStart(),
|
||||
Flags);
|
||||
// Remap captured variables to use their private copies in the outlined
|
||||
// function.
|
||||
for (auto I : OuterDeclMap) {
|
||||
CGF.LocalDeclMap[I.first] = I.second;
|
||||
}
|
||||
}
|
||||
CGCapturedStmtInfo::EmitBody(CGF, S);
|
||||
// Clear mappings of captured private variables.
|
||||
for (auto I : OuterDeclMap) {
|
||||
CGF.LocalDeclMap.erase(I.first);
|
||||
}
|
||||
}
|
||||
|
||||
CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
|
||||
: CGM(CGM), DefaultOpenMPPSource(nullptr) {
|
||||
IdentTy = llvm::StructType::create(
|
||||
|
@ -74,10 +51,11 @@ CGOpenMPRuntime::GetOrCreateDefaultOpenMPLocation(OpenMPLocationFlags Flags) {
|
|||
DefaultOpenMPPSource =
|
||||
llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
|
||||
}
|
||||
auto DefaultOpenMPLocation = new llvm::GlobalVariable(
|
||||
CGM.getModule(), IdentTy, /*isConstant*/ true,
|
||||
llvm::GlobalValue::PrivateLinkage, /*Initializer*/ nullptr);
|
||||
llvm::GlobalVariable *DefaultOpenMPLocation = cast<llvm::GlobalVariable>(
|
||||
CGM.CreateRuntimeVariable(IdentTy, ".kmpc_default_loc.addr"));
|
||||
DefaultOpenMPLocation->setUnnamedAddr(true);
|
||||
DefaultOpenMPLocation->setConstant(true);
|
||||
DefaultOpenMPLocation->setLinkage(llvm::GlobalValue::PrivateLinkage);
|
||||
|
||||
llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
|
||||
llvm::Constant *Values[] = {Zero,
|
||||
|
@ -85,7 +63,6 @@ CGOpenMPRuntime::GetOrCreateDefaultOpenMPLocation(OpenMPLocationFlags Flags) {
|
|||
Zero, Zero, DefaultOpenMPPSource};
|
||||
llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
|
||||
DefaultOpenMPLocation->setInitializer(Init);
|
||||
OpenMPDefaultLocMap[Flags] = DefaultOpenMPLocation;
|
||||
return DefaultOpenMPLocation;
|
||||
}
|
||||
return Entry;
|
||||
|
@ -143,14 +120,14 @@ llvm::Value *CGOpenMPRuntime::EmitOpenMPUpdateLocation(
|
|||
return LocValue;
|
||||
}
|
||||
|
||||
llvm::Value *CGOpenMPRuntime::GetOpenMPThreadID(CodeGenFunction &CGF,
|
||||
SourceLocation Loc) {
|
||||
llvm::Value *CGOpenMPRuntime::GetOpenMPGlobalThreadNum(CodeGenFunction &CGF,
|
||||
SourceLocation Loc) {
|
||||
assert(CGF.CurFn && "No function in current CodeGenFunction.");
|
||||
|
||||
llvm::Value *ThreadID = nullptr;
|
||||
OpenMPThreadIDMapTy::iterator I = OpenMPThreadIDMap.find(CGF.CurFn);
|
||||
if (I != OpenMPThreadIDMap.end()) {
|
||||
ThreadID = I->second;
|
||||
llvm::Value *GTid = nullptr;
|
||||
OpenMPGtidMapTy::iterator I = OpenMPGtidMap.find(CGF.CurFn);
|
||||
if (I != OpenMPGtidMap.end()) {
|
||||
GTid = I->second;
|
||||
} else {
|
||||
// Check if current function is a function which has first parameter
|
||||
// with type int32 and name ".global_tid.".
|
||||
|
@ -168,24 +145,24 @@ llvm::Value *CGOpenMPRuntime::GetOpenMPThreadID(CodeGenFunction &CGF,
|
|||
CGF.CurFn->arg_begin()->getName() == ".global_tid.") {
|
||||
CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
|
||||
CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
|
||||
ThreadID = CGF.Builder.CreateLoad(CGF.CurFn->arg_begin());
|
||||
GTid = CGF.Builder.CreateLoad(CGF.CurFn->arg_begin());
|
||||
} else {
|
||||
// Generate "int32 .kmpc_global_thread_num.addr;"
|
||||
CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
|
||||
CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
|
||||
llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc)};
|
||||
ThreadID = CGF.EmitRuntimeCall(
|
||||
GTid = CGF.EmitRuntimeCall(
|
||||
CreateRuntimeFunction(OMPRTL__kmpc_global_thread_num), Args);
|
||||
}
|
||||
OpenMPThreadIDMap[CGF.CurFn] = ThreadID;
|
||||
OpenMPGtidMap[CGF.CurFn] = GTid;
|
||||
}
|
||||
return ThreadID;
|
||||
return GTid;
|
||||
}
|
||||
|
||||
void CGOpenMPRuntime::FunctionFinished(CodeGenFunction &CGF) {
|
||||
assert(CGF.CurFn && "No function in current CodeGenFunction.");
|
||||
if (OpenMPThreadIDMap.count(CGF.CurFn))
|
||||
OpenMPThreadIDMap.erase(CGF.CurFn);
|
||||
if (OpenMPGtidMap.count(CGF.CurFn))
|
||||
OpenMPGtidMap.erase(CGF.CurFn);
|
||||
if (OpenMPLocMap.count(CGF.CurFn))
|
||||
OpenMPLocMap.erase(CGF.CurFn);
|
||||
}
|
||||
|
@ -242,33 +219,10 @@ CGOpenMPRuntime::CreateRuntimeFunction(OpenMPRTLFunction Function) {
|
|||
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
|
||||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_barrier: {
|
||||
// Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
|
||||
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
|
||||
llvm::FunctionType *FnTy =
|
||||
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
|
||||
RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return RTLFn;
|
||||
}
|
||||
|
||||
void CGOpenMPRuntime::EmitOMPParallelCall(CodeGenFunction &CGF,
|
||||
SourceLocation Loc,
|
||||
llvm::Value *OutlinedFn,
|
||||
llvm::Value *CapturedStruct) {
|
||||
// Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
|
||||
llvm::Value *Args[] = {
|
||||
EmitOpenMPUpdateLocation(CGF, Loc),
|
||||
CGF.Builder.getInt32(1), // Number of arguments after 'microtask' argument
|
||||
// (there is only one additional argument - 'context')
|
||||
CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy()),
|
||||
CGF.EmitCastToVoidPtr(CapturedStruct)};
|
||||
auto RTLFn = CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
|
||||
CGF.EmitRuntimeCall(RTLFn, Args);
|
||||
}
|
||||
|
||||
llvm::Value *CGOpenMPRuntime::GetCriticalRegionLock(StringRef CriticalName) {
|
||||
SmallString<256> Buffer;
|
||||
llvm::raw_svector_ostream Out(Buffer);
|
||||
|
@ -291,7 +245,7 @@ void CGOpenMPRuntime::EmitOMPCriticalRegionStart(CodeGenFunction &CGF,
|
|||
SourceLocation Loc) {
|
||||
// Prepare other arguments and build a call to __kmpc_critical
|
||||
llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc),
|
||||
GetOpenMPThreadID(CGF, Loc), RegionLock};
|
||||
GetOpenMPGlobalThreadNum(CGF, Loc), RegionLock};
|
||||
auto RTLFn = CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_critical);
|
||||
CGF.EmitRuntimeCall(RTLFn, Args);
|
||||
}
|
||||
|
@ -301,19 +255,8 @@ void CGOpenMPRuntime::EmitOMPCriticalRegionEnd(CodeGenFunction &CGF,
|
|||
SourceLocation Loc) {
|
||||
// Prepare other arguments and build a call to __kmpc_end_critical
|
||||
llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc),
|
||||
GetOpenMPThreadID(CGF, Loc), RegionLock};
|
||||
GetOpenMPGlobalThreadNum(CGF, Loc), RegionLock};
|
||||
auto RTLFn =
|
||||
CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_end_critical);
|
||||
CGF.EmitRuntimeCall(RTLFn, Args);
|
||||
}
|
||||
|
||||
void CGOpenMPRuntime::EmitOMPBarrierCall(CodeGenFunction &CGF,
|
||||
SourceLocation Loc,
|
||||
OpenMPLocationFlags Flags) {
|
||||
// Build call __kmpc_barrier(loc, thread_id)
|
||||
llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc, Flags),
|
||||
GetOpenMPThreadID(CGF, Loc)};
|
||||
auto RTLFn = CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_barrier);
|
||||
CGF.EmitRuntimeCall(RTLFn, Args);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,49 +14,33 @@
|
|||
#ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
|
||||
#define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
|
||||
|
||||
#include "CodeGenFunction.h"
|
||||
#include "clang/AST/StmtOpenMP.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
|
||||
namespace llvm {
|
||||
class AllocaInst;
|
||||
class CallInst;
|
||||
class GlobalVariable;
|
||||
class Constant;
|
||||
class Function;
|
||||
class Module;
|
||||
class StructLayout;
|
||||
class ArrayType;
|
||||
class FunctionType;
|
||||
class StructType;
|
||||
class Type;
|
||||
class Value;
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace CodeGen {
|
||||
|
||||
/// \brief API for captured statement code generation in OpenMP constructs.
|
||||
class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
|
||||
public:
|
||||
CGOpenMPRegionInfo(const OMPExecutableDirective &D, const CapturedStmt &S,
|
||||
const VarDecl *ThreadIDVar)
|
||||
: CGCapturedStmtInfo(S, CR_OpenMP), ThreadIDVar(ThreadIDVar),
|
||||
Directive(D) {}
|
||||
|
||||
virtual ~CGOpenMPRegionInfo() override{};
|
||||
|
||||
/// \brief Gets a variable or parameter for storing global thread id
|
||||
/// inside OpenMP construct.
|
||||
const VarDecl *getThreadIDVariable() const { return ThreadIDVar; }
|
||||
|
||||
static bool classof(const CGCapturedStmtInfo *Info) {
|
||||
return Info->getKind() == CR_OpenMP;
|
||||
}
|
||||
|
||||
/// \brief Emit the captured statement body.
|
||||
virtual void EmitBody(CodeGenFunction &CGF, Stmt *S) override;
|
||||
|
||||
/// \brief Get the name of the capture helper.
|
||||
virtual StringRef getHelperName() const override { return ".omp_outlined."; }
|
||||
|
||||
private:
|
||||
/// \brief A variable or parameter storing global thread id for OpenMP
|
||||
/// constructs.
|
||||
const VarDecl *ThreadIDVar;
|
||||
/// \brief OpenMP executable directive associated with the region.
|
||||
const OMPExecutableDirective &Directive;
|
||||
};
|
||||
class CodeGenFunction;
|
||||
class CodeGenModule;
|
||||
|
||||
class CGOpenMPRuntime {
|
||||
public:
|
||||
|
@ -92,9 +76,7 @@ public:
|
|||
OMPRTL__kmpc_critical,
|
||||
// Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit);
|
||||
OMPRTL__kmpc_end_critical,
|
||||
// Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_barrier
|
||||
OMPRTL__kmpc_end_critical
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -157,15 +139,24 @@ private:
|
|||
/// \brief Map of local debug location and functions.
|
||||
typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPLocMapTy;
|
||||
OpenMPLocMapTy OpenMPLocMap;
|
||||
/// \brief Map of local ThreadID and functions.
|
||||
typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPThreadIDMapTy;
|
||||
OpenMPThreadIDMapTy OpenMPThreadIDMap;
|
||||
/// \brief Map of local gtid and functions.
|
||||
typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPGtidMapTy;
|
||||
OpenMPGtidMapTy OpenMPGtidMap;
|
||||
/// \brief Type kmp_critical_name, originally defined as typedef kmp_int32
|
||||
/// kmp_critical_name[8];
|
||||
llvm::ArrayType *KmpCriticalNameTy;
|
||||
/// \brief Map of critical regions names and the corresponding lock objects.
|
||||
llvm::StringMap<llvm::Value *, llvm::BumpPtrAllocator> CriticalRegionVarNames;
|
||||
|
||||
public:
|
||||
explicit CGOpenMPRuntime(CodeGenModule &CGM);
|
||||
virtual ~CGOpenMPRuntime() {}
|
||||
|
||||
/// \brief Cleans up references to the objects in finished function.
|
||||
/// \param CGF Reference to finished CodeGenFunction.
|
||||
///
|
||||
void FunctionFinished(CodeGenFunction &CGF);
|
||||
|
||||
/// \brief Emits object of ident_t type with info for source location.
|
||||
/// \param CGF Reference to current CodeGenFunction.
|
||||
/// \param Loc Clang source location.
|
||||
|
@ -175,6 +166,13 @@ private:
|
|||
EmitOpenMPUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
|
||||
OpenMPLocationFlags Flags = OMP_IDENT_KMPC);
|
||||
|
||||
/// \brief Generates global thread number value.
|
||||
/// \param CGF Reference to current CodeGenFunction.
|
||||
/// \param Loc Clang source location.
|
||||
///
|
||||
llvm::Value *GetOpenMPGlobalThreadNum(CodeGenFunction &CGF,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// \brief Returns pointer to ident_t type;
|
||||
llvm::Type *getIdentTyPointerTy();
|
||||
|
||||
|
@ -186,33 +184,6 @@ private:
|
|||
/// \return Specified function.
|
||||
llvm::Constant *CreateRuntimeFunction(OpenMPRTLFunction Function);
|
||||
|
||||
/// \brief Gets thread id value for the current thread.
|
||||
/// \param CGF Reference to current CodeGenFunction.
|
||||
/// \param Loc Clang source location.
|
||||
///
|
||||
llvm::Value *GetOpenMPThreadID(CodeGenFunction &CGF, SourceLocation Loc);
|
||||
|
||||
public:
|
||||
explicit CGOpenMPRuntime(CodeGenModule &CGM);
|
||||
virtual ~CGOpenMPRuntime() {}
|
||||
|
||||
/// \brief Cleans up references to the objects in finished function.
|
||||
/// \param CGF Reference to finished CodeGenFunction.
|
||||
///
|
||||
void FunctionFinished(CodeGenFunction &CGF);
|
||||
|
||||
/// \brief Emits code for parallel call of the \a OutlinedFn with variables
|
||||
/// captured in a record which address is stored in \a CapturedStruct.
|
||||
/// \param CGF Reference to current CodeGenFunction.
|
||||
/// \param Loc Clang source location.
|
||||
/// \param OutlinedFn Outlined function to be run in parallel threads.
|
||||
/// \param CapturedStruct A pointer to the record with the references to
|
||||
/// variables used in \a OutlinedFn function.
|
||||
///
|
||||
virtual void EmitOMPParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||
llvm::Value *OutlinedFn,
|
||||
llvm::Value *CapturedStruct);
|
||||
|
||||
/// \brief Returns corresponding lock object for the specified critical region
|
||||
/// name. If the lock object does not exist it is created, otherwise the
|
||||
/// reference to the existing copy is returned.
|
||||
|
@ -237,14 +208,6 @@ public:
|
|||
virtual void EmitOMPCriticalRegionEnd(CodeGenFunction &CGF,
|
||||
llvm::Value *RegionLock,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// \brief Emits a barrier for OpenMP threads.
|
||||
/// \param CGF Reference to current CodeGenFunction.
|
||||
/// \param Loc Clang source location.
|
||||
/// \param Flags Flags for the barrier.
|
||||
///
|
||||
virtual void EmitOMPBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||
OpenMPLocationFlags Flags);
|
||||
};
|
||||
} // namespace CodeGen
|
||||
} // namespace clang
|
||||
|
|
|
@ -24,110 +24,6 @@ using namespace CodeGen;
|
|||
// OpenMP Directive Emission
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr,
|
||||
llvm::Value *PrivateAddr,
|
||||
const Expr *AssignExpr,
|
||||
QualType OriginalType,
|
||||
const VarDecl *VDInit) {
|
||||
EmitBlock(createBasicBlock(".omp.assign.begin."));
|
||||
if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) {
|
||||
// Perform simple memcpy.
|
||||
EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(),
|
||||
AssignExpr->getType());
|
||||
} else {
|
||||
// Perform element-by-element initialization.
|
||||
QualType ElementTy;
|
||||
auto SrcBegin = OriginalAddr.getAddress();
|
||||
auto DestBegin = PrivateAddr;
|
||||
auto ArrayTy = OriginalType->getAsArrayTypeUnsafe();
|
||||
auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin);
|
||||
auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin);
|
||||
auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements);
|
||||
auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements);
|
||||
// The basic structure here is a do-while loop, because we don't
|
||||
// need to check for the zero-element case.
|
||||
auto BodyBB = createBasicBlock("omp.arraycpy.body");
|
||||
auto DoneBB = createBasicBlock("omp.arraycpy.done");
|
||||
auto IsEmpty =
|
||||
Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
|
||||
Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
|
||||
|
||||
// Enter the loop body, making that address the current address.
|
||||
auto EntryBB = Builder.GetInsertBlock();
|
||||
EmitBlock(BodyBB);
|
||||
auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2,
|
||||
"omp.arraycpy.srcElementPast");
|
||||
SrcElementPast->addIncoming(SrcEnd, EntryBB);
|
||||
auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2,
|
||||
"omp.arraycpy.destElementPast");
|
||||
DestElementPast->addIncoming(DestEnd, EntryBB);
|
||||
|
||||
// Shift the address back by one element.
|
||||
auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
|
||||
auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne,
|
||||
"omp.arraycpy.dest.element");
|
||||
auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne,
|
||||
"omp.arraycpy.src.element");
|
||||
{
|
||||
// Create RunCleanScope to cleanup possible temps.
|
||||
CodeGenFunction::RunCleanupsScope Init(*this);
|
||||
// Emit initialization for single element.
|
||||
LocalDeclMap[VDInit] = SrcElement;
|
||||
EmitAnyExprToMem(AssignExpr, DestElement,
|
||||
AssignExpr->getType().getQualifiers(),
|
||||
/*IsInitializer*/ false);
|
||||
LocalDeclMap.erase(VDInit);
|
||||
}
|
||||
|
||||
// Check whether we've reached the end.
|
||||
auto Done =
|
||||
Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done");
|
||||
Builder.CreateCondBr(Done, DoneBB, BodyBB);
|
||||
DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock());
|
||||
SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock());
|
||||
|
||||
// Done.
|
||||
EmitBlock(DoneBB, true);
|
||||
}
|
||||
EmitBlock(createBasicBlock(".omp.assign.end."));
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPFirstprivateClause(
|
||||
const OMPExecutableDirective &D,
|
||||
CodeGenFunction::OuterDeclMapTy &OuterDeclMap) {
|
||||
auto PrivateFilter = [](const OMPClause *C) -> bool {
|
||||
return C->getClauseKind() == OMPC_firstprivate;
|
||||
};
|
||||
for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)>
|
||||
I(D.clauses(), PrivateFilter); I; ++I) {
|
||||
auto *C = cast<OMPFirstprivateClause>(*I);
|
||||
auto IRef = C->varlist_begin();
|
||||
auto InitsRef = C->inits().begin();
|
||||
for (auto IInit : C->private_copies()) {
|
||||
auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
|
||||
if (*InitsRef != nullptr) {
|
||||
// Emit VarDecl with copy init for arrays.
|
||||
auto *FD = CapturedStmtInfo->lookup(
|
||||
cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()));
|
||||
LValue Base = MakeNaturalAlignAddrLValue(
|
||||
CapturedStmtInfo->getContextValue(),
|
||||
getContext().getTagDeclType(FD->getParent()));
|
||||
auto OriginalAddr = EmitLValueForField(Base, FD);
|
||||
auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
|
||||
auto Emission = EmitAutoVarAlloca(*VD);
|
||||
// Emit initialization of aggregate firstprivate vars.
|
||||
EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(),
|
||||
VD->getInit(), (*IRef)->getType(), VDInit);
|
||||
EmitAutoVarCleanups(Emission);
|
||||
} else
|
||||
// Emit VarDecl with copy init.
|
||||
EmitDecl(*VD);
|
||||
OuterDeclMap[cast<DeclRefExpr>(*IRef)->getDecl()] = GetAddrOfLocalVar(VD);
|
||||
++IRef, ++InitsRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
|
||||
const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
|
||||
llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
|
||||
|
@ -135,13 +31,22 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
|
|||
llvm::Value *OutlinedFn;
|
||||
{
|
||||
CodeGenFunction CGF(CGM, true);
|
||||
CGOpenMPRegionInfo CGInfo(S, *CS, *CS->getCapturedDecl()->param_begin());
|
||||
CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind());
|
||||
CGF.CapturedStmtInfo = &CGInfo;
|
||||
OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
|
||||
}
|
||||
|
||||
CGM.getOpenMPRuntime().EmitOMPParallelCall(*this, S.getLocStart(), OutlinedFn,
|
||||
CapturedStruct);
|
||||
// Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
|
||||
llvm::Value *Args[] = {
|
||||
CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
|
||||
Builder.getInt32(1), // Number of arguments after 'microtask' argument
|
||||
// (there is only one additional argument - 'context')
|
||||
Builder.CreateBitCast(OutlinedFn,
|
||||
CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
|
||||
EmitCastToVoidPtr(CapturedStruct)};
|
||||
llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
|
||||
CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
|
||||
EmitRuntimeCall(RTLFn, Args);
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S,
|
||||
|
|
|
@ -113,7 +113,6 @@ class CodeGenFunction : public CodeGenTypeCache {
|
|||
void operator=(const CodeGenFunction &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
friend class CGCXXABI;
|
||||
friend class CGOpenMPRegionInfo;
|
||||
public:
|
||||
/// A jump destination is an abstract label, branching to which may
|
||||
/// require a jump out through normal cleanups.
|
||||
|
@ -1827,10 +1826,6 @@ public:
|
|||
typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
|
||||
llvm::Value *Address);
|
||||
|
||||
/// \brief Determine whether the given initializer is trivial in the sense
|
||||
/// that it requires no code to be generated.
|
||||
bool isTrivialInitializer(const Expr *Init);
|
||||
|
||||
/// EmitAutoVarDecl - Emit an auto variable declaration.
|
||||
///
|
||||
/// This function can be called with a null (unreachable) insert point.
|
||||
|
@ -1996,16 +1991,8 @@ public:
|
|||
ArrayRef<const Attr *> Attrs = None);
|
||||
|
||||
llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
|
||||
void GenerateCapturedStmtFunctionProlog(const CapturedStmt &S);
|
||||
llvm::Function *GenerateCapturedStmtFunctionEpilog(const CapturedStmt &S);
|
||||
llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S);
|
||||
llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S);
|
||||
typedef llvm::DenseMap<const Decl *, llvm::Value *> OuterDeclMapTy;
|
||||
void EmitOMPAggregateAssign(LValue OriginalAddr, llvm::Value *PrivateAddr,
|
||||
const Expr *AssignExpr, QualType Type,
|
||||
const VarDecl *VDInit);
|
||||
void EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
|
||||
OuterDeclMapTy &OuterDeclMap);
|
||||
|
||||
void EmitOMPParallelDirective(const OMPParallelDirective &S);
|
||||
void EmitOMPSimdDirective(const OMPSimdDirective &S);
|
||||
|
|
|
@ -3902,36 +3902,11 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
|
|||
return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DiagsUninitializedSeveretyRAII {
|
||||
private:
|
||||
DiagnosticsEngine &Diags;
|
||||
SourceLocation SavedLoc;
|
||||
bool IsIgnored;
|
||||
|
||||
public:
|
||||
DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
|
||||
bool IsIgnored)
|
||||
: Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
|
||||
if (!IsIgnored) {
|
||||
Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
|
||||
/*Map*/ diag::Severity::Ignored, Loc);
|
||||
}
|
||||
}
|
||||
~DiagsUninitializedSeveretyRAII() {
|
||||
if (!IsIgnored)
|
||||
Diags.popMappings(SavedLoc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
SmallVector<Expr *, 8> Vars;
|
||||
SmallVector<Expr *, 8> PrivateCopies;
|
||||
SmallVector<Expr *, 8> Inits;
|
||||
bool IsImplicitClause =
|
||||
StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
|
||||
auto ImplicitClauseLoc = DSAStack->getConstructLoc();
|
||||
|
@ -3941,13 +3916,11 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
|
||||
// It will be analyzed later.
|
||||
Vars.push_back(RefExpr);
|
||||
PrivateCopies.push_back(nullptr);
|
||||
Inits.push_back(nullptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
SourceLocation ELoc =
|
||||
IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc();
|
||||
SourceLocation ELoc = IsImplicitClause ? ImplicitClauseLoc
|
||||
: RefExpr->getExprLoc();
|
||||
// OpenMP [2.1, C/C++]
|
||||
// A list item is a variable name.
|
||||
// OpenMP [2.9.3.3, Restrictions, p.1]
|
||||
|
@ -3965,8 +3938,6 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
if (Type->isDependentType() || Type->isInstantiationDependentType()) {
|
||||
// It will be analyzed later.
|
||||
Vars.push_back(DE);
|
||||
PrivateCopies.push_back(nullptr);
|
||||
Inits.push_back(nullptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4000,6 +3971,65 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
// clause requires an accessible, unambiguous copy constructor for the
|
||||
// class type.
|
||||
Type = Context.getBaseElementType(Type);
|
||||
CXXRecordDecl *RD = getLangOpts().CPlusPlus
|
||||
? Type.getNonReferenceType()->getAsCXXRecordDecl()
|
||||
: nullptr;
|
||||
// FIXME This code must be replaced by actual constructing/destructing of
|
||||
// the firstprivate variable.
|
||||
if (RD) {
|
||||
CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0);
|
||||
PartialDiagnostic PD =
|
||||
PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
|
||||
if (!CD ||
|
||||
CheckConstructorAccess(ELoc, CD,
|
||||
InitializedEntity::InitializeTemporary(Type),
|
||||
CD->getAccess(), PD) == AR_inaccessible ||
|
||||
CD->isDeleted()) {
|
||||
if (IsImplicitClause) {
|
||||
Diag(ImplicitClauseLoc,
|
||||
diag::err_omp_task_predetermined_firstprivate_required_method)
|
||||
<< 0;
|
||||
Diag(RefExpr->getExprLoc(), diag::note_used_here);
|
||||
} else {
|
||||
Diag(ELoc, diag::err_omp_required_method)
|
||||
<< getOpenMPClauseName(OMPC_firstprivate) << 1;
|
||||
}
|
||||
bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
|
||||
VarDecl::DeclarationOnly;
|
||||
Diag(VD->getLocation(),
|
||||
IsDecl ? diag::note_previous_decl : diag::note_defined_here)
|
||||
<< VD;
|
||||
Diag(RD->getLocation(), diag::note_previous_decl) << RD;
|
||||
continue;
|
||||
}
|
||||
MarkFunctionReferenced(ELoc, CD);
|
||||
DiagnoseUseOfDecl(CD, ELoc);
|
||||
|
||||
CXXDestructorDecl *DD = RD->getDestructor();
|
||||
if (DD) {
|
||||
if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
|
||||
DD->isDeleted()) {
|
||||
if (IsImplicitClause) {
|
||||
Diag(ImplicitClauseLoc,
|
||||
diag::err_omp_task_predetermined_firstprivate_required_method)
|
||||
<< 1;
|
||||
Diag(RefExpr->getExprLoc(), diag::note_used_here);
|
||||
} else {
|
||||
Diag(ELoc, diag::err_omp_required_method)
|
||||
<< getOpenMPClauseName(OMPC_firstprivate) << 4;
|
||||
}
|
||||
bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
|
||||
VarDecl::DeclarationOnly;
|
||||
Diag(VD->getLocation(),
|
||||
IsDecl ? diag::note_previous_decl : diag::note_defined_here)
|
||||
<< VD;
|
||||
Diag(RD->getLocation(), diag::note_previous_decl) << RD;
|
||||
continue;
|
||||
}
|
||||
MarkFunctionReferenced(ELoc, DD);
|
||||
DiagnoseUseOfDecl(DD, ELoc);
|
||||
}
|
||||
}
|
||||
|
||||
// If an implicit firstprivate variable found it was checked already.
|
||||
if (!IsImplicitClause) {
|
||||
|
@ -4089,67 +4119,15 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
|
|||
}
|
||||
}
|
||||
|
||||
Type = Type.getUnqualifiedType();
|
||||
auto VDPrivate = VarDecl::Create(Context, CurContext, DE->getLocStart(),
|
||||
ELoc, VD->getIdentifier(), VD->getType(),
|
||||
VD->getTypeSourceInfo(), /*S*/ SC_Auto);
|
||||
// Generate helper private variable and initialize it with the value of the
|
||||
// original variable. The address of the original variable is replaced by
|
||||
// the address of the new private variable in the CodeGen. This new variable
|
||||
// is not added to IdResolver, so the code in the OpenMP region uses
|
||||
// original variable for proper diagnostics and variable capturing.
|
||||
Expr *VDInitRefExpr = nullptr;
|
||||
// For arrays generate initializer for single element and replace it by the
|
||||
// original array element in CodeGen.
|
||||
if (DE->getType()->isArrayType()) {
|
||||
auto VDInit = VarDecl::Create(Context, CurContext, DE->getLocStart(),
|
||||
ELoc, VD->getIdentifier(), Type,
|
||||
VD->getTypeSourceInfo(), /*S*/ SC_Auto);
|
||||
CurContext->addHiddenDecl(VDInit);
|
||||
VDInitRefExpr = DeclRefExpr::Create(
|
||||
Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
|
||||
/*TemplateKWLoc*/ SourceLocation(), VDInit,
|
||||
/*isEnclosingLocal*/ false, ELoc, Type,
|
||||
/*VK*/ VK_LValue);
|
||||
VDInit->setIsUsed();
|
||||
auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
|
||||
InitializedEntity Entity = InitializedEntity::InitializeVariable(VDInit);
|
||||
InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
|
||||
|
||||
InitializationSequence InitSeq(*this, Entity, Kind, Init);
|
||||
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
|
||||
if (Result.isInvalid())
|
||||
VDPrivate->setInvalidDecl();
|
||||
else
|
||||
VDPrivate->setInit(Result.getAs<Expr>());
|
||||
} else {
|
||||
AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(DE).get(),
|
||||
/*DirectInit*/ false, /*TypeMayContainAuto*/ false);
|
||||
}
|
||||
if (VDPrivate->isInvalidDecl()) {
|
||||
if (IsImplicitClause) {
|
||||
Diag(DE->getExprLoc(),
|
||||
diag::note_omp_task_predetermined_firstprivate_here);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
CurContext->addDecl(VDPrivate);
|
||||
auto VDPrivateRefExpr = DeclRefExpr::Create(
|
||||
Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
|
||||
/*TemplateKWLoc*/ SourceLocation(), VDPrivate,
|
||||
/*isEnclosingLocal*/ false, DE->getLocStart(), DE->getType(),
|
||||
/*VK*/ VK_LValue);
|
||||
DSAStack->addDSA(VD, DE, OMPC_firstprivate);
|
||||
Vars.push_back(DE);
|
||||
PrivateCopies.push_back(VDPrivateRefExpr);
|
||||
Inits.push_back(VDInitRefExpr);
|
||||
}
|
||||
|
||||
if (Vars.empty())
|
||||
return nullptr;
|
||||
|
||||
return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
|
||||
Vars, PrivateCopies, Inits);
|
||||
Vars);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
|
||||
|
|
|
@ -1854,14 +1854,6 @@ void OMPClauseReader::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
|
|||
for (unsigned i = 0; i != NumVars; ++i)
|
||||
Vars.push_back(Reader->Reader.ReadSubExpr());
|
||||
C->setVarRefs(Vars);
|
||||
Vars.clear();
|
||||
for (unsigned i = 0; i != NumVars; ++i)
|
||||
Vars.push_back(Reader->Reader.ReadSubExpr());
|
||||
C->setPrivateCopies(Vars);
|
||||
Vars.clear();
|
||||
for (unsigned i = 0; i != NumVars; ++i)
|
||||
Vars.push_back(Reader->Reader.ReadSubExpr());
|
||||
C->setInits(Vars);
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
|
||||
|
|
|
@ -1761,15 +1761,8 @@ void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
|
|||
void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
||||
for (auto *VE : C->varlists()) {
|
||||
for (auto *VE : C->varlists())
|
||||
Writer->Writer.AddStmt(VE);
|
||||
}
|
||||
for (auto *VE : C->private_copies()) {
|
||||
Writer->Writer.AddStmt(VE);
|
||||
}
|
||||
for (auto *VE : C->inits()) {
|
||||
Writer->Writer.AddStmt(VE);
|
||||
}
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -26,23 +26,23 @@ class S3 {
|
|||
S3 &operator=(const S3 &s3);
|
||||
|
||||
public:
|
||||
S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
|
||||
S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}}
|
||||
S3() : a(0) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note 2 {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note 4 {{'S5' declared here}}
|
||||
int a;
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5() : a(0) {}
|
||||
|
@ -62,8 +62,8 @@ S3 h;
|
|||
|
||||
template <class I, class C>
|
||||
int foomain(int argc, char **argv) {
|
||||
I e(4);
|
||||
C g(5);
|
||||
I e(4); // expected-note {{'e' defined here}}
|
||||
C g(5); // expected-note 2 {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel
|
||||
|
@ -107,7 +107,7 @@ int foomain(int argc, char **argv) {
|
|||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
#pragma omp for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
|
@ -138,7 +138,7 @@ int foomain(int argc, char **argv) {
|
|||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel private(i) // expected-note {{defined as private}}
|
||||
|
@ -155,8 +155,8 @@ int foomain(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note 2 {{'g' defined here}}
|
||||
S3 m;
|
||||
S6 n(2);
|
||||
int i;
|
||||
|
@ -194,7 +194,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'const S3'}}
|
||||
#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
|
@ -235,7 +235,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
|
@ -263,7 +263,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
|
@ -291,4 +291,3 @@ int main(int argc, char **argv) {
|
|||
|
||||
return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -27,22 +27,22 @@ class S3 {
|
|||
|
||||
public:
|
||||
S3() : a(0) {}
|
||||
S3(const S3 &s3) : a(s3.a) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note 2 {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note 4 {{'S5' declared here}}
|
||||
int a;
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5() : a(0) {}
|
||||
|
@ -62,8 +62,8 @@ S3 h;
|
|||
|
||||
template <class I, class C>
|
||||
int foomain(int argc, char **argv) {
|
||||
I e(4);
|
||||
C g(5);
|
||||
I e(4); // expected-note {{'e' defined here}}
|
||||
C g(5); // expected-note 2 {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel
|
||||
|
@ -99,7 +99,7 @@ int foomain(int argc, char **argv) {
|
|||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
#pragma omp for simd firstprivate(a, b) // expected-error {{a firstprivate variable with incomplete type 'S1'}}
|
||||
#pragma omp for simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
|
@ -107,7 +107,7 @@ int foomain(int argc, char **argv) {
|
|||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
#pragma omp for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for simd firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
|
@ -138,7 +138,7 @@ int foomain(int argc, char **argv) {
|
|||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel
|
||||
#pragma omp for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for simd lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel private(i) // expected-note {{defined as private}}
|
||||
|
@ -155,8 +155,8 @@ int foomain(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note 2 {{'g' defined here}}
|
||||
S3 m;
|
||||
S6 n(2);
|
||||
int i;
|
||||
|
@ -235,7 +235,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for simd firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
|
@ -263,7 +263,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp for simd lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
|
|
|
@ -39,7 +39,7 @@ int main (int argc, char **argv) {
|
|||
// CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0
|
||||
// CHECK-NEXT: store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]]
|
||||
// CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8*
|
||||
// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @.omp_outlined. to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @__captured_stmt to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-NEXT: [[ARGV:%.+]] = load i8*** {{%[a-z0-9.]+}}
|
||||
// CHECK-NEXT: [[RET:%.+]] = call {{[a-z]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
|
||||
// CHECK-NEXT: ret i32 [[RET]]
|
||||
|
@ -55,13 +55,13 @@ int main (int argc, char **argv) {
|
|||
// CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t* [[LOC_2_ADDR]], i32 0, i32 4
|
||||
// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8]* [[LOC1]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]]
|
||||
// CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8*
|
||||
// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @.omp_outlined. to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @__captured_stmt to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-DEBUG-NEXT: [[ARGV:%.+]] = load i8*** {{%[a-z0-9.]+}}
|
||||
// CHECK-DEBUG-NEXT: [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
|
||||
// CHECK-DEBUG-NEXT: ret i32 [[RET]]
|
||||
// CHECK-DEBUG-NEXT: }
|
||||
|
||||
// CHECK-LABEL: define internal void @.omp_outlined.(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context)
|
||||
// CHECK-LABEL: define internal void @__captured_stmt(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context)
|
||||
// CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon*
|
||||
// CHECK: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]]
|
||||
// CHECK: [[CONTEXT_PTR:%.+]] = load %struct.anon** [[CONTEXT_ADDR]]
|
||||
|
@ -73,7 +73,7 @@ int main (int argc, char **argv) {
|
|||
// CHECK: call void @{{.+terminate.*}}(
|
||||
// CHECK-NEXT: unreachable
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-DEBUG-LABEL: define internal void @.omp_outlined.(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context)
|
||||
// CHECK-DEBUG-LABEL: define internal void @__captured_stmt(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context)
|
||||
// CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon*
|
||||
// CHECK-DEBUG: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]]
|
||||
// CHECK-DEBUG: [[CONTEXT_PTR:%.+]] = load %struct.anon** [[CONTEXT_ADDR]]
|
||||
|
@ -96,7 +96,7 @@ int main (int argc, char **argv) {
|
|||
// CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0
|
||||
// CHECK-NEXT: store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]]
|
||||
// CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8*
|
||||
// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @.omp_outlined.1 to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @__captured_stmt1 to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-NEXT: ret i32 0
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-DEBUG: define linkonce_odr i32 [[TMAIN]](i8** %argc)
|
||||
|
@ -110,11 +110,11 @@ int main (int argc, char **argv) {
|
|||
// CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t* [[LOC_2_ADDR]], i32 0, i32 4
|
||||
// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8]* [[LOC2]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]]
|
||||
// CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8*
|
||||
// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @.omp_outlined.1 to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @__captured_stmt1 to void (i32*, i32*, ...)*), i8* [[BITCAST]])
|
||||
// CHECK-DEBUG-NEXT: ret i32 0
|
||||
// CHECK-DEBUG-NEXT: }
|
||||
|
||||
// CHECK-LABEL: define internal void @.omp_outlined.1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context)
|
||||
// CHECK-LABEL: define internal void @__captured_stmt1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context)
|
||||
// CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0*
|
||||
// CHECK: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]]
|
||||
// CHECK: [[CONTEXT_PTR:%.+]] = load %struct.anon.0** [[CONTEXT_ADDR]]
|
||||
|
@ -126,7 +126,7 @@ int main (int argc, char **argv) {
|
|||
// CHECK: call void @{{.+terminate.*}}(
|
||||
// CHECK-NEXT: unreachable
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-DEBUG-LABEL: define internal void @.omp_outlined.1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context)
|
||||
// CHECK-DEBUG-LABEL: define internal void @__captured_stmt1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context)
|
||||
// CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0*
|
||||
// CHECK-DEBUG: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]]
|
||||
// CHECK-DEBUG: [[CONTEXT_PTR:%.+]] = load %struct.anon.0** [[CONTEXT_ADDR]]
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
struct St {
|
||||
int a, b;
|
||||
St() : a(0), b(0) {}
|
||||
St(const St &st) : a(st.a + st.b), b(0) {}
|
||||
~St() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct S {
|
||||
T f;
|
||||
S(T a) : f(a) {}
|
||||
S() : f() {}
|
||||
S(const S &s, St t = St()) : f(s.f + t.a) {}
|
||||
operator T() { return T(); }
|
||||
~S() {}
|
||||
};
|
||||
|
||||
// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
|
||||
// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
|
||||
// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
|
||||
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* }
|
||||
// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
|
||||
// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
|
||||
|
||||
template <typename T>
|
||||
T tmain() {
|
||||
S<T> test;
|
||||
T t_var = T();
|
||||
T vec[] = {1, 2};
|
||||
S<T> s_arr[] = {1, 2};
|
||||
S<T> var(3);
|
||||
#pragma omp parallel firstprivate(t_var, vec, s_arr, var)
|
||||
{
|
||||
vec[0] = t_var;
|
||||
s_arr[0] = var;
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
int main() {
|
||||
S<float> test;
|
||||
int t_var = 0;
|
||||
int vec[] = {1, 2};
|
||||
S<float> s_arr[] = {1, 2};
|
||||
S<float> var(3);
|
||||
#pragma omp parallel firstprivate(t_var, vec, s_arr, var)
|
||||
{
|
||||
vec[0] = t_var;
|
||||
s_arr[0] = var;
|
||||
}
|
||||
return tmain<int>();
|
||||
}
|
||||
|
||||
// CHECK: define i{{[0-9]+}} @main()
|
||||
// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
|
||||
// CHECK: call void [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
|
||||
// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]*
|
||||
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void
|
||||
// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
|
||||
// CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
|
||||
// CHECK: ret
|
||||
//
|
||||
// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}})
|
||||
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
|
||||
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
|
||||
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
|
||||
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
|
||||
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_ADDR]]
|
||||
// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
|
||||
// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}** [[T_VAR_PTR_REF]],
|
||||
// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}* [[T_VAR_REF]],
|
||||
// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
|
||||
// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
|
||||
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]],
|
||||
// CHECK: br label %[[VEC_PRIV_INIT:.+]]
|
||||
// CHECK: [[VEC_PRIV_INIT]]:
|
||||
// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
|
||||
// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]],
|
||||
// CHECK: br label %[[VEC_PRIV_INIT_END:.+]]
|
||||
// CHECK: [[VEC_PRIV_INIT_END]]:
|
||||
// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
|
||||
// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]** [[S_ARR_REF_PTR]],
|
||||
// CHECK: br label %[[S_ARR_PRIV_INIT:.+]]
|
||||
// CHECK: [[S_ARR_PRIV_INIT:.+]]:
|
||||
// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
|
||||
// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
|
||||
// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
|
||||
// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2
|
||||
// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]]
|
||||
// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]]
|
||||
// CHECK: [[S_ARR_BODY]]:
|
||||
// CHECK: call void [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
|
||||
// CHECK: call void [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: call void [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]]
|
||||
// CHECK: br label %[[S_ARR_PRIV_INIT_END:.+]]
|
||||
// CHECK: [[S_ARR_PRIV_INIT_END]]:
|
||||
// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
|
||||
// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]** [[VAR_REF_PTR]],
|
||||
// CHECK: call void [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
|
||||
// CHECK: call void [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: call void [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
|
||||
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
|
||||
// CHECK: call void [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
|
||||
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
|
||||
// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
|
||||
// CHECK: ret
|
||||
//
|
||||
// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}})
|
||||
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
|
||||
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
|
||||
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
|
||||
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
|
||||
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_ADDR]]
|
||||
// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
|
||||
// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}** [[T_VAR_PTR_REF]],
|
||||
// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}* [[T_VAR_REF]],
|
||||
// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
|
||||
// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
|
||||
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]],
|
||||
// CHECK: br label %[[VEC_PRIV_INIT:.+]]
|
||||
// CHECK: [[VEC_PRIV_INIT]]:
|
||||
// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
|
||||
// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]],
|
||||
// CHECK: br label %[[VEC_PRIV_INIT_END:.+]]
|
||||
// CHECK: [[VEC_PRIV_INIT_END]]:
|
||||
// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
|
||||
// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]** [[S_ARR_REF_PTR]],
|
||||
// CHECK: br label %[[S_ARR_PRIV_INIT:.+]]
|
||||
// CHECK: [[S_ARR_PRIV_INIT:.+]]:
|
||||
// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
|
||||
// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
|
||||
// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2
|
||||
// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2
|
||||
// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]]
|
||||
// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]]
|
||||
// CHECK: [[S_ARR_BODY]]:
|
||||
// CHECK: call void [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
|
||||
// CHECK: call void [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: call void [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]]
|
||||
// CHECK: br label %[[S_ARR_PRIV_INIT_END:.+]]
|
||||
// CHECK: [[S_ARR_PRIV_INIT_END]]:
|
||||
// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
|
||||
// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]** [[VAR_REF_PTR]],
|
||||
// CHECK: call void [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
|
||||
// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: call void [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]*
|
||||
// CHECK: ret void
|
||||
#endif
|
||||
|
|
@ -13,7 +13,7 @@ class S2 {
|
|||
mutable int a;
|
||||
public:
|
||||
S2():a(0) { }
|
||||
S2(const S2 &s2):a(s2.a) { }
|
||||
S2(S2 &s2):a(s2.a) { }
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -24,22 +24,22 @@ class S3 {
|
|||
int a;
|
||||
public:
|
||||
S3():a(0) { }
|
||||
S3(const S3 &s3):a(s3.a) { }
|
||||
S3(S3 &s3):a(s3.a) { }
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
public:
|
||||
S4(int v):a(v) { }
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note {{'S5' declared here}}
|
||||
int a;
|
||||
S5():a(0) {}
|
||||
S5(const S5 &s5):a(s5.a) { } // expected-note {{implicitly declared private here}}
|
||||
S5(const S5 &s5):a(s5.a) { }
|
||||
public:
|
||||
S5(int v):a(v) { }
|
||||
};
|
||||
|
@ -50,8 +50,8 @@ S3 h;
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = { 0 };
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel firstprivate // expected-error {{expected '(' after 'firstprivate'}}
|
||||
|
@ -69,7 +69,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp parallel firstprivate(da)
|
||||
#pragma omp parallel firstprivate(S2::S2s)
|
||||
#pragma omp parallel firstprivate(S2::S2sc)
|
||||
#pragma omp parallel firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp parallel firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
|
||||
#pragma omp parallel private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}}
|
||||
foo();
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -27,22 +27,22 @@ class S3 {
|
|||
|
||||
public:
|
||||
S3() : a(0) {}
|
||||
S3(const S3 &s3) : a(s3.a) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note 2 {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note 4 {{'S5' declared here}}
|
||||
int a;
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5() : a(0) {}
|
||||
|
@ -62,8 +62,8 @@ S3 h;
|
|||
|
||||
template <class I, class C>
|
||||
int foomain(int argc, char **argv) {
|
||||
I e(4);
|
||||
C g(5);
|
||||
I e(4); // expected-note {{'e' defined here}}
|
||||
C g(5); // expected-note 2 {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
|
||||
|
@ -96,7 +96,7 @@ int foomain(int argc, char **argv) {
|
|||
#pragma omp parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
|
||||
|
@ -123,7 +123,7 @@ int foomain(int argc, char **argv) {
|
|||
#pragma omp parallel for firstprivate(i)
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel private(i)
|
||||
|
@ -140,8 +140,8 @@ int foomain(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note 2 {{'g' defined here}}
|
||||
S3 m;
|
||||
S6 n(2);
|
||||
int i;
|
||||
|
@ -201,7 +201,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for firstprivate(m) // OK
|
||||
|
@ -223,7 +223,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for lastprivate(n) firstprivate(n) // OK
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -27,22 +27,22 @@ class S3 {
|
|||
|
||||
public:
|
||||
S3() : a(0) {}
|
||||
S3(const S3 &s3) : a(s3.a) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note 2 {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note 4 {{'S5' declared here}}
|
||||
int a;
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5() : a(0) {}
|
||||
|
@ -62,8 +62,8 @@ S3 h;
|
|||
|
||||
template <class I, class C>
|
||||
int foomain(int argc, char **argv) {
|
||||
I e(4);
|
||||
C g(5);
|
||||
I e(4); // expected-note {{'e' defined here}}
|
||||
C g(5); // expected-note 2 {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
|
||||
|
@ -96,7 +96,7 @@ int foomain(int argc, char **argv) {
|
|||
#pragma omp parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}}
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for simd firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
|
||||
|
@ -122,7 +122,7 @@ int foomain(int argc, char **argv) {
|
|||
#pragma omp parallel for simd firstprivate(i)
|
||||
for (int k = 0; k < argc; ++k)
|
||||
++k;
|
||||
#pragma omp parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for simd lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel private(i)
|
||||
|
@ -139,8 +139,8 @@ int foomain(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note 2 {{'g' defined here}}
|
||||
S3 m;
|
||||
S6 n(2);
|
||||
int i;
|
||||
|
@ -200,7 +200,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp parallel for simd safelen(5)
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for simd firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for simd firstprivate(m) // OK
|
||||
|
@ -221,7 +221,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp parallel for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel for simd lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
for (i = 0; i < argc; ++i)
|
||||
foo();
|
||||
#pragma omp parallel for simd lastprivate(n) firstprivate(n) // OK
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -27,22 +27,22 @@ class S3 {
|
|||
|
||||
public:
|
||||
S3() : a(0) {}
|
||||
S3(const S3 &s3) : a(s3.a) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note 2 {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note 4 {{'S5' declared here}}
|
||||
int a;
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5() : a(0) {}
|
||||
|
@ -62,8 +62,8 @@ S3 h;
|
|||
|
||||
template <class I, class C>
|
||||
int foomain(int argc, char **argv) {
|
||||
I e(4);
|
||||
C g(5);
|
||||
I e(4); // expected-note {{'e' defined here}}
|
||||
C g(5); // expected-note 2 {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
|
||||
|
@ -106,7 +106,7 @@ int foomain(int argc, char **argv) {
|
|||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ int foomain(int argc, char **argv) {
|
|||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
@ -158,8 +158,8 @@ int foomain(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note 2 {{'g' defined here}}
|
||||
S3 m;
|
||||
S6 n(2);
|
||||
int i;
|
||||
|
@ -237,7 +237,7 @@ int main(int argc, char **argv) {
|
|||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ int main(int argc, char **argv) {
|
|||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -27,22 +27,22 @@ class S3 {
|
|||
|
||||
public:
|
||||
S3() : a(0) {}
|
||||
S3(const S3 &s3) : a(s3.a) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note 2 {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note 4 {{'S5' declared here}}
|
||||
int a;
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5() : a(0) {}
|
||||
|
@ -62,8 +62,8 @@ S3 h;
|
|||
|
||||
template <class I, class C>
|
||||
int foomain(int argc, char **argv) {
|
||||
I e(4);
|
||||
C g(5);
|
||||
I e(4); // expected-note {{'e' defined here}}
|
||||
C g(5); // expected-note 2 {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel
|
||||
|
@ -117,7 +117,7 @@ int foomain(int argc, char **argv) {
|
|||
foo();
|
||||
}
|
||||
#pragma omp parallel
|
||||
#pragma omp sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ int foomain(int argc, char **argv) {
|
|||
foo();
|
||||
}
|
||||
#pragma omp parallel
|
||||
#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
@ -173,8 +173,8 @@ int foomain(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note 2 {{'g' defined here}}
|
||||
S3 m;
|
||||
S6 n(2);
|
||||
int i;
|
||||
|
@ -271,7 +271,7 @@ int main(int argc, char **argv) {
|
|||
foo();
|
||||
}
|
||||
#pragma omp parallel
|
||||
#pragma omp sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ int main(int argc, char **argv) {
|
|||
foo();
|
||||
}
|
||||
#pragma omp parallel
|
||||
#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -27,22 +27,22 @@ class S3 {
|
|||
|
||||
public:
|
||||
S3() : a(0) {}
|
||||
S3(const S3 &s3) : a(s3.a) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note 2 {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note 4 {{'S5' declared here}}
|
||||
int a;
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5() : a(0) {}
|
||||
|
@ -62,8 +62,8 @@ S3 h;
|
|||
|
||||
template <class I, class C>
|
||||
int foomain(int argc, char **argv) {
|
||||
I e(4);
|
||||
C g(5);
|
||||
I e(4); // expected-note {{'e' defined here}}
|
||||
C g(5); // expected-note 2 {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp parallel
|
||||
|
@ -97,7 +97,7 @@ int foomain(int argc, char **argv) {
|
|||
#pragma omp single firstprivate(argv[1]) // expected-error {{expected variable name}}
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp single firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp single firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
|
||||
|
@ -121,7 +121,7 @@ int foomain(int argc, char **argv) {
|
|||
#pragma omp single firstprivate(i)
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp single firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
foo();
|
||||
#pragma omp parallel private(i) // expected-note {{defined as private}}
|
||||
#pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}}
|
||||
|
@ -135,8 +135,8 @@ int foomain(int argc, char **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note 2 {{'g' defined here}}
|
||||
S3 m;
|
||||
S6 n(2);
|
||||
int i;
|
||||
|
@ -197,7 +197,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp single safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp single'}}
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp single firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp single firstprivate(m) // OK
|
||||
|
@ -215,7 +215,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp single firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp single firstprivate(n) // OK
|
||||
|
|
|
@ -14,7 +14,7 @@ class S2 {
|
|||
|
||||
public:
|
||||
S2() : a(0) {}
|
||||
S2(const S2 &s2) : a(s2.a) {}
|
||||
S2(S2 &s2) : a(s2.a) {}
|
||||
static float S2s;
|
||||
static const float S2sc;
|
||||
};
|
||||
|
@ -26,23 +26,23 @@ class S3 {
|
|||
|
||||
public:
|
||||
S3() : a(0) {}
|
||||
S3(const S3 &s3) : a(s3.a) {}
|
||||
S3(S3 &s3) : a(s3.a) {}
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
class S4 { // expected-note {{'S4' declared here}}
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
|
||||
S4(const S4 &s4);
|
||||
|
||||
public:
|
||||
S4(int v) : a(v) {}
|
||||
};
|
||||
class S5 {
|
||||
class S5 { // expected-note {{'S5' declared here}}
|
||||
int a;
|
||||
S5() : a(0) {}
|
||||
S5(const S5 &s5) : a(s5.a) {} // expected-note 2 {{implicitly declared private here}}
|
||||
S5(const S5 &s5) : a(s5.a) {}
|
||||
|
||||
public:
|
||||
S5(int v) : a(v) {}
|
||||
|
@ -54,8 +54,8 @@ S3 h;
|
|||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = {0};
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
S4 e(4); // expected-note {{'e' defined here}}
|
||||
S5 g(5); // expected-note {{'g' defined here}}
|
||||
int i;
|
||||
int &j = i; // expected-note {{'j' defined here}}
|
||||
#pragma omp task firstprivate // expected-error {{expected '(' after 'firstprivate'}}
|
||||
|
@ -73,7 +73,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp task firstprivate(da)
|
||||
#pragma omp task firstprivate(S2::S2s)
|
||||
#pragma omp task firstprivate(S2::S2sc)
|
||||
#pragma omp task firstprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} expected-error 2 {{calling a private constructor of class 'S5'}}
|
||||
#pragma omp task firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp task firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
|
||||
#pragma omp task private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}}
|
||||
foo();
|
||||
|
|
|
@ -5,8 +5,8 @@ void foo() {
|
|||
|
||||
#pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}}
|
||||
|
||||
class S {
|
||||
S(const S &s) { a = s.a + 12; } // expected-note 6 {{implicitly declared private here}}
|
||||
class S { // expected-note 6 {{'S' declared here}}
|
||||
S(const S &s) { a = s.a + 12; }
|
||||
int a;
|
||||
|
||||
public:
|
||||
|
@ -17,35 +17,23 @@ public:
|
|||
S operator+(const S &) { return *this; }
|
||||
};
|
||||
|
||||
class S1 {
|
||||
int a;
|
||||
|
||||
public:
|
||||
S1() : a(0) {}
|
||||
S1 &operator++() { return *this; }
|
||||
S1(const S1 &) = delete; // expected-note 2 {{'S1' has been explicitly marked deleted here}}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
int foo() {
|
||||
T a;
|
||||
T a; // expected-note 3 {{'a' defined here}}
|
||||
T &b = a; // expected-note 4 {{'b' defined here}}
|
||||
int r;
|
||||
S1 s1;
|
||||
// expected-error@+1 2 {{call to deleted constructor of 'S1'}}
|
||||
#pragma omp task
|
||||
// expected-note@+1 2 {{predetermined as a firstprivate in a task construct here}}
|
||||
++s1;
|
||||
#pragma omp task default(none)
|
||||
#pragma omp task default(shared)
|
||||
++a;
|
||||
// expected-error@+2 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp task default(none)
|
||||
#pragma omp task
|
||||
// expected-error@+1 {{calling a private constructor of class 'S'}}
|
||||
// expected-note@+1 {{used here}}
|
||||
++a;
|
||||
#pragma omp task
|
||||
// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp task
|
||||
// expected-error@+1 {{calling a private constructor of class 'S'}}
|
||||
// expected-note@+1 {{used here}}
|
||||
++a;
|
||||
#pragma omp task default(shared)
|
||||
#pragma omp task
|
||||
|
@ -58,11 +46,11 @@ int foo() {
|
|||
#pragma omp task
|
||||
// expected-note@+1 2 {{used here}}
|
||||
++b;
|
||||
// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
|
||||
// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
|
||||
// expected-error@+3 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
|
||||
// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
|
||||
// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp task
|
||||
// expected-error@+2 {{calling a private constructor of class 'S'}}
|
||||
// expected-note@+1 2 {{used here}}
|
||||
// expected-note@+1 3 {{used here}}
|
||||
#pragma omp parallel shared(a, b)
|
||||
++a, ++b;
|
||||
// expected-note@+1 3 {{defined as reduction}}
|
||||
|
@ -121,7 +109,7 @@ int foo() {
|
|||
int main(int argc, char **argv) {
|
||||
int a;
|
||||
int &b = a; // expected-note 2 {{'b' defined here}}
|
||||
S sa;
|
||||
S sa; // expected-note 3 {{'sa' defined here}}
|
||||
S &sb = sa; // expected-note 2 {{'sb' defined here}}
|
||||
int r;
|
||||
#pragma omp task { // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
|
||||
|
@ -205,12 +193,14 @@ L2:
|
|||
#pragma omp task default(shared)
|
||||
++sa;
|
||||
#pragma omp task default(none)
|
||||
// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp task
|
||||
// expected-error@+1 {{calling a private constructor of class 'S'}}
|
||||
// expected-note@+1 {{used here}}
|
||||
++sa;
|
||||
#pragma omp task
|
||||
// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp task
|
||||
// expected-error@+1 {{calling a private constructor of class 'S'}}
|
||||
// expected-note@+1 {{used here}}
|
||||
++sa;
|
||||
#pragma omp task default(shared)
|
||||
#pragma omp task
|
||||
|
@ -222,10 +212,10 @@ L2:
|
|||
#pragma omp task
|
||||
// expected-note@+1 {{used here}}
|
||||
++sb;
|
||||
// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
|
||||
// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
|
||||
// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
|
||||
#pragma omp task
|
||||
// expected-error@+2 {{calling a private constructor of class 'S'}}
|
||||
// expected-note@+1 {{used here}}
|
||||
// expected-note@+1 2 {{used here}}
|
||||
#pragma omp parallel shared(sa, sb)
|
||||
++sa, ++sb;
|
||||
// expected-note@+1 2 {{defined as reduction}}
|
||||
|
|
Loading…
Reference in New Issue