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