blob: 4953d2d14e7a4340cb5be2b49db56ccbdf06af0f [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
Alexey Bataev6af701f2013-05-13 04:18:18 +000011/// clauses.
Alexey Bataevc6400582013-03-22 06:34:35 +000012///
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
Alexey Bataev6af701f2013-05-13 04:18:18 +000025class VarDeclFilterCCC : public CorrectionCandidateCallback {
26private:
27 Sema &Actions;
28public:
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());
Alexey Bataevc6400582013-03-22 06:34:35 +000036 }
Alexey Bataev6af701f2013-05-13 04:18:18 +000037 return false;
Alexey Bataevc6400582013-03-22 06:34:35 +000038 }
Alexey Bataev6af701f2013-05-13 04:18:18 +000039};
40}
41
42ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
43 CXXScopeSpec &ScopeSpec,
44 const DeclarationNameInfo &Id) {
45 LookupResult Lookup(*this, Id, LookupOrdinaryName);
46 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
47
48 if (Lookup.isAmbiguous())
49 return ExprError();
50
51 VarDecl *VD;
52 if (!Lookup.isSingleResult()) {
53 VarDeclFilterCCC Validator(*this);
54 TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope,
55 0, Validator);
56 std::string CorrectedStr = Corrected.getAsString(getLangOpts());
57 std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts());
58 if (Lookup.empty()) {
59 if (Corrected.isResolved()) {
60 Diag(Id.getLoc(), diag::err_undeclared_var_use_suggest)
61 << Id.getName() << CorrectedQuotedStr
62 << FixItHint::CreateReplacement(Id.getLoc(), CorrectedStr);
63 } else {
64 Diag(Id.getLoc(), diag::err_undeclared_var_use)
65 << Id.getName();
66 }
67 } else {
68 Diag(Id.getLoc(), diag::err_omp_expected_var_arg_suggest)
69 << Id.getName() << Corrected.isResolved() << CorrectedQuotedStr
70 << FixItHint::CreateReplacement(Id.getLoc(), CorrectedStr);
71 }
72 if (!Corrected.isResolved()) return ExprError();
73 VD = Corrected.getCorrectionDeclAs<VarDecl>();
74 } else {
75 if (!(VD = Lookup.getAsSingle<VarDecl>())) {
76 Diag(Id.getLoc(), diag::err_omp_expected_var_arg_suggest)
77 << Id.getName() << 0;
78 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
79 return ExprError();
80 }
81 }
82 Lookup.suppressDiagnostics();
83
84 // OpenMP [2.9.2, Syntax, C/C++]
85 // Variables must be file-scope, namespace-scope, or static block-scope.
86 if (!VD->hasGlobalStorage()) {
87 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
88 << getOpenMPDirectiveName(OMPD_threadprivate)
89 << !VD->isStaticLocal();
90 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
91 VarDecl::DeclarationOnly;
92 Diag(VD->getLocation(),
93 IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD;
94 return ExprError();
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(Id.getLoc(), diag::err_omp_var_scope)
114 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
115 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
116 VarDecl::DeclarationOnly;
117 Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
118 diag::note_defined_here) << VD;
119 return ExprError();
120 }
121
122 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
123 // A threadprivate directive must lexically precede all references to any
124 // of the variables in its list.
125 if (VD->isUsed()) {
126 Diag(Id.getLoc(), diag::err_omp_var_used)
127 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
128 return ExprError();
129 }
130
131 QualType ExprType = VD->getType().getNonReferenceType();
132 ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_RValue, Id.getLoc());
133 return DE;
134}
135
136Sema::DeclGroupPtrTy Sema::ActOnOpenMPThreadprivateDirective(
137 SourceLocation Loc,
138 ArrayRef<Expr *> VarList) {
139 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
Alexey Bataevc6400582013-03-22 06:34:35 +0000140 CurContext->addDecl(D);
141 return DeclGroupPtrTy::make(DeclGroupRef(D));
142 }
143 return DeclGroupPtrTy();
144}
145
146OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
147 SourceLocation Loc,
Alexey Bataev6af701f2013-05-13 04:18:18 +0000148 ArrayRef<Expr *> VarList) {
149 SmallVector<Expr *, 8> Vars;
150 for (ArrayRef<Expr *>::iterator I = VarList.begin(),
Alexey Bataevc6400582013-03-22 06:34:35 +0000151 E = VarList.end();
152 I != E; ++I) {
Alexey Bataev6af701f2013-05-13 04:18:18 +0000153 DeclRefExpr *DE = cast<DeclRefExpr>(*I);
154 VarDecl *VD = cast<VarDecl>(DE->getDecl());
155 SourceLocation ILoc = DE->getExprLoc();
Alexey Bataevc6400582013-03-22 06:34:35 +0000156
157 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
158 // A threadprivate variable must not have an incomplete type.
159 if (RequireCompleteType(ILoc, VD->getType(),
Alexey Bataev6af701f2013-05-13 04:18:18 +0000160 diag::err_omp_threadprivate_incomplete_type)) {
Alexey Bataevc6400582013-03-22 06:34:35 +0000161 continue;
162 }
163
164 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
165 // A threadprivate variable must not have a reference type.
166 if (VD->getType()->isReferenceType()) {
167 Diag(ILoc, diag::err_omp_ref_type_arg)
Alexey Bataev6af701f2013-05-13 04:18:18 +0000168 << getOpenMPDirectiveName(OMPD_threadprivate);
169 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
170 VarDecl::DeclarationOnly;
171 Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
172 diag::note_defined_here) << VD;
Alexey Bataevc6400582013-03-22 06:34:35 +0000173 continue;
174 }
175
Richard Smith38afbc72013-04-13 02:43:54 +0000176 // Check if this is a TLS variable.
177 if (VD->getTLSKind()) {
Alexey Bataevc6400582013-03-22 06:34:35 +0000178 Diag(ILoc, diag::err_omp_var_thread_local) << VD;
Alexey Bataev6af701f2013-05-13 04:18:18 +0000179 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
180 VarDecl::DeclarationOnly;
181 Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
182 diag::note_defined_here) << VD;
Alexey Bataevc6400582013-03-22 06:34:35 +0000183 continue;
184 }
185
186 Vars.push_back(*I);
187 }
188 return Vars.empty() ?
189 0 : OMPThreadPrivateDecl::Create(Context,
190 getCurLexicalContext(),
191 Loc, Vars);
192}
Alexey Bataev6af701f2013-05-13 04:18:18 +0000193