blob: c815d4f9abc79ebe4a8d613902e7202a15b5238b [file] [log] [blame]
Alexey Bataevc6400582013-03-22 06:34:35 +00001//===--- 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/DeclOpenMP.h"
18#include "clang/Lex/Preprocessor.h"
19#include "clang/Sema/SemaInternal.h"
20#include "clang/Sema/Lookup.h"
21using namespace clang;
22
23namespace {
24
25 class VarDeclFilterCCC : public CorrectionCandidateCallback {
26 private:
27 Sema &Actions;
28 public:
29 VarDeclFilterCCC(Sema &S) : Actions(S) { }
30 virtual bool ValidateCandidate(const TypoCorrection &Candidate) {
31 NamedDecl *ND = Candidate.getCorrectionDecl();
32 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
33 return VD->hasGlobalStorage() &&
34 Actions.isDeclInScope(ND, Actions.getCurLexicalContext(),
35 Actions.getCurScope());
36 }
37 return false;
38 }
39 };
40}
41Sema::DeclGroupPtrTy Sema::ActOnOpenMPThreadprivateDirective(
42 SourceLocation Loc,
43 Scope *CurScope,
44 ArrayRef<DeclarationNameInfo> IdList) {
45 SmallVector<DeclRefExpr *, 5> Vars;
46 for (ArrayRef<DeclarationNameInfo>::iterator I = IdList.begin(),
47 E = IdList.end();
48 I != E; ++I) {
49 LookupResult Lookup(*this, *I, LookupOrdinaryName);
50 LookupParsedName(Lookup, CurScope, NULL, true);
51
52 if (Lookup.isAmbiguous())
53 continue;
54
55 VarDecl *VD;
56 if (!Lookup.isSingleResult()) {
57 VarDeclFilterCCC Validator(*this);
58 TypoCorrection Corrected = CorrectTypo(*I, LookupOrdinaryName, CurScope,
59 0, Validator);
60 std::string CorrectedStr = Corrected.getAsString(getLangOpts());
61 std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts());
62 if (Lookup.empty()) {
63 if (Corrected.isResolved()) {
64 Diag(I->getLoc(), diag::err_undeclared_var_use_suggest)
65 << I->getName() << CorrectedQuotedStr
66 << FixItHint::CreateReplacement(I->getLoc(), CorrectedStr);
67 } else {
68 Diag(I->getLoc(), diag::err_undeclared_var_use)
69 << I->getName();
70 }
71 } else {
72 Diag(I->getLoc(), diag::err_omp_expected_var_arg_suggest)
73 << I->getName() << Corrected.isResolved() << CorrectedQuotedStr
74 << FixItHint::CreateReplacement(I->getLoc(), CorrectedStr);
75 }
76 if (!Corrected.isResolved()) continue;
77 VD = Corrected.getCorrectionDeclAs<VarDecl>();
78 } else {
79 if (!(VD = Lookup.getAsSingle<VarDecl>())) {
80 Diag(I->getLoc(), diag::err_omp_expected_var_arg_suggest)
81 << I->getName() << 0;
82 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
83 continue;
84 }
85 }
86
87 // OpenMP [2.9.2, Syntax, C/C++]
88 // Variables must be file-scope, namespace-scope, or static block-scope.
89 if (!VD->hasGlobalStorage()) {
90 Diag(I->getLoc(), diag::err_omp_global_var_arg)
91 << getOpenMPDirectiveName(OMPD_threadprivate)
92 << !VD->isStaticLocal();
93 Diag(VD->getLocation(), diag::note_forward_declaration) << VD;
94 continue;
95 }
96
97 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
98 // A threadprivate directive for file-scope variables must appear outside
99 // any definition or declaration.
100 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
101 // A threadprivate directive for static class member variables must appear
102 // in the class definition, in the same scope in which the member
103 // variables are declared.
104 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
105 // A threadprivate directive for namespace-scope variables must appear
106 // outside any definition or declaration other than the namespace
107 // definition itself.
108 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
109 // A threadprivate directive for static block-scope variables must appear
110 // in the scope of the variable and not in a nested scope.
111 NamedDecl *ND = cast<NamedDecl>(VD);
112 if (!isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
113 Diag(I->getLoc(), diag::err_omp_var_scope)
114 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
115 Diag(VD->getLocation(), diag::note_forward_declaration) << VD;
116 continue;
117 }
118
119 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
120 // A threadprivate directive must lexically precede all references to any
121 // of the variables in its list.
122 if (VD->isUsed()) {
123 Diag(I->getLoc(), diag::err_omp_var_used)
124 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
125 continue;
126 }
127
128 QualType ExprType = VD->getType().getNonReferenceType();
129 DeclRefExpr *Var = cast<DeclRefExpr>(BuildDeclRefExpr(VD,
130 ExprType,
131 VK_RValue,
132 I->getLoc()).take());
133 Vars.push_back(Var);
134 }
135 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, Vars)) {
136 CurContext->addDecl(D);
137 return DeclGroupPtrTy::make(DeclGroupRef(D));
138 }
139 return DeclGroupPtrTy();
140}
141
142OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
143 SourceLocation Loc,
144 ArrayRef<DeclRefExpr *> VarList) {
145 SmallVector<DeclRefExpr *, 5> Vars;
146 for (ArrayRef<DeclRefExpr *>::iterator I = VarList.begin(),
147 E = VarList.end();
148 I != E; ++I) {
149 VarDecl *VD = cast<VarDecl>((*I)->getDecl());
150 SourceLocation ILoc = (*I)->getLocation();
151
152 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
153 // A threadprivate variable must not have an incomplete type.
154 if (RequireCompleteType(ILoc, VD->getType(),
155 diag::err_omp_incomplete_type)) {
156 continue;
157 }
158
159 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
160 // A threadprivate variable must not have a reference type.
161 if (VD->getType()->isReferenceType()) {
162 Diag(ILoc, diag::err_omp_ref_type_arg)
163 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
164 Diag(VD->getLocation(), diag::note_forward_declaration) << VD;
165 continue;
166 }
167
Richard Smith38afbc72013-04-13 02:43:54 +0000168 // Check if this is a TLS variable.
169 if (VD->getTLSKind()) {
Alexey Bataevc6400582013-03-22 06:34:35 +0000170 Diag(ILoc, diag::err_omp_var_thread_local) << VD;
171 Diag(VD->getLocation(), diag::note_forward_declaration) << VD;
172 continue;
173 }
174
175 Vars.push_back(*I);
176 }
177 return Vars.empty() ?
178 0 : OMPThreadPrivateDecl::Create(Context,
179 getCurLexicalContext(),
180 Loc, Vars);
181}