From a889917493e990c314a088c3611523f8cf908eb0 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 6 Aug 2015 12:30:57 +0000 Subject: [OPENMP 4.1] Allow references in init expression for loop-based constructs. OpenMP 4.1 allows to use variables with reference types in private clauses and, therefore, in init expressions of the cannonical loop forms. llvm-svn: 244209 --- clang/lib/Sema/SemaOpenMP.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'clang/lib/Sema/SemaOpenMP.cpp') diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ac2440cacd1..57ebb38a70c 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2251,6 +2251,9 @@ public: Expr *BuildPreCond(Scope *S, Expr *Cond) const; /// \brief Build reference expression to the counter be used for codegen. Expr *BuildCounterVar() const; + /// \brief Build reference expression to the private counter be used for + /// codegen. + Expr *BuildPrivateCounterVar() const; /// \brief Build initization of the counter be used for codegen. Expr *BuildCounterInit() const; /// \brief Build step of the counter be used for codegen. @@ -2414,7 +2417,7 @@ bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { } else if (auto DS = dyn_cast(S)) { if (DS->isSingleDecl()) { if (auto Var = dyn_cast_or_null(DS->getSingleDecl())) { - if (Var->hasInit()) { + if (Var->hasInit() && !Var->getType()->isReferenceType()) { // Accept non-canonical init form here but emit ext. warning. if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) SemaRef.Diag(S->getLocStart(), @@ -2699,7 +2702,19 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { /// \brief Build reference expression to the counter be used for codegen. Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { - return buildDeclRefExpr(SemaRef, Var, Var->getType(), DefaultLoc); + return buildDeclRefExpr(SemaRef, Var, Var->getType().getNonReferenceType(), + DefaultLoc); +} + +Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { + if (Var && !Var->isInvalidDecl()) { + auto Type = Var->getType().getNonReferenceType(); + auto *PrivateVar = buildVarDecl(SemaRef, DefaultLoc, Type, Var->getName()); + if (PrivateVar->isInvalidDecl()) + return nullptr; + return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); + } + return nullptr; } /// \brief Build initization of the counter be used for codegen. @@ -2717,6 +2732,8 @@ struct LoopIterationSpace { Expr *NumIterations; /// \brief The loop counter variable. Expr *CounterVar; + /// \brief Private loop counter variable. + Expr *PrivateCounterVar; /// \brief This is initializer for the initial value of #CounterVar. Expr *CounterInit; /// \brief This is step for the #CounterVar used to generate its update: @@ -2801,7 +2818,7 @@ static bool CheckOpenMPIterationSpace( // A variable of signed or unsigned integer type. // For C++, a variable of a random access iterator type. // For C, a variable of a pointer type. - auto VarType = Var->getType(); + auto VarType = Var->getType().getNonReferenceType(); if (!VarType->isDependentType() && !VarType->isIntegerType() && !VarType->isPointerType() && !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { @@ -2877,6 +2894,7 @@ static bool CheckOpenMPIterationSpace( ResultIterSpace.NumIterations = ISC.BuildNumIterations( DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); ResultIterSpace.CounterVar = ISC.BuildCounterVar(); + ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); ResultIterSpace.CounterInit = ISC.BuildCounterInit(); ResultIterSpace.CounterStep = ISC.BuildCounterStep(); ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); @@ -2887,6 +2905,7 @@ static bool CheckOpenMPIterationSpace( HasErrors |= (ResultIterSpace.PreCond == nullptr || ResultIterSpace.NumIterations == nullptr || ResultIterSpace.CounterVar == nullptr || + ResultIterSpace.PrivateCounterVar == nullptr || ResultIterSpace.CounterInit == nullptr || ResultIterSpace.CounterStep == nullptr); @@ -3286,6 +3305,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, } // Save results Built.Counters[Cnt] = IS.CounterVar; + Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; Built.Updates[Cnt] = Update.get(); Built.Finals[Cnt] = Final.get(); } -- cgit v1.2.3