r205164 - [OPENMP] Implemented 'copyin' clause
Alexey Bataev
a.bataev at hotmail.com
Sun Mar 30 20:36:39 PDT 2014
Author: abataev
Date: Sun Mar 30 22:36:38 2014
New Revision: 205164
URL: http://llvm.org/viewvc/llvm-project?rev=205164&view=rev
Log:
[OPENMP] Implemented 'copyin' clause
Added:
cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp (with props)
Modified:
cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
cfe/trunk/include/clang/AST/OpenMPClause.h
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/OpenMPKinds.def
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Stmt.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/AST/StmtProfile.cpp
cfe/trunk/lib/Basic/OpenMPKinds.cpp
cfe/trunk/lib/Parse/ParseOpenMP.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/test/OpenMP/parallel_ast_print.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Sun Mar 30 22:36:38 2014
@@ -2405,6 +2405,12 @@ bool DataRecursiveASTVisitor<Derived>::V
return true;
}
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Sun Mar 30 22:36:38 2014
@@ -95,7 +95,7 @@ protected:
llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())));
}
- /// \brief Build clause with number of variables \a N.
+ /// \brief Build a clause with \a N variables
///
/// \param K Kind of the clause.
/// \param StartLoc Starting location of the clause (the clause keyword).
@@ -553,6 +553,65 @@ public:
}
};
+/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel copyin(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'copyin'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPCopyinClause(unsigned N)
+ : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \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 variables.
+ ///
+ static OMPCopyinClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_copyin;
+ }
+};
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Sun Mar 30 22:36:38 2014
@@ -2442,6 +2442,12 @@ bool RecursiveASTVisitor<Derived>::Visit
return true;
}
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Mar 30 22:36:38 2014
@@ -6915,6 +6915,8 @@ def note_omp_conversion_here : Note<
def err_omp_ambiguous_conversion : Error<
"ambiguous conversion from type %0 to an integral or unscoped "
"enumeration type">;
+def err_omp_required_access : Error<
+ "%0 variable must be %1">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Sun Mar 30 22:36:38 2014
@@ -42,6 +42,7 @@ OPENMP_CLAUSE(default, OMPDefaultClause)
OPENMP_CLAUSE(private, OMPPrivateClause)
OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
OPENMP_CLAUSE(shared, OMPSharedClause)
+OPENMP_CLAUSE(copyin, OMPCopyinClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -50,6 +51,7 @@ OPENMP_PARALLEL_CLAUSE(default)
OPENMP_PARALLEL_CLAUSE(private)
OPENMP_PARALLEL_CLAUSE(firstprivate)
OPENMP_PARALLEL_CLAUSE(shared)
+OPENMP_PARALLEL_CLAUSE(copyin)
// FIXME: more clauses allowed for directive 'omp simd'.
OPENMP_SIMD_CLAUSE(private)
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Mar 30 22:36:38 2014
@@ -7210,6 +7210,11 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'copyin' clause.
+ OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// \brief The kind of conversion being performed.
enum CheckedConversionKind {
Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Sun Mar 30 22:36:38 2014
@@ -1192,6 +1192,28 @@ OMPSharedClause *OMPSharedClause::Create
return new (Mem) OMPSharedClause(N);
}
+OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPCopyinClause *Clause = new (Mem) OMPCopyinClause(StartLoc, LParenLoc,
+ EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPCopyinClause(N);
+}
+
void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
assert(Clauses.size() == getNumClauses() &&
"Number of clauses is not the same as the preallocated buffer");
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Sun Mar 30 22:36:38 2014
@@ -629,9 +629,15 @@ template<typename T>
void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
for (typename T::varlist_iterator I = Node->varlist_begin(),
E = Node->varlist_end();
- I != E; ++I)
- OS << (I == Node->varlist_begin() ? StartSym : ',')
- << *cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl());
+ I != E; ++I) {
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) {
+ OS << (I == Node->varlist_begin() ? StartSym : ',');
+ cast<NamedDecl>(DRE->getDecl())->printQualifiedName(OS);
+ } else {
+ OS << (I == Node->varlist_begin() ? StartSym : ',');
+ (*I)->printPretty(OS, 0, Policy, 0);
+ }
+ }
}
void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
@@ -656,6 +662,14 @@ void OMPClausePrinter::VisitOMPSharedCla
VisitOMPClauseList(Node, '(');
OS << ")";
}
+}
+
+void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "copyin";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
}
}
Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Sun Mar 30 22:36:38 2014
@@ -297,6 +297,9 @@ void OMPClauseProfiler::VisitOMPFirstpri
void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+}
}
void
Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Sun Mar 30 22:36:38 2014
@@ -83,6 +83,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
+ case OMPC_copyin:
case NUM_OPENMP_CLAUSES:
break;
}
@@ -109,6 +110,7 @@ const char *clang::getOpenMPSimpleClause
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
+ case OMPC_copyin:
case NUM_OPENMP_CLAUSES:
break;
}
Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Sun Mar 30 22:36:38 2014
@@ -301,6 +301,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
+ case OMPC_copyin:
Clause = ParseOpenMPVarListClause(CKind);
break;
case OMPC_unknown:
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Sun Mar 30 22:36:38 2014
@@ -111,7 +111,6 @@ public:
DSAVarData hasDSA(VarDecl *D, OpenMPClauseKind CKind,
OpenMPDirectiveKind DKind = OMPD_unknown);
-
/// \brief Returns currently analyzed directive.
OpenMPDirectiveKind getCurrentDirective() const {
return Stack.back().Directive;
@@ -126,6 +125,13 @@ public:
return Stack.back().DefaultAttr;
}
+ /// \brief Checks if the spewcified variable is threadprivate.
+ bool isThreadPrivate(VarDecl *D) {
+ DSAVarData DVar = getTopDSA(D);
+ return (DVar.CKind == OMPC_threadprivate || DVar.CKind == OMPC_copyin);
+ }
+
+ Scope *getCurScope() const { return Stack.back().CurScope; }
Scope *getCurScope() { return Stack.back().CurScope; }
};
} // end anonymous namespace.
@@ -245,7 +251,8 @@ void DSAStackTy::addDSA(VarDecl *D, Decl
}
}
-bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
+bool
+DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
if (Stack.size() > 2) {
reverse_iterator I = Iter, E = Stack.rend() - 1;
Scope *TopScope = 0;
@@ -611,7 +618,7 @@ public:
DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD);
if (DVar.CKind != OMPC_unknown) {
if (DKind == OMPD_task && DVar.CKind != OMPC_shared &&
- DVar.CKind != OMPC_threadprivate && !DVar.RefExpr)
+ !Stack->isThreadPrivate(VD) && !DVar.RefExpr)
ImplicitFirstprivate.push_back(DVar.RefExpr);
return;
}
@@ -768,6 +775,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
+ case OMPC_copyin:
case OMPC_threadprivate:
case OMPC_unknown:
case NUM_OPENMP_CLAUSES:
@@ -922,6 +930,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
+ case OMPC_copyin:
case OMPC_threadprivate:
case OMPC_unknown:
case NUM_OPENMP_CLAUSES:
@@ -992,6 +1001,9 @@ OMPClause *Sema::ActOnOpenMPVarListClaus
case OMPC_shared:
Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_copyin:
+ Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_num_threads:
case OMPC_safelen:
@@ -1371,4 +1383,84 @@ OMPClause *Sema::ActOnOpenMPSharedClause
return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
+OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ SmallVector<Expr *, 8> Vars;
+ for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
+ I != E; ++I) {
+ assert(*I && "NULL expr in OpenMP copyin clause.");
+ if (isa<DependentScopeDeclRefExpr>(*I)) {
+ // It will be analyzed later.
+ Vars.push_back(*I);
+ continue;
+ }
+
+ SourceLocation ELoc = (*I)->getExprLoc();
+ // OpenMP [2.1, C/C++]
+ // A list item is a variable name.
+ // OpenMP [2.14.4.1, Restrictions, p.1]
+ // A list item that appears in a copyin clause must be threadprivate.
+ DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I);
+ if (!DE || !isa<VarDecl>(DE->getDecl())) {
+ Diag(ELoc, diag::err_omp_expected_var_name)
+ << (*I)->getSourceRange();
+ continue;
+ }
+
+ Decl *D = DE->getDecl();
+ VarDecl *VD = cast<VarDecl>(D);
+
+ QualType Type = VD->getType();
+ if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+ // It will be analyzed later.
+ Vars.push_back(DE);
+ continue;
+ }
+
+ // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
+ // A list item that appears in a copyin clause must be threadprivate.
+ if (!DSAStack->isThreadPrivate(VD)) {
+ Diag(ELoc, diag::err_omp_required_access)
+ << getOpenMPClauseName(OMPC_copyin)
+ << getOpenMPDirectiveName(OMPD_threadprivate);
+ continue;
+ }
+
+ // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
+ // A variable of class type (or array thereof) that appears in a
+ // copyin clause requires an accesible, unambiguous copy assignment
+ // operator for the class type.
+ Type = Context.getBaseElementType(Type);
+ CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
+ Type->getAsCXXRecordDecl() : 0;
+ if (RD) {
+ CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+ DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+ if (!MD ||
+ CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+ MD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_copyin) << 2;
+ 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, MD);
+ DiagnoseUseOfDecl(MD, ELoc);
+ }
+
+ DSAStack->addDSA(VD, DE, OMPC_copyin);
+ Vars.push_back(DE);
+ }
+
+ if (Vars.empty()) return 0;
+
+ return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
+}
+
#undef DSAStack
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sun Mar 30 22:36:38 2014
@@ -1382,6 +1382,18 @@ public:
EndLoc);
}
+ /// \brief Build a new OpenMP 'copyin' clause.
+ ///
+ /// By default, performs semantic analysis to build the new statement.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc,
+ EndLoc);
+ }
+
/// \brief Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -6420,6 +6432,25 @@ TreeTransform<Derived>::TransformOMPShar
C->getLocStart(),
C->getLParenLoc(),
C->getLocEnd());
+}
+
+template<typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (OMPCopyinClause::varlist_iterator I = C->varlist_begin(),
+ E = C->varlist_end();
+ I != E; ++I) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I));
+ if (EVar.isInvalid())
+ return 0;
+ Vars.push_back(EVar.take());
+ }
+ return getDerived().RebuildOMPCopyinClause(Vars,
+ C->getLocStart(),
+ C->getLParenLoc(),
+ C->getLocEnd());
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sun Mar 30 22:36:38 2014
@@ -1692,6 +1692,9 @@ OMPClause *OMPClauseReader::readClause()
case OMPC_shared:
C = OMPSharedClause::CreateEmpty(Context, Record[Idx++]);
break;
+ case OMPC_copyin:
+ C = OMPCopyinClause::CreateEmpty(Context, Record[Idx++]);
+ break;
}
Visit(C);
C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
@@ -1746,6 +1749,16 @@ void OMPClauseReader::VisitOMPSharedClau
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
unsigned NumVars = C->varlist_size();
SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned i = 0; i != NumVars; ++i)
+ Vars.push_back(Reader->Reader.ReadSubExpr());
+ C->setVarRefs(Vars);
+}
+
+void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) {
+ C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+ unsigned NumVars = C->varlist_size();
+ SmallVector<Expr *, 16> Vars;
Vars.reserve(NumVars);
for (unsigned i = 0; i != NumVars; ++i)
Vars.push_back(Reader->Reader.ReadSubExpr());
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Sun Mar 30 22:36:38 2014
@@ -1716,6 +1716,15 @@ void OMPClauseWriter::VisitOMPSharedClau
Writer->Writer.AddStmt(I);
}
+void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
+ Record.push_back(C->varlist_size());
+ Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+ for (OMPCopyinClause::varlist_iterator I = C->varlist_begin(),
+ E = C->varlist_end();
+ I != E; ++I)
+ Writer->Writer.AddStmt(*I);
+}
+
//===----------------------------------------------------------------------===//
// OpenMP Directives.
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/test/OpenMP/parallel_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_ast_print.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_ast_print.cpp Sun Mar 30 22:36:38 2014
@@ -11,8 +11,23 @@ void foo() {}
template <class T>
struct S {
operator T() {return T();}
+ static T TS;
+ #pragma omp threadprivate(TS)
};
+// CHECK: template <class T = int> struct S {
+// CHECK: static int TS;
+// CHECK-NEXT: #pragma omp threadprivate(S<int>::TS)
+// CHECK-NEXT: }
+// CHECK: template <class T = long> struct S {
+// CHECK: static long TS;
+// CHECK-NEXT: #pragma omp threadprivate(S<long>::TS)
+// CHECK-NEXT: }
+// CHECK: template <class T> struct S {
+// CHECK: static T TS;
+// CHECK-NEXT: #pragma omp threadprivate(S::TS)
+// CHECK: };
+
template <typename T, int C>
T tmain(T argc, T *argv) {
T b = argc, c, d, e, f, g;
@@ -20,19 +35,20 @@ T tmain(T argc, T *argv) {
S<T> s;
#pragma omp parallel
a=2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C)
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C) copyin(S<T>::TS)
foo();
#pragma omp parallel if (C) num_threads(s)
foo();
return 0;
}
+
// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
// CHECK-NEXT: int b = argc, c, d, e, f, g;
// CHECK-NEXT: static int a;
// CHECK-NEXT: S<int> s;
// CHECK-NEXT: #pragma omp parallel
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s)
// CHECK-NEXT: foo()
@@ -42,7 +58,7 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: S<long> s;
// CHECK-NEXT: #pragma omp parallel
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s)
// CHECK-NEXT: foo()
@@ -52,7 +68,7 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: S<T> s;
// CHECK-NEXT: #pragma omp parallel
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s)
// CHECK-NEXT: foo()
@@ -63,14 +79,15 @@ int main (int argc, char **argv) {
long x;
int b = argc, c, d, e, f, g;
static int a;
+ #pragma omp threadprivate(a)
Enum ee;
// CHECK: Enum ee;
#pragma omp parallel
// CHECK-NEXT: #pragma omp parallel
a=2;
// CHECK-NEXT: a = 2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee)
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee)
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a)
foo();
// CHECK-NEXT: foo();
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
Added: cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp?rev=205164&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp Sun Mar 30 22:36:38 2014
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2 & operator =(S2 &s2) { return *this; }
+};
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3 &operator =(S3 &s3) { return *this; }
+};
+class S4 { // expected-note {{'S4' declared here}}
+ int a;
+ S4();
+ S4 &operator =(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 { // expected-note {{'S5' declared here}}
+ int a;
+ S5():a(0) {}
+ S5 &operator =(const S5 &s5) { return *this; }
+public:
+ S5(int v):a(v) { }
+};
+template <class T>
+class ST {
+public:
+ static T s;
+};
+
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note {{'l' defined here}}
+S5 m(4); // expected-note {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp parallel copyin // expected-error {{expected '(' after 'copyin'}}
+ #pragma omp parallel copyin ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp parallel copyin () // expected-error {{expected expression}}
+ #pragma omp parallel copyin (k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp parallel copyin (h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp parallel copyin (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ #pragma omp parallel copyin (l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+ #pragma omp parallel copyin (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp parallel copyin (argv[1]) // expected-error {{expected variable name}}
+ #pragma omp parallel copyin(i) // expected-error {{copyin variable must be threadprivate}}
+ #pragma omp parallel copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+ #pragma omp parallel copyin(ST<int>::s) // expected-error {{copyin variable must be threadprivate}}
+ foo();
+
+ return 0;
+}
Propchange: cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Propchange: cfe/trunk/test/OpenMP/parallel_copyin_messages.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=205164&r1=205163&r2=205164&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Sun Mar 30 22:36:38 2014
@@ -1954,6 +1954,9 @@ void OMPClauseEnqueue::VisitOMPFirstpriv
void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+}
}
void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
More information about the cfe-commits
mailing list