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