Home | History | Annotate | Download | only in Sema
      1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// \brief This file implements semantic analysis for OpenMP directives and
     11 /// clauses.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "clang/Basic/OpenMPKinds.h"
     16 #include "clang/AST/Decl.h"
     17 #include "clang/AST/DeclCXX.h"
     18 #include "clang/AST/DeclOpenMP.h"
     19 #include "clang/AST/StmtCXX.h"
     20 #include "clang/AST/StmtOpenMP.h"
     21 #include "clang/AST/StmtVisitor.h"
     22 #include "clang/Lex/Preprocessor.h"
     23 #include "clang/Sema/Initialization.h"
     24 #include "clang/Sema/SemaInternal.h"
     25 #include "clang/Sema/Lookup.h"
     26 #include "clang/Sema/Scope.h"
     27 #include "clang/Sema/ScopeInfo.h"
     28 using namespace clang;
     29 
     30 namespace {
     31 
     32 class VarDeclFilterCCC : public CorrectionCandidateCallback {
     33 private:
     34   Sema &Actions;
     35 public:
     36   VarDeclFilterCCC(Sema &S) : Actions(S) { }
     37   virtual bool ValidateCandidate(const TypoCorrection &Candidate) {
     38     NamedDecl *ND = Candidate.getCorrectionDecl();
     39     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
     40       return VD->hasGlobalStorage() &&
     41              Actions.isDeclInScope(ND, Actions.getCurLexicalContext(),
     42                                    Actions.getCurScope());
     43     }
     44     return false;
     45   }
     46 };
     47 }
     48 
     49 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
     50                                          CXXScopeSpec &ScopeSpec,
     51                                          const DeclarationNameInfo &Id) {
     52   LookupResult Lookup(*this, Id, LookupOrdinaryName);
     53   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
     54 
     55   if (Lookup.isAmbiguous())
     56     return ExprError();
     57 
     58   VarDecl *VD;
     59   if (!Lookup.isSingleResult()) {
     60     VarDeclFilterCCC Validator(*this);
     61     TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope,
     62                                            0, Validator);
     63     std::string CorrectedStr = Corrected.getAsString(getLangOpts());
     64     std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts());
     65     if (Lookup.empty()) {
     66       if (Corrected.isResolved()) {
     67         Diag(Id.getLoc(), diag::err_undeclared_var_use_suggest)
     68           << Id.getName() << CorrectedQuotedStr
     69           << FixItHint::CreateReplacement(Id.getLoc(), CorrectedStr);
     70       } else {
     71         Diag(Id.getLoc(), diag::err_undeclared_var_use)
     72           << Id.getName();
     73       }
     74     } else {
     75       Diag(Id.getLoc(), diag::err_omp_expected_var_arg_suggest)
     76         << Id.getName() << Corrected.isResolved() << CorrectedQuotedStr
     77         << FixItHint::CreateReplacement(Id.getLoc(), CorrectedStr);
     78     }
     79     if (!Corrected.isResolved()) return ExprError();
     80     VD = Corrected.getCorrectionDeclAs<VarDecl>();
     81   } else {
     82     if (!(VD = Lookup.getAsSingle<VarDecl>())) {
     83       Diag(Id.getLoc(), diag::err_omp_expected_var_arg_suggest)
     84         << Id.getName() << 0;
     85       Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
     86       return ExprError();
     87     }
     88   }
     89   Lookup.suppressDiagnostics();
     90 
     91   // OpenMP [2.9.2, Syntax, C/C++]
     92   //   Variables must be file-scope, namespace-scope, or static block-scope.
     93   if (!VD->hasGlobalStorage()) {
     94     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
     95       << getOpenMPDirectiveName(OMPD_threadprivate)
     96       << !VD->isStaticLocal();
     97     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
     98                   VarDecl::DeclarationOnly;
     99     Diag(VD->getLocation(),
    100          IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD;
    101     return ExprError();
    102   }
    103 
    104   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
    105   //   A threadprivate directive for file-scope variables must appear outside
    106   //   any definition or declaration.
    107   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
    108   //   A threadprivate directive for static class member variables must appear
    109   //   in the class definition, in the same scope in which the member
    110   //   variables are declared.
    111   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
    112   //   A threadprivate directive for namespace-scope variables must appear
    113   //   outside any definition or declaration other than the namespace
    114   //   definition itself.
    115   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
    116   //   A threadprivate directive for static block-scope variables must appear
    117   //   in the scope of the variable and not in a nested scope.
    118   NamedDecl *ND = cast<NamedDecl>(VD);
    119   if (!isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
    120     Diag(Id.getLoc(), diag::err_omp_var_scope)
    121       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
    122     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
    123                   VarDecl::DeclarationOnly;
    124     Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
    125                                      diag::note_defined_here) << VD;
    126     return ExprError();
    127   }
    128 
    129   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
    130   //   A threadprivate directive must lexically precede all references to any
    131   //   of the variables in its list.
    132   if (VD->isUsed()) {
    133     Diag(Id.getLoc(), diag::err_omp_var_used)
    134       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
    135     return ExprError();
    136   }
    137 
    138   QualType ExprType = VD->getType().getNonReferenceType();
    139   ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_RValue, Id.getLoc());
    140   return DE;
    141 }
    142 
    143 Sema::DeclGroupPtrTy Sema::ActOnOpenMPThreadprivateDirective(
    144                                 SourceLocation Loc,
    145                                 ArrayRef<Expr *> VarList) {
    146   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
    147     CurContext->addDecl(D);
    148     return DeclGroupPtrTy::make(DeclGroupRef(D));
    149   }
    150   return DeclGroupPtrTy();
    151 }
    152 
    153 OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
    154                                  SourceLocation Loc,
    155                                  ArrayRef<Expr *> VarList) {
    156   SmallVector<Expr *, 8> Vars;
    157   for (ArrayRef<Expr *>::iterator I = VarList.begin(),
    158                                          E = VarList.end();
    159        I != E; ++I) {
    160     DeclRefExpr *DE = cast<DeclRefExpr>(*I);
    161     VarDecl *VD = cast<VarDecl>(DE->getDecl());
    162     SourceLocation ILoc = DE->getExprLoc();
    163 
    164     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
    165     //   A threadprivate variable must not have an incomplete type.
    166     if (RequireCompleteType(ILoc, VD->getType(),
    167                             diag::err_omp_threadprivate_incomplete_type)) {
    168       continue;
    169     }
    170 
    171     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
    172     //   A threadprivate variable must not have a reference type.
    173     if (VD->getType()->isReferenceType()) {
    174       Diag(ILoc, diag::err_omp_ref_type_arg)
    175         << getOpenMPDirectiveName(OMPD_threadprivate)
    176         << VD->getType();
    177       bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
    178                     VarDecl::DeclarationOnly;
    179       Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
    180                                        diag::note_defined_here) << VD;
    181       continue;
    182     }
    183 
    184     // Check if this is a TLS variable.
    185     if (VD->getTLSKind()) {
    186       Diag(ILoc, diag::err_omp_var_thread_local) << VD;
    187       bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
    188                     VarDecl::DeclarationOnly;
    189       Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
    190                                        diag::note_defined_here) << VD;
    191       continue;
    192     }
    193 
    194     Vars.push_back(*I);
    195   }
    196   return Vars.empty() ?
    197               0 : OMPThreadPrivateDecl::Create(Context,
    198                                                getCurLexicalContext(),
    199                                                Loc, Vars);
    200 }
    201 
    202 StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
    203                                                 ArrayRef<OMPClause *> Clauses,
    204                                                 Stmt *AStmt,
    205                                                 SourceLocation StartLoc,
    206                                                 SourceLocation EndLoc) {
    207   StmtResult Res = StmtError();
    208   switch (Kind) {
    209   case OMPD_parallel:
    210     Res = ActOnOpenMPParallelDirective(Clauses, AStmt, StartLoc, EndLoc);
    211     break;
    212   case OMPD_threadprivate:
    213   case OMPD_task:
    214     llvm_unreachable("OpenMP Directive is not allowed");
    215   case OMPD_unknown:
    216   case NUM_OPENMP_DIRECTIVES:
    217     llvm_unreachable("Unknown OpenMP directive");
    218   }
    219   return Res;
    220 }
    221 
    222 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
    223                                               Stmt *AStmt,
    224                                               SourceLocation StartLoc,
    225                                               SourceLocation EndLoc) {
    226   getCurFunction()->setHasBranchProtectedScope();
    227 
    228   return Owned(OMPParallelDirective::Create(Context, StartLoc, EndLoc,
    229                                             Clauses, AStmt));
    230 }
    231 
    232 OMPClause *Sema::ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
    233                                          unsigned Argument,
    234                                          SourceLocation ArgumentLoc,
    235                                          SourceLocation StartLoc,
    236                                          SourceLocation LParenLoc,
    237                                          SourceLocation EndLoc) {
    238   OMPClause *Res = 0;
    239   switch (Kind) {
    240   case OMPC_default:
    241     Res = ActOnOpenMPDefaultClause(
    242                              static_cast<OpenMPDefaultClauseKind>(Argument),
    243                              ArgumentLoc, StartLoc, LParenLoc, EndLoc);
    244     break;
    245   case OMPC_private:
    246   case OMPC_threadprivate:
    247   case OMPC_unknown:
    248   case NUM_OPENMP_CLAUSES:
    249     llvm_unreachable("Clause is not allowed.");
    250   }
    251   return Res;
    252 }
    253 
    254 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
    255                                           SourceLocation KindKwLoc,
    256                                           SourceLocation StartLoc,
    257                                           SourceLocation LParenLoc,
    258                                           SourceLocation EndLoc) {
    259   if (Kind == OMPC_DEFAULT_unknown) {
    260     std::string Values;
    261     std::string Sep(NUM_OPENMP_DEFAULT_KINDS > 1 ? ", " : "");
    262     for (unsigned i = OMPC_DEFAULT_unknown + 1;
    263          i < NUM_OPENMP_DEFAULT_KINDS; ++i) {
    264       Values += "'";
    265       Values += getOpenMPSimpleClauseTypeName(OMPC_default, i);
    266       Values += "'";
    267       switch (i) {
    268       case NUM_OPENMP_DEFAULT_KINDS - 2:
    269         Values += " or ";
    270         break;
    271       case NUM_OPENMP_DEFAULT_KINDS - 1:
    272         break;
    273       default:
    274         Values += Sep;
    275         break;
    276       }
    277     }
    278     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
    279       << Values << getOpenMPClauseName(OMPC_default);
    280     return 0;
    281   }
    282   return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc,
    283                                         EndLoc);
    284 }
    285 
    286 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
    287                                           ArrayRef<Expr *> VarList,
    288                                           SourceLocation StartLoc,
    289                                           SourceLocation LParenLoc,
    290                                           SourceLocation EndLoc) {
    291   OMPClause *Res = 0;
    292   switch (Kind) {
    293   case OMPC_private:
    294     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
    295     break;
    296   case OMPC_default:
    297   case OMPC_threadprivate:
    298   case OMPC_unknown:
    299   case NUM_OPENMP_CLAUSES:
    300     llvm_unreachable("Clause is not allowed.");
    301   }
    302   return Res;
    303 }
    304 
    305 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
    306                                           SourceLocation StartLoc,
    307                                           SourceLocation LParenLoc,
    308                                           SourceLocation EndLoc) {
    309   SmallVector<Expr *, 8> Vars;
    310   for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
    311        I != E; ++I) {
    312     if (*I && isa<DependentScopeDeclRefExpr>(*I)) {
    313       // It will be analyzed later.
    314       Vars.push_back(*I);
    315       continue;
    316     }
    317 
    318     SourceLocation ELoc = (*I)->getExprLoc();
    319     // OpenMP [2.1, C/C++]
    320     //  A list item is a variable name.
    321     // OpenMP  [2.9.3.3, Restrictions, p.1]
    322     //  A variable that is part of another variable (as an array or
    323     //  structure element) cannot appear in a private clause.
    324     DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
    325     if (!DE || !isa<VarDecl>(DE->getDecl())) {
    326       Diag(ELoc, diag::err_omp_expected_var_name)
    327         << (*I)->getSourceRange();
    328       continue;
    329     }
    330     Decl *D = DE->getDecl();
    331     VarDecl *VD = cast<VarDecl>(D);
    332 
    333     QualType Type = VD->getType();
    334     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
    335       // It will be analyzed later.
    336       Vars.push_back(DE);
    337       continue;
    338     }
    339 
    340     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
    341     //  A variable that appears in a private clause must not have an incomplete
    342     //  type or a reference type.
    343     if (RequireCompleteType(ELoc, Type,
    344                             diag::err_omp_private_incomplete_type)) {
    345       continue;
    346     }
    347     if (Type->isReferenceType()) {
    348       Diag(ELoc, diag::err_omp_clause_ref_type_arg)
    349         << getOpenMPClauseName(OMPC_private) << Type;
    350       bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
    351                     VarDecl::DeclarationOnly;
    352       Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
    353                                        diag::note_defined_here) << VD;
    354       continue;
    355     }
    356 
    357     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
    358     //  A variable of class type (or array thereof) that appears in a private
    359     //  clause requires an accesible, unambiguous default constructor for the
    360     //  class type.
    361     while (Type.getNonReferenceType()->isArrayType()) {
    362       Type = cast<ArrayType>(
    363                  Type.getNonReferenceType().getTypePtr())->getElementType();
    364     }
    365     CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
    366                           Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
    367     if (RD) {
    368       CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
    369       PartialDiagnostic PD =
    370         PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
    371       if (!CD ||
    372           CheckConstructorAccess(ELoc, CD,
    373                                  InitializedEntity::InitializeTemporary(Type),
    374                                  CD->getAccess(), PD) == AR_inaccessible ||
    375           CD->isDeleted()) {
    376         Diag(ELoc, diag::err_omp_required_method)
    377              << getOpenMPClauseName(OMPC_private) << 0;
    378         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
    379                       VarDecl::DeclarationOnly;
    380         Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
    381                                          diag::note_defined_here) << VD;
    382         Diag(RD->getLocation(), diag::note_previous_decl) << RD;
    383         continue;
    384       }
    385       MarkFunctionReferenced(ELoc, CD);
    386       DiagnoseUseOfDecl(CD, ELoc);
    387 
    388       CXXDestructorDecl *DD = RD->getDestructor();
    389       if (DD) {
    390         if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
    391             DD->isDeleted()) {
    392           Diag(ELoc, diag::err_omp_required_method)
    393                << getOpenMPClauseName(OMPC_private) << 4;
    394           bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
    395                         VarDecl::DeclarationOnly;
    396           Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
    397                                            diag::note_defined_here) << VD;
    398           Diag(RD->getLocation(), diag::note_previous_decl) << RD;
    399           continue;
    400         }
    401         MarkFunctionReferenced(ELoc, DD);
    402         DiagnoseUseOfDecl(DD, ELoc);
    403       }
    404     }
    405 
    406     Vars.push_back(DE);
    407   }
    408 
    409   if (Vars.empty()) return 0;
    410 
    411   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
    412 }
    413 
    414