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"
28using namespace clang;
29
30namespace {
31
32class VarDeclFilterCCC : public CorrectionCandidateCallback {
33private:
34  Sema &Actions;
35public:
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
49ExprResult 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
143Sema::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
153OMPThreadPrivateDecl *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
202StmtResult 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
222StmtResult 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
232OMPClause *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
254OMPClause *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
286OMPClause *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
305OMPClause *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