Index: include/clang/AST/OpenMPClause.h =================================================================== --- include/clang/AST/OpenMPClause.h +++ include/clang/AST/OpenMPClause.h @@ -18,7 +18,6 @@ #include "clang/AST/Expr.h" #include "clang/AST/Stmt.h" -#include "clang/AST/PrettyPrinter.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/SourceLocation.h" @@ -128,7 +127,6 @@ varlist_iterator varlist_end() { return getVarRefs().end(); } varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); } varlist_const_iterator varlist_end() const { return getVarRefs().end(); } - unsigned numberOfVariables() const { return NumVars; } /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } Index: include/clang/AST/StmtOpenMP.h =================================================================== --- include/clang/AST/StmtOpenMP.h +++ include/clang/AST/StmtOpenMP.h @@ -1817,17 +1817,18 @@ /// OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) - : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, - OMPD_target_data, StartLoc, EndLoc, NumClauses, 1) {} + : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, + OMPD_target_data, StartLoc, EndLoc, NumClauses, + 1) {} /// \brief Build an empty directive. /// /// \param N Number of clauses. /// explicit OMPTargetDataDirective(unsigned NumClauses) - : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, - OMPD_target_data, SourceLocation(), - SourceLocation(), NumClauses, 1) {} + : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, + OMPD_target_data, SourceLocation(), + SourceLocation(), NumClauses, 1) {} public: /// \brief Creates directive with a list of \a Clauses. Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -7763,8 +7763,8 @@ /// \brief Called on well-formed '\#pragma omp target data' after parsing of /// the associated statement. StmtResult ActOnOpenMPTargetDataDirective(ArrayRef Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); /// \brief Called on well-formed '\#pragma omp teams' after parsing of the /// associated statement. StmtResult ActOnOpenMPTeamsDirective(ArrayRef Clauses, Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1958,10 +1958,9 @@ else return EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD), CapturedStmtInfo->getContextValue()); - } - assert(isa(CurCodeDecl)); - return MakeAddrLValue(GetAddrOfBlockDecl(VD, VD->hasAttr()), - T, Alignment); + } else if (isa(CurCodeDecl)) + return MakeAddrLValue(GetAddrOfBlockDecl(VD, VD->hasAttr()), + T, Alignment); } } Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -237,12 +237,12 @@ case Stmt::OMPTargetDirectiveClass: EmitOMPTargetDirective(cast(*S)); break; - case Stmt::OMPTargetDataDirectiveClass: - EmitOMPTargetDataDirective(cast(*S)); - break; case Stmt::OMPTeamsDirectiveClass: EmitOMPTeamsDirective(cast(*S)); break; + case Stmt::OMPTargetDataDirectiveClass: + EmitOMPTargetDataDirective(cast(*S)); + break; } } Index: lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -2094,12 +2094,44 @@ llvm_unreachable("CodeGen for 'omp target' is not supported yet."); } +void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) { + llvm_unreachable("CodeGen for 'omp teams' is not supported yet."); +} + +void CodeGenFunction::EmitOMPIfClause(const Expr *IfCond) { + auto ThenBlock = createBasicBlock("omp.if.then"); + auto ElseBlock = createBasicBlock("omp.if.else"); + auto ContBlock = createBasicBlock("omp.if.end"); + + EmitBranchOnBoolExpr(IfCond, ThenBlock, ElseBlock, 0); + + // generate the else block + EmitBlock(ElseBlock); + EmitBranch(ContBlock); + + // generate the then block + EmitBlock(ThenBlock); + EmitBranch(ContBlock); + + EmitBlock(ContBlock); +} + // Generate the instructions for '#pragma omp target data' directive. void CodeGenFunction::EmitOMPTargetDataDirective( - const OMPTargetDataDirective &S) { - llvm_unreachable("CodeGen for 'omp target data' is not supported yet."); -} + const OMPTargetDataDirective &S) { -void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) { - llvm_unreachable("CodeGen for 'omp teams' is not supported yet."); + // if clause condition + const Expr *IfCond = nullptr; + if (auto C = S.getSingleClause(OMPC_if)) { + IfCond = cast(C)->getCondition(); + } + + if (IfCond) + EmitOMPIfClause(IfCond); + + auto *CS = cast(S.getAssociatedStmt())->getCapturedStmt(); + EmitStmt(CS); + + if (IfCond) + EmitOMPIfClause(IfCond); } Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2200,6 +2200,7 @@ void EmitOMPTargetDirective(const OMPTargetDirective &S); void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S); void EmitOMPTeamsDirective(const OMPTeamsDirective &S); + void EmitOMPIfClause(const Expr *Cond); /// \brief Emit inner loop of the worksharing/simd construct. /// Index: lib/Parse/ParseOpenMP.cpp =================================================================== --- lib/Parse/ParseOpenMP.cpp +++ lib/Parse/ParseOpenMP.cpp @@ -19,6 +19,7 @@ #include "clang/Parse/Parser.h" #include "clang/Sema/Scope.h" #include "llvm/ADT/PointerIntPair.h" + using namespace clang; //===----------------------------------------------------------------------===// @@ -29,11 +30,12 @@ // Array of foldings: F[i][0] F[i][1] ===> F[i][2]. // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd // TODO: add other combined directives in topological order. - const OpenMPDirectiveKind F[][3] = { + const OpenMPDirectiveKind F[][4] = { { OMPD_for, OMPD_simd, OMPD_for_simd }, { OMPD_parallel, OMPD_for, OMPD_parallel_for }, { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd }, - { OMPD_parallel, OMPD_sections, OMPD_parallel_sections } + { OMPD_parallel, OMPD_sections, OMPD_parallel_sections }, + { OMPD_target, OMPD_unknown, OMPD_target_data } }; auto Tok = P.getCurToken(); auto DKind = @@ -41,18 +43,6 @@ ? OMPD_unknown : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok)); - switch (DKind) { - case OMPD_target: { - auto SavedToken = P.getPreprocessor().LookAhead(0); - if (!SavedToken.isAnnotation()) { - if (P.getPreprocessor().getSpelling(SavedToken) == "data") { - DKind = OMPD_target_data; - P.ConsumeToken(); - } - } - break; - } - default: for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) { if (DKind == F[i][0]) { Tok = P.getPreprocessor().LookAhead(0); @@ -61,12 +51,16 @@ ? OMPD_unknown : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok)); if (SDKind == F[i][1]) { - P.ConsumeToken(); - DKind = F[i][2]; + auto IsTargetData = (Tok.isNot(tok::annot_pragma_openmp_end) && + DKind == OMPD_target && + P.getPreprocessor().getSpelling(Tok) == "data"); + if ((DKind != OMPD_target) || IsTargetData) { + P.ConsumeToken(); + DKind = F[i][2]; + } } } } - } return DKind; }