File: | build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/clang/lib/Sema/TreeTransform.h |
Warning: | line 6203, column 19 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/ | ||||||||||||
2 | // | ||||||||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||||||
6 | //===----------------------------------------------------------------------===/ | ||||||||||||
7 | // | ||||||||||||
8 | // This file implements C++ template instantiation for declarations. | ||||||||||||
9 | // | ||||||||||||
10 | //===----------------------------------------------------------------------===/ | ||||||||||||
11 | |||||||||||||
12 | #include "TreeTransform.h" | ||||||||||||
13 | #include "clang/AST/ASTConsumer.h" | ||||||||||||
14 | #include "clang/AST/ASTContext.h" | ||||||||||||
15 | #include "clang/AST/ASTMutationListener.h" | ||||||||||||
16 | #include "clang/AST/DeclTemplate.h" | ||||||||||||
17 | #include "clang/AST/DeclVisitor.h" | ||||||||||||
18 | #include "clang/AST/DependentDiagnostic.h" | ||||||||||||
19 | #include "clang/AST/Expr.h" | ||||||||||||
20 | #include "clang/AST/ExprCXX.h" | ||||||||||||
21 | #include "clang/AST/PrettyDeclStackTrace.h" | ||||||||||||
22 | #include "clang/AST/TypeLoc.h" | ||||||||||||
23 | #include "clang/Basic/SourceManager.h" | ||||||||||||
24 | #include "clang/Basic/TargetInfo.h" | ||||||||||||
25 | #include "clang/Sema/Initialization.h" | ||||||||||||
26 | #include "clang/Sema/Lookup.h" | ||||||||||||
27 | #include "clang/Sema/ScopeInfo.h" | ||||||||||||
28 | #include "clang/Sema/SemaInternal.h" | ||||||||||||
29 | #include "clang/Sema/Template.h" | ||||||||||||
30 | #include "clang/Sema/TemplateInstCallback.h" | ||||||||||||
31 | #include "llvm/Support/TimeProfiler.h" | ||||||||||||
32 | |||||||||||||
33 | using namespace clang; | ||||||||||||
34 | |||||||||||||
35 | static bool isDeclWithinFunction(const Decl *D) { | ||||||||||||
36 | const DeclContext *DC = D->getDeclContext(); | ||||||||||||
37 | if (DC->isFunctionOrMethod()) | ||||||||||||
38 | return true; | ||||||||||||
39 | |||||||||||||
40 | if (DC->isRecord()) | ||||||||||||
41 | return cast<CXXRecordDecl>(DC)->isLocalClass(); | ||||||||||||
42 | |||||||||||||
43 | return false; | ||||||||||||
44 | } | ||||||||||||
45 | |||||||||||||
46 | template<typename DeclT> | ||||||||||||
47 | static bool SubstQualifier(Sema &SemaRef, const DeclT *OldDecl, DeclT *NewDecl, | ||||||||||||
48 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
49 | if (!OldDecl->getQualifierLoc()) | ||||||||||||
50 | return false; | ||||||||||||
51 | |||||||||||||
52 | assert((NewDecl->getFriendObjectKind() ||(static_cast <bool> ((NewDecl->getFriendObjectKind() || !OldDecl->getLexicalDeclContext()->isDependentContext ()) && "non-friend with qualified name defined in dependent context" ) ? void (0) : __assert_fail ("(NewDecl->getFriendObjectKind() || !OldDecl->getLexicalDeclContext()->isDependentContext()) && \"non-friend with qualified name defined in dependent context\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 54, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
53 | !OldDecl->getLexicalDeclContext()->isDependentContext()) &&(static_cast <bool> ((NewDecl->getFriendObjectKind() || !OldDecl->getLexicalDeclContext()->isDependentContext ()) && "non-friend with qualified name defined in dependent context" ) ? void (0) : __assert_fail ("(NewDecl->getFriendObjectKind() || !OldDecl->getLexicalDeclContext()->isDependentContext()) && \"non-friend with qualified name defined in dependent context\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 54, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
54 | "non-friend with qualified name defined in dependent context")(static_cast <bool> ((NewDecl->getFriendObjectKind() || !OldDecl->getLexicalDeclContext()->isDependentContext ()) && "non-friend with qualified name defined in dependent context" ) ? void (0) : __assert_fail ("(NewDecl->getFriendObjectKind() || !OldDecl->getLexicalDeclContext()->isDependentContext()) && \"non-friend with qualified name defined in dependent context\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 54, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
55 | Sema::ContextRAII SavedContext( | ||||||||||||
56 | SemaRef, | ||||||||||||
57 | const_cast<DeclContext *>(NewDecl->getFriendObjectKind() | ||||||||||||
58 | ? NewDecl->getLexicalDeclContext() | ||||||||||||
59 | : OldDecl->getLexicalDeclContext())); | ||||||||||||
60 | |||||||||||||
61 | NestedNameSpecifierLoc NewQualifierLoc | ||||||||||||
62 | = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), | ||||||||||||
63 | TemplateArgs); | ||||||||||||
64 | |||||||||||||
65 | if (!NewQualifierLoc) | ||||||||||||
66 | return true; | ||||||||||||
67 | |||||||||||||
68 | NewDecl->setQualifierInfo(NewQualifierLoc); | ||||||||||||
69 | return false; | ||||||||||||
70 | } | ||||||||||||
71 | |||||||||||||
72 | bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl, | ||||||||||||
73 | DeclaratorDecl *NewDecl) { | ||||||||||||
74 | return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs); | ||||||||||||
75 | } | ||||||||||||
76 | |||||||||||||
77 | bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, | ||||||||||||
78 | TagDecl *NewDecl) { | ||||||||||||
79 | return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs); | ||||||||||||
80 | } | ||||||||||||
81 | |||||||||||||
82 | // Include attribute instantiation code. | ||||||||||||
83 | #include "clang/Sema/AttrTemplateInstantiate.inc" | ||||||||||||
84 | |||||||||||||
85 | static void instantiateDependentAlignedAttr( | ||||||||||||
86 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
87 | const AlignedAttr *Aligned, Decl *New, bool IsPackExpansion) { | ||||||||||||
88 | if (Aligned->isAlignmentExpr()) { | ||||||||||||
89 | // The alignment expression is a constant expression. | ||||||||||||
90 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
91 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
92 | ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs); | ||||||||||||
93 | if (!Result.isInvalid()) | ||||||||||||
94 | S.AddAlignedAttr(New, *Aligned, Result.getAs<Expr>(), IsPackExpansion); | ||||||||||||
95 | } else { | ||||||||||||
96 | TypeSourceInfo *Result = S.SubstType(Aligned->getAlignmentType(), | ||||||||||||
97 | TemplateArgs, Aligned->getLocation(), | ||||||||||||
98 | DeclarationName()); | ||||||||||||
99 | if (Result) | ||||||||||||
100 | S.AddAlignedAttr(New, *Aligned, Result, IsPackExpansion); | ||||||||||||
101 | } | ||||||||||||
102 | } | ||||||||||||
103 | |||||||||||||
104 | static void instantiateDependentAlignedAttr( | ||||||||||||
105 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
106 | const AlignedAttr *Aligned, Decl *New) { | ||||||||||||
107 | if (!Aligned->isPackExpansion()) { | ||||||||||||
108 | instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, false); | ||||||||||||
109 | return; | ||||||||||||
110 | } | ||||||||||||
111 | |||||||||||||
112 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
113 | if (Aligned->isAlignmentExpr()) | ||||||||||||
114 | S.collectUnexpandedParameterPacks(Aligned->getAlignmentExpr(), | ||||||||||||
115 | Unexpanded); | ||||||||||||
116 | else | ||||||||||||
117 | S.collectUnexpandedParameterPacks(Aligned->getAlignmentType()->getTypeLoc(), | ||||||||||||
118 | Unexpanded); | ||||||||||||
119 | assert(!Unexpanded.empty() && "Pack expansion without parameter packs?")(static_cast <bool> (!Unexpanded.empty() && "Pack expansion without parameter packs?" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Pack expansion without parameter packs?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 119, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
120 | |||||||||||||
121 | // Determine whether we can expand this attribute pack yet. | ||||||||||||
122 | bool Expand = true, RetainExpansion = false; | ||||||||||||
123 | Optional<unsigned> NumExpansions; | ||||||||||||
124 | // FIXME: Use the actual location of the ellipsis. | ||||||||||||
125 | SourceLocation EllipsisLoc = Aligned->getLocation(); | ||||||||||||
126 | if (S.CheckParameterPacksForExpansion(EllipsisLoc, Aligned->getRange(), | ||||||||||||
127 | Unexpanded, TemplateArgs, Expand, | ||||||||||||
128 | RetainExpansion, NumExpansions)) | ||||||||||||
129 | return; | ||||||||||||
130 | |||||||||||||
131 | if (!Expand) { | ||||||||||||
132 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, -1); | ||||||||||||
133 | instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, true); | ||||||||||||
134 | } else { | ||||||||||||
135 | for (unsigned I = 0; I != *NumExpansions; ++I) { | ||||||||||||
136 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, I); | ||||||||||||
137 | instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, false); | ||||||||||||
138 | } | ||||||||||||
139 | } | ||||||||||||
140 | } | ||||||||||||
141 | |||||||||||||
142 | static void instantiateDependentAssumeAlignedAttr( | ||||||||||||
143 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
144 | const AssumeAlignedAttr *Aligned, Decl *New) { | ||||||||||||
145 | // The alignment expression is a constant expression. | ||||||||||||
146 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
147 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
148 | |||||||||||||
149 | Expr *E, *OE = nullptr; | ||||||||||||
150 | ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs); | ||||||||||||
151 | if (Result.isInvalid()) | ||||||||||||
152 | return; | ||||||||||||
153 | E = Result.getAs<Expr>(); | ||||||||||||
154 | |||||||||||||
155 | if (Aligned->getOffset()) { | ||||||||||||
156 | Result = S.SubstExpr(Aligned->getOffset(), TemplateArgs); | ||||||||||||
157 | if (Result.isInvalid()) | ||||||||||||
158 | return; | ||||||||||||
159 | OE = Result.getAs<Expr>(); | ||||||||||||
160 | } | ||||||||||||
161 | |||||||||||||
162 | S.AddAssumeAlignedAttr(New, *Aligned, E, OE); | ||||||||||||
163 | } | ||||||||||||
164 | |||||||||||||
165 | static void instantiateDependentAlignValueAttr( | ||||||||||||
166 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
167 | const AlignValueAttr *Aligned, Decl *New) { | ||||||||||||
168 | // The alignment expression is a constant expression. | ||||||||||||
169 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
170 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
171 | ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs); | ||||||||||||
172 | if (!Result.isInvalid()) | ||||||||||||
173 | S.AddAlignValueAttr(New, *Aligned, Result.getAs<Expr>()); | ||||||||||||
174 | } | ||||||||||||
175 | |||||||||||||
176 | static void instantiateDependentAllocAlignAttr( | ||||||||||||
177 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
178 | const AllocAlignAttr *Align, Decl *New) { | ||||||||||||
179 | Expr *Param = IntegerLiteral::Create( | ||||||||||||
180 | S.getASTContext(), | ||||||||||||
181 | llvm::APInt(64, Align->getParamIndex().getSourceIndex()), | ||||||||||||
182 | S.getASTContext().UnsignedLongLongTy, Align->getLocation()); | ||||||||||||
183 | S.AddAllocAlignAttr(New, *Align, Param); | ||||||||||||
184 | } | ||||||||||||
185 | |||||||||||||
186 | static void instantiateDependentAnnotationAttr( | ||||||||||||
187 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
188 | const AnnotateAttr *Attr, Decl *New) { | ||||||||||||
189 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
190 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
191 | |||||||||||||
192 | // If the attribute has delayed arguments it will have to instantiate those | ||||||||||||
193 | // and handle them as new arguments for the attribute. | ||||||||||||
194 | bool HasDelayedArgs = Attr->delayedArgs_size(); | ||||||||||||
195 | |||||||||||||
196 | ArrayRef<Expr *> ArgsToInstantiate = | ||||||||||||
197 | HasDelayedArgs | ||||||||||||
198 | ? ArrayRef<Expr *>{Attr->delayedArgs_begin(), Attr->delayedArgs_end()} | ||||||||||||
199 | : ArrayRef<Expr *>{Attr->args_begin(), Attr->args_end()}; | ||||||||||||
200 | |||||||||||||
201 | SmallVector<Expr *, 4> Args; | ||||||||||||
202 | if (S.SubstExprs(ArgsToInstantiate, | ||||||||||||
203 | /*IsCall=*/false, TemplateArgs, Args)) | ||||||||||||
204 | return; | ||||||||||||
205 | |||||||||||||
206 | StringRef Str = Attr->getAnnotation(); | ||||||||||||
207 | if (HasDelayedArgs) { | ||||||||||||
208 | if (Args.size() < 1) { | ||||||||||||
209 | S.Diag(Attr->getLoc(), diag::err_attribute_too_few_arguments) | ||||||||||||
210 | << Attr << 1; | ||||||||||||
211 | return; | ||||||||||||
212 | } | ||||||||||||
213 | |||||||||||||
214 | if (!S.checkStringLiteralArgumentAttr(*Attr, Args[0], Str)) | ||||||||||||
215 | return; | ||||||||||||
216 | |||||||||||||
217 | llvm::SmallVector<Expr *, 4> ActualArgs; | ||||||||||||
218 | ActualArgs.insert(ActualArgs.begin(), Args.begin() + 1, Args.end()); | ||||||||||||
219 | std::swap(Args, ActualArgs); | ||||||||||||
220 | } | ||||||||||||
221 | S.AddAnnotationAttr(New, *Attr, Str, Args); | ||||||||||||
222 | } | ||||||||||||
223 | |||||||||||||
224 | static Expr *instantiateDependentFunctionAttrCondition( | ||||||||||||
225 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
226 | const Attr *A, Expr *OldCond, const Decl *Tmpl, FunctionDecl *New) { | ||||||||||||
227 | Expr *Cond = nullptr; | ||||||||||||
228 | { | ||||||||||||
229 | Sema::ContextRAII SwitchContext(S, New); | ||||||||||||
230 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
231 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
232 | ExprResult Result = S.SubstExpr(OldCond, TemplateArgs); | ||||||||||||
233 | if (Result.isInvalid()) | ||||||||||||
234 | return nullptr; | ||||||||||||
235 | Cond = Result.getAs<Expr>(); | ||||||||||||
236 | } | ||||||||||||
237 | if (!Cond->isTypeDependent()) { | ||||||||||||
238 | ExprResult Converted = S.PerformContextuallyConvertToBool(Cond); | ||||||||||||
239 | if (Converted.isInvalid()) | ||||||||||||
240 | return nullptr; | ||||||||||||
241 | Cond = Converted.get(); | ||||||||||||
242 | } | ||||||||||||
243 | |||||||||||||
244 | SmallVector<PartialDiagnosticAt, 8> Diags; | ||||||||||||
245 | if (OldCond->isValueDependent() && !Cond->isValueDependent() && | ||||||||||||
246 | !Expr::isPotentialConstantExprUnevaluated(Cond, New, Diags)) { | ||||||||||||
247 | S.Diag(A->getLocation(), diag::err_attr_cond_never_constant_expr) << A; | ||||||||||||
248 | for (const auto &P : Diags) | ||||||||||||
249 | S.Diag(P.first, P.second); | ||||||||||||
250 | return nullptr; | ||||||||||||
251 | } | ||||||||||||
252 | return Cond; | ||||||||||||
253 | } | ||||||||||||
254 | |||||||||||||
255 | static void instantiateDependentEnableIfAttr( | ||||||||||||
256 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
257 | const EnableIfAttr *EIA, const Decl *Tmpl, FunctionDecl *New) { | ||||||||||||
258 | Expr *Cond = instantiateDependentFunctionAttrCondition( | ||||||||||||
259 | S, TemplateArgs, EIA, EIA->getCond(), Tmpl, New); | ||||||||||||
260 | |||||||||||||
261 | if (Cond) | ||||||||||||
262 | New->addAttr(new (S.getASTContext()) EnableIfAttr(S.getASTContext(), *EIA, | ||||||||||||
263 | Cond, EIA->getMessage())); | ||||||||||||
264 | } | ||||||||||||
265 | |||||||||||||
266 | static void instantiateDependentDiagnoseIfAttr( | ||||||||||||
267 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
268 | const DiagnoseIfAttr *DIA, const Decl *Tmpl, FunctionDecl *New) { | ||||||||||||
269 | Expr *Cond = instantiateDependentFunctionAttrCondition( | ||||||||||||
270 | S, TemplateArgs, DIA, DIA->getCond(), Tmpl, New); | ||||||||||||
271 | |||||||||||||
272 | if (Cond) | ||||||||||||
273 | New->addAttr(new (S.getASTContext()) DiagnoseIfAttr( | ||||||||||||
274 | S.getASTContext(), *DIA, Cond, DIA->getMessage(), | ||||||||||||
275 | DIA->getDiagnosticType(), DIA->getArgDependent(), New)); | ||||||||||||
276 | } | ||||||||||||
277 | |||||||||||||
278 | // Constructs and adds to New a new instance of CUDALaunchBoundsAttr using | ||||||||||||
279 | // template A as the base and arguments from TemplateArgs. | ||||||||||||
280 | static void instantiateDependentCUDALaunchBoundsAttr( | ||||||||||||
281 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
282 | const CUDALaunchBoundsAttr &Attr, Decl *New) { | ||||||||||||
283 | // The alignment expression is a constant expression. | ||||||||||||
284 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
285 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
286 | |||||||||||||
287 | ExprResult Result = S.SubstExpr(Attr.getMaxThreads(), TemplateArgs); | ||||||||||||
288 | if (Result.isInvalid()) | ||||||||||||
289 | return; | ||||||||||||
290 | Expr *MaxThreads = Result.getAs<Expr>(); | ||||||||||||
291 | |||||||||||||
292 | Expr *MinBlocks = nullptr; | ||||||||||||
293 | if (Attr.getMinBlocks()) { | ||||||||||||
294 | Result = S.SubstExpr(Attr.getMinBlocks(), TemplateArgs); | ||||||||||||
295 | if (Result.isInvalid()) | ||||||||||||
296 | return; | ||||||||||||
297 | MinBlocks = Result.getAs<Expr>(); | ||||||||||||
298 | } | ||||||||||||
299 | |||||||||||||
300 | S.AddLaunchBoundsAttr(New, Attr, MaxThreads, MinBlocks); | ||||||||||||
301 | } | ||||||||||||
302 | |||||||||||||
303 | static void | ||||||||||||
304 | instantiateDependentModeAttr(Sema &S, | ||||||||||||
305 | const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
306 | const ModeAttr &Attr, Decl *New) { | ||||||||||||
307 | S.AddModeAttr(New, Attr, Attr.getMode(), | ||||||||||||
308 | /*InInstantiation=*/true); | ||||||||||||
309 | } | ||||||||||||
310 | |||||||||||||
311 | /// Instantiation of 'declare simd' attribute and its arguments. | ||||||||||||
312 | static void instantiateOMPDeclareSimdDeclAttr( | ||||||||||||
313 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
314 | const OMPDeclareSimdDeclAttr &Attr, Decl *New) { | ||||||||||||
315 | // Allow 'this' in clauses with varlists. | ||||||||||||
316 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(New)) | ||||||||||||
317 | New = FTD->getTemplatedDecl(); | ||||||||||||
318 | auto *FD = cast<FunctionDecl>(New); | ||||||||||||
319 | auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(FD->getDeclContext()); | ||||||||||||
320 | SmallVector<Expr *, 4> Uniforms, Aligneds, Alignments, Linears, Steps; | ||||||||||||
321 | SmallVector<unsigned, 4> LinModifiers; | ||||||||||||
322 | |||||||||||||
323 | auto SubstExpr = [&](Expr *E) -> ExprResult { | ||||||||||||
324 | if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) | ||||||||||||
325 | if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||||||||
326 | Sema::ContextRAII SavedContext(S, FD); | ||||||||||||
327 | LocalInstantiationScope Local(S); | ||||||||||||
328 | if (FD->getNumParams() > PVD->getFunctionScopeIndex()) | ||||||||||||
329 | Local.InstantiatedLocal( | ||||||||||||
330 | PVD, FD->getParamDecl(PVD->getFunctionScopeIndex())); | ||||||||||||
331 | return S.SubstExpr(E, TemplateArgs); | ||||||||||||
332 | } | ||||||||||||
333 | Sema::CXXThisScopeRAII ThisScope(S, ThisContext, Qualifiers(), | ||||||||||||
334 | FD->isCXXInstanceMember()); | ||||||||||||
335 | return S.SubstExpr(E, TemplateArgs); | ||||||||||||
336 | }; | ||||||||||||
337 | |||||||||||||
338 | // Substitute a single OpenMP clause, which is a potentially-evaluated | ||||||||||||
339 | // full-expression. | ||||||||||||
340 | auto Subst = [&](Expr *E) -> ExprResult { | ||||||||||||
341 | EnterExpressionEvaluationContext Evaluated( | ||||||||||||
342 | S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||||||||
343 | ExprResult Res = SubstExpr(E); | ||||||||||||
344 | if (Res.isInvalid()) | ||||||||||||
345 | return Res; | ||||||||||||
346 | return S.ActOnFinishFullExpr(Res.get(), false); | ||||||||||||
347 | }; | ||||||||||||
348 | |||||||||||||
349 | ExprResult Simdlen; | ||||||||||||
350 | if (auto *E = Attr.getSimdlen()) | ||||||||||||
351 | Simdlen = Subst(E); | ||||||||||||
352 | |||||||||||||
353 | if (Attr.uniforms_size() > 0) { | ||||||||||||
354 | for(auto *E : Attr.uniforms()) { | ||||||||||||
355 | ExprResult Inst = Subst(E); | ||||||||||||
356 | if (Inst.isInvalid()) | ||||||||||||
357 | continue; | ||||||||||||
358 | Uniforms.push_back(Inst.get()); | ||||||||||||
359 | } | ||||||||||||
360 | } | ||||||||||||
361 | |||||||||||||
362 | auto AI = Attr.alignments_begin(); | ||||||||||||
363 | for (auto *E : Attr.aligneds()) { | ||||||||||||
364 | ExprResult Inst = Subst(E); | ||||||||||||
365 | if (Inst.isInvalid()) | ||||||||||||
366 | continue; | ||||||||||||
367 | Aligneds.push_back(Inst.get()); | ||||||||||||
368 | Inst = ExprEmpty(); | ||||||||||||
369 | if (*AI) | ||||||||||||
370 | Inst = S.SubstExpr(*AI, TemplateArgs); | ||||||||||||
371 | Alignments.push_back(Inst.get()); | ||||||||||||
372 | ++AI; | ||||||||||||
373 | } | ||||||||||||
374 | |||||||||||||
375 | auto SI = Attr.steps_begin(); | ||||||||||||
376 | for (auto *E : Attr.linears()) { | ||||||||||||
377 | ExprResult Inst = Subst(E); | ||||||||||||
378 | if (Inst.isInvalid()) | ||||||||||||
379 | continue; | ||||||||||||
380 | Linears.push_back(Inst.get()); | ||||||||||||
381 | Inst = ExprEmpty(); | ||||||||||||
382 | if (*SI) | ||||||||||||
383 | Inst = S.SubstExpr(*SI, TemplateArgs); | ||||||||||||
384 | Steps.push_back(Inst.get()); | ||||||||||||
385 | ++SI; | ||||||||||||
386 | } | ||||||||||||
387 | LinModifiers.append(Attr.modifiers_begin(), Attr.modifiers_end()); | ||||||||||||
388 | (void)S.ActOnOpenMPDeclareSimdDirective( | ||||||||||||
389 | S.ConvertDeclToDeclGroup(New), Attr.getBranchState(), Simdlen.get(), | ||||||||||||
390 | Uniforms, Aligneds, Alignments, Linears, LinModifiers, Steps, | ||||||||||||
391 | Attr.getRange()); | ||||||||||||
392 | } | ||||||||||||
393 | |||||||||||||
394 | /// Instantiation of 'declare variant' attribute and its arguments. | ||||||||||||
395 | static void instantiateOMPDeclareVariantAttr( | ||||||||||||
396 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
397 | const OMPDeclareVariantAttr &Attr, Decl *New) { | ||||||||||||
398 | // Allow 'this' in clauses with varlists. | ||||||||||||
399 | if (auto *FTD = dyn_cast<FunctionTemplateDecl>(New)) | ||||||||||||
400 | New = FTD->getTemplatedDecl(); | ||||||||||||
401 | auto *FD = cast<FunctionDecl>(New); | ||||||||||||
402 | auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(FD->getDeclContext()); | ||||||||||||
403 | |||||||||||||
404 | auto &&SubstExpr = [FD, ThisContext, &S, &TemplateArgs](Expr *E) { | ||||||||||||
405 | if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) | ||||||||||||
406 | if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { | ||||||||||||
407 | Sema::ContextRAII SavedContext(S, FD); | ||||||||||||
408 | LocalInstantiationScope Local(S); | ||||||||||||
409 | if (FD->getNumParams() > PVD->getFunctionScopeIndex()) | ||||||||||||
410 | Local.InstantiatedLocal( | ||||||||||||
411 | PVD, FD->getParamDecl(PVD->getFunctionScopeIndex())); | ||||||||||||
412 | return S.SubstExpr(E, TemplateArgs); | ||||||||||||
413 | } | ||||||||||||
414 | Sema::CXXThisScopeRAII ThisScope(S, ThisContext, Qualifiers(), | ||||||||||||
415 | FD->isCXXInstanceMember()); | ||||||||||||
416 | return S.SubstExpr(E, TemplateArgs); | ||||||||||||
417 | }; | ||||||||||||
418 | |||||||||||||
419 | // Substitute a single OpenMP clause, which is a potentially-evaluated | ||||||||||||
420 | // full-expression. | ||||||||||||
421 | auto &&Subst = [&SubstExpr, &S](Expr *E) { | ||||||||||||
422 | EnterExpressionEvaluationContext Evaluated( | ||||||||||||
423 | S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||||||||
424 | ExprResult Res = SubstExpr(E); | ||||||||||||
425 | if (Res.isInvalid()) | ||||||||||||
426 | return Res; | ||||||||||||
427 | return S.ActOnFinishFullExpr(Res.get(), false); | ||||||||||||
428 | }; | ||||||||||||
429 | |||||||||||||
430 | ExprResult VariantFuncRef; | ||||||||||||
431 | if (Expr *E = Attr.getVariantFuncRef()) { | ||||||||||||
432 | // Do not mark function as is used to prevent its emission if this is the | ||||||||||||
433 | // only place where it is used. | ||||||||||||
434 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
435 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
436 | VariantFuncRef = Subst(E); | ||||||||||||
437 | } | ||||||||||||
438 | |||||||||||||
439 | // Copy the template version of the OMPTraitInfo and run substitute on all | ||||||||||||
440 | // score and condition expressiosn. | ||||||||||||
441 | OMPTraitInfo &TI = S.getASTContext().getNewOMPTraitInfo(); | ||||||||||||
442 | TI = *Attr.getTraitInfos(); | ||||||||||||
443 | |||||||||||||
444 | // Try to substitute template parameters in score and condition expressions. | ||||||||||||
445 | auto SubstScoreOrConditionExpr = [&S, Subst](Expr *&E, bool) { | ||||||||||||
446 | if (E) { | ||||||||||||
447 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
448 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
449 | ExprResult ER = Subst(E); | ||||||||||||
450 | if (ER.isUsable()) | ||||||||||||
451 | E = ER.get(); | ||||||||||||
452 | else | ||||||||||||
453 | return true; | ||||||||||||
454 | } | ||||||||||||
455 | return false; | ||||||||||||
456 | }; | ||||||||||||
457 | if (TI.anyScoreOrCondition(SubstScoreOrConditionExpr)) | ||||||||||||
458 | return; | ||||||||||||
459 | |||||||||||||
460 | Expr *E = VariantFuncRef.get(); | ||||||||||||
461 | |||||||||||||
462 | // Check function/variant ref for `omp declare variant` but not for `omp | ||||||||||||
463 | // begin declare variant` (which use implicit attributes). | ||||||||||||
464 | Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData = | ||||||||||||
465 | S.checkOpenMPDeclareVariantFunction(S.ConvertDeclToDeclGroup(New), E, TI, | ||||||||||||
466 | Attr.appendArgs_size(), | ||||||||||||
467 | Attr.getRange()); | ||||||||||||
468 | |||||||||||||
469 | if (!DeclVarData) | ||||||||||||
470 | return; | ||||||||||||
471 | |||||||||||||
472 | E = DeclVarData.value().second; | ||||||||||||
473 | FD = DeclVarData.value().first; | ||||||||||||
474 | |||||||||||||
475 | if (auto *VariantDRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) { | ||||||||||||
476 | if (auto *VariantFD = dyn_cast<FunctionDecl>(VariantDRE->getDecl())) { | ||||||||||||
477 | if (auto *VariantFTD = VariantFD->getDescribedFunctionTemplate()) { | ||||||||||||
478 | if (!VariantFTD->isThisDeclarationADefinition()) | ||||||||||||
479 | return; | ||||||||||||
480 | Sema::TentativeAnalysisScope Trap(S); | ||||||||||||
481 | const TemplateArgumentList *TAL = TemplateArgumentList::CreateCopy( | ||||||||||||
482 | S.Context, TemplateArgs.getInnermost()); | ||||||||||||
483 | |||||||||||||
484 | auto *SubstFD = S.InstantiateFunctionDeclaration(VariantFTD, TAL, | ||||||||||||
485 | New->getLocation()); | ||||||||||||
486 | if (!SubstFD) | ||||||||||||
487 | return; | ||||||||||||
488 | QualType NewType = S.Context.mergeFunctionTypes( | ||||||||||||
489 | SubstFD->getType(), FD->getType(), | ||||||||||||
490 | /* OfBlockPointer */ false, | ||||||||||||
491 | /* Unqualified */ false, /* AllowCXX */ true); | ||||||||||||
492 | if (NewType.isNull()) | ||||||||||||
493 | return; | ||||||||||||
494 | S.InstantiateFunctionDefinition( | ||||||||||||
495 | New->getLocation(), SubstFD, /* Recursive */ true, | ||||||||||||
496 | /* DefinitionRequired */ false, /* AtEndOfTU */ false); | ||||||||||||
497 | SubstFD->setInstantiationIsPending(!SubstFD->isDefined()); | ||||||||||||
498 | E = DeclRefExpr::Create(S.Context, NestedNameSpecifierLoc(), | ||||||||||||
499 | SourceLocation(), SubstFD, | ||||||||||||
500 | /* RefersToEnclosingVariableOrCapture */ false, | ||||||||||||
501 | /* NameLoc */ SubstFD->getLocation(), | ||||||||||||
502 | SubstFD->getType(), ExprValueKind::VK_PRValue); | ||||||||||||
503 | } | ||||||||||||
504 | } | ||||||||||||
505 | } | ||||||||||||
506 | |||||||||||||
507 | SmallVector<Expr *, 8> NothingExprs; | ||||||||||||
508 | SmallVector<Expr *, 8> NeedDevicePtrExprs; | ||||||||||||
509 | SmallVector<OMPInteropInfo, 4> AppendArgs; | ||||||||||||
510 | |||||||||||||
511 | for (Expr *E : Attr.adjustArgsNothing()) { | ||||||||||||
512 | ExprResult ER = Subst(E); | ||||||||||||
513 | if (ER.isInvalid()) | ||||||||||||
514 | continue; | ||||||||||||
515 | NothingExprs.push_back(ER.get()); | ||||||||||||
516 | } | ||||||||||||
517 | for (Expr *E : Attr.adjustArgsNeedDevicePtr()) { | ||||||||||||
518 | ExprResult ER = Subst(E); | ||||||||||||
519 | if (ER.isInvalid()) | ||||||||||||
520 | continue; | ||||||||||||
521 | NeedDevicePtrExprs.push_back(ER.get()); | ||||||||||||
522 | } | ||||||||||||
523 | for (OMPInteropInfo &II : Attr.appendArgs()) { | ||||||||||||
524 | // When prefer_type is implemented for append_args handle them here too. | ||||||||||||
525 | AppendArgs.emplace_back(II.IsTarget, II.IsTargetSync); | ||||||||||||
526 | } | ||||||||||||
527 | |||||||||||||
528 | S.ActOnOpenMPDeclareVariantDirective( | ||||||||||||
529 | FD, E, TI, NothingExprs, NeedDevicePtrExprs, AppendArgs, SourceLocation(), | ||||||||||||
530 | SourceLocation(), Attr.getRange()); | ||||||||||||
531 | } | ||||||||||||
532 | |||||||||||||
533 | static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr( | ||||||||||||
534 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
535 | const AMDGPUFlatWorkGroupSizeAttr &Attr, Decl *New) { | ||||||||||||
536 | // Both min and max expression are constant expressions. | ||||||||||||
537 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
538 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
539 | |||||||||||||
540 | ExprResult Result = S.SubstExpr(Attr.getMin(), TemplateArgs); | ||||||||||||
541 | if (Result.isInvalid()) | ||||||||||||
542 | return; | ||||||||||||
543 | Expr *MinExpr = Result.getAs<Expr>(); | ||||||||||||
544 | |||||||||||||
545 | Result = S.SubstExpr(Attr.getMax(), TemplateArgs); | ||||||||||||
546 | if (Result.isInvalid()) | ||||||||||||
547 | return; | ||||||||||||
548 | Expr *MaxExpr = Result.getAs<Expr>(); | ||||||||||||
549 | |||||||||||||
550 | S.addAMDGPUFlatWorkGroupSizeAttr(New, Attr, MinExpr, MaxExpr); | ||||||||||||
551 | } | ||||||||||||
552 | |||||||||||||
553 | static ExplicitSpecifier | ||||||||||||
554 | instantiateExplicitSpecifier(Sema &S, | ||||||||||||
555 | const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
556 | ExplicitSpecifier ES, FunctionDecl *New) { | ||||||||||||
557 | if (!ES.getExpr()) | ||||||||||||
558 | return ES; | ||||||||||||
559 | Expr *OldCond = ES.getExpr(); | ||||||||||||
560 | Expr *Cond = nullptr; | ||||||||||||
561 | { | ||||||||||||
562 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
563 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
564 | ExprResult SubstResult = S.SubstExpr(OldCond, TemplateArgs); | ||||||||||||
565 | if (SubstResult.isInvalid()) { | ||||||||||||
566 | return ExplicitSpecifier::Invalid(); | ||||||||||||
567 | } | ||||||||||||
568 | Cond = SubstResult.get(); | ||||||||||||
569 | } | ||||||||||||
570 | ExplicitSpecifier Result(Cond, ES.getKind()); | ||||||||||||
571 | if (!Cond->isTypeDependent()) | ||||||||||||
572 | S.tryResolveExplicitSpecifier(Result); | ||||||||||||
573 | return Result; | ||||||||||||
574 | } | ||||||||||||
575 | |||||||||||||
576 | static void instantiateDependentAMDGPUWavesPerEUAttr( | ||||||||||||
577 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
578 | const AMDGPUWavesPerEUAttr &Attr, Decl *New) { | ||||||||||||
579 | // Both min and max expression are constant expressions. | ||||||||||||
580 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
581 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
582 | |||||||||||||
583 | ExprResult Result = S.SubstExpr(Attr.getMin(), TemplateArgs); | ||||||||||||
584 | if (Result.isInvalid()) | ||||||||||||
585 | return; | ||||||||||||
586 | Expr *MinExpr = Result.getAs<Expr>(); | ||||||||||||
587 | |||||||||||||
588 | Expr *MaxExpr = nullptr; | ||||||||||||
589 | if (auto Max = Attr.getMax()) { | ||||||||||||
590 | Result = S.SubstExpr(Max, TemplateArgs); | ||||||||||||
591 | if (Result.isInvalid()) | ||||||||||||
592 | return; | ||||||||||||
593 | MaxExpr = Result.getAs<Expr>(); | ||||||||||||
594 | } | ||||||||||||
595 | |||||||||||||
596 | S.addAMDGPUWavesPerEUAttr(New, Attr, MinExpr, MaxExpr); | ||||||||||||
597 | } | ||||||||||||
598 | |||||||||||||
599 | // This doesn't take any template parameters, but we have a custom action that | ||||||||||||
600 | // needs to happen when the kernel itself is instantiated. We need to run the | ||||||||||||
601 | // ItaniumMangler to mark the names required to name this kernel. | ||||||||||||
602 | static void instantiateDependentSYCLKernelAttr( | ||||||||||||
603 | Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
604 | const SYCLKernelAttr &Attr, Decl *New) { | ||||||||||||
605 | New->addAttr(Attr.clone(S.getASTContext())); | ||||||||||||
606 | } | ||||||||||||
607 | |||||||||||||
608 | /// Determine whether the attribute A might be relevant to the declaration D. | ||||||||||||
609 | /// If not, we can skip instantiating it. The attribute may or may not have | ||||||||||||
610 | /// been instantiated yet. | ||||||||||||
611 | static bool isRelevantAttr(Sema &S, const Decl *D, const Attr *A) { | ||||||||||||
612 | // 'preferred_name' is only relevant to the matching specialization of the | ||||||||||||
613 | // template. | ||||||||||||
614 | if (const auto *PNA = dyn_cast<PreferredNameAttr>(A)) { | ||||||||||||
615 | QualType T = PNA->getTypedefType(); | ||||||||||||
616 | const auto *RD = cast<CXXRecordDecl>(D); | ||||||||||||
617 | if (!T->isDependentType() && !RD->isDependentContext() && | ||||||||||||
618 | !declaresSameEntity(T->getAsCXXRecordDecl(), RD)) | ||||||||||||
619 | return false; | ||||||||||||
620 | for (const auto *ExistingPNA : D->specific_attrs<PreferredNameAttr>()) | ||||||||||||
621 | if (S.Context.hasSameType(ExistingPNA->getTypedefType(), | ||||||||||||
622 | PNA->getTypedefType())) | ||||||||||||
623 | return false; | ||||||||||||
624 | return true; | ||||||||||||
625 | } | ||||||||||||
626 | |||||||||||||
627 | if (const auto *BA = dyn_cast<BuiltinAttr>(A)) { | ||||||||||||
628 | const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); | ||||||||||||
629 | switch (BA->getID()) { | ||||||||||||
630 | case Builtin::BIforward: | ||||||||||||
631 | // Do not treat 'std::forward' as a builtin if it takes an rvalue reference | ||||||||||||
632 | // type and returns an lvalue reference type. The library implementation | ||||||||||||
633 | // will produce an error in this case; don't get in its way. | ||||||||||||
634 | if (FD && FD->getNumParams() >= 1 && | ||||||||||||
635 | FD->getParamDecl(0)->getType()->isRValueReferenceType() && | ||||||||||||
636 | FD->getReturnType()->isLValueReferenceType()) { | ||||||||||||
637 | return false; | ||||||||||||
638 | } | ||||||||||||
639 | [[fallthrough]]; | ||||||||||||
640 | case Builtin::BImove: | ||||||||||||
641 | case Builtin::BImove_if_noexcept: | ||||||||||||
642 | // HACK: Super-old versions of libc++ (3.1 and earlier) provide | ||||||||||||
643 | // std::forward and std::move overloads that sometimes return by value | ||||||||||||
644 | // instead of by reference when building in C++98 mode. Don't treat such | ||||||||||||
645 | // cases as builtins. | ||||||||||||
646 | if (FD && !FD->getReturnType()->isReferenceType()) | ||||||||||||
647 | return false; | ||||||||||||
648 | break; | ||||||||||||
649 | } | ||||||||||||
650 | } | ||||||||||||
651 | |||||||||||||
652 | return true; | ||||||||||||
653 | } | ||||||||||||
654 | |||||||||||||
655 | void Sema::InstantiateAttrsForDecl( | ||||||||||||
656 | const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, | ||||||||||||
657 | Decl *New, LateInstantiatedAttrVec *LateAttrs, | ||||||||||||
658 | LocalInstantiationScope *OuterMostScope) { | ||||||||||||
659 | if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) { | ||||||||||||
660 | // FIXME: This function is called multiple times for the same template | ||||||||||||
661 | // specialization. We should only instantiate attributes that were added | ||||||||||||
662 | // since the previous instantiation. | ||||||||||||
663 | for (const auto *TmplAttr : Tmpl->attrs()) { | ||||||||||||
664 | if (!isRelevantAttr(*this, New, TmplAttr)) | ||||||||||||
665 | continue; | ||||||||||||
666 | |||||||||||||
667 | // FIXME: If any of the special case versions from InstantiateAttrs become | ||||||||||||
668 | // applicable to template declaration, we'll need to add them here. | ||||||||||||
669 | CXXThisScopeRAII ThisScope( | ||||||||||||
670 | *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()), | ||||||||||||
671 | Qualifiers(), ND->isCXXInstanceMember()); | ||||||||||||
672 | |||||||||||||
673 | Attr *NewAttr = sema::instantiateTemplateAttributeForDecl( | ||||||||||||
674 | TmplAttr, Context, *this, TemplateArgs); | ||||||||||||
675 | if (NewAttr && isRelevantAttr(*this, New, NewAttr)) | ||||||||||||
676 | New->addAttr(NewAttr); | ||||||||||||
677 | } | ||||||||||||
678 | } | ||||||||||||
679 | } | ||||||||||||
680 | |||||||||||||
681 | static Sema::RetainOwnershipKind | ||||||||||||
682 | attrToRetainOwnershipKind(const Attr *A) { | ||||||||||||
683 | switch (A->getKind()) { | ||||||||||||
684 | case clang::attr::CFConsumed: | ||||||||||||
685 | return Sema::RetainOwnershipKind::CF; | ||||||||||||
686 | case clang::attr::OSConsumed: | ||||||||||||
687 | return Sema::RetainOwnershipKind::OS; | ||||||||||||
688 | case clang::attr::NSConsumed: | ||||||||||||
689 | return Sema::RetainOwnershipKind::NS; | ||||||||||||
690 | default: | ||||||||||||
691 | llvm_unreachable("Wrong argument supplied")::llvm::llvm_unreachable_internal("Wrong argument supplied", "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp" , 691); | ||||||||||||
692 | } | ||||||||||||
693 | } | ||||||||||||
694 | |||||||||||||
695 | void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
696 | const Decl *Tmpl, Decl *New, | ||||||||||||
697 | LateInstantiatedAttrVec *LateAttrs, | ||||||||||||
698 | LocalInstantiationScope *OuterMostScope) { | ||||||||||||
699 | for (const auto *TmplAttr : Tmpl->attrs()) { | ||||||||||||
700 | if (!isRelevantAttr(*this, New, TmplAttr)) | ||||||||||||
701 | continue; | ||||||||||||
702 | |||||||||||||
703 | // FIXME: This should be generalized to more than just the AlignedAttr. | ||||||||||||
704 | const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr); | ||||||||||||
705 | if (Aligned && Aligned->isAlignmentDependent()) { | ||||||||||||
706 | instantiateDependentAlignedAttr(*this, TemplateArgs, Aligned, New); | ||||||||||||
707 | continue; | ||||||||||||
708 | } | ||||||||||||
709 | |||||||||||||
710 | if (const auto *AssumeAligned = dyn_cast<AssumeAlignedAttr>(TmplAttr)) { | ||||||||||||
711 | instantiateDependentAssumeAlignedAttr(*this, TemplateArgs, AssumeAligned, New); | ||||||||||||
712 | continue; | ||||||||||||
713 | } | ||||||||||||
714 | |||||||||||||
715 | if (const auto *AlignValue = dyn_cast<AlignValueAttr>(TmplAttr)) { | ||||||||||||
716 | instantiateDependentAlignValueAttr(*this, TemplateArgs, AlignValue, New); | ||||||||||||
717 | continue; | ||||||||||||
718 | } | ||||||||||||
719 | |||||||||||||
720 | if (const auto *AllocAlign = dyn_cast<AllocAlignAttr>(TmplAttr)) { | ||||||||||||
721 | instantiateDependentAllocAlignAttr(*this, TemplateArgs, AllocAlign, New); | ||||||||||||
722 | continue; | ||||||||||||
723 | } | ||||||||||||
724 | |||||||||||||
725 | if (const auto *Annotate = dyn_cast<AnnotateAttr>(TmplAttr)) { | ||||||||||||
726 | instantiateDependentAnnotationAttr(*this, TemplateArgs, Annotate, New); | ||||||||||||
727 | continue; | ||||||||||||
728 | } | ||||||||||||
729 | |||||||||||||
730 | if (const auto *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr)) { | ||||||||||||
731 | instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl, | ||||||||||||
732 | cast<FunctionDecl>(New)); | ||||||||||||
733 | continue; | ||||||||||||
734 | } | ||||||||||||
735 | |||||||||||||
736 | if (const auto *DiagnoseIf = dyn_cast<DiagnoseIfAttr>(TmplAttr)) { | ||||||||||||
737 | instantiateDependentDiagnoseIfAttr(*this, TemplateArgs, DiagnoseIf, Tmpl, | ||||||||||||
738 | cast<FunctionDecl>(New)); | ||||||||||||
739 | continue; | ||||||||||||
740 | } | ||||||||||||
741 | |||||||||||||
742 | if (const auto *CUDALaunchBounds = | ||||||||||||
743 | dyn_cast<CUDALaunchBoundsAttr>(TmplAttr)) { | ||||||||||||
744 | instantiateDependentCUDALaunchBoundsAttr(*this, TemplateArgs, | ||||||||||||
745 | *CUDALaunchBounds, New); | ||||||||||||
746 | continue; | ||||||||||||
747 | } | ||||||||||||
748 | |||||||||||||
749 | if (const auto *Mode = dyn_cast<ModeAttr>(TmplAttr)) { | ||||||||||||
750 | instantiateDependentModeAttr(*this, TemplateArgs, *Mode, New); | ||||||||||||
751 | continue; | ||||||||||||
752 | } | ||||||||||||
753 | |||||||||||||
754 | if (const auto *OMPAttr = dyn_cast<OMPDeclareSimdDeclAttr>(TmplAttr)) { | ||||||||||||
755 | instantiateOMPDeclareSimdDeclAttr(*this, TemplateArgs, *OMPAttr, New); | ||||||||||||
756 | continue; | ||||||||||||
757 | } | ||||||||||||
758 | |||||||||||||
759 | if (const auto *OMPAttr = dyn_cast<OMPDeclareVariantAttr>(TmplAttr)) { | ||||||||||||
760 | instantiateOMPDeclareVariantAttr(*this, TemplateArgs, *OMPAttr, New); | ||||||||||||
761 | continue; | ||||||||||||
762 | } | ||||||||||||
763 | |||||||||||||
764 | if (const auto *AMDGPUFlatWorkGroupSize = | ||||||||||||
765 | dyn_cast<AMDGPUFlatWorkGroupSizeAttr>(TmplAttr)) { | ||||||||||||
766 | instantiateDependentAMDGPUFlatWorkGroupSizeAttr( | ||||||||||||
767 | *this, TemplateArgs, *AMDGPUFlatWorkGroupSize, New); | ||||||||||||
768 | } | ||||||||||||
769 | |||||||||||||
770 | if (const auto *AMDGPUFlatWorkGroupSize = | ||||||||||||
771 | dyn_cast<AMDGPUWavesPerEUAttr>(TmplAttr)) { | ||||||||||||
772 | instantiateDependentAMDGPUWavesPerEUAttr(*this, TemplateArgs, | ||||||||||||
773 | *AMDGPUFlatWorkGroupSize, New); | ||||||||||||
774 | } | ||||||||||||
775 | |||||||||||||
776 | // Existing DLL attribute on the instantiation takes precedence. | ||||||||||||
777 | if (TmplAttr->getKind() == attr::DLLExport || | ||||||||||||
778 | TmplAttr->getKind() == attr::DLLImport) { | ||||||||||||
779 | if (New->hasAttr<DLLExportAttr>() || New->hasAttr<DLLImportAttr>()) { | ||||||||||||
780 | continue; | ||||||||||||
781 | } | ||||||||||||
782 | } | ||||||||||||
783 | |||||||||||||
784 | if (const auto *ABIAttr = dyn_cast<ParameterABIAttr>(TmplAttr)) { | ||||||||||||
785 | AddParameterABIAttr(New, *ABIAttr, ABIAttr->getABI()); | ||||||||||||
786 | continue; | ||||||||||||
787 | } | ||||||||||||
788 | |||||||||||||
789 | if (isa<NSConsumedAttr>(TmplAttr) || isa<OSConsumedAttr>(TmplAttr) || | ||||||||||||
790 | isa<CFConsumedAttr>(TmplAttr)) { | ||||||||||||
791 | AddXConsumedAttr(New, *TmplAttr, attrToRetainOwnershipKind(TmplAttr), | ||||||||||||
792 | /*template instantiation=*/true); | ||||||||||||
793 | continue; | ||||||||||||
794 | } | ||||||||||||
795 | |||||||||||||
796 | if (auto *A = dyn_cast<PointerAttr>(TmplAttr)) { | ||||||||||||
797 | if (!New->hasAttr<PointerAttr>()) | ||||||||||||
798 | New->addAttr(A->clone(Context)); | ||||||||||||
799 | continue; | ||||||||||||
800 | } | ||||||||||||
801 | |||||||||||||
802 | if (auto *A = dyn_cast<OwnerAttr>(TmplAttr)) { | ||||||||||||
803 | if (!New->hasAttr<OwnerAttr>()) | ||||||||||||
804 | New->addAttr(A->clone(Context)); | ||||||||||||
805 | continue; | ||||||||||||
806 | } | ||||||||||||
807 | |||||||||||||
808 | if (auto *A = dyn_cast<SYCLKernelAttr>(TmplAttr)) { | ||||||||||||
809 | instantiateDependentSYCLKernelAttr(*this, TemplateArgs, *A, New); | ||||||||||||
810 | continue; | ||||||||||||
811 | } | ||||||||||||
812 | |||||||||||||
813 | assert(!TmplAttr->isPackExpansion())(static_cast <bool> (!TmplAttr->isPackExpansion()) ? void (0) : __assert_fail ("!TmplAttr->isPackExpansion()", "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 813, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
814 | if (TmplAttr->isLateParsed() && LateAttrs) { | ||||||||||||
815 | // Late parsed attributes must be instantiated and attached after the | ||||||||||||
816 | // enclosing class has been instantiated. See Sema::InstantiateClass. | ||||||||||||
817 | LocalInstantiationScope *Saved = nullptr; | ||||||||||||
818 | if (CurrentInstantiationScope) | ||||||||||||
819 | Saved = CurrentInstantiationScope->cloneScopes(OuterMostScope); | ||||||||||||
820 | LateAttrs->push_back(LateInstantiatedAttribute(TmplAttr, Saved, New)); | ||||||||||||
821 | } else { | ||||||||||||
822 | // Allow 'this' within late-parsed attributes. | ||||||||||||
823 | auto *ND = cast<NamedDecl>(New); | ||||||||||||
824 | auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()); | ||||||||||||
825 | CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(), | ||||||||||||
826 | ND->isCXXInstanceMember()); | ||||||||||||
827 | |||||||||||||
828 | Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context, | ||||||||||||
829 | *this, TemplateArgs); | ||||||||||||
830 | if (NewAttr && isRelevantAttr(*this, New, TmplAttr)) | ||||||||||||
831 | New->addAttr(NewAttr); | ||||||||||||
832 | } | ||||||||||||
833 | } | ||||||||||||
834 | } | ||||||||||||
835 | |||||||||||||
836 | /// In the MS ABI, we need to instantiate default arguments of dllexported | ||||||||||||
837 | /// default constructors along with the constructor definition. This allows IR | ||||||||||||
838 | /// gen to emit a constructor closure which calls the default constructor with | ||||||||||||
839 | /// its default arguments. | ||||||||||||
840 | void Sema::InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor) { | ||||||||||||
841 | assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&(static_cast <bool> (Context.getTargetInfo().getCXXABI( ).isMicrosoft() && Ctor->isDefaultConstructor()) ? void (0) : __assert_fail ("Context.getTargetInfo().getCXXABI().isMicrosoft() && Ctor->isDefaultConstructor()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 842, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
842 | Ctor->isDefaultConstructor())(static_cast <bool> (Context.getTargetInfo().getCXXABI( ).isMicrosoft() && Ctor->isDefaultConstructor()) ? void (0) : __assert_fail ("Context.getTargetInfo().getCXXABI().isMicrosoft() && Ctor->isDefaultConstructor()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 842, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
843 | unsigned NumParams = Ctor->getNumParams(); | ||||||||||||
844 | if (NumParams == 0) | ||||||||||||
845 | return; | ||||||||||||
846 | DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>(); | ||||||||||||
847 | if (!Attr) | ||||||||||||
848 | return; | ||||||||||||
849 | for (unsigned I = 0; I != NumParams; ++I) { | ||||||||||||
850 | (void)CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor, | ||||||||||||
851 | Ctor->getParamDecl(I)); | ||||||||||||
852 | CleanupVarDeclMarking(); | ||||||||||||
853 | } | ||||||||||||
854 | } | ||||||||||||
855 | |||||||||||||
856 | /// Get the previous declaration of a declaration for the purposes of template | ||||||||||||
857 | /// instantiation. If this finds a previous declaration, then the previous | ||||||||||||
858 | /// declaration of the instantiation of D should be an instantiation of the | ||||||||||||
859 | /// result of this function. | ||||||||||||
860 | template<typename DeclT> | ||||||||||||
861 | static DeclT *getPreviousDeclForInstantiation(DeclT *D) { | ||||||||||||
862 | DeclT *Result = D->getPreviousDecl(); | ||||||||||||
863 | |||||||||||||
864 | // If the declaration is within a class, and the previous declaration was | ||||||||||||
865 | // merged from a different definition of that class, then we don't have a | ||||||||||||
866 | // previous declaration for the purpose of template instantiation. | ||||||||||||
867 | if (Result && isa<CXXRecordDecl>(D->getDeclContext()) && | ||||||||||||
868 | D->getLexicalDeclContext() != Result->getLexicalDeclContext()) | ||||||||||||
869 | return nullptr; | ||||||||||||
870 | |||||||||||||
871 | return Result; | ||||||||||||
872 | } | ||||||||||||
873 | |||||||||||||
874 | Decl * | ||||||||||||
875 | TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) { | ||||||||||||
876 | llvm_unreachable("Translation units cannot be instantiated")::llvm::llvm_unreachable_internal("Translation units cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 876); | ||||||||||||
877 | } | ||||||||||||
878 | |||||||||||||
879 | Decl *TemplateDeclInstantiator::VisitHLSLBufferDecl(HLSLBufferDecl *Decl) { | ||||||||||||
880 | llvm_unreachable("HLSL buffer declarations cannot be instantiated")::llvm::llvm_unreachable_internal("HLSL buffer declarations cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 880); | ||||||||||||
881 | } | ||||||||||||
882 | |||||||||||||
883 | Decl * | ||||||||||||
884 | TemplateDeclInstantiator::VisitPragmaCommentDecl(PragmaCommentDecl *D) { | ||||||||||||
885 | llvm_unreachable("pragma comment cannot be instantiated")::llvm::llvm_unreachable_internal("pragma comment cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 885); | ||||||||||||
886 | } | ||||||||||||
887 | |||||||||||||
888 | Decl *TemplateDeclInstantiator::VisitPragmaDetectMismatchDecl( | ||||||||||||
889 | PragmaDetectMismatchDecl *D) { | ||||||||||||
890 | llvm_unreachable("pragma comment cannot be instantiated")::llvm::llvm_unreachable_internal("pragma comment cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 890); | ||||||||||||
891 | } | ||||||||||||
892 | |||||||||||||
893 | Decl * | ||||||||||||
894 | TemplateDeclInstantiator::VisitExternCContextDecl(ExternCContextDecl *D) { | ||||||||||||
895 | llvm_unreachable("extern \"C\" context cannot be instantiated")::llvm::llvm_unreachable_internal("extern \"C\" context cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 895); | ||||||||||||
896 | } | ||||||||||||
897 | |||||||||||||
898 | Decl *TemplateDeclInstantiator::VisitMSGuidDecl(MSGuidDecl *D) { | ||||||||||||
899 | llvm_unreachable("GUID declaration cannot be instantiated")::llvm::llvm_unreachable_internal("GUID declaration cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 899); | ||||||||||||
900 | } | ||||||||||||
901 | |||||||||||||
902 | Decl *TemplateDeclInstantiator::VisitUnnamedGlobalConstantDecl( | ||||||||||||
903 | UnnamedGlobalConstantDecl *D) { | ||||||||||||
904 | llvm_unreachable("UnnamedGlobalConstantDecl cannot be instantiated")::llvm::llvm_unreachable_internal("UnnamedGlobalConstantDecl cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 904); | ||||||||||||
905 | } | ||||||||||||
906 | |||||||||||||
907 | Decl *TemplateDeclInstantiator::VisitTemplateParamObjectDecl( | ||||||||||||
908 | TemplateParamObjectDecl *D) { | ||||||||||||
909 | llvm_unreachable("template parameter objects cannot be instantiated")::llvm::llvm_unreachable_internal("template parameter objects cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 909); | ||||||||||||
910 | } | ||||||||||||
911 | |||||||||||||
912 | Decl * | ||||||||||||
913 | TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) { | ||||||||||||
914 | LabelDecl *Inst = LabelDecl::Create(SemaRef.Context, Owner, D->getLocation(), | ||||||||||||
915 | D->getIdentifier()); | ||||||||||||
916 | Owner->addDecl(Inst); | ||||||||||||
917 | return Inst; | ||||||||||||
918 | } | ||||||||||||
919 | |||||||||||||
920 | Decl * | ||||||||||||
921 | TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) { | ||||||||||||
922 | llvm_unreachable("Namespaces cannot be instantiated")::llvm::llvm_unreachable_internal("Namespaces cannot be instantiated" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 922); | ||||||||||||
923 | } | ||||||||||||
924 | |||||||||||||
925 | Decl * | ||||||||||||
926 | TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { | ||||||||||||
927 | NamespaceAliasDecl *Inst | ||||||||||||
928 | = NamespaceAliasDecl::Create(SemaRef.Context, Owner, | ||||||||||||
929 | D->getNamespaceLoc(), | ||||||||||||
930 | D->getAliasLoc(), | ||||||||||||
931 | D->getIdentifier(), | ||||||||||||
932 | D->getQualifierLoc(), | ||||||||||||
933 | D->getTargetNameLoc(), | ||||||||||||
934 | D->getNamespace()); | ||||||||||||
935 | Owner->addDecl(Inst); | ||||||||||||
936 | return Inst; | ||||||||||||
937 | } | ||||||||||||
938 | |||||||||||||
939 | Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, | ||||||||||||
940 | bool IsTypeAlias) { | ||||||||||||
941 | bool Invalid = false; | ||||||||||||
942 | TypeSourceInfo *DI = D->getTypeSourceInfo(); | ||||||||||||
943 | if (DI->getType()->isInstantiationDependentType() || | ||||||||||||
944 | DI->getType()->isVariablyModifiedType()) { | ||||||||||||
945 | DI = SemaRef.SubstType(DI, TemplateArgs, | ||||||||||||
946 | D->getLocation(), D->getDeclName()); | ||||||||||||
947 | if (!DI) { | ||||||||||||
948 | Invalid = true; | ||||||||||||
949 | DI = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.Context.IntTy); | ||||||||||||
950 | } | ||||||||||||
951 | } else { | ||||||||||||
952 | SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType()); | ||||||||||||
953 | } | ||||||||||||
954 | |||||||||||||
955 | // HACK: 2012-10-23 g++ has a bug where it gets the value kind of ?: wrong. | ||||||||||||
956 | // libstdc++ relies upon this bug in its implementation of common_type. If we | ||||||||||||
957 | // happen to be processing that implementation, fake up the g++ ?: | ||||||||||||
958 | // semantics. See LWG issue 2141 for more information on the bug. The bugs | ||||||||||||
959 | // are fixed in g++ and libstdc++ 4.9.0 (2014-04-22). | ||||||||||||
960 | const DecltypeType *DT = DI->getType()->getAs<DecltypeType>(); | ||||||||||||
961 | CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext()); | ||||||||||||
962 | if (DT && RD && isa<ConditionalOperator>(DT->getUnderlyingExpr()) && | ||||||||||||
963 | DT->isReferenceType() && | ||||||||||||
964 | RD->getEnclosingNamespaceContext() == SemaRef.getStdNamespace() && | ||||||||||||
965 | RD->getIdentifier() && RD->getIdentifier()->isStr("common_type") && | ||||||||||||
966 | D->getIdentifier() && D->getIdentifier()->isStr("type") && | ||||||||||||
967 | SemaRef.getSourceManager().isInSystemHeader(D->getBeginLoc())) | ||||||||||||
968 | // Fold it to the (non-reference) type which g++ would have produced. | ||||||||||||
969 | DI = SemaRef.Context.getTrivialTypeSourceInfo( | ||||||||||||
970 | DI->getType().getNonReferenceType()); | ||||||||||||
971 | |||||||||||||
972 | // Create the new typedef | ||||||||||||
973 | TypedefNameDecl *Typedef; | ||||||||||||
974 | if (IsTypeAlias) | ||||||||||||
975 | Typedef = TypeAliasDecl::Create(SemaRef.Context, Owner, D->getBeginLoc(), | ||||||||||||
976 | D->getLocation(), D->getIdentifier(), DI); | ||||||||||||
977 | else | ||||||||||||
978 | Typedef = TypedefDecl::Create(SemaRef.Context, Owner, D->getBeginLoc(), | ||||||||||||
979 | D->getLocation(), D->getIdentifier(), DI); | ||||||||||||
980 | if (Invalid) | ||||||||||||
981 | Typedef->setInvalidDecl(); | ||||||||||||
982 | |||||||||||||
983 | // If the old typedef was the name for linkage purposes of an anonymous | ||||||||||||
984 | // tag decl, re-establish that relationship for the new typedef. | ||||||||||||
985 | if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) { | ||||||||||||
986 | TagDecl *oldTag = oldTagType->getDecl(); | ||||||||||||
987 | if (oldTag->getTypedefNameForAnonDecl() == D && !Invalid) { | ||||||||||||
988 | TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl(); | ||||||||||||
989 | assert(!newTag->hasNameForLinkage())(static_cast <bool> (!newTag->hasNameForLinkage()) ? void (0) : __assert_fail ("!newTag->hasNameForLinkage()", "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 989, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
990 | newTag->setTypedefNameForAnonDecl(Typedef); | ||||||||||||
991 | } | ||||||||||||
992 | } | ||||||||||||
993 | |||||||||||||
994 | if (TypedefNameDecl *Prev = getPreviousDeclForInstantiation(D)) { | ||||||||||||
995 | NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev, | ||||||||||||
996 | TemplateArgs); | ||||||||||||
997 | if (!InstPrev) | ||||||||||||
998 | return nullptr; | ||||||||||||
999 | |||||||||||||
1000 | TypedefNameDecl *InstPrevTypedef = cast<TypedefNameDecl>(InstPrev); | ||||||||||||
1001 | |||||||||||||
1002 | // If the typedef types are not identical, reject them. | ||||||||||||
1003 | SemaRef.isIncompatibleTypedef(InstPrevTypedef, Typedef); | ||||||||||||
1004 | |||||||||||||
1005 | Typedef->setPreviousDecl(InstPrevTypedef); | ||||||||||||
1006 | } | ||||||||||||
1007 | |||||||||||||
1008 | SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef); | ||||||||||||
1009 | |||||||||||||
1010 | if (D->getUnderlyingType()->getAs<DependentNameType>()) | ||||||||||||
1011 | SemaRef.inferGslPointerAttribute(Typedef); | ||||||||||||
1012 | |||||||||||||
1013 | Typedef->setAccess(D->getAccess()); | ||||||||||||
1014 | Typedef->setReferenced(D->isReferenced()); | ||||||||||||
1015 | |||||||||||||
1016 | return Typedef; | ||||||||||||
1017 | } | ||||||||||||
1018 | |||||||||||||
1019 | Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) { | ||||||||||||
1020 | Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false); | ||||||||||||
1021 | if (Typedef) | ||||||||||||
1022 | Owner->addDecl(Typedef); | ||||||||||||
1023 | return Typedef; | ||||||||||||
1024 | } | ||||||||||||
1025 | |||||||||||||
1026 | Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) { | ||||||||||||
1027 | Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true); | ||||||||||||
1028 | if (Typedef) | ||||||||||||
1029 | Owner->addDecl(Typedef); | ||||||||||||
1030 | return Typedef; | ||||||||||||
1031 | } | ||||||||||||
1032 | |||||||||||||
1033 | Decl * | ||||||||||||
1034 | TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { | ||||||||||||
1035 | // Create a local instantiation scope for this type alias template, which | ||||||||||||
1036 | // will contain the instantiations of the template parameters. | ||||||||||||
1037 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
1038 | |||||||||||||
1039 | TemplateParameterList *TempParams = D->getTemplateParameters(); | ||||||||||||
1040 | TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | ||||||||||||
1041 | if (!InstParams) | ||||||||||||
1042 | return nullptr; | ||||||||||||
1043 | |||||||||||||
1044 | TypeAliasDecl *Pattern = D->getTemplatedDecl(); | ||||||||||||
1045 | |||||||||||||
1046 | TypeAliasTemplateDecl *PrevAliasTemplate = nullptr; | ||||||||||||
1047 | if (getPreviousDeclForInstantiation<TypedefNameDecl>(Pattern)) { | ||||||||||||
1048 | DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); | ||||||||||||
1049 | if (!Found.empty()) { | ||||||||||||
1050 | PrevAliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Found.front()); | ||||||||||||
1051 | } | ||||||||||||
1052 | } | ||||||||||||
1053 | |||||||||||||
1054 | TypeAliasDecl *AliasInst = cast_or_null<TypeAliasDecl>( | ||||||||||||
1055 | InstantiateTypedefNameDecl(Pattern, /*IsTypeAlias=*/true)); | ||||||||||||
1056 | if (!AliasInst) | ||||||||||||
1057 | return nullptr; | ||||||||||||
1058 | |||||||||||||
1059 | TypeAliasTemplateDecl *Inst | ||||||||||||
1060 | = TypeAliasTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(), | ||||||||||||
1061 | D->getDeclName(), InstParams, AliasInst); | ||||||||||||
1062 | AliasInst->setDescribedAliasTemplate(Inst); | ||||||||||||
1063 | if (PrevAliasTemplate) | ||||||||||||
1064 | Inst->setPreviousDecl(PrevAliasTemplate); | ||||||||||||
1065 | |||||||||||||
1066 | Inst->setAccess(D->getAccess()); | ||||||||||||
1067 | |||||||||||||
1068 | if (!PrevAliasTemplate) | ||||||||||||
1069 | Inst->setInstantiatedFromMemberTemplate(D); | ||||||||||||
1070 | |||||||||||||
1071 | Owner->addDecl(Inst); | ||||||||||||
1072 | |||||||||||||
1073 | return Inst; | ||||||||||||
1074 | } | ||||||||||||
1075 | |||||||||||||
1076 | Decl *TemplateDeclInstantiator::VisitBindingDecl(BindingDecl *D) { | ||||||||||||
1077 | auto *NewBD = BindingDecl::Create(SemaRef.Context, Owner, D->getLocation(), | ||||||||||||
1078 | D->getIdentifier()); | ||||||||||||
1079 | NewBD->setReferenced(D->isReferenced()); | ||||||||||||
1080 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewBD); | ||||||||||||
1081 | return NewBD; | ||||||||||||
1082 | } | ||||||||||||
1083 | |||||||||||||
1084 | Decl *TemplateDeclInstantiator::VisitDecompositionDecl(DecompositionDecl *D) { | ||||||||||||
1085 | // Transform the bindings first. | ||||||||||||
1086 | SmallVector<BindingDecl*, 16> NewBindings; | ||||||||||||
1087 | for (auto *OldBD : D->bindings()) | ||||||||||||
1088 | NewBindings.push_back(cast<BindingDecl>(VisitBindingDecl(OldBD))); | ||||||||||||
1089 | ArrayRef<BindingDecl*> NewBindingArray = NewBindings; | ||||||||||||
1090 | |||||||||||||
1091 | auto *NewDD = cast_or_null<DecompositionDecl>( | ||||||||||||
1092 | VisitVarDecl(D, /*InstantiatingVarTemplate=*/false, &NewBindingArray)); | ||||||||||||
1093 | |||||||||||||
1094 | if (!NewDD || NewDD->isInvalidDecl()) | ||||||||||||
1095 | for (auto *NewBD : NewBindings) | ||||||||||||
1096 | NewBD->setInvalidDecl(); | ||||||||||||
1097 | |||||||||||||
1098 | return NewDD; | ||||||||||||
1099 | } | ||||||||||||
1100 | |||||||||||||
1101 | Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { | ||||||||||||
1102 | return VisitVarDecl(D, /*InstantiatingVarTemplate=*/false); | ||||||||||||
1103 | } | ||||||||||||
1104 | |||||||||||||
1105 | Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, | ||||||||||||
1106 | bool InstantiatingVarTemplate, | ||||||||||||
1107 | ArrayRef<BindingDecl*> *Bindings) { | ||||||||||||
1108 | |||||||||||||
1109 | // Do substitution on the type of the declaration | ||||||||||||
1110 | TypeSourceInfo *DI = SemaRef.SubstType( | ||||||||||||
1111 | D->getTypeSourceInfo(), TemplateArgs, D->getTypeSpecStartLoc(), | ||||||||||||
1112 | D->getDeclName(), /*AllowDeducedTST*/true); | ||||||||||||
1113 | if (!DI) | ||||||||||||
1114 | return nullptr; | ||||||||||||
1115 | |||||||||||||
1116 | if (DI->getType()->isFunctionType()) { | ||||||||||||
1117 | SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function) | ||||||||||||
1118 | << D->isStaticDataMember() << DI->getType(); | ||||||||||||
1119 | return nullptr; | ||||||||||||
1120 | } | ||||||||||||
1121 | |||||||||||||
1122 | DeclContext *DC = Owner; | ||||||||||||
1123 | if (D->isLocalExternDecl()) | ||||||||||||
1124 | SemaRef.adjustContextForLocalExternDecl(DC); | ||||||||||||
1125 | |||||||||||||
1126 | // Build the instantiated declaration. | ||||||||||||
1127 | VarDecl *Var; | ||||||||||||
1128 | if (Bindings) | ||||||||||||
1129 | Var = DecompositionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), | ||||||||||||
1130 | D->getLocation(), DI->getType(), DI, | ||||||||||||
1131 | D->getStorageClass(), *Bindings); | ||||||||||||
1132 | else | ||||||||||||
1133 | Var = VarDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), | ||||||||||||
1134 | D->getLocation(), D->getIdentifier(), DI->getType(), | ||||||||||||
1135 | DI, D->getStorageClass()); | ||||||||||||
1136 | |||||||||||||
1137 | // In ARC, infer 'retaining' for variables of retainable type. | ||||||||||||
1138 | if (SemaRef.getLangOpts().ObjCAutoRefCount && | ||||||||||||
1139 | SemaRef.inferObjCARCLifetime(Var)) | ||||||||||||
1140 | Var->setInvalidDecl(); | ||||||||||||
1141 | |||||||||||||
1142 | if (SemaRef.getLangOpts().OpenCL) | ||||||||||||
1143 | SemaRef.deduceOpenCLAddressSpace(Var); | ||||||||||||
1144 | |||||||||||||
1145 | // Substitute the nested name specifier, if any. | ||||||||||||
1146 | if (SubstQualifier(D, Var)) | ||||||||||||
1147 | return nullptr; | ||||||||||||
1148 | |||||||||||||
1149 | SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner, | ||||||||||||
1150 | StartingScope, InstantiatingVarTemplate); | ||||||||||||
1151 | if (D->isNRVOVariable() && !Var->isInvalidDecl()) { | ||||||||||||
1152 | QualType RT; | ||||||||||||
1153 | if (auto *F = dyn_cast<FunctionDecl>(DC)) | ||||||||||||
1154 | RT = F->getReturnType(); | ||||||||||||
1155 | else if (isa<BlockDecl>(DC)) | ||||||||||||
1156 | RT = cast<FunctionType>(SemaRef.getCurBlock()->FunctionType) | ||||||||||||
1157 | ->getReturnType(); | ||||||||||||
1158 | else | ||||||||||||
1159 | llvm_unreachable("Unknown context type")::llvm::llvm_unreachable_internal("Unknown context type", "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp" , 1159); | ||||||||||||
1160 | |||||||||||||
1161 | // This is the last chance we have of checking copy elision eligibility | ||||||||||||
1162 | // for functions in dependent contexts. The sema actions for building | ||||||||||||
1163 | // the return statement during template instantiation will have no effect | ||||||||||||
1164 | // regarding copy elision, since NRVO propagation runs on the scope exit | ||||||||||||
1165 | // actions, and these are not run on instantiation. | ||||||||||||
1166 | // This might run through some VarDecls which were returned from non-taken | ||||||||||||
1167 | // 'if constexpr' branches, and these will end up being constructed on the | ||||||||||||
1168 | // return slot even if they will never be returned, as a sort of accidental | ||||||||||||
1169 | // 'optimization'. Notably, functions with 'auto' return types won't have it | ||||||||||||
1170 | // deduced by this point. Coupled with the limitation described | ||||||||||||
1171 | // previously, this makes it very hard to support copy elision for these. | ||||||||||||
1172 | Sema::NamedReturnInfo Info = SemaRef.getNamedReturnInfo(Var); | ||||||||||||
1173 | bool NRVO = SemaRef.getCopyElisionCandidate(Info, RT) != nullptr; | ||||||||||||
1174 | Var->setNRVOVariable(NRVO); | ||||||||||||
1175 | } | ||||||||||||
1176 | |||||||||||||
1177 | Var->setImplicit(D->isImplicit()); | ||||||||||||
1178 | |||||||||||||
1179 | if (Var->isStaticLocal()) | ||||||||||||
1180 | SemaRef.CheckStaticLocalForDllExport(Var); | ||||||||||||
1181 | |||||||||||||
1182 | return Var; | ||||||||||||
1183 | } | ||||||||||||
1184 | |||||||||||||
1185 | Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) { | ||||||||||||
1186 | AccessSpecDecl* AD | ||||||||||||
1187 | = AccessSpecDecl::Create(SemaRef.Context, D->getAccess(), Owner, | ||||||||||||
1188 | D->getAccessSpecifierLoc(), D->getColonLoc()); | ||||||||||||
1189 | Owner->addHiddenDecl(AD); | ||||||||||||
1190 | return AD; | ||||||||||||
1191 | } | ||||||||||||
1192 | |||||||||||||
1193 | Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { | ||||||||||||
1194 | bool Invalid = false; | ||||||||||||
1195 | TypeSourceInfo *DI = D->getTypeSourceInfo(); | ||||||||||||
1196 | if (DI->getType()->isInstantiationDependentType() || | ||||||||||||
1197 | DI->getType()->isVariablyModifiedType()) { | ||||||||||||
1198 | DI = SemaRef.SubstType(DI, TemplateArgs, | ||||||||||||
1199 | D->getLocation(), D->getDeclName()); | ||||||||||||
1200 | if (!DI) { | ||||||||||||
1201 | DI = D->getTypeSourceInfo(); | ||||||||||||
1202 | Invalid = true; | ||||||||||||
1203 | } else if (DI->getType()->isFunctionType()) { | ||||||||||||
1204 | // C++ [temp.arg.type]p3: | ||||||||||||
1205 | // If a declaration acquires a function type through a type | ||||||||||||
1206 | // dependent on a template-parameter and this causes a | ||||||||||||
1207 | // declaration that does not use the syntactic form of a | ||||||||||||
1208 | // function declarator to have function type, the program is | ||||||||||||
1209 | // ill-formed. | ||||||||||||
1210 | SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function) | ||||||||||||
1211 | << DI->getType(); | ||||||||||||
1212 | Invalid = true; | ||||||||||||
1213 | } | ||||||||||||
1214 | } else { | ||||||||||||
1215 | SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType()); | ||||||||||||
1216 | } | ||||||||||||
1217 | |||||||||||||
1218 | Expr *BitWidth = D->getBitWidth(); | ||||||||||||
1219 | if (Invalid) | ||||||||||||
1220 | BitWidth = nullptr; | ||||||||||||
1221 | else if (BitWidth) { | ||||||||||||
1222 | // The bit-width expression is a constant expression. | ||||||||||||
1223 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
1224 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
1225 | |||||||||||||
1226 | ExprResult InstantiatedBitWidth | ||||||||||||
1227 | = SemaRef.SubstExpr(BitWidth, TemplateArgs); | ||||||||||||
1228 | if (InstantiatedBitWidth.isInvalid()) { | ||||||||||||
1229 | Invalid = true; | ||||||||||||
1230 | BitWidth = nullptr; | ||||||||||||
1231 | } else | ||||||||||||
1232 | BitWidth = InstantiatedBitWidth.getAs<Expr>(); | ||||||||||||
1233 | } | ||||||||||||
1234 | |||||||||||||
1235 | FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), | ||||||||||||
1236 | DI->getType(), DI, | ||||||||||||
1237 | cast<RecordDecl>(Owner), | ||||||||||||
1238 | D->getLocation(), | ||||||||||||
1239 | D->isMutable(), | ||||||||||||
1240 | BitWidth, | ||||||||||||
1241 | D->getInClassInitStyle(), | ||||||||||||
1242 | D->getInnerLocStart(), | ||||||||||||
1243 | D->getAccess(), | ||||||||||||
1244 | nullptr); | ||||||||||||
1245 | if (!Field) { | ||||||||||||
1246 | cast<Decl>(Owner)->setInvalidDecl(); | ||||||||||||
1247 | return nullptr; | ||||||||||||
1248 | } | ||||||||||||
1249 | |||||||||||||
1250 | SemaRef.InstantiateAttrs(TemplateArgs, D, Field, LateAttrs, StartingScope); | ||||||||||||
1251 | |||||||||||||
1252 | if (Field->hasAttrs()) | ||||||||||||
1253 | SemaRef.CheckAlignasUnderalignment(Field); | ||||||||||||
1254 | |||||||||||||
1255 | if (Invalid) | ||||||||||||
1256 | Field->setInvalidDecl(); | ||||||||||||
1257 | |||||||||||||
1258 | if (!Field->getDeclName()) { | ||||||||||||
1259 | // Keep track of where this decl came from. | ||||||||||||
1260 | SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D); | ||||||||||||
1261 | } | ||||||||||||
1262 | if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) { | ||||||||||||
1263 | if (Parent->isAnonymousStructOrUnion() && | ||||||||||||
1264 | Parent->getRedeclContext()->isFunctionOrMethod()) | ||||||||||||
1265 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field); | ||||||||||||
1266 | } | ||||||||||||
1267 | |||||||||||||
1268 | Field->setImplicit(D->isImplicit()); | ||||||||||||
1269 | Field->setAccess(D->getAccess()); | ||||||||||||
1270 | Owner->addDecl(Field); | ||||||||||||
1271 | |||||||||||||
1272 | return Field; | ||||||||||||
1273 | } | ||||||||||||
1274 | |||||||||||||
1275 | Decl *TemplateDeclInstantiator::VisitMSPropertyDecl(MSPropertyDecl *D) { | ||||||||||||
1276 | bool Invalid = false; | ||||||||||||
1277 | TypeSourceInfo *DI = D->getTypeSourceInfo(); | ||||||||||||
1278 | |||||||||||||
1279 | if (DI->getType()->isVariablyModifiedType()) { | ||||||||||||
1280 | SemaRef.Diag(D->getLocation(), diag::err_property_is_variably_modified) | ||||||||||||
1281 | << D; | ||||||||||||
1282 | Invalid = true; | ||||||||||||
1283 | } else if (DI->getType()->isInstantiationDependentType()) { | ||||||||||||
1284 | DI = SemaRef.SubstType(DI, TemplateArgs, | ||||||||||||
1285 | D->getLocation(), D->getDeclName()); | ||||||||||||
1286 | if (!DI) { | ||||||||||||
1287 | DI = D->getTypeSourceInfo(); | ||||||||||||
1288 | Invalid = true; | ||||||||||||
1289 | } else if (DI->getType()->isFunctionType()) { | ||||||||||||
1290 | // C++ [temp.arg.type]p3: | ||||||||||||
1291 | // If a declaration acquires a function type through a type | ||||||||||||
1292 | // dependent on a template-parameter and this causes a | ||||||||||||
1293 | // declaration that does not use the syntactic form of a | ||||||||||||
1294 | // function declarator to have function type, the program is | ||||||||||||
1295 | // ill-formed. | ||||||||||||
1296 | SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function) | ||||||||||||
1297 | << DI->getType(); | ||||||||||||
1298 | Invalid = true; | ||||||||||||
1299 | } | ||||||||||||
1300 | } else { | ||||||||||||
1301 | SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType()); | ||||||||||||
1302 | } | ||||||||||||
1303 | |||||||||||||
1304 | MSPropertyDecl *Property = MSPropertyDecl::Create( | ||||||||||||
1305 | SemaRef.Context, Owner, D->getLocation(), D->getDeclName(), DI->getType(), | ||||||||||||
1306 | DI, D->getBeginLoc(), D->getGetterId(), D->getSetterId()); | ||||||||||||
1307 | |||||||||||||
1308 | SemaRef.InstantiateAttrs(TemplateArgs, D, Property, LateAttrs, | ||||||||||||
1309 | StartingScope); | ||||||||||||
1310 | |||||||||||||
1311 | if (Invalid) | ||||||||||||
1312 | Property->setInvalidDecl(); | ||||||||||||
1313 | |||||||||||||
1314 | Property->setAccess(D->getAccess()); | ||||||||||||
1315 | Owner->addDecl(Property); | ||||||||||||
1316 | |||||||||||||
1317 | return Property; | ||||||||||||
1318 | } | ||||||||||||
1319 | |||||||||||||
1320 | Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) { | ||||||||||||
1321 | NamedDecl **NamedChain = | ||||||||||||
1322 | new (SemaRef.Context)NamedDecl*[D->getChainingSize()]; | ||||||||||||
1323 | |||||||||||||
1324 | int i = 0; | ||||||||||||
1325 | for (auto *PI : D->chain()) { | ||||||||||||
1326 | NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), PI, | ||||||||||||
1327 | TemplateArgs); | ||||||||||||
1328 | if (!Next) | ||||||||||||
1329 | return nullptr; | ||||||||||||
1330 | |||||||||||||
1331 | NamedChain[i++] = Next; | ||||||||||||
1332 | } | ||||||||||||
1333 | |||||||||||||
1334 | QualType T = cast<FieldDecl>(NamedChain[i-1])->getType(); | ||||||||||||
1335 | IndirectFieldDecl *IndirectField = IndirectFieldDecl::Create( | ||||||||||||
1336 | SemaRef.Context, Owner, D->getLocation(), D->getIdentifier(), T, | ||||||||||||
1337 | {NamedChain, D->getChainingSize()}); | ||||||||||||
1338 | |||||||||||||
1339 | for (const auto *Attr : D->attrs()) | ||||||||||||
1340 | IndirectField->addAttr(Attr->clone(SemaRef.Context)); | ||||||||||||
1341 | |||||||||||||
1342 | IndirectField->setImplicit(D->isImplicit()); | ||||||||||||
1343 | IndirectField->setAccess(D->getAccess()); | ||||||||||||
1344 | Owner->addDecl(IndirectField); | ||||||||||||
1345 | return IndirectField; | ||||||||||||
1346 | } | ||||||||||||
1347 | |||||||||||||
1348 | Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { | ||||||||||||
1349 | // Handle friend type expressions by simply substituting template | ||||||||||||
1350 | // parameters into the pattern type and checking the result. | ||||||||||||
1351 | if (TypeSourceInfo *Ty = D->getFriendType()) { | ||||||||||||
1352 | TypeSourceInfo *InstTy; | ||||||||||||
1353 | // If this is an unsupported friend, don't bother substituting template | ||||||||||||
1354 | // arguments into it. The actual type referred to won't be used by any | ||||||||||||
1355 | // parts of Clang, and may not be valid for instantiating. Just use the | ||||||||||||
1356 | // same info for the instantiated friend. | ||||||||||||
1357 | if (D->isUnsupportedFriend()) { | ||||||||||||
1358 | InstTy = Ty; | ||||||||||||
1359 | } else { | ||||||||||||
1360 | InstTy = SemaRef.SubstType(Ty, TemplateArgs, | ||||||||||||
1361 | D->getLocation(), DeclarationName()); | ||||||||||||
1362 | } | ||||||||||||
1363 | if (!InstTy) | ||||||||||||
1364 | return nullptr; | ||||||||||||
1365 | |||||||||||||
1366 | FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getBeginLoc(), | ||||||||||||
1367 | D->getFriendLoc(), InstTy); | ||||||||||||
1368 | if (!FD) | ||||||||||||
1369 | return nullptr; | ||||||||||||
1370 | |||||||||||||
1371 | FD->setAccess(AS_public); | ||||||||||||
1372 | FD->setUnsupportedFriend(D->isUnsupportedFriend()); | ||||||||||||
1373 | Owner->addDecl(FD); | ||||||||||||
1374 | return FD; | ||||||||||||
1375 | } | ||||||||||||
1376 | |||||||||||||
1377 | NamedDecl *ND = D->getFriendDecl(); | ||||||||||||
1378 | assert(ND && "friend decl must be a decl or a type!")(static_cast <bool> (ND && "friend decl must be a decl or a type!" ) ? void (0) : __assert_fail ("ND && \"friend decl must be a decl or a type!\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1378, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1379 | |||||||||||||
1380 | // All of the Visit implementations for the various potential friend | ||||||||||||
1381 | // declarations have to be carefully written to work for friend | ||||||||||||
1382 | // objects, with the most important detail being that the target | ||||||||||||
1383 | // decl should almost certainly not be placed in Owner. | ||||||||||||
1384 | Decl *NewND = Visit(ND); | ||||||||||||
1385 | if (!NewND) return nullptr; | ||||||||||||
1386 | |||||||||||||
1387 | FriendDecl *FD = | ||||||||||||
1388 | FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(), | ||||||||||||
1389 | cast<NamedDecl>(NewND), D->getFriendLoc()); | ||||||||||||
1390 | FD->setAccess(AS_public); | ||||||||||||
1391 | FD->setUnsupportedFriend(D->isUnsupportedFriend()); | ||||||||||||
1392 | Owner->addDecl(FD); | ||||||||||||
1393 | return FD; | ||||||||||||
1394 | } | ||||||||||||
1395 | |||||||||||||
1396 | Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) { | ||||||||||||
1397 | Expr *AssertExpr = D->getAssertExpr(); | ||||||||||||
1398 | |||||||||||||
1399 | // The expression in a static assertion is a constant expression. | ||||||||||||
1400 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
1401 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
1402 | |||||||||||||
1403 | ExprResult InstantiatedAssertExpr | ||||||||||||
1404 | = SemaRef.SubstExpr(AssertExpr, TemplateArgs); | ||||||||||||
1405 | if (InstantiatedAssertExpr.isInvalid()) | ||||||||||||
1406 | return nullptr; | ||||||||||||
1407 | |||||||||||||
1408 | return SemaRef.BuildStaticAssertDeclaration(D->getLocation(), | ||||||||||||
1409 | InstantiatedAssertExpr.get(), | ||||||||||||
1410 | D->getMessage(), | ||||||||||||
1411 | D->getRParenLoc(), | ||||||||||||
1412 | D->isFailed()); | ||||||||||||
1413 | } | ||||||||||||
1414 | |||||||||||||
1415 | Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { | ||||||||||||
1416 | EnumDecl *PrevDecl = nullptr; | ||||||||||||
1417 | if (EnumDecl *PatternPrev = getPreviousDeclForInstantiation(D)) { | ||||||||||||
1418 | NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), | ||||||||||||
1419 | PatternPrev, | ||||||||||||
1420 | TemplateArgs); | ||||||||||||
1421 | if (!Prev) return nullptr; | ||||||||||||
1422 | PrevDecl = cast<EnumDecl>(Prev); | ||||||||||||
1423 | } | ||||||||||||
1424 | |||||||||||||
1425 | EnumDecl *Enum = | ||||||||||||
1426 | EnumDecl::Create(SemaRef.Context, Owner, D->getBeginLoc(), | ||||||||||||
1427 | D->getLocation(), D->getIdentifier(), PrevDecl, | ||||||||||||
1428 | D->isScoped(), D->isScopedUsingClassTag(), D->isFixed()); | ||||||||||||
1429 | if (D->isFixed()) { | ||||||||||||
1430 | if (TypeSourceInfo *TI = D->getIntegerTypeSourceInfo()) { | ||||||||||||
1431 | // If we have type source information for the underlying type, it means it | ||||||||||||
1432 | // has been explicitly set by the user. Perform substitution on it before | ||||||||||||
1433 | // moving on. | ||||||||||||
1434 | SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc(); | ||||||||||||
1435 | TypeSourceInfo *NewTI = SemaRef.SubstType(TI, TemplateArgs, UnderlyingLoc, | ||||||||||||
1436 | DeclarationName()); | ||||||||||||
1437 | if (!NewTI || SemaRef.CheckEnumUnderlyingType(NewTI)) | ||||||||||||
1438 | Enum->setIntegerType(SemaRef.Context.IntTy); | ||||||||||||
1439 | else | ||||||||||||
1440 | Enum->setIntegerTypeSourceInfo(NewTI); | ||||||||||||
1441 | } else { | ||||||||||||
1442 | assert(!D->getIntegerType()->isDependentType()(static_cast <bool> (!D->getIntegerType()->isDependentType () && "Dependent type without type source info") ? void (0) : __assert_fail ("!D->getIntegerType()->isDependentType() && \"Dependent type without type source info\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1443, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
1443 | && "Dependent type without type source info")(static_cast <bool> (!D->getIntegerType()->isDependentType () && "Dependent type without type source info") ? void (0) : __assert_fail ("!D->getIntegerType()->isDependentType() && \"Dependent type without type source info\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1443, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1444 | Enum->setIntegerType(D->getIntegerType()); | ||||||||||||
1445 | } | ||||||||||||
1446 | } | ||||||||||||
1447 | |||||||||||||
1448 | SemaRef.InstantiateAttrs(TemplateArgs, D, Enum); | ||||||||||||
1449 | |||||||||||||
1450 | Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation); | ||||||||||||
1451 | Enum->setAccess(D->getAccess()); | ||||||||||||
1452 | // Forward the mangling number from the template to the instantiated decl. | ||||||||||||
1453 | SemaRef.Context.setManglingNumber(Enum, SemaRef.Context.getManglingNumber(D)); | ||||||||||||
1454 | // See if the old tag was defined along with a declarator. | ||||||||||||
1455 | // If it did, mark the new tag as being associated with that declarator. | ||||||||||||
1456 | if (DeclaratorDecl *DD = SemaRef.Context.getDeclaratorForUnnamedTagDecl(D)) | ||||||||||||
1457 | SemaRef.Context.addDeclaratorForUnnamedTagDecl(Enum, DD); | ||||||||||||
1458 | // See if the old tag was defined along with a typedef. | ||||||||||||
1459 | // If it did, mark the new tag as being associated with that typedef. | ||||||||||||
1460 | if (TypedefNameDecl *TND = SemaRef.Context.getTypedefNameForUnnamedTagDecl(D)) | ||||||||||||
1461 | SemaRef.Context.addTypedefNameForUnnamedTagDecl(Enum, TND); | ||||||||||||
1462 | if (SubstQualifier(D, Enum)) return nullptr; | ||||||||||||
1463 | Owner->addDecl(Enum); | ||||||||||||
1464 | |||||||||||||
1465 | EnumDecl *Def = D->getDefinition(); | ||||||||||||
1466 | if (Def && Def != D) { | ||||||||||||
1467 | // If this is an out-of-line definition of an enum member template, check | ||||||||||||
1468 | // that the underlying types match in the instantiation of both | ||||||||||||
1469 | // declarations. | ||||||||||||
1470 | if (TypeSourceInfo *TI = Def->getIntegerTypeSourceInfo()) { | ||||||||||||
1471 | SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc(); | ||||||||||||
1472 | QualType DefnUnderlying = | ||||||||||||
1473 | SemaRef.SubstType(TI->getType(), TemplateArgs, | ||||||||||||
1474 | UnderlyingLoc, DeclarationName()); | ||||||||||||
1475 | SemaRef.CheckEnumRedeclaration(Def->getLocation(), Def->isScoped(), | ||||||||||||
1476 | DefnUnderlying, /*IsFixed=*/true, Enum); | ||||||||||||
1477 | } | ||||||||||||
1478 | } | ||||||||||||
1479 | |||||||||||||
1480 | // C++11 [temp.inst]p1: The implicit instantiation of a class template | ||||||||||||
1481 | // specialization causes the implicit instantiation of the declarations, but | ||||||||||||
1482 | // not the definitions of scoped member enumerations. | ||||||||||||
1483 | // | ||||||||||||
1484 | // DR1484 clarifies that enumeration definitions inside of a template | ||||||||||||
1485 | // declaration aren't considered entities that can be separately instantiated | ||||||||||||
1486 | // from the rest of the entity they are declared inside of. | ||||||||||||
1487 | if (isDeclWithinFunction(D) ? D == Def : Def && !Enum->isScoped()) { | ||||||||||||
1488 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum); | ||||||||||||
1489 | InstantiateEnumDefinition(Enum, Def); | ||||||||||||
1490 | } | ||||||||||||
1491 | |||||||||||||
1492 | return Enum; | ||||||||||||
1493 | } | ||||||||||||
1494 | |||||||||||||
1495 | void TemplateDeclInstantiator::InstantiateEnumDefinition( | ||||||||||||
1496 | EnumDecl *Enum, EnumDecl *Pattern) { | ||||||||||||
1497 | Enum->startDefinition(); | ||||||||||||
1498 | |||||||||||||
1499 | // Update the location to refer to the definition. | ||||||||||||
1500 | Enum->setLocation(Pattern->getLocation()); | ||||||||||||
1501 | |||||||||||||
1502 | SmallVector<Decl*, 4> Enumerators; | ||||||||||||
1503 | |||||||||||||
1504 | EnumConstantDecl *LastEnumConst = nullptr; | ||||||||||||
1505 | for (auto *EC : Pattern->enumerators()) { | ||||||||||||
1506 | // The specified value for the enumerator. | ||||||||||||
1507 | ExprResult Value((Expr *)nullptr); | ||||||||||||
1508 | if (Expr *UninstValue = EC->getInitExpr()) { | ||||||||||||
1509 | // The enumerator's value expression is a constant expression. | ||||||||||||
1510 | EnterExpressionEvaluationContext Unevaluated( | ||||||||||||
1511 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
1512 | |||||||||||||
1513 | Value = SemaRef.SubstExpr(UninstValue, TemplateArgs); | ||||||||||||
1514 | } | ||||||||||||
1515 | |||||||||||||
1516 | // Drop the initial value and continue. | ||||||||||||
1517 | bool isInvalid = false; | ||||||||||||
1518 | if (Value.isInvalid()) { | ||||||||||||
1519 | Value = nullptr; | ||||||||||||
1520 | isInvalid = true; | ||||||||||||
1521 | } | ||||||||||||
1522 | |||||||||||||
1523 | EnumConstantDecl *EnumConst | ||||||||||||
1524 | = SemaRef.CheckEnumConstant(Enum, LastEnumConst, | ||||||||||||
1525 | EC->getLocation(), EC->getIdentifier(), | ||||||||||||
1526 | Value.get()); | ||||||||||||
1527 | |||||||||||||
1528 | if (isInvalid) { | ||||||||||||
1529 | if (EnumConst) | ||||||||||||
1530 | EnumConst->setInvalidDecl(); | ||||||||||||
1531 | Enum->setInvalidDecl(); | ||||||||||||
1532 | } | ||||||||||||
1533 | |||||||||||||
1534 | if (EnumConst) { | ||||||||||||
1535 | SemaRef.InstantiateAttrs(TemplateArgs, EC, EnumConst); | ||||||||||||
1536 | |||||||||||||
1537 | EnumConst->setAccess(Enum->getAccess()); | ||||||||||||
1538 | Enum->addDecl(EnumConst); | ||||||||||||
1539 | Enumerators.push_back(EnumConst); | ||||||||||||
1540 | LastEnumConst = EnumConst; | ||||||||||||
1541 | |||||||||||||
1542 | if (Pattern->getDeclContext()->isFunctionOrMethod() && | ||||||||||||
1543 | !Enum->isScoped()) { | ||||||||||||
1544 | // If the enumeration is within a function or method, record the enum | ||||||||||||
1545 | // constant as a local. | ||||||||||||
1546 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(EC, EnumConst); | ||||||||||||
1547 | } | ||||||||||||
1548 | } | ||||||||||||
1549 | } | ||||||||||||
1550 | |||||||||||||
1551 | SemaRef.ActOnEnumBody(Enum->getLocation(), Enum->getBraceRange(), Enum, | ||||||||||||
1552 | Enumerators, nullptr, ParsedAttributesView()); | ||||||||||||
1553 | } | ||||||||||||
1554 | |||||||||||||
1555 | Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) { | ||||||||||||
1556 | llvm_unreachable("EnumConstantDecls can only occur within EnumDecls.")::llvm::llvm_unreachable_internal("EnumConstantDecls can only occur within EnumDecls." , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1556); | ||||||||||||
1557 | } | ||||||||||||
1558 | |||||||||||||
1559 | Decl * | ||||||||||||
1560 | TemplateDeclInstantiator::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) { | ||||||||||||
1561 | llvm_unreachable("BuiltinTemplateDecls cannot be instantiated.")::llvm::llvm_unreachable_internal("BuiltinTemplateDecls cannot be instantiated." , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1561); | ||||||||||||
1562 | } | ||||||||||||
1563 | |||||||||||||
1564 | Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { | ||||||||||||
1565 | bool isFriend = (D->getFriendObjectKind() != Decl::FOK_None); | ||||||||||||
1566 | |||||||||||||
1567 | // Create a local instantiation scope for this class template, which | ||||||||||||
1568 | // will contain the instantiations of the template parameters. | ||||||||||||
1569 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
1570 | TemplateParameterList *TempParams = D->getTemplateParameters(); | ||||||||||||
1571 | TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | ||||||||||||
1572 | if (!InstParams) | ||||||||||||
1573 | return nullptr; | ||||||||||||
1574 | |||||||||||||
1575 | CXXRecordDecl *Pattern = D->getTemplatedDecl(); | ||||||||||||
1576 | |||||||||||||
1577 | // Instantiate the qualifier. We have to do this first in case | ||||||||||||
1578 | // we're a friend declaration, because if we are then we need to put | ||||||||||||
1579 | // the new declaration in the appropriate context. | ||||||||||||
1580 | NestedNameSpecifierLoc QualifierLoc = Pattern->getQualifierLoc(); | ||||||||||||
1581 | if (QualifierLoc) { | ||||||||||||
1582 | QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, | ||||||||||||
1583 | TemplateArgs); | ||||||||||||
1584 | if (!QualifierLoc) | ||||||||||||
1585 | return nullptr; | ||||||||||||
1586 | } | ||||||||||||
1587 | |||||||||||||
1588 | CXXRecordDecl *PrevDecl = nullptr; | ||||||||||||
1589 | ClassTemplateDecl *PrevClassTemplate = nullptr; | ||||||||||||
1590 | |||||||||||||
1591 | if (!isFriend && getPreviousDeclForInstantiation(Pattern)) { | ||||||||||||
1592 | DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); | ||||||||||||
1593 | if (!Found.empty()) { | ||||||||||||
1594 | PrevClassTemplate = dyn_cast<ClassTemplateDecl>(Found.front()); | ||||||||||||
1595 | if (PrevClassTemplate) | ||||||||||||
1596 | PrevDecl = PrevClassTemplate->getTemplatedDecl(); | ||||||||||||
1597 | } | ||||||||||||
1598 | } | ||||||||||||
1599 | |||||||||||||
1600 | // If this isn't a friend, then it's a member template, in which | ||||||||||||
1601 | // case we just want to build the instantiation in the | ||||||||||||
1602 | // specialization. If it is a friend, we want to build it in | ||||||||||||
1603 | // the appropriate context. | ||||||||||||
1604 | DeclContext *DC = Owner; | ||||||||||||
1605 | if (isFriend) { | ||||||||||||
1606 | if (QualifierLoc) { | ||||||||||||
1607 | CXXScopeSpec SS; | ||||||||||||
1608 | SS.Adopt(QualifierLoc); | ||||||||||||
1609 | DC = SemaRef.computeDeclContext(SS); | ||||||||||||
1610 | if (!DC) return nullptr; | ||||||||||||
1611 | } else { | ||||||||||||
1612 | DC = SemaRef.FindInstantiatedContext(Pattern->getLocation(), | ||||||||||||
1613 | Pattern->getDeclContext(), | ||||||||||||
1614 | TemplateArgs); | ||||||||||||
1615 | } | ||||||||||||
1616 | |||||||||||||
1617 | // Look for a previous declaration of the template in the owning | ||||||||||||
1618 | // context. | ||||||||||||
1619 | LookupResult R(SemaRef, Pattern->getDeclName(), Pattern->getLocation(), | ||||||||||||
1620 | Sema::LookupOrdinaryName, | ||||||||||||
1621 | SemaRef.forRedeclarationInCurContext()); | ||||||||||||
1622 | SemaRef.LookupQualifiedName(R, DC); | ||||||||||||
1623 | |||||||||||||
1624 | if (R.isSingleResult()) { | ||||||||||||
1625 | PrevClassTemplate = R.getAsSingle<ClassTemplateDecl>(); | ||||||||||||
1626 | if (PrevClassTemplate) | ||||||||||||
1627 | PrevDecl = PrevClassTemplate->getTemplatedDecl(); | ||||||||||||
1628 | } | ||||||||||||
1629 | |||||||||||||
1630 | if (!PrevClassTemplate && QualifierLoc) { | ||||||||||||
1631 | SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope) | ||||||||||||
1632 | << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC | ||||||||||||
1633 | << QualifierLoc.getSourceRange(); | ||||||||||||
1634 | return nullptr; | ||||||||||||
1635 | } | ||||||||||||
1636 | |||||||||||||
1637 | if (PrevClassTemplate) { | ||||||||||||
1638 | const ClassTemplateDecl *MostRecentPrevCT = | ||||||||||||
1639 | PrevClassTemplate->getMostRecentDecl(); | ||||||||||||
1640 | TemplateParameterList *PrevParams = | ||||||||||||
1641 | MostRecentPrevCT->getTemplateParameters(); | ||||||||||||
1642 | |||||||||||||
1643 | // Make sure the parameter lists match. | ||||||||||||
1644 | if (!SemaRef.TemplateParameterListsAreEqual( | ||||||||||||
1645 | D->getTemplatedDecl(), InstParams, | ||||||||||||
1646 | MostRecentPrevCT->getTemplatedDecl(), PrevParams, true, | ||||||||||||
1647 | Sema::TPL_TemplateMatch)) | ||||||||||||
1648 | return nullptr; | ||||||||||||
1649 | |||||||||||||
1650 | // Do some additional validation, then merge default arguments | ||||||||||||
1651 | // from the existing declarations. | ||||||||||||
1652 | if (SemaRef.CheckTemplateParameterList(InstParams, PrevParams, | ||||||||||||
1653 | Sema::TPC_ClassTemplate)) | ||||||||||||
1654 | return nullptr; | ||||||||||||
1655 | } | ||||||||||||
1656 | } | ||||||||||||
1657 | |||||||||||||
1658 | CXXRecordDecl *RecordInst = CXXRecordDecl::Create( | ||||||||||||
1659 | SemaRef.Context, Pattern->getTagKind(), DC, Pattern->getBeginLoc(), | ||||||||||||
1660 | Pattern->getLocation(), Pattern->getIdentifier(), PrevDecl, | ||||||||||||
1661 | /*DelayTypeCreation=*/true); | ||||||||||||
1662 | |||||||||||||
1663 | if (QualifierLoc) | ||||||||||||
1664 | RecordInst->setQualifierInfo(QualifierLoc); | ||||||||||||
1665 | |||||||||||||
1666 | SemaRef.InstantiateAttrsForDecl(TemplateArgs, Pattern, RecordInst, LateAttrs, | ||||||||||||
1667 | StartingScope); | ||||||||||||
1668 | |||||||||||||
1669 | ClassTemplateDecl *Inst | ||||||||||||
1670 | = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(), | ||||||||||||
1671 | D->getIdentifier(), InstParams, RecordInst); | ||||||||||||
1672 | assert(!(isFriend && Owner->isDependentContext()))(static_cast <bool> (!(isFriend && Owner->isDependentContext ())) ? void (0) : __assert_fail ("!(isFriend && Owner->isDependentContext())" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1672, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1673 | Inst->setPreviousDecl(PrevClassTemplate); | ||||||||||||
1674 | |||||||||||||
1675 | RecordInst->setDescribedClassTemplate(Inst); | ||||||||||||
1676 | |||||||||||||
1677 | if (isFriend) { | ||||||||||||
1678 | if (PrevClassTemplate) | ||||||||||||
1679 | Inst->setAccess(PrevClassTemplate->getAccess()); | ||||||||||||
1680 | else | ||||||||||||
1681 | Inst->setAccess(D->getAccess()); | ||||||||||||
1682 | |||||||||||||
1683 | Inst->setObjectOfFriendDecl(); | ||||||||||||
1684 | // TODO: do we want to track the instantiation progeny of this | ||||||||||||
1685 | // friend target decl? | ||||||||||||
1686 | } else { | ||||||||||||
1687 | Inst->setAccess(D->getAccess()); | ||||||||||||
1688 | if (!PrevClassTemplate) | ||||||||||||
1689 | Inst->setInstantiatedFromMemberTemplate(D); | ||||||||||||
1690 | } | ||||||||||||
1691 | |||||||||||||
1692 | // Trigger creation of the type for the instantiation. | ||||||||||||
1693 | SemaRef.Context.getInjectedClassNameType(RecordInst, | ||||||||||||
1694 | Inst->getInjectedClassNameSpecialization()); | ||||||||||||
1695 | |||||||||||||
1696 | // Finish handling of friends. | ||||||||||||
1697 | if (isFriend) { | ||||||||||||
1698 | DC->makeDeclVisibleInContext(Inst); | ||||||||||||
1699 | Inst->setLexicalDeclContext(Owner); | ||||||||||||
1700 | RecordInst->setLexicalDeclContext(Owner); | ||||||||||||
1701 | return Inst; | ||||||||||||
1702 | } | ||||||||||||
1703 | |||||||||||||
1704 | if (D->isOutOfLine()) { | ||||||||||||
1705 | Inst->setLexicalDeclContext(D->getLexicalDeclContext()); | ||||||||||||
1706 | RecordInst->setLexicalDeclContext(D->getLexicalDeclContext()); | ||||||||||||
1707 | } | ||||||||||||
1708 | |||||||||||||
1709 | Owner->addDecl(Inst); | ||||||||||||
1710 | |||||||||||||
1711 | if (!PrevClassTemplate) { | ||||||||||||
1712 | // Queue up any out-of-line partial specializations of this member | ||||||||||||
1713 | // class template; the client will force their instantiation once | ||||||||||||
1714 | // the enclosing class has been instantiated. | ||||||||||||
1715 | SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; | ||||||||||||
1716 | D->getPartialSpecializations(PartialSpecs); | ||||||||||||
1717 | for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) | ||||||||||||
1718 | if (PartialSpecs[I]->getFirstDecl()->isOutOfLine()) | ||||||||||||
1719 | OutOfLinePartialSpecs.push_back(std::make_pair(Inst, PartialSpecs[I])); | ||||||||||||
1720 | } | ||||||||||||
1721 | |||||||||||||
1722 | return Inst; | ||||||||||||
1723 | } | ||||||||||||
1724 | |||||||||||||
1725 | Decl * | ||||||||||||
1726 | TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( | ||||||||||||
1727 | ClassTemplatePartialSpecializationDecl *D) { | ||||||||||||
1728 | ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate(); | ||||||||||||
1729 | |||||||||||||
1730 | // Lookup the already-instantiated declaration in the instantiation | ||||||||||||
1731 | // of the class template and return that. | ||||||||||||
1732 | DeclContext::lookup_result Found | ||||||||||||
1733 | = Owner->lookup(ClassTemplate->getDeclName()); | ||||||||||||
1734 | if (Found.empty()) | ||||||||||||
1735 | return nullptr; | ||||||||||||
1736 | |||||||||||||
1737 | ClassTemplateDecl *InstClassTemplate | ||||||||||||
1738 | = dyn_cast<ClassTemplateDecl>(Found.front()); | ||||||||||||
1739 | if (!InstClassTemplate) | ||||||||||||
1740 | return nullptr; | ||||||||||||
1741 | |||||||||||||
1742 | if (ClassTemplatePartialSpecializationDecl *Result | ||||||||||||
1743 | = InstClassTemplate->findPartialSpecInstantiatedFromMember(D)) | ||||||||||||
1744 | return Result; | ||||||||||||
1745 | |||||||||||||
1746 | return InstantiateClassTemplatePartialSpecialization(InstClassTemplate, D); | ||||||||||||
1747 | } | ||||||||||||
1748 | |||||||||||||
1749 | Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) { | ||||||||||||
1750 | assert(D->getTemplatedDecl()->isStaticDataMember() &&(static_cast <bool> (D->getTemplatedDecl()->isStaticDataMember () && "Only static data member templates are allowed." ) ? void (0) : __assert_fail ("D->getTemplatedDecl()->isStaticDataMember() && \"Only static data member templates are allowed.\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1751, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
1751 | "Only static data member templates are allowed.")(static_cast <bool> (D->getTemplatedDecl()->isStaticDataMember () && "Only static data member templates are allowed." ) ? void (0) : __assert_fail ("D->getTemplatedDecl()->isStaticDataMember() && \"Only static data member templates are allowed.\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1751, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1752 | |||||||||||||
1753 | // Create a local instantiation scope for this variable template, which | ||||||||||||
1754 | // will contain the instantiations of the template parameters. | ||||||||||||
1755 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
1756 | TemplateParameterList *TempParams = D->getTemplateParameters(); | ||||||||||||
1757 | TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | ||||||||||||
1758 | if (!InstParams) | ||||||||||||
1759 | return nullptr; | ||||||||||||
1760 | |||||||||||||
1761 | VarDecl *Pattern = D->getTemplatedDecl(); | ||||||||||||
1762 | VarTemplateDecl *PrevVarTemplate = nullptr; | ||||||||||||
1763 | |||||||||||||
1764 | if (getPreviousDeclForInstantiation(Pattern)) { | ||||||||||||
1765 | DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); | ||||||||||||
1766 | if (!Found.empty()) | ||||||||||||
1767 | PrevVarTemplate = dyn_cast<VarTemplateDecl>(Found.front()); | ||||||||||||
1768 | } | ||||||||||||
1769 | |||||||||||||
1770 | VarDecl *VarInst = | ||||||||||||
1771 | cast_or_null<VarDecl>(VisitVarDecl(Pattern, | ||||||||||||
1772 | /*InstantiatingVarTemplate=*/true)); | ||||||||||||
1773 | if (!VarInst) return nullptr; | ||||||||||||
1774 | |||||||||||||
1775 | DeclContext *DC = Owner; | ||||||||||||
1776 | |||||||||||||
1777 | VarTemplateDecl *Inst = VarTemplateDecl::Create( | ||||||||||||
1778 | SemaRef.Context, DC, D->getLocation(), D->getIdentifier(), InstParams, | ||||||||||||
1779 | VarInst); | ||||||||||||
1780 | VarInst->setDescribedVarTemplate(Inst); | ||||||||||||
1781 | Inst->setPreviousDecl(PrevVarTemplate); | ||||||||||||
1782 | |||||||||||||
1783 | Inst->setAccess(D->getAccess()); | ||||||||||||
1784 | if (!PrevVarTemplate) | ||||||||||||
1785 | Inst->setInstantiatedFromMemberTemplate(D); | ||||||||||||
1786 | |||||||||||||
1787 | if (D->isOutOfLine()) { | ||||||||||||
1788 | Inst->setLexicalDeclContext(D->getLexicalDeclContext()); | ||||||||||||
1789 | VarInst->setLexicalDeclContext(D->getLexicalDeclContext()); | ||||||||||||
1790 | } | ||||||||||||
1791 | |||||||||||||
1792 | Owner->addDecl(Inst); | ||||||||||||
1793 | |||||||||||||
1794 | if (!PrevVarTemplate) { | ||||||||||||
1795 | // Queue up any out-of-line partial specializations of this member | ||||||||||||
1796 | // variable template; the client will force their instantiation once | ||||||||||||
1797 | // the enclosing class has been instantiated. | ||||||||||||
1798 | SmallVector<VarTemplatePartialSpecializationDecl *, 4> PartialSpecs; | ||||||||||||
1799 | D->getPartialSpecializations(PartialSpecs); | ||||||||||||
1800 | for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) | ||||||||||||
1801 | if (PartialSpecs[I]->getFirstDecl()->isOutOfLine()) | ||||||||||||
1802 | OutOfLineVarPartialSpecs.push_back( | ||||||||||||
1803 | std::make_pair(Inst, PartialSpecs[I])); | ||||||||||||
1804 | } | ||||||||||||
1805 | |||||||||||||
1806 | return Inst; | ||||||||||||
1807 | } | ||||||||||||
1808 | |||||||||||||
1809 | Decl *TemplateDeclInstantiator::VisitVarTemplatePartialSpecializationDecl( | ||||||||||||
1810 | VarTemplatePartialSpecializationDecl *D) { | ||||||||||||
1811 | assert(D->isStaticDataMember() &&(static_cast <bool> (D->isStaticDataMember() && "Only static data member templates are allowed.") ? void (0) : __assert_fail ("D->isStaticDataMember() && \"Only static data member templates are allowed.\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1812, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
1812 | "Only static data member templates are allowed.")(static_cast <bool> (D->isStaticDataMember() && "Only static data member templates are allowed.") ? void (0) : __assert_fail ("D->isStaticDataMember() && \"Only static data member templates are allowed.\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1812, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1813 | |||||||||||||
1814 | VarTemplateDecl *VarTemplate = D->getSpecializedTemplate(); | ||||||||||||
1815 | |||||||||||||
1816 | // Lookup the already-instantiated declaration and return that. | ||||||||||||
1817 | DeclContext::lookup_result Found = Owner->lookup(VarTemplate->getDeclName()); | ||||||||||||
1818 | assert(!Found.empty() && "Instantiation found nothing?")(static_cast <bool> (!Found.empty() && "Instantiation found nothing?" ) ? void (0) : __assert_fail ("!Found.empty() && \"Instantiation found nothing?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1818, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1819 | |||||||||||||
1820 | VarTemplateDecl *InstVarTemplate = dyn_cast<VarTemplateDecl>(Found.front()); | ||||||||||||
1821 | assert(InstVarTemplate && "Instantiation did not find a variable template?")(static_cast <bool> (InstVarTemplate && "Instantiation did not find a variable template?" ) ? void (0) : __assert_fail ("InstVarTemplate && \"Instantiation did not find a variable template?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1821, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1822 | |||||||||||||
1823 | if (VarTemplatePartialSpecializationDecl *Result = | ||||||||||||
1824 | InstVarTemplate->findPartialSpecInstantiatedFromMember(D)) | ||||||||||||
1825 | return Result; | ||||||||||||
1826 | |||||||||||||
1827 | return InstantiateVarTemplatePartialSpecialization(InstVarTemplate, D); | ||||||||||||
1828 | } | ||||||||||||
1829 | |||||||||||||
1830 | Decl * | ||||||||||||
1831 | TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { | ||||||||||||
1832 | // Create a local instantiation scope for this function template, which | ||||||||||||
1833 | // will contain the instantiations of the template parameters and then get | ||||||||||||
1834 | // merged with the local instantiation scope for the function template | ||||||||||||
1835 | // itself. | ||||||||||||
1836 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
1837 | Sema::ConstraintEvalRAII<TemplateDeclInstantiator> RAII(*this); | ||||||||||||
1838 | |||||||||||||
1839 | TemplateParameterList *TempParams = D->getTemplateParameters(); | ||||||||||||
1840 | TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | ||||||||||||
1841 | if (!InstParams) | ||||||||||||
1842 | return nullptr; | ||||||||||||
1843 | |||||||||||||
1844 | FunctionDecl *Instantiated = nullptr; | ||||||||||||
1845 | if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl())) | ||||||||||||
1846 | Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod, | ||||||||||||
1847 | InstParams)); | ||||||||||||
1848 | else | ||||||||||||
1849 | Instantiated = cast_or_null<FunctionDecl>(VisitFunctionDecl( | ||||||||||||
1850 | D->getTemplatedDecl(), | ||||||||||||
1851 | InstParams)); | ||||||||||||
1852 | |||||||||||||
1853 | if (!Instantiated) | ||||||||||||
1854 | return nullptr; | ||||||||||||
1855 | |||||||||||||
1856 | // Link the instantiated function template declaration to the function | ||||||||||||
1857 | // template from which it was instantiated. | ||||||||||||
1858 | FunctionTemplateDecl *InstTemplate | ||||||||||||
1859 | = Instantiated->getDescribedFunctionTemplate(); | ||||||||||||
1860 | InstTemplate->setAccess(D->getAccess()); | ||||||||||||
1861 | assert(InstTemplate &&(static_cast <bool> (InstTemplate && "VisitFunctionDecl/CXXMethodDecl didn't create a template!" ) ? void (0) : __assert_fail ("InstTemplate && \"VisitFunctionDecl/CXXMethodDecl didn't create a template!\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1862, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
1862 | "VisitFunctionDecl/CXXMethodDecl didn't create a template!")(static_cast <bool> (InstTemplate && "VisitFunctionDecl/CXXMethodDecl didn't create a template!" ) ? void (0) : __assert_fail ("InstTemplate && \"VisitFunctionDecl/CXXMethodDecl didn't create a template!\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1862, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1863 | |||||||||||||
1864 | bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None); | ||||||||||||
1865 | |||||||||||||
1866 | // Link the instantiation back to the pattern *unless* this is a | ||||||||||||
1867 | // non-definition friend declaration. | ||||||||||||
1868 | if (!InstTemplate->getInstantiatedFromMemberTemplate() && | ||||||||||||
1869 | !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition())) | ||||||||||||
1870 | InstTemplate->setInstantiatedFromMemberTemplate(D); | ||||||||||||
1871 | |||||||||||||
1872 | // Make declarations visible in the appropriate context. | ||||||||||||
1873 | if (!isFriend) { | ||||||||||||
1874 | Owner->addDecl(InstTemplate); | ||||||||||||
1875 | } else if (InstTemplate->getDeclContext()->isRecord() && | ||||||||||||
1876 | !getPreviousDeclForInstantiation(D)) { | ||||||||||||
1877 | SemaRef.CheckFriendAccess(InstTemplate); | ||||||||||||
1878 | } | ||||||||||||
1879 | |||||||||||||
1880 | return InstTemplate; | ||||||||||||
1881 | } | ||||||||||||
1882 | |||||||||||||
1883 | Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { | ||||||||||||
1884 | CXXRecordDecl *PrevDecl = nullptr; | ||||||||||||
1885 | if (CXXRecordDecl *PatternPrev = getPreviousDeclForInstantiation(D)) { | ||||||||||||
1886 | NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), | ||||||||||||
1887 | PatternPrev, | ||||||||||||
1888 | TemplateArgs); | ||||||||||||
1889 | if (!Prev) return nullptr; | ||||||||||||
1890 | PrevDecl = cast<CXXRecordDecl>(Prev); | ||||||||||||
1891 | } | ||||||||||||
1892 | |||||||||||||
1893 | CXXRecordDecl *Record = nullptr; | ||||||||||||
1894 | bool IsInjectedClassName = D->isInjectedClassName(); | ||||||||||||
1895 | if (D->isLambda()) | ||||||||||||
1896 | Record = CXXRecordDecl::CreateLambda( | ||||||||||||
1897 | SemaRef.Context, Owner, D->getLambdaTypeInfo(), D->getLocation(), | ||||||||||||
1898 | D->getLambdaDependencyKind(), D->isGenericLambda(), | ||||||||||||
1899 | D->getLambdaCaptureDefault()); | ||||||||||||
1900 | else | ||||||||||||
1901 | Record = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner, | ||||||||||||
1902 | D->getBeginLoc(), D->getLocation(), | ||||||||||||
1903 | D->getIdentifier(), PrevDecl, | ||||||||||||
1904 | /*DelayTypeCreation=*/IsInjectedClassName); | ||||||||||||
1905 | // Link the type of the injected-class-name to that of the outer class. | ||||||||||||
1906 | if (IsInjectedClassName) | ||||||||||||
1907 | (void)SemaRef.Context.getTypeDeclType(Record, cast<CXXRecordDecl>(Owner)); | ||||||||||||
1908 | |||||||||||||
1909 | // Substitute the nested name specifier, if any. | ||||||||||||
1910 | if (SubstQualifier(D, Record)) | ||||||||||||
1911 | return nullptr; | ||||||||||||
1912 | |||||||||||||
1913 | SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, Record, LateAttrs, | ||||||||||||
1914 | StartingScope); | ||||||||||||
1915 | |||||||||||||
1916 | Record->setImplicit(D->isImplicit()); | ||||||||||||
1917 | // FIXME: Check against AS_none is an ugly hack to work around the issue that | ||||||||||||
1918 | // the tag decls introduced by friend class declarations don't have an access | ||||||||||||
1919 | // specifier. Remove once this area of the code gets sorted out. | ||||||||||||
1920 | if (D->getAccess() != AS_none) | ||||||||||||
1921 | Record->setAccess(D->getAccess()); | ||||||||||||
1922 | if (!IsInjectedClassName) | ||||||||||||
1923 | Record->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation); | ||||||||||||
1924 | |||||||||||||
1925 | // If the original function was part of a friend declaration, | ||||||||||||
1926 | // inherit its namespace state. | ||||||||||||
1927 | if (D->getFriendObjectKind()) | ||||||||||||
1928 | Record->setObjectOfFriendDecl(); | ||||||||||||
1929 | |||||||||||||
1930 | // Make sure that anonymous structs and unions are recorded. | ||||||||||||
1931 | if (D->isAnonymousStructOrUnion()) | ||||||||||||
1932 | Record->setAnonymousStructOrUnion(true); | ||||||||||||
1933 | |||||||||||||
1934 | if (D->isLocalClass()) | ||||||||||||
1935 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record); | ||||||||||||
1936 | |||||||||||||
1937 | // Forward the mangling number from the template to the instantiated decl. | ||||||||||||
1938 | SemaRef.Context.setManglingNumber(Record, | ||||||||||||
1939 | SemaRef.Context.getManglingNumber(D)); | ||||||||||||
1940 | |||||||||||||
1941 | // See if the old tag was defined along with a declarator. | ||||||||||||
1942 | // If it did, mark the new tag as being associated with that declarator. | ||||||||||||
1943 | if (DeclaratorDecl *DD = SemaRef.Context.getDeclaratorForUnnamedTagDecl(D)) | ||||||||||||
1944 | SemaRef.Context.addDeclaratorForUnnamedTagDecl(Record, DD); | ||||||||||||
1945 | |||||||||||||
1946 | // See if the old tag was defined along with a typedef. | ||||||||||||
1947 | // If it did, mark the new tag as being associated with that typedef. | ||||||||||||
1948 | if (TypedefNameDecl *TND = SemaRef.Context.getTypedefNameForUnnamedTagDecl(D)) | ||||||||||||
1949 | SemaRef.Context.addTypedefNameForUnnamedTagDecl(Record, TND); | ||||||||||||
1950 | |||||||||||||
1951 | Owner->addDecl(Record); | ||||||||||||
1952 | |||||||||||||
1953 | // DR1484 clarifies that the members of a local class are instantiated as part | ||||||||||||
1954 | // of the instantiation of their enclosing entity. | ||||||||||||
1955 | if (D->isCompleteDefinition() && D->isLocalClass()) { | ||||||||||||
1956 | Sema::LocalEagerInstantiationScope LocalInstantiations(SemaRef); | ||||||||||||
1957 | |||||||||||||
1958 | SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs, | ||||||||||||
1959 | TSK_ImplicitInstantiation, | ||||||||||||
1960 | /*Complain=*/true); | ||||||||||||
1961 | |||||||||||||
1962 | // For nested local classes, we will instantiate the members when we | ||||||||||||
1963 | // reach the end of the outermost (non-nested) local class. | ||||||||||||
1964 | if (!D->isCXXClassMember()) | ||||||||||||
1965 | SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs, | ||||||||||||
1966 | TSK_ImplicitInstantiation); | ||||||||||||
1967 | |||||||||||||
1968 | // This class may have local implicit instantiations that need to be | ||||||||||||
1969 | // performed within this scope. | ||||||||||||
1970 | LocalInstantiations.perform(); | ||||||||||||
1971 | } | ||||||||||||
1972 | |||||||||||||
1973 | SemaRef.DiagnoseUnusedNestedTypedefs(Record); | ||||||||||||
1974 | |||||||||||||
1975 | if (IsInjectedClassName) | ||||||||||||
1976 | assert(Record->isInjectedClassName() && "Broken injected-class-name")(static_cast <bool> (Record->isInjectedClassName() && "Broken injected-class-name") ? void (0) : __assert_fail ("Record->isInjectedClassName() && \"Broken injected-class-name\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 1976, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1977 | |||||||||||||
1978 | return Record; | ||||||||||||
1979 | } | ||||||||||||
1980 | |||||||||||||
1981 | /// Adjust the given function type for an instantiation of the | ||||||||||||
1982 | /// given declaration, to cope with modifications to the function's type that | ||||||||||||
1983 | /// aren't reflected in the type-source information. | ||||||||||||
1984 | /// | ||||||||||||
1985 | /// \param D The declaration we're instantiating. | ||||||||||||
1986 | /// \param TInfo The already-instantiated type. | ||||||||||||
1987 | static QualType adjustFunctionTypeForInstantiation(ASTContext &Context, | ||||||||||||
1988 | FunctionDecl *D, | ||||||||||||
1989 | TypeSourceInfo *TInfo) { | ||||||||||||
1990 | const FunctionProtoType *OrigFunc | ||||||||||||
1991 | = D->getType()->castAs<FunctionProtoType>(); | ||||||||||||
1992 | const FunctionProtoType *NewFunc | ||||||||||||
1993 | = TInfo->getType()->castAs<FunctionProtoType>(); | ||||||||||||
1994 | if (OrigFunc->getExtInfo() == NewFunc->getExtInfo()) | ||||||||||||
1995 | return TInfo->getType(); | ||||||||||||
1996 | |||||||||||||
1997 | FunctionProtoType::ExtProtoInfo NewEPI = NewFunc->getExtProtoInfo(); | ||||||||||||
1998 | NewEPI.ExtInfo = OrigFunc->getExtInfo(); | ||||||||||||
1999 | return Context.getFunctionType(NewFunc->getReturnType(), | ||||||||||||
2000 | NewFunc->getParamTypes(), NewEPI); | ||||||||||||
2001 | } | ||||||||||||
2002 | |||||||||||||
2003 | /// Normal class members are of more specific types and therefore | ||||||||||||
2004 | /// don't make it here. This function serves three purposes: | ||||||||||||
2005 | /// 1) instantiating function templates | ||||||||||||
2006 | /// 2) substituting friend declarations | ||||||||||||
2007 | /// 3) substituting deduction guide declarations for nested class templates | ||||||||||||
2008 | Decl *TemplateDeclInstantiator::VisitFunctionDecl( | ||||||||||||
2009 | FunctionDecl *D, TemplateParameterList *TemplateParams, | ||||||||||||
2010 | RewriteKind FunctionRewriteKind) { | ||||||||||||
2011 | // Check whether there is already a function template specialization for | ||||||||||||
2012 | // this declaration. | ||||||||||||
2013 | FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); | ||||||||||||
2014 | if (FunctionTemplate && !TemplateParams) { | ||||||||||||
2015 | ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost(); | ||||||||||||
2016 | |||||||||||||
2017 | void *InsertPos = nullptr; | ||||||||||||
2018 | FunctionDecl *SpecFunc | ||||||||||||
2019 | = FunctionTemplate->findSpecialization(Innermost, InsertPos); | ||||||||||||
2020 | |||||||||||||
2021 | // If we already have a function template specialization, return it. | ||||||||||||
2022 | if (SpecFunc) | ||||||||||||
2023 | return SpecFunc; | ||||||||||||
2024 | } | ||||||||||||
2025 | |||||||||||||
2026 | bool isFriend; | ||||||||||||
2027 | if (FunctionTemplate) | ||||||||||||
2028 | isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None); | ||||||||||||
2029 | else | ||||||||||||
2030 | isFriend = (D->getFriendObjectKind() != Decl::FOK_None); | ||||||||||||
2031 | |||||||||||||
2032 | bool MergeWithParentScope = (TemplateParams != nullptr) || | ||||||||||||
2033 | Owner->isFunctionOrMethod() || | ||||||||||||
2034 | !(isa<Decl>(Owner) && | ||||||||||||
2035 | cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); | ||||||||||||
2036 | LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); | ||||||||||||
2037 | |||||||||||||
2038 | ExplicitSpecifier InstantiatedExplicitSpecifier; | ||||||||||||
2039 | if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) { | ||||||||||||
2040 | InstantiatedExplicitSpecifier = instantiateExplicitSpecifier( | ||||||||||||
2041 | SemaRef, TemplateArgs, DGuide->getExplicitSpecifier(), DGuide); | ||||||||||||
2042 | if (InstantiatedExplicitSpecifier.isInvalid()) | ||||||||||||
2043 | return nullptr; | ||||||||||||
2044 | } | ||||||||||||
2045 | |||||||||||||
2046 | SmallVector<ParmVarDecl *, 4> Params; | ||||||||||||
2047 | TypeSourceInfo *TInfo = SubstFunctionType(D, Params); | ||||||||||||
2048 | if (!TInfo) | ||||||||||||
2049 | return nullptr; | ||||||||||||
2050 | QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo); | ||||||||||||
2051 | |||||||||||||
2052 | if (TemplateParams && TemplateParams->size()) { | ||||||||||||
2053 | auto *LastParam = | ||||||||||||
2054 | dyn_cast<TemplateTypeParmDecl>(TemplateParams->asArray().back()); | ||||||||||||
2055 | if (LastParam && LastParam->isImplicit() && | ||||||||||||
2056 | LastParam->hasTypeConstraint()) { | ||||||||||||
2057 | // In abbreviated templates, the type-constraints of invented template | ||||||||||||
2058 | // type parameters are instantiated with the function type, invalidating | ||||||||||||
2059 | // the TemplateParameterList which relied on the template type parameter | ||||||||||||
2060 | // not having a type constraint. Recreate the TemplateParameterList with | ||||||||||||
2061 | // the updated parameter list. | ||||||||||||
2062 | TemplateParams = TemplateParameterList::Create( | ||||||||||||
2063 | SemaRef.Context, TemplateParams->getTemplateLoc(), | ||||||||||||
2064 | TemplateParams->getLAngleLoc(), TemplateParams->asArray(), | ||||||||||||
2065 | TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause()); | ||||||||||||
2066 | } | ||||||||||||
2067 | } | ||||||||||||
2068 | |||||||||||||
2069 | NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); | ||||||||||||
2070 | if (QualifierLoc) { | ||||||||||||
2071 | QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, | ||||||||||||
2072 | TemplateArgs); | ||||||||||||
2073 | if (!QualifierLoc) | ||||||||||||
2074 | return nullptr; | ||||||||||||
2075 | } | ||||||||||||
2076 | |||||||||||||
2077 | Expr *TrailingRequiresClause = D->getTrailingRequiresClause(); | ||||||||||||
2078 | |||||||||||||
2079 | // If we're instantiating a local function declaration, put the result | ||||||||||||
2080 | // in the enclosing namespace; otherwise we need to find the instantiated | ||||||||||||
2081 | // context. | ||||||||||||
2082 | DeclContext *DC; | ||||||||||||
2083 | if (D->isLocalExternDecl()) { | ||||||||||||
2084 | DC = Owner; | ||||||||||||
2085 | SemaRef.adjustContextForLocalExternDecl(DC); | ||||||||||||
2086 | } else if (isFriend && QualifierLoc) { | ||||||||||||
2087 | CXXScopeSpec SS; | ||||||||||||
2088 | SS.Adopt(QualifierLoc); | ||||||||||||
2089 | DC = SemaRef.computeDeclContext(SS); | ||||||||||||
2090 | if (!DC) return nullptr; | ||||||||||||
2091 | } else { | ||||||||||||
2092 | DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), | ||||||||||||
2093 | TemplateArgs); | ||||||||||||
2094 | } | ||||||||||||
2095 | |||||||||||||
2096 | DeclarationNameInfo NameInfo | ||||||||||||
2097 | = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); | ||||||||||||
2098 | |||||||||||||
2099 | if (FunctionRewriteKind != RewriteKind::None) | ||||||||||||
2100 | adjustForRewrite(FunctionRewriteKind, D, T, TInfo, NameInfo); | ||||||||||||
2101 | |||||||||||||
2102 | FunctionDecl *Function; | ||||||||||||
2103 | if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) { | ||||||||||||
2104 | Function = CXXDeductionGuideDecl::Create( | ||||||||||||
2105 | SemaRef.Context, DC, D->getInnerLocStart(), | ||||||||||||
2106 | InstantiatedExplicitSpecifier, NameInfo, T, TInfo, | ||||||||||||
2107 | D->getSourceRange().getEnd()); | ||||||||||||
2108 | if (DGuide->isCopyDeductionCandidate()) | ||||||||||||
2109 | cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate(); | ||||||||||||
2110 | Function->setAccess(D->getAccess()); | ||||||||||||
2111 | } else { | ||||||||||||
2112 | Function = FunctionDecl::Create( | ||||||||||||
2113 | SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo, | ||||||||||||
2114 | D->getCanonicalDecl()->getStorageClass(), D->UsesFPIntrin(), | ||||||||||||
2115 | D->isInlineSpecified(), D->hasWrittenPrototype(), D->getConstexprKind(), | ||||||||||||
2116 | TrailingRequiresClause); | ||||||||||||
2117 | Function->setFriendConstraintRefersToEnclosingTemplate( | ||||||||||||
2118 | D->FriendConstraintRefersToEnclosingTemplate()); | ||||||||||||
2119 | Function->setRangeEnd(D->getSourceRange().getEnd()); | ||||||||||||
2120 | } | ||||||||||||
2121 | |||||||||||||
2122 | if (D->isInlined()) | ||||||||||||
2123 | Function->setImplicitlyInline(); | ||||||||||||
2124 | |||||||||||||
2125 | if (QualifierLoc) | ||||||||||||
2126 | Function->setQualifierInfo(QualifierLoc); | ||||||||||||
2127 | |||||||||||||
2128 | if (D->isLocalExternDecl()) | ||||||||||||
2129 | Function->setLocalExternDecl(); | ||||||||||||
2130 | |||||||||||||
2131 | DeclContext *LexicalDC = Owner; | ||||||||||||
2132 | if (!isFriend && D->isOutOfLine() && !D->isLocalExternDecl()) { | ||||||||||||
2133 | assert(D->getDeclContext()->isFileContext())(static_cast <bool> (D->getDeclContext()->isFileContext ()) ? void (0) : __assert_fail ("D->getDeclContext()->isFileContext()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 2133, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
2134 | LexicalDC = D->getDeclContext(); | ||||||||||||
2135 | } | ||||||||||||
2136 | |||||||||||||
2137 | Function->setLexicalDeclContext(LexicalDC); | ||||||||||||
2138 | |||||||||||||
2139 | // Attach the parameters | ||||||||||||
2140 | for (unsigned P = 0; P < Params.size(); ++P) | ||||||||||||
2141 | if (Params[P]) | ||||||||||||
2142 | Params[P]->setOwningFunction(Function); | ||||||||||||
2143 | Function->setParams(Params); | ||||||||||||
2144 | |||||||||||||
2145 | if (TrailingRequiresClause) | ||||||||||||
2146 | Function->setTrailingRequiresClause(TrailingRequiresClause); | ||||||||||||
2147 | |||||||||||||
2148 | if (TemplateParams) { | ||||||||||||
2149 | // Our resulting instantiation is actually a function template, since we | ||||||||||||
2150 | // are substituting only the outer template parameters. For example, given | ||||||||||||
2151 | // | ||||||||||||
2152 | // template<typename T> | ||||||||||||
2153 | // struct X { | ||||||||||||
2154 | // template<typename U> friend void f(T, U); | ||||||||||||
2155 | // }; | ||||||||||||
2156 | // | ||||||||||||
2157 | // X<int> x; | ||||||||||||
2158 | // | ||||||||||||
2159 | // We are instantiating the friend function template "f" within X<int>, | ||||||||||||
2160 | // which means substituting int for T, but leaving "f" as a friend function | ||||||||||||
2161 | // template. | ||||||||||||
2162 | // Build the function template itself. | ||||||||||||
2163 | FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, DC, | ||||||||||||
2164 | Function->getLocation(), | ||||||||||||
2165 | Function->getDeclName(), | ||||||||||||
2166 | TemplateParams, Function); | ||||||||||||
2167 | Function->setDescribedFunctionTemplate(FunctionTemplate); | ||||||||||||
2168 | |||||||||||||
2169 | FunctionTemplate->setLexicalDeclContext(LexicalDC); | ||||||||||||
2170 | |||||||||||||
2171 | if (isFriend && D->isThisDeclarationADefinition()) { | ||||||||||||
2172 | FunctionTemplate->setInstantiatedFromMemberTemplate( | ||||||||||||
2173 | D->getDescribedFunctionTemplate()); | ||||||||||||
2174 | } | ||||||||||||
2175 | } else if (FunctionTemplate) { | ||||||||||||
2176 | // Record this function template specialization. | ||||||||||||
2177 | ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost(); | ||||||||||||
2178 | Function->setFunctionTemplateSpecialization(FunctionTemplate, | ||||||||||||
2179 | TemplateArgumentList::CreateCopy(SemaRef.Context, | ||||||||||||
2180 | Innermost), | ||||||||||||
2181 | /*InsertPos=*/nullptr); | ||||||||||||
2182 | } else if (isFriend && D->isThisDeclarationADefinition()) { | ||||||||||||
2183 | // Do not connect the friend to the template unless it's actually a | ||||||||||||
2184 | // definition. We don't want non-template functions to be marked as being | ||||||||||||
2185 | // template instantiations. | ||||||||||||
2186 | Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); | ||||||||||||
2187 | } else if (!isFriend) { | ||||||||||||
2188 | // If this is not a function template, and this is not a friend (that is, | ||||||||||||
2189 | // this is a locally declared function), save the instantiation relationship | ||||||||||||
2190 | // for the purposes of constraint instantiation. | ||||||||||||
2191 | Function->setInstantiatedFromDecl(D); | ||||||||||||
2192 | } | ||||||||||||
2193 | |||||||||||||
2194 | if (isFriend) { | ||||||||||||
2195 | Function->setObjectOfFriendDecl(); | ||||||||||||
2196 | if (FunctionTemplateDecl *FT = Function->getDescribedFunctionTemplate()) | ||||||||||||
2197 | FT->setObjectOfFriendDecl(); | ||||||||||||
2198 | } | ||||||||||||
2199 | |||||||||||||
2200 | if (InitFunctionInstantiation(Function, D)) | ||||||||||||
2201 | Function->setInvalidDecl(); | ||||||||||||
2202 | |||||||||||||
2203 | bool IsExplicitSpecialization = false; | ||||||||||||
2204 | |||||||||||||
2205 | LookupResult Previous( | ||||||||||||
2206 | SemaRef, Function->getDeclName(), SourceLocation(), | ||||||||||||
2207 | D->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage | ||||||||||||
2208 | : Sema::LookupOrdinaryName, | ||||||||||||
2209 | D->isLocalExternDecl() ? Sema::ForExternalRedeclaration | ||||||||||||
2210 | : SemaRef.forRedeclarationInCurContext()); | ||||||||||||
2211 | |||||||||||||
2212 | if (DependentFunctionTemplateSpecializationInfo *Info | ||||||||||||
2213 | = D->getDependentSpecializationInfo()) { | ||||||||||||
2214 | assert(isFriend && "non-friend has dependent specialization info?")(static_cast <bool> (isFriend && "non-friend has dependent specialization info?" ) ? void (0) : __assert_fail ("isFriend && \"non-friend has dependent specialization info?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 2214, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
2215 | |||||||||||||
2216 | // Instantiate the explicit template arguments. | ||||||||||||
2217 | TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), | ||||||||||||
2218 | Info->getRAngleLoc()); | ||||||||||||
2219 | if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, | ||||||||||||
2220 | ExplicitArgs)) | ||||||||||||
2221 | return nullptr; | ||||||||||||
2222 | |||||||||||||
2223 | // Map the candidate templates to their instantiations. | ||||||||||||
2224 | for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) { | ||||||||||||
2225 | Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(), | ||||||||||||
2226 | Info->getTemplate(I), | ||||||||||||
2227 | TemplateArgs); | ||||||||||||
2228 | if (!Temp) return nullptr; | ||||||||||||
2229 | |||||||||||||
2230 | Previous.addDecl(cast<FunctionTemplateDecl>(Temp)); | ||||||||||||
2231 | } | ||||||||||||
2232 | |||||||||||||
2233 | if (SemaRef.CheckFunctionTemplateSpecialization(Function, | ||||||||||||
2234 | &ExplicitArgs, | ||||||||||||
2235 | Previous)) | ||||||||||||
2236 | Function->setInvalidDecl(); | ||||||||||||
2237 | |||||||||||||
2238 | IsExplicitSpecialization = true; | ||||||||||||
2239 | } else if (const ASTTemplateArgumentListInfo *Info = | ||||||||||||
2240 | D->getTemplateSpecializationArgsAsWritten()) { | ||||||||||||
2241 | // The name of this function was written as a template-id. | ||||||||||||
2242 | SemaRef.LookupQualifiedName(Previous, DC); | ||||||||||||
2243 | |||||||||||||
2244 | // Instantiate the explicit template arguments. | ||||||||||||
2245 | TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), | ||||||||||||
2246 | Info->getRAngleLoc()); | ||||||||||||
2247 | if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, | ||||||||||||
2248 | ExplicitArgs)) | ||||||||||||
2249 | return nullptr; | ||||||||||||
2250 | |||||||||||||
2251 | if (SemaRef.CheckFunctionTemplateSpecialization(Function, | ||||||||||||
2252 | &ExplicitArgs, | ||||||||||||
2253 | Previous)) | ||||||||||||
2254 | Function->setInvalidDecl(); | ||||||||||||
2255 | |||||||||||||
2256 | IsExplicitSpecialization = true; | ||||||||||||
2257 | } else if (TemplateParams || !FunctionTemplate) { | ||||||||||||
2258 | // Look only into the namespace where the friend would be declared to | ||||||||||||
2259 | // find a previous declaration. This is the innermost enclosing namespace, | ||||||||||||
2260 | // as described in ActOnFriendFunctionDecl. | ||||||||||||
2261 | SemaRef.LookupQualifiedName(Previous, DC->getRedeclContext()); | ||||||||||||
2262 | |||||||||||||
2263 | // In C++, the previous declaration we find might be a tag type | ||||||||||||
2264 | // (class or enum). In this case, the new declaration will hide the | ||||||||||||
2265 | // tag type. Note that this does does not apply if we're declaring a | ||||||||||||
2266 | // typedef (C++ [dcl.typedef]p4). | ||||||||||||
2267 | if (Previous.isSingleTagDecl()) | ||||||||||||
2268 | Previous.clear(); | ||||||||||||
2269 | |||||||||||||
2270 | // Filter out previous declarations that don't match the scope. The only | ||||||||||||
2271 | // effect this has is to remove declarations found in inline namespaces | ||||||||||||
2272 | // for friend declarations with unqualified names. | ||||||||||||
2273 | SemaRef.FilterLookupForScope(Previous, DC, /*Scope*/ nullptr, | ||||||||||||
2274 | /*ConsiderLinkage*/ true, | ||||||||||||
2275 | QualifierLoc.hasQualifier()); | ||||||||||||
2276 | } | ||||||||||||
2277 | |||||||||||||
2278 | SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous, | ||||||||||||
2279 | IsExplicitSpecialization, | ||||||||||||
2280 | Function->isThisDeclarationADefinition()); | ||||||||||||
2281 | |||||||||||||
2282 | // Check the template parameter list against the previous declaration. The | ||||||||||||
2283 | // goal here is to pick up default arguments added since the friend was | ||||||||||||
2284 | // declared; we know the template parameter lists match, since otherwise | ||||||||||||
2285 | // we would not have picked this template as the previous declaration. | ||||||||||||
2286 | if (isFriend && TemplateParams && FunctionTemplate->getPreviousDecl()) { | ||||||||||||
2287 | SemaRef.CheckTemplateParameterList( | ||||||||||||
2288 | TemplateParams, | ||||||||||||
2289 | FunctionTemplate->getPreviousDecl()->getTemplateParameters(), | ||||||||||||
2290 | Function->isThisDeclarationADefinition() | ||||||||||||
2291 | ? Sema::TPC_FriendFunctionTemplateDefinition | ||||||||||||
2292 | : Sema::TPC_FriendFunctionTemplate); | ||||||||||||
2293 | } | ||||||||||||
2294 | |||||||||||||
2295 | // If we're introducing a friend definition after the first use, trigger | ||||||||||||
2296 | // instantiation. | ||||||||||||
2297 | // FIXME: If this is a friend function template definition, we should check | ||||||||||||
2298 | // to see if any specializations have been used. | ||||||||||||
2299 | if (isFriend && D->isThisDeclarationADefinition() && Function->isUsed(false)) { | ||||||||||||
2300 | if (MemberSpecializationInfo *MSInfo = | ||||||||||||
2301 | Function->getMemberSpecializationInfo()) { | ||||||||||||
2302 | if (MSInfo->getPointOfInstantiation().isInvalid()) { | ||||||||||||
2303 | SourceLocation Loc = D->getLocation(); // FIXME | ||||||||||||
2304 | MSInfo->setPointOfInstantiation(Loc); | ||||||||||||
2305 | SemaRef.PendingLocalImplicitInstantiations.push_back( | ||||||||||||
2306 | std::make_pair(Function, Loc)); | ||||||||||||
2307 | } | ||||||||||||
2308 | } | ||||||||||||
2309 | } | ||||||||||||
2310 | |||||||||||||
2311 | if (D->isExplicitlyDefaulted()) { | ||||||||||||
2312 | if (SubstDefaultedFunction(Function, D)) | ||||||||||||
2313 | return nullptr; | ||||||||||||
2314 | } | ||||||||||||
2315 | if (D->isDeleted()) | ||||||||||||
2316 | SemaRef.SetDeclDeleted(Function, D->getLocation()); | ||||||||||||
2317 | |||||||||||||
2318 | NamedDecl *PrincipalDecl = | ||||||||||||
2319 | (TemplateParams ? cast<NamedDecl>(FunctionTemplate) : Function); | ||||||||||||
2320 | |||||||||||||
2321 | // If this declaration lives in a different context from its lexical context, | ||||||||||||
2322 | // add it to the corresponding lookup table. | ||||||||||||
2323 | if (isFriend || | ||||||||||||
2324 | (Function->isLocalExternDecl() && !Function->getPreviousDecl())) | ||||||||||||
2325 | DC->makeDeclVisibleInContext(PrincipalDecl); | ||||||||||||
2326 | |||||||||||||
2327 | if (Function->isOverloadedOperator() && !DC->isRecord() && | ||||||||||||
2328 | PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary)) | ||||||||||||
2329 | PrincipalDecl->setNonMemberOperator(); | ||||||||||||
2330 | |||||||||||||
2331 | return Function; | ||||||||||||
2332 | } | ||||||||||||
2333 | |||||||||||||
2334 | Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( | ||||||||||||
2335 | CXXMethodDecl *D, TemplateParameterList *TemplateParams, | ||||||||||||
2336 | Optional<const ASTTemplateArgumentListInfo *> ClassScopeSpecializationArgs, | ||||||||||||
2337 | RewriteKind FunctionRewriteKind) { | ||||||||||||
2338 | FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); | ||||||||||||
2339 | if (FunctionTemplate && !TemplateParams) { | ||||||||||||
2340 | // We are creating a function template specialization from a function | ||||||||||||
2341 | // template. Check whether there is already a function template | ||||||||||||
2342 | // specialization for this particular set of template arguments. | ||||||||||||
2343 | ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost(); | ||||||||||||
2344 | |||||||||||||
2345 | void *InsertPos = nullptr; | ||||||||||||
2346 | FunctionDecl *SpecFunc | ||||||||||||
2347 | = FunctionTemplate->findSpecialization(Innermost, InsertPos); | ||||||||||||
2348 | |||||||||||||
2349 | // If we already have a function template specialization, return it. | ||||||||||||
2350 | if (SpecFunc) | ||||||||||||
2351 | return SpecFunc; | ||||||||||||
2352 | } | ||||||||||||
2353 | |||||||||||||
2354 | bool isFriend; | ||||||||||||
2355 | if (FunctionTemplate) | ||||||||||||
2356 | isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None); | ||||||||||||
2357 | else | ||||||||||||
2358 | isFriend = (D->getFriendObjectKind() != Decl::FOK_None); | ||||||||||||
2359 | |||||||||||||
2360 | bool MergeWithParentScope = (TemplateParams != nullptr) || | ||||||||||||
2361 | !(isa<Decl>(Owner) && | ||||||||||||
2362 | cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); | ||||||||||||
2363 | LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); | ||||||||||||
2364 | |||||||||||||
2365 | // Instantiate enclosing template arguments for friends. | ||||||||||||
2366 | SmallVector<TemplateParameterList *, 4> TempParamLists; | ||||||||||||
2367 | unsigned NumTempParamLists = 0; | ||||||||||||
2368 | if (isFriend && (NumTempParamLists = D->getNumTemplateParameterLists())) { | ||||||||||||
2369 | TempParamLists.resize(NumTempParamLists); | ||||||||||||
2370 | for (unsigned I = 0; I != NumTempParamLists; ++I) { | ||||||||||||
2371 | TemplateParameterList *TempParams = D->getTemplateParameterList(I); | ||||||||||||
2372 | TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | ||||||||||||
2373 | if (!InstParams) | ||||||||||||
2374 | return nullptr; | ||||||||||||
2375 | TempParamLists[I] = InstParams; | ||||||||||||
2376 | } | ||||||||||||
2377 | } | ||||||||||||
2378 | |||||||||||||
2379 | ExplicitSpecifier InstantiatedExplicitSpecifier = | ||||||||||||
2380 | instantiateExplicitSpecifier(SemaRef, TemplateArgs, | ||||||||||||
2381 | ExplicitSpecifier::getFromDecl(D), D); | ||||||||||||
2382 | if (InstantiatedExplicitSpecifier.isInvalid()) | ||||||||||||
2383 | return nullptr; | ||||||||||||
2384 | |||||||||||||
2385 | // Implicit destructors/constructors created for local classes in | ||||||||||||
2386 | // DeclareImplicit* (see SemaDeclCXX.cpp) might not have an associated TSI. | ||||||||||||
2387 | // Unfortunately there isn't enough context in those functions to | ||||||||||||
2388 | // conditionally populate the TSI without breaking non-template related use | ||||||||||||
2389 | // cases. Populate TSIs prior to calling SubstFunctionType to make sure we get | ||||||||||||
2390 | // a proper transformation. | ||||||||||||
2391 | if (cast<CXXRecordDecl>(D->getParent())->isLambda() && | ||||||||||||
2392 | !D->getTypeSourceInfo() && | ||||||||||||
2393 | isa<CXXConstructorDecl, CXXDestructorDecl>(D)) { | ||||||||||||
2394 | TypeSourceInfo *TSI = | ||||||||||||
2395 | SemaRef.Context.getTrivialTypeSourceInfo(D->getType()); | ||||||||||||
2396 | D->setTypeSourceInfo(TSI); | ||||||||||||
2397 | } | ||||||||||||
2398 | |||||||||||||
2399 | SmallVector<ParmVarDecl *, 4> Params; | ||||||||||||
2400 | TypeSourceInfo *TInfo = SubstFunctionType(D, Params); | ||||||||||||
2401 | if (!TInfo) | ||||||||||||
2402 | return nullptr; | ||||||||||||
2403 | QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo); | ||||||||||||
2404 | |||||||||||||
2405 | if (TemplateParams && TemplateParams->size()) { | ||||||||||||
2406 | auto *LastParam = | ||||||||||||
2407 | dyn_cast<TemplateTypeParmDecl>(TemplateParams->asArray().back()); | ||||||||||||
2408 | if (LastParam && LastParam->isImplicit() && | ||||||||||||
2409 | LastParam->hasTypeConstraint()) { | ||||||||||||
2410 | // In abbreviated templates, the type-constraints of invented template | ||||||||||||
2411 | // type parameters are instantiated with the function type, invalidating | ||||||||||||
2412 | // the TemplateParameterList which relied on the template type parameter | ||||||||||||
2413 | // not having a type constraint. Recreate the TemplateParameterList with | ||||||||||||
2414 | // the updated parameter list. | ||||||||||||
2415 | TemplateParams = TemplateParameterList::Create( | ||||||||||||
2416 | SemaRef.Context, TemplateParams->getTemplateLoc(), | ||||||||||||
2417 | TemplateParams->getLAngleLoc(), TemplateParams->asArray(), | ||||||||||||
2418 | TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause()); | ||||||||||||
2419 | } | ||||||||||||
2420 | } | ||||||||||||
2421 | |||||||||||||
2422 | NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); | ||||||||||||
2423 | if (QualifierLoc) { | ||||||||||||
2424 | QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, | ||||||||||||
2425 | TemplateArgs); | ||||||||||||
2426 | if (!QualifierLoc) | ||||||||||||
2427 | return nullptr; | ||||||||||||
2428 | } | ||||||||||||
2429 | |||||||||||||
2430 | DeclContext *DC = Owner; | ||||||||||||
2431 | if (isFriend) { | ||||||||||||
2432 | if (QualifierLoc) { | ||||||||||||
2433 | CXXScopeSpec SS; | ||||||||||||
2434 | SS.Adopt(QualifierLoc); | ||||||||||||
2435 | DC = SemaRef.computeDeclContext(SS); | ||||||||||||
2436 | |||||||||||||
2437 | if (DC && SemaRef.RequireCompleteDeclContext(SS, DC)) | ||||||||||||
2438 | return nullptr; | ||||||||||||
2439 | } else { | ||||||||||||
2440 | DC = SemaRef.FindInstantiatedContext(D->getLocation(), | ||||||||||||
2441 | D->getDeclContext(), | ||||||||||||
2442 | TemplateArgs); | ||||||||||||
2443 | } | ||||||||||||
2444 | if (!DC) return nullptr; | ||||||||||||
2445 | } | ||||||||||||
2446 | |||||||||||||
2447 | CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); | ||||||||||||
2448 | Expr *TrailingRequiresClause = D->getTrailingRequiresClause(); | ||||||||||||
2449 | |||||||||||||
2450 | DeclarationNameInfo NameInfo | ||||||||||||
2451 | = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); | ||||||||||||
2452 | |||||||||||||
2453 | if (FunctionRewriteKind != RewriteKind::None) | ||||||||||||
2454 | adjustForRewrite(FunctionRewriteKind, D, T, TInfo, NameInfo); | ||||||||||||
2455 | |||||||||||||
2456 | // Build the instantiated method declaration. | ||||||||||||
2457 | CXXMethodDecl *Method = nullptr; | ||||||||||||
2458 | |||||||||||||
2459 | SourceLocation StartLoc = D->getInnerLocStart(); | ||||||||||||
2460 | if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { | ||||||||||||
2461 | Method = CXXConstructorDecl::Create( | ||||||||||||
2462 | SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, | ||||||||||||
2463 | InstantiatedExplicitSpecifier, Constructor->UsesFPIntrin(), | ||||||||||||
2464 | Constructor->isInlineSpecified(), false, | ||||||||||||
2465 | Constructor->getConstexprKind(), InheritedConstructor(), | ||||||||||||
2466 | TrailingRequiresClause); | ||||||||||||
2467 | Method->setRangeEnd(Constructor->getEndLoc()); | ||||||||||||
2468 | if (Constructor->isDefaultConstructor() || | ||||||||||||
2469 | Constructor->isCopyOrMoveConstructor()) | ||||||||||||
2470 | Method->setIneligibleOrNotSelected(true); | ||||||||||||
2471 | } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { | ||||||||||||
2472 | Method = CXXDestructorDecl::Create( | ||||||||||||
2473 | SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, | ||||||||||||
2474 | Destructor->UsesFPIntrin(), Destructor->isInlineSpecified(), false, | ||||||||||||
2475 | Destructor->getConstexprKind(), TrailingRequiresClause); | ||||||||||||
2476 | Method->setIneligibleOrNotSelected(true); | ||||||||||||
2477 | Method->setRangeEnd(Destructor->getEndLoc()); | ||||||||||||
2478 | Method->setDeclName(SemaRef.Context.DeclarationNames.getCXXDestructorName( | ||||||||||||
2479 | SemaRef.Context.getCanonicalType( | ||||||||||||
2480 | SemaRef.Context.getTypeDeclType(Record)))); | ||||||||||||
2481 | } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) { | ||||||||||||
2482 | Method = CXXConversionDecl::Create( | ||||||||||||
2483 | SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, | ||||||||||||
2484 | Conversion->UsesFPIntrin(), Conversion->isInlineSpecified(), | ||||||||||||
2485 | InstantiatedExplicitSpecifier, Conversion->getConstexprKind(), | ||||||||||||
2486 | Conversion->getEndLoc(), TrailingRequiresClause); | ||||||||||||
2487 | } else { | ||||||||||||
2488 | StorageClass SC = D->isStatic() ? SC_Static : SC_None; | ||||||||||||
2489 | Method = CXXMethodDecl::Create( | ||||||||||||
2490 | SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC, | ||||||||||||
2491 | D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(), | ||||||||||||
2492 | D->getEndLoc(), TrailingRequiresClause); | ||||||||||||
2493 | if (D->isMoveAssignmentOperator() || D->isCopyAssignmentOperator()) | ||||||||||||
2494 | Method->setIneligibleOrNotSelected(true); | ||||||||||||
2495 | } | ||||||||||||
2496 | |||||||||||||
2497 | if (D->isInlined()) | ||||||||||||
2498 | Method->setImplicitlyInline(); | ||||||||||||
2499 | |||||||||||||
2500 | if (QualifierLoc) | ||||||||||||
2501 | Method->setQualifierInfo(QualifierLoc); | ||||||||||||
2502 | |||||||||||||
2503 | if (TemplateParams) { | ||||||||||||
2504 | // Our resulting instantiation is actually a function template, since we | ||||||||||||
2505 | // are substituting only the outer template parameters. For example, given | ||||||||||||
2506 | // | ||||||||||||
2507 | // template<typename T> | ||||||||||||
2508 | // struct X { | ||||||||||||
2509 | // template<typename U> void f(T, U); | ||||||||||||
2510 | // }; | ||||||||||||
2511 | // | ||||||||||||
2512 | // X<int> x; | ||||||||||||
2513 | // | ||||||||||||
2514 | // We are instantiating the member template "f" within X<int>, which means | ||||||||||||
2515 | // substituting int for T, but leaving "f" as a member function template. | ||||||||||||
2516 | // Build the function template itself. | ||||||||||||
2517 | FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, Record, | ||||||||||||
2518 | Method->getLocation(), | ||||||||||||
2519 | Method->getDeclName(), | ||||||||||||
2520 | TemplateParams, Method); | ||||||||||||
2521 | if (isFriend) { | ||||||||||||
2522 | FunctionTemplate->setLexicalDeclContext(Owner); | ||||||||||||
2523 | FunctionTemplate->setObjectOfFriendDecl(); | ||||||||||||
2524 | } else if (D->isOutOfLine()) | ||||||||||||
2525 | FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext()); | ||||||||||||
2526 | Method->setDescribedFunctionTemplate(FunctionTemplate); | ||||||||||||
2527 | } else if (FunctionTemplate) { | ||||||||||||
2528 | // Record this function template specialization. | ||||||||||||
2529 | ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost(); | ||||||||||||
2530 | Method->setFunctionTemplateSpecialization(FunctionTemplate, | ||||||||||||
2531 | TemplateArgumentList::CreateCopy(SemaRef.Context, | ||||||||||||
2532 | Innermost), | ||||||||||||
2533 | /*InsertPos=*/nullptr); | ||||||||||||
2534 | } else if (!isFriend) { | ||||||||||||
2535 | // Record that this is an instantiation of a member function. | ||||||||||||
2536 | Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); | ||||||||||||
2537 | } | ||||||||||||
2538 | |||||||||||||
2539 | // If we are instantiating a member function defined | ||||||||||||
2540 | // out-of-line, the instantiation will have the same lexical | ||||||||||||
2541 | // context (which will be a namespace scope) as the template. | ||||||||||||
2542 | if (isFriend) { | ||||||||||||
2543 | if (NumTempParamLists) | ||||||||||||
2544 | Method->setTemplateParameterListsInfo( | ||||||||||||
2545 | SemaRef.Context, | ||||||||||||
2546 | llvm::makeArrayRef(TempParamLists.data(), NumTempParamLists)); | ||||||||||||
2547 | |||||||||||||
2548 | Method->setLexicalDeclContext(Owner); | ||||||||||||
2549 | Method->setObjectOfFriendDecl(); | ||||||||||||
2550 | } else if (D->isOutOfLine()) | ||||||||||||
2551 | Method->setLexicalDeclContext(D->getLexicalDeclContext()); | ||||||||||||
2552 | |||||||||||||
2553 | // Attach the parameters | ||||||||||||
2554 | for (unsigned P = 0; P < Params.size(); ++P) | ||||||||||||
2555 | Params[P]->setOwningFunction(Method); | ||||||||||||
2556 | Method->setParams(Params); | ||||||||||||
2557 | |||||||||||||
2558 | if (InitMethodInstantiation(Method, D)) | ||||||||||||
2559 | Method->setInvalidDecl(); | ||||||||||||
2560 | |||||||||||||
2561 | LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName, | ||||||||||||
2562 | Sema::ForExternalRedeclaration); | ||||||||||||
2563 | |||||||||||||
2564 | bool IsExplicitSpecialization = false; | ||||||||||||
2565 | |||||||||||||
2566 | // If the name of this function was written as a template-id, instantiate | ||||||||||||
2567 | // the explicit template arguments. | ||||||||||||
2568 | if (DependentFunctionTemplateSpecializationInfo *Info | ||||||||||||
2569 | = D->getDependentSpecializationInfo()) { | ||||||||||||
2570 | assert(isFriend && "non-friend has dependent specialization info?")(static_cast <bool> (isFriend && "non-friend has dependent specialization info?" ) ? void (0) : __assert_fail ("isFriend && \"non-friend has dependent specialization info?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 2570, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
2571 | |||||||||||||
2572 | // Instantiate the explicit template arguments. | ||||||||||||
2573 | TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), | ||||||||||||
2574 | Info->getRAngleLoc()); | ||||||||||||
2575 | if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, | ||||||||||||
2576 | ExplicitArgs)) | ||||||||||||
2577 | return nullptr; | ||||||||||||
2578 | |||||||||||||
2579 | // Map the candidate templates to their instantiations. | ||||||||||||
2580 | for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) { | ||||||||||||
2581 | Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(), | ||||||||||||
2582 | Info->getTemplate(I), | ||||||||||||
2583 | TemplateArgs); | ||||||||||||
2584 | if (!Temp) return nullptr; | ||||||||||||
2585 | |||||||||||||
2586 | Previous.addDecl(cast<FunctionTemplateDecl>(Temp)); | ||||||||||||
2587 | } | ||||||||||||
2588 | |||||||||||||
2589 | if (SemaRef.CheckFunctionTemplateSpecialization(Method, | ||||||||||||
2590 | &ExplicitArgs, | ||||||||||||
2591 | Previous)) | ||||||||||||
2592 | Method->setInvalidDecl(); | ||||||||||||
2593 | |||||||||||||
2594 | IsExplicitSpecialization = true; | ||||||||||||
2595 | } else if (const ASTTemplateArgumentListInfo *Info = | ||||||||||||
2596 | ClassScopeSpecializationArgs.value_or( | ||||||||||||
2597 | D->getTemplateSpecializationArgsAsWritten())) { | ||||||||||||
2598 | SemaRef.LookupQualifiedName(Previous, DC); | ||||||||||||
2599 | |||||||||||||
2600 | TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), | ||||||||||||
2601 | Info->getRAngleLoc()); | ||||||||||||
2602 | if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, | ||||||||||||
2603 | ExplicitArgs)) | ||||||||||||
2604 | return nullptr; | ||||||||||||
2605 | |||||||||||||
2606 | if (SemaRef.CheckFunctionTemplateSpecialization(Method, | ||||||||||||
2607 | &ExplicitArgs, | ||||||||||||
2608 | Previous)) | ||||||||||||
2609 | Method->setInvalidDecl(); | ||||||||||||
2610 | |||||||||||||
2611 | IsExplicitSpecialization = true; | ||||||||||||
2612 | } else if (ClassScopeSpecializationArgs) { | ||||||||||||
2613 | // Class-scope explicit specialization written without explicit template | ||||||||||||
2614 | // arguments. | ||||||||||||
2615 | SemaRef.LookupQualifiedName(Previous, DC); | ||||||||||||
2616 | if (SemaRef.CheckFunctionTemplateSpecialization(Method, nullptr, Previous)) | ||||||||||||
2617 | Method->setInvalidDecl(); | ||||||||||||
2618 | |||||||||||||
2619 | IsExplicitSpecialization = true; | ||||||||||||
2620 | } else if (!FunctionTemplate || TemplateParams || isFriend) { | ||||||||||||
2621 | SemaRef.LookupQualifiedName(Previous, Record); | ||||||||||||
2622 | |||||||||||||
2623 | // In C++, the previous declaration we find might be a tag type | ||||||||||||
2624 | // (class or enum). In this case, the new declaration will hide the | ||||||||||||
2625 | // tag type. Note that this does does not apply if we're declaring a | ||||||||||||
2626 | // typedef (C++ [dcl.typedef]p4). | ||||||||||||
2627 | if (Previous.isSingleTagDecl()) | ||||||||||||
2628 | Previous.clear(); | ||||||||||||
2629 | } | ||||||||||||
2630 | |||||||||||||
2631 | SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous, | ||||||||||||
2632 | IsExplicitSpecialization, | ||||||||||||
2633 | Method->isThisDeclarationADefinition()); | ||||||||||||
2634 | |||||||||||||
2635 | if (D->isPure()) | ||||||||||||
2636 | SemaRef.CheckPureMethod(Method, SourceRange()); | ||||||||||||
2637 | |||||||||||||
2638 | // Propagate access. For a non-friend declaration, the access is | ||||||||||||
2639 | // whatever we're propagating from. For a friend, it should be the | ||||||||||||
2640 | // previous declaration we just found. | ||||||||||||
2641 | if (isFriend && Method->getPreviousDecl()) | ||||||||||||
2642 | Method->setAccess(Method->getPreviousDecl()->getAccess()); | ||||||||||||
2643 | else | ||||||||||||
2644 | Method->setAccess(D->getAccess()); | ||||||||||||
2645 | if (FunctionTemplate) | ||||||||||||
2646 | FunctionTemplate->setAccess(Method->getAccess()); | ||||||||||||
2647 | |||||||||||||
2648 | SemaRef.CheckOverrideControl(Method); | ||||||||||||
2649 | |||||||||||||
2650 | // If a function is defined as defaulted or deleted, mark it as such now. | ||||||||||||
2651 | if (D->isExplicitlyDefaulted()) { | ||||||||||||
2652 | if (SubstDefaultedFunction(Method, D)) | ||||||||||||
2653 | return nullptr; | ||||||||||||
2654 | } | ||||||||||||
2655 | if (D->isDeletedAsWritten()) | ||||||||||||
2656 | SemaRef.SetDeclDeleted(Method, Method->getLocation()); | ||||||||||||
2657 | |||||||||||||
2658 | // If this is an explicit specialization, mark the implicitly-instantiated | ||||||||||||
2659 | // template specialization as being an explicit specialization too. | ||||||||||||
2660 | // FIXME: Is this necessary? | ||||||||||||
2661 | if (IsExplicitSpecialization && !isFriend) | ||||||||||||
2662 | SemaRef.CompleteMemberSpecialization(Method, Previous); | ||||||||||||
2663 | |||||||||||||
2664 | // If there's a function template, let our caller handle it. | ||||||||||||
2665 | if (FunctionTemplate) { | ||||||||||||
2666 | // do nothing | ||||||||||||
2667 | |||||||||||||
2668 | // Don't hide a (potentially) valid declaration with an invalid one. | ||||||||||||
2669 | } else if (Method->isInvalidDecl() && !Previous.empty()) { | ||||||||||||
2670 | // do nothing | ||||||||||||
2671 | |||||||||||||
2672 | // Otherwise, check access to friends and make them visible. | ||||||||||||
2673 | } else if (isFriend) { | ||||||||||||
2674 | // We only need to re-check access for methods which we didn't | ||||||||||||
2675 | // manage to match during parsing. | ||||||||||||
2676 | if (!D->getPreviousDecl()) | ||||||||||||
2677 | SemaRef.CheckFriendAccess(Method); | ||||||||||||
2678 | |||||||||||||
2679 | Record->makeDeclVisibleInContext(Method); | ||||||||||||
2680 | |||||||||||||
2681 | // Otherwise, add the declaration. We don't need to do this for | ||||||||||||
2682 | // class-scope specializations because we'll have matched them with | ||||||||||||
2683 | // the appropriate template. | ||||||||||||
2684 | } else { | ||||||||||||
2685 | Owner->addDecl(Method); | ||||||||||||
2686 | } | ||||||||||||
2687 | |||||||||||||
2688 | // PR17480: Honor the used attribute to instantiate member function | ||||||||||||
2689 | // definitions | ||||||||||||
2690 | if (Method->hasAttr<UsedAttr>()) { | ||||||||||||
2691 | if (const auto *A = dyn_cast<CXXRecordDecl>(Owner)) { | ||||||||||||
2692 | SourceLocation Loc; | ||||||||||||
2693 | if (const MemberSpecializationInfo *MSInfo = | ||||||||||||
2694 | A->getMemberSpecializationInfo()) | ||||||||||||
2695 | Loc = MSInfo->getPointOfInstantiation(); | ||||||||||||
2696 | else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(A)) | ||||||||||||
2697 | Loc = Spec->getPointOfInstantiation(); | ||||||||||||
2698 | SemaRef.MarkFunctionReferenced(Loc, Method); | ||||||||||||
2699 | } | ||||||||||||
2700 | } | ||||||||||||
2701 | |||||||||||||
2702 | return Method; | ||||||||||||
2703 | } | ||||||||||||
2704 | |||||||||||||
2705 | Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) { | ||||||||||||
2706 | return VisitCXXMethodDecl(D); | ||||||||||||
2707 | } | ||||||||||||
2708 | |||||||||||||
2709 | Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) { | ||||||||||||
2710 | return VisitCXXMethodDecl(D); | ||||||||||||
2711 | } | ||||||||||||
2712 | |||||||||||||
2713 | Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) { | ||||||||||||
2714 | return VisitCXXMethodDecl(D); | ||||||||||||
2715 | } | ||||||||||||
2716 | |||||||||||||
2717 | Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { | ||||||||||||
2718 | return SemaRef.SubstParmVarDecl(D, TemplateArgs, /*indexAdjustment*/ 0, None, | ||||||||||||
2719 | /*ExpectParameterPack=*/ false); | ||||||||||||
2720 | } | ||||||||||||
2721 | |||||||||||||
2722 | Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( | ||||||||||||
2723 | TemplateTypeParmDecl *D) { | ||||||||||||
2724 | assert(D->getTypeForDecl()->isTemplateTypeParmType())(static_cast <bool> (D->getTypeForDecl()->isTemplateTypeParmType ()) ? void (0) : __assert_fail ("D->getTypeForDecl()->isTemplateTypeParmType()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 2724, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
2725 | |||||||||||||
2726 | Optional<unsigned> NumExpanded; | ||||||||||||
2727 | |||||||||||||
2728 | if (const TypeConstraint *TC = D->getTypeConstraint()) { | ||||||||||||
2729 | if (D->isPackExpansion() && !D->isExpandedParameterPack()) { | ||||||||||||
2730 | assert(TC->getTemplateArgsAsWritten() &&(static_cast <bool> (TC->getTemplateArgsAsWritten() && "type parameter can only be an expansion when explicit arguments " "are specified") ? void (0) : __assert_fail ("TC->getTemplateArgsAsWritten() && \"type parameter can only be an expansion when explicit arguments \" \"are specified\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 2732, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
2731 | "type parameter can only be an expansion when explicit arguments "(static_cast <bool> (TC->getTemplateArgsAsWritten() && "type parameter can only be an expansion when explicit arguments " "are specified") ? void (0) : __assert_fail ("TC->getTemplateArgsAsWritten() && \"type parameter can only be an expansion when explicit arguments \" \"are specified\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 2732, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
2732 | "are specified")(static_cast <bool> (TC->getTemplateArgsAsWritten() && "type parameter can only be an expansion when explicit arguments " "are specified") ? void (0) : __assert_fail ("TC->getTemplateArgsAsWritten() && \"type parameter can only be an expansion when explicit arguments \" \"are specified\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 2732, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
2733 | // The template type parameter pack's type is a pack expansion of types. | ||||||||||||
2734 | // Determine whether we need to expand this parameter pack into separate | ||||||||||||
2735 | // types. | ||||||||||||
2736 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
2737 | for (auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments()) | ||||||||||||
2738 | SemaRef.collectUnexpandedParameterPacks(ArgLoc, Unexpanded); | ||||||||||||
2739 | |||||||||||||
2740 | // Determine whether the set of unexpanded parameter packs can and should | ||||||||||||
2741 | // be expanded. | ||||||||||||
2742 | bool Expand = true; | ||||||||||||
2743 | bool RetainExpansion = false; | ||||||||||||
2744 | if (SemaRef.CheckParameterPacksForExpansion( | ||||||||||||
2745 | cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint()) | ||||||||||||
2746 | ->getEllipsisLoc(), | ||||||||||||
2747 | SourceRange(TC->getConceptNameLoc(), | ||||||||||||
2748 | TC->hasExplicitTemplateArgs() ? | ||||||||||||
2749 | TC->getTemplateArgsAsWritten()->getRAngleLoc() : | ||||||||||||
2750 | TC->getConceptNameInfo().getEndLoc()), | ||||||||||||
2751 | Unexpanded, TemplateArgs, Expand, RetainExpansion, NumExpanded)) | ||||||||||||
2752 | return nullptr; | ||||||||||||
2753 | } | ||||||||||||
2754 | } | ||||||||||||
2755 | |||||||||||||
2756 | TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create( | ||||||||||||
2757 | SemaRef.Context, Owner, D->getBeginLoc(), D->getLocation(), | ||||||||||||
2758 | D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), D->getIndex(), | ||||||||||||
2759 | D->getIdentifier(), D->wasDeclaredWithTypename(), D->isParameterPack(), | ||||||||||||
2760 | D->hasTypeConstraint(), NumExpanded); | ||||||||||||
2761 | |||||||||||||
2762 | Inst->setAccess(AS_public); | ||||||||||||
2763 | Inst->setImplicit(D->isImplicit()); | ||||||||||||
2764 | if (auto *TC = D->getTypeConstraint()) { | ||||||||||||
2765 | if (!D->isImplicit()) { | ||||||||||||
2766 | // Invented template parameter type constraints will be instantiated | ||||||||||||
2767 | // with the corresponding auto-typed parameter as it might reference | ||||||||||||
2768 | // other parameters. | ||||||||||||
2769 | if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs, | ||||||||||||
2770 | EvaluateConstraints)) | ||||||||||||
2771 | return nullptr; | ||||||||||||
2772 | } | ||||||||||||
2773 | } | ||||||||||||
2774 | if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { | ||||||||||||
2775 | TypeSourceInfo *InstantiatedDefaultArg = | ||||||||||||
2776 | SemaRef.SubstType(D->getDefaultArgumentInfo(), TemplateArgs, | ||||||||||||
2777 | D->getDefaultArgumentLoc(), D->getDeclName()); | ||||||||||||
2778 | if (InstantiatedDefaultArg) | ||||||||||||
2779 | Inst->setDefaultArgument(InstantiatedDefaultArg); | ||||||||||||
2780 | } | ||||||||||||
2781 | |||||||||||||
2782 | // Introduce this template parameter's instantiation into the instantiation | ||||||||||||
2783 | // scope. | ||||||||||||
2784 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Inst); | ||||||||||||
2785 | |||||||||||||
2786 | return Inst; | ||||||||||||
2787 | } | ||||||||||||
2788 | |||||||||||||
2789 | Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( | ||||||||||||
2790 | NonTypeTemplateParmDecl *D) { | ||||||||||||
2791 | // Substitute into the type of the non-type template parameter. | ||||||||||||
2792 | TypeLoc TL = D->getTypeSourceInfo()->getTypeLoc(); | ||||||||||||
2793 | SmallVector<TypeSourceInfo *, 4> ExpandedParameterPackTypesAsWritten; | ||||||||||||
2794 | SmallVector<QualType, 4> ExpandedParameterPackTypes; | ||||||||||||
2795 | bool IsExpandedParameterPack = false; | ||||||||||||
2796 | TypeSourceInfo *DI; | ||||||||||||
2797 | QualType T; | ||||||||||||
2798 | bool Invalid = false; | ||||||||||||
2799 | |||||||||||||
2800 | if (D->isExpandedParameterPack()) { | ||||||||||||
2801 | // The non-type template parameter pack is an already-expanded pack | ||||||||||||
2802 | // expansion of types. Substitute into each of the expanded types. | ||||||||||||
2803 | ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes()); | ||||||||||||
2804 | ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes()); | ||||||||||||
2805 | for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { | ||||||||||||
2806 | TypeSourceInfo *NewDI = | ||||||||||||
2807 | SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), TemplateArgs, | ||||||||||||
2808 | D->getLocation(), D->getDeclName()); | ||||||||||||
2809 | if (!NewDI) | ||||||||||||
2810 | return nullptr; | ||||||||||||
2811 | |||||||||||||
2812 | QualType NewT = | ||||||||||||
2813 | SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation()); | ||||||||||||
2814 | if (NewT.isNull()) | ||||||||||||
2815 | return nullptr; | ||||||||||||
2816 | |||||||||||||
2817 | ExpandedParameterPackTypesAsWritten.push_back(NewDI); | ||||||||||||
2818 | ExpandedParameterPackTypes.push_back(NewT); | ||||||||||||
2819 | } | ||||||||||||
2820 | |||||||||||||
2821 | IsExpandedParameterPack = true; | ||||||||||||
2822 | DI = D->getTypeSourceInfo(); | ||||||||||||
2823 | T = DI->getType(); | ||||||||||||
2824 | } else if (D->isPackExpansion()) { | ||||||||||||
2825 | // The non-type template parameter pack's type is a pack expansion of types. | ||||||||||||
2826 | // Determine whether we need to expand this parameter pack into separate | ||||||||||||
2827 | // types. | ||||||||||||
2828 | PackExpansionTypeLoc Expansion = TL.castAs<PackExpansionTypeLoc>(); | ||||||||||||
2829 | TypeLoc Pattern = Expansion.getPatternLoc(); | ||||||||||||
2830 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
2831 | SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); | ||||||||||||
2832 | |||||||||||||
2833 | // Determine whether the set of unexpanded parameter packs can and should | ||||||||||||
2834 | // be expanded. | ||||||||||||
2835 | bool Expand = true; | ||||||||||||
2836 | bool RetainExpansion = false; | ||||||||||||
2837 | Optional<unsigned> OrigNumExpansions | ||||||||||||
2838 | = Expansion.getTypePtr()->getNumExpansions(); | ||||||||||||
2839 | Optional<unsigned> NumExpansions = OrigNumExpansions; | ||||||||||||
2840 | if (SemaRef.CheckParameterPacksForExpansion(Expansion.getEllipsisLoc(), | ||||||||||||
2841 | Pattern.getSourceRange(), | ||||||||||||
2842 | Unexpanded, | ||||||||||||
2843 | TemplateArgs, | ||||||||||||
2844 | Expand, RetainExpansion, | ||||||||||||
2845 | NumExpansions)) | ||||||||||||
2846 | return nullptr; | ||||||||||||
2847 | |||||||||||||
2848 | if (Expand) { | ||||||||||||
2849 | for (unsigned I = 0; I != *NumExpansions; ++I) { | ||||||||||||
2850 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); | ||||||||||||
2851 | TypeSourceInfo *NewDI = SemaRef.SubstType(Pattern, TemplateArgs, | ||||||||||||
2852 | D->getLocation(), | ||||||||||||
2853 | D->getDeclName()); | ||||||||||||
2854 | if (!NewDI) | ||||||||||||
2855 | return nullptr; | ||||||||||||
2856 | |||||||||||||
2857 | QualType NewT = | ||||||||||||
2858 | SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation()); | ||||||||||||
2859 | if (NewT.isNull()) | ||||||||||||
2860 | return nullptr; | ||||||||||||
2861 | |||||||||||||
2862 | ExpandedParameterPackTypesAsWritten.push_back(NewDI); | ||||||||||||
2863 | ExpandedParameterPackTypes.push_back(NewT); | ||||||||||||
2864 | } | ||||||||||||
2865 | |||||||||||||
2866 | // Note that we have an expanded parameter pack. The "type" of this | ||||||||||||
2867 | // expanded parameter pack is the original expansion type, but callers | ||||||||||||
2868 | // will end up using the expanded parameter pack types for type-checking. | ||||||||||||
2869 | IsExpandedParameterPack = true; | ||||||||||||
2870 | DI = D->getTypeSourceInfo(); | ||||||||||||
2871 | T = DI->getType(); | ||||||||||||
2872 | } else { | ||||||||||||
2873 | // We cannot fully expand the pack expansion now, so substitute into the | ||||||||||||
2874 | // pattern and create a new pack expansion type. | ||||||||||||
2875 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); | ||||||||||||
2876 | TypeSourceInfo *NewPattern = SemaRef.SubstType(Pattern, TemplateArgs, | ||||||||||||
2877 | D->getLocation(), | ||||||||||||
2878 | D->getDeclName()); | ||||||||||||
2879 | if (!NewPattern) | ||||||||||||
2880 | return nullptr; | ||||||||||||
2881 | |||||||||||||
2882 | SemaRef.CheckNonTypeTemplateParameterType(NewPattern, D->getLocation()); | ||||||||||||
2883 | DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(), | ||||||||||||
2884 | NumExpansions); | ||||||||||||
2885 | if (!DI) | ||||||||||||
2886 | return nullptr; | ||||||||||||
2887 | |||||||||||||
2888 | T = DI->getType(); | ||||||||||||
2889 | } | ||||||||||||
2890 | } else { | ||||||||||||
2891 | // Simple case: substitution into a parameter that is not a parameter pack. | ||||||||||||
2892 | DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs, | ||||||||||||
2893 | D->getLocation(), D->getDeclName()); | ||||||||||||
2894 | if (!DI) | ||||||||||||
2895 | return nullptr; | ||||||||||||
2896 | |||||||||||||
2897 | // Check that this type is acceptable for a non-type template parameter. | ||||||||||||
2898 | T = SemaRef.CheckNonTypeTemplateParameterType(DI, D->getLocation()); | ||||||||||||
2899 | if (T.isNull()) { | ||||||||||||
2900 | T = SemaRef.Context.IntTy; | ||||||||||||
2901 | Invalid = true; | ||||||||||||
2902 | } | ||||||||||||
2903 | } | ||||||||||||
2904 | |||||||||||||
2905 | NonTypeTemplateParmDecl *Param; | ||||||||||||
2906 | if (IsExpandedParameterPack) | ||||||||||||
2907 | Param = NonTypeTemplateParmDecl::Create( | ||||||||||||
2908 | SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), | ||||||||||||
2909 | D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), | ||||||||||||
2910 | D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes, | ||||||||||||
2911 | ExpandedParameterPackTypesAsWritten); | ||||||||||||
2912 | else | ||||||||||||
2913 | Param = NonTypeTemplateParmDecl::Create( | ||||||||||||
2914 | SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), | ||||||||||||
2915 | D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), | ||||||||||||
2916 | D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI); | ||||||||||||
2917 | |||||||||||||
2918 | if (AutoTypeLoc AutoLoc = DI->getTypeLoc().getContainedAutoTypeLoc()) | ||||||||||||
2919 | if (AutoLoc.isConstrained()) | ||||||||||||
2920 | if (SemaRef.AttachTypeConstraint( | ||||||||||||
2921 | AutoLoc, Param, | ||||||||||||
2922 | IsExpandedParameterPack | ||||||||||||
2923 | ? DI->getTypeLoc().getAs<PackExpansionTypeLoc>() | ||||||||||||
2924 | .getEllipsisLoc() | ||||||||||||
2925 | : SourceLocation())) | ||||||||||||
2926 | Invalid = true; | ||||||||||||
2927 | |||||||||||||
2928 | Param->setAccess(AS_public); | ||||||||||||
2929 | Param->setImplicit(D->isImplicit()); | ||||||||||||
2930 | if (Invalid) | ||||||||||||
2931 | Param->setInvalidDecl(); | ||||||||||||
2932 | |||||||||||||
2933 | if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { | ||||||||||||
2934 | EnterExpressionEvaluationContext ConstantEvaluated( | ||||||||||||
2935 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | ||||||||||||
2936 | ExprResult Value = SemaRef.SubstExpr(D->getDefaultArgument(), TemplateArgs); | ||||||||||||
2937 | if (!Value.isInvalid()) | ||||||||||||
2938 | Param->setDefaultArgument(Value.get()); | ||||||||||||
2939 | } | ||||||||||||
2940 | |||||||||||||
2941 | // Introduce this template parameter's instantiation into the instantiation | ||||||||||||
2942 | // scope. | ||||||||||||
2943 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); | ||||||||||||
2944 | return Param; | ||||||||||||
2945 | } | ||||||||||||
2946 | |||||||||||||
2947 | static void collectUnexpandedParameterPacks( | ||||||||||||
2948 | Sema &S, | ||||||||||||
2949 | TemplateParameterList *Params, | ||||||||||||
2950 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||||||
2951 | for (const auto &P : *Params) { | ||||||||||||
2952 | if (P->isTemplateParameterPack()) | ||||||||||||
2953 | continue; | ||||||||||||
2954 | if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) | ||||||||||||
2955 | S.collectUnexpandedParameterPacks(NTTP->getTypeSourceInfo()->getTypeLoc(), | ||||||||||||
2956 | Unexpanded); | ||||||||||||
2957 | if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) | ||||||||||||
2958 | collectUnexpandedParameterPacks(S, TTP->getTemplateParameters(), | ||||||||||||
2959 | Unexpanded); | ||||||||||||
2960 | } | ||||||||||||
2961 | } | ||||||||||||
2962 | |||||||||||||
2963 | Decl * | ||||||||||||
2964 | TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( | ||||||||||||
2965 | TemplateTemplateParmDecl *D) { | ||||||||||||
2966 | // Instantiate the template parameter list of the template template parameter. | ||||||||||||
2967 | TemplateParameterList *TempParams = D->getTemplateParameters(); | ||||||||||||
2968 | TemplateParameterList *InstParams; | ||||||||||||
2969 | SmallVector<TemplateParameterList*, 8> ExpandedParams; | ||||||||||||
2970 | |||||||||||||
2971 | bool IsExpandedParameterPack = false; | ||||||||||||
2972 | |||||||||||||
2973 | if (D->isExpandedParameterPack()) { | ||||||||||||
2974 | // The template template parameter pack is an already-expanded pack | ||||||||||||
2975 | // expansion of template parameters. Substitute into each of the expanded | ||||||||||||
2976 | // parameters. | ||||||||||||
2977 | ExpandedParams.reserve(D->getNumExpansionTemplateParameters()); | ||||||||||||
2978 | for (unsigned I = 0, N = D->getNumExpansionTemplateParameters(); | ||||||||||||
2979 | I != N; ++I) { | ||||||||||||
2980 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
2981 | TemplateParameterList *Expansion = | ||||||||||||
2982 | SubstTemplateParams(D->getExpansionTemplateParameters(I)); | ||||||||||||
2983 | if (!Expansion) | ||||||||||||
2984 | return nullptr; | ||||||||||||
2985 | ExpandedParams.push_back(Expansion); | ||||||||||||
2986 | } | ||||||||||||
2987 | |||||||||||||
2988 | IsExpandedParameterPack = true; | ||||||||||||
2989 | InstParams = TempParams; | ||||||||||||
2990 | } else if (D->isPackExpansion()) { | ||||||||||||
2991 | // The template template parameter pack expands to a pack of template | ||||||||||||
2992 | // template parameters. Determine whether we need to expand this parameter | ||||||||||||
2993 | // pack into separate parameters. | ||||||||||||
2994 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
2995 | collectUnexpandedParameterPacks(SemaRef, D->getTemplateParameters(), | ||||||||||||
2996 | Unexpanded); | ||||||||||||
2997 | |||||||||||||
2998 | // Determine whether the set of unexpanded parameter packs can and should | ||||||||||||
2999 | // be expanded. | ||||||||||||
3000 | bool Expand = true; | ||||||||||||
3001 | bool RetainExpansion = false; | ||||||||||||
3002 | Optional<unsigned> NumExpansions; | ||||||||||||
3003 | if (SemaRef.CheckParameterPacksForExpansion(D->getLocation(), | ||||||||||||
3004 | TempParams->getSourceRange(), | ||||||||||||
3005 | Unexpanded, | ||||||||||||
3006 | TemplateArgs, | ||||||||||||
3007 | Expand, RetainExpansion, | ||||||||||||
3008 | NumExpansions)) | ||||||||||||
3009 | return nullptr; | ||||||||||||
3010 | |||||||||||||
3011 | if (Expand) { | ||||||||||||
3012 | for (unsigned I = 0; I != *NumExpansions; ++I) { | ||||||||||||
3013 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); | ||||||||||||
3014 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
3015 | TemplateParameterList *Expansion = SubstTemplateParams(TempParams); | ||||||||||||
3016 | if (!Expansion) | ||||||||||||
3017 | return nullptr; | ||||||||||||
3018 | ExpandedParams.push_back(Expansion); | ||||||||||||
3019 | } | ||||||||||||
3020 | |||||||||||||
3021 | // Note that we have an expanded parameter pack. The "type" of this | ||||||||||||
3022 | // expanded parameter pack is the original expansion type, but callers | ||||||||||||
3023 | // will end up using the expanded parameter pack types for type-checking. | ||||||||||||
3024 | IsExpandedParameterPack = true; | ||||||||||||
3025 | InstParams = TempParams; | ||||||||||||
3026 | } else { | ||||||||||||
3027 | // We cannot fully expand the pack expansion now, so just substitute | ||||||||||||
3028 | // into the pattern. | ||||||||||||
3029 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); | ||||||||||||
3030 | |||||||||||||
3031 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
3032 | InstParams = SubstTemplateParams(TempParams); | ||||||||||||
3033 | if (!InstParams) | ||||||||||||
3034 | return nullptr; | ||||||||||||
3035 | } | ||||||||||||
3036 | } else { | ||||||||||||
3037 | // Perform the actual substitution of template parameters within a new, | ||||||||||||
3038 | // local instantiation scope. | ||||||||||||
3039 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
3040 | InstParams = SubstTemplateParams(TempParams); | ||||||||||||
3041 | if (!InstParams) | ||||||||||||
3042 | return nullptr; | ||||||||||||
3043 | } | ||||||||||||
3044 | |||||||||||||
3045 | // Build the template template parameter. | ||||||||||||
3046 | TemplateTemplateParmDecl *Param; | ||||||||||||
3047 | if (IsExpandedParameterPack) | ||||||||||||
3048 | Param = TemplateTemplateParmDecl::Create( | ||||||||||||
3049 | SemaRef.Context, Owner, D->getLocation(), | ||||||||||||
3050 | D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), | ||||||||||||
3051 | D->getPosition(), D->getIdentifier(), InstParams, ExpandedParams); | ||||||||||||
3052 | else | ||||||||||||
3053 | Param = TemplateTemplateParmDecl::Create( | ||||||||||||
3054 | SemaRef.Context, Owner, D->getLocation(), | ||||||||||||
3055 | D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), | ||||||||||||
3056 | D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams); | ||||||||||||
3057 | if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { | ||||||||||||
3058 | NestedNameSpecifierLoc QualifierLoc = | ||||||||||||
3059 | D->getDefaultArgument().getTemplateQualifierLoc(); | ||||||||||||
3060 | QualifierLoc = | ||||||||||||
3061 | SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs); | ||||||||||||
3062 | TemplateName TName = SemaRef.SubstTemplateName( | ||||||||||||
3063 | QualifierLoc, D->getDefaultArgument().getArgument().getAsTemplate(), | ||||||||||||
3064 | D->getDefaultArgument().getTemplateNameLoc(), TemplateArgs); | ||||||||||||
3065 | if (!TName.isNull()) | ||||||||||||
3066 | Param->setDefaultArgument( | ||||||||||||
3067 | SemaRef.Context, | ||||||||||||
3068 | TemplateArgumentLoc(SemaRef.Context, TemplateArgument(TName), | ||||||||||||
3069 | D->getDefaultArgument().getTemplateQualifierLoc(), | ||||||||||||
3070 | D->getDefaultArgument().getTemplateNameLoc())); | ||||||||||||
3071 | } | ||||||||||||
3072 | Param->setAccess(AS_public); | ||||||||||||
3073 | Param->setImplicit(D->isImplicit()); | ||||||||||||
3074 | |||||||||||||
3075 | // Introduce this template parameter's instantiation into the instantiation | ||||||||||||
3076 | // scope. | ||||||||||||
3077 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); | ||||||||||||
3078 | |||||||||||||
3079 | return Param; | ||||||||||||
3080 | } | ||||||||||||
3081 | |||||||||||||
3082 | Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { | ||||||||||||
3083 | // Using directives are never dependent (and never contain any types or | ||||||||||||
3084 | // expressions), so they require no explicit instantiation work. | ||||||||||||
3085 | |||||||||||||
3086 | UsingDirectiveDecl *Inst | ||||||||||||
3087 | = UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(), | ||||||||||||
3088 | D->getNamespaceKeyLocation(), | ||||||||||||
3089 | D->getQualifierLoc(), | ||||||||||||
3090 | D->getIdentLocation(), | ||||||||||||
3091 | D->getNominatedNamespace(), | ||||||||||||
3092 | D->getCommonAncestor()); | ||||||||||||
3093 | |||||||||||||
3094 | // Add the using directive to its declaration context | ||||||||||||
3095 | // only if this is not a function or method. | ||||||||||||
3096 | if (!Owner->isFunctionOrMethod()) | ||||||||||||
3097 | Owner->addDecl(Inst); | ||||||||||||
3098 | |||||||||||||
3099 | return Inst; | ||||||||||||
3100 | } | ||||||||||||
3101 | |||||||||||||
3102 | Decl *TemplateDeclInstantiator::VisitBaseUsingDecls(BaseUsingDecl *D, | ||||||||||||
3103 | BaseUsingDecl *Inst, | ||||||||||||
3104 | LookupResult *Lookup) { | ||||||||||||
3105 | |||||||||||||
3106 | bool isFunctionScope = Owner->isFunctionOrMethod(); | ||||||||||||
3107 | |||||||||||||
3108 | for (auto *Shadow : D->shadows()) { | ||||||||||||
3109 | // FIXME: UsingShadowDecl doesn't preserve its immediate target, so | ||||||||||||
3110 | // reconstruct it in the case where it matters. Hm, can we extract it from | ||||||||||||
3111 | // the DeclSpec when parsing and save it in the UsingDecl itself? | ||||||||||||
3112 | NamedDecl *OldTarget = Shadow->getTargetDecl(); | ||||||||||||
3113 | if (auto *CUSD = dyn_cast<ConstructorUsingShadowDecl>(Shadow)) | ||||||||||||
3114 | if (auto *BaseShadow = CUSD->getNominatedBaseClassShadowDecl()) | ||||||||||||
3115 | OldTarget = BaseShadow; | ||||||||||||
3116 | |||||||||||||
3117 | NamedDecl *InstTarget = nullptr; | ||||||||||||
3118 | if (auto *EmptyD = | ||||||||||||
3119 | dyn_cast<UnresolvedUsingIfExistsDecl>(Shadow->getTargetDecl())) { | ||||||||||||
3120 | InstTarget = UnresolvedUsingIfExistsDecl::Create( | ||||||||||||
3121 | SemaRef.Context, Owner, EmptyD->getLocation(), EmptyD->getDeclName()); | ||||||||||||
3122 | } else { | ||||||||||||
3123 | InstTarget = cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl( | ||||||||||||
3124 | Shadow->getLocation(), OldTarget, TemplateArgs)); | ||||||||||||
3125 | } | ||||||||||||
3126 | if (!InstTarget) | ||||||||||||
3127 | return nullptr; | ||||||||||||
3128 | |||||||||||||
3129 | UsingShadowDecl *PrevDecl = nullptr; | ||||||||||||
3130 | if (Lookup && | ||||||||||||
3131 | SemaRef.CheckUsingShadowDecl(Inst, InstTarget, *Lookup, PrevDecl)) | ||||||||||||
3132 | continue; | ||||||||||||
3133 | |||||||||||||
3134 | if (UsingShadowDecl *OldPrev = getPreviousDeclForInstantiation(Shadow)) | ||||||||||||
3135 | PrevDecl = cast_or_null<UsingShadowDecl>(SemaRef.FindInstantiatedDecl( | ||||||||||||
3136 | Shadow->getLocation(), OldPrev, TemplateArgs)); | ||||||||||||
3137 | |||||||||||||
3138 | UsingShadowDecl *InstShadow = SemaRef.BuildUsingShadowDecl( | ||||||||||||
3139 | /*Scope*/ nullptr, Inst, InstTarget, PrevDecl); | ||||||||||||
3140 | SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow); | ||||||||||||
3141 | |||||||||||||
3142 | if (isFunctionScope) | ||||||||||||
3143 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(Shadow, InstShadow); | ||||||||||||
3144 | } | ||||||||||||
3145 | |||||||||||||
3146 | return Inst; | ||||||||||||
3147 | } | ||||||||||||
3148 | |||||||||||||
3149 | Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { | ||||||||||||
3150 | |||||||||||||
3151 | // The nested name specifier may be dependent, for example | ||||||||||||
3152 | // template <typename T> struct t { | ||||||||||||
3153 | // struct s1 { T f1(); }; | ||||||||||||
3154 | // struct s2 : s1 { using s1::f1; }; | ||||||||||||
3155 | // }; | ||||||||||||
3156 | // template struct t<int>; | ||||||||||||
3157 | // Here, in using s1::f1, s1 refers to t<T>::s1; | ||||||||||||
3158 | // we need to substitute for t<int>::s1. | ||||||||||||
3159 | NestedNameSpecifierLoc QualifierLoc | ||||||||||||
3160 | = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), | ||||||||||||
3161 | TemplateArgs); | ||||||||||||
3162 | if (!QualifierLoc) | ||||||||||||
3163 | return nullptr; | ||||||||||||
3164 | |||||||||||||
3165 | // For an inheriting constructor declaration, the name of the using | ||||||||||||
3166 | // declaration is the name of a constructor in this class, not in the | ||||||||||||
3167 | // base class. | ||||||||||||
3168 | DeclarationNameInfo NameInfo = D->getNameInfo(); | ||||||||||||
3169 | if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) | ||||||||||||
3170 | if (auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.CurContext)) | ||||||||||||
3171 | NameInfo.setName(SemaRef.Context.DeclarationNames.getCXXConstructorName( | ||||||||||||
3172 | SemaRef.Context.getCanonicalType(SemaRef.Context.getRecordType(RD)))); | ||||||||||||
3173 | |||||||||||||
3174 | // We only need to do redeclaration lookups if we're in a class scope (in | ||||||||||||
3175 | // fact, it's not really even possible in non-class scopes). | ||||||||||||
3176 | bool CheckRedeclaration = Owner->isRecord(); | ||||||||||||
3177 | LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName, | ||||||||||||
3178 | Sema::ForVisibleRedeclaration); | ||||||||||||
3179 | |||||||||||||
3180 | UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner, | ||||||||||||
3181 | D->getUsingLoc(), | ||||||||||||
3182 | QualifierLoc, | ||||||||||||
3183 | NameInfo, | ||||||||||||
3184 | D->hasTypename()); | ||||||||||||
3185 | |||||||||||||
3186 | CXXScopeSpec SS; | ||||||||||||
3187 | SS.Adopt(QualifierLoc); | ||||||||||||
3188 | if (CheckRedeclaration) { | ||||||||||||
3189 | Prev.setHideTags(false); | ||||||||||||
3190 | SemaRef.LookupQualifiedName(Prev, Owner); | ||||||||||||
3191 | |||||||||||||
3192 | // Check for invalid redeclarations. | ||||||||||||
3193 | if (SemaRef.CheckUsingDeclRedeclaration(D->getUsingLoc(), | ||||||||||||
3194 | D->hasTypename(), SS, | ||||||||||||
3195 | D->getLocation(), Prev)) | ||||||||||||
3196 | NewUD->setInvalidDecl(); | ||||||||||||
3197 | } | ||||||||||||
3198 | |||||||||||||
3199 | if (!NewUD->isInvalidDecl() && | ||||||||||||
3200 | SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), D->hasTypename(), SS, | ||||||||||||
3201 | NameInfo, D->getLocation(), nullptr, D)) | ||||||||||||
3202 | NewUD->setInvalidDecl(); | ||||||||||||
3203 | |||||||||||||
3204 | SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D); | ||||||||||||
3205 | NewUD->setAccess(D->getAccess()); | ||||||||||||
3206 | Owner->addDecl(NewUD); | ||||||||||||
3207 | |||||||||||||
3208 | // Don't process the shadow decls for an invalid decl. | ||||||||||||
3209 | if (NewUD->isInvalidDecl()) | ||||||||||||
3210 | return NewUD; | ||||||||||||
3211 | |||||||||||||
3212 | // If the using scope was dependent, or we had dependent bases, we need to | ||||||||||||
3213 | // recheck the inheritance | ||||||||||||
3214 | if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) | ||||||||||||
3215 | SemaRef.CheckInheritingConstructorUsingDecl(NewUD); | ||||||||||||
3216 | |||||||||||||
3217 | return VisitBaseUsingDecls(D, NewUD, CheckRedeclaration ? &Prev : nullptr); | ||||||||||||
3218 | } | ||||||||||||
3219 | |||||||||||||
3220 | Decl *TemplateDeclInstantiator::VisitUsingEnumDecl(UsingEnumDecl *D) { | ||||||||||||
3221 | // Cannot be a dependent type, but still could be an instantiation | ||||||||||||
3222 | EnumDecl *EnumD = cast_or_null<EnumDecl>(SemaRef.FindInstantiatedDecl( | ||||||||||||
3223 | D->getLocation(), D->getEnumDecl(), TemplateArgs)); | ||||||||||||
3224 | |||||||||||||
3225 | if (SemaRef.RequireCompleteEnumDecl(EnumD, EnumD->getLocation())) | ||||||||||||
3226 | return nullptr; | ||||||||||||
3227 | |||||||||||||
3228 | UsingEnumDecl *NewUD = | ||||||||||||
3229 | UsingEnumDecl::Create(SemaRef.Context, Owner, D->getUsingLoc(), | ||||||||||||
3230 | D->getEnumLoc(), D->getLocation(), EnumD); | ||||||||||||
3231 | |||||||||||||
3232 | SemaRef.Context.setInstantiatedFromUsingEnumDecl(NewUD, D); | ||||||||||||
3233 | NewUD->setAccess(D->getAccess()); | ||||||||||||
3234 | Owner->addDecl(NewUD); | ||||||||||||
3235 | |||||||||||||
3236 | // Don't process the shadow decls for an invalid decl. | ||||||||||||
3237 | if (NewUD->isInvalidDecl()) | ||||||||||||
3238 | return NewUD; | ||||||||||||
3239 | |||||||||||||
3240 | // We don't have to recheck for duplication of the UsingEnumDecl itself, as it | ||||||||||||
3241 | // cannot be dependent, and will therefore have been checked during template | ||||||||||||
3242 | // definition. | ||||||||||||
3243 | |||||||||||||
3244 | return VisitBaseUsingDecls(D, NewUD, nullptr); | ||||||||||||
3245 | } | ||||||||||||
3246 | |||||||||||||
3247 | Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) { | ||||||||||||
3248 | // Ignore these; we handle them in bulk when processing the UsingDecl. | ||||||||||||
3249 | return nullptr; | ||||||||||||
3250 | } | ||||||||||||
3251 | |||||||||||||
3252 | Decl *TemplateDeclInstantiator::VisitConstructorUsingShadowDecl( | ||||||||||||
3253 | ConstructorUsingShadowDecl *D) { | ||||||||||||
3254 | // Ignore these; we handle them in bulk when processing the UsingDecl. | ||||||||||||
3255 | return nullptr; | ||||||||||||
3256 | } | ||||||||||||
3257 | |||||||||||||
3258 | template <typename T> | ||||||||||||
3259 | Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl( | ||||||||||||
3260 | T *D, bool InstantiatingPackElement) { | ||||||||||||
3261 | // If this is a pack expansion, expand it now. | ||||||||||||
3262 | if (D->isPackExpansion() && !InstantiatingPackElement) { | ||||||||||||
3263 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
3264 | SemaRef.collectUnexpandedParameterPacks(D->getQualifierLoc(), Unexpanded); | ||||||||||||
3265 | SemaRef.collectUnexpandedParameterPacks(D->getNameInfo(), Unexpanded); | ||||||||||||
3266 | |||||||||||||
3267 | // Determine whether the set of unexpanded parameter packs can and should | ||||||||||||
3268 | // be expanded. | ||||||||||||
3269 | bool Expand = true; | ||||||||||||
3270 | bool RetainExpansion = false; | ||||||||||||
3271 | Optional<unsigned> NumExpansions; | ||||||||||||
3272 | if (SemaRef.CheckParameterPacksForExpansion( | ||||||||||||
3273 | D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs, | ||||||||||||
3274 | Expand, RetainExpansion, NumExpansions)) | ||||||||||||
3275 | return nullptr; | ||||||||||||
3276 | |||||||||||||
3277 | // This declaration cannot appear within a function template signature, | ||||||||||||
3278 | // so we can't have a partial argument list for a parameter pack. | ||||||||||||
3279 | assert(!RetainExpansion &&(static_cast <bool> (!RetainExpansion && "should never need to retain an expansion for UsingPackDecl" ) ? void (0) : __assert_fail ("!RetainExpansion && \"should never need to retain an expansion for UsingPackDecl\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3280, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
3280 | "should never need to retain an expansion for UsingPackDecl")(static_cast <bool> (!RetainExpansion && "should never need to retain an expansion for UsingPackDecl" ) ? void (0) : __assert_fail ("!RetainExpansion && \"should never need to retain an expansion for UsingPackDecl\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3280, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3281 | |||||||||||||
3282 | if (!Expand) { | ||||||||||||
3283 | // We cannot fully expand the pack expansion now, so substitute into the | ||||||||||||
3284 | // pattern and create a new pack expansion. | ||||||||||||
3285 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); | ||||||||||||
3286 | return instantiateUnresolvedUsingDecl(D, true); | ||||||||||||
3287 | } | ||||||||||||
3288 | |||||||||||||
3289 | // Within a function, we don't have any normal way to check for conflicts | ||||||||||||
3290 | // between shadow declarations from different using declarations in the | ||||||||||||
3291 | // same pack expansion, but this is always ill-formed because all expansions | ||||||||||||
3292 | // must produce (conflicting) enumerators. | ||||||||||||
3293 | // | ||||||||||||
3294 | // Sadly we can't just reject this in the template definition because it | ||||||||||||
3295 | // could be valid if the pack is empty or has exactly one expansion. | ||||||||||||
3296 | if (D->getDeclContext()->isFunctionOrMethod() && *NumExpansions > 1) { | ||||||||||||
3297 | SemaRef.Diag(D->getEllipsisLoc(), | ||||||||||||
3298 | diag::err_using_decl_redeclaration_expansion); | ||||||||||||
3299 | return nullptr; | ||||||||||||
3300 | } | ||||||||||||
3301 | |||||||||||||
3302 | // Instantiate the slices of this pack and build a UsingPackDecl. | ||||||||||||
3303 | SmallVector<NamedDecl*, 8> Expansions; | ||||||||||||
3304 | for (unsigned I = 0; I != *NumExpansions; ++I) { | ||||||||||||
3305 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); | ||||||||||||
3306 | Decl *Slice = instantiateUnresolvedUsingDecl(D, true); | ||||||||||||
3307 | if (!Slice) | ||||||||||||
3308 | return nullptr; | ||||||||||||
3309 | // Note that we can still get unresolved using declarations here, if we | ||||||||||||
3310 | // had arguments for all packs but the pattern also contained other | ||||||||||||
3311 | // template arguments (this only happens during partial substitution, eg | ||||||||||||
3312 | // into the body of a generic lambda in a function template). | ||||||||||||
3313 | Expansions.push_back(cast<NamedDecl>(Slice)); | ||||||||||||
3314 | } | ||||||||||||
3315 | |||||||||||||
3316 | auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions); | ||||||||||||
3317 | if (isDeclWithinFunction(D)) | ||||||||||||
3318 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD); | ||||||||||||
3319 | return NewD; | ||||||||||||
3320 | } | ||||||||||||
3321 | |||||||||||||
3322 | UnresolvedUsingTypenameDecl *TD = dyn_cast<UnresolvedUsingTypenameDecl>(D); | ||||||||||||
3323 | SourceLocation TypenameLoc = TD ? TD->getTypenameLoc() : SourceLocation(); | ||||||||||||
3324 | |||||||||||||
3325 | NestedNameSpecifierLoc QualifierLoc | ||||||||||||
3326 | = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), | ||||||||||||
3327 | TemplateArgs); | ||||||||||||
3328 | if (!QualifierLoc) | ||||||||||||
3329 | return nullptr; | ||||||||||||
3330 | |||||||||||||
3331 | CXXScopeSpec SS; | ||||||||||||
3332 | SS.Adopt(QualifierLoc); | ||||||||||||
3333 | |||||||||||||
3334 | DeclarationNameInfo NameInfo | ||||||||||||
3335 | = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); | ||||||||||||
3336 | |||||||||||||
3337 | // Produce a pack expansion only if we're not instantiating a particular | ||||||||||||
3338 | // slice of a pack expansion. | ||||||||||||
3339 | bool InstantiatingSlice = D->getEllipsisLoc().isValid() && | ||||||||||||
3340 | SemaRef.ArgumentPackSubstitutionIndex != -1; | ||||||||||||
3341 | SourceLocation EllipsisLoc = | ||||||||||||
3342 | InstantiatingSlice ? SourceLocation() : D->getEllipsisLoc(); | ||||||||||||
3343 | |||||||||||||
3344 | bool IsUsingIfExists = D->template hasAttr<UsingIfExistsAttr>(); | ||||||||||||
3345 | NamedDecl *UD = SemaRef.BuildUsingDeclaration( | ||||||||||||
3346 | /*Scope*/ nullptr, D->getAccess(), D->getUsingLoc(), | ||||||||||||
3347 | /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc, | ||||||||||||
3348 | ParsedAttributesView(), | ||||||||||||
3349 | /*IsInstantiation*/ true, IsUsingIfExists); | ||||||||||||
3350 | if (UD) { | ||||||||||||
3351 | SemaRef.InstantiateAttrs(TemplateArgs, D, UD); | ||||||||||||
3352 | SemaRef.Context.setInstantiatedFromUsingDecl(UD, D); | ||||||||||||
3353 | } | ||||||||||||
3354 | |||||||||||||
3355 | return UD; | ||||||||||||
3356 | } | ||||||||||||
3357 | |||||||||||||
3358 | Decl *TemplateDeclInstantiator::VisitUnresolvedUsingTypenameDecl( | ||||||||||||
3359 | UnresolvedUsingTypenameDecl *D) { | ||||||||||||
3360 | return instantiateUnresolvedUsingDecl(D); | ||||||||||||
3361 | } | ||||||||||||
3362 | |||||||||||||
3363 | Decl *TemplateDeclInstantiator::VisitUnresolvedUsingValueDecl( | ||||||||||||
3364 | UnresolvedUsingValueDecl *D) { | ||||||||||||
3365 | return instantiateUnresolvedUsingDecl(D); | ||||||||||||
3366 | } | ||||||||||||
3367 | |||||||||||||
3368 | Decl *TemplateDeclInstantiator::VisitUnresolvedUsingIfExistsDecl( | ||||||||||||
3369 | UnresolvedUsingIfExistsDecl *D) { | ||||||||||||
3370 | llvm_unreachable("referring to unresolved decl out of UsingShadowDecl")::llvm::llvm_unreachable_internal("referring to unresolved decl out of UsingShadowDecl" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3370); | ||||||||||||
3371 | } | ||||||||||||
3372 | |||||||||||||
3373 | Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) { | ||||||||||||
3374 | SmallVector<NamedDecl*, 8> Expansions; | ||||||||||||
3375 | for (auto *UD : D->expansions()) { | ||||||||||||
3376 | if (NamedDecl *NewUD = | ||||||||||||
3377 | SemaRef.FindInstantiatedDecl(D->getLocation(), UD, TemplateArgs)) | ||||||||||||
3378 | Expansions.push_back(NewUD); | ||||||||||||
3379 | else | ||||||||||||
3380 | return nullptr; | ||||||||||||
3381 | } | ||||||||||||
3382 | |||||||||||||
3383 | auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions); | ||||||||||||
3384 | if (isDeclWithinFunction(D)) | ||||||||||||
3385 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD); | ||||||||||||
3386 | return NewD; | ||||||||||||
3387 | } | ||||||||||||
3388 | |||||||||||||
3389 | Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( | ||||||||||||
3390 | ClassScopeFunctionSpecializationDecl *Decl) { | ||||||||||||
3391 | CXXMethodDecl *OldFD = Decl->getSpecialization(); | ||||||||||||
3392 | return cast_or_null<CXXMethodDecl>( | ||||||||||||
3393 | VisitCXXMethodDecl(OldFD, nullptr, Decl->getTemplateArgsAsWritten())); | ||||||||||||
3394 | } | ||||||||||||
3395 | |||||||||||||
3396 | Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( | ||||||||||||
3397 | OMPThreadPrivateDecl *D) { | ||||||||||||
3398 | SmallVector<Expr *, 5> Vars; | ||||||||||||
3399 | for (auto *I : D->varlists()) { | ||||||||||||
3400 | Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get(); | ||||||||||||
3401 | assert(isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr")(static_cast <bool> (isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr") ? void (0) : __assert_fail ("isa<DeclRefExpr>(Var) && \"threadprivate arg is not a DeclRefExpr\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3401, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3402 | Vars.push_back(Var); | ||||||||||||
3403 | } | ||||||||||||
3404 | |||||||||||||
3405 | OMPThreadPrivateDecl *TD = | ||||||||||||
3406 | SemaRef.CheckOMPThreadPrivateDecl(D->getLocation(), Vars); | ||||||||||||
3407 | |||||||||||||
3408 | TD->setAccess(AS_public); | ||||||||||||
3409 | Owner->addDecl(TD); | ||||||||||||
3410 | |||||||||||||
3411 | return TD; | ||||||||||||
3412 | } | ||||||||||||
3413 | |||||||||||||
3414 | Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) { | ||||||||||||
3415 | SmallVector<Expr *, 5> Vars; | ||||||||||||
3416 | for (auto *I : D->varlists()) { | ||||||||||||
3417 | Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get(); | ||||||||||||
3418 | assert(isa<DeclRefExpr>(Var) && "allocate arg is not a DeclRefExpr")(static_cast <bool> (isa<DeclRefExpr>(Var) && "allocate arg is not a DeclRefExpr") ? void (0) : __assert_fail ("isa<DeclRefExpr>(Var) && \"allocate arg is not a DeclRefExpr\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3418, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3419 | Vars.push_back(Var); | ||||||||||||
3420 | } | ||||||||||||
3421 | SmallVector<OMPClause *, 4> Clauses; | ||||||||||||
3422 | // Copy map clauses from the original mapper. | ||||||||||||
3423 | for (OMPClause *C : D->clauselists()) { | ||||||||||||
3424 | OMPClause *IC = nullptr; | ||||||||||||
3425 | if (auto *AC = dyn_cast<OMPAllocatorClause>(C)) { | ||||||||||||
3426 | ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs); | ||||||||||||
3427 | if (!NewE.isUsable()) | ||||||||||||
3428 | continue; | ||||||||||||
3429 | IC = SemaRef.ActOnOpenMPAllocatorClause( | ||||||||||||
3430 | NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc()); | ||||||||||||
3431 | } else if (auto *AC = dyn_cast<OMPAlignClause>(C)) { | ||||||||||||
3432 | ExprResult NewE = SemaRef.SubstExpr(AC->getAlignment(), TemplateArgs); | ||||||||||||
3433 | if (!NewE.isUsable()) | ||||||||||||
3434 | continue; | ||||||||||||
3435 | IC = SemaRef.ActOnOpenMPAlignClause(NewE.get(), AC->getBeginLoc(), | ||||||||||||
3436 | AC->getLParenLoc(), AC->getEndLoc()); | ||||||||||||
3437 | // If align clause value ends up being invalid, this can end up null. | ||||||||||||
3438 | if (!IC) | ||||||||||||
3439 | continue; | ||||||||||||
3440 | } | ||||||||||||
3441 | Clauses.push_back(IC); | ||||||||||||
3442 | } | ||||||||||||
3443 | |||||||||||||
3444 | Sema::DeclGroupPtrTy Res = SemaRef.ActOnOpenMPAllocateDirective( | ||||||||||||
3445 | D->getLocation(), Vars, Clauses, Owner); | ||||||||||||
3446 | if (Res.get().isNull()) | ||||||||||||
3447 | return nullptr; | ||||||||||||
3448 | return Res.get().getSingleDecl(); | ||||||||||||
3449 | } | ||||||||||||
3450 | |||||||||||||
3451 | Decl *TemplateDeclInstantiator::VisitOMPRequiresDecl(OMPRequiresDecl *D) { | ||||||||||||
3452 | llvm_unreachable(::llvm::llvm_unreachable_internal("Requires directive cannot be instantiated within a dependent context" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3453) | ||||||||||||
3453 | "Requires directive cannot be instantiated within a dependent context")::llvm::llvm_unreachable_internal("Requires directive cannot be instantiated within a dependent context" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3453); | ||||||||||||
3454 | } | ||||||||||||
3455 | |||||||||||||
3456 | Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( | ||||||||||||
3457 | OMPDeclareReductionDecl *D) { | ||||||||||||
3458 | // Instantiate type and check if it is allowed. | ||||||||||||
3459 | const bool RequiresInstantiation = | ||||||||||||
3460 | D->getType()->isDependentType() || | ||||||||||||
3461 | D->getType()->isInstantiationDependentType() || | ||||||||||||
3462 | D->getType()->containsUnexpandedParameterPack(); | ||||||||||||
3463 | QualType SubstReductionType; | ||||||||||||
3464 | if (RequiresInstantiation) { | ||||||||||||
3465 | SubstReductionType = SemaRef.ActOnOpenMPDeclareReductionType( | ||||||||||||
3466 | D->getLocation(), | ||||||||||||
3467 | ParsedType::make(SemaRef.SubstType( | ||||||||||||
3468 | D->getType(), TemplateArgs, D->getLocation(), DeclarationName()))); | ||||||||||||
3469 | } else { | ||||||||||||
3470 | SubstReductionType = D->getType(); | ||||||||||||
3471 | } | ||||||||||||
3472 | if (SubstReductionType.isNull()) | ||||||||||||
3473 | return nullptr; | ||||||||||||
3474 | Expr *Combiner = D->getCombiner(); | ||||||||||||
3475 | Expr *Init = D->getInitializer(); | ||||||||||||
3476 | bool IsCorrect = true; | ||||||||||||
3477 | // Create instantiated copy. | ||||||||||||
3478 | std::pair<QualType, SourceLocation> ReductionTypes[] = { | ||||||||||||
3479 | std::make_pair(SubstReductionType, D->getLocation())}; | ||||||||||||
3480 | auto *PrevDeclInScope = D->getPrevDeclInScope(); | ||||||||||||
3481 | if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) { | ||||||||||||
3482 | PrevDeclInScope = cast<OMPDeclareReductionDecl>( | ||||||||||||
3483 | SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope) | ||||||||||||
3484 | ->get<Decl *>()); | ||||||||||||
3485 | } | ||||||||||||
3486 | auto DRD = SemaRef.ActOnOpenMPDeclareReductionDirectiveStart( | ||||||||||||
3487 | /*S=*/nullptr, Owner, D->getDeclName(), ReductionTypes, D->getAccess(), | ||||||||||||
3488 | PrevDeclInScope); | ||||||||||||
3489 | auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl()); | ||||||||||||
3490 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD); | ||||||||||||
3491 | Expr *SubstCombiner = nullptr; | ||||||||||||
3492 | Expr *SubstInitializer = nullptr; | ||||||||||||
3493 | // Combiners instantiation sequence. | ||||||||||||
3494 | if (Combiner) { | ||||||||||||
3495 | SemaRef.ActOnOpenMPDeclareReductionCombinerStart( | ||||||||||||
3496 | /*S=*/nullptr, NewDRD); | ||||||||||||
3497 | SemaRef.CurrentInstantiationScope->InstantiatedLocal( | ||||||||||||
3498 | cast<DeclRefExpr>(D->getCombinerIn())->getDecl(), | ||||||||||||
3499 | cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl()); | ||||||||||||
3500 | SemaRef.CurrentInstantiationScope->InstantiatedLocal( | ||||||||||||
3501 | cast<DeclRefExpr>(D->getCombinerOut())->getDecl(), | ||||||||||||
3502 | cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl()); | ||||||||||||
3503 | auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner); | ||||||||||||
3504 | Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(), | ||||||||||||
3505 | ThisContext); | ||||||||||||
3506 | SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get(); | ||||||||||||
3507 | SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner); | ||||||||||||
3508 | } | ||||||||||||
3509 | // Initializers instantiation sequence. | ||||||||||||
3510 | if (Init) { | ||||||||||||
3511 | VarDecl *OmpPrivParm = SemaRef.ActOnOpenMPDeclareReductionInitializerStart( | ||||||||||||
3512 | /*S=*/nullptr, NewDRD); | ||||||||||||
3513 | SemaRef.CurrentInstantiationScope->InstantiatedLocal( | ||||||||||||
3514 | cast<DeclRefExpr>(D->getInitOrig())->getDecl(), | ||||||||||||
3515 | cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl()); | ||||||||||||
3516 | SemaRef.CurrentInstantiationScope->InstantiatedLocal( | ||||||||||||
3517 | cast<DeclRefExpr>(D->getInitPriv())->getDecl(), | ||||||||||||
3518 | cast<DeclRefExpr>(NewDRD->getInitPriv())->getDecl()); | ||||||||||||
3519 | if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) { | ||||||||||||
3520 | SubstInitializer = SemaRef.SubstExpr(Init, TemplateArgs).get(); | ||||||||||||
3521 | } else { | ||||||||||||
3522 | auto *OldPrivParm = | ||||||||||||
3523 | cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl()); | ||||||||||||
3524 | IsCorrect = IsCorrect && OldPrivParm->hasInit(); | ||||||||||||
3525 | if (IsCorrect) | ||||||||||||
3526 | SemaRef.InstantiateVariableInitializer(OmpPrivParm, OldPrivParm, | ||||||||||||
3527 | TemplateArgs); | ||||||||||||
3528 | } | ||||||||||||
3529 | SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(NewDRD, SubstInitializer, | ||||||||||||
3530 | OmpPrivParm); | ||||||||||||
3531 | } | ||||||||||||
3532 | IsCorrect = IsCorrect && SubstCombiner && | ||||||||||||
3533 | (!Init || | ||||||||||||
3534 | (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit && | ||||||||||||
3535 | SubstInitializer) || | ||||||||||||
3536 | (D->getInitializerKind() != OMPDeclareReductionDecl::CallInit && | ||||||||||||
3537 | !SubstInitializer)); | ||||||||||||
3538 | |||||||||||||
3539 | (void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd( | ||||||||||||
3540 | /*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl()); | ||||||||||||
3541 | |||||||||||||
3542 | return NewDRD; | ||||||||||||
3543 | } | ||||||||||||
3544 | |||||||||||||
3545 | Decl * | ||||||||||||
3546 | TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { | ||||||||||||
3547 | // Instantiate type and check if it is allowed. | ||||||||||||
3548 | const bool RequiresInstantiation = | ||||||||||||
3549 | D->getType()->isDependentType() || | ||||||||||||
3550 | D->getType()->isInstantiationDependentType() || | ||||||||||||
3551 | D->getType()->containsUnexpandedParameterPack(); | ||||||||||||
3552 | QualType SubstMapperTy; | ||||||||||||
3553 | DeclarationName VN = D->getVarName(); | ||||||||||||
3554 | if (RequiresInstantiation) { | ||||||||||||
3555 | SubstMapperTy = SemaRef.ActOnOpenMPDeclareMapperType( | ||||||||||||
3556 | D->getLocation(), | ||||||||||||
3557 | ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs, | ||||||||||||
3558 | D->getLocation(), VN))); | ||||||||||||
3559 | } else { | ||||||||||||
3560 | SubstMapperTy = D->getType(); | ||||||||||||
3561 | } | ||||||||||||
3562 | if (SubstMapperTy.isNull()) | ||||||||||||
3563 | return nullptr; | ||||||||||||
3564 | // Create an instantiated copy of mapper. | ||||||||||||
3565 | auto *PrevDeclInScope = D->getPrevDeclInScope(); | ||||||||||||
3566 | if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) { | ||||||||||||
3567 | PrevDeclInScope = cast<OMPDeclareMapperDecl>( | ||||||||||||
3568 | SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope) | ||||||||||||
3569 | ->get<Decl *>()); | ||||||||||||
3570 | } | ||||||||||||
3571 | bool IsCorrect = true; | ||||||||||||
3572 | SmallVector<OMPClause *, 6> Clauses; | ||||||||||||
3573 | // Instantiate the mapper variable. | ||||||||||||
3574 | DeclarationNameInfo DirName; | ||||||||||||
3575 | SemaRef.StartOpenMPDSABlock(llvm::omp::OMPD_declare_mapper, DirName, | ||||||||||||
3576 | /*S=*/nullptr, | ||||||||||||
3577 | (*D->clauselist_begin())->getBeginLoc()); | ||||||||||||
3578 | ExprResult MapperVarRef = SemaRef.ActOnOpenMPDeclareMapperDirectiveVarDecl( | ||||||||||||
3579 | /*S=*/nullptr, SubstMapperTy, D->getLocation(), VN); | ||||||||||||
3580 | SemaRef.CurrentInstantiationScope->InstantiatedLocal( | ||||||||||||
3581 | cast<DeclRefExpr>(D->getMapperVarRef())->getDecl(), | ||||||||||||
3582 | cast<DeclRefExpr>(MapperVarRef.get())->getDecl()); | ||||||||||||
3583 | auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner); | ||||||||||||
3584 | Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(), | ||||||||||||
3585 | ThisContext); | ||||||||||||
3586 | // Instantiate map clauses. | ||||||||||||
3587 | for (OMPClause *C : D->clauselists()) { | ||||||||||||
3588 | auto *OldC = cast<OMPMapClause>(C); | ||||||||||||
3589 | SmallVector<Expr *, 4> NewVars; | ||||||||||||
3590 | for (Expr *OE : OldC->varlists()) { | ||||||||||||
3591 | Expr *NE = SemaRef.SubstExpr(OE, TemplateArgs).get(); | ||||||||||||
3592 | if (!NE) { | ||||||||||||
3593 | IsCorrect = false; | ||||||||||||
3594 | break; | ||||||||||||
3595 | } | ||||||||||||
3596 | NewVars.push_back(NE); | ||||||||||||
3597 | } | ||||||||||||
3598 | if (!IsCorrect) | ||||||||||||
3599 | break; | ||||||||||||
3600 | NestedNameSpecifierLoc NewQualifierLoc = | ||||||||||||
3601 | SemaRef.SubstNestedNameSpecifierLoc(OldC->getMapperQualifierLoc(), | ||||||||||||
3602 | TemplateArgs); | ||||||||||||
3603 | CXXScopeSpec SS; | ||||||||||||
3604 | SS.Adopt(NewQualifierLoc); | ||||||||||||
3605 | DeclarationNameInfo NewNameInfo = | ||||||||||||
3606 | SemaRef.SubstDeclarationNameInfo(OldC->getMapperIdInfo(), TemplateArgs); | ||||||||||||
3607 | OMPVarListLocTy Locs(OldC->getBeginLoc(), OldC->getLParenLoc(), | ||||||||||||
3608 | OldC->getEndLoc()); | ||||||||||||
3609 | OMPClause *NewC = SemaRef.ActOnOpenMPMapClause( | ||||||||||||
3610 | OldC->getMapTypeModifiers(), OldC->getMapTypeModifiersLoc(), SS, | ||||||||||||
3611 | NewNameInfo, OldC->getMapType(), OldC->isImplicitMapType(), | ||||||||||||
3612 | OldC->getMapLoc(), OldC->getColonLoc(), NewVars, Locs); | ||||||||||||
3613 | Clauses.push_back(NewC); | ||||||||||||
3614 | } | ||||||||||||
3615 | SemaRef.EndOpenMPDSABlock(nullptr); | ||||||||||||
3616 | if (!IsCorrect) | ||||||||||||
3617 | return nullptr; | ||||||||||||
3618 | Sema::DeclGroupPtrTy DG = SemaRef.ActOnOpenMPDeclareMapperDirective( | ||||||||||||
3619 | /*S=*/nullptr, Owner, D->getDeclName(), SubstMapperTy, D->getLocation(), | ||||||||||||
3620 | VN, D->getAccess(), MapperVarRef.get(), Clauses, PrevDeclInScope); | ||||||||||||
3621 | Decl *NewDMD = DG.get().getSingleDecl(); | ||||||||||||
3622 | SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDMD); | ||||||||||||
3623 | return NewDMD; | ||||||||||||
3624 | } | ||||||||||||
3625 | |||||||||||||
3626 | Decl *TemplateDeclInstantiator::VisitOMPCapturedExprDecl( | ||||||||||||
3627 | OMPCapturedExprDecl * /*D*/) { | ||||||||||||
3628 | llvm_unreachable("Should not be met in templates")::llvm::llvm_unreachable_internal("Should not be met in templates" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3628); | ||||||||||||
3629 | } | ||||||||||||
3630 | |||||||||||||
3631 | Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { | ||||||||||||
3632 | return VisitFunctionDecl(D, nullptr); | ||||||||||||
3633 | } | ||||||||||||
3634 | |||||||||||||
3635 | Decl * | ||||||||||||
3636 | TemplateDeclInstantiator::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { | ||||||||||||
3637 | Decl *Inst = VisitFunctionDecl(D, nullptr); | ||||||||||||
3638 | if (Inst && !D->getDescribedFunctionTemplate()) | ||||||||||||
3639 | Owner->addDecl(Inst); | ||||||||||||
3640 | return Inst; | ||||||||||||
3641 | } | ||||||||||||
3642 | |||||||||||||
3643 | Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { | ||||||||||||
3644 | return VisitCXXMethodDecl(D, nullptr); | ||||||||||||
3645 | } | ||||||||||||
3646 | |||||||||||||
3647 | Decl *TemplateDeclInstantiator::VisitRecordDecl(RecordDecl *D) { | ||||||||||||
3648 | llvm_unreachable("There are only CXXRecordDecls in C++")::llvm::llvm_unreachable_internal("There are only CXXRecordDecls in C++" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3648); | ||||||||||||
3649 | } | ||||||||||||
3650 | |||||||||||||
3651 | Decl * | ||||||||||||
3652 | TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( | ||||||||||||
3653 | ClassTemplateSpecializationDecl *D) { | ||||||||||||
3654 | // As a MS extension, we permit class-scope explicit specialization | ||||||||||||
3655 | // of member class templates. | ||||||||||||
3656 | ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate(); | ||||||||||||
3657 | assert(ClassTemplate->getDeclContext()->isRecord() &&(static_cast <bool> (ClassTemplate->getDeclContext() ->isRecord() && D->getTemplateSpecializationKind () == TSK_ExplicitSpecialization && "can only instantiate an explicit specialization " "for a member class template") ? void (0) : __assert_fail ("ClassTemplate->getDeclContext()->isRecord() && D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization && \"can only instantiate an explicit specialization \" \"for a member class template\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3660, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
3658 | D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&(static_cast <bool> (ClassTemplate->getDeclContext() ->isRecord() && D->getTemplateSpecializationKind () == TSK_ExplicitSpecialization && "can only instantiate an explicit specialization " "for a member class template") ? void (0) : __assert_fail ("ClassTemplate->getDeclContext()->isRecord() && D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization && \"can only instantiate an explicit specialization \" \"for a member class template\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3660, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
3659 | "can only instantiate an explicit specialization "(static_cast <bool> (ClassTemplate->getDeclContext() ->isRecord() && D->getTemplateSpecializationKind () == TSK_ExplicitSpecialization && "can only instantiate an explicit specialization " "for a member class template") ? void (0) : __assert_fail ("ClassTemplate->getDeclContext()->isRecord() && D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization && \"can only instantiate an explicit specialization \" \"for a member class template\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3660, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
3660 | "for a member class template")(static_cast <bool> (ClassTemplate->getDeclContext() ->isRecord() && D->getTemplateSpecializationKind () == TSK_ExplicitSpecialization && "can only instantiate an explicit specialization " "for a member class template") ? void (0) : __assert_fail ("ClassTemplate->getDeclContext()->isRecord() && D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization && \"can only instantiate an explicit specialization \" \"for a member class template\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3660, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3661 | |||||||||||||
3662 | // Lookup the already-instantiated declaration in the instantiation | ||||||||||||
3663 | // of the class template. | ||||||||||||
3664 | ClassTemplateDecl *InstClassTemplate = | ||||||||||||
3665 | cast_or_null<ClassTemplateDecl>(SemaRef.FindInstantiatedDecl( | ||||||||||||
3666 | D->getLocation(), ClassTemplate, TemplateArgs)); | ||||||||||||
3667 | if (!InstClassTemplate) | ||||||||||||
3668 | return nullptr; | ||||||||||||
3669 | |||||||||||||
3670 | // Substitute into the template arguments of the class template explicit | ||||||||||||
3671 | // specialization. | ||||||||||||
3672 | TemplateSpecializationTypeLoc Loc = D->getTypeAsWritten()->getTypeLoc(). | ||||||||||||
3673 | castAs<TemplateSpecializationTypeLoc>(); | ||||||||||||
3674 | TemplateArgumentListInfo InstTemplateArgs(Loc.getLAngleLoc(), | ||||||||||||
3675 | Loc.getRAngleLoc()); | ||||||||||||
3676 | SmallVector<TemplateArgumentLoc, 4> ArgLocs; | ||||||||||||
3677 | for (unsigned I = 0; I != Loc.getNumArgs(); ++I) | ||||||||||||
3678 | ArgLocs.push_back(Loc.getArgLoc(I)); | ||||||||||||
3679 | if (SemaRef.SubstTemplateArguments(ArgLocs, TemplateArgs, InstTemplateArgs)) | ||||||||||||
3680 | return nullptr; | ||||||||||||
3681 | |||||||||||||
3682 | // Check that the template argument list is well-formed for this | ||||||||||||
3683 | // class template. | ||||||||||||
3684 | SmallVector<TemplateArgument, 4> Converted; | ||||||||||||
3685 | if (SemaRef.CheckTemplateArgumentList(InstClassTemplate, | ||||||||||||
3686 | D->getLocation(), | ||||||||||||
3687 | InstTemplateArgs, | ||||||||||||
3688 | false, | ||||||||||||
3689 | Converted, | ||||||||||||
3690 | /*UpdateArgsWithConversions=*/true)) | ||||||||||||
3691 | return nullptr; | ||||||||||||
3692 | |||||||||||||
3693 | // Figure out where to insert this class template explicit specialization | ||||||||||||
3694 | // in the member template's set of class template explicit specializations. | ||||||||||||
3695 | void *InsertPos = nullptr; | ||||||||||||
3696 | ClassTemplateSpecializationDecl *PrevDecl = | ||||||||||||
3697 | InstClassTemplate->findSpecialization(Converted, InsertPos); | ||||||||||||
3698 | |||||||||||||
3699 | // Check whether we've already seen a conflicting instantiation of this | ||||||||||||
3700 | // declaration (for instance, if there was a prior implicit instantiation). | ||||||||||||
3701 | bool Ignored; | ||||||||||||
3702 | if (PrevDecl && | ||||||||||||
3703 | SemaRef.CheckSpecializationInstantiationRedecl(D->getLocation(), | ||||||||||||
3704 | D->getSpecializationKind(), | ||||||||||||
3705 | PrevDecl, | ||||||||||||
3706 | PrevDecl->getSpecializationKind(), | ||||||||||||
3707 | PrevDecl->getPointOfInstantiation(), | ||||||||||||
3708 | Ignored)) | ||||||||||||
3709 | return nullptr; | ||||||||||||
3710 | |||||||||||||
3711 | // If PrevDecl was a definition and D is also a definition, diagnose. | ||||||||||||
3712 | // This happens in cases like: | ||||||||||||
3713 | // | ||||||||||||
3714 | // template<typename T, typename U> | ||||||||||||
3715 | // struct Outer { | ||||||||||||
3716 | // template<typename X> struct Inner; | ||||||||||||
3717 | // template<> struct Inner<T> {}; | ||||||||||||
3718 | // template<> struct Inner<U> {}; | ||||||||||||
3719 | // }; | ||||||||||||
3720 | // | ||||||||||||
3721 | // Outer<int, int> outer; // error: the explicit specializations of Inner | ||||||||||||
3722 | // // have the same signature. | ||||||||||||
3723 | if (PrevDecl && PrevDecl->getDefinition() && | ||||||||||||
3724 | D->isThisDeclarationADefinition()) { | ||||||||||||
3725 | SemaRef.Diag(D->getLocation(), diag::err_redefinition) << PrevDecl; | ||||||||||||
3726 | SemaRef.Diag(PrevDecl->getDefinition()->getLocation(), | ||||||||||||
3727 | diag::note_previous_definition); | ||||||||||||
3728 | return nullptr; | ||||||||||||
3729 | } | ||||||||||||
3730 | |||||||||||||
3731 | // Create the class template partial specialization declaration. | ||||||||||||
3732 | ClassTemplateSpecializationDecl *InstD = | ||||||||||||
3733 | ClassTemplateSpecializationDecl::Create( | ||||||||||||
3734 | SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(), | ||||||||||||
3735 | D->getLocation(), InstClassTemplate, Converted, PrevDecl); | ||||||||||||
3736 | |||||||||||||
3737 | // Add this partial specialization to the set of class template partial | ||||||||||||
3738 | // specializations. | ||||||||||||
3739 | if (!PrevDecl) | ||||||||||||
3740 | InstClassTemplate->AddSpecialization(InstD, InsertPos); | ||||||||||||
3741 | |||||||||||||
3742 | // Substitute the nested name specifier, if any. | ||||||||||||
3743 | if (SubstQualifier(D, InstD)) | ||||||||||||
3744 | return nullptr; | ||||||||||||
3745 | |||||||||||||
3746 | // Build the canonical type that describes the converted template | ||||||||||||
3747 | // arguments of the class template explicit specialization. | ||||||||||||
3748 | QualType CanonType = SemaRef.Context.getTemplateSpecializationType( | ||||||||||||
3749 | TemplateName(InstClassTemplate), Converted, | ||||||||||||
3750 | SemaRef.Context.getRecordType(InstD)); | ||||||||||||
3751 | |||||||||||||
3752 | // Build the fully-sugared type for this class template | ||||||||||||
3753 | // specialization as the user wrote in the specialization | ||||||||||||
3754 | // itself. This means that we'll pretty-print the type retrieved | ||||||||||||
3755 | // from the specialization's declaration the way that the user | ||||||||||||
3756 | // actually wrote the specialization, rather than formatting the | ||||||||||||
3757 | // name based on the "canonical" representation used to store the | ||||||||||||
3758 | // template arguments in the specialization. | ||||||||||||
3759 | TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo( | ||||||||||||
3760 | TemplateName(InstClassTemplate), D->getLocation(), InstTemplateArgs, | ||||||||||||
3761 | CanonType); | ||||||||||||
3762 | |||||||||||||
3763 | InstD->setAccess(D->getAccess()); | ||||||||||||
3764 | InstD->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation); | ||||||||||||
3765 | InstD->setSpecializationKind(D->getSpecializationKind()); | ||||||||||||
3766 | InstD->setTypeAsWritten(WrittenTy); | ||||||||||||
3767 | InstD->setExternLoc(D->getExternLoc()); | ||||||||||||
3768 | InstD->setTemplateKeywordLoc(D->getTemplateKeywordLoc()); | ||||||||||||
3769 | |||||||||||||
3770 | Owner->addDecl(InstD); | ||||||||||||
3771 | |||||||||||||
3772 | // Instantiate the members of the class-scope explicit specialization eagerly. | ||||||||||||
3773 | // We don't have support for lazy instantiation of an explicit specialization | ||||||||||||
3774 | // yet, and MSVC eagerly instantiates in this case. | ||||||||||||
3775 | // FIXME: This is wrong in standard C++. | ||||||||||||
3776 | if (D->isThisDeclarationADefinition() && | ||||||||||||
3777 | SemaRef.InstantiateClass(D->getLocation(), InstD, D, TemplateArgs, | ||||||||||||
3778 | TSK_ImplicitInstantiation, | ||||||||||||
3779 | /*Complain=*/true)) | ||||||||||||
3780 | return nullptr; | ||||||||||||
3781 | |||||||||||||
3782 | return InstD; | ||||||||||||
3783 | } | ||||||||||||
3784 | |||||||||||||
3785 | Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( | ||||||||||||
3786 | VarTemplateSpecializationDecl *D) { | ||||||||||||
3787 | |||||||||||||
3788 | TemplateArgumentListInfo VarTemplateArgsInfo; | ||||||||||||
3789 | VarTemplateDecl *VarTemplate = D->getSpecializedTemplate(); | ||||||||||||
3790 | assert(VarTemplate &&(static_cast <bool> (VarTemplate && "A template specialization without specialized template?" ) ? void (0) : __assert_fail ("VarTemplate && \"A template specialization without specialized template?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3791, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
3791 | "A template specialization without specialized template?")(static_cast <bool> (VarTemplate && "A template specialization without specialized template?" ) ? void (0) : __assert_fail ("VarTemplate && \"A template specialization without specialized template?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3791, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3792 | |||||||||||||
3793 | VarTemplateDecl *InstVarTemplate = | ||||||||||||
3794 | cast_or_null<VarTemplateDecl>(SemaRef.FindInstantiatedDecl( | ||||||||||||
3795 | D->getLocation(), VarTemplate, TemplateArgs)); | ||||||||||||
3796 | if (!InstVarTemplate) | ||||||||||||
3797 | return nullptr; | ||||||||||||
3798 | |||||||||||||
3799 | // Substitute the current template arguments. | ||||||||||||
3800 | if (const ASTTemplateArgumentListInfo *TemplateArgsInfo = | ||||||||||||
3801 | D->getTemplateArgsInfo()) { | ||||||||||||
3802 | VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo->getLAngleLoc()); | ||||||||||||
3803 | VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo->getRAngleLoc()); | ||||||||||||
3804 | |||||||||||||
3805 | if (SemaRef.SubstTemplateArguments(TemplateArgsInfo->arguments(), | ||||||||||||
3806 | TemplateArgs, VarTemplateArgsInfo)) | ||||||||||||
3807 | return nullptr; | ||||||||||||
3808 | } | ||||||||||||
3809 | |||||||||||||
3810 | // Check that the template argument list is well-formed for this template. | ||||||||||||
3811 | SmallVector<TemplateArgument, 4> Converted; | ||||||||||||
3812 | if (SemaRef.CheckTemplateArgumentList(InstVarTemplate, D->getLocation(), | ||||||||||||
3813 | VarTemplateArgsInfo, false, Converted, | ||||||||||||
3814 | /*UpdateArgsWithConversions=*/true)) | ||||||||||||
3815 | return nullptr; | ||||||||||||
3816 | |||||||||||||
3817 | // Check whether we've already seen a declaration of this specialization. | ||||||||||||
3818 | void *InsertPos = nullptr; | ||||||||||||
3819 | VarTemplateSpecializationDecl *PrevDecl = | ||||||||||||
3820 | InstVarTemplate->findSpecialization(Converted, InsertPos); | ||||||||||||
3821 | |||||||||||||
3822 | // Check whether we've already seen a conflicting instantiation of this | ||||||||||||
3823 | // declaration (for instance, if there was a prior implicit instantiation). | ||||||||||||
3824 | bool Ignored; | ||||||||||||
3825 | if (PrevDecl && SemaRef.CheckSpecializationInstantiationRedecl( | ||||||||||||
3826 | D->getLocation(), D->getSpecializationKind(), PrevDecl, | ||||||||||||
3827 | PrevDecl->getSpecializationKind(), | ||||||||||||
3828 | PrevDecl->getPointOfInstantiation(), Ignored)) | ||||||||||||
3829 | return nullptr; | ||||||||||||
3830 | |||||||||||||
3831 | return VisitVarTemplateSpecializationDecl( | ||||||||||||
3832 | InstVarTemplate, D, VarTemplateArgsInfo, Converted, PrevDecl); | ||||||||||||
3833 | } | ||||||||||||
3834 | |||||||||||||
3835 | Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( | ||||||||||||
3836 | VarTemplateDecl *VarTemplate, VarDecl *D, | ||||||||||||
3837 | const TemplateArgumentListInfo &TemplateArgsInfo, | ||||||||||||
3838 | ArrayRef<TemplateArgument> Converted, | ||||||||||||
3839 | VarTemplateSpecializationDecl *PrevDecl) { | ||||||||||||
3840 | |||||||||||||
3841 | // Do substitution on the type of the declaration | ||||||||||||
3842 | TypeSourceInfo *DI = | ||||||||||||
3843 | SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs, | ||||||||||||
3844 | D->getTypeSpecStartLoc(), D->getDeclName()); | ||||||||||||
3845 | if (!DI) | ||||||||||||
3846 | return nullptr; | ||||||||||||
3847 | |||||||||||||
3848 | if (DI->getType()->isFunctionType()) { | ||||||||||||
3849 | SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function) | ||||||||||||
3850 | << D->isStaticDataMember() << DI->getType(); | ||||||||||||
3851 | return nullptr; | ||||||||||||
3852 | } | ||||||||||||
3853 | |||||||||||||
3854 | // Build the instantiated declaration | ||||||||||||
3855 | VarTemplateSpecializationDecl *Var = VarTemplateSpecializationDecl::Create( | ||||||||||||
3856 | SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), | ||||||||||||
3857 | VarTemplate, DI->getType(), DI, D->getStorageClass(), Converted); | ||||||||||||
3858 | Var->setTemplateArgsInfo(TemplateArgsInfo); | ||||||||||||
3859 | if (!PrevDecl) { | ||||||||||||
3860 | void *InsertPos = nullptr; | ||||||||||||
3861 | VarTemplate->findSpecialization(Converted, InsertPos); | ||||||||||||
3862 | VarTemplate->AddSpecialization(Var, InsertPos); | ||||||||||||
3863 | } | ||||||||||||
3864 | |||||||||||||
3865 | if (SemaRef.getLangOpts().OpenCL) | ||||||||||||
3866 | SemaRef.deduceOpenCLAddressSpace(Var); | ||||||||||||
3867 | |||||||||||||
3868 | // Substitute the nested name specifier, if any. | ||||||||||||
3869 | if (SubstQualifier(D, Var)) | ||||||||||||
3870 | return nullptr; | ||||||||||||
3871 | |||||||||||||
3872 | SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner, | ||||||||||||
3873 | StartingScope, false, PrevDecl); | ||||||||||||
3874 | |||||||||||||
3875 | return Var; | ||||||||||||
3876 | } | ||||||||||||
3877 | |||||||||||||
3878 | Decl *TemplateDeclInstantiator::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) { | ||||||||||||
3879 | llvm_unreachable("@defs is not supported in Objective-C++")::llvm::llvm_unreachable_internal("@defs is not supported in Objective-C++" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3879); | ||||||||||||
3880 | } | ||||||||||||
3881 | |||||||||||||
3882 | Decl *TemplateDeclInstantiator::VisitFriendTemplateDecl(FriendTemplateDecl *D) { | ||||||||||||
3883 | // FIXME: We need to be able to instantiate FriendTemplateDecls. | ||||||||||||
3884 | unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID( | ||||||||||||
3885 | DiagnosticsEngine::Error, | ||||||||||||
3886 | "cannot instantiate %0 yet"); | ||||||||||||
3887 | SemaRef.Diag(D->getLocation(), DiagID) | ||||||||||||
3888 | << D->getDeclKindName(); | ||||||||||||
3889 | |||||||||||||
3890 | return nullptr; | ||||||||||||
3891 | } | ||||||||||||
3892 | |||||||||||||
3893 | Decl *TemplateDeclInstantiator::VisitConceptDecl(ConceptDecl *D) { | ||||||||||||
3894 | llvm_unreachable("Concept definitions cannot reside inside a template")::llvm::llvm_unreachable_internal("Concept definitions cannot reside inside a template" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3894); | ||||||||||||
3895 | } | ||||||||||||
3896 | |||||||||||||
3897 | Decl * | ||||||||||||
3898 | TemplateDeclInstantiator::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) { | ||||||||||||
3899 | return RequiresExprBodyDecl::Create(SemaRef.Context, D->getDeclContext(), | ||||||||||||
3900 | D->getBeginLoc()); | ||||||||||||
3901 | } | ||||||||||||
3902 | |||||||||||||
3903 | Decl *TemplateDeclInstantiator::VisitDecl(Decl *D) { | ||||||||||||
3904 | llvm_unreachable("Unexpected decl")::llvm::llvm_unreachable_internal("Unexpected decl", "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp" , 3904); | ||||||||||||
3905 | } | ||||||||||||
3906 | |||||||||||||
3907 | Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner, | ||||||||||||
3908 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
3909 | TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); | ||||||||||||
3910 | if (D->isInvalidDecl()) | ||||||||||||
3911 | return nullptr; | ||||||||||||
3912 | |||||||||||||
3913 | Decl *SubstD; | ||||||||||||
3914 | runWithSufficientStackSpace(D->getLocation(), [&] { | ||||||||||||
3915 | SubstD = Instantiator.Visit(D); | ||||||||||||
3916 | }); | ||||||||||||
3917 | return SubstD; | ||||||||||||
3918 | } | ||||||||||||
3919 | |||||||||||||
3920 | void TemplateDeclInstantiator::adjustForRewrite(RewriteKind RK, | ||||||||||||
3921 | FunctionDecl *Orig, QualType &T, | ||||||||||||
3922 | TypeSourceInfo *&TInfo, | ||||||||||||
3923 | DeclarationNameInfo &NameInfo) { | ||||||||||||
3924 | assert(RK == RewriteKind::RewriteSpaceshipAsEqualEqual)(static_cast <bool> (RK == RewriteKind::RewriteSpaceshipAsEqualEqual ) ? void (0) : __assert_fail ("RK == RewriteKind::RewriteSpaceshipAsEqualEqual" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3924, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3925 | |||||||||||||
3926 | // C++2a [class.compare.default]p3: | ||||||||||||
3927 | // the return type is replaced with bool | ||||||||||||
3928 | auto *FPT = T->castAs<FunctionProtoType>(); | ||||||||||||
3929 | T = SemaRef.Context.getFunctionType( | ||||||||||||
3930 | SemaRef.Context.BoolTy, FPT->getParamTypes(), FPT->getExtProtoInfo()); | ||||||||||||
3931 | |||||||||||||
3932 | // Update the return type in the source info too. The most straightforward | ||||||||||||
3933 | // way is to create new TypeSourceInfo for the new type. Use the location of | ||||||||||||
3934 | // the '= default' as the location of the new type. | ||||||||||||
3935 | // | ||||||||||||
3936 | // FIXME: Set the correct return type when we initially transform the type, | ||||||||||||
3937 | // rather than delaying it to now. | ||||||||||||
3938 | TypeSourceInfo *NewTInfo = | ||||||||||||
3939 | SemaRef.Context.getTrivialTypeSourceInfo(T, Orig->getEndLoc()); | ||||||||||||
3940 | auto OldLoc = TInfo->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>(); | ||||||||||||
3941 | assert(OldLoc && "type of function is not a function type?")(static_cast <bool> (OldLoc && "type of function is not a function type?" ) ? void (0) : __assert_fail ("OldLoc && \"type of function is not a function type?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3941, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3942 | auto NewLoc = NewTInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>(); | ||||||||||||
3943 | for (unsigned I = 0, N = OldLoc.getNumParams(); I != N; ++I) | ||||||||||||
3944 | NewLoc.setParam(I, OldLoc.getParam(I)); | ||||||||||||
3945 | TInfo = NewTInfo; | ||||||||||||
3946 | |||||||||||||
3947 | // and the declarator-id is replaced with operator== | ||||||||||||
3948 | NameInfo.setName( | ||||||||||||
3949 | SemaRef.Context.DeclarationNames.getCXXOperatorName(OO_EqualEqual)); | ||||||||||||
3950 | } | ||||||||||||
3951 | |||||||||||||
3952 | FunctionDecl *Sema::SubstSpaceshipAsEqualEqual(CXXRecordDecl *RD, | ||||||||||||
3953 | FunctionDecl *Spaceship) { | ||||||||||||
3954 | if (Spaceship->isInvalidDecl()) | ||||||||||||
3955 | return nullptr; | ||||||||||||
3956 | |||||||||||||
3957 | // C++2a [class.compare.default]p3: | ||||||||||||
3958 | // an == operator function is declared implicitly [...] with the same | ||||||||||||
3959 | // access and function-definition and in the same class scope as the | ||||||||||||
3960 | // three-way comparison operator function | ||||||||||||
3961 | MultiLevelTemplateArgumentList NoTemplateArgs; | ||||||||||||
3962 | NoTemplateArgs.setKind(TemplateSubstitutionKind::Rewrite); | ||||||||||||
3963 | NoTemplateArgs.addOuterRetainedLevels(RD->getTemplateDepth()); | ||||||||||||
3964 | TemplateDeclInstantiator Instantiator(*this, RD, NoTemplateArgs); | ||||||||||||
3965 | Decl *R; | ||||||||||||
3966 | if (auto *MD = dyn_cast<CXXMethodDecl>(Spaceship)) { | ||||||||||||
3967 | R = Instantiator.VisitCXXMethodDecl( | ||||||||||||
3968 | MD, nullptr, None, | ||||||||||||
3969 | TemplateDeclInstantiator::RewriteKind::RewriteSpaceshipAsEqualEqual); | ||||||||||||
3970 | } else { | ||||||||||||
3971 | assert(Spaceship->getFriendObjectKind() &&(static_cast <bool> (Spaceship->getFriendObjectKind( ) && "defaulted spaceship is neither a member nor a friend" ) ? void (0) : __assert_fail ("Spaceship->getFriendObjectKind() && \"defaulted spaceship is neither a member nor a friend\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3972, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
3972 | "defaulted spaceship is neither a member nor a friend")(static_cast <bool> (Spaceship->getFriendObjectKind( ) && "defaulted spaceship is neither a member nor a friend" ) ? void (0) : __assert_fail ("Spaceship->getFriendObjectKind() && \"defaulted spaceship is neither a member nor a friend\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 3972, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
3973 | |||||||||||||
3974 | R = Instantiator.VisitFunctionDecl( | ||||||||||||
3975 | Spaceship, nullptr, | ||||||||||||
3976 | TemplateDeclInstantiator::RewriteKind::RewriteSpaceshipAsEqualEqual); | ||||||||||||
3977 | if (!R) | ||||||||||||
3978 | return nullptr; | ||||||||||||
3979 | |||||||||||||
3980 | FriendDecl *FD = | ||||||||||||
3981 | FriendDecl::Create(Context, RD, Spaceship->getLocation(), | ||||||||||||
3982 | cast<NamedDecl>(R), Spaceship->getBeginLoc()); | ||||||||||||
3983 | FD->setAccess(AS_public); | ||||||||||||
3984 | RD->addDecl(FD); | ||||||||||||
3985 | } | ||||||||||||
3986 | return cast_or_null<FunctionDecl>(R); | ||||||||||||
3987 | } | ||||||||||||
3988 | |||||||||||||
3989 | /// Instantiates a nested template parameter list in the current | ||||||||||||
3990 | /// instantiation context. | ||||||||||||
3991 | /// | ||||||||||||
3992 | /// \param L The parameter list to instantiate | ||||||||||||
3993 | /// | ||||||||||||
3994 | /// \returns NULL if there was an error | ||||||||||||
3995 | TemplateParameterList * | ||||||||||||
3996 | TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { | ||||||||||||
3997 | // Get errors for all the parameters before bailing out. | ||||||||||||
3998 | bool Invalid = false; | ||||||||||||
3999 | |||||||||||||
4000 | unsigned N = L->size(); | ||||||||||||
4001 | typedef SmallVector<NamedDecl *, 8> ParamVector; | ||||||||||||
4002 | ParamVector Params; | ||||||||||||
4003 | Params.reserve(N); | ||||||||||||
4004 | for (auto &P : *L) { | ||||||||||||
4005 | NamedDecl *D = cast_or_null<NamedDecl>(Visit(P)); | ||||||||||||
4006 | Params.push_back(D); | ||||||||||||
4007 | Invalid = Invalid || !D || D->isInvalidDecl(); | ||||||||||||
4008 | } | ||||||||||||
4009 | |||||||||||||
4010 | // Clean up if we had an error. | ||||||||||||
4011 | if (Invalid) | ||||||||||||
4012 | return nullptr; | ||||||||||||
4013 | |||||||||||||
4014 | Expr *InstRequiresClause = L->getRequiresClause(); | ||||||||||||
4015 | |||||||||||||
4016 | TemplateParameterList *InstL | ||||||||||||
4017 | = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(), | ||||||||||||
4018 | L->getLAngleLoc(), Params, | ||||||||||||
4019 | L->getRAngleLoc(), InstRequiresClause); | ||||||||||||
4020 | return InstL; | ||||||||||||
4021 | } | ||||||||||||
4022 | |||||||||||||
4023 | TemplateParameterList * | ||||||||||||
4024 | Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, | ||||||||||||
4025 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
4026 | TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); | ||||||||||||
4027 | return Instantiator.SubstTemplateParams(Params); | ||||||||||||
4028 | } | ||||||||||||
4029 | |||||||||||||
4030 | /// Instantiate the declaration of a class template partial | ||||||||||||
4031 | /// specialization. | ||||||||||||
4032 | /// | ||||||||||||
4033 | /// \param ClassTemplate the (instantiated) class template that is partially | ||||||||||||
4034 | // specialized by the instantiation of \p PartialSpec. | ||||||||||||
4035 | /// | ||||||||||||
4036 | /// \param PartialSpec the (uninstantiated) class template partial | ||||||||||||
4037 | /// specialization that we are instantiating. | ||||||||||||
4038 | /// | ||||||||||||
4039 | /// \returns The instantiated partial specialization, if successful; otherwise, | ||||||||||||
4040 | /// NULL to indicate an error. | ||||||||||||
4041 | ClassTemplatePartialSpecializationDecl * | ||||||||||||
4042 | TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( | ||||||||||||
4043 | ClassTemplateDecl *ClassTemplate, | ||||||||||||
4044 | ClassTemplatePartialSpecializationDecl *PartialSpec) { | ||||||||||||
4045 | // Create a local instantiation scope for this class template partial | ||||||||||||
4046 | // specialization, which will contain the instantiations of the template | ||||||||||||
4047 | // parameters. | ||||||||||||
4048 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
4049 | |||||||||||||
4050 | // Substitute into the template parameters of the class template partial | ||||||||||||
4051 | // specialization. | ||||||||||||
4052 | TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); | ||||||||||||
4053 | TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | ||||||||||||
4054 | if (!InstParams) | ||||||||||||
4055 | return nullptr; | ||||||||||||
4056 | |||||||||||||
4057 | // Substitute into the template arguments of the class template partial | ||||||||||||
4058 | // specialization. | ||||||||||||
4059 | const ASTTemplateArgumentListInfo *TemplArgInfo | ||||||||||||
4060 | = PartialSpec->getTemplateArgsAsWritten(); | ||||||||||||
4061 | TemplateArgumentListInfo InstTemplateArgs(TemplArgInfo->LAngleLoc, | ||||||||||||
4062 | TemplArgInfo->RAngleLoc); | ||||||||||||
4063 | if (SemaRef.SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs, | ||||||||||||
4064 | InstTemplateArgs)) | ||||||||||||
4065 | return nullptr; | ||||||||||||
4066 | |||||||||||||
4067 | // Check that the template argument list is well-formed for this | ||||||||||||
4068 | // class template. | ||||||||||||
4069 | SmallVector<TemplateArgument, 4> Converted; | ||||||||||||
4070 | if (SemaRef.CheckTemplateArgumentList(ClassTemplate, | ||||||||||||
4071 | PartialSpec->getLocation(), | ||||||||||||
4072 | InstTemplateArgs, | ||||||||||||
4073 | false, | ||||||||||||
4074 | Converted)) | ||||||||||||
4075 | return nullptr; | ||||||||||||
4076 | |||||||||||||
4077 | // Check these arguments are valid for a template partial specialization. | ||||||||||||
4078 | if (SemaRef.CheckTemplatePartialSpecializationArgs( | ||||||||||||
4079 | PartialSpec->getLocation(), ClassTemplate, InstTemplateArgs.size(), | ||||||||||||
4080 | Converted)) | ||||||||||||
4081 | return nullptr; | ||||||||||||
4082 | |||||||||||||
4083 | // Figure out where to insert this class template partial specialization | ||||||||||||
4084 | // in the member template's set of class template partial specializations. | ||||||||||||
4085 | void *InsertPos = nullptr; | ||||||||||||
4086 | ClassTemplateSpecializationDecl *PrevDecl | ||||||||||||
4087 | = ClassTemplate->findPartialSpecialization(Converted, InstParams, | ||||||||||||
4088 | InsertPos); | ||||||||||||
4089 | |||||||||||||
4090 | // Build the canonical type that describes the converted template | ||||||||||||
4091 | // arguments of the class template partial specialization. | ||||||||||||
4092 | QualType CanonType | ||||||||||||
4093 | = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate), | ||||||||||||
4094 | Converted); | ||||||||||||
4095 | |||||||||||||
4096 | // Build the fully-sugared type for this class template | ||||||||||||
4097 | // specialization as the user wrote in the specialization | ||||||||||||
4098 | // itself. This means that we'll pretty-print the type retrieved | ||||||||||||
4099 | // from the specialization's declaration the way that the user | ||||||||||||
4100 | // actually wrote the specialization, rather than formatting the | ||||||||||||
4101 | // name based on the "canonical" representation used to store the | ||||||||||||
4102 | // template arguments in the specialization. | ||||||||||||
4103 | TypeSourceInfo *WrittenTy | ||||||||||||
4104 | = SemaRef.Context.getTemplateSpecializationTypeInfo( | ||||||||||||
4105 | TemplateName(ClassTemplate), | ||||||||||||
4106 | PartialSpec->getLocation(), | ||||||||||||
4107 | InstTemplateArgs, | ||||||||||||
4108 | CanonType); | ||||||||||||
4109 | |||||||||||||
4110 | if (PrevDecl) { | ||||||||||||
4111 | // We've already seen a partial specialization with the same template | ||||||||||||
4112 | // parameters and template arguments. This can happen, for example, when | ||||||||||||
4113 | // substituting the outer template arguments ends up causing two | ||||||||||||
4114 | // class template partial specializations of a member class template | ||||||||||||
4115 | // to have identical forms, e.g., | ||||||||||||
4116 | // | ||||||||||||
4117 | // template<typename T, typename U> | ||||||||||||
4118 | // struct Outer { | ||||||||||||
4119 | // template<typename X, typename Y> struct Inner; | ||||||||||||
4120 | // template<typename Y> struct Inner<T, Y>; | ||||||||||||
4121 | // template<typename Y> struct Inner<U, Y>; | ||||||||||||
4122 | // }; | ||||||||||||
4123 | // | ||||||||||||
4124 | // Outer<int, int> outer; // error: the partial specializations of Inner | ||||||||||||
4125 | // // have the same signature. | ||||||||||||
4126 | SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared) | ||||||||||||
4127 | << WrittenTy->getType(); | ||||||||||||
4128 | SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here) | ||||||||||||
4129 | << SemaRef.Context.getTypeDeclType(PrevDecl); | ||||||||||||
4130 | return nullptr; | ||||||||||||
4131 | } | ||||||||||||
4132 | |||||||||||||
4133 | |||||||||||||
4134 | // Create the class template partial specialization declaration. | ||||||||||||
4135 | ClassTemplatePartialSpecializationDecl *InstPartialSpec = | ||||||||||||
4136 | ClassTemplatePartialSpecializationDecl::Create( | ||||||||||||
4137 | SemaRef.Context, PartialSpec->getTagKind(), Owner, | ||||||||||||
4138 | PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams, | ||||||||||||
4139 | ClassTemplate, Converted, InstTemplateArgs, CanonType, nullptr); | ||||||||||||
4140 | // Substitute the nested name specifier, if any. | ||||||||||||
4141 | if (SubstQualifier(PartialSpec, InstPartialSpec)) | ||||||||||||
4142 | return nullptr; | ||||||||||||
4143 | |||||||||||||
4144 | InstPartialSpec->setInstantiatedFromMember(PartialSpec); | ||||||||||||
4145 | InstPartialSpec->setTypeAsWritten(WrittenTy); | ||||||||||||
4146 | |||||||||||||
4147 | // Check the completed partial specialization. | ||||||||||||
4148 | SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec); | ||||||||||||
4149 | |||||||||||||
4150 | // Add this partial specialization to the set of class template partial | ||||||||||||
4151 | // specializations. | ||||||||||||
4152 | ClassTemplate->AddPartialSpecialization(InstPartialSpec, | ||||||||||||
4153 | /*InsertPos=*/nullptr); | ||||||||||||
4154 | return InstPartialSpec; | ||||||||||||
4155 | } | ||||||||||||
4156 | |||||||||||||
4157 | /// Instantiate the declaration of a variable template partial | ||||||||||||
4158 | /// specialization. | ||||||||||||
4159 | /// | ||||||||||||
4160 | /// \param VarTemplate the (instantiated) variable template that is partially | ||||||||||||
4161 | /// specialized by the instantiation of \p PartialSpec. | ||||||||||||
4162 | /// | ||||||||||||
4163 | /// \param PartialSpec the (uninstantiated) variable template partial | ||||||||||||
4164 | /// specialization that we are instantiating. | ||||||||||||
4165 | /// | ||||||||||||
4166 | /// \returns The instantiated partial specialization, if successful; otherwise, | ||||||||||||
4167 | /// NULL to indicate an error. | ||||||||||||
4168 | VarTemplatePartialSpecializationDecl * | ||||||||||||
4169 | TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( | ||||||||||||
4170 | VarTemplateDecl *VarTemplate, | ||||||||||||
4171 | VarTemplatePartialSpecializationDecl *PartialSpec) { | ||||||||||||
4172 | // Create a local instantiation scope for this variable template partial | ||||||||||||
4173 | // specialization, which will contain the instantiations of the template | ||||||||||||
4174 | // parameters. | ||||||||||||
4175 | LocalInstantiationScope Scope(SemaRef); | ||||||||||||
4176 | |||||||||||||
4177 | // Substitute into the template parameters of the variable template partial | ||||||||||||
4178 | // specialization. | ||||||||||||
4179 | TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); | ||||||||||||
4180 | TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | ||||||||||||
4181 | if (!InstParams) | ||||||||||||
4182 | return nullptr; | ||||||||||||
4183 | |||||||||||||
4184 | // Substitute into the template arguments of the variable template partial | ||||||||||||
4185 | // specialization. | ||||||||||||
4186 | const ASTTemplateArgumentListInfo *TemplArgInfo | ||||||||||||
4187 | = PartialSpec->getTemplateArgsAsWritten(); | ||||||||||||
4188 | TemplateArgumentListInfo InstTemplateArgs(TemplArgInfo->LAngleLoc, | ||||||||||||
4189 | TemplArgInfo->RAngleLoc); | ||||||||||||
4190 | if (SemaRef.SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs, | ||||||||||||
4191 | InstTemplateArgs)) | ||||||||||||
4192 | return nullptr; | ||||||||||||
4193 | |||||||||||||
4194 | // Check that the template argument list is well-formed for this | ||||||||||||
4195 | // class template. | ||||||||||||
4196 | SmallVector<TemplateArgument, 4> Converted; | ||||||||||||
4197 | if (SemaRef.CheckTemplateArgumentList(VarTemplate, PartialSpec->getLocation(), | ||||||||||||
4198 | InstTemplateArgs, false, Converted)) | ||||||||||||
4199 | return nullptr; | ||||||||||||
4200 | |||||||||||||
4201 | // Check these arguments are valid for a template partial specialization. | ||||||||||||
4202 | if (SemaRef.CheckTemplatePartialSpecializationArgs( | ||||||||||||
4203 | PartialSpec->getLocation(), VarTemplate, InstTemplateArgs.size(), | ||||||||||||
4204 | Converted)) | ||||||||||||
4205 | return nullptr; | ||||||||||||
4206 | |||||||||||||
4207 | // Figure out where to insert this variable template partial specialization | ||||||||||||
4208 | // in the member template's set of variable template partial specializations. | ||||||||||||
4209 | void *InsertPos = nullptr; | ||||||||||||
4210 | VarTemplateSpecializationDecl *PrevDecl = | ||||||||||||
4211 | VarTemplate->findPartialSpecialization(Converted, InstParams, InsertPos); | ||||||||||||
4212 | |||||||||||||
4213 | // Build the canonical type that describes the converted template | ||||||||||||
4214 | // arguments of the variable template partial specialization. | ||||||||||||
4215 | QualType CanonType = SemaRef.Context.getTemplateSpecializationType( | ||||||||||||
4216 | TemplateName(VarTemplate), Converted); | ||||||||||||
4217 | |||||||||||||
4218 | // Build the fully-sugared type for this variable template | ||||||||||||
4219 | // specialization as the user wrote in the specialization | ||||||||||||
4220 | // itself. This means that we'll pretty-print the type retrieved | ||||||||||||
4221 | // from the specialization's declaration the way that the user | ||||||||||||
4222 | // actually wrote the specialization, rather than formatting the | ||||||||||||
4223 | // name based on the "canonical" representation used to store the | ||||||||||||
4224 | // template arguments in the specialization. | ||||||||||||
4225 | TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo( | ||||||||||||
4226 | TemplateName(VarTemplate), PartialSpec->getLocation(), InstTemplateArgs, | ||||||||||||
4227 | CanonType); | ||||||||||||
4228 | |||||||||||||
4229 | if (PrevDecl) { | ||||||||||||
4230 | // We've already seen a partial specialization with the same template | ||||||||||||
4231 | // parameters and template arguments. This can happen, for example, when | ||||||||||||
4232 | // substituting the outer template arguments ends up causing two | ||||||||||||
4233 | // variable template partial specializations of a member variable template | ||||||||||||
4234 | // to have identical forms, e.g., | ||||||||||||
4235 | // | ||||||||||||
4236 | // template<typename T, typename U> | ||||||||||||
4237 | // struct Outer { | ||||||||||||
4238 | // template<typename X, typename Y> pair<X,Y> p; | ||||||||||||
4239 | // template<typename Y> pair<T, Y> p; | ||||||||||||
4240 | // template<typename Y> pair<U, Y> p; | ||||||||||||
4241 | // }; | ||||||||||||
4242 | // | ||||||||||||
4243 | // Outer<int, int> outer; // error: the partial specializations of Inner | ||||||||||||
4244 | // // have the same signature. | ||||||||||||
4245 | SemaRef.Diag(PartialSpec->getLocation(), | ||||||||||||
4246 | diag::err_var_partial_spec_redeclared) | ||||||||||||
4247 | << WrittenTy->getType(); | ||||||||||||
4248 | SemaRef.Diag(PrevDecl->getLocation(), | ||||||||||||
4249 | diag::note_var_prev_partial_spec_here); | ||||||||||||
4250 | return nullptr; | ||||||||||||
4251 | } | ||||||||||||
4252 | |||||||||||||
4253 | // Do substitution on the type of the declaration | ||||||||||||
4254 | TypeSourceInfo *DI = SemaRef.SubstType( | ||||||||||||
4255 | PartialSpec->getTypeSourceInfo(), TemplateArgs, | ||||||||||||
4256 | PartialSpec->getTypeSpecStartLoc(), PartialSpec->getDeclName()); | ||||||||||||
4257 | if (!DI) | ||||||||||||
4258 | return nullptr; | ||||||||||||
4259 | |||||||||||||
4260 | if (DI->getType()->isFunctionType()) { | ||||||||||||
4261 | SemaRef.Diag(PartialSpec->getLocation(), | ||||||||||||
4262 | diag::err_variable_instantiates_to_function) | ||||||||||||
4263 | << PartialSpec->isStaticDataMember() << DI->getType(); | ||||||||||||
4264 | return nullptr; | ||||||||||||
4265 | } | ||||||||||||
4266 | |||||||||||||
4267 | // Create the variable template partial specialization declaration. | ||||||||||||
4268 | VarTemplatePartialSpecializationDecl *InstPartialSpec = | ||||||||||||
4269 | VarTemplatePartialSpecializationDecl::Create( | ||||||||||||
4270 | SemaRef.Context, Owner, PartialSpec->getInnerLocStart(), | ||||||||||||
4271 | PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(), | ||||||||||||
4272 | DI, PartialSpec->getStorageClass(), Converted, InstTemplateArgs); | ||||||||||||
4273 | |||||||||||||
4274 | // Substitute the nested name specifier, if any. | ||||||||||||
4275 | if (SubstQualifier(PartialSpec, InstPartialSpec)) | ||||||||||||
4276 | return nullptr; | ||||||||||||
4277 | |||||||||||||
4278 | InstPartialSpec->setInstantiatedFromMember(PartialSpec); | ||||||||||||
4279 | InstPartialSpec->setTypeAsWritten(WrittenTy); | ||||||||||||
4280 | |||||||||||||
4281 | // Check the completed partial specialization. | ||||||||||||
4282 | SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec); | ||||||||||||
4283 | |||||||||||||
4284 | // Add this partial specialization to the set of variable template partial | ||||||||||||
4285 | // specializations. The instantiation of the initializer is not necessary. | ||||||||||||
4286 | VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/nullptr); | ||||||||||||
4287 | |||||||||||||
4288 | SemaRef.BuildVariableInstantiation(InstPartialSpec, PartialSpec, TemplateArgs, | ||||||||||||
4289 | LateAttrs, Owner, StartingScope); | ||||||||||||
4290 | |||||||||||||
4291 | return InstPartialSpec; | ||||||||||||
4292 | } | ||||||||||||
4293 | |||||||||||||
4294 | TypeSourceInfo* | ||||||||||||
4295 | TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, | ||||||||||||
4296 | SmallVectorImpl<ParmVarDecl *> &Params) { | ||||||||||||
4297 | TypeSourceInfo *OldTInfo = D->getTypeSourceInfo(); | ||||||||||||
4298 | assert(OldTInfo && "substituting function without type source info")(static_cast <bool> (OldTInfo && "substituting function without type source info" ) ? void (0) : __assert_fail ("OldTInfo && \"substituting function without type source info\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4298, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4299 | assert(Params.empty() && "parameter vector is non-empty at start")(static_cast <bool> (Params.empty() && "parameter vector is non-empty at start" ) ? void (0) : __assert_fail ("Params.empty() && \"parameter vector is non-empty at start\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4299, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4300 | |||||||||||||
4301 | CXXRecordDecl *ThisContext = nullptr; | ||||||||||||
4302 | Qualifiers ThisTypeQuals; | ||||||||||||
4303 | if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { | ||||||||||||
4304 | ThisContext = cast<CXXRecordDecl>(Owner); | ||||||||||||
4305 | ThisTypeQuals = Method->getMethodQualifiers(); | ||||||||||||
4306 | } | ||||||||||||
4307 | |||||||||||||
4308 | TypeSourceInfo *NewTInfo = SemaRef.SubstFunctionDeclType( | ||||||||||||
4309 | OldTInfo, TemplateArgs, D->getTypeSpecStartLoc(), D->getDeclName(), | ||||||||||||
4310 | ThisContext, ThisTypeQuals, EvaluateConstraints); | ||||||||||||
4311 | if (!NewTInfo) | ||||||||||||
4312 | return nullptr; | ||||||||||||
4313 | |||||||||||||
4314 | TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); | ||||||||||||
4315 | if (FunctionProtoTypeLoc OldProtoLoc = OldTL.getAs<FunctionProtoTypeLoc>()) { | ||||||||||||
4316 | if (NewTInfo != OldTInfo) { | ||||||||||||
4317 | // Get parameters from the new type info. | ||||||||||||
4318 | TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens(); | ||||||||||||
4319 | FunctionProtoTypeLoc NewProtoLoc = NewTL.castAs<FunctionProtoTypeLoc>(); | ||||||||||||
4320 | unsigned NewIdx = 0; | ||||||||||||
4321 | for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumParams(); | ||||||||||||
4322 | OldIdx != NumOldParams; ++OldIdx) { | ||||||||||||
4323 | ParmVarDecl *OldParam = OldProtoLoc.getParam(OldIdx); | ||||||||||||
4324 | if (!OldParam) | ||||||||||||
4325 | return nullptr; | ||||||||||||
4326 | |||||||||||||
4327 | LocalInstantiationScope *Scope = SemaRef.CurrentInstantiationScope; | ||||||||||||
4328 | |||||||||||||
4329 | Optional<unsigned> NumArgumentsInExpansion; | ||||||||||||
4330 | if (OldParam->isParameterPack()) | ||||||||||||
4331 | NumArgumentsInExpansion = | ||||||||||||
4332 | SemaRef.getNumArgumentsInExpansion(OldParam->getType(), | ||||||||||||
4333 | TemplateArgs); | ||||||||||||
4334 | if (!NumArgumentsInExpansion) { | ||||||||||||
4335 | // Simple case: normal parameter, or a parameter pack that's | ||||||||||||
4336 | // instantiated to a (still-dependent) parameter pack. | ||||||||||||
4337 | ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++); | ||||||||||||
4338 | Params.push_back(NewParam); | ||||||||||||
4339 | Scope->InstantiatedLocal(OldParam, NewParam); | ||||||||||||
4340 | } else { | ||||||||||||
4341 | // Parameter pack expansion: make the instantiation an argument pack. | ||||||||||||
4342 | Scope->MakeInstantiatedLocalArgPack(OldParam); | ||||||||||||
4343 | for (unsigned I = 0; I != *NumArgumentsInExpansion; ++I) { | ||||||||||||
4344 | ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++); | ||||||||||||
4345 | Params.push_back(NewParam); | ||||||||||||
4346 | Scope->InstantiatedLocalPackArg(OldParam, NewParam); | ||||||||||||
4347 | } | ||||||||||||
4348 | } | ||||||||||||
4349 | } | ||||||||||||
4350 | } else { | ||||||||||||
4351 | // The function type itself was not dependent and therefore no | ||||||||||||
4352 | // substitution occurred. However, we still need to instantiate | ||||||||||||
4353 | // the function parameters themselves. | ||||||||||||
4354 | const FunctionProtoType *OldProto = | ||||||||||||
4355 | cast<FunctionProtoType>(OldProtoLoc.getType()); | ||||||||||||
4356 | for (unsigned i = 0, i_end = OldProtoLoc.getNumParams(); i != i_end; | ||||||||||||
4357 | ++i) { | ||||||||||||
4358 | ParmVarDecl *OldParam = OldProtoLoc.getParam(i); | ||||||||||||
4359 | if (!OldParam) { | ||||||||||||
4360 | Params.push_back(SemaRef.BuildParmVarDeclForTypedef( | ||||||||||||
4361 | D, D->getLocation(), OldProto->getParamType(i))); | ||||||||||||
4362 | continue; | ||||||||||||
4363 | } | ||||||||||||
4364 | |||||||||||||
4365 | ParmVarDecl *Parm = | ||||||||||||
4366 | cast_or_null<ParmVarDecl>(VisitParmVarDecl(OldParam)); | ||||||||||||
4367 | if (!Parm) | ||||||||||||
4368 | return nullptr; | ||||||||||||
4369 | Params.push_back(Parm); | ||||||||||||
4370 | } | ||||||||||||
4371 | } | ||||||||||||
4372 | } else { | ||||||||||||
4373 | // If the type of this function, after ignoring parentheses, is not | ||||||||||||
4374 | // *directly* a function type, then we're instantiating a function that | ||||||||||||
4375 | // was declared via a typedef or with attributes, e.g., | ||||||||||||
4376 | // | ||||||||||||
4377 | // typedef int functype(int, int); | ||||||||||||
4378 | // functype func; | ||||||||||||
4379 | // int __cdecl meth(int, int); | ||||||||||||
4380 | // | ||||||||||||
4381 | // In this case, we'll just go instantiate the ParmVarDecls that we | ||||||||||||
4382 | // synthesized in the method declaration. | ||||||||||||
4383 | SmallVector<QualType, 4> ParamTypes; | ||||||||||||
4384 | Sema::ExtParameterInfoBuilder ExtParamInfos; | ||||||||||||
4385 | if (SemaRef.SubstParmTypes(D->getLocation(), D->parameters(), nullptr, | ||||||||||||
4386 | TemplateArgs, ParamTypes, &Params, | ||||||||||||
4387 | ExtParamInfos)) | ||||||||||||
4388 | return nullptr; | ||||||||||||
4389 | } | ||||||||||||
4390 | |||||||||||||
4391 | return NewTInfo; | ||||||||||||
4392 | } | ||||||||||||
4393 | |||||||||||||
4394 | /// Introduce the instantiated function parameters into the local | ||||||||||||
4395 | /// instantiation scope, and set the parameter names to those used | ||||||||||||
4396 | /// in the template. | ||||||||||||
4397 | bool Sema::addInstantiatedParametersToScope( | ||||||||||||
4398 | FunctionDecl *Function, const FunctionDecl *PatternDecl, | ||||||||||||
4399 | LocalInstantiationScope &Scope, | ||||||||||||
4400 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
4401 | unsigned FParamIdx = 0; | ||||||||||||
4402 | for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) { | ||||||||||||
4403 | const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I); | ||||||||||||
4404 | if (!PatternParam->isParameterPack()) { | ||||||||||||
4405 | // Simple case: not a parameter pack. | ||||||||||||
4406 | assert(FParamIdx < Function->getNumParams())(static_cast <bool> (FParamIdx < Function->getNumParams ()) ? void (0) : __assert_fail ("FParamIdx < Function->getNumParams()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4406, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4407 | ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); | ||||||||||||
4408 | FunctionParam->setDeclName(PatternParam->getDeclName()); | ||||||||||||
4409 | // If the parameter's type is not dependent, update it to match the type | ||||||||||||
4410 | // in the pattern. They can differ in top-level cv-qualifiers, and we want | ||||||||||||
4411 | // the pattern's type here. If the type is dependent, they can't differ, | ||||||||||||
4412 | // per core issue 1668. Substitute into the type from the pattern, in case | ||||||||||||
4413 | // it's instantiation-dependent. | ||||||||||||
4414 | // FIXME: Updating the type to work around this is at best fragile. | ||||||||||||
4415 | if (!PatternDecl->getType()->isDependentType()) { | ||||||||||||
4416 | QualType T = SubstType(PatternParam->getType(), TemplateArgs, | ||||||||||||
4417 | FunctionParam->getLocation(), | ||||||||||||
4418 | FunctionParam->getDeclName()); | ||||||||||||
4419 | if (T.isNull()) | ||||||||||||
4420 | return true; | ||||||||||||
4421 | FunctionParam->setType(T); | ||||||||||||
4422 | } | ||||||||||||
4423 | |||||||||||||
4424 | Scope.InstantiatedLocal(PatternParam, FunctionParam); | ||||||||||||
4425 | ++FParamIdx; | ||||||||||||
4426 | continue; | ||||||||||||
4427 | } | ||||||||||||
4428 | |||||||||||||
4429 | // Expand the parameter pack. | ||||||||||||
4430 | Scope.MakeInstantiatedLocalArgPack(PatternParam); | ||||||||||||
4431 | Optional<unsigned> NumArgumentsInExpansion = | ||||||||||||
4432 | getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs); | ||||||||||||
4433 | if (NumArgumentsInExpansion) { | ||||||||||||
4434 | QualType PatternType = | ||||||||||||
4435 | PatternParam->getType()->castAs<PackExpansionType>()->getPattern(); | ||||||||||||
4436 | for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) { | ||||||||||||
4437 | ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); | ||||||||||||
4438 | FunctionParam->setDeclName(PatternParam->getDeclName()); | ||||||||||||
4439 | if (!PatternDecl->getType()->isDependentType()) { | ||||||||||||
4440 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, Arg); | ||||||||||||
4441 | QualType T = | ||||||||||||
4442 | SubstType(PatternType, TemplateArgs, FunctionParam->getLocation(), | ||||||||||||
4443 | FunctionParam->getDeclName()); | ||||||||||||
4444 | if (T.isNull()) | ||||||||||||
4445 | return true; | ||||||||||||
4446 | FunctionParam->setType(T); | ||||||||||||
4447 | } | ||||||||||||
4448 | |||||||||||||
4449 | Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); | ||||||||||||
4450 | ++FParamIdx; | ||||||||||||
4451 | } | ||||||||||||
4452 | } | ||||||||||||
4453 | } | ||||||||||||
4454 | |||||||||||||
4455 | return false; | ||||||||||||
4456 | } | ||||||||||||
4457 | |||||||||||||
4458 | bool Sema::InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, | ||||||||||||
4459 | ParmVarDecl *Param) { | ||||||||||||
4460 | assert(Param->hasUninstantiatedDefaultArg())(static_cast <bool> (Param->hasUninstantiatedDefaultArg ()) ? void (0) : __assert_fail ("Param->hasUninstantiatedDefaultArg()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4460, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4461 | Expr *UninstExpr = Param->getUninstantiatedDefaultArg(); | ||||||||||||
4462 | |||||||||||||
4463 | EnterExpressionEvaluationContext EvalContext( | ||||||||||||
4464 | *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param); | ||||||||||||
4465 | |||||||||||||
4466 | // Instantiate the expression. | ||||||||||||
4467 | // | ||||||||||||
4468 | // FIXME: Pass in a correct Pattern argument, otherwise | ||||||||||||
4469 | // getTemplateInstantiationArgs uses the lexical context of FD, e.g. | ||||||||||||
4470 | // | ||||||||||||
4471 | // template<typename T> | ||||||||||||
4472 | // struct A { | ||||||||||||
4473 | // static int FooImpl(); | ||||||||||||
4474 | // | ||||||||||||
4475 | // template<typename Tp> | ||||||||||||
4476 | // // bug: default argument A<T>::FooImpl() is evaluated with 2-level | ||||||||||||
4477 | // // template argument list [[T], [Tp]], should be [[Tp]]. | ||||||||||||
4478 | // friend A<Tp> Foo(int a); | ||||||||||||
4479 | // }; | ||||||||||||
4480 | // | ||||||||||||
4481 | // template<typename T> | ||||||||||||
4482 | // A<T> Foo(int a = A<T>::FooImpl()); | ||||||||||||
4483 | MultiLevelTemplateArgumentList TemplateArgs | ||||||||||||
4484 | = getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true); | ||||||||||||
4485 | |||||||||||||
4486 | InstantiatingTemplate Inst(*this, CallLoc, Param, | ||||||||||||
4487 | TemplateArgs.getInnermost()); | ||||||||||||
4488 | if (Inst.isInvalid()) | ||||||||||||
4489 | return true; | ||||||||||||
4490 | if (Inst.isAlreadyInstantiating()) { | ||||||||||||
4491 | Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD; | ||||||||||||
4492 | Param->setInvalidDecl(); | ||||||||||||
4493 | return true; | ||||||||||||
4494 | } | ||||||||||||
4495 | |||||||||||||
4496 | ExprResult Result; | ||||||||||||
4497 | { | ||||||||||||
4498 | // C++ [dcl.fct.default]p5: | ||||||||||||
4499 | // The names in the [default argument] expression are bound, and | ||||||||||||
4500 | // the semantic constraints are checked, at the point where the | ||||||||||||
4501 | // default argument expression appears. | ||||||||||||
4502 | ContextRAII SavedContext(*this, FD); | ||||||||||||
4503 | LocalInstantiationScope Local(*this); | ||||||||||||
4504 | |||||||||||||
4505 | FunctionDecl *Pattern = FD->getTemplateInstantiationPattern( | ||||||||||||
4506 | /*ForDefinition*/ false); | ||||||||||||
4507 | if (addInstantiatedParametersToScope(FD, Pattern, Local, TemplateArgs)) | ||||||||||||
4508 | return true; | ||||||||||||
4509 | |||||||||||||
4510 | runWithSufficientStackSpace(CallLoc, [&] { | ||||||||||||
4511 | Result = SubstInitializer(UninstExpr, TemplateArgs, | ||||||||||||
4512 | /*DirectInit*/false); | ||||||||||||
4513 | }); | ||||||||||||
4514 | } | ||||||||||||
4515 | if (Result.isInvalid()) | ||||||||||||
4516 | return true; | ||||||||||||
4517 | |||||||||||||
4518 | // Check the expression as an initializer for the parameter. | ||||||||||||
4519 | InitializedEntity Entity | ||||||||||||
4520 | = InitializedEntity::InitializeParameter(Context, Param); | ||||||||||||
4521 | InitializationKind Kind = InitializationKind::CreateCopy( | ||||||||||||
4522 | Param->getLocation(), | ||||||||||||
4523 | /*FIXME:EqualLoc*/ UninstExpr->getBeginLoc()); | ||||||||||||
4524 | Expr *ResultE = Result.getAs<Expr>(); | ||||||||||||
4525 | |||||||||||||
4526 | InitializationSequence InitSeq(*this, Entity, Kind, ResultE); | ||||||||||||
4527 | Result = InitSeq.Perform(*this, Entity, Kind, ResultE); | ||||||||||||
4528 | if (Result.isInvalid()) | ||||||||||||
4529 | return true; | ||||||||||||
4530 | |||||||||||||
4531 | Result = | ||||||||||||
4532 | ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(), | ||||||||||||
4533 | /*DiscardedValue*/ false); | ||||||||||||
4534 | if (Result.isInvalid()) | ||||||||||||
4535 | return true; | ||||||||||||
4536 | |||||||||||||
4537 | // Remember the instantiated default argument. | ||||||||||||
4538 | Param->setDefaultArg(Result.getAs<Expr>()); | ||||||||||||
4539 | if (ASTMutationListener *L = getASTMutationListener()) | ||||||||||||
4540 | L->DefaultArgumentInstantiated(Param); | ||||||||||||
4541 | |||||||||||||
4542 | return false; | ||||||||||||
4543 | } | ||||||||||||
4544 | |||||||||||||
4545 | void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, | ||||||||||||
4546 | FunctionDecl *Decl) { | ||||||||||||
4547 | const FunctionProtoType *Proto = Decl->getType()->castAs<FunctionProtoType>(); | ||||||||||||
4548 | if (Proto->getExceptionSpecType() != EST_Uninstantiated) | ||||||||||||
4549 | return; | ||||||||||||
4550 | |||||||||||||
4551 | InstantiatingTemplate Inst(*this, PointOfInstantiation, Decl, | ||||||||||||
4552 | InstantiatingTemplate::ExceptionSpecification()); | ||||||||||||
4553 | if (Inst.isInvalid()) { | ||||||||||||
4554 | // We hit the instantiation depth limit. Clear the exception specification | ||||||||||||
4555 | // so that our callers don't have to cope with EST_Uninstantiated. | ||||||||||||
4556 | UpdateExceptionSpec(Decl, EST_None); | ||||||||||||
4557 | return; | ||||||||||||
4558 | } | ||||||||||||
4559 | if (Inst.isAlreadyInstantiating()) { | ||||||||||||
4560 | // This exception specification indirectly depends on itself. Reject. | ||||||||||||
4561 | // FIXME: Corresponding rule in the standard? | ||||||||||||
4562 | Diag(PointOfInstantiation, diag::err_exception_spec_cycle) << Decl; | ||||||||||||
4563 | UpdateExceptionSpec(Decl, EST_None); | ||||||||||||
4564 | return; | ||||||||||||
4565 | } | ||||||||||||
4566 | |||||||||||||
4567 | // Enter the scope of this instantiation. We don't use | ||||||||||||
4568 | // PushDeclContext because we don't have a scope. | ||||||||||||
4569 | Sema::ContextRAII savedContext(*this, Decl); | ||||||||||||
4570 | LocalInstantiationScope Scope(*this); | ||||||||||||
4571 | |||||||||||||
4572 | MultiLevelTemplateArgumentList TemplateArgs = | ||||||||||||
4573 | getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true); | ||||||||||||
4574 | |||||||||||||
4575 | // FIXME: We can't use getTemplateInstantiationPattern(false) in general | ||||||||||||
4576 | // here, because for a non-defining friend declaration in a class template, | ||||||||||||
4577 | // we don't store enough information to map back to the friend declaration in | ||||||||||||
4578 | // the template. | ||||||||||||
4579 | FunctionDecl *Template = Proto->getExceptionSpecTemplate(); | ||||||||||||
4580 | if (addInstantiatedParametersToScope(Decl, Template, Scope, TemplateArgs)) { | ||||||||||||
4581 | UpdateExceptionSpec(Decl, EST_None); | ||||||||||||
4582 | return; | ||||||||||||
4583 | } | ||||||||||||
4584 | |||||||||||||
4585 | SubstExceptionSpec(Decl, Template->getType()->castAs<FunctionProtoType>(), | ||||||||||||
4586 | TemplateArgs); | ||||||||||||
4587 | } | ||||||||||||
4588 | |||||||||||||
4589 | /// Initializes the common fields of an instantiation function | ||||||||||||
4590 | /// declaration (New) from the corresponding fields of its template (Tmpl). | ||||||||||||
4591 | /// | ||||||||||||
4592 | /// \returns true if there was an error | ||||||||||||
4593 | bool | ||||||||||||
4594 | TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, | ||||||||||||
4595 | FunctionDecl *Tmpl) { | ||||||||||||
4596 | New->setImplicit(Tmpl->isImplicit()); | ||||||||||||
4597 | |||||||||||||
4598 | // Forward the mangling number from the template to the instantiated decl. | ||||||||||||
4599 | SemaRef.Context.setManglingNumber(New, | ||||||||||||
4600 | SemaRef.Context.getManglingNumber(Tmpl)); | ||||||||||||
4601 | |||||||||||||
4602 | // If we are performing substituting explicitly-specified template arguments | ||||||||||||
4603 | // or deduced template arguments into a function template and we reach this | ||||||||||||
4604 | // point, we are now past the point where SFINAE applies and have committed | ||||||||||||
4605 | // to keeping the new function template specialization. We therefore | ||||||||||||
4606 | // convert the active template instantiation for the function template | ||||||||||||
4607 | // into a template instantiation for this specific function template | ||||||||||||
4608 | // specialization, which is not a SFINAE context, so that we diagnose any | ||||||||||||
4609 | // further errors in the declaration itself. | ||||||||||||
4610 | // | ||||||||||||
4611 | // FIXME: This is a hack. | ||||||||||||
4612 | typedef Sema::CodeSynthesisContext ActiveInstType; | ||||||||||||
4613 | ActiveInstType &ActiveInst = SemaRef.CodeSynthesisContexts.back(); | ||||||||||||
4614 | if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution || | ||||||||||||
4615 | ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) { | ||||||||||||
4616 | if (FunctionTemplateDecl *FunTmpl | ||||||||||||
4617 | = dyn_cast<FunctionTemplateDecl>(ActiveInst.Entity)) { | ||||||||||||
4618 | assert(FunTmpl->getTemplatedDecl() == Tmpl &&(static_cast <bool> (FunTmpl->getTemplatedDecl() == Tmpl && "Deduction from the wrong function template?") ? void (0) : __assert_fail ("FunTmpl->getTemplatedDecl() == Tmpl && \"Deduction from the wrong function template?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4619, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
4619 | "Deduction from the wrong function template?")(static_cast <bool> (FunTmpl->getTemplatedDecl() == Tmpl && "Deduction from the wrong function template?") ? void (0) : __assert_fail ("FunTmpl->getTemplatedDecl() == Tmpl && \"Deduction from the wrong function template?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4619, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4620 | (void) FunTmpl; | ||||||||||||
4621 | SemaRef.InstantiatingSpecializations.erase( | ||||||||||||
4622 | {ActiveInst.Entity->getCanonicalDecl(), ActiveInst.Kind}); | ||||||||||||
4623 | atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst); | ||||||||||||
4624 | ActiveInst.Kind = ActiveInstType::TemplateInstantiation; | ||||||||||||
4625 | ActiveInst.Entity = New; | ||||||||||||
4626 | atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst); | ||||||||||||
4627 | } | ||||||||||||
4628 | } | ||||||||||||
4629 | |||||||||||||
4630 | const FunctionProtoType *Proto = Tmpl->getType()->getAs<FunctionProtoType>(); | ||||||||||||
4631 | assert(Proto && "Function template without prototype?")(static_cast <bool> (Proto && "Function template without prototype?" ) ? void (0) : __assert_fail ("Proto && \"Function template without prototype?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4631, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4632 | |||||||||||||
4633 | if (Proto->hasExceptionSpec() || Proto->getNoReturnAttr()) { | ||||||||||||
4634 | FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); | ||||||||||||
4635 | |||||||||||||
4636 | // DR1330: In C++11, defer instantiation of a non-trivial | ||||||||||||
4637 | // exception specification. | ||||||||||||
4638 | // DR1484: Local classes and their members are instantiated along with the | ||||||||||||
4639 | // containing function. | ||||||||||||
4640 | if (SemaRef.getLangOpts().CPlusPlus11 && | ||||||||||||
4641 | EPI.ExceptionSpec.Type != EST_None && | ||||||||||||
4642 | EPI.ExceptionSpec.Type != EST_DynamicNone && | ||||||||||||
4643 | EPI.ExceptionSpec.Type != EST_BasicNoexcept && | ||||||||||||
4644 | !Tmpl->isInLocalScopeForInstantiation()) { | ||||||||||||
4645 | FunctionDecl *ExceptionSpecTemplate = Tmpl; | ||||||||||||
4646 | if (EPI.ExceptionSpec.Type == EST_Uninstantiated) | ||||||||||||
4647 | ExceptionSpecTemplate = EPI.ExceptionSpec.SourceTemplate; | ||||||||||||
4648 | ExceptionSpecificationType NewEST = EST_Uninstantiated; | ||||||||||||
4649 | if (EPI.ExceptionSpec.Type == EST_Unevaluated) | ||||||||||||
4650 | NewEST = EST_Unevaluated; | ||||||||||||
4651 | |||||||||||||
4652 | // Mark the function has having an uninstantiated exception specification. | ||||||||||||
4653 | const FunctionProtoType *NewProto | ||||||||||||
4654 | = New->getType()->getAs<FunctionProtoType>(); | ||||||||||||
4655 | assert(NewProto && "Template instantiation without function prototype?")(static_cast <bool> (NewProto && "Template instantiation without function prototype?" ) ? void (0) : __assert_fail ("NewProto && \"Template instantiation without function prototype?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4655, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4656 | EPI = NewProto->getExtProtoInfo(); | ||||||||||||
4657 | EPI.ExceptionSpec.Type = NewEST; | ||||||||||||
4658 | EPI.ExceptionSpec.SourceDecl = New; | ||||||||||||
4659 | EPI.ExceptionSpec.SourceTemplate = ExceptionSpecTemplate; | ||||||||||||
4660 | New->setType(SemaRef.Context.getFunctionType( | ||||||||||||
4661 | NewProto->getReturnType(), NewProto->getParamTypes(), EPI)); | ||||||||||||
4662 | } else { | ||||||||||||
4663 | Sema::ContextRAII SwitchContext(SemaRef, New); | ||||||||||||
4664 | SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs); | ||||||||||||
4665 | } | ||||||||||||
4666 | } | ||||||||||||
4667 | |||||||||||||
4668 | // Get the definition. Leaves the variable unchanged if undefined. | ||||||||||||
4669 | const FunctionDecl *Definition = Tmpl; | ||||||||||||
4670 | Tmpl->isDefined(Definition); | ||||||||||||
4671 | |||||||||||||
4672 | SemaRef.InstantiateAttrs(TemplateArgs, Definition, New, | ||||||||||||
4673 | LateAttrs, StartingScope); | ||||||||||||
4674 | |||||||||||||
4675 | return false; | ||||||||||||
4676 | } | ||||||||||||
4677 | |||||||||||||
4678 | /// Initializes common fields of an instantiated method | ||||||||||||
4679 | /// declaration (New) from the corresponding fields of its template | ||||||||||||
4680 | /// (Tmpl). | ||||||||||||
4681 | /// | ||||||||||||
4682 | /// \returns true if there was an error | ||||||||||||
4683 | bool | ||||||||||||
4684 | TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, | ||||||||||||
4685 | CXXMethodDecl *Tmpl) { | ||||||||||||
4686 | if (InitFunctionInstantiation(New, Tmpl)) | ||||||||||||
4687 | return true; | ||||||||||||
4688 | |||||||||||||
4689 | if (isa<CXXDestructorDecl>(New) && SemaRef.getLangOpts().CPlusPlus11) | ||||||||||||
4690 | SemaRef.AdjustDestructorExceptionSpec(cast<CXXDestructorDecl>(New)); | ||||||||||||
4691 | |||||||||||||
4692 | New->setAccess(Tmpl->getAccess()); | ||||||||||||
4693 | if (Tmpl->isVirtualAsWritten()) | ||||||||||||
4694 | New->setVirtualAsWritten(true); | ||||||||||||
4695 | |||||||||||||
4696 | // FIXME: New needs a pointer to Tmpl | ||||||||||||
4697 | return false; | ||||||||||||
4698 | } | ||||||||||||
4699 | |||||||||||||
4700 | bool TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New, | ||||||||||||
4701 | FunctionDecl *Tmpl) { | ||||||||||||
4702 | // Transfer across any unqualified lookups. | ||||||||||||
4703 | if (auto *DFI = Tmpl->getDefaultedFunctionInfo()) { | ||||||||||||
4704 | SmallVector<DeclAccessPair, 32> Lookups; | ||||||||||||
4705 | Lookups.reserve(DFI->getUnqualifiedLookups().size()); | ||||||||||||
4706 | bool AnyChanged = false; | ||||||||||||
4707 | for (DeclAccessPair DA : DFI->getUnqualifiedLookups()) { | ||||||||||||
4708 | NamedDecl *D = SemaRef.FindInstantiatedDecl(New->getLocation(), | ||||||||||||
4709 | DA.getDecl(), TemplateArgs); | ||||||||||||
4710 | if (!D) | ||||||||||||
4711 | return true; | ||||||||||||
4712 | AnyChanged |= (D != DA.getDecl()); | ||||||||||||
4713 | Lookups.push_back(DeclAccessPair::make(D, DA.getAccess())); | ||||||||||||
4714 | } | ||||||||||||
4715 | |||||||||||||
4716 | // It's unlikely that substitution will change any declarations. Don't | ||||||||||||
4717 | // store an unnecessary copy in that case. | ||||||||||||
4718 | New->setDefaultedFunctionInfo( | ||||||||||||
4719 | AnyChanged ? FunctionDecl::DefaultedFunctionInfo::Create( | ||||||||||||
4720 | SemaRef.Context, Lookups) | ||||||||||||
4721 | : DFI); | ||||||||||||
4722 | } | ||||||||||||
4723 | |||||||||||||
4724 | SemaRef.SetDeclDefaulted(New, Tmpl->getLocation()); | ||||||||||||
4725 | return false; | ||||||||||||
4726 | } | ||||||||||||
4727 | |||||||||||||
4728 | /// Instantiate (or find existing instantiation of) a function template with a | ||||||||||||
4729 | /// given set of template arguments. | ||||||||||||
4730 | /// | ||||||||||||
4731 | /// Usually this should not be used, and template argument deduction should be | ||||||||||||
4732 | /// used in its place. | ||||||||||||
4733 | FunctionDecl * | ||||||||||||
4734 | Sema::InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, | ||||||||||||
4735 | const TemplateArgumentList *Args, | ||||||||||||
4736 | SourceLocation Loc) { | ||||||||||||
4737 | FunctionDecl *FD = FTD->getTemplatedDecl(); | ||||||||||||
4738 | |||||||||||||
4739 | sema::TemplateDeductionInfo Info(Loc); | ||||||||||||
4740 | InstantiatingTemplate Inst( | ||||||||||||
4741 | *this, Loc, FTD, Args->asArray(), | ||||||||||||
4742 | CodeSynthesisContext::ExplicitTemplateArgumentSubstitution, Info); | ||||||||||||
4743 | if (Inst.isInvalid()) | ||||||||||||
4744 | return nullptr; | ||||||||||||
4745 | |||||||||||||
4746 | ContextRAII SavedContext(*this, FD); | ||||||||||||
4747 | MultiLevelTemplateArgumentList MArgs(*Args); | ||||||||||||
4748 | |||||||||||||
4749 | return cast_or_null<FunctionDecl>(SubstDecl(FD, FD->getParent(), MArgs)); | ||||||||||||
4750 | } | ||||||||||||
4751 | |||||||||||||
4752 | /// Instantiate the definition of the given function from its | ||||||||||||
4753 | /// template. | ||||||||||||
4754 | /// | ||||||||||||
4755 | /// \param PointOfInstantiation the point at which the instantiation was | ||||||||||||
4756 | /// required. Note that this is not precisely a "point of instantiation" | ||||||||||||
4757 | /// for the function, but it's close. | ||||||||||||
4758 | /// | ||||||||||||
4759 | /// \param Function the already-instantiated declaration of a | ||||||||||||
4760 | /// function template specialization or member function of a class template | ||||||||||||
4761 | /// specialization. | ||||||||||||
4762 | /// | ||||||||||||
4763 | /// \param Recursive if true, recursively instantiates any functions that | ||||||||||||
4764 | /// are required by this instantiation. | ||||||||||||
4765 | /// | ||||||||||||
4766 | /// \param DefinitionRequired if true, then we are performing an explicit | ||||||||||||
4767 | /// instantiation where the body of the function is required. Complain if | ||||||||||||
4768 | /// there is no such body. | ||||||||||||
4769 | void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, | ||||||||||||
4770 | FunctionDecl *Function, | ||||||||||||
4771 | bool Recursive, | ||||||||||||
4772 | bool DefinitionRequired, | ||||||||||||
4773 | bool AtEndOfTU) { | ||||||||||||
4774 | if (Function->isInvalidDecl() || isa<CXXDeductionGuideDecl>(Function)) | ||||||||||||
4775 | return; | ||||||||||||
4776 | |||||||||||||
4777 | // Never instantiate an explicit specialization except if it is a class scope | ||||||||||||
4778 | // explicit specialization. | ||||||||||||
4779 | TemplateSpecializationKind TSK = | ||||||||||||
4780 | Function->getTemplateSpecializationKindForInstantiation(); | ||||||||||||
4781 | if (TSK == TSK_ExplicitSpecialization) | ||||||||||||
4782 | return; | ||||||||||||
4783 | |||||||||||||
4784 | // Never implicitly instantiate a builtin; we don't actually need a function | ||||||||||||
4785 | // body. | ||||||||||||
4786 | if (Function->getBuiltinID() && TSK == TSK_ImplicitInstantiation && | ||||||||||||
4787 | !DefinitionRequired) | ||||||||||||
4788 | return; | ||||||||||||
4789 | |||||||||||||
4790 | // Don't instantiate a definition if we already have one. | ||||||||||||
4791 | const FunctionDecl *ExistingDefn = nullptr; | ||||||||||||
4792 | if (Function->isDefined(ExistingDefn, | ||||||||||||
4793 | /*CheckForPendingFriendDefinition=*/true)) { | ||||||||||||
4794 | if (ExistingDefn->isThisDeclarationADefinition()) | ||||||||||||
4795 | return; | ||||||||||||
4796 | |||||||||||||
4797 | // If we're asked to instantiate a function whose body comes from an | ||||||||||||
4798 | // instantiated friend declaration, attach the instantiated body to the | ||||||||||||
4799 | // corresponding declaration of the function. | ||||||||||||
4800 | assert(ExistingDefn->isThisDeclarationInstantiatedFromAFriendDefinition())(static_cast <bool> (ExistingDefn->isThisDeclarationInstantiatedFromAFriendDefinition ()) ? void (0) : __assert_fail ("ExistingDefn->isThisDeclarationInstantiatedFromAFriendDefinition()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4800, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4801 | Function = const_cast<FunctionDecl*>(ExistingDefn); | ||||||||||||
4802 | } | ||||||||||||
4803 | |||||||||||||
4804 | // Find the function body that we'll be substituting. | ||||||||||||
4805 | const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern(); | ||||||||||||
4806 | assert(PatternDecl && "instantiating a non-template")(static_cast <bool> (PatternDecl && "instantiating a non-template" ) ? void (0) : __assert_fail ("PatternDecl && \"instantiating a non-template\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4806, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4807 | |||||||||||||
4808 | const FunctionDecl *PatternDef = PatternDecl->getDefinition(); | ||||||||||||
4809 | Stmt *Pattern = nullptr; | ||||||||||||
4810 | if (PatternDef) { | ||||||||||||
4811 | Pattern = PatternDef->getBody(PatternDef); | ||||||||||||
4812 | PatternDecl = PatternDef; | ||||||||||||
4813 | if (PatternDef->willHaveBody()) | ||||||||||||
4814 | PatternDef = nullptr; | ||||||||||||
4815 | } | ||||||||||||
4816 | |||||||||||||
4817 | // FIXME: We need to track the instantiation stack in order to know which | ||||||||||||
4818 | // definitions should be visible within this instantiation. | ||||||||||||
4819 | if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function, | ||||||||||||
4820 | Function->getInstantiatedFromMemberFunction(), | ||||||||||||
4821 | PatternDecl, PatternDef, TSK, | ||||||||||||
4822 | /*Complain*/DefinitionRequired)) { | ||||||||||||
4823 | if (DefinitionRequired) | ||||||||||||
4824 | Function->setInvalidDecl(); | ||||||||||||
4825 | else if (TSK == TSK_ExplicitInstantiationDefinition || | ||||||||||||
4826 | (Function->isConstexpr() && !Recursive)) { | ||||||||||||
4827 | // Try again at the end of the translation unit (at which point a | ||||||||||||
4828 | // definition will be required). | ||||||||||||
4829 | assert(!Recursive)(static_cast <bool> (!Recursive) ? void (0) : __assert_fail ("!Recursive", "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp" , 4829, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4830 | Function->setInstantiationIsPending(true); | ||||||||||||
4831 | PendingInstantiations.push_back( | ||||||||||||
4832 | std::make_pair(Function, PointOfInstantiation)); | ||||||||||||
4833 | } else if (TSK == TSK_ImplicitInstantiation) { | ||||||||||||
4834 | if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() && | ||||||||||||
4835 | !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) { | ||||||||||||
4836 | Diag(PointOfInstantiation, diag::warn_func_template_missing) | ||||||||||||
4837 | << Function; | ||||||||||||
4838 | Diag(PatternDecl->getLocation(), diag::note_forward_template_decl); | ||||||||||||
4839 | if (getLangOpts().CPlusPlus11) | ||||||||||||
4840 | Diag(PointOfInstantiation, diag::note_inst_declaration_hint) | ||||||||||||
4841 | << Function; | ||||||||||||
4842 | } | ||||||||||||
4843 | } | ||||||||||||
4844 | |||||||||||||
4845 | return; | ||||||||||||
4846 | } | ||||||||||||
4847 | |||||||||||||
4848 | // Postpone late parsed template instantiations. | ||||||||||||
4849 | if (PatternDecl->isLateTemplateParsed() && | ||||||||||||
4850 | !LateTemplateParser) { | ||||||||||||
4851 | Function->setInstantiationIsPending(true); | ||||||||||||
4852 | LateParsedInstantiations.push_back( | ||||||||||||
4853 | std::make_pair(Function, PointOfInstantiation)); | ||||||||||||
4854 | return; | ||||||||||||
4855 | } | ||||||||||||
4856 | |||||||||||||
4857 | llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() { | ||||||||||||
4858 | std::string Name; | ||||||||||||
4859 | llvm::raw_string_ostream OS(Name); | ||||||||||||
4860 | Function->getNameForDiagnostic(OS, getPrintingPolicy(), | ||||||||||||
4861 | /*Qualified=*/true); | ||||||||||||
4862 | return Name; | ||||||||||||
4863 | }); | ||||||||||||
4864 | |||||||||||||
4865 | // If we're performing recursive template instantiation, create our own | ||||||||||||
4866 | // queue of pending implicit instantiations that we will instantiate later, | ||||||||||||
4867 | // while we're still within our own instantiation context. | ||||||||||||
4868 | // This has to happen before LateTemplateParser below is called, so that | ||||||||||||
4869 | // it marks vtables used in late parsed templates as used. | ||||||||||||
4870 | GlobalEagerInstantiationScope GlobalInstantiations(*this, | ||||||||||||
4871 | /*Enabled=*/Recursive); | ||||||||||||
4872 | LocalEagerInstantiationScope LocalInstantiations(*this); | ||||||||||||
4873 | |||||||||||||
4874 | // Call the LateTemplateParser callback if there is a need to late parse | ||||||||||||
4875 | // a templated function definition. | ||||||||||||
4876 | if (!Pattern && PatternDecl->isLateTemplateParsed() && | ||||||||||||
4877 | LateTemplateParser) { | ||||||||||||
4878 | // FIXME: Optimize to allow individual templates to be deserialized. | ||||||||||||
4879 | if (PatternDecl->isFromASTFile()) | ||||||||||||
4880 | ExternalSource->ReadLateParsedTemplates(LateParsedTemplateMap); | ||||||||||||
4881 | |||||||||||||
4882 | auto LPTIter = LateParsedTemplateMap.find(PatternDecl); | ||||||||||||
4883 | assert(LPTIter != LateParsedTemplateMap.end() &&(static_cast <bool> (LPTIter != LateParsedTemplateMap.end () && "missing LateParsedTemplate") ? void (0) : __assert_fail ("LPTIter != LateParsedTemplateMap.end() && \"missing LateParsedTemplate\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4884, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
4884 | "missing LateParsedTemplate")(static_cast <bool> (LPTIter != LateParsedTemplateMap.end () && "missing LateParsedTemplate") ? void (0) : __assert_fail ("LPTIter != LateParsedTemplateMap.end() && \"missing LateParsedTemplate\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4884, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4885 | LateTemplateParser(OpaqueParser, *LPTIter->second); | ||||||||||||
4886 | Pattern = PatternDecl->getBody(PatternDecl); | ||||||||||||
4887 | } | ||||||||||||
4888 | |||||||||||||
4889 | // Note, we should never try to instantiate a deleted function template. | ||||||||||||
4890 | assert((Pattern || PatternDecl->isDefaulted() ||(static_cast <bool> ((Pattern || PatternDecl->isDefaulted () || PatternDecl->hasSkippedBody()) && "unexpected kind of function template definition" ) ? void (0) : __assert_fail ("(Pattern || PatternDecl->isDefaulted() || PatternDecl->hasSkippedBody()) && \"unexpected kind of function template definition\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4892, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
4891 | PatternDecl->hasSkippedBody()) &&(static_cast <bool> ((Pattern || PatternDecl->isDefaulted () || PatternDecl->hasSkippedBody()) && "unexpected kind of function template definition" ) ? void (0) : __assert_fail ("(Pattern || PatternDecl->isDefaulted() || PatternDecl->hasSkippedBody()) && \"unexpected kind of function template definition\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4892, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
4892 | "unexpected kind of function template definition")(static_cast <bool> ((Pattern || PatternDecl->isDefaulted () || PatternDecl->hasSkippedBody()) && "unexpected kind of function template definition" ) ? void (0) : __assert_fail ("(Pattern || PatternDecl->isDefaulted() || PatternDecl->hasSkippedBody()) && \"unexpected kind of function template definition\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4892, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4893 | |||||||||||||
4894 | // C++1y [temp.explicit]p10: | ||||||||||||
4895 | // Except for inline functions, declarations with types deduced from their | ||||||||||||
4896 | // initializer or return value, and class template specializations, other | ||||||||||||
4897 | // explicit instantiation declarations have the effect of suppressing the | ||||||||||||
4898 | // implicit instantiation of the entity to which they refer. | ||||||||||||
4899 | if (TSK == TSK_ExplicitInstantiationDeclaration && | ||||||||||||
4900 | !PatternDecl->isInlined() && | ||||||||||||
4901 | !PatternDecl->getReturnType()->getContainedAutoType()) | ||||||||||||
4902 | return; | ||||||||||||
4903 | |||||||||||||
4904 | if (PatternDecl->isInlined()) { | ||||||||||||
4905 | // Function, and all later redeclarations of it (from imported modules, | ||||||||||||
4906 | // for instance), are now implicitly inline. | ||||||||||||
4907 | for (auto *D = Function->getMostRecentDecl(); /**/; | ||||||||||||
4908 | D = D->getPreviousDecl()) { | ||||||||||||
4909 | D->setImplicitlyInline(); | ||||||||||||
4910 | if (D == Function) | ||||||||||||
4911 | break; | ||||||||||||
4912 | } | ||||||||||||
4913 | } | ||||||||||||
4914 | |||||||||||||
4915 | InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); | ||||||||||||
4916 | if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) | ||||||||||||
4917 | return; | ||||||||||||
4918 | PrettyDeclStackTraceEntry CrashInfo(Context, Function, SourceLocation(), | ||||||||||||
4919 | "instantiating function definition"); | ||||||||||||
4920 | |||||||||||||
4921 | // The instantiation is visible here, even if it was first declared in an | ||||||||||||
4922 | // unimported module. | ||||||||||||
4923 | Function->setVisibleDespiteOwningModule(); | ||||||||||||
4924 | |||||||||||||
4925 | // Copy the inner loc start from the pattern. | ||||||||||||
4926 | Function->setInnerLocStart(PatternDecl->getInnerLocStart()); | ||||||||||||
4927 | |||||||||||||
4928 | EnterExpressionEvaluationContext EvalContext( | ||||||||||||
4929 | *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); | ||||||||||||
4930 | |||||||||||||
4931 | // Introduce a new scope where local variable instantiations will be | ||||||||||||
4932 | // recorded, unless we're actually a member function within a local | ||||||||||||
4933 | // class, in which case we need to merge our results with the parent | ||||||||||||
4934 | // scope (of the enclosing function). The exception is instantiating | ||||||||||||
4935 | // a function template specialization, since the template to be | ||||||||||||
4936 | // instantiated already has references to locals properly substituted. | ||||||||||||
4937 | bool MergeWithParentScope = false; | ||||||||||||
4938 | if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Function->getDeclContext())) | ||||||||||||
4939 | MergeWithParentScope = | ||||||||||||
4940 | Rec->isLocalClass() && !Function->isFunctionTemplateSpecialization(); | ||||||||||||
4941 | |||||||||||||
4942 | LocalInstantiationScope Scope(*this, MergeWithParentScope); | ||||||||||||
4943 | auto RebuildTypeSourceInfoForDefaultSpecialMembers = [&]() { | ||||||||||||
4944 | // Special members might get their TypeSourceInfo set up w.r.t the | ||||||||||||
4945 | // PatternDecl context, in which case parameters could still be pointing | ||||||||||||
4946 | // back to the original class, make sure arguments are bound to the | ||||||||||||
4947 | // instantiated record instead. | ||||||||||||
4948 | assert(PatternDecl->isDefaulted() &&(static_cast <bool> (PatternDecl->isDefaulted() && "Special member needs to be defaulted") ? void (0) : __assert_fail ("PatternDecl->isDefaulted() && \"Special member needs to be defaulted\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4949, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
| |||||||||||||
4949 | "Special member needs to be defaulted")(static_cast <bool> (PatternDecl->isDefaulted() && "Special member needs to be defaulted") ? void (0) : __assert_fail ("PatternDecl->isDefaulted() && \"Special member needs to be defaulted\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 4949, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4950 | auto PatternSM = getDefaultedFunctionKind(PatternDecl).asSpecialMember(); | ||||||||||||
4951 | if (!(PatternSM == Sema::CXXCopyConstructor || | ||||||||||||
4952 | PatternSM == Sema::CXXCopyAssignment || | ||||||||||||
4953 | PatternSM == Sema::CXXMoveConstructor || | ||||||||||||
4954 | PatternSM == Sema::CXXMoveAssignment)) | ||||||||||||
4955 | return; | ||||||||||||
4956 | |||||||||||||
4957 | auto *NewRec = dyn_cast<CXXRecordDecl>(Function->getDeclContext()); | ||||||||||||
4958 | const auto *PatternRec = | ||||||||||||
4959 | dyn_cast<CXXRecordDecl>(PatternDecl->getDeclContext()); | ||||||||||||
4960 | if (!NewRec
| ||||||||||||
4961 | return; | ||||||||||||
4962 | if (!PatternRec->isLambda()) | ||||||||||||
4963 | return; | ||||||||||||
4964 | |||||||||||||
4965 | struct SpecialMemberTypeInfoRebuilder | ||||||||||||
4966 | : TreeTransform<SpecialMemberTypeInfoRebuilder> { | ||||||||||||
4967 | using Base = TreeTransform<SpecialMemberTypeInfoRebuilder>; | ||||||||||||
4968 | const CXXRecordDecl *OldDecl; | ||||||||||||
4969 | CXXRecordDecl *NewDecl; | ||||||||||||
4970 | |||||||||||||
4971 | SpecialMemberTypeInfoRebuilder(Sema &SemaRef, const CXXRecordDecl *O, | ||||||||||||
4972 | CXXRecordDecl *N) | ||||||||||||
4973 | : TreeTransform(SemaRef), OldDecl(O), NewDecl(N) {} | ||||||||||||
4974 | |||||||||||||
4975 | bool TransformExceptionSpec(SourceLocation Loc, | ||||||||||||
4976 | FunctionProtoType::ExceptionSpecInfo &ESI, | ||||||||||||
4977 | SmallVectorImpl<QualType> &Exceptions, | ||||||||||||
4978 | bool &Changed) { | ||||||||||||
4979 | return false; | ||||||||||||
4980 | } | ||||||||||||
4981 | |||||||||||||
4982 | QualType TransformRecordType(TypeLocBuilder &TLB, RecordTypeLoc TL) { | ||||||||||||
4983 | const RecordType *T = TL.getTypePtr(); | ||||||||||||
4984 | RecordDecl *Record = cast_or_null<RecordDecl>( | ||||||||||||
4985 | getDerived().TransformDecl(TL.getNameLoc(), T->getDecl())); | ||||||||||||
4986 | if (Record != OldDecl) | ||||||||||||
4987 | return Base::TransformRecordType(TLB, TL); | ||||||||||||
4988 | |||||||||||||
4989 | QualType Result = getDerived().RebuildRecordType(NewDecl); | ||||||||||||
4990 | if (Result.isNull()) | ||||||||||||
4991 | return QualType(); | ||||||||||||
4992 | |||||||||||||
4993 | RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result); | ||||||||||||
4994 | NewTL.setNameLoc(TL.getNameLoc()); | ||||||||||||
4995 | return Result; | ||||||||||||
4996 | } | ||||||||||||
4997 | } IR{*this, PatternRec, NewRec}; | ||||||||||||
4998 | |||||||||||||
4999 | TypeSourceInfo *NewSI = IR.TransformType(Function->getTypeSourceInfo()); | ||||||||||||
5000 | Function->setType(NewSI->getType()); | ||||||||||||
5001 | Function->setTypeSourceInfo(NewSI); | ||||||||||||
5002 | |||||||||||||
5003 | ParmVarDecl *Parm = Function->getParamDecl(0); | ||||||||||||
5004 | TypeSourceInfo *NewParmSI = IR.TransformType(Parm->getTypeSourceInfo()); | ||||||||||||
5005 | Parm->setType(NewParmSI->getType()); | ||||||||||||
5006 | Parm->setTypeSourceInfo(NewParmSI); | ||||||||||||
5007 | }; | ||||||||||||
5008 | |||||||||||||
5009 | if (PatternDecl->isDefaulted()) { | ||||||||||||
5010 | RebuildTypeSourceInfoForDefaultSpecialMembers(); | ||||||||||||
5011 | SetDeclDefaulted(Function, PatternDecl->getLocation()); | ||||||||||||
5012 | } else { | ||||||||||||
5013 | MultiLevelTemplateArgumentList TemplateArgs = | ||||||||||||
5014 | getTemplateInstantiationArgs(Function, nullptr, false, PatternDecl); | ||||||||||||
5015 | |||||||||||||
5016 | // Substitute into the qualifier; we can get a substitution failure here | ||||||||||||
5017 | // through evil use of alias templates. | ||||||||||||
5018 | // FIXME: Is CurContext correct for this? Should we go to the (instantiation | ||||||||||||
5019 | // of the) lexical context of the pattern? | ||||||||||||
5020 | SubstQualifier(*this, PatternDecl, Function, TemplateArgs); | ||||||||||||
5021 | |||||||||||||
5022 | ActOnStartOfFunctionDef(nullptr, Function); | ||||||||||||
5023 | |||||||||||||
5024 | // Enter the scope of this instantiation. We don't use | ||||||||||||
5025 | // PushDeclContext because we don't have a scope. | ||||||||||||
5026 | Sema::ContextRAII savedContext(*this, Function); | ||||||||||||
5027 | |||||||||||||
5028 | if (addInstantiatedParametersToScope(Function, PatternDecl, Scope, | ||||||||||||
5029 | TemplateArgs)) | ||||||||||||
5030 | return; | ||||||||||||
5031 | |||||||||||||
5032 | StmtResult Body; | ||||||||||||
5033 | if (PatternDecl->hasSkippedBody()) { | ||||||||||||
5034 | ActOnSkippedFunctionBody(Function); | ||||||||||||
5035 | Body = nullptr; | ||||||||||||
5036 | } else { | ||||||||||||
5037 | if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) { | ||||||||||||
5038 | // If this is a constructor, instantiate the member initializers. | ||||||||||||
5039 | InstantiateMemInitializers(Ctor, cast<CXXConstructorDecl>(PatternDecl), | ||||||||||||
5040 | TemplateArgs); | ||||||||||||
5041 | |||||||||||||
5042 | // If this is an MS ABI dllexport default constructor, instantiate any | ||||||||||||
5043 | // default arguments. | ||||||||||||
5044 | if (Context.getTargetInfo().getCXXABI().isMicrosoft() && | ||||||||||||
5045 | Ctor->isDefaultConstructor()) { | ||||||||||||
5046 | InstantiateDefaultCtorDefaultArgs(Ctor); | ||||||||||||
5047 | } | ||||||||||||
5048 | } | ||||||||||||
5049 | |||||||||||||
5050 | // Instantiate the function body. | ||||||||||||
5051 | Body = SubstStmt(Pattern, TemplateArgs); | ||||||||||||
5052 | |||||||||||||
5053 | if (Body.isInvalid()) | ||||||||||||
5054 | Function->setInvalidDecl(); | ||||||||||||
5055 | } | ||||||||||||
5056 | // FIXME: finishing the function body while in an expression evaluation | ||||||||||||
5057 | // context seems wrong. Investigate more. | ||||||||||||
5058 | ActOnFinishFunctionBody(Function, Body.get(), /*IsInstantiation=*/true); | ||||||||||||
5059 | |||||||||||||
5060 | PerformDependentDiagnostics(PatternDecl, TemplateArgs); | ||||||||||||
5061 | |||||||||||||
5062 | if (auto *Listener = getASTMutationListener()) | ||||||||||||
5063 | Listener->FunctionDefinitionInstantiated(Function); | ||||||||||||
5064 | |||||||||||||
5065 | savedContext.pop(); | ||||||||||||
5066 | } | ||||||||||||
5067 | |||||||||||||
5068 | DeclGroupRef DG(Function); | ||||||||||||
5069 | Consumer.HandleTopLevelDecl(DG); | ||||||||||||
5070 | |||||||||||||
5071 | // This class may have local implicit instantiations that need to be | ||||||||||||
5072 | // instantiation within this scope. | ||||||||||||
5073 | LocalInstantiations.perform(); | ||||||||||||
5074 | Scope.Exit(); | ||||||||||||
5075 | GlobalInstantiations.perform(); | ||||||||||||
5076 | } | ||||||||||||
5077 | |||||||||||||
5078 | VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation( | ||||||||||||
5079 | VarTemplateDecl *VarTemplate, VarDecl *FromVar, | ||||||||||||
5080 | const TemplateArgumentList &TemplateArgList, | ||||||||||||
5081 | const TemplateArgumentListInfo &TemplateArgsInfo, | ||||||||||||
5082 | SmallVectorImpl<TemplateArgument> &Converted, | ||||||||||||
5083 | SourceLocation PointOfInstantiation, | ||||||||||||
5084 | LateInstantiatedAttrVec *LateAttrs, | ||||||||||||
5085 | LocalInstantiationScope *StartingScope) { | ||||||||||||
5086 | if (FromVar->isInvalidDecl()) | ||||||||||||
5087 | return nullptr; | ||||||||||||
5088 | |||||||||||||
5089 | InstantiatingTemplate Inst(*this, PointOfInstantiation, FromVar); | ||||||||||||
5090 | if (Inst.isInvalid()) | ||||||||||||
5091 | return nullptr; | ||||||||||||
5092 | |||||||||||||
5093 | MultiLevelTemplateArgumentList TemplateArgLists; | ||||||||||||
5094 | TemplateArgLists.addOuterTemplateArguments(&TemplateArgList); | ||||||||||||
5095 | |||||||||||||
5096 | // Instantiate the first declaration of the variable template: for a partial | ||||||||||||
5097 | // specialization of a static data member template, the first declaration may | ||||||||||||
5098 | // or may not be the declaration in the class; if it's in the class, we want | ||||||||||||
5099 | // to instantiate a member in the class (a declaration), and if it's outside, | ||||||||||||
5100 | // we want to instantiate a definition. | ||||||||||||
5101 | // | ||||||||||||
5102 | // If we're instantiating an explicitly-specialized member template or member | ||||||||||||
5103 | // partial specialization, don't do this. The member specialization completely | ||||||||||||
5104 | // replaces the original declaration in this case. | ||||||||||||
5105 | bool IsMemberSpec = false; | ||||||||||||
5106 | if (VarTemplatePartialSpecializationDecl *PartialSpec = | ||||||||||||
5107 | dyn_cast<VarTemplatePartialSpecializationDecl>(FromVar)) | ||||||||||||
5108 | IsMemberSpec = PartialSpec->isMemberSpecialization(); | ||||||||||||
5109 | else if (VarTemplateDecl *FromTemplate = FromVar->getDescribedVarTemplate()) | ||||||||||||
5110 | IsMemberSpec = FromTemplate->isMemberSpecialization(); | ||||||||||||
5111 | if (!IsMemberSpec) | ||||||||||||
5112 | FromVar = FromVar->getFirstDecl(); | ||||||||||||
5113 | |||||||||||||
5114 | MultiLevelTemplateArgumentList MultiLevelList(TemplateArgList); | ||||||||||||
5115 | TemplateDeclInstantiator Instantiator(*this, FromVar->getDeclContext(), | ||||||||||||
5116 | MultiLevelList); | ||||||||||||
5117 | |||||||||||||
5118 | // TODO: Set LateAttrs and StartingScope ... | ||||||||||||
5119 | |||||||||||||
5120 | return cast_or_null<VarTemplateSpecializationDecl>( | ||||||||||||
5121 | Instantiator.VisitVarTemplateSpecializationDecl( | ||||||||||||
5122 | VarTemplate, FromVar, TemplateArgsInfo, Converted)); | ||||||||||||
5123 | } | ||||||||||||
5124 | |||||||||||||
5125 | /// Instantiates a variable template specialization by completing it | ||||||||||||
5126 | /// with appropriate type information and initializer. | ||||||||||||
5127 | VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( | ||||||||||||
5128 | VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, | ||||||||||||
5129 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
5130 | assert(PatternDecl->isThisDeclarationADefinition() &&(static_cast <bool> (PatternDecl->isThisDeclarationADefinition () && "don't have a definition to instantiate from") ? void (0) : __assert_fail ("PatternDecl->isThisDeclarationADefinition() && \"don't have a definition to instantiate from\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 5131, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
5131 | "don't have a definition to instantiate from")(static_cast <bool> (PatternDecl->isThisDeclarationADefinition () && "don't have a definition to instantiate from") ? void (0) : __assert_fail ("PatternDecl->isThisDeclarationADefinition() && \"don't have a definition to instantiate from\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 5131, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
5132 | |||||||||||||
5133 | // Do substitution on the type of the declaration | ||||||||||||
5134 | TypeSourceInfo *DI = | ||||||||||||
5135 | SubstType(PatternDecl->getTypeSourceInfo(), TemplateArgs, | ||||||||||||
5136 | PatternDecl->getTypeSpecStartLoc(), PatternDecl->getDeclName()); | ||||||||||||
5137 | if (!DI) | ||||||||||||
5138 | return nullptr; | ||||||||||||
5139 | |||||||||||||
5140 | // Update the type of this variable template specialization. | ||||||||||||
5141 | VarSpec->setType(DI->getType()); | ||||||||||||
5142 | |||||||||||||
5143 | // Convert the declaration into a definition now. | ||||||||||||
5144 | VarSpec->setCompleteDefinition(); | ||||||||||||
5145 | |||||||||||||
5146 | // Instantiate the initializer. | ||||||||||||
5147 | InstantiateVariableInitializer(VarSpec, PatternDecl, TemplateArgs); | ||||||||||||
5148 | |||||||||||||
5149 | if (getLangOpts().OpenCL) | ||||||||||||
5150 | deduceOpenCLAddressSpace(VarSpec); | ||||||||||||
5151 | |||||||||||||
5152 | return VarSpec; | ||||||||||||
5153 | } | ||||||||||||
5154 | |||||||||||||
5155 | /// BuildVariableInstantiation - Used after a new variable has been created. | ||||||||||||
5156 | /// Sets basic variable data and decides whether to postpone the | ||||||||||||
5157 | /// variable instantiation. | ||||||||||||
5158 | void Sema::BuildVariableInstantiation( | ||||||||||||
5159 | VarDecl *NewVar, VarDecl *OldVar, | ||||||||||||
5160 | const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
5161 | LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner, | ||||||||||||
5162 | LocalInstantiationScope *StartingScope, | ||||||||||||
5163 | bool InstantiatingVarTemplate, | ||||||||||||
5164 | VarTemplateSpecializationDecl *PrevDeclForVarTemplateSpecialization) { | ||||||||||||
5165 | // Instantiating a partial specialization to produce a partial | ||||||||||||
5166 | // specialization. | ||||||||||||
5167 | bool InstantiatingVarTemplatePartialSpec = | ||||||||||||
5168 | isa<VarTemplatePartialSpecializationDecl>(OldVar) && | ||||||||||||
5169 | isa<VarTemplatePartialSpecializationDecl>(NewVar); | ||||||||||||
5170 | // Instantiating from a variable template (or partial specialization) to | ||||||||||||
5171 | // produce a variable template specialization. | ||||||||||||
5172 | bool InstantiatingSpecFromTemplate = | ||||||||||||
5173 | isa<VarTemplateSpecializationDecl>(NewVar) && | ||||||||||||
5174 | (OldVar->getDescribedVarTemplate() || | ||||||||||||
5175 | isa<VarTemplatePartialSpecializationDecl>(OldVar)); | ||||||||||||
5176 | |||||||||||||
5177 | // If we are instantiating a local extern declaration, the | ||||||||||||
5178 | // instantiation belongs lexically to the containing function. | ||||||||||||
5179 | // If we are instantiating a static data member defined | ||||||||||||
5180 | // out-of-line, the instantiation will have the same lexical | ||||||||||||
5181 | // context (which will be a namespace scope) as the template. | ||||||||||||
5182 | if (OldVar->isLocalExternDecl()) { | ||||||||||||
5183 | NewVar->setLocalExternDecl(); | ||||||||||||
5184 | NewVar->setLexicalDeclContext(Owner); | ||||||||||||
5185 | } else if (OldVar->isOutOfLine()) | ||||||||||||
5186 | NewVar->setLexicalDeclContext(OldVar->getLexicalDeclContext()); | ||||||||||||
5187 | NewVar->setTSCSpec(OldVar->getTSCSpec()); | ||||||||||||
5188 | NewVar->setInitStyle(OldVar->getInitStyle()); | ||||||||||||
5189 | NewVar->setCXXForRangeDecl(OldVar->isCXXForRangeDecl()); | ||||||||||||
5190 | NewVar->setObjCForDecl(OldVar->isObjCForDecl()); | ||||||||||||
5191 | NewVar->setConstexpr(OldVar->isConstexpr()); | ||||||||||||
5192 | NewVar->setInitCapture(OldVar->isInitCapture()); | ||||||||||||
5193 | NewVar->setPreviousDeclInSameBlockScope( | ||||||||||||
5194 | OldVar->isPreviousDeclInSameBlockScope()); | ||||||||||||
5195 | NewVar->setAccess(OldVar->getAccess()); | ||||||||||||
5196 | |||||||||||||
5197 | if (!OldVar->isStaticDataMember()) { | ||||||||||||
5198 | if (OldVar->isUsed(false)) | ||||||||||||
5199 | NewVar->setIsUsed(); | ||||||||||||
5200 | NewVar->setReferenced(OldVar->isReferenced()); | ||||||||||||
5201 | } | ||||||||||||
5202 | |||||||||||||
5203 | InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope); | ||||||||||||
5204 | |||||||||||||
5205 | LookupResult Previous( | ||||||||||||
5206 | *this, NewVar->getDeclName(), NewVar->getLocation(), | ||||||||||||
5207 | NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage | ||||||||||||
5208 | : Sema::LookupOrdinaryName, | ||||||||||||
5209 | NewVar->isLocalExternDecl() ? Sema::ForExternalRedeclaration | ||||||||||||
5210 | : forRedeclarationInCurContext()); | ||||||||||||
5211 | |||||||||||||
5212 | if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl() && | ||||||||||||
5213 | (!OldVar->getPreviousDecl()->getDeclContext()->isDependentContext() || | ||||||||||||
5214 | OldVar->getPreviousDecl()->getDeclContext()==OldVar->getDeclContext())) { | ||||||||||||
5215 | // We have a previous declaration. Use that one, so we merge with the | ||||||||||||
5216 | // right type. | ||||||||||||
5217 | if (NamedDecl *NewPrev = FindInstantiatedDecl( | ||||||||||||
5218 | NewVar->getLocation(), OldVar->getPreviousDecl(), TemplateArgs)) | ||||||||||||
5219 | Previous.addDecl(NewPrev); | ||||||||||||
5220 | } else if (!isa<VarTemplateSpecializationDecl>(NewVar) && | ||||||||||||
5221 | OldVar->hasLinkage()) { | ||||||||||||
5222 | LookupQualifiedName(Previous, NewVar->getDeclContext(), false); | ||||||||||||
5223 | } else if (PrevDeclForVarTemplateSpecialization) { | ||||||||||||
5224 | Previous.addDecl(PrevDeclForVarTemplateSpecialization); | ||||||||||||
5225 | } | ||||||||||||
5226 | CheckVariableDeclaration(NewVar, Previous); | ||||||||||||
5227 | |||||||||||||
5228 | if (!InstantiatingVarTemplate) { | ||||||||||||
5229 | NewVar->getLexicalDeclContext()->addHiddenDecl(NewVar); | ||||||||||||
5230 | if (!NewVar->isLocalExternDecl() || !NewVar->getPreviousDecl()) | ||||||||||||
5231 | NewVar->getDeclContext()->makeDeclVisibleInContext(NewVar); | ||||||||||||
5232 | } | ||||||||||||
5233 | |||||||||||||
5234 | if (!OldVar->isOutOfLine()) { | ||||||||||||
5235 | if (NewVar->getDeclContext()->isFunctionOrMethod()) | ||||||||||||
5236 | CurrentInstantiationScope->InstantiatedLocal(OldVar, NewVar); | ||||||||||||
5237 | } | ||||||||||||
5238 | |||||||||||||
5239 | // Link instantiations of static data members back to the template from | ||||||||||||
5240 | // which they were instantiated. | ||||||||||||
5241 | // | ||||||||||||
5242 | // Don't do this when instantiating a template (we link the template itself | ||||||||||||
5243 | // back in that case) nor when instantiating a static data member template | ||||||||||||
5244 | // (that's not a member specialization). | ||||||||||||
5245 | if (NewVar->isStaticDataMember() && !InstantiatingVarTemplate && | ||||||||||||
5246 | !InstantiatingSpecFromTemplate) | ||||||||||||
5247 | NewVar->setInstantiationOfStaticDataMember(OldVar, | ||||||||||||
5248 | TSK_ImplicitInstantiation); | ||||||||||||
5249 | |||||||||||||
5250 | // If the pattern is an (in-class) explicit specialization, then the result | ||||||||||||
5251 | // is also an explicit specialization. | ||||||||||||
5252 | if (VarTemplateSpecializationDecl *OldVTSD = | ||||||||||||
5253 | dyn_cast<VarTemplateSpecializationDecl>(OldVar)) { | ||||||||||||
5254 | if (OldVTSD->getSpecializationKind() == TSK_ExplicitSpecialization && | ||||||||||||
5255 | !isa<VarTemplatePartialSpecializationDecl>(OldVTSD)) | ||||||||||||
5256 | cast<VarTemplateSpecializationDecl>(NewVar)->setSpecializationKind( | ||||||||||||
5257 | TSK_ExplicitSpecialization); | ||||||||||||
5258 | } | ||||||||||||
5259 | |||||||||||||
5260 | // Forward the mangling number from the template to the instantiated decl. | ||||||||||||
5261 | Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar)); | ||||||||||||
5262 | Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar)); | ||||||||||||
5263 | |||||||||||||
5264 | // Figure out whether to eagerly instantiate the initializer. | ||||||||||||
5265 | if (InstantiatingVarTemplate || InstantiatingVarTemplatePartialSpec) { | ||||||||||||
5266 | // We're producing a template. Don't instantiate the initializer yet. | ||||||||||||
5267 | } else if (NewVar->getType()->isUndeducedType()) { | ||||||||||||
5268 | // We need the type to complete the declaration of the variable. | ||||||||||||
5269 | InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs); | ||||||||||||
5270 | } else if (InstantiatingSpecFromTemplate || | ||||||||||||
5271 | (OldVar->isInline() && OldVar->isThisDeclarationADefinition() && | ||||||||||||
5272 | !NewVar->isThisDeclarationADefinition())) { | ||||||||||||
5273 | // Delay instantiation of the initializer for variable template | ||||||||||||
5274 | // specializations or inline static data members until a definition of the | ||||||||||||
5275 | // variable is needed. | ||||||||||||
5276 | } else { | ||||||||||||
5277 | InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs); | ||||||||||||
5278 | } | ||||||||||||
5279 | |||||||||||||
5280 | // Diagnose unused local variables with dependent types, where the diagnostic | ||||||||||||
5281 | // will have been deferred. | ||||||||||||
5282 | if (!NewVar->isInvalidDecl() && | ||||||||||||
5283 | NewVar->getDeclContext()->isFunctionOrMethod() && | ||||||||||||
5284 | OldVar->getType()->isDependentType()) | ||||||||||||
5285 | DiagnoseUnusedDecl(NewVar); | ||||||||||||
5286 | } | ||||||||||||
5287 | |||||||||||||
5288 | /// Instantiate the initializer of a variable. | ||||||||||||
5289 | void Sema::InstantiateVariableInitializer( | ||||||||||||
5290 | VarDecl *Var, VarDecl *OldVar, | ||||||||||||
5291 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
5292 | if (ASTMutationListener *L = getASTContext().getASTMutationListener()) | ||||||||||||
5293 | L->VariableDefinitionInstantiated(Var); | ||||||||||||
5294 | |||||||||||||
5295 | // We propagate the 'inline' flag with the initializer, because it | ||||||||||||
5296 | // would otherwise imply that the variable is a definition for a | ||||||||||||
5297 | // non-static data member. | ||||||||||||
5298 | if (OldVar->isInlineSpecified()) | ||||||||||||
5299 | Var->setInlineSpecified(); | ||||||||||||
5300 | else if (OldVar->isInline()) | ||||||||||||
5301 | Var->setImplicitlyInline(); | ||||||||||||
5302 | |||||||||||||
5303 | if (OldVar->getInit()) { | ||||||||||||
5304 | EnterExpressionEvaluationContext Evaluated( | ||||||||||||
5305 | *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var); | ||||||||||||
5306 | |||||||||||||
5307 | // Instantiate the initializer. | ||||||||||||
5308 | ExprResult Init; | ||||||||||||
5309 | |||||||||||||
5310 | { | ||||||||||||
5311 | ContextRAII SwitchContext(*this, Var->getDeclContext()); | ||||||||||||
5312 | Init = SubstInitializer(OldVar->getInit(), TemplateArgs, | ||||||||||||
5313 | OldVar->getInitStyle() == VarDecl::CallInit); | ||||||||||||
5314 | } | ||||||||||||
5315 | |||||||||||||
5316 | if (!Init.isInvalid()) { | ||||||||||||
5317 | Expr *InitExpr = Init.get(); | ||||||||||||
5318 | |||||||||||||
5319 | if (Var->hasAttr<DLLImportAttr>() && | ||||||||||||
5320 | (!InitExpr || | ||||||||||||
5321 | !InitExpr->isConstantInitializer(getASTContext(), false))) { | ||||||||||||
5322 | // Do not dynamically initialize dllimport variables. | ||||||||||||
5323 | } else if (InitExpr) { | ||||||||||||
5324 | bool DirectInit = OldVar->isDirectInit(); | ||||||||||||
5325 | AddInitializerToDecl(Var, InitExpr, DirectInit); | ||||||||||||
5326 | } else | ||||||||||||
5327 | ActOnUninitializedDecl(Var); | ||||||||||||
5328 | } else { | ||||||||||||
5329 | // FIXME: Not too happy about invalidating the declaration | ||||||||||||
5330 | // because of a bogus initializer. | ||||||||||||
5331 | Var->setInvalidDecl(); | ||||||||||||
5332 | } | ||||||||||||
5333 | } else { | ||||||||||||
5334 | // `inline` variables are a definition and declaration all in one; we won't | ||||||||||||
5335 | // pick up an initializer from anywhere else. | ||||||||||||
5336 | if (Var->isStaticDataMember() && !Var->isInline()) { | ||||||||||||
5337 | if (!Var->isOutOfLine()) | ||||||||||||
5338 | return; | ||||||||||||
5339 | |||||||||||||
5340 | // If the declaration inside the class had an initializer, don't add | ||||||||||||
5341 | // another one to the out-of-line definition. | ||||||||||||
5342 | if (OldVar->getFirstDecl()->hasInit()) | ||||||||||||
5343 | return; | ||||||||||||
5344 | } | ||||||||||||
5345 | |||||||||||||
5346 | // We'll add an initializer to a for-range declaration later. | ||||||||||||
5347 | if (Var->isCXXForRangeDecl() || Var->isObjCForDecl()) | ||||||||||||
5348 | return; | ||||||||||||
5349 | |||||||||||||
5350 | ActOnUninitializedDecl(Var); | ||||||||||||
5351 | } | ||||||||||||
5352 | |||||||||||||
5353 | if (getLangOpts().CUDA) | ||||||||||||
5354 | checkAllowedCUDAInitializer(Var); | ||||||||||||
5355 | } | ||||||||||||
5356 | |||||||||||||
5357 | /// Instantiate the definition of the given variable from its | ||||||||||||
5358 | /// template. | ||||||||||||
5359 | /// | ||||||||||||
5360 | /// \param PointOfInstantiation the point at which the instantiation was | ||||||||||||
5361 | /// required. Note that this is not precisely a "point of instantiation" | ||||||||||||
5362 | /// for the variable, but it's close. | ||||||||||||
5363 | /// | ||||||||||||
5364 | /// \param Var the already-instantiated declaration of a templated variable. | ||||||||||||
5365 | /// | ||||||||||||
5366 | /// \param Recursive if true, recursively instantiates any functions that | ||||||||||||
5367 | /// are required by this instantiation. | ||||||||||||
5368 | /// | ||||||||||||
5369 | /// \param DefinitionRequired if true, then we are performing an explicit | ||||||||||||
5370 | /// instantiation where a definition of the variable is required. Complain | ||||||||||||
5371 | /// if there is no such definition. | ||||||||||||
5372 | void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, | ||||||||||||
5373 | VarDecl *Var, bool Recursive, | ||||||||||||
5374 | bool DefinitionRequired, bool AtEndOfTU) { | ||||||||||||
5375 | if (Var->isInvalidDecl()) | ||||||||||||
5376 | return; | ||||||||||||
5377 | |||||||||||||
5378 | // Never instantiate an explicitly-specialized entity. | ||||||||||||
5379 | TemplateSpecializationKind TSK = | ||||||||||||
5380 | Var->getTemplateSpecializationKindForInstantiation(); | ||||||||||||
5381 | if (TSK == TSK_ExplicitSpecialization) | ||||||||||||
5382 | return; | ||||||||||||
5383 | |||||||||||||
5384 | // Find the pattern and the arguments to substitute into it. | ||||||||||||
5385 | VarDecl *PatternDecl = Var->getTemplateInstantiationPattern(); | ||||||||||||
5386 | assert(PatternDecl && "no pattern for templated variable")(static_cast <bool> (PatternDecl && "no pattern for templated variable" ) ? void (0) : __assert_fail ("PatternDecl && \"no pattern for templated variable\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 5386, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
5387 | MultiLevelTemplateArgumentList TemplateArgs = | ||||||||||||
5388 | getTemplateInstantiationArgs(Var); | ||||||||||||
5389 | |||||||||||||
5390 | VarTemplateSpecializationDecl *VarSpec = | ||||||||||||
5391 | dyn_cast<VarTemplateSpecializationDecl>(Var); | ||||||||||||
5392 | if (VarSpec) { | ||||||||||||
5393 | // If this is a static data member template, there might be an | ||||||||||||
5394 | // uninstantiated initializer on the declaration. If so, instantiate | ||||||||||||
5395 | // it now. | ||||||||||||
5396 | // | ||||||||||||
5397 | // FIXME: This largely duplicates what we would do below. The difference | ||||||||||||
5398 | // is that along this path we may instantiate an initializer from an | ||||||||||||
5399 | // in-class declaration of the template and instantiate the definition | ||||||||||||
5400 | // from a separate out-of-class definition. | ||||||||||||
5401 | if (PatternDecl->isStaticDataMember() && | ||||||||||||
5402 | (PatternDecl = PatternDecl->getFirstDecl())->hasInit() && | ||||||||||||
5403 | !Var->hasInit()) { | ||||||||||||
5404 | // FIXME: Factor out the duplicated instantiation context setup/tear down | ||||||||||||
5405 | // code here. | ||||||||||||
5406 | InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); | ||||||||||||
5407 | if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) | ||||||||||||
5408 | return; | ||||||||||||
5409 | PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), | ||||||||||||
5410 | "instantiating variable initializer"); | ||||||||||||
5411 | |||||||||||||
5412 | // The instantiation is visible here, even if it was first declared in an | ||||||||||||
5413 | // unimported module. | ||||||||||||
5414 | Var->setVisibleDespiteOwningModule(); | ||||||||||||
5415 | |||||||||||||
5416 | // If we're performing recursive template instantiation, create our own | ||||||||||||
5417 | // queue of pending implicit instantiations that we will instantiate | ||||||||||||
5418 | // later, while we're still within our own instantiation context. | ||||||||||||
5419 | GlobalEagerInstantiationScope GlobalInstantiations(*this, | ||||||||||||
5420 | /*Enabled=*/Recursive); | ||||||||||||
5421 | LocalInstantiationScope Local(*this); | ||||||||||||
5422 | LocalEagerInstantiationScope LocalInstantiations(*this); | ||||||||||||
5423 | |||||||||||||
5424 | // Enter the scope of this instantiation. We don't use | ||||||||||||
5425 | // PushDeclContext because we don't have a scope. | ||||||||||||
5426 | ContextRAII PreviousContext(*this, Var->getDeclContext()); | ||||||||||||
5427 | InstantiateVariableInitializer(Var, PatternDecl, TemplateArgs); | ||||||||||||
5428 | PreviousContext.pop(); | ||||||||||||
5429 | |||||||||||||
5430 | // This variable may have local implicit instantiations that need to be | ||||||||||||
5431 | // instantiated within this scope. | ||||||||||||
5432 | LocalInstantiations.perform(); | ||||||||||||
5433 | Local.Exit(); | ||||||||||||
5434 | GlobalInstantiations.perform(); | ||||||||||||
5435 | } | ||||||||||||
5436 | } else { | ||||||||||||
5437 | assert(Var->isStaticDataMember() && PatternDecl->isStaticDataMember() &&(static_cast <bool> (Var->isStaticDataMember() && PatternDecl->isStaticDataMember() && "not a static data member?" ) ? void (0) : __assert_fail ("Var->isStaticDataMember() && PatternDecl->isStaticDataMember() && \"not a static data member?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 5438, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
5438 | "not a static data member?")(static_cast <bool> (Var->isStaticDataMember() && PatternDecl->isStaticDataMember() && "not a static data member?" ) ? void (0) : __assert_fail ("Var->isStaticDataMember() && PatternDecl->isStaticDataMember() && \"not a static data member?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 5438, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
5439 | } | ||||||||||||
5440 | |||||||||||||
5441 | VarDecl *Def = PatternDecl->getDefinition(getASTContext()); | ||||||||||||
5442 | |||||||||||||
5443 | // If we don't have a definition of the variable template, we won't perform | ||||||||||||
5444 | // any instantiation. Rather, we rely on the user to instantiate this | ||||||||||||
5445 | // definition (or provide a specialization for it) in another translation | ||||||||||||
5446 | // unit. | ||||||||||||
5447 | if (!Def && !DefinitionRequired) { | ||||||||||||
5448 | if (TSK == TSK_ExplicitInstantiationDefinition) { | ||||||||||||
5449 | PendingInstantiations.push_back( | ||||||||||||
5450 | std::make_pair(Var, PointOfInstantiation)); | ||||||||||||
5451 | } else if (TSK == TSK_ImplicitInstantiation) { | ||||||||||||
5452 | // Warn about missing definition at the end of translation unit. | ||||||||||||
5453 | if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() && | ||||||||||||
5454 | !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) { | ||||||||||||
5455 | Diag(PointOfInstantiation, diag::warn_var_template_missing) | ||||||||||||
5456 | << Var; | ||||||||||||
5457 | Diag(PatternDecl->getLocation(), diag::note_forward_template_decl); | ||||||||||||
5458 | if (getLangOpts().CPlusPlus11) | ||||||||||||
5459 | Diag(PointOfInstantiation, diag::note_inst_declaration_hint) << Var; | ||||||||||||
5460 | } | ||||||||||||
5461 | return; | ||||||||||||
5462 | } | ||||||||||||
5463 | } | ||||||||||||
5464 | |||||||||||||
5465 | // FIXME: We need to track the instantiation stack in order to know which | ||||||||||||
5466 | // definitions should be visible within this instantiation. | ||||||||||||
5467 | // FIXME: Produce diagnostics when Var->getInstantiatedFromStaticDataMember(). | ||||||||||||
5468 | if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Var, | ||||||||||||
5469 | /*InstantiatedFromMember*/false, | ||||||||||||
5470 | PatternDecl, Def, TSK, | ||||||||||||
5471 | /*Complain*/DefinitionRequired)) | ||||||||||||
5472 | return; | ||||||||||||
5473 | |||||||||||||
5474 | // C++11 [temp.explicit]p10: | ||||||||||||
5475 | // Except for inline functions, const variables of literal types, variables | ||||||||||||
5476 | // of reference types, [...] explicit instantiation declarations | ||||||||||||
5477 | // have the effect of suppressing the implicit instantiation of the entity | ||||||||||||
5478 | // to which they refer. | ||||||||||||
5479 | // | ||||||||||||
5480 | // FIXME: That's not exactly the same as "might be usable in constant | ||||||||||||
5481 | // expressions", which only allows constexpr variables and const integral | ||||||||||||
5482 | // types, not arbitrary const literal types. | ||||||||||||
5483 | if (TSK == TSK_ExplicitInstantiationDeclaration && | ||||||||||||
5484 | !Var->mightBeUsableInConstantExpressions(getASTContext())) | ||||||||||||
5485 | return; | ||||||||||||
5486 | |||||||||||||
5487 | // Make sure to pass the instantiated variable to the consumer at the end. | ||||||||||||
5488 | struct PassToConsumerRAII { | ||||||||||||
5489 | ASTConsumer &Consumer; | ||||||||||||
5490 | VarDecl *Var; | ||||||||||||
5491 | |||||||||||||
5492 | PassToConsumerRAII(ASTConsumer &Consumer, VarDecl *Var) | ||||||||||||
5493 | : Consumer(Consumer), Var(Var) { } | ||||||||||||
5494 | |||||||||||||
5495 | ~PassToConsumerRAII() { | ||||||||||||
5496 | Consumer.HandleCXXStaticMemberVarInstantiation(Var); | ||||||||||||
5497 | } | ||||||||||||
5498 | } PassToConsumerRAII(Consumer, Var); | ||||||||||||
5499 | |||||||||||||
5500 | // If we already have a definition, we're done. | ||||||||||||
5501 | if (VarDecl *Def = Var->getDefinition()) { | ||||||||||||
5502 | // We may be explicitly instantiating something we've already implicitly | ||||||||||||
5503 | // instantiated. | ||||||||||||
5504 | Def->setTemplateSpecializationKind(Var->getTemplateSpecializationKind(), | ||||||||||||
5505 | PointOfInstantiation); | ||||||||||||
5506 | return; | ||||||||||||
5507 | } | ||||||||||||
5508 | |||||||||||||
5509 | InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); | ||||||||||||
5510 | if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) | ||||||||||||
5511 | return; | ||||||||||||
5512 | PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), | ||||||||||||
5513 | "instantiating variable definition"); | ||||||||||||
5514 | |||||||||||||
5515 | // If we're performing recursive template instantiation, create our own | ||||||||||||
5516 | // queue of pending implicit instantiations that we will instantiate later, | ||||||||||||
5517 | // while we're still within our own instantiation context. | ||||||||||||
5518 | GlobalEagerInstantiationScope GlobalInstantiations(*this, | ||||||||||||
5519 | /*Enabled=*/Recursive); | ||||||||||||
5520 | |||||||||||||
5521 | // Enter the scope of this instantiation. We don't use | ||||||||||||
5522 | // PushDeclContext because we don't have a scope. | ||||||||||||
5523 | ContextRAII PreviousContext(*this, Var->getDeclContext()); | ||||||||||||
5524 | LocalInstantiationScope Local(*this); | ||||||||||||
5525 | |||||||||||||
5526 | LocalEagerInstantiationScope LocalInstantiations(*this); | ||||||||||||
5527 | |||||||||||||
5528 | VarDecl *OldVar = Var; | ||||||||||||
5529 | if (Def->isStaticDataMember() && !Def->isOutOfLine()) { | ||||||||||||
5530 | // We're instantiating an inline static data member whose definition was | ||||||||||||
5531 | // provided inside the class. | ||||||||||||
5532 | InstantiateVariableInitializer(Var, Def, TemplateArgs); | ||||||||||||
5533 | } else if (!VarSpec) { | ||||||||||||
5534 | Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(), | ||||||||||||
5535 | TemplateArgs)); | ||||||||||||
5536 | } else if (Var->isStaticDataMember() && | ||||||||||||
5537 | Var->getLexicalDeclContext()->isRecord()) { | ||||||||||||
5538 | // We need to instantiate the definition of a static data member template, | ||||||||||||
5539 | // and all we have is the in-class declaration of it. Instantiate a separate | ||||||||||||
5540 | // declaration of the definition. | ||||||||||||
5541 | TemplateDeclInstantiator Instantiator(*this, Var->getDeclContext(), | ||||||||||||
5542 | TemplateArgs); | ||||||||||||
5543 | |||||||||||||
5544 | TemplateArgumentListInfo TemplateArgInfo; | ||||||||||||
5545 | if (const ASTTemplateArgumentListInfo *ArgInfo = | ||||||||||||
5546 | VarSpec->getTemplateArgsInfo()) { | ||||||||||||
5547 | TemplateArgInfo.setLAngleLoc(ArgInfo->getLAngleLoc()); | ||||||||||||
5548 | TemplateArgInfo.setRAngleLoc(ArgInfo->getRAngleLoc()); | ||||||||||||
5549 | for (const TemplateArgumentLoc &Arg : ArgInfo->arguments()) | ||||||||||||
5550 | TemplateArgInfo.addArgument(Arg); | ||||||||||||
5551 | } | ||||||||||||
5552 | |||||||||||||
5553 | Var = cast_or_null<VarDecl>(Instantiator.VisitVarTemplateSpecializationDecl( | ||||||||||||
5554 | VarSpec->getSpecializedTemplate(), Def, TemplateArgInfo, | ||||||||||||
5555 | VarSpec->getTemplateArgs().asArray(), VarSpec)); | ||||||||||||
5556 | if (Var) { | ||||||||||||
5557 | llvm::PointerUnion<VarTemplateDecl *, | ||||||||||||
5558 | VarTemplatePartialSpecializationDecl *> PatternPtr = | ||||||||||||
5559 | VarSpec->getSpecializedTemplateOrPartial(); | ||||||||||||
5560 | if (VarTemplatePartialSpecializationDecl *Partial = | ||||||||||||
5561 | PatternPtr.dyn_cast<VarTemplatePartialSpecializationDecl *>()) | ||||||||||||
5562 | cast<VarTemplateSpecializationDecl>(Var)->setInstantiationOf( | ||||||||||||
5563 | Partial, &VarSpec->getTemplateInstantiationArgs()); | ||||||||||||
5564 | |||||||||||||
5565 | // Attach the initializer. | ||||||||||||
5566 | InstantiateVariableInitializer(Var, Def, TemplateArgs); | ||||||||||||
5567 | } | ||||||||||||
5568 | } else | ||||||||||||
5569 | // Complete the existing variable's definition with an appropriately | ||||||||||||
5570 | // substituted type and initializer. | ||||||||||||
5571 | Var = CompleteVarTemplateSpecializationDecl(VarSpec, Def, TemplateArgs); | ||||||||||||
5572 | |||||||||||||
5573 | PreviousContext.pop(); | ||||||||||||
5574 | |||||||||||||
5575 | if (Var) { | ||||||||||||
5576 | PassToConsumerRAII.Var = Var; | ||||||||||||
5577 | Var->setTemplateSpecializationKind(OldVar->getTemplateSpecializationKind(), | ||||||||||||
5578 | OldVar->getPointOfInstantiation()); | ||||||||||||
5579 | } | ||||||||||||
5580 | |||||||||||||
5581 | // This variable may have local implicit instantiations that need to be | ||||||||||||
5582 | // instantiated within this scope. | ||||||||||||
5583 | LocalInstantiations.perform(); | ||||||||||||
5584 | Local.Exit(); | ||||||||||||
5585 | GlobalInstantiations.perform(); | ||||||||||||
5586 | } | ||||||||||||
5587 | |||||||||||||
5588 | void | ||||||||||||
5589 | Sema::InstantiateMemInitializers(CXXConstructorDecl *New, | ||||||||||||
5590 | const CXXConstructorDecl *Tmpl, | ||||||||||||
5591 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
5592 | |||||||||||||
5593 | SmallVector<CXXCtorInitializer*, 4> NewInits; | ||||||||||||
5594 | bool AnyErrors = Tmpl->isInvalidDecl(); | ||||||||||||
5595 | |||||||||||||
5596 | // Instantiate all the initializers. | ||||||||||||
5597 | for (const auto *Init : Tmpl->inits()) { | ||||||||||||
5598 | // Only instantiate written initializers, let Sema re-construct implicit | ||||||||||||
5599 | // ones. | ||||||||||||
5600 | if (!Init->isWritten()) | ||||||||||||
5601 | continue; | ||||||||||||
5602 | |||||||||||||
5603 | SourceLocation EllipsisLoc; | ||||||||||||
5604 | |||||||||||||
5605 | if (Init->isPackExpansion()) { | ||||||||||||
5606 | // This is a pack expansion. We should expand it now. | ||||||||||||
5607 | TypeLoc BaseTL = Init->getTypeSourceInfo()->getTypeLoc(); | ||||||||||||
5608 | SmallVector<UnexpandedParameterPack, 4> Unexpanded; | ||||||||||||
5609 | collectUnexpandedParameterPacks(BaseTL, Unexpanded); | ||||||||||||
5610 | collectUnexpandedParameterPacks(Init->getInit(), Unexpanded); | ||||||||||||
5611 | bool ShouldExpand = false; | ||||||||||||
5612 | bool RetainExpansion = false; | ||||||||||||
5613 | Optional<unsigned> NumExpansions; | ||||||||||||
5614 | if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(), | ||||||||||||
5615 | BaseTL.getSourceRange(), | ||||||||||||
5616 | Unexpanded, | ||||||||||||
5617 | TemplateArgs, ShouldExpand, | ||||||||||||
5618 | RetainExpansion, | ||||||||||||
5619 | NumExpansions)) { | ||||||||||||
5620 | AnyErrors = true; | ||||||||||||
5621 | New->setInvalidDecl(); | ||||||||||||
5622 | continue; | ||||||||||||
5623 | } | ||||||||||||
5624 | assert(ShouldExpand && "Partial instantiation of base initializer?")(static_cast <bool> (ShouldExpand && "Partial instantiation of base initializer?" ) ? void (0) : __assert_fail ("ShouldExpand && \"Partial instantiation of base initializer?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 5624, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
5625 | |||||||||||||
5626 | // Loop over all of the arguments in the argument pack(s), | ||||||||||||
5627 | for (unsigned I = 0; I != *NumExpansions; ++I) { | ||||||||||||
5628 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I); | ||||||||||||
5629 | |||||||||||||
5630 | // Instantiate the initializer. | ||||||||||||
5631 | ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs, | ||||||||||||
5632 | /*CXXDirectInit=*/true); | ||||||||||||
5633 | if (TempInit.isInvalid()) { | ||||||||||||
5634 | AnyErrors = true; | ||||||||||||
5635 | break; | ||||||||||||
5636 | } | ||||||||||||
5637 | |||||||||||||
5638 | // Instantiate the base type. | ||||||||||||
5639 | TypeSourceInfo *BaseTInfo = SubstType(Init->getTypeSourceInfo(), | ||||||||||||
5640 | TemplateArgs, | ||||||||||||
5641 | Init->getSourceLocation(), | ||||||||||||
5642 | New->getDeclName()); | ||||||||||||
5643 | if (!BaseTInfo) { | ||||||||||||
5644 | AnyErrors = true; | ||||||||||||
5645 | break; | ||||||||||||
5646 | } | ||||||||||||
5647 | |||||||||||||
5648 | // Build the initializer. | ||||||||||||
5649 | MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(), | ||||||||||||
5650 | BaseTInfo, TempInit.get(), | ||||||||||||
5651 | New->getParent(), | ||||||||||||
5652 | SourceLocation()); | ||||||||||||
5653 | if (NewInit.isInvalid()) { | ||||||||||||
5654 | AnyErrors = true; | ||||||||||||
5655 | break; | ||||||||||||
5656 | } | ||||||||||||
5657 | |||||||||||||
5658 | NewInits.push_back(NewInit.get()); | ||||||||||||
5659 | } | ||||||||||||
5660 | |||||||||||||
5661 | continue; | ||||||||||||
5662 | } | ||||||||||||
5663 | |||||||||||||
5664 | // Instantiate the initializer. | ||||||||||||
5665 | ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs, | ||||||||||||
5666 | /*CXXDirectInit=*/true); | ||||||||||||
5667 | if (TempInit.isInvalid()) { | ||||||||||||
5668 | AnyErrors = true; | ||||||||||||
5669 | continue; | ||||||||||||
5670 | } | ||||||||||||
5671 | |||||||||||||
5672 | MemInitResult NewInit; | ||||||||||||
5673 | if (Init->isDelegatingInitializer() || Init->isBaseInitializer()) { | ||||||||||||
5674 | TypeSourceInfo *TInfo = SubstType(Init->getTypeSourceInfo(), | ||||||||||||
5675 | TemplateArgs, | ||||||||||||
5676 | Init->getSourceLocation(), | ||||||||||||
5677 | New->getDeclName()); | ||||||||||||
5678 | if (!TInfo) { | ||||||||||||
5679 | AnyErrors = true; | ||||||||||||
5680 | New->setInvalidDecl(); | ||||||||||||
5681 | continue; | ||||||||||||
5682 | } | ||||||||||||
5683 | |||||||||||||
5684 | if (Init->isBaseInitializer()) | ||||||||||||
5685 | NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.get(), | ||||||||||||
5686 | New->getParent(), EllipsisLoc); | ||||||||||||
5687 | else | ||||||||||||
5688 | NewInit = BuildDelegatingInitializer(TInfo, TempInit.get(), | ||||||||||||
5689 | cast<CXXRecordDecl>(CurContext->getParent())); | ||||||||||||
5690 | } else if (Init->isMemberInitializer()) { | ||||||||||||
5691 | FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl( | ||||||||||||
5692 | Init->getMemberLocation(), | ||||||||||||
5693 | Init->getMember(), | ||||||||||||
5694 | TemplateArgs)); | ||||||||||||
5695 | if (!Member) { | ||||||||||||
5696 | AnyErrors = true; | ||||||||||||
5697 | New->setInvalidDecl(); | ||||||||||||
5698 | continue; | ||||||||||||
5699 | } | ||||||||||||
5700 | |||||||||||||
5701 | NewInit = BuildMemberInitializer(Member, TempInit.get(), | ||||||||||||
5702 | Init->getSourceLocation()); | ||||||||||||
5703 | } else if (Init->isIndirectMemberInitializer()) { | ||||||||||||
5704 | IndirectFieldDecl *IndirectMember = | ||||||||||||
5705 | cast_or_null<IndirectFieldDecl>(FindInstantiatedDecl( | ||||||||||||
5706 | Init->getMemberLocation(), | ||||||||||||
5707 | Init->getIndirectMember(), TemplateArgs)); | ||||||||||||
5708 | |||||||||||||
5709 | if (!IndirectMember) { | ||||||||||||
5710 | AnyErrors = true; | ||||||||||||
5711 | New->setInvalidDecl(); | ||||||||||||
5712 | continue; | ||||||||||||
5713 | } | ||||||||||||
5714 | |||||||||||||
5715 | NewInit = BuildMemberInitializer(IndirectMember, TempInit.get(), | ||||||||||||
5716 | Init->getSourceLocation()); | ||||||||||||
5717 | } | ||||||||||||
5718 | |||||||||||||
5719 | if (NewInit.isInvalid()) { | ||||||||||||
5720 | AnyErrors = true; | ||||||||||||
5721 | New->setInvalidDecl(); | ||||||||||||
5722 | } else { | ||||||||||||
5723 | NewInits.push_back(NewInit.get()); | ||||||||||||
5724 | } | ||||||||||||
5725 | } | ||||||||||||
5726 | |||||||||||||
5727 | // Assign all the initializers to the new constructor. | ||||||||||||
5728 | ActOnMemInitializers(New, | ||||||||||||
5729 | /*FIXME: ColonLoc */ | ||||||||||||
5730 | SourceLocation(), | ||||||||||||
5731 | NewInits, | ||||||||||||
5732 | AnyErrors); | ||||||||||||
5733 | } | ||||||||||||
5734 | |||||||||||||
5735 | // TODO: this could be templated if the various decl types used the | ||||||||||||
5736 | // same method name. | ||||||||||||
5737 | static bool isInstantiationOf(ClassTemplateDecl *Pattern, | ||||||||||||
5738 | ClassTemplateDecl *Instance) { | ||||||||||||
5739 | Pattern = Pattern->getCanonicalDecl(); | ||||||||||||
5740 | |||||||||||||
5741 | do { | ||||||||||||
5742 | Instance = Instance->getCanonicalDecl(); | ||||||||||||
5743 | if (Pattern == Instance) return true; | ||||||||||||
5744 | Instance = Instance->getInstantiatedFromMemberTemplate(); | ||||||||||||
5745 | } while (Instance); | ||||||||||||
5746 | |||||||||||||
5747 | return false; | ||||||||||||
5748 | } | ||||||||||||
5749 | |||||||||||||
5750 | static bool isInstantiationOf(FunctionTemplateDecl *Pattern, | ||||||||||||
5751 | FunctionTemplateDecl *Instance) { | ||||||||||||
5752 | Pattern = Pattern->getCanonicalDecl(); | ||||||||||||
5753 | |||||||||||||
5754 | do { | ||||||||||||
5755 | Instance = Instance->getCanonicalDecl(); | ||||||||||||
5756 | if (Pattern == Instance) return true; | ||||||||||||
5757 | Instance = Instance->getInstantiatedFromMemberTemplate(); | ||||||||||||
5758 | } while (Instance); | ||||||||||||
5759 | |||||||||||||
5760 | return false; | ||||||||||||
5761 | } | ||||||||||||
5762 | |||||||||||||
5763 | static bool | ||||||||||||
5764 | isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern, | ||||||||||||
5765 | ClassTemplatePartialSpecializationDecl *Instance) { | ||||||||||||
5766 | Pattern | ||||||||||||
5767 | = cast<ClassTemplatePartialSpecializationDecl>(Pattern->getCanonicalDecl()); | ||||||||||||
5768 | do { | ||||||||||||
5769 | Instance = cast<ClassTemplatePartialSpecializationDecl>( | ||||||||||||
5770 | Instance->getCanonicalDecl()); | ||||||||||||
5771 | if (Pattern == Instance) | ||||||||||||
5772 | return true; | ||||||||||||
5773 | Instance = Instance->getInstantiatedFromMember(); | ||||||||||||
5774 | } while (Instance); | ||||||||||||
5775 | |||||||||||||
5776 | return false; | ||||||||||||
5777 | } | ||||||||||||
5778 | |||||||||||||
5779 | static bool isInstantiationOf(CXXRecordDecl *Pattern, | ||||||||||||
5780 | CXXRecordDecl *Instance) { | ||||||||||||
5781 | Pattern = Pattern->getCanonicalDecl(); | ||||||||||||
5782 | |||||||||||||
5783 | do { | ||||||||||||
5784 | Instance = Instance->getCanonicalDecl(); | ||||||||||||
5785 | if (Pattern == Instance) return true; | ||||||||||||
5786 | Instance = Instance->getInstantiatedFromMemberClass(); | ||||||||||||
5787 | } while (Instance); | ||||||||||||
5788 | |||||||||||||
5789 | return false; | ||||||||||||
5790 | } | ||||||||||||
5791 | |||||||||||||
5792 | static bool isInstantiationOf(FunctionDecl *Pattern, | ||||||||||||
5793 | FunctionDecl *Instance) { | ||||||||||||
5794 | Pattern = Pattern->getCanonicalDecl(); | ||||||||||||
5795 | |||||||||||||
5796 | do { | ||||||||||||
5797 | Instance = Instance->getCanonicalDecl(); | ||||||||||||
5798 | if (Pattern == Instance) return true; | ||||||||||||
5799 | Instance = Instance->getInstantiatedFromMemberFunction(); | ||||||||||||
5800 | } while (Instance); | ||||||||||||
5801 | |||||||||||||
5802 | return false; | ||||||||||||
5803 | } | ||||||||||||
5804 | |||||||||||||
5805 | static bool isInstantiationOf(EnumDecl *Pattern, | ||||||||||||
5806 | EnumDecl *Instance) { | ||||||||||||
5807 | Pattern = Pattern->getCanonicalDecl(); | ||||||||||||
5808 | |||||||||||||
5809 | do { | ||||||||||||
5810 | Instance = Instance->getCanonicalDecl(); | ||||||||||||
5811 | if (Pattern == Instance) return true; | ||||||||||||
5812 | Instance = Instance->getInstantiatedFromMemberEnum(); | ||||||||||||
5813 | } while (Instance); | ||||||||||||
5814 | |||||||||||||
5815 | return false; | ||||||||||||
5816 | } | ||||||||||||
5817 | |||||||||||||
5818 | static bool isInstantiationOf(UsingShadowDecl *Pattern, | ||||||||||||
5819 | UsingShadowDecl *Instance, | ||||||||||||
5820 | ASTContext &C) { | ||||||||||||
5821 | return declaresSameEntity(C.getInstantiatedFromUsingShadowDecl(Instance), | ||||||||||||
5822 | Pattern); | ||||||||||||
5823 | } | ||||||||||||
5824 | |||||||||||||
5825 | static bool isInstantiationOf(UsingDecl *Pattern, UsingDecl *Instance, | ||||||||||||
5826 | ASTContext &C) { | ||||||||||||
5827 | return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern); | ||||||||||||
5828 | } | ||||||||||||
5829 | |||||||||||||
5830 | template<typename T> | ||||||||||||
5831 | static bool isInstantiationOfUnresolvedUsingDecl(T *Pattern, Decl *Other, | ||||||||||||
5832 | ASTContext &Ctx) { | ||||||||||||
5833 | // An unresolved using declaration can instantiate to an unresolved using | ||||||||||||
5834 | // declaration, or to a using declaration or a using declaration pack. | ||||||||||||
5835 | // | ||||||||||||
5836 | // Multiple declarations can claim to be instantiated from an unresolved | ||||||||||||
5837 | // using declaration if it's a pack expansion. We want the UsingPackDecl | ||||||||||||
5838 | // in that case, not the individual UsingDecls within the pack. | ||||||||||||
5839 | bool OtherIsPackExpansion; | ||||||||||||
5840 | NamedDecl *OtherFrom; | ||||||||||||
5841 | if (auto *OtherUUD = dyn_cast<T>(Other)) { | ||||||||||||
5842 | OtherIsPackExpansion = OtherUUD->isPackExpansion(); | ||||||||||||
5843 | OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUUD); | ||||||||||||
5844 | } else if (auto *OtherUPD = dyn_cast<UsingPackDecl>(Other)) { | ||||||||||||
5845 | OtherIsPackExpansion = true; | ||||||||||||
5846 | OtherFrom = OtherUPD->getInstantiatedFromUsingDecl(); | ||||||||||||
5847 | } else if (auto *OtherUD = dyn_cast<UsingDecl>(Other)) { | ||||||||||||
5848 | OtherIsPackExpansion = false; | ||||||||||||
5849 | OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUD); | ||||||||||||
5850 | } else { | ||||||||||||
5851 | return false; | ||||||||||||
5852 | } | ||||||||||||
5853 | return Pattern->isPackExpansion() == OtherIsPackExpansion && | ||||||||||||
5854 | declaresSameEntity(OtherFrom, Pattern); | ||||||||||||
5855 | } | ||||||||||||
5856 | |||||||||||||
5857 | static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, | ||||||||||||
5858 | VarDecl *Instance) { | ||||||||||||
5859 | assert(Instance->isStaticDataMember())(static_cast <bool> (Instance->isStaticDataMember()) ? void (0) : __assert_fail ("Instance->isStaticDataMember()" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 5859, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
5860 | |||||||||||||
5861 | Pattern = Pattern->getCanonicalDecl(); | ||||||||||||
5862 | |||||||||||||
5863 | do { | ||||||||||||
5864 | Instance = Instance->getCanonicalDecl(); | ||||||||||||
5865 | if (Pattern == Instance) return true; | ||||||||||||
5866 | Instance = Instance->getInstantiatedFromStaticDataMember(); | ||||||||||||
5867 | } while (Instance); | ||||||||||||
5868 | |||||||||||||
5869 | return false; | ||||||||||||
5870 | } | ||||||||||||
5871 | |||||||||||||
5872 | // Other is the prospective instantiation | ||||||||||||
5873 | // D is the prospective pattern | ||||||||||||
5874 | static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) { | ||||||||||||
5875 | if (auto *UUD = dyn_cast<UnresolvedUsingTypenameDecl>(D)) | ||||||||||||
5876 | return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx); | ||||||||||||
5877 | |||||||||||||
5878 | if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(D)) | ||||||||||||
5879 | return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx); | ||||||||||||
5880 | |||||||||||||
5881 | if (D->getKind() != Other->getKind()) | ||||||||||||
5882 | return false; | ||||||||||||
5883 | |||||||||||||
5884 | if (auto *Record = dyn_cast<CXXRecordDecl>(Other)) | ||||||||||||
5885 | return isInstantiationOf(cast<CXXRecordDecl>(D), Record); | ||||||||||||
5886 | |||||||||||||
5887 | if (auto *Function = dyn_cast<FunctionDecl>(Other)) | ||||||||||||
5888 | return isInstantiationOf(cast<FunctionDecl>(D), Function); | ||||||||||||
5889 | |||||||||||||
5890 | if (auto *Enum = dyn_cast<EnumDecl>(Other)) | ||||||||||||
5891 | return isInstantiationOf(cast<EnumDecl>(D), Enum); | ||||||||||||
5892 | |||||||||||||
5893 | if (auto *Var = dyn_cast<VarDecl>(Other)) | ||||||||||||
5894 | if (Var->isStaticDataMember()) | ||||||||||||
5895 | return isInstantiationOfStaticDataMember(cast<VarDecl>(D), Var); | ||||||||||||
5896 | |||||||||||||
5897 | if (auto *Temp = dyn_cast<ClassTemplateDecl>(Other)) | ||||||||||||
5898 | return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp); | ||||||||||||
5899 | |||||||||||||
5900 | if (auto *Temp = dyn_cast<FunctionTemplateDecl>(Other)) | ||||||||||||
5901 | return isInstantiationOf(cast<FunctionTemplateDecl>(D), Temp); | ||||||||||||
5902 | |||||||||||||
5903 | if (auto *PartialSpec = | ||||||||||||
5904 | dyn_cast<ClassTemplatePartialSpecializationDecl>(Other)) | ||||||||||||
5905 | return isInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(D), | ||||||||||||
5906 | PartialSpec); | ||||||||||||
5907 | |||||||||||||
5908 | if (auto *Field = dyn_cast<FieldDecl>(Other)) { | ||||||||||||
5909 | if (!Field->getDeclName()) { | ||||||||||||
5910 | // This is an unnamed field. | ||||||||||||
5911 | return declaresSameEntity(Ctx.getInstantiatedFromUnnamedFieldDecl(Field), | ||||||||||||
5912 | cast<FieldDecl>(D)); | ||||||||||||
5913 | } | ||||||||||||
5914 | } | ||||||||||||
5915 | |||||||||||||
5916 | if (auto *Using = dyn_cast<UsingDecl>(Other)) | ||||||||||||
5917 | return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx); | ||||||||||||
5918 | |||||||||||||
5919 | if (auto *Shadow = dyn_cast<UsingShadowDecl>(Other)) | ||||||||||||
5920 | return isInstantiationOf(cast<UsingShadowDecl>(D), Shadow, Ctx); | ||||||||||||
5921 | |||||||||||||
5922 | return D->getDeclName() && | ||||||||||||
5923 | D->getDeclName() == cast<NamedDecl>(Other)->getDeclName(); | ||||||||||||
5924 | } | ||||||||||||
5925 | |||||||||||||
5926 | template<typename ForwardIterator> | ||||||||||||
5927 | static NamedDecl *findInstantiationOf(ASTContext &Ctx, | ||||||||||||
5928 | NamedDecl *D, | ||||||||||||
5929 | ForwardIterator first, | ||||||||||||
5930 | ForwardIterator last) { | ||||||||||||
5931 | for (; first != last; ++first) | ||||||||||||
5932 | if (isInstantiationOf(Ctx, D, *first)) | ||||||||||||
5933 | return cast<NamedDecl>(*first); | ||||||||||||
5934 | |||||||||||||
5935 | return nullptr; | ||||||||||||
5936 | } | ||||||||||||
5937 | |||||||||||||
5938 | /// Finds the instantiation of the given declaration context | ||||||||||||
5939 | /// within the current instantiation. | ||||||||||||
5940 | /// | ||||||||||||
5941 | /// \returns NULL if there was an error | ||||||||||||
5942 | DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC, | ||||||||||||
5943 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
5944 | if (NamedDecl *D = dyn_cast<NamedDecl>(DC)) { | ||||||||||||
5945 | Decl* ID = FindInstantiatedDecl(Loc, D, TemplateArgs, true); | ||||||||||||
5946 | return cast_or_null<DeclContext>(ID); | ||||||||||||
5947 | } else return DC; | ||||||||||||
5948 | } | ||||||||||||
5949 | |||||||||||||
5950 | /// Determine whether the given context is dependent on template parameters at | ||||||||||||
5951 | /// level \p Level or below. | ||||||||||||
5952 | /// | ||||||||||||
5953 | /// Sometimes we only substitute an inner set of template arguments and leave | ||||||||||||
5954 | /// the outer templates alone. In such cases, contexts dependent only on the | ||||||||||||
5955 | /// outer levels are not effectively dependent. | ||||||||||||
5956 | static bool isDependentContextAtLevel(DeclContext *DC, unsigned Level) { | ||||||||||||
5957 | if (!DC->isDependentContext()) | ||||||||||||
5958 | return false; | ||||||||||||
5959 | if (!Level) | ||||||||||||
5960 | return true; | ||||||||||||
5961 | return cast<Decl>(DC)->getTemplateDepth() > Level; | ||||||||||||
5962 | } | ||||||||||||
5963 | |||||||||||||
5964 | /// Find the instantiation of the given declaration within the | ||||||||||||
5965 | /// current instantiation. | ||||||||||||
5966 | /// | ||||||||||||
5967 | /// This routine is intended to be used when \p D is a declaration | ||||||||||||
5968 | /// referenced from within a template, that needs to mapped into the | ||||||||||||
5969 | /// corresponding declaration within an instantiation. For example, | ||||||||||||
5970 | /// given: | ||||||||||||
5971 | /// | ||||||||||||
5972 | /// \code | ||||||||||||
5973 | /// template<typename T> | ||||||||||||
5974 | /// struct X { | ||||||||||||
5975 | /// enum Kind { | ||||||||||||
5976 | /// KnownValue = sizeof(T) | ||||||||||||
5977 | /// }; | ||||||||||||
5978 | /// | ||||||||||||
5979 | /// bool getKind() const { return KnownValue; } | ||||||||||||
5980 | /// }; | ||||||||||||
5981 | /// | ||||||||||||
5982 | /// template struct X<int>; | ||||||||||||
5983 | /// \endcode | ||||||||||||
5984 | /// | ||||||||||||
5985 | /// In the instantiation of X<int>::getKind(), we need to map the \p | ||||||||||||
5986 | /// EnumConstantDecl for \p KnownValue (which refers to | ||||||||||||
5987 | /// X<T>::<Kind>::KnownValue) to its instantiation (X<int>::<Kind>::KnownValue). | ||||||||||||
5988 | /// \p FindInstantiatedDecl performs this mapping from within the instantiation | ||||||||||||
5989 | /// of X<int>. | ||||||||||||
5990 | NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, | ||||||||||||
5991 | const MultiLevelTemplateArgumentList &TemplateArgs, | ||||||||||||
5992 | bool FindingInstantiatedContext) { | ||||||||||||
5993 | DeclContext *ParentDC = D->getDeclContext(); | ||||||||||||
5994 | // Determine whether our parent context depends on any of the template | ||||||||||||
5995 | // arguments we're currently substituting. | ||||||||||||
5996 | bool ParentDependsOnArgs = isDependentContextAtLevel( | ||||||||||||
5997 | ParentDC, TemplateArgs.getNumRetainedOuterLevels()); | ||||||||||||
5998 | // FIXME: Parameters of pointer to functions (y below) that are themselves | ||||||||||||
5999 | // parameters (p below) can have their ParentDC set to the translation-unit | ||||||||||||
6000 | // - thus we can not consistently check if the ParentDC of such a parameter | ||||||||||||
6001 | // is Dependent or/and a FunctionOrMethod. | ||||||||||||
6002 | // For e.g. this code, during Template argument deduction tries to | ||||||||||||
6003 | // find an instantiated decl for (T y) when the ParentDC for y is | ||||||||||||
6004 | // the translation unit. | ||||||||||||
6005 | // e.g. template <class T> void Foo(auto (*p)(T y) -> decltype(y())) {} | ||||||||||||
6006 | // float baz(float(*)()) { return 0.0; } | ||||||||||||
6007 | // Foo(baz); | ||||||||||||
6008 | // The better fix here is perhaps to ensure that a ParmVarDecl, by the time | ||||||||||||
6009 | // it gets here, always has a FunctionOrMethod as its ParentDC?? | ||||||||||||
6010 | // For now: | ||||||||||||
6011 | // - as long as we have a ParmVarDecl whose parent is non-dependent and | ||||||||||||
6012 | // whose type is not instantiation dependent, do nothing to the decl | ||||||||||||
6013 | // - otherwise find its instantiated decl. | ||||||||||||
6014 | if (isa<ParmVarDecl>(D) && !ParentDependsOnArgs && | ||||||||||||
6015 | !cast<ParmVarDecl>(D)->getType()->isInstantiationDependentType()) | ||||||||||||
6016 | return D; | ||||||||||||
6017 | if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) || | ||||||||||||
6018 | isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) || | ||||||||||||
6019 | (ParentDependsOnArgs && (ParentDC->isFunctionOrMethod() || | ||||||||||||
6020 | isa<OMPDeclareReductionDecl>(ParentDC) || | ||||||||||||
6021 | isa<OMPDeclareMapperDecl>(ParentDC))) || | ||||||||||||
6022 | (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda() && | ||||||||||||
6023 | cast<CXXRecordDecl>(D)->getTemplateDepth() > | ||||||||||||
6024 | TemplateArgs.getNumRetainedOuterLevels())) { | ||||||||||||
6025 | // D is a local of some kind. Look into the map of local | ||||||||||||
6026 | // declarations to their instantiations. | ||||||||||||
6027 | if (CurrentInstantiationScope) { | ||||||||||||
6028 | if (auto Found = CurrentInstantiationScope->findInstantiationOf(D)) { | ||||||||||||
6029 | if (Decl *FD = Found->dyn_cast<Decl *>()) | ||||||||||||
6030 | return cast<NamedDecl>(FD); | ||||||||||||
6031 | |||||||||||||
6032 | int PackIdx = ArgumentPackSubstitutionIndex; | ||||||||||||
6033 | assert(PackIdx != -1 &&(static_cast <bool> (PackIdx != -1 && "found declaration pack but not pack expanding" ) ? void (0) : __assert_fail ("PackIdx != -1 && \"found declaration pack but not pack expanding\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6034, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
6034 | "found declaration pack but not pack expanding")(static_cast <bool> (PackIdx != -1 && "found declaration pack but not pack expanding" ) ? void (0) : __assert_fail ("PackIdx != -1 && \"found declaration pack but not pack expanding\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6034, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
6035 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; | ||||||||||||
6036 | return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]); | ||||||||||||
6037 | } | ||||||||||||
6038 | } | ||||||||||||
6039 | |||||||||||||
6040 | // If we're performing a partial substitution during template argument | ||||||||||||
6041 | // deduction, we may not have values for template parameters yet. They | ||||||||||||
6042 | // just map to themselves. | ||||||||||||
6043 | if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) || | ||||||||||||
6044 | isa<TemplateTemplateParmDecl>(D)) | ||||||||||||
6045 | return D; | ||||||||||||
6046 | |||||||||||||
6047 | if (D->isInvalidDecl()) | ||||||||||||
6048 | return nullptr; | ||||||||||||
6049 | |||||||||||||
6050 | // Normally this function only searches for already instantiated declaration | ||||||||||||
6051 | // however we have to make an exclusion for local types used before | ||||||||||||
6052 | // definition as in the code: | ||||||||||||
6053 | // | ||||||||||||
6054 | // template<typename T> void f1() { | ||||||||||||
6055 | // void g1(struct x1); | ||||||||||||
6056 | // struct x1 {}; | ||||||||||||
6057 | // } | ||||||||||||
6058 | // | ||||||||||||
6059 | // In this case instantiation of the type of 'g1' requires definition of | ||||||||||||
6060 | // 'x1', which is defined later. Error recovery may produce an enum used | ||||||||||||
6061 | // before definition. In these cases we need to instantiate relevant | ||||||||||||
6062 | // declarations here. | ||||||||||||
6063 | bool NeedInstantiate = false; | ||||||||||||
6064 | if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) | ||||||||||||
6065 | NeedInstantiate = RD->isLocalClass(); | ||||||||||||
6066 | else if (isa<TypedefNameDecl>(D) && | ||||||||||||
6067 | isa<CXXDeductionGuideDecl>(D->getDeclContext())) | ||||||||||||
6068 | NeedInstantiate = true; | ||||||||||||
6069 | else | ||||||||||||
6070 | NeedInstantiate = isa<EnumDecl>(D); | ||||||||||||
6071 | if (NeedInstantiate) { | ||||||||||||
6072 | Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); | ||||||||||||
6073 | CurrentInstantiationScope->InstantiatedLocal(D, Inst); | ||||||||||||
6074 | return cast<TypeDecl>(Inst); | ||||||||||||
6075 | } | ||||||||||||
6076 | |||||||||||||
6077 | // If we didn't find the decl, then we must have a label decl that hasn't | ||||||||||||
6078 | // been found yet. Lazily instantiate it and return it now. | ||||||||||||
6079 | assert(isa<LabelDecl>(D))(static_cast <bool> (isa<LabelDecl>(D)) ? void (0 ) : __assert_fail ("isa<LabelDecl>(D)", "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp" , 6079, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
6080 | |||||||||||||
6081 | Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); | ||||||||||||
6082 | assert(Inst && "Failed to instantiate label??")(static_cast <bool> (Inst && "Failed to instantiate label??" ) ? void (0) : __assert_fail ("Inst && \"Failed to instantiate label??\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6082, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
6083 | |||||||||||||
6084 | CurrentInstantiationScope->InstantiatedLocal(D, Inst); | ||||||||||||
6085 | return cast<LabelDecl>(Inst); | ||||||||||||
6086 | } | ||||||||||||
6087 | |||||||||||||
6088 | if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { | ||||||||||||
6089 | if (!Record->isDependentContext()) | ||||||||||||
6090 | return D; | ||||||||||||
6091 | |||||||||||||
6092 | // Determine whether this record is the "templated" declaration describing | ||||||||||||
6093 | // a class template or class template partial specialization. | ||||||||||||
6094 | ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate(); | ||||||||||||
6095 | if (ClassTemplate) | ||||||||||||
6096 | ClassTemplate = ClassTemplate->getCanonicalDecl(); | ||||||||||||
6097 | else if (ClassTemplatePartialSpecializationDecl *PartialSpec | ||||||||||||
6098 | = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) | ||||||||||||
6099 | ClassTemplate = PartialSpec->getSpecializedTemplate()->getCanonicalDecl(); | ||||||||||||
6100 | |||||||||||||
6101 | // Walk the current context to find either the record or an instantiation of | ||||||||||||
6102 | // it. | ||||||||||||
6103 | DeclContext *DC = CurContext; | ||||||||||||
6104 | while (!DC->isFileContext()) { | ||||||||||||
6105 | // If we're performing substitution while we're inside the template | ||||||||||||
6106 | // definition, we'll find our own context. We're done. | ||||||||||||
6107 | if (DC->Equals(Record)) | ||||||||||||
6108 | return Record; | ||||||||||||
6109 | |||||||||||||
6110 | if (CXXRecordDecl *InstRecord = dyn_cast<CXXRecordDecl>(DC)) { | ||||||||||||
6111 | // Check whether we're in the process of instantiating a class template | ||||||||||||
6112 | // specialization of the template we're mapping. | ||||||||||||
6113 | if (ClassTemplateSpecializationDecl *InstSpec | ||||||||||||
6114 | = dyn_cast<ClassTemplateSpecializationDecl>(InstRecord)){ | ||||||||||||
6115 | ClassTemplateDecl *SpecTemplate = InstSpec->getSpecializedTemplate(); | ||||||||||||
6116 | if (ClassTemplate && isInstantiationOf(ClassTemplate, SpecTemplate)) | ||||||||||||
6117 | return InstRecord; | ||||||||||||
6118 | } | ||||||||||||
6119 | |||||||||||||
6120 | // Check whether we're in the process of instantiating a member class. | ||||||||||||
6121 | if (isInstantiationOf(Record, InstRecord)) | ||||||||||||
6122 | return InstRecord; | ||||||||||||
6123 | } | ||||||||||||
6124 | |||||||||||||
6125 | // Move to the outer template scope. | ||||||||||||
6126 | if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) { | ||||||||||||
6127 | // FIXME: We should use `getNonTransparentDeclContext()` here instead | ||||||||||||
6128 | // of `getDeclContext()` once we find the invalid test case. | ||||||||||||
6129 | if (FD->getFriendObjectKind() && FD->getDeclContext()->isFileContext()){ | ||||||||||||
6130 | DC = FD->getLexicalDeclContext(); | ||||||||||||
6131 | continue; | ||||||||||||
6132 | } | ||||||||||||
6133 | // An implicit deduction guide acts as if it's within the class template | ||||||||||||
6134 | // specialization described by its name and first N template params. | ||||||||||||
6135 | auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD); | ||||||||||||
6136 | if (Guide && Guide->isImplicit()) { | ||||||||||||
6137 | TemplateDecl *TD = Guide->getDeducedTemplate(); | ||||||||||||
6138 | // Convert the arguments to an "as-written" list. | ||||||||||||
6139 | TemplateArgumentListInfo Args(Loc, Loc); | ||||||||||||
6140 | for (TemplateArgument Arg : TemplateArgs.getInnermost().take_front( | ||||||||||||
6141 | TD->getTemplateParameters()->size())) { | ||||||||||||
6142 | ArrayRef<TemplateArgument> Unpacked(Arg); | ||||||||||||
6143 | if (Arg.getKind() == TemplateArgument::Pack) | ||||||||||||
6144 | Unpacked = Arg.pack_elements(); | ||||||||||||
6145 | for (TemplateArgument UnpackedArg : Unpacked) | ||||||||||||
6146 | Args.addArgument( | ||||||||||||
6147 | getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc)); | ||||||||||||
6148 | } | ||||||||||||
6149 | QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args); | ||||||||||||
6150 | if (T.isNull()) | ||||||||||||
6151 | return nullptr; | ||||||||||||
6152 | auto *SubstRecord = T->getAsCXXRecordDecl(); | ||||||||||||
6153 | assert(SubstRecord && "class template id not a class type?")(static_cast <bool> (SubstRecord && "class template id not a class type?" ) ? void (0) : __assert_fail ("SubstRecord && \"class template id not a class type?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6153, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
6154 | // Check that this template-id names the primary template and not a | ||||||||||||
6155 | // partial or explicit specialization. (In the latter cases, it's | ||||||||||||
6156 | // meaningless to attempt to find an instantiation of D within the | ||||||||||||
6157 | // specialization.) | ||||||||||||
6158 | // FIXME: The standard doesn't say what should happen here. | ||||||||||||
6159 | if (FindingInstantiatedContext && | ||||||||||||
6160 | usesPartialOrExplicitSpecialization( | ||||||||||||
6161 | Loc, cast<ClassTemplateSpecializationDecl>(SubstRecord))) { | ||||||||||||
6162 | Diag(Loc, diag::err_specialization_not_primary_template) | ||||||||||||
6163 | << T << (SubstRecord->getTemplateSpecializationKind() == | ||||||||||||
6164 | TSK_ExplicitSpecialization); | ||||||||||||
6165 | return nullptr; | ||||||||||||
6166 | } | ||||||||||||
6167 | DC = SubstRecord; | ||||||||||||
6168 | continue; | ||||||||||||
6169 | } | ||||||||||||
6170 | } | ||||||||||||
6171 | |||||||||||||
6172 | DC = DC->getParent(); | ||||||||||||
6173 | } | ||||||||||||
6174 | |||||||||||||
6175 | // Fall through to deal with other dependent record types (e.g., | ||||||||||||
6176 | // anonymous unions in class templates). | ||||||||||||
6177 | } | ||||||||||||
6178 | |||||||||||||
6179 | if (!ParentDependsOnArgs) | ||||||||||||
6180 | return D; | ||||||||||||
6181 | |||||||||||||
6182 | ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs); | ||||||||||||
6183 | if (!ParentDC) | ||||||||||||
6184 | return nullptr; | ||||||||||||
6185 | |||||||||||||
6186 | if (ParentDC != D->getDeclContext()) { | ||||||||||||
6187 | // We performed some kind of instantiation in the parent context, | ||||||||||||
6188 | // so now we need to look into the instantiated parent context to | ||||||||||||
6189 | // find the instantiation of the declaration D. | ||||||||||||
6190 | |||||||||||||
6191 | // If our context used to be dependent, we may need to instantiate | ||||||||||||
6192 | // it before performing lookup into that context. | ||||||||||||
6193 | bool IsBeingInstantiated = false; | ||||||||||||
6194 | if (CXXRecordDecl *Spec = dyn_cast<CXXRecordDecl>(ParentDC)) { | ||||||||||||
6195 | if (!Spec->isDependentContext()) { | ||||||||||||
6196 | QualType T = Context.getTypeDeclType(Spec); | ||||||||||||
6197 | const RecordType *Tag = T->getAs<RecordType>(); | ||||||||||||
6198 | assert(Tag && "type of non-dependent record is not a RecordType")(static_cast <bool> (Tag && "type of non-dependent record is not a RecordType" ) ? void (0) : __assert_fail ("Tag && \"type of non-dependent record is not a RecordType\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6198, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
6199 | if (Tag->isBeingDefined()) | ||||||||||||
6200 | IsBeingInstantiated = true; | ||||||||||||
6201 | if (!Tag->isBeingDefined() && | ||||||||||||
6202 | RequireCompleteType(Loc, T, diag::err_incomplete_type)) | ||||||||||||
6203 | return nullptr; | ||||||||||||
6204 | |||||||||||||
6205 | ParentDC = Tag->getDecl(); | ||||||||||||
6206 | } | ||||||||||||
6207 | } | ||||||||||||
6208 | |||||||||||||
6209 | NamedDecl *Result = nullptr; | ||||||||||||
6210 | // FIXME: If the name is a dependent name, this lookup won't necessarily | ||||||||||||
6211 | // find it. Does that ever matter? | ||||||||||||
6212 | if (auto Name = D->getDeclName()) { | ||||||||||||
6213 | DeclarationNameInfo NameInfo(Name, D->getLocation()); | ||||||||||||
6214 | DeclarationNameInfo NewNameInfo = | ||||||||||||
6215 | SubstDeclarationNameInfo(NameInfo, TemplateArgs); | ||||||||||||
6216 | Name = NewNameInfo.getName(); | ||||||||||||
6217 | if (!Name) | ||||||||||||
6218 | return nullptr; | ||||||||||||
6219 | DeclContext::lookup_result Found = ParentDC->lookup(Name); | ||||||||||||
6220 | |||||||||||||
6221 | Result = findInstantiationOf(Context, D, Found.begin(), Found.end()); | ||||||||||||
6222 | } else { | ||||||||||||
6223 | // Since we don't have a name for the entity we're looking for, | ||||||||||||
6224 | // our only option is to walk through all of the declarations to | ||||||||||||
6225 | // find that name. This will occur in a few cases: | ||||||||||||
6226 | // | ||||||||||||
6227 | // - anonymous struct/union within a template | ||||||||||||
6228 | // - unnamed class/struct/union/enum within a template | ||||||||||||
6229 | // | ||||||||||||
6230 | // FIXME: Find a better way to find these instantiations! | ||||||||||||
6231 | Result = findInstantiationOf(Context, D, | ||||||||||||
6232 | ParentDC->decls_begin(), | ||||||||||||
6233 | ParentDC->decls_end()); | ||||||||||||
6234 | } | ||||||||||||
6235 | |||||||||||||
6236 | if (!Result) { | ||||||||||||
6237 | if (isa<UsingShadowDecl>(D)) { | ||||||||||||
6238 | // UsingShadowDecls can instantiate to nothing because of using hiding. | ||||||||||||
6239 | } else if (hasUncompilableErrorOccurred()) { | ||||||||||||
6240 | // We've already complained about some ill-formed code, so most likely | ||||||||||||
6241 | // this declaration failed to instantiate. There's no point in | ||||||||||||
6242 | // complaining further, since this is normal in invalid code. | ||||||||||||
6243 | // FIXME: Use more fine-grained 'invalid' tracking for this. | ||||||||||||
6244 | } else if (IsBeingInstantiated) { | ||||||||||||
6245 | // The class in which this member exists is currently being | ||||||||||||
6246 | // instantiated, and we haven't gotten around to instantiating this | ||||||||||||
6247 | // member yet. This can happen when the code uses forward declarations | ||||||||||||
6248 | // of member classes, and introduces ordering dependencies via | ||||||||||||
6249 | // template instantiation. | ||||||||||||
6250 | Diag(Loc, diag::err_member_not_yet_instantiated) | ||||||||||||
6251 | << D->getDeclName() | ||||||||||||
6252 | << Context.getTypeDeclType(cast<CXXRecordDecl>(ParentDC)); | ||||||||||||
6253 | Diag(D->getLocation(), diag::note_non_instantiated_member_here); | ||||||||||||
6254 | } else if (EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) { | ||||||||||||
6255 | // This enumeration constant was found when the template was defined, | ||||||||||||
6256 | // but can't be found in the instantiation. This can happen if an | ||||||||||||
6257 | // unscoped enumeration member is explicitly specialized. | ||||||||||||
6258 | EnumDecl *Enum = cast<EnumDecl>(ED->getLexicalDeclContext()); | ||||||||||||
6259 | EnumDecl *Spec = cast<EnumDecl>(FindInstantiatedDecl(Loc, Enum, | ||||||||||||
6260 | TemplateArgs)); | ||||||||||||
6261 | assert(Spec->getTemplateSpecializationKind() ==(static_cast <bool> (Spec->getTemplateSpecializationKind () == TSK_ExplicitSpecialization) ? void (0) : __assert_fail ( "Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6262, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
6262 | TSK_ExplicitSpecialization)(static_cast <bool> (Spec->getTemplateSpecializationKind () == TSK_ExplicitSpecialization) ? void (0) : __assert_fail ( "Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6262, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
6263 | Diag(Loc, diag::err_enumerator_does_not_exist) | ||||||||||||
6264 | << D->getDeclName() | ||||||||||||
6265 | << Context.getTypeDeclType(cast<TypeDecl>(Spec->getDeclContext())); | ||||||||||||
6266 | Diag(Spec->getLocation(), diag::note_enum_specialized_here) | ||||||||||||
6267 | << Context.getTypeDeclType(Spec); | ||||||||||||
6268 | } else { | ||||||||||||
6269 | // We should have found something, but didn't. | ||||||||||||
6270 | llvm_unreachable("Unable to find instantiation of declaration!")::llvm::llvm_unreachable_internal("Unable to find instantiation of declaration!" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6270); | ||||||||||||
6271 | } | ||||||||||||
6272 | } | ||||||||||||
6273 | |||||||||||||
6274 | D = Result; | ||||||||||||
6275 | } | ||||||||||||
6276 | |||||||||||||
6277 | return D; | ||||||||||||
6278 | } | ||||||||||||
6279 | |||||||||||||
6280 | /// Performs template instantiation for all implicit template | ||||||||||||
6281 | /// instantiations we have seen until this point. | ||||||||||||
6282 | void Sema::PerformPendingInstantiations(bool LocalOnly) { | ||||||||||||
6283 | std::deque<PendingImplicitInstantiation> delayedPCHInstantiations; | ||||||||||||
6284 | while (!PendingLocalImplicitInstantiations.empty() || | ||||||||||||
6285 | (!LocalOnly && !PendingInstantiations.empty())) { | ||||||||||||
6286 | PendingImplicitInstantiation Inst; | ||||||||||||
6287 | |||||||||||||
6288 | if (PendingLocalImplicitInstantiations.empty()) { | ||||||||||||
6289 | Inst = PendingInstantiations.front(); | ||||||||||||
6290 | PendingInstantiations.pop_front(); | ||||||||||||
6291 | } else { | ||||||||||||
6292 | Inst = PendingLocalImplicitInstantiations.front(); | ||||||||||||
6293 | PendingLocalImplicitInstantiations.pop_front(); | ||||||||||||
6294 | } | ||||||||||||
6295 | |||||||||||||
6296 | // Instantiate function definitions | ||||||||||||
6297 | if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) { | ||||||||||||
6298 | bool DefinitionRequired = Function->getTemplateSpecializationKind() == | ||||||||||||
6299 | TSK_ExplicitInstantiationDefinition; | ||||||||||||
6300 | if (Function->isMultiVersion()) { | ||||||||||||
6301 | getASTContext().forEachMultiversionedFunctionVersion( | ||||||||||||
6302 | Function, [this, Inst, DefinitionRequired](FunctionDecl *CurFD) { | ||||||||||||
6303 | InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, CurFD, true, | ||||||||||||
6304 | DefinitionRequired, true); | ||||||||||||
6305 | if (CurFD->isDefined()) | ||||||||||||
6306 | CurFD->setInstantiationIsPending(false); | ||||||||||||
6307 | }); | ||||||||||||
6308 | } else { | ||||||||||||
6309 | InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, Function, true, | ||||||||||||
6310 | DefinitionRequired, true); | ||||||||||||
6311 | if (Function->isDefined()) | ||||||||||||
6312 | Function->setInstantiationIsPending(false); | ||||||||||||
6313 | } | ||||||||||||
6314 | // Definition of a PCH-ed template declaration may be available only in the TU. | ||||||||||||
6315 | if (!LocalOnly && LangOpts.PCHInstantiateTemplates && | ||||||||||||
6316 | TUKind == TU_Prefix && Function->instantiationIsPending()) | ||||||||||||
6317 | delayedPCHInstantiations.push_back(Inst); | ||||||||||||
6318 | continue; | ||||||||||||
6319 | } | ||||||||||||
6320 | |||||||||||||
6321 | // Instantiate variable definitions | ||||||||||||
6322 | VarDecl *Var = cast<VarDecl>(Inst.first); | ||||||||||||
6323 | |||||||||||||
6324 | assert((Var->isStaticDataMember() ||(static_cast <bool> ((Var->isStaticDataMember() || isa <VarTemplateSpecializationDecl>(Var)) && "Not a static data member, nor a variable template" " specialization?") ? void (0) : __assert_fail ("(Var->isStaticDataMember() || isa<VarTemplateSpecializationDecl>(Var)) && \"Not a static data member, nor a variable template\" \" specialization?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6327, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
6325 | isa<VarTemplateSpecializationDecl>(Var)) &&(static_cast <bool> ((Var->isStaticDataMember() || isa <VarTemplateSpecializationDecl>(Var)) && "Not a static data member, nor a variable template" " specialization?") ? void (0) : __assert_fail ("(Var->isStaticDataMember() || isa<VarTemplateSpecializationDecl>(Var)) && \"Not a static data member, nor a variable template\" \" specialization?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6327, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
6326 | "Not a static data member, nor a variable template"(static_cast <bool> ((Var->isStaticDataMember() || isa <VarTemplateSpecializationDecl>(Var)) && "Not a static data member, nor a variable template" " specialization?") ? void (0) : __assert_fail ("(Var->isStaticDataMember() || isa<VarTemplateSpecializationDecl>(Var)) && \"Not a static data member, nor a variable template\" \" specialization?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6327, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
6327 | " specialization?")(static_cast <bool> ((Var->isStaticDataMember() || isa <VarTemplateSpecializationDecl>(Var)) && "Not a static data member, nor a variable template" " specialization?") ? void (0) : __assert_fail ("(Var->isStaticDataMember() || isa<VarTemplateSpecializationDecl>(Var)) && \"Not a static data member, nor a variable template\" \" specialization?\"" , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6327, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
6328 | |||||||||||||
6329 | // Don't try to instantiate declarations if the most recent redeclaration | ||||||||||||
6330 | // is invalid. | ||||||||||||
6331 | if (Var->getMostRecentDecl()->isInvalidDecl()) | ||||||||||||
6332 | continue; | ||||||||||||
6333 | |||||||||||||
6334 | // Check if the most recent declaration has changed the specialization kind | ||||||||||||
6335 | // and removed the need for implicit instantiation. | ||||||||||||
6336 | switch (Var->getMostRecentDecl() | ||||||||||||
6337 | ->getTemplateSpecializationKindForInstantiation()) { | ||||||||||||
6338 | case TSK_Undeclared: | ||||||||||||
6339 | llvm_unreachable("Cannot instantitiate an undeclared specialization.")::llvm::llvm_unreachable_internal("Cannot instantitiate an undeclared specialization." , "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp", 6339); | ||||||||||||
6340 | case TSK_ExplicitInstantiationDeclaration: | ||||||||||||
6341 | case TSK_ExplicitSpecialization: | ||||||||||||
6342 | continue; // No longer need to instantiate this type. | ||||||||||||
6343 | case TSK_ExplicitInstantiationDefinition: | ||||||||||||
6344 | // We only need an instantiation if the pending instantiation *is* the | ||||||||||||
6345 | // explicit instantiation. | ||||||||||||
6346 | if (Var != Var->getMostRecentDecl()) | ||||||||||||
6347 | continue; | ||||||||||||
6348 | break; | ||||||||||||
6349 | case TSK_ImplicitInstantiation: | ||||||||||||
6350 | break; | ||||||||||||
6351 | } | ||||||||||||
6352 | |||||||||||||
6353 | PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), | ||||||||||||
6354 | "instantiating variable definition"); | ||||||||||||
6355 | bool DefinitionRequired = Var->getTemplateSpecializationKind() == | ||||||||||||
6356 | TSK_ExplicitInstantiationDefinition; | ||||||||||||
6357 | |||||||||||||
6358 | // Instantiate static data member definitions or variable template | ||||||||||||
6359 | // specializations. | ||||||||||||
6360 | InstantiateVariableDefinition(/*FIXME:*/ Inst.second, Var, true, | ||||||||||||
6361 | DefinitionRequired, true); | ||||||||||||
6362 | } | ||||||||||||
6363 | |||||||||||||
6364 | if (!LocalOnly && LangOpts.PCHInstantiateTemplates) | ||||||||||||
6365 | PendingInstantiations.swap(delayedPCHInstantiations); | ||||||||||||
6366 | } | ||||||||||||
6367 | |||||||||||||
6368 | void Sema::PerformDependentDiagnostics(const DeclContext *Pattern, | ||||||||||||
6369 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
6370 | for (auto *DD : Pattern->ddiags()) { | ||||||||||||
6371 | switch (DD->getKind()) { | ||||||||||||
6372 | case DependentDiagnostic::Access: | ||||||||||||
6373 | HandleDependentAccessCheck(*DD, TemplateArgs); | ||||||||||||
6374 | break; | ||||||||||||
6375 | } | ||||||||||||
6376 | } | ||||||||||||
6377 | } |
1 | //===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | //===----------------------------------------------------------------------===// | |||
7 | // | |||
8 | // This file implements a semantic tree transformation that takes a given | |||
9 | // AST and rebuilds it, possibly transforming some nodes in the process. | |||
10 | // | |||
11 | //===----------------------------------------------------------------------===// | |||
12 | ||||
13 | #ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H | |||
14 | #define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H | |||
15 | ||||
16 | #include "CoroutineStmtBuilder.h" | |||
17 | #include "TypeLocBuilder.h" | |||
18 | #include "clang/AST/Decl.h" | |||
19 | #include "clang/AST/DeclObjC.h" | |||
20 | #include "clang/AST/DeclTemplate.h" | |||
21 | #include "clang/AST/Expr.h" | |||
22 | #include "clang/AST/ExprConcepts.h" | |||
23 | #include "clang/AST/ExprCXX.h" | |||
24 | #include "clang/AST/ExprObjC.h" | |||
25 | #include "clang/AST/ExprOpenMP.h" | |||
26 | #include "clang/AST/OpenMPClause.h" | |||
27 | #include "clang/AST/Stmt.h" | |||
28 | #include "clang/AST/StmtCXX.h" | |||
29 | #include "clang/AST/StmtObjC.h" | |||
30 | #include "clang/AST/StmtOpenMP.h" | |||
31 | #include "clang/Basic/DiagnosticParse.h" | |||
32 | #include "clang/Basic/OpenMPKinds.h" | |||
33 | #include "clang/Sema/Designator.h" | |||
34 | #include "clang/Sema/Lookup.h" | |||
35 | #include "clang/Sema/Ownership.h" | |||
36 | #include "clang/Sema/ParsedTemplate.h" | |||
37 | #include "clang/Sema/ScopeInfo.h" | |||
38 | #include "clang/Sema/SemaDiagnostic.h" | |||
39 | #include "clang/Sema/SemaInternal.h" | |||
40 | #include "llvm/ADT/ArrayRef.h" | |||
41 | #include "llvm/Support/ErrorHandling.h" | |||
42 | #include <algorithm> | |||
43 | ||||
44 | using namespace llvm::omp; | |||
45 | ||||
46 | namespace clang { | |||
47 | using namespace sema; | |||
48 | ||||
49 | /// A semantic tree transformation that allows one to transform one | |||
50 | /// abstract syntax tree into another. | |||
51 | /// | |||
52 | /// A new tree transformation is defined by creating a new subclass \c X of | |||
53 | /// \c TreeTransform<X> and then overriding certain operations to provide | |||
54 | /// behavior specific to that transformation. For example, template | |||
55 | /// instantiation is implemented as a tree transformation where the | |||
56 | /// transformation of TemplateTypeParmType nodes involves substituting the | |||
57 | /// template arguments for their corresponding template parameters; a similar | |||
58 | /// transformation is performed for non-type template parameters and | |||
59 | /// template template parameters. | |||
60 | /// | |||
61 | /// This tree-transformation template uses static polymorphism to allow | |||
62 | /// subclasses to customize any of its operations. Thus, a subclass can | |||
63 | /// override any of the transformation or rebuild operators by providing an | |||
64 | /// operation with the same signature as the default implementation. The | |||
65 | /// overriding function should not be virtual. | |||
66 | /// | |||
67 | /// Semantic tree transformations are split into two stages, either of which | |||
68 | /// can be replaced by a subclass. The "transform" step transforms an AST node | |||
69 | /// or the parts of an AST node using the various transformation functions, | |||
70 | /// then passes the pieces on to the "rebuild" step, which constructs a new AST | |||
71 | /// node of the appropriate kind from the pieces. The default transformation | |||
72 | /// routines recursively transform the operands to composite AST nodes (e.g., | |||
73 | /// the pointee type of a PointerType node) and, if any of those operand nodes | |||
74 | /// were changed by the transformation, invokes the rebuild operation to create | |||
75 | /// a new AST node. | |||
76 | /// | |||
77 | /// Subclasses can customize the transformation at various levels. The | |||
78 | /// most coarse-grained transformations involve replacing TransformType(), | |||
79 | /// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(), | |||
80 | /// TransformTemplateName(), or TransformTemplateArgument() with entirely | |||
81 | /// new implementations. | |||
82 | /// | |||
83 | /// For more fine-grained transformations, subclasses can replace any of the | |||
84 | /// \c TransformXXX functions (where XXX is the name of an AST node, e.g., | |||
85 | /// PointerType, StmtExpr) to alter the transformation. As mentioned previously, | |||
86 | /// replacing TransformTemplateTypeParmType() allows template instantiation | |||
87 | /// to substitute template arguments for their corresponding template | |||
88 | /// parameters. Additionally, subclasses can override the \c RebuildXXX | |||
89 | /// functions to control how AST nodes are rebuilt when their operands change. | |||
90 | /// By default, \c TreeTransform will invoke semantic analysis to rebuild | |||
91 | /// AST nodes. However, certain other tree transformations (e.g, cloning) may | |||
92 | /// be able to use more efficient rebuild steps. | |||
93 | /// | |||
94 | /// There are a handful of other functions that can be overridden, allowing one | |||
95 | /// to avoid traversing nodes that don't need any transformation | |||
96 | /// (\c AlreadyTransformed()), force rebuilding AST nodes even when their | |||
97 | /// operands have not changed (\c AlwaysRebuild()), and customize the | |||
98 | /// default locations and entity names used for type-checking | |||
99 | /// (\c getBaseLocation(), \c getBaseEntity()). | |||
100 | template<typename Derived> | |||
101 | class TreeTransform { | |||
102 | /// Private RAII object that helps us forget and then re-remember | |||
103 | /// the template argument corresponding to a partially-substituted parameter | |||
104 | /// pack. | |||
105 | class ForgetPartiallySubstitutedPackRAII { | |||
106 | Derived &Self; | |||
107 | TemplateArgument Old; | |||
108 | ||||
109 | public: | |||
110 | ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) { | |||
111 | Old = Self.ForgetPartiallySubstitutedPack(); | |||
112 | } | |||
113 | ||||
114 | ~ForgetPartiallySubstitutedPackRAII() { | |||
115 | Self.RememberPartiallySubstitutedPack(Old); | |||
116 | } | |||
117 | }; | |||
118 | ||||
119 | protected: | |||
120 | Sema &SemaRef; | |||
121 | ||||
122 | /// The set of local declarations that have been transformed, for | |||
123 | /// cases where we are forced to build new declarations within the transformer | |||
124 | /// rather than in the subclass (e.g., lambda closure types). | |||
125 | llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls; | |||
126 | ||||
127 | public: | |||
128 | /// Initializes a new tree transformer. | |||
129 | TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { } | |||
130 | ||||
131 | /// Retrieves a reference to the derived class. | |||
132 | Derived &getDerived() { return static_cast<Derived&>(*this); } | |||
133 | ||||
134 | /// Retrieves a reference to the derived class. | |||
135 | const Derived &getDerived() const { | |||
136 | return static_cast<const Derived&>(*this); | |||
137 | } | |||
138 | ||||
139 | static inline ExprResult Owned(Expr *E) { return E; } | |||
140 | static inline StmtResult Owned(Stmt *S) { return S; } | |||
141 | ||||
142 | /// Retrieves a reference to the semantic analysis object used for | |||
143 | /// this tree transform. | |||
144 | Sema &getSema() const { return SemaRef; } | |||
145 | ||||
146 | /// Whether the transformation should always rebuild AST nodes, even | |||
147 | /// if none of the children have changed. | |||
148 | /// | |||
149 | /// Subclasses may override this function to specify when the transformation | |||
150 | /// should rebuild all AST nodes. | |||
151 | /// | |||
152 | /// We must always rebuild all AST nodes when performing variadic template | |||
153 | /// pack expansion, in order to avoid violating the AST invariant that each | |||
154 | /// statement node appears at most once in its containing declaration. | |||
155 | bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; } | |||
156 | ||||
157 | /// Whether the transformation is forming an expression or statement that | |||
158 | /// replaces the original. In this case, we'll reuse mangling numbers from | |||
159 | /// existing lambdas. | |||
160 | bool ReplacingOriginal() { return false; } | |||
161 | ||||
162 | /// Wether CXXConstructExpr can be skipped when they are implicit. | |||
163 | /// They will be reconstructed when used if needed. | |||
164 | /// This is useful when the user that cause rebuilding of the | |||
165 | /// CXXConstructExpr is outside of the expression at which the TreeTransform | |||
166 | /// started. | |||
167 | bool AllowSkippingCXXConstructExpr() { return true; } | |||
168 | ||||
169 | /// Returns the location of the entity being transformed, if that | |||
170 | /// information was not available elsewhere in the AST. | |||
171 | /// | |||
172 | /// By default, returns no source-location information. Subclasses can | |||
173 | /// provide an alternative implementation that provides better location | |||
174 | /// information. | |||
175 | SourceLocation getBaseLocation() { return SourceLocation(); } | |||
176 | ||||
177 | /// Returns the name of the entity being transformed, if that | |||
178 | /// information was not available elsewhere in the AST. | |||
179 | /// | |||
180 | /// By default, returns an empty name. Subclasses can provide an alternative | |||
181 | /// implementation with a more precise name. | |||
182 | DeclarationName getBaseEntity() { return DeclarationName(); } | |||
183 | ||||
184 | /// Sets the "base" location and entity when that | |||
185 | /// information is known based on another transformation. | |||
186 | /// | |||
187 | /// By default, the source location and entity are ignored. Subclasses can | |||
188 | /// override this function to provide a customized implementation. | |||
189 | void setBase(SourceLocation Loc, DeclarationName Entity) { } | |||
190 | ||||
191 | /// RAII object that temporarily sets the base location and entity | |||
192 | /// used for reporting diagnostics in types. | |||
193 | class TemporaryBase { | |||
194 | TreeTransform &Self; | |||
195 | SourceLocation OldLocation; | |||
196 | DeclarationName OldEntity; | |||
197 | ||||
198 | public: | |||
199 | TemporaryBase(TreeTransform &Self, SourceLocation Location, | |||
200 | DeclarationName Entity) : Self(Self) { | |||
201 | OldLocation = Self.getDerived().getBaseLocation(); | |||
202 | OldEntity = Self.getDerived().getBaseEntity(); | |||
203 | ||||
204 | if (Location.isValid()) | |||
205 | Self.getDerived().setBase(Location, Entity); | |||
206 | } | |||
207 | ||||
208 | ~TemporaryBase() { | |||
209 | Self.getDerived().setBase(OldLocation, OldEntity); | |||
210 | } | |||
211 | }; | |||
212 | ||||
213 | /// Determine whether the given type \p T has already been | |||
214 | /// transformed. | |||
215 | /// | |||
216 | /// Subclasses can provide an alternative implementation of this routine | |||
217 | /// to short-circuit evaluation when it is known that a given type will | |||
218 | /// not change. For example, template instantiation need not traverse | |||
219 | /// non-dependent types. | |||
220 | bool AlreadyTransformed(QualType T) { | |||
221 | return T.isNull(); | |||
222 | } | |||
223 | ||||
224 | /// Transform a template parameter depth level. | |||
225 | /// | |||
226 | /// During a transformation that transforms template parameters, this maps | |||
227 | /// an old template parameter depth to a new depth. | |||
228 | unsigned TransformTemplateDepth(unsigned Depth) { | |||
229 | return Depth; | |||
230 | } | |||
231 | ||||
232 | /// Determine whether the given call argument should be dropped, e.g., | |||
233 | /// because it is a default argument. | |||
234 | /// | |||
235 | /// Subclasses can provide an alternative implementation of this routine to | |||
236 | /// determine which kinds of call arguments get dropped. By default, | |||
237 | /// CXXDefaultArgument nodes are dropped (prior to transformation). | |||
238 | bool DropCallArgument(Expr *E) { | |||
239 | return E->isDefaultArgument(); | |||
240 | } | |||
241 | ||||
242 | /// Determine whether we should expand a pack expansion with the | |||
243 | /// given set of parameter packs into separate arguments by repeatedly | |||
244 | /// transforming the pattern. | |||
245 | /// | |||
246 | /// By default, the transformer never tries to expand pack expansions. | |||
247 | /// Subclasses can override this routine to provide different behavior. | |||
248 | /// | |||
249 | /// \param EllipsisLoc The location of the ellipsis that identifies the | |||
250 | /// pack expansion. | |||
251 | /// | |||
252 | /// \param PatternRange The source range that covers the entire pattern of | |||
253 | /// the pack expansion. | |||
254 | /// | |||
255 | /// \param Unexpanded The set of unexpanded parameter packs within the | |||
256 | /// pattern. | |||
257 | /// | |||
258 | /// \param ShouldExpand Will be set to \c true if the transformer should | |||
259 | /// expand the corresponding pack expansions into separate arguments. When | |||
260 | /// set, \c NumExpansions must also be set. | |||
261 | /// | |||
262 | /// \param RetainExpansion Whether the caller should add an unexpanded | |||
263 | /// pack expansion after all of the expanded arguments. This is used | |||
264 | /// when extending explicitly-specified template argument packs per | |||
265 | /// C++0x [temp.arg.explicit]p9. | |||
266 | /// | |||
267 | /// \param NumExpansions The number of separate arguments that will be in | |||
268 | /// the expanded form of the corresponding pack expansion. This is both an | |||
269 | /// input and an output parameter, which can be set by the caller if the | |||
270 | /// number of expansions is known a priori (e.g., due to a prior substitution) | |||
271 | /// and will be set by the callee when the number of expansions is known. | |||
272 | /// The callee must set this value when \c ShouldExpand is \c true; it may | |||
273 | /// set this value in other cases. | |||
274 | /// | |||
275 | /// \returns true if an error occurred (e.g., because the parameter packs | |||
276 | /// are to be instantiated with arguments of different lengths), false | |||
277 | /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) | |||
278 | /// must be set. | |||
279 | bool TryExpandParameterPacks(SourceLocation EllipsisLoc, | |||
280 | SourceRange PatternRange, | |||
281 | ArrayRef<UnexpandedParameterPack> Unexpanded, | |||
282 | bool &ShouldExpand, | |||
283 | bool &RetainExpansion, | |||
284 | Optional<unsigned> &NumExpansions) { | |||
285 | ShouldExpand = false; | |||
286 | return false; | |||
287 | } | |||
288 | ||||
289 | /// "Forget" about the partially-substituted pack template argument, | |||
290 | /// when performing an instantiation that must preserve the parameter pack | |||
291 | /// use. | |||
292 | /// | |||
293 | /// This routine is meant to be overridden by the template instantiator. | |||
294 | TemplateArgument ForgetPartiallySubstitutedPack() { | |||
295 | return TemplateArgument(); | |||
296 | } | |||
297 | ||||
298 | /// "Remember" the partially-substituted pack template argument | |||
299 | /// after performing an instantiation that must preserve the parameter pack | |||
300 | /// use. | |||
301 | /// | |||
302 | /// This routine is meant to be overridden by the template instantiator. | |||
303 | void RememberPartiallySubstitutedPack(TemplateArgument Arg) { } | |||
304 | ||||
305 | /// Note to the derived class when a function parameter pack is | |||
306 | /// being expanded. | |||
307 | void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { } | |||
308 | ||||
309 | /// Transforms the given type into another type. | |||
310 | /// | |||
311 | /// By default, this routine transforms a type by creating a | |||
312 | /// TypeSourceInfo for it and delegating to the appropriate | |||
313 | /// function. This is expensive, but we don't mind, because | |||
314 | /// this method is deprecated anyway; all users should be | |||
315 | /// switched to storing TypeSourceInfos. | |||
316 | /// | |||
317 | /// \returns the transformed type. | |||
318 | QualType TransformType(QualType T); | |||
319 | ||||
320 | /// Transforms the given type-with-location into a new | |||
321 | /// type-with-location. | |||
322 | /// | |||
323 | /// By default, this routine transforms a type by delegating to the | |||
324 | /// appropriate TransformXXXType to build a new type. Subclasses | |||
325 | /// may override this function (to take over all type | |||
326 | /// transformations) or some set of the TransformXXXType functions | |||
327 | /// to alter the transformation. | |||
328 | TypeSourceInfo *TransformType(TypeSourceInfo *DI); | |||
329 | ||||
330 | /// Transform the given type-with-location into a new | |||
331 | /// type, collecting location information in the given builder | |||
332 | /// as necessary. | |||
333 | /// | |||
334 | QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL); | |||
335 | ||||
336 | /// Transform a type that is permitted to produce a | |||
337 | /// DeducedTemplateSpecializationType. | |||
338 | /// | |||
339 | /// This is used in the (relatively rare) contexts where it is acceptable | |||
340 | /// for transformation to produce a class template type with deduced | |||
341 | /// template arguments. | |||
342 | /// @{ | |||
343 | QualType TransformTypeWithDeducedTST(QualType T); | |||
344 | TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI); | |||
345 | /// @} | |||
346 | ||||
347 | /// The reason why the value of a statement is not discarded, if any. | |||
348 | enum StmtDiscardKind { | |||
349 | SDK_Discarded, | |||
350 | SDK_NotDiscarded, | |||
351 | SDK_StmtExprResult, | |||
352 | }; | |||
353 | ||||
354 | /// Transform the given statement. | |||
355 | /// | |||
356 | /// By default, this routine transforms a statement by delegating to the | |||
357 | /// appropriate TransformXXXStmt function to transform a specific kind of | |||
358 | /// statement or the TransformExpr() function to transform an expression. | |||
359 | /// Subclasses may override this function to transform statements using some | |||
360 | /// other mechanism. | |||
361 | /// | |||
362 | /// \returns the transformed statement. | |||
363 | StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded); | |||
364 | ||||
365 | /// Transform the given statement. | |||
366 | /// | |||
367 | /// By default, this routine transforms a statement by delegating to the | |||
368 | /// appropriate TransformOMPXXXClause function to transform a specific kind | |||
369 | /// of clause. Subclasses may override this function to transform statements | |||
370 | /// using some other mechanism. | |||
371 | /// | |||
372 | /// \returns the transformed OpenMP clause. | |||
373 | OMPClause *TransformOMPClause(OMPClause *S); | |||
374 | ||||
375 | /// Transform the given attribute. | |||
376 | /// | |||
377 | /// By default, this routine transforms a statement by delegating to the | |||
378 | /// appropriate TransformXXXAttr function to transform a specific kind | |||
379 | /// of attribute. Subclasses may override this function to transform | |||
380 | /// attributed statements using some other mechanism. | |||
381 | /// | |||
382 | /// \returns the transformed attribute | |||
383 | const Attr *TransformAttr(const Attr *S); | |||
384 | ||||
385 | /// Transform the specified attribute. | |||
386 | /// | |||
387 | /// Subclasses should override the transformation of attributes with a pragma | |||
388 | /// spelling to transform expressions stored within the attribute. | |||
389 | /// | |||
390 | /// \returns the transformed attribute. | |||
391 | #define ATTR(X) | |||
392 | #define PRAGMA_SPELLING_ATTR(X) \ | |||
393 | const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; } | |||
394 | #include "clang/Basic/AttrList.inc" | |||
395 | ||||
396 | /// Transform the given expression. | |||
397 | /// | |||
398 | /// By default, this routine transforms an expression by delegating to the | |||
399 | /// appropriate TransformXXXExpr function to build a new expression. | |||
400 | /// Subclasses may override this function to transform expressions using some | |||
401 | /// other mechanism. | |||
402 | /// | |||
403 | /// \returns the transformed expression. | |||
404 | ExprResult TransformExpr(Expr *E); | |||
405 | ||||
406 | /// Transform the given initializer. | |||
407 | /// | |||
408 | /// By default, this routine transforms an initializer by stripping off the | |||
409 | /// semantic nodes added by initialization, then passing the result to | |||
410 | /// TransformExpr or TransformExprs. | |||
411 | /// | |||
412 | /// \returns the transformed initializer. | |||
413 | ExprResult TransformInitializer(Expr *Init, bool NotCopyInit); | |||
414 | ||||
415 | /// Transform the given list of expressions. | |||
416 | /// | |||
417 | /// This routine transforms a list of expressions by invoking | |||
418 | /// \c TransformExpr() for each subexpression. However, it also provides | |||
419 | /// support for variadic templates by expanding any pack expansions (if the | |||
420 | /// derived class permits such expansion) along the way. When pack expansions | |||
421 | /// are present, the number of outputs may not equal the number of inputs. | |||
422 | /// | |||
423 | /// \param Inputs The set of expressions to be transformed. | |||
424 | /// | |||
425 | /// \param NumInputs The number of expressions in \c Inputs. | |||
426 | /// | |||
427 | /// \param IsCall If \c true, then this transform is being performed on | |||
428 | /// function-call arguments, and any arguments that should be dropped, will | |||
429 | /// be. | |||
430 | /// | |||
431 | /// \param Outputs The transformed input expressions will be added to this | |||
432 | /// vector. | |||
433 | /// | |||
434 | /// \param ArgChanged If non-NULL, will be set \c true if any argument changed | |||
435 | /// due to transformation. | |||
436 | /// | |||
437 | /// \returns true if an error occurred, false otherwise. | |||
438 | bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall, | |||
439 | SmallVectorImpl<Expr *> &Outputs, | |||
440 | bool *ArgChanged = nullptr); | |||
441 | ||||
442 | /// Transform the given declaration, which is referenced from a type | |||
443 | /// or expression. | |||
444 | /// | |||
445 | /// By default, acts as the identity function on declarations, unless the | |||
446 | /// transformer has had to transform the declaration itself. Subclasses | |||
447 | /// may override this function to provide alternate behavior. | |||
448 | Decl *TransformDecl(SourceLocation Loc, Decl *D) { | |||
449 | llvm::DenseMap<Decl *, Decl *>::iterator Known | |||
450 | = TransformedLocalDecls.find(D); | |||
451 | if (Known != TransformedLocalDecls.end()) | |||
452 | return Known->second; | |||
453 | ||||
454 | return D; | |||
455 | } | |||
456 | ||||
457 | /// Transform the specified condition. | |||
458 | /// | |||
459 | /// By default, this transforms the variable and expression and rebuilds | |||
460 | /// the condition. | |||
461 | Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var, | |||
462 | Expr *Expr, | |||
463 | Sema::ConditionKind Kind); | |||
464 | ||||
465 | /// Transform the attributes associated with the given declaration and | |||
466 | /// place them on the new declaration. | |||
467 | /// | |||
468 | /// By default, this operation does nothing. Subclasses may override this | |||
469 | /// behavior to transform attributes. | |||
470 | void transformAttrs(Decl *Old, Decl *New) { } | |||
471 | ||||
472 | /// Note that a local declaration has been transformed by this | |||
473 | /// transformer. | |||
474 | /// | |||
475 | /// Local declarations are typically transformed via a call to | |||
476 | /// TransformDefinition. However, in some cases (e.g., lambda expressions), | |||
477 | /// the transformer itself has to transform the declarations. This routine | |||
478 | /// can be overridden by a subclass that keeps track of such mappings. | |||
479 | void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) { | |||
480 | assert(New.size() == 1 &&(static_cast <bool> (New.size() == 1 && "must override transformedLocalDecl if performing pack expansion" ) ? void (0) : __assert_fail ("New.size() == 1 && \"must override transformedLocalDecl if performing pack expansion\"" , "clang/lib/Sema/TreeTransform.h", 481, __extension__ __PRETTY_FUNCTION__ )) | |||
481 | "must override transformedLocalDecl if performing pack expansion")(static_cast <bool> (New.size() == 1 && "must override transformedLocalDecl if performing pack expansion" ) ? void (0) : __assert_fail ("New.size() == 1 && \"must override transformedLocalDecl if performing pack expansion\"" , "clang/lib/Sema/TreeTransform.h", 481, __extension__ __PRETTY_FUNCTION__ )); | |||
482 | TransformedLocalDecls[Old] = New.front(); | |||
483 | } | |||
484 | ||||
485 | /// Transform the definition of the given declaration. | |||
486 | /// | |||
487 | /// By default, invokes TransformDecl() to transform the declaration. | |||
488 | /// Subclasses may override this function to provide alternate behavior. | |||
489 | Decl *TransformDefinition(SourceLocation Loc, Decl *D) { | |||
490 | return getDerived().TransformDecl(Loc, D); | |||
491 | } | |||
492 | ||||
493 | /// Transform the given declaration, which was the first part of a | |||
494 | /// nested-name-specifier in a member access expression. | |||
495 | /// | |||
496 | /// This specific declaration transformation only applies to the first | |||
497 | /// identifier in a nested-name-specifier of a member access expression, e.g., | |||
498 | /// the \c T in \c x->T::member | |||
499 | /// | |||
500 | /// By default, invokes TransformDecl() to transform the declaration. | |||
501 | /// Subclasses may override this function to provide alternate behavior. | |||
502 | NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) { | |||
503 | return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D)); | |||
504 | } | |||
505 | ||||
506 | /// Transform the set of declarations in an OverloadExpr. | |||
507 | bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL, | |||
508 | LookupResult &R); | |||
509 | ||||
510 | /// Transform the given nested-name-specifier with source-location | |||
511 | /// information. | |||
512 | /// | |||
513 | /// By default, transforms all of the types and declarations within the | |||
514 | /// nested-name-specifier. Subclasses may override this function to provide | |||
515 | /// alternate behavior. | |||
516 | NestedNameSpecifierLoc | |||
517 | TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, | |||
518 | QualType ObjectType = QualType(), | |||
519 | NamedDecl *FirstQualifierInScope = nullptr); | |||
520 | ||||
521 | /// Transform the given declaration name. | |||
522 | /// | |||
523 | /// By default, transforms the types of conversion function, constructor, | |||
524 | /// and destructor names and then (if needed) rebuilds the declaration name. | |||
525 | /// Identifiers and selectors are returned unmodified. Subclasses may | |||
526 | /// override this function to provide alternate behavior. | |||
527 | DeclarationNameInfo | |||
528 | TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo); | |||
529 | ||||
530 | bool TransformRequiresExprRequirements(ArrayRef<concepts::Requirement *> Reqs, | |||
531 | llvm::SmallVectorImpl<concepts::Requirement *> &Transformed); | |||
532 | concepts::TypeRequirement * | |||
533 | TransformTypeRequirement(concepts::TypeRequirement *Req); | |||
534 | concepts::ExprRequirement * | |||
535 | TransformExprRequirement(concepts::ExprRequirement *Req); | |||
536 | concepts::NestedRequirement * | |||
537 | TransformNestedRequirement(concepts::NestedRequirement *Req); | |||
538 | ||||
539 | /// Transform the given template name. | |||
540 | /// | |||
541 | /// \param SS The nested-name-specifier that qualifies the template | |||
542 | /// name. This nested-name-specifier must already have been transformed. | |||
543 | /// | |||
544 | /// \param Name The template name to transform. | |||
545 | /// | |||
546 | /// \param NameLoc The source location of the template name. | |||
547 | /// | |||
548 | /// \param ObjectType If we're translating a template name within a member | |||
549 | /// access expression, this is the type of the object whose member template | |||
550 | /// is being referenced. | |||
551 | /// | |||
552 | /// \param FirstQualifierInScope If the first part of a nested-name-specifier | |||
553 | /// also refers to a name within the current (lexical) scope, this is the | |||
554 | /// declaration it refers to. | |||
555 | /// | |||
556 | /// By default, transforms the template name by transforming the declarations | |||
557 | /// and nested-name-specifiers that occur within the template name. | |||
558 | /// Subclasses may override this function to provide alternate behavior. | |||
559 | TemplateName | |||
560 | TransformTemplateName(CXXScopeSpec &SS, TemplateName Name, | |||
561 | SourceLocation NameLoc, | |||
562 | QualType ObjectType = QualType(), | |||
563 | NamedDecl *FirstQualifierInScope = nullptr, | |||
564 | bool AllowInjectedClassName = false); | |||
565 | ||||
566 | /// Transform the given template argument. | |||
567 | /// | |||
568 | /// By default, this operation transforms the type, expression, or | |||
569 | /// declaration stored within the template argument and constructs a | |||
570 | /// new template argument from the transformed result. Subclasses may | |||
571 | /// override this function to provide alternate behavior. | |||
572 | /// | |||
573 | /// Returns true if there was an error. | |||
574 | bool TransformTemplateArgument(const TemplateArgumentLoc &Input, | |||
575 | TemplateArgumentLoc &Output, | |||
576 | bool Uneval = false); | |||
577 | ||||
578 | /// Transform the given set of template arguments. | |||
579 | /// | |||
580 | /// By default, this operation transforms all of the template arguments | |||
581 | /// in the input set using \c TransformTemplateArgument(), and appends | |||
582 | /// the transformed arguments to the output list. | |||
583 | /// | |||
584 | /// Note that this overload of \c TransformTemplateArguments() is merely | |||
585 | /// a convenience function. Subclasses that wish to override this behavior | |||
586 | /// should override the iterator-based member template version. | |||
587 | /// | |||
588 | /// \param Inputs The set of template arguments to be transformed. | |||
589 | /// | |||
590 | /// \param NumInputs The number of template arguments in \p Inputs. | |||
591 | /// | |||
592 | /// \param Outputs The set of transformed template arguments output by this | |||
593 | /// routine. | |||
594 | /// | |||
595 | /// Returns true if an error occurred. | |||
596 | bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs, | |||
597 | unsigned NumInputs, | |||
598 | TemplateArgumentListInfo &Outputs, | |||
599 | bool Uneval = false) { | |||
600 | return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs, | |||
601 | Uneval); | |||
602 | } | |||
603 | ||||
604 | /// Transform the given set of template arguments. | |||
605 | /// | |||
606 | /// By default, this operation transforms all of the template arguments | |||
607 | /// in the input set using \c TransformTemplateArgument(), and appends | |||
608 | /// the transformed arguments to the output list. | |||
609 | /// | |||
610 | /// \param First An iterator to the first template argument. | |||
611 | /// | |||
612 | /// \param Last An iterator one step past the last template argument. | |||
613 | /// | |||
614 | /// \param Outputs The set of transformed template arguments output by this | |||
615 | /// routine. | |||
616 | /// | |||
617 | /// Returns true if an error occurred. | |||
618 | template<typename InputIterator> | |||
619 | bool TransformTemplateArguments(InputIterator First, | |||
620 | InputIterator Last, | |||
621 | TemplateArgumentListInfo &Outputs, | |||
622 | bool Uneval = false); | |||
623 | ||||
624 | /// Fakes up a TemplateArgumentLoc for a given TemplateArgument. | |||
625 | void InventTemplateArgumentLoc(const TemplateArgument &Arg, | |||
626 | TemplateArgumentLoc &ArgLoc); | |||
627 | ||||
628 | /// Fakes up a TypeSourceInfo for a type. | |||
629 | TypeSourceInfo *InventTypeSourceInfo(QualType T) { | |||
630 | return SemaRef.Context.getTrivialTypeSourceInfo(T, | |||
631 | getDerived().getBaseLocation()); | |||
632 | } | |||
633 | ||||
634 | #define ABSTRACT_TYPELOC(CLASS, PARENT) | |||
635 | #define TYPELOC(CLASS, PARENT) \ | |||
636 | QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T); | |||
637 | #include "clang/AST/TypeLocNodes.def" | |||
638 | ||||
639 | template<typename Fn> | |||
640 | QualType TransformFunctionProtoType(TypeLocBuilder &TLB, | |||
641 | FunctionProtoTypeLoc TL, | |||
642 | CXXRecordDecl *ThisContext, | |||
643 | Qualifiers ThisTypeQuals, | |||
644 | Fn TransformExceptionSpec); | |||
645 | ||||
646 | bool TransformExceptionSpec(SourceLocation Loc, | |||
647 | FunctionProtoType::ExceptionSpecInfo &ESI, | |||
648 | SmallVectorImpl<QualType> &Exceptions, | |||
649 | bool &Changed); | |||
650 | ||||
651 | StmtResult TransformSEHHandler(Stmt *Handler); | |||
652 | ||||
653 | QualType | |||
654 | TransformTemplateSpecializationType(TypeLocBuilder &TLB, | |||
655 | TemplateSpecializationTypeLoc TL, | |||
656 | TemplateName Template); | |||
657 | ||||
658 | QualType | |||
659 | TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, | |||
660 | DependentTemplateSpecializationTypeLoc TL, | |||
661 | TemplateName Template, | |||
662 | CXXScopeSpec &SS); | |||
663 | ||||
664 | QualType TransformDependentTemplateSpecializationType( | |||
665 | TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, | |||
666 | NestedNameSpecifierLoc QualifierLoc); | |||
667 | ||||
668 | /// Transforms the parameters of a function type into the | |||
669 | /// given vectors. | |||
670 | /// | |||
671 | /// The result vectors should be kept in sync; null entries in the | |||
672 | /// variables vector are acceptable. | |||
673 | /// | |||
674 | /// Return true on error. | |||
675 | bool TransformFunctionTypeParams( | |||
676 | SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, | |||
677 | const QualType *ParamTypes, | |||
678 | const FunctionProtoType::ExtParameterInfo *ParamInfos, | |||
679 | SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars, | |||
680 | Sema::ExtParameterInfoBuilder &PInfos); | |||
681 | ||||
682 | /// Transforms a single function-type parameter. Return null | |||
683 | /// on error. | |||
684 | /// | |||
685 | /// \param indexAdjustment - A number to add to the parameter's | |||
686 | /// scope index; can be negative | |||
687 | ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, | |||
688 | int indexAdjustment, | |||
689 | Optional<unsigned> NumExpansions, | |||
690 | bool ExpectParameterPack); | |||
691 | ||||
692 | /// Transform the body of a lambda-expression. | |||
693 | StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body); | |||
694 | /// Alternative implementation of TransformLambdaBody that skips transforming | |||
695 | /// the body. | |||
696 | StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body); | |||
697 | ||||
698 | QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL); | |||
699 | ||||
700 | StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr); | |||
701 | ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E); | |||
702 | ||||
703 | TemplateParameterList *TransformTemplateParameterList( | |||
704 | TemplateParameterList *TPL) { | |||
705 | return TPL; | |||
706 | } | |||
707 | ||||
708 | ExprResult TransformAddressOfOperand(Expr *E); | |||
709 | ||||
710 | ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E, | |||
711 | bool IsAddressOfOperand, | |||
712 | TypeSourceInfo **RecoveryTSI); | |||
713 | ||||
714 | ExprResult TransformParenDependentScopeDeclRefExpr( | |||
715 | ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand, | |||
716 | TypeSourceInfo **RecoveryTSI); | |||
717 | ||||
718 | StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S); | |||
719 | ||||
720 | // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous | |||
721 | // amount of stack usage with clang. | |||
722 | #define STMT(Node, Parent) \ | |||
723 | LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) \ | |||
724 | StmtResult Transform##Node(Node *S); | |||
725 | #define VALUESTMT(Node, Parent) \ | |||
726 | LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) \ | |||
727 | StmtResult Transform##Node(Node *S, StmtDiscardKind SDK); | |||
728 | #define EXPR(Node, Parent) \ | |||
729 | LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) \ | |||
730 | ExprResult Transform##Node(Node *E); | |||
731 | #define ABSTRACT_STMT(Stmt) | |||
732 | #include "clang/AST/StmtNodes.inc" | |||
733 | ||||
734 | #define GEN_CLANG_CLAUSE_CLASS | |||
735 | #define CLAUSE_CLASS(Enum, Str, Class) \ | |||
736 | LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) \ | |||
737 | OMPClause *Transform##Class(Class *S); | |||
738 | #include "llvm/Frontend/OpenMP/OMP.inc" | |||
739 | ||||
740 | /// Build a new qualified type given its unqualified type and type location. | |||
741 | /// | |||
742 | /// By default, this routine adds type qualifiers only to types that can | |||
743 | /// have qualifiers, and silently suppresses those qualifiers that are not | |||
744 | /// permitted. Subclasses may override this routine to provide different | |||
745 | /// behavior. | |||
746 | QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL); | |||
747 | ||||
748 | /// Build a new pointer type given its pointee type. | |||
749 | /// | |||
750 | /// By default, performs semantic analysis when building the pointer type. | |||
751 | /// Subclasses may override this routine to provide different behavior. | |||
752 | QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil); | |||
753 | ||||
754 | /// Build a new block pointer type given its pointee type. | |||
755 | /// | |||
756 | /// By default, performs semantic analysis when building the block pointer | |||
757 | /// type. Subclasses may override this routine to provide different behavior. | |||
758 | QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil); | |||
759 | ||||
760 | /// Build a new reference type given the type it references. | |||
761 | /// | |||
762 | /// By default, performs semantic analysis when building the | |||
763 | /// reference type. Subclasses may override this routine to provide | |||
764 | /// different behavior. | |||
765 | /// | |||
766 | /// \param LValue whether the type was written with an lvalue sigil | |||
767 | /// or an rvalue sigil. | |||
768 | QualType RebuildReferenceType(QualType ReferentType, | |||
769 | bool LValue, | |||
770 | SourceLocation Sigil); | |||
771 | ||||
772 | /// Build a new member pointer type given the pointee type and the | |||
773 | /// class type it refers into. | |||
774 | /// | |||
775 | /// By default, performs semantic analysis when building the member pointer | |||
776 | /// type. Subclasses may override this routine to provide different behavior. | |||
777 | QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType, | |||
778 | SourceLocation Sigil); | |||
779 | ||||
780 | QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, | |||
781 | SourceLocation ProtocolLAngleLoc, | |||
782 | ArrayRef<ObjCProtocolDecl *> Protocols, | |||
783 | ArrayRef<SourceLocation> ProtocolLocs, | |||
784 | SourceLocation ProtocolRAngleLoc); | |||
785 | ||||
786 | /// Build an Objective-C object type. | |||
787 | /// | |||
788 | /// By default, performs semantic analysis when building the object type. | |||
789 | /// Subclasses may override this routine to provide different behavior. | |||
790 | QualType RebuildObjCObjectType(QualType BaseType, | |||
791 | SourceLocation Loc, | |||
792 | SourceLocation TypeArgsLAngleLoc, | |||
793 | ArrayRef<TypeSourceInfo *> TypeArgs, | |||
794 | SourceLocation TypeArgsRAngleLoc, | |||
795 | SourceLocation ProtocolLAngleLoc, | |||
796 | ArrayRef<ObjCProtocolDecl *> Protocols, | |||
797 | ArrayRef<SourceLocation> ProtocolLocs, | |||
798 | SourceLocation ProtocolRAngleLoc); | |||
799 | ||||
800 | /// Build a new Objective-C object pointer type given the pointee type. | |||
801 | /// | |||
802 | /// By default, directly builds the pointer type, with no additional semantic | |||
803 | /// analysis. | |||
804 | QualType RebuildObjCObjectPointerType(QualType PointeeType, | |||
805 | SourceLocation Star); | |||
806 | ||||
807 | /// Build a new array type given the element type, size | |||
808 | /// modifier, size of the array (if known), size expression, and index type | |||
809 | /// qualifiers. | |||
810 | /// | |||
811 | /// By default, performs semantic analysis when building the array type. | |||
812 | /// Subclasses may override this routine to provide different behavior. | |||
813 | /// Also by default, all of the other Rebuild*Array | |||
814 | QualType RebuildArrayType(QualType ElementType, | |||
815 | ArrayType::ArraySizeModifier SizeMod, | |||
816 | const llvm::APInt *Size, | |||
817 | Expr *SizeExpr, | |||
818 | unsigned IndexTypeQuals, | |||
819 | SourceRange BracketsRange); | |||
820 | ||||
821 | /// Build a new constant array type given the element type, size | |||
822 | /// modifier, (known) size of the array, and index type qualifiers. | |||
823 | /// | |||
824 | /// By default, performs semantic analysis when building the array type. | |||
825 | /// Subclasses may override this routine to provide different behavior. | |||
826 | QualType RebuildConstantArrayType(QualType ElementType, | |||
827 | ArrayType::ArraySizeModifier SizeMod, | |||
828 | const llvm::APInt &Size, | |||
829 | Expr *SizeExpr, | |||
830 | unsigned IndexTypeQuals, | |||
831 | SourceRange BracketsRange); | |||
832 | ||||
833 | /// Build a new incomplete array type given the element type, size | |||
834 | /// modifier, and index type qualifiers. | |||
835 | /// | |||
836 | /// By default, performs semantic analysis when building the array type. | |||
837 | /// Subclasses may override this routine to provide different behavior. | |||
838 | QualType RebuildIncompleteArrayType(QualType ElementType, | |||
839 | ArrayType::ArraySizeModifier SizeMod, | |||
840 | unsigned IndexTypeQuals, | |||
841 | SourceRange BracketsRange); | |||
842 | ||||
843 | /// Build a new variable-length array type given the element type, | |||
844 | /// size modifier, size expression, and index type qualifiers. | |||
845 | /// | |||
846 | /// By default, performs semantic analysis when building the array type. | |||
847 | /// Subclasses may override this routine to provide different behavior. | |||
848 | QualType RebuildVariableArrayType(QualType ElementType, | |||
849 | ArrayType::ArraySizeModifier SizeMod, | |||
850 | Expr *SizeExpr, | |||
851 | unsigned IndexTypeQuals, | |||
852 | SourceRange BracketsRange); | |||
853 | ||||
854 | /// Build a new dependent-sized array type given the element type, | |||
855 | /// size modifier, size expression, and index type qualifiers. | |||
856 | /// | |||
857 | /// By default, performs semantic analysis when building the array type. | |||
858 | /// Subclasses may override this routine to provide different behavior. | |||
859 | QualType RebuildDependentSizedArrayType(QualType ElementType, | |||
860 | ArrayType::ArraySizeModifier SizeMod, | |||
861 | Expr *SizeExpr, | |||
862 | unsigned IndexTypeQuals, | |||
863 | SourceRange BracketsRange); | |||
864 | ||||
865 | /// Build a new vector type given the element type and | |||
866 | /// number of elements. | |||
867 | /// | |||
868 | /// By default, performs semantic analysis when building the vector type. | |||
869 | /// Subclasses may override this routine to provide different behavior. | |||
870 | QualType RebuildVectorType(QualType ElementType, unsigned NumElements, | |||
871 | VectorType::VectorKind VecKind); | |||
872 | ||||
873 | /// Build a new potentially dependently-sized extended vector type | |||
874 | /// given the element type and number of elements. | |||
875 | /// | |||
876 | /// By default, performs semantic analysis when building the vector type. | |||
877 | /// Subclasses may override this routine to provide different behavior. | |||
878 | QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr, | |||
879 | SourceLocation AttributeLoc, | |||
880 | VectorType::VectorKind); | |||
881 | ||||
882 | /// Build a new extended vector type given the element type and | |||
883 | /// number of elements. | |||
884 | /// | |||
885 | /// By default, performs semantic analysis when building the vector type. | |||
886 | /// Subclasses may override this routine to provide different behavior. | |||
887 | QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements, | |||
888 | SourceLocation AttributeLoc); | |||
889 | ||||
890 | /// Build a new potentially dependently-sized extended vector type | |||
891 | /// given the element type and number of elements. | |||
892 | /// | |||
893 | /// By default, performs semantic analysis when building the vector type. | |||
894 | /// Subclasses may override this routine to provide different behavior. | |||
895 | QualType RebuildDependentSizedExtVectorType(QualType ElementType, | |||
896 | Expr *SizeExpr, | |||
897 | SourceLocation AttributeLoc); | |||
898 | ||||
899 | /// Build a new matrix type given the element type and dimensions. | |||
900 | QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows, | |||
901 | unsigned NumColumns); | |||
902 | ||||
903 | /// Build a new matrix type given the type and dependently-defined | |||
904 | /// dimensions. | |||
905 | QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr, | |||
906 | Expr *ColumnExpr, | |||
907 | SourceLocation AttributeLoc); | |||
908 | ||||
909 | /// Build a new DependentAddressSpaceType or return the pointee | |||
910 | /// type variable with the correct address space (retrieved from | |||
911 | /// AddrSpaceExpr) applied to it. The former will be returned in cases | |||
912 | /// where the address space remains dependent. | |||
913 | /// | |||
914 | /// By default, performs semantic analysis when building the type with address | |||
915 | /// space applied. Subclasses may override this routine to provide different | |||
916 | /// behavior. | |||
917 | QualType RebuildDependentAddressSpaceType(QualType PointeeType, | |||
918 | Expr *AddrSpaceExpr, | |||
919 | SourceLocation AttributeLoc); | |||
920 | ||||
921 | /// Build a new function type. | |||
922 | /// | |||
923 | /// By default, performs semantic analysis when building the function type. | |||
924 | /// Subclasses may override this routine to provide different behavior. | |||
925 | QualType RebuildFunctionProtoType(QualType T, | |||
926 | MutableArrayRef<QualType> ParamTypes, | |||
927 | const FunctionProtoType::ExtProtoInfo &EPI); | |||
928 | ||||
929 | /// Build a new unprototyped function type. | |||
930 | QualType RebuildFunctionNoProtoType(QualType ResultType); | |||
931 | ||||
932 | /// Rebuild an unresolved typename type, given the decl that | |||
933 | /// the UnresolvedUsingTypenameDecl was transformed to. | |||
934 | QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D); | |||
935 | ||||
936 | /// Build a new type found via an alias. | |||
937 | QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) { | |||
938 | return SemaRef.Context.getUsingType(Found, Underlying); | |||
939 | } | |||
940 | ||||
941 | /// Build a new typedef type. | |||
942 | QualType RebuildTypedefType(TypedefNameDecl *Typedef) { | |||
943 | return SemaRef.Context.getTypeDeclType(Typedef); | |||
944 | } | |||
945 | ||||
946 | /// Build a new MacroDefined type. | |||
947 | QualType RebuildMacroQualifiedType(QualType T, | |||
948 | const IdentifierInfo *MacroII) { | |||
949 | return SemaRef.Context.getMacroQualifiedType(T, MacroII); | |||
950 | } | |||
951 | ||||
952 | /// Build a new class/struct/union type. | |||
953 | QualType RebuildRecordType(RecordDecl *Record) { | |||
954 | return SemaRef.Context.getTypeDeclType(Record); | |||
955 | } | |||
956 | ||||
957 | /// Build a new Enum type. | |||
958 | QualType RebuildEnumType(EnumDecl *Enum) { | |||
959 | return SemaRef.Context.getTypeDeclType(Enum); | |||
960 | } | |||
961 | ||||
962 | /// Build a new typeof(expr) type. | |||
963 | /// | |||
964 | /// By default, performs semantic analysis when building the typeof type. | |||
965 | /// Subclasses may override this routine to provide different behavior. | |||
966 | QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc, | |||
967 | TypeOfKind Kind); | |||
968 | ||||
969 | /// Build a new typeof(type) type. | |||
970 | /// | |||
971 | /// By default, builds a new TypeOfType with the given underlying type. | |||
972 | QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind); | |||
973 | ||||
974 | /// Build a new unary transform type. | |||
975 | QualType RebuildUnaryTransformType(QualType BaseType, | |||
976 | UnaryTransformType::UTTKind UKind, | |||
977 | SourceLocation Loc); | |||
978 | ||||
979 | /// Build a new C++11 decltype type. | |||
980 | /// | |||
981 | /// By default, performs semantic analysis when building the decltype type. | |||
982 | /// Subclasses may override this routine to provide different behavior. | |||
983 | QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc); | |||
984 | ||||
985 | /// Build a new C++11 auto type. | |||
986 | /// | |||
987 | /// By default, builds a new AutoType with the given deduced type. | |||
988 | QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword, | |||
989 | ConceptDecl *TypeConstraintConcept, | |||
990 | ArrayRef<TemplateArgument> TypeConstraintArgs) { | |||
991 | // Note, IsDependent is always false here: we implicitly convert an 'auto' | |||
992 | // which has been deduced to a dependent type into an undeduced 'auto', so | |||
993 | // that we'll retry deduction after the transformation. | |||
994 | return SemaRef.Context.getAutoType(Deduced, Keyword, | |||
995 | /*IsDependent*/ false, /*IsPack=*/false, | |||
996 | TypeConstraintConcept, | |||
997 | TypeConstraintArgs); | |||
998 | } | |||
999 | ||||
1000 | /// By default, builds a new DeducedTemplateSpecializationType with the given | |||
1001 | /// deduced type. | |||
1002 | QualType RebuildDeducedTemplateSpecializationType(TemplateName Template, | |||
1003 | QualType Deduced) { | |||
1004 | return SemaRef.Context.getDeducedTemplateSpecializationType( | |||
1005 | Template, Deduced, /*IsDependent*/ false); | |||
1006 | } | |||
1007 | ||||
1008 | /// Build a new template specialization type. | |||
1009 | /// | |||
1010 | /// By default, performs semantic analysis when building the template | |||
1011 | /// specialization type. Subclasses may override this routine to provide | |||
1012 | /// different behavior. | |||
1013 | QualType RebuildTemplateSpecializationType(TemplateName Template, | |||
1014 | SourceLocation TemplateLoc, | |||
1015 | TemplateArgumentListInfo &Args); | |||
1016 | ||||
1017 | /// Build a new parenthesized type. | |||
1018 | /// | |||
1019 | /// By default, builds a new ParenType type from the inner type. | |||
1020 | /// Subclasses may override this routine to provide different behavior. | |||
1021 | QualType RebuildParenType(QualType InnerType) { | |||
1022 | return SemaRef.BuildParenType(InnerType); | |||
1023 | } | |||
1024 | ||||
1025 | /// Build a new qualified name type. | |||
1026 | /// | |||
1027 | /// By default, builds a new ElaboratedType type from the keyword, | |||
1028 | /// the nested-name-specifier and the named type. | |||
1029 | /// Subclasses may override this routine to provide different behavior. | |||
1030 | QualType RebuildElaboratedType(SourceLocation KeywordLoc, | |||
1031 | ElaboratedTypeKeyword Keyword, | |||
1032 | NestedNameSpecifierLoc QualifierLoc, | |||
1033 | QualType Named) { | |||
1034 | return SemaRef.Context.getElaboratedType(Keyword, | |||
1035 | QualifierLoc.getNestedNameSpecifier(), | |||
1036 | Named); | |||
1037 | } | |||
1038 | ||||
1039 | /// Build a new typename type that refers to a template-id. | |||
1040 | /// | |||
1041 | /// By default, builds a new DependentNameType type from the | |||
1042 | /// nested-name-specifier and the given type. Subclasses may override | |||
1043 | /// this routine to provide different behavior. | |||
1044 | QualType RebuildDependentTemplateSpecializationType( | |||
1045 | ElaboratedTypeKeyword Keyword, | |||
1046 | NestedNameSpecifierLoc QualifierLoc, | |||
1047 | SourceLocation TemplateKWLoc, | |||
1048 | const IdentifierInfo *Name, | |||
1049 | SourceLocation NameLoc, | |||
1050 | TemplateArgumentListInfo &Args, | |||
1051 | bool AllowInjectedClassName) { | |||
1052 | // Rebuild the template name. | |||
1053 | // TODO: avoid TemplateName abstraction | |||
1054 | CXXScopeSpec SS; | |||
1055 | SS.Adopt(QualifierLoc); | |||
1056 | TemplateName InstName = getDerived().RebuildTemplateName( | |||
1057 | SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr, | |||
1058 | AllowInjectedClassName); | |||
1059 | ||||
1060 | if (InstName.isNull()) | |||
1061 | return QualType(); | |||
1062 | ||||
1063 | // If it's still dependent, make a dependent specialization. | |||
1064 | if (InstName.getAsDependentTemplateName()) | |||
1065 | return SemaRef.Context.getDependentTemplateSpecializationType(Keyword, | |||
1066 | QualifierLoc.getNestedNameSpecifier(), | |||
1067 | Name, | |||
1068 | Args); | |||
1069 | ||||
1070 | // Otherwise, make an elaborated type wrapping a non-dependent | |||
1071 | // specialization. | |||
1072 | QualType T = | |||
1073 | getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args); | |||
1074 | if (T.isNull()) | |||
1075 | return QualType(); | |||
1076 | return SemaRef.Context.getElaboratedType( | |||
1077 | Keyword, QualifierLoc.getNestedNameSpecifier(), T); | |||
1078 | } | |||
1079 | ||||
1080 | /// Build a new typename type that refers to an identifier. | |||
1081 | /// | |||
1082 | /// By default, performs semantic analysis when building the typename type | |||
1083 | /// (or elaborated type). Subclasses may override this routine to provide | |||
1084 | /// different behavior. | |||
1085 | QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, | |||
1086 | SourceLocation KeywordLoc, | |||
1087 | NestedNameSpecifierLoc QualifierLoc, | |||
1088 | const IdentifierInfo *Id, | |||
1089 | SourceLocation IdLoc, | |||
1090 | bool DeducedTSTContext) { | |||
1091 | CXXScopeSpec SS; | |||
1092 | SS.Adopt(QualifierLoc); | |||
1093 | ||||
1094 | if (QualifierLoc.getNestedNameSpecifier()->isDependent()) { | |||
1095 | // If the name is still dependent, just build a new dependent name type. | |||
1096 | if (!SemaRef.computeDeclContext(SS)) | |||
1097 | return SemaRef.Context.getDependentNameType(Keyword, | |||
1098 | QualifierLoc.getNestedNameSpecifier(), | |||
1099 | Id); | |||
1100 | } | |||
1101 | ||||
1102 | if (Keyword == ETK_None || Keyword == ETK_Typename) { | |||
1103 | return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc, | |||
1104 | *Id, IdLoc, DeducedTSTContext); | |||
1105 | } | |||
1106 | ||||
1107 | TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); | |||
1108 | ||||
1109 | // We had a dependent elaborated-type-specifier that has been transformed | |||
1110 | // into a non-dependent elaborated-type-specifier. Find the tag we're | |||
1111 | // referring to. | |||
1112 | LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName); | |||
1113 | DeclContext *DC = SemaRef.computeDeclContext(SS, false); | |||
1114 | if (!DC) | |||
1115 | return QualType(); | |||
1116 | ||||
1117 | if (SemaRef.RequireCompleteDeclContext(SS, DC)) | |||
1118 | return QualType(); | |||
1119 | ||||
1120 | TagDecl *Tag = nullptr; | |||
1121 | SemaRef.LookupQualifiedName(Result, DC); | |||
1122 | switch (Result.getResultKind()) { | |||
1123 | case LookupResult::NotFound: | |||
1124 | case LookupResult::NotFoundInCurrentInstantiation: | |||
1125 | break; | |||
1126 | ||||
1127 | case LookupResult::Found: | |||
1128 | Tag = Result.getAsSingle<TagDecl>(); | |||
1129 | break; | |||
1130 | ||||
1131 | case LookupResult::FoundOverloaded: | |||
1132 | case LookupResult::FoundUnresolvedValue: | |||
1133 | llvm_unreachable("Tag lookup cannot find non-tags")::llvm::llvm_unreachable_internal("Tag lookup cannot find non-tags" , "clang/lib/Sema/TreeTransform.h", 1133); | |||
1134 | ||||
1135 | case LookupResult::Ambiguous: | |||
1136 | // Let the LookupResult structure handle ambiguities. | |||
1137 | return QualType(); | |||
1138 | } | |||
1139 | ||||
1140 | if (!Tag) { | |||
1141 | // Check where the name exists but isn't a tag type and use that to emit | |||
1142 | // better diagnostics. | |||
1143 | LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName); | |||
1144 | SemaRef.LookupQualifiedName(Result, DC); | |||
1145 | switch (Result.getResultKind()) { | |||
1146 | case LookupResult::Found: | |||
1147 | case LookupResult::FoundOverloaded: | |||
1148 | case LookupResult::FoundUnresolvedValue: { | |||
1149 | NamedDecl *SomeDecl = Result.getRepresentativeDecl(); | |||
1150 | Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind); | |||
1151 | SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << SomeDecl | |||
1152 | << NTK << Kind; | |||
1153 | SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at); | |||
1154 | break; | |||
1155 | } | |||
1156 | default: | |||
1157 | SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope) | |||
1158 | << Kind << Id << DC << QualifierLoc.getSourceRange(); | |||
1159 | break; | |||
1160 | } | |||
1161 | return QualType(); | |||
1162 | } | |||
1163 | ||||
1164 | if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false, | |||
1165 | IdLoc, Id)) { | |||
1166 | SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id; | |||
1167 | SemaRef.Diag(Tag->getLocation(), diag::note_previous_use); | |||
1168 | return QualType(); | |||
1169 | } | |||
1170 | ||||
1171 | // Build the elaborated-type-specifier type. | |||
1172 | QualType T = SemaRef.Context.getTypeDeclType(Tag); | |||
1173 | return SemaRef.Context.getElaboratedType(Keyword, | |||
1174 | QualifierLoc.getNestedNameSpecifier(), | |||
1175 | T); | |||
1176 | } | |||
1177 | ||||
1178 | /// Build a new pack expansion type. | |||
1179 | /// | |||
1180 | /// By default, builds a new PackExpansionType type from the given pattern. | |||
1181 | /// Subclasses may override this routine to provide different behavior. | |||
1182 | QualType RebuildPackExpansionType(QualType Pattern, | |||
1183 | SourceRange PatternRange, | |||
1184 | SourceLocation EllipsisLoc, | |||
1185 | Optional<unsigned> NumExpansions) { | |||
1186 | return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc, | |||
1187 | NumExpansions); | |||
1188 | } | |||
1189 | ||||
1190 | /// Build a new atomic type given its value type. | |||
1191 | /// | |||
1192 | /// By default, performs semantic analysis when building the atomic type. | |||
1193 | /// Subclasses may override this routine to provide different behavior. | |||
1194 | QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc); | |||
1195 | ||||
1196 | /// Build a new pipe type given its value type. | |||
1197 | QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc, | |||
1198 | bool isReadPipe); | |||
1199 | ||||
1200 | /// Build a bit-precise int given its value type. | |||
1201 | QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits, | |||
1202 | SourceLocation Loc); | |||
1203 | ||||
1204 | /// Build a dependent bit-precise int given its value type. | |||
1205 | QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr, | |||
1206 | SourceLocation Loc); | |||
1207 | ||||
1208 | /// Build a new template name given a nested name specifier, a flag | |||
1209 | /// indicating whether the "template" keyword was provided, and the template | |||
1210 | /// that the template name refers to. | |||
1211 | /// | |||
1212 | /// By default, builds the new template name directly. Subclasses may override | |||
1213 | /// this routine to provide different behavior. | |||
1214 | TemplateName RebuildTemplateName(CXXScopeSpec &SS, | |||
1215 | bool TemplateKW, | |||
1216 | TemplateDecl *Template); | |||
1217 | ||||
1218 | /// Build a new template name given a nested name specifier and the | |||
1219 | /// name that is referred to as a template. | |||
1220 | /// | |||
1221 | /// By default, performs semantic analysis to determine whether the name can | |||
1222 | /// be resolved to a specific template, then builds the appropriate kind of | |||
1223 | /// template name. Subclasses may override this routine to provide different | |||
1224 | /// behavior. | |||
1225 | TemplateName RebuildTemplateName(CXXScopeSpec &SS, | |||
1226 | SourceLocation TemplateKWLoc, | |||
1227 | const IdentifierInfo &Name, | |||
1228 | SourceLocation NameLoc, QualType ObjectType, | |||
1229 | NamedDecl *FirstQualifierInScope, | |||
1230 | bool AllowInjectedClassName); | |||
1231 | ||||
1232 | /// Build a new template name given a nested name specifier and the | |||
1233 | /// overloaded operator name that is referred to as a template. | |||
1234 | /// | |||
1235 | /// By default, performs semantic analysis to determine whether the name can | |||
1236 | /// be resolved to a specific template, then builds the appropriate kind of | |||
1237 | /// template name. Subclasses may override this routine to provide different | |||
1238 | /// behavior. | |||
1239 | TemplateName RebuildTemplateName(CXXScopeSpec &SS, | |||
1240 | SourceLocation TemplateKWLoc, | |||
1241 | OverloadedOperatorKind Operator, | |||
1242 | SourceLocation NameLoc, QualType ObjectType, | |||
1243 | bool AllowInjectedClassName); | |||
1244 | ||||
1245 | /// Build a new template name given a template template parameter pack | |||
1246 | /// and the | |||
1247 | /// | |||
1248 | /// By default, performs semantic analysis to determine whether the name can | |||
1249 | /// be resolved to a specific template, then builds the appropriate kind of | |||
1250 | /// template name. Subclasses may override this routine to provide different | |||
1251 | /// behavior. | |||
1252 | TemplateName RebuildTemplateName(TemplateTemplateParmDecl *Param, | |||
1253 | const TemplateArgument &ArgPack) { | |||
1254 | return getSema().Context.getSubstTemplateTemplateParmPack(Param, ArgPack); | |||
1255 | } | |||
1256 | ||||
1257 | /// Build a new compound statement. | |||
1258 | /// | |||
1259 | /// By default, performs semantic analysis to build the new statement. | |||
1260 | /// Subclasses may override this routine to provide different behavior. | |||
1261 | StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc, | |||
1262 | MultiStmtArg Statements, | |||
1263 | SourceLocation RBraceLoc, | |||
1264 | bool IsStmtExpr) { | |||
1265 | return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements, | |||
1266 | IsStmtExpr); | |||
1267 | } | |||
1268 | ||||
1269 | /// Build a new case statement. | |||
1270 | /// | |||
1271 | /// By default, performs semantic analysis to build the new statement. | |||
1272 | /// Subclasses may override this routine to provide different behavior. | |||
1273 | StmtResult RebuildCaseStmt(SourceLocation CaseLoc, | |||
1274 | Expr *LHS, | |||
1275 | SourceLocation EllipsisLoc, | |||
1276 | Expr *RHS, | |||
1277 | SourceLocation ColonLoc) { | |||
1278 | return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS, | |||
1279 | ColonLoc); | |||
1280 | } | |||
1281 | ||||
1282 | /// Attach the body to a new case statement. | |||
1283 | /// | |||
1284 | /// By default, performs semantic analysis to build the new statement. | |||
1285 | /// Subclasses may override this routine to provide different behavior. | |||
1286 | StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) { | |||
1287 | getSema().ActOnCaseStmtBody(S, Body); | |||
1288 | return S; | |||
1289 | } | |||
1290 | ||||
1291 | /// Build a new default statement. | |||
1292 | /// | |||
1293 | /// By default, performs semantic analysis to build the new statement. | |||
1294 | /// Subclasses may override this routine to provide different behavior. | |||
1295 | StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc, | |||
1296 | SourceLocation ColonLoc, | |||
1297 | Stmt *SubStmt) { | |||
1298 | return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt, | |||
1299 | /*CurScope=*/nullptr); | |||
1300 | } | |||
1301 | ||||
1302 | /// Build a new label statement. | |||
1303 | /// | |||
1304 | /// By default, performs semantic analysis to build the new statement. | |||
1305 | /// Subclasses may override this routine to provide different behavior. | |||
1306 | StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L, | |||
1307 | SourceLocation ColonLoc, Stmt *SubStmt) { | |||
1308 | return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt); | |||
1309 | } | |||
1310 | ||||
1311 | /// Build a new attributed statement. | |||
1312 | /// | |||
1313 | /// By default, performs semantic analysis to build the new statement. | |||
1314 | /// Subclasses may override this routine to provide different behavior. | |||
1315 | StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, | |||
1316 | ArrayRef<const Attr *> Attrs, | |||
1317 | Stmt *SubStmt) { | |||
1318 | return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt); | |||
1319 | } | |||
1320 | ||||
1321 | /// Build a new "if" statement. | |||
1322 | /// | |||
1323 | /// By default, performs semantic analysis to build the new statement. | |||
1324 | /// Subclasses may override this routine to provide different behavior. | |||
1325 | StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind, | |||
1326 | SourceLocation LParenLoc, Sema::ConditionResult Cond, | |||
1327 | SourceLocation RParenLoc, Stmt *Init, Stmt *Then, | |||
1328 | SourceLocation ElseLoc, Stmt *Else) { | |||
1329 | return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc, | |||
1330 | Then, ElseLoc, Else); | |||
1331 | } | |||
1332 | ||||
1333 | /// Start building a new switch statement. | |||
1334 | /// | |||
1335 | /// By default, performs semantic analysis to build the new statement. | |||
1336 | /// Subclasses may override this routine to provide different behavior. | |||
1337 | StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc, | |||
1338 | SourceLocation LParenLoc, Stmt *Init, | |||
1339 | Sema::ConditionResult Cond, | |||
1340 | SourceLocation RParenLoc) { | |||
1341 | return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond, | |||
1342 | RParenLoc); | |||
1343 | } | |||
1344 | ||||
1345 | /// Attach the body to the switch statement. | |||
1346 | /// | |||
1347 | /// By default, performs semantic analysis to build the new statement. | |||
1348 | /// Subclasses may override this routine to provide different behavior. | |||
1349 | StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc, | |||
1350 | Stmt *Switch, Stmt *Body) { | |||
1351 | return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body); | |||
1352 | } | |||
1353 | ||||
1354 | /// Build a new while statement. | |||
1355 | /// | |||
1356 | /// By default, performs semantic analysis to build the new statement. | |||
1357 | /// Subclasses may override this routine to provide different behavior. | |||
1358 | StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, | |||
1359 | Sema::ConditionResult Cond, | |||
1360 | SourceLocation RParenLoc, Stmt *Body) { | |||
1361 | return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body); | |||
1362 | } | |||
1363 | ||||
1364 | /// Build a new do-while statement. | |||
1365 | /// | |||
1366 | /// By default, performs semantic analysis to build the new statement. | |||
1367 | /// Subclasses may override this routine to provide different behavior. | |||
1368 | StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body, | |||
1369 | SourceLocation WhileLoc, SourceLocation LParenLoc, | |||
1370 | Expr *Cond, SourceLocation RParenLoc) { | |||
1371 | return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc, | |||
1372 | Cond, RParenLoc); | |||
1373 | } | |||
1374 | ||||
1375 | /// Build a new for statement. | |||
1376 | /// | |||
1377 | /// By default, performs semantic analysis to build the new statement. | |||
1378 | /// Subclasses may override this routine to provide different behavior. | |||
1379 | StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, | |||
1380 | Stmt *Init, Sema::ConditionResult Cond, | |||
1381 | Sema::FullExprArg Inc, SourceLocation RParenLoc, | |||
1382 | Stmt *Body) { | |||
1383 | return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond, | |||
1384 | Inc, RParenLoc, Body); | |||
1385 | } | |||
1386 | ||||
1387 | /// Build a new goto statement. | |||
1388 | /// | |||
1389 | /// By default, performs semantic analysis to build the new statement. | |||
1390 | /// Subclasses may override this routine to provide different behavior. | |||
1391 | StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, | |||
1392 | LabelDecl *Label) { | |||
1393 | return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label); | |||
1394 | } | |||
1395 | ||||
1396 | /// Build a new indirect goto statement. | |||
1397 | /// | |||
1398 | /// By default, performs semantic analysis to build the new statement. | |||
1399 | /// Subclasses may override this routine to provide different behavior. | |||
1400 | StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc, | |||
1401 | SourceLocation StarLoc, | |||
1402 | Expr *Target) { | |||
1403 | return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target); | |||
1404 | } | |||
1405 | ||||
1406 | /// Build a new return statement. | |||
1407 | /// | |||
1408 | /// By default, performs semantic analysis to build the new statement. | |||
1409 | /// Subclasses may override this routine to provide different behavior. | |||
1410 | StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) { | |||
1411 | return getSema().BuildReturnStmt(ReturnLoc, Result); | |||
1412 | } | |||
1413 | ||||
1414 | /// Build a new declaration statement. | |||
1415 | /// | |||
1416 | /// By default, performs semantic analysis to build the new statement. | |||
1417 | /// Subclasses may override this routine to provide different behavior. | |||
1418 | StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls, | |||
1419 | SourceLocation StartLoc, SourceLocation EndLoc) { | |||
1420 | Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls); | |||
1421 | return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc); | |||
1422 | } | |||
1423 | ||||
1424 | /// Build a new inline asm statement. | |||
1425 | /// | |||
1426 | /// By default, performs semantic analysis to build the new statement. | |||
1427 | /// Subclasses may override this routine to provide different behavior. | |||
1428 | StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, | |||
1429 | bool IsVolatile, unsigned NumOutputs, | |||
1430 | unsigned NumInputs, IdentifierInfo **Names, | |||
1431 | MultiExprArg Constraints, MultiExprArg Exprs, | |||
1432 | Expr *AsmString, MultiExprArg Clobbers, | |||
1433 | unsigned NumLabels, | |||
1434 | SourceLocation RParenLoc) { | |||
1435 | return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, | |||
1436 | NumInputs, Names, Constraints, Exprs, | |||
1437 | AsmString, Clobbers, NumLabels, RParenLoc); | |||
1438 | } | |||
1439 | ||||
1440 | /// Build a new MS style inline asm statement. | |||
1441 | /// | |||
1442 | /// By default, performs semantic analysis to build the new statement. | |||
1443 | /// Subclasses may override this routine to provide different behavior. | |||
1444 | StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, | |||
1445 | ArrayRef<Token> AsmToks, | |||
1446 | StringRef AsmString, | |||
1447 | unsigned NumOutputs, unsigned NumInputs, | |||
1448 | ArrayRef<StringRef> Constraints, | |||
1449 | ArrayRef<StringRef> Clobbers, | |||
1450 | ArrayRef<Expr*> Exprs, | |||
1451 | SourceLocation EndLoc) { | |||
1452 | return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString, | |||
1453 | NumOutputs, NumInputs, | |||
1454 | Constraints, Clobbers, Exprs, EndLoc); | |||
1455 | } | |||
1456 | ||||
1457 | /// Build a new co_return statement. | |||
1458 | /// | |||
1459 | /// By default, performs semantic analysis to build the new statement. | |||
1460 | /// Subclasses may override this routine to provide different behavior. | |||
1461 | StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result, | |||
1462 | bool IsImplicit) { | |||
1463 | return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit); | |||
1464 | } | |||
1465 | ||||
1466 | /// Build a new co_await expression. | |||
1467 | /// | |||
1468 | /// By default, performs semantic analysis to build the new expression. | |||
1469 | /// Subclasses may override this routine to provide different behavior. | |||
1470 | ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, | |||
1471 | UnresolvedLookupExpr *OpCoawaitLookup, | |||
1472 | bool IsImplicit) { | |||
1473 | // This function rebuilds a coawait-expr given its operator. | |||
1474 | // For an explicit coawait-expr, the rebuild involves the full set | |||
1475 | // of transformations performed by BuildUnresolvedCoawaitExpr(), | |||
1476 | // including calling await_transform(). | |||
1477 | // For an implicit coawait-expr, we need to rebuild the "operator | |||
1478 | // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr(). | |||
1479 | // This mirrors how the implicit CoawaitExpr is originally created | |||
1480 | // in Sema::ActOnCoroutineBodyStart(). | |||
1481 | if (IsImplicit) { | |||
1482 | ExprResult Suspend = getSema().BuildOperatorCoawaitCall( | |||
1483 | CoawaitLoc, Operand, OpCoawaitLookup); | |||
1484 | if (Suspend.isInvalid()) | |||
1485 | return ExprError(); | |||
1486 | return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand, | |||
1487 | Suspend.get(), true); | |||
1488 | } | |||
1489 | ||||
1490 | return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand, | |||
1491 | OpCoawaitLookup); | |||
1492 | } | |||
1493 | ||||
1494 | /// Build a new co_await expression. | |||
1495 | /// | |||
1496 | /// By default, performs semantic analysis to build the new expression. | |||
1497 | /// Subclasses may override this routine to provide different behavior. | |||
1498 | ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc, | |||
1499 | Expr *Result, | |||
1500 | UnresolvedLookupExpr *Lookup) { | |||
1501 | return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup); | |||
1502 | } | |||
1503 | ||||
1504 | /// Build a new co_yield expression. | |||
1505 | /// | |||
1506 | /// By default, performs semantic analysis to build the new expression. | |||
1507 | /// Subclasses may override this routine to provide different behavior. | |||
1508 | ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) { | |||
1509 | return getSema().BuildCoyieldExpr(CoyieldLoc, Result); | |||
1510 | } | |||
1511 | ||||
1512 | StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) { | |||
1513 | return getSema().BuildCoroutineBodyStmt(Args); | |||
1514 | } | |||
1515 | ||||
1516 | /// Build a new Objective-C \@try statement. | |||
1517 | /// | |||
1518 | /// By default, performs semantic analysis to build the new statement. | |||
1519 | /// Subclasses may override this routine to provide different behavior. | |||
1520 | StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc, | |||
1521 | Stmt *TryBody, | |||
1522 | MultiStmtArg CatchStmts, | |||
1523 | Stmt *Finally) { | |||
1524 | return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts, | |||
1525 | Finally); | |||
1526 | } | |||
1527 | ||||
1528 | /// Rebuild an Objective-C exception declaration. | |||
1529 | /// | |||
1530 | /// By default, performs semantic analysis to build the new declaration. | |||
1531 | /// Subclasses may override this routine to provide different behavior. | |||
1532 | VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, | |||
1533 | TypeSourceInfo *TInfo, QualType T) { | |||
1534 | return getSema().BuildObjCExceptionDecl(TInfo, T, | |||
1535 | ExceptionDecl->getInnerLocStart(), | |||
1536 | ExceptionDecl->getLocation(), | |||
1537 | ExceptionDecl->getIdentifier()); | |||
1538 | } | |||
1539 | ||||
1540 | /// Build a new Objective-C \@catch statement. | |||
1541 | /// | |||
1542 | /// By default, performs semantic analysis to build the new statement. | |||
1543 | /// Subclasses may override this routine to provide different behavior. | |||
1544 | StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc, | |||
1545 | SourceLocation RParenLoc, | |||
1546 | VarDecl *Var, | |||
1547 | Stmt *Body) { | |||
1548 | return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, | |||
1549 | Var, Body); | |||
1550 | } | |||
1551 | ||||
1552 | /// Build a new Objective-C \@finally statement. | |||
1553 | /// | |||
1554 | /// By default, performs semantic analysis to build the new statement. | |||
1555 | /// Subclasses may override this routine to provide different behavior. | |||
1556 | StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc, | |||
1557 | Stmt *Body) { | |||
1558 | return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body); | |||
1559 | } | |||
1560 | ||||
1561 | /// Build a new Objective-C \@throw statement. | |||
1562 | /// | |||
1563 | /// By default, performs semantic analysis to build the new statement. | |||
1564 | /// Subclasses may override this routine to provide different behavior. | |||
1565 | StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc, | |||
1566 | Expr *Operand) { | |||
1567 | return getSema().BuildObjCAtThrowStmt(AtLoc, Operand); | |||
1568 | } | |||
1569 | ||||
1570 | /// Build a new OpenMP Canonical loop. | |||
1571 | /// | |||
1572 | /// Ensures that the outermost loop in @p LoopStmt is wrapped by a | |||
1573 | /// OMPCanonicalLoop. | |||
1574 | StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) { | |||
1575 | return getSema().ActOnOpenMPCanonicalLoop(LoopStmt); | |||
1576 | } | |||
1577 | ||||
1578 | /// Build a new OpenMP executable directive. | |||
1579 | /// | |||
1580 | /// By default, performs semantic analysis to build the new statement. | |||
1581 | /// Subclasses may override this routine to provide different behavior. | |||
1582 | StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind, | |||
1583 | DeclarationNameInfo DirName, | |||
1584 | OpenMPDirectiveKind CancelRegion, | |||
1585 | ArrayRef<OMPClause *> Clauses, | |||
1586 | Stmt *AStmt, SourceLocation StartLoc, | |||
1587 | SourceLocation EndLoc) { | |||
1588 | return getSema().ActOnOpenMPExecutableDirective( | |||
1589 | Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc); | |||
1590 | } | |||
1591 | ||||
1592 | /// Build a new OpenMP 'if' clause. | |||
1593 | /// | |||
1594 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1595 | /// Subclasses may override this routine to provide different behavior. | |||
1596 | OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier, | |||
1597 | Expr *Condition, SourceLocation StartLoc, | |||
1598 | SourceLocation LParenLoc, | |||
1599 | SourceLocation NameModifierLoc, | |||
1600 | SourceLocation ColonLoc, | |||
1601 | SourceLocation EndLoc) { | |||
1602 | return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc, | |||
1603 | LParenLoc, NameModifierLoc, ColonLoc, | |||
1604 | EndLoc); | |||
1605 | } | |||
1606 | ||||
1607 | /// Build a new OpenMP 'final' clause. | |||
1608 | /// | |||
1609 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1610 | /// Subclasses may override this routine to provide different behavior. | |||
1611 | OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc, | |||
1612 | SourceLocation LParenLoc, | |||
1613 | SourceLocation EndLoc) { | |||
1614 | return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc, | |||
1615 | EndLoc); | |||
1616 | } | |||
1617 | ||||
1618 | /// Build a new OpenMP 'num_threads' clause. | |||
1619 | /// | |||
1620 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1621 | /// Subclasses may override this routine to provide different behavior. | |||
1622 | OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads, | |||
1623 | SourceLocation StartLoc, | |||
1624 | SourceLocation LParenLoc, | |||
1625 | SourceLocation EndLoc) { | |||
1626 | return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc, | |||
1627 | LParenLoc, EndLoc); | |||
1628 | } | |||
1629 | ||||
1630 | /// Build a new OpenMP 'safelen' clause. | |||
1631 | /// | |||
1632 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1633 | /// Subclasses may override this routine to provide different behavior. | |||
1634 | OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc, | |||
1635 | SourceLocation LParenLoc, | |||
1636 | SourceLocation EndLoc) { | |||
1637 | return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc); | |||
1638 | } | |||
1639 | ||||
1640 | /// Build a new OpenMP 'simdlen' clause. | |||
1641 | /// | |||
1642 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1643 | /// Subclasses may override this routine to provide different behavior. | |||
1644 | OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc, | |||
1645 | SourceLocation LParenLoc, | |||
1646 | SourceLocation EndLoc) { | |||
1647 | return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc); | |||
1648 | } | |||
1649 | ||||
1650 | OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes, | |||
1651 | SourceLocation StartLoc, | |||
1652 | SourceLocation LParenLoc, | |||
1653 | SourceLocation EndLoc) { | |||
1654 | return getSema().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc, EndLoc); | |||
1655 | } | |||
1656 | ||||
1657 | /// Build a new OpenMP 'full' clause. | |||
1658 | OMPClause *RebuildOMPFullClause(SourceLocation StartLoc, | |||
1659 | SourceLocation EndLoc) { | |||
1660 | return getSema().ActOnOpenMPFullClause(StartLoc, EndLoc); | |||
1661 | } | |||
1662 | ||||
1663 | /// Build a new OpenMP 'partial' clause. | |||
1664 | OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc, | |||
1665 | SourceLocation LParenLoc, | |||
1666 | SourceLocation EndLoc) { | |||
1667 | return getSema().ActOnOpenMPPartialClause(Factor, StartLoc, LParenLoc, | |||
1668 | EndLoc); | |||
1669 | } | |||
1670 | ||||
1671 | /// Build a new OpenMP 'allocator' clause. | |||
1672 | /// | |||
1673 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1674 | /// Subclasses may override this routine to provide different behavior. | |||
1675 | OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc, | |||
1676 | SourceLocation LParenLoc, | |||
1677 | SourceLocation EndLoc) { | |||
1678 | return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc); | |||
1679 | } | |||
1680 | ||||
1681 | /// Build a new OpenMP 'collapse' clause. | |||
1682 | /// | |||
1683 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1684 | /// Subclasses may override this routine to provide different behavior. | |||
1685 | OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc, | |||
1686 | SourceLocation LParenLoc, | |||
1687 | SourceLocation EndLoc) { | |||
1688 | return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc, | |||
1689 | EndLoc); | |||
1690 | } | |||
1691 | ||||
1692 | /// Build a new OpenMP 'default' clause. | |||
1693 | /// | |||
1694 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1695 | /// Subclasses may override this routine to provide different behavior. | |||
1696 | OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc, | |||
1697 | SourceLocation StartLoc, | |||
1698 | SourceLocation LParenLoc, | |||
1699 | SourceLocation EndLoc) { | |||
1700 | return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc, | |||
1701 | StartLoc, LParenLoc, EndLoc); | |||
1702 | } | |||
1703 | ||||
1704 | /// Build a new OpenMP 'proc_bind' clause. | |||
1705 | /// | |||
1706 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1707 | /// Subclasses may override this routine to provide different behavior. | |||
1708 | OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind, | |||
1709 | SourceLocation KindKwLoc, | |||
1710 | SourceLocation StartLoc, | |||
1711 | SourceLocation LParenLoc, | |||
1712 | SourceLocation EndLoc) { | |||
1713 | return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc, | |||
1714 | StartLoc, LParenLoc, EndLoc); | |||
1715 | } | |||
1716 | ||||
1717 | /// Build a new OpenMP 'schedule' clause. | |||
1718 | /// | |||
1719 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1720 | /// Subclasses may override this routine to provide different behavior. | |||
1721 | OMPClause *RebuildOMPScheduleClause( | |||
1722 | OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, | |||
1723 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, | |||
1724 | SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, | |||
1725 | SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { | |||
1726 | return getSema().ActOnOpenMPScheduleClause( | |||
1727 | M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc, | |||
1728 | CommaLoc, EndLoc); | |||
1729 | } | |||
1730 | ||||
1731 | /// Build a new OpenMP 'ordered' clause. | |||
1732 | /// | |||
1733 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1734 | /// Subclasses may override this routine to provide different behavior. | |||
1735 | OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc, | |||
1736 | SourceLocation EndLoc, | |||
1737 | SourceLocation LParenLoc, Expr *Num) { | |||
1738 | return getSema().ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Num); | |||
1739 | } | |||
1740 | ||||
1741 | /// Build a new OpenMP 'private' clause. | |||
1742 | /// | |||
1743 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1744 | /// Subclasses may override this routine to provide different behavior. | |||
1745 | OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList, | |||
1746 | SourceLocation StartLoc, | |||
1747 | SourceLocation LParenLoc, | |||
1748 | SourceLocation EndLoc) { | |||
1749 | return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, | |||
1750 | EndLoc); | |||
1751 | } | |||
1752 | ||||
1753 | /// Build a new OpenMP 'firstprivate' clause. | |||
1754 | /// | |||
1755 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1756 | /// Subclasses may override this routine to provide different behavior. | |||
1757 | OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList, | |||
1758 | SourceLocation StartLoc, | |||
1759 | SourceLocation LParenLoc, | |||
1760 | SourceLocation EndLoc) { | |||
1761 | return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, | |||
1762 | EndLoc); | |||
1763 | } | |||
1764 | ||||
1765 | /// Build a new OpenMP 'lastprivate' clause. | |||
1766 | /// | |||
1767 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1768 | /// Subclasses may override this routine to provide different behavior. | |||
1769 | OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList, | |||
1770 | OpenMPLastprivateModifier LPKind, | |||
1771 | SourceLocation LPKindLoc, | |||
1772 | SourceLocation ColonLoc, | |||
1773 | SourceLocation StartLoc, | |||
1774 | SourceLocation LParenLoc, | |||
1775 | SourceLocation EndLoc) { | |||
1776 | return getSema().ActOnOpenMPLastprivateClause( | |||
1777 | VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); | |||
1778 | } | |||
1779 | ||||
1780 | /// Build a new OpenMP 'shared' clause. | |||
1781 | /// | |||
1782 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1783 | /// Subclasses may override this routine to provide different behavior. | |||
1784 | OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList, | |||
1785 | SourceLocation StartLoc, | |||
1786 | SourceLocation LParenLoc, | |||
1787 | SourceLocation EndLoc) { | |||
1788 | return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, | |||
1789 | EndLoc); | |||
1790 | } | |||
1791 | ||||
1792 | /// Build a new OpenMP 'reduction' clause. | |||
1793 | /// | |||
1794 | /// By default, performs semantic analysis to build the new statement. | |||
1795 | /// Subclasses may override this routine to provide different behavior. | |||
1796 | OMPClause *RebuildOMPReductionClause( | |||
1797 | ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, | |||
1798 | SourceLocation StartLoc, SourceLocation LParenLoc, | |||
1799 | SourceLocation ModifierLoc, SourceLocation ColonLoc, | |||
1800 | SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, | |||
1801 | const DeclarationNameInfo &ReductionId, | |||
1802 | ArrayRef<Expr *> UnresolvedReductions) { | |||
1803 | return getSema().ActOnOpenMPReductionClause( | |||
1804 | VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, | |||
1805 | ReductionIdScopeSpec, ReductionId, UnresolvedReductions); | |||
1806 | } | |||
1807 | ||||
1808 | /// Build a new OpenMP 'task_reduction' clause. | |||
1809 | /// | |||
1810 | /// By default, performs semantic analysis to build the new statement. | |||
1811 | /// Subclasses may override this routine to provide different behavior. | |||
1812 | OMPClause *RebuildOMPTaskReductionClause( | |||
1813 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, | |||
1814 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, | |||
1815 | CXXScopeSpec &ReductionIdScopeSpec, | |||
1816 | const DeclarationNameInfo &ReductionId, | |||
1817 | ArrayRef<Expr *> UnresolvedReductions) { | |||
1818 | return getSema().ActOnOpenMPTaskReductionClause( | |||
1819 | VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, | |||
1820 | ReductionId, UnresolvedReductions); | |||
1821 | } | |||
1822 | ||||
1823 | /// Build a new OpenMP 'in_reduction' clause. | |||
1824 | /// | |||
1825 | /// By default, performs semantic analysis to build the new statement. | |||
1826 | /// Subclasses may override this routine to provide different behavior. | |||
1827 | OMPClause * | |||
1828 | RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, | |||
1829 | SourceLocation LParenLoc, SourceLocation ColonLoc, | |||
1830 | SourceLocation EndLoc, | |||
1831 | CXXScopeSpec &ReductionIdScopeSpec, | |||
1832 | const DeclarationNameInfo &ReductionId, | |||
1833 | ArrayRef<Expr *> UnresolvedReductions) { | |||
1834 | return getSema().ActOnOpenMPInReductionClause( | |||
1835 | VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, | |||
1836 | ReductionId, UnresolvedReductions); | |||
1837 | } | |||
1838 | ||||
1839 | /// Build a new OpenMP 'linear' clause. | |||
1840 | /// | |||
1841 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1842 | /// Subclasses may override this routine to provide different behavior. | |||
1843 | OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, | |||
1844 | SourceLocation StartLoc, | |||
1845 | SourceLocation LParenLoc, | |||
1846 | OpenMPLinearClauseKind Modifier, | |||
1847 | SourceLocation ModifierLoc, | |||
1848 | SourceLocation ColonLoc, | |||
1849 | SourceLocation EndLoc) { | |||
1850 | return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc, | |||
1851 | Modifier, ModifierLoc, ColonLoc, | |||
1852 | EndLoc); | |||
1853 | } | |||
1854 | ||||
1855 | /// Build a new OpenMP 'aligned' clause. | |||
1856 | /// | |||
1857 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1858 | /// Subclasses may override this routine to provide different behavior. | |||
1859 | OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment, | |||
1860 | SourceLocation StartLoc, | |||
1861 | SourceLocation LParenLoc, | |||
1862 | SourceLocation ColonLoc, | |||
1863 | SourceLocation EndLoc) { | |||
1864 | return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc, | |||
1865 | LParenLoc, ColonLoc, EndLoc); | |||
1866 | } | |||
1867 | ||||
1868 | /// Build a new OpenMP 'copyin' clause. | |||
1869 | /// | |||
1870 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1871 | /// Subclasses may override this routine to provide different behavior. | |||
1872 | OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList, | |||
1873 | SourceLocation StartLoc, | |||
1874 | SourceLocation LParenLoc, | |||
1875 | SourceLocation EndLoc) { | |||
1876 | return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, | |||
1877 | EndLoc); | |||
1878 | } | |||
1879 | ||||
1880 | /// Build a new OpenMP 'copyprivate' clause. | |||
1881 | /// | |||
1882 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1883 | /// Subclasses may override this routine to provide different behavior. | |||
1884 | OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList, | |||
1885 | SourceLocation StartLoc, | |||
1886 | SourceLocation LParenLoc, | |||
1887 | SourceLocation EndLoc) { | |||
1888 | return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, | |||
1889 | EndLoc); | |||
1890 | } | |||
1891 | ||||
1892 | /// Build a new OpenMP 'flush' pseudo clause. | |||
1893 | /// | |||
1894 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1895 | /// Subclasses may override this routine to provide different behavior. | |||
1896 | OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList, | |||
1897 | SourceLocation StartLoc, | |||
1898 | SourceLocation LParenLoc, | |||
1899 | SourceLocation EndLoc) { | |||
1900 | return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, | |||
1901 | EndLoc); | |||
1902 | } | |||
1903 | ||||
1904 | /// Build a new OpenMP 'depobj' pseudo clause. | |||
1905 | /// | |||
1906 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1907 | /// Subclasses may override this routine to provide different behavior. | |||
1908 | OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, | |||
1909 | SourceLocation LParenLoc, | |||
1910 | SourceLocation EndLoc) { | |||
1911 | return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc, | |||
1912 | EndLoc); | |||
1913 | } | |||
1914 | ||||
1915 | /// Build a new OpenMP 'depend' pseudo clause. | |||
1916 | /// | |||
1917 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1918 | /// Subclasses may override this routine to provide different behavior. | |||
1919 | OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data, | |||
1920 | Expr *DepModifier, ArrayRef<Expr *> VarList, | |||
1921 | SourceLocation StartLoc, | |||
1922 | SourceLocation LParenLoc, | |||
1923 | SourceLocation EndLoc) { | |||
1924 | return getSema().ActOnOpenMPDependClause(Data, DepModifier, VarList, | |||
1925 | StartLoc, LParenLoc, EndLoc); | |||
1926 | } | |||
1927 | ||||
1928 | /// Build a new OpenMP 'device' clause. | |||
1929 | /// | |||
1930 | /// By default, performs semantic analysis to build the new statement. | |||
1931 | /// Subclasses may override this routine to provide different behavior. | |||
1932 | OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier, | |||
1933 | Expr *Device, SourceLocation StartLoc, | |||
1934 | SourceLocation LParenLoc, | |||
1935 | SourceLocation ModifierLoc, | |||
1936 | SourceLocation EndLoc) { | |||
1937 | return getSema().ActOnOpenMPDeviceClause(Modifier, Device, StartLoc, | |||
1938 | LParenLoc, ModifierLoc, EndLoc); | |||
1939 | } | |||
1940 | ||||
1941 | /// Build a new OpenMP 'map' clause. | |||
1942 | /// | |||
1943 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1944 | /// Subclasses may override this routine to provide different behavior. | |||
1945 | OMPClause *RebuildOMPMapClause( | |||
1946 | ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, | |||
1947 | ArrayRef<SourceLocation> MapTypeModifiersLoc, | |||
1948 | CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId, | |||
1949 | OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, | |||
1950 | SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, | |||
1951 | const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { | |||
1952 | return getSema().ActOnOpenMPMapClause( | |||
1953 | MapTypeModifiers, MapTypeModifiersLoc, MapperIdScopeSpec, MapperId, | |||
1954 | MapType, IsMapTypeImplicit, MapLoc, ColonLoc, VarList, Locs, | |||
1955 | /*NoDiagnose=*/false, UnresolvedMappers); | |||
1956 | } | |||
1957 | ||||
1958 | /// Build a new OpenMP 'allocate' clause. | |||
1959 | /// | |||
1960 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
1961 | /// Subclasses may override this routine to provide different behavior. | |||
1962 | OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList, | |||
1963 | SourceLocation StartLoc, | |||
1964 | SourceLocation LParenLoc, | |||
1965 | SourceLocation ColonLoc, | |||
1966 | SourceLocation EndLoc) { | |||
1967 | return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc, | |||
1968 | LParenLoc, ColonLoc, EndLoc); | |||
1969 | } | |||
1970 | ||||
1971 | /// Build a new OpenMP 'num_teams' clause. | |||
1972 | /// | |||
1973 | /// By default, performs semantic analysis to build the new statement. | |||
1974 | /// Subclasses may override this routine to provide different behavior. | |||
1975 | OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, | |||
1976 | SourceLocation LParenLoc, | |||
1977 | SourceLocation EndLoc) { | |||
1978 | return getSema().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc, LParenLoc, | |||
1979 | EndLoc); | |||
1980 | } | |||
1981 | ||||
1982 | /// Build a new OpenMP 'thread_limit' clause. | |||
1983 | /// | |||
1984 | /// By default, performs semantic analysis to build the new statement. | |||
1985 | /// Subclasses may override this routine to provide different behavior. | |||
1986 | OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit, | |||
1987 | SourceLocation StartLoc, | |||
1988 | SourceLocation LParenLoc, | |||
1989 | SourceLocation EndLoc) { | |||
1990 | return getSema().ActOnOpenMPThreadLimitClause(ThreadLimit, StartLoc, | |||
1991 | LParenLoc, EndLoc); | |||
1992 | } | |||
1993 | ||||
1994 | /// Build a new OpenMP 'priority' clause. | |||
1995 | /// | |||
1996 | /// By default, performs semantic analysis to build the new statement. | |||
1997 | /// Subclasses may override this routine to provide different behavior. | |||
1998 | OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc, | |||
1999 | SourceLocation LParenLoc, | |||
2000 | SourceLocation EndLoc) { | |||
2001 | return getSema().ActOnOpenMPPriorityClause(Priority, StartLoc, LParenLoc, | |||
2002 | EndLoc); | |||
2003 | } | |||
2004 | ||||
2005 | /// Build a new OpenMP 'grainsize' clause. | |||
2006 | /// | |||
2007 | /// By default, performs semantic analysis to build the new statement. | |||
2008 | /// Subclasses may override this routine to provide different behavior. | |||
2009 | OMPClause *RebuildOMPGrainsizeClause(Expr *Grainsize, SourceLocation StartLoc, | |||
2010 | SourceLocation LParenLoc, | |||
2011 | SourceLocation EndLoc) { | |||
2012 | return getSema().ActOnOpenMPGrainsizeClause(Grainsize, StartLoc, LParenLoc, | |||
2013 | EndLoc); | |||
2014 | } | |||
2015 | ||||
2016 | /// Build a new OpenMP 'num_tasks' clause. | |||
2017 | /// | |||
2018 | /// By default, performs semantic analysis to build the new statement. | |||
2019 | /// Subclasses may override this routine to provide different behavior. | |||
2020 | OMPClause *RebuildOMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, | |||
2021 | SourceLocation LParenLoc, | |||
2022 | SourceLocation EndLoc) { | |||
2023 | return getSema().ActOnOpenMPNumTasksClause(NumTasks, StartLoc, LParenLoc, | |||
2024 | EndLoc); | |||
2025 | } | |||
2026 | ||||
2027 | /// Build a new OpenMP 'hint' clause. | |||
2028 | /// | |||
2029 | /// By default, performs semantic analysis to build the new statement. | |||
2030 | /// Subclasses may override this routine to provide different behavior. | |||
2031 | OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc, | |||
2032 | SourceLocation LParenLoc, | |||
2033 | SourceLocation EndLoc) { | |||
2034 | return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc); | |||
2035 | } | |||
2036 | ||||
2037 | /// Build a new OpenMP 'detach' clause. | |||
2038 | /// | |||
2039 | /// By default, performs semantic analysis to build the new statement. | |||
2040 | /// Subclasses may override this routine to provide different behavior. | |||
2041 | OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc, | |||
2042 | SourceLocation LParenLoc, | |||
2043 | SourceLocation EndLoc) { | |||
2044 | return getSema().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); | |||
2045 | } | |||
2046 | ||||
2047 | /// Build a new OpenMP 'dist_schedule' clause. | |||
2048 | /// | |||
2049 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2050 | /// Subclasses may override this routine to provide different behavior. | |||
2051 | OMPClause * | |||
2052 | RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, | |||
2053 | Expr *ChunkSize, SourceLocation StartLoc, | |||
2054 | SourceLocation LParenLoc, SourceLocation KindLoc, | |||
2055 | SourceLocation CommaLoc, SourceLocation EndLoc) { | |||
2056 | return getSema().ActOnOpenMPDistScheduleClause( | |||
2057 | Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc); | |||
2058 | } | |||
2059 | ||||
2060 | /// Build a new OpenMP 'to' clause. | |||
2061 | /// | |||
2062 | /// By default, performs semantic analysis to build the new statement. | |||
2063 | /// Subclasses may override this routine to provide different behavior. | |||
2064 | OMPClause * | |||
2065 | RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | |||
2066 | ArrayRef<SourceLocation> MotionModifiersLoc, | |||
2067 | CXXScopeSpec &MapperIdScopeSpec, | |||
2068 | DeclarationNameInfo &MapperId, SourceLocation ColonLoc, | |||
2069 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, | |||
2070 | ArrayRef<Expr *> UnresolvedMappers) { | |||
2071 | return getSema().ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, | |||
2072 | MapperIdScopeSpec, MapperId, ColonLoc, | |||
2073 | VarList, Locs, UnresolvedMappers); | |||
2074 | } | |||
2075 | ||||
2076 | /// Build a new OpenMP 'from' clause. | |||
2077 | /// | |||
2078 | /// By default, performs semantic analysis to build the new statement. | |||
2079 | /// Subclasses may override this routine to provide different behavior. | |||
2080 | OMPClause * | |||
2081 | RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | |||
2082 | ArrayRef<SourceLocation> MotionModifiersLoc, | |||
2083 | CXXScopeSpec &MapperIdScopeSpec, | |||
2084 | DeclarationNameInfo &MapperId, SourceLocation ColonLoc, | |||
2085 | ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, | |||
2086 | ArrayRef<Expr *> UnresolvedMappers) { | |||
2087 | return getSema().ActOnOpenMPFromClause( | |||
2088 | MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId, | |||
2089 | ColonLoc, VarList, Locs, UnresolvedMappers); | |||
2090 | } | |||
2091 | ||||
2092 | /// Build a new OpenMP 'use_device_ptr' clause. | |||
2093 | /// | |||
2094 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2095 | /// Subclasses may override this routine to provide different behavior. | |||
2096 | OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList, | |||
2097 | const OMPVarListLocTy &Locs) { | |||
2098 | return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs); | |||
2099 | } | |||
2100 | ||||
2101 | /// Build a new OpenMP 'use_device_addr' clause. | |||
2102 | /// | |||
2103 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2104 | /// Subclasses may override this routine to provide different behavior. | |||
2105 | OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, | |||
2106 | const OMPVarListLocTy &Locs) { | |||
2107 | return getSema().ActOnOpenMPUseDeviceAddrClause(VarList, Locs); | |||
2108 | } | |||
2109 | ||||
2110 | /// Build a new OpenMP 'is_device_ptr' clause. | |||
2111 | /// | |||
2112 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2113 | /// Subclasses may override this routine to provide different behavior. | |||
2114 | OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList, | |||
2115 | const OMPVarListLocTy &Locs) { | |||
2116 | return getSema().ActOnOpenMPIsDevicePtrClause(VarList, Locs); | |||
2117 | } | |||
2118 | ||||
2119 | /// Build a new OpenMP 'has_device_addr' clause. | |||
2120 | /// | |||
2121 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2122 | /// Subclasses may override this routine to provide different behavior. | |||
2123 | OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, | |||
2124 | const OMPVarListLocTy &Locs) { | |||
2125 | return getSema().ActOnOpenMPHasDeviceAddrClause(VarList, Locs); | |||
2126 | } | |||
2127 | ||||
2128 | /// Build a new OpenMP 'defaultmap' clause. | |||
2129 | /// | |||
2130 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2131 | /// Subclasses may override this routine to provide different behavior. | |||
2132 | OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, | |||
2133 | OpenMPDefaultmapClauseKind Kind, | |||
2134 | SourceLocation StartLoc, | |||
2135 | SourceLocation LParenLoc, | |||
2136 | SourceLocation MLoc, | |||
2137 | SourceLocation KindLoc, | |||
2138 | SourceLocation EndLoc) { | |||
2139 | return getSema().ActOnOpenMPDefaultmapClause(M, Kind, StartLoc, LParenLoc, | |||
2140 | MLoc, KindLoc, EndLoc); | |||
2141 | } | |||
2142 | ||||
2143 | /// Build a new OpenMP 'nontemporal' clause. | |||
2144 | /// | |||
2145 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2146 | /// Subclasses may override this routine to provide different behavior. | |||
2147 | OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList, | |||
2148 | SourceLocation StartLoc, | |||
2149 | SourceLocation LParenLoc, | |||
2150 | SourceLocation EndLoc) { | |||
2151 | return getSema().ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, | |||
2152 | EndLoc); | |||
2153 | } | |||
2154 | ||||
2155 | /// Build a new OpenMP 'inclusive' clause. | |||
2156 | /// | |||
2157 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2158 | /// Subclasses may override this routine to provide different behavior. | |||
2159 | OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList, | |||
2160 | SourceLocation StartLoc, | |||
2161 | SourceLocation LParenLoc, | |||
2162 | SourceLocation EndLoc) { | |||
2163 | return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, | |||
2164 | EndLoc); | |||
2165 | } | |||
2166 | ||||
2167 | /// Build a new OpenMP 'exclusive' clause. | |||
2168 | /// | |||
2169 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2170 | /// Subclasses may override this routine to provide different behavior. | |||
2171 | OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList, | |||
2172 | SourceLocation StartLoc, | |||
2173 | SourceLocation LParenLoc, | |||
2174 | SourceLocation EndLoc) { | |||
2175 | return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, | |||
2176 | EndLoc); | |||
2177 | } | |||
2178 | ||||
2179 | /// Build a new OpenMP 'uses_allocators' clause. | |||
2180 | /// | |||
2181 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2182 | /// Subclasses may override this routine to provide different behavior. | |||
2183 | OMPClause *RebuildOMPUsesAllocatorsClause( | |||
2184 | ArrayRef<Sema::UsesAllocatorsData> Data, SourceLocation StartLoc, | |||
2185 | SourceLocation LParenLoc, SourceLocation EndLoc) { | |||
2186 | return getSema().ActOnOpenMPUsesAllocatorClause(StartLoc, LParenLoc, EndLoc, | |||
2187 | Data); | |||
2188 | } | |||
2189 | ||||
2190 | /// Build a new OpenMP 'affinity' clause. | |||
2191 | /// | |||
2192 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2193 | /// Subclasses may override this routine to provide different behavior. | |||
2194 | OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc, | |||
2195 | SourceLocation LParenLoc, | |||
2196 | SourceLocation ColonLoc, | |||
2197 | SourceLocation EndLoc, Expr *Modifier, | |||
2198 | ArrayRef<Expr *> Locators) { | |||
2199 | return getSema().ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, | |||
2200 | EndLoc, Modifier, Locators); | |||
2201 | } | |||
2202 | ||||
2203 | /// Build a new OpenMP 'order' clause. | |||
2204 | /// | |||
2205 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2206 | /// Subclasses may override this routine to provide different behavior. | |||
2207 | OMPClause *RebuildOMPOrderClause(OpenMPOrderClauseKind Kind, | |||
2208 | SourceLocation KindKwLoc, | |||
2209 | SourceLocation StartLoc, | |||
2210 | SourceLocation LParenLoc, | |||
2211 | SourceLocation EndLoc) { | |||
2212 | return getSema().ActOnOpenMPOrderClause(Kind, KindKwLoc, StartLoc, | |||
2213 | LParenLoc, EndLoc); | |||
2214 | } | |||
2215 | ||||
2216 | /// Build a new OpenMP 'init' clause. | |||
2217 | /// | |||
2218 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2219 | /// Subclasses may override this routine to provide different behavior. | |||
2220 | OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, | |||
2221 | SourceLocation StartLoc, | |||
2222 | SourceLocation LParenLoc, | |||
2223 | SourceLocation VarLoc, | |||
2224 | SourceLocation EndLoc) { | |||
2225 | return getSema().ActOnOpenMPInitClause(InteropVar, InteropInfo, StartLoc, | |||
2226 | LParenLoc, VarLoc, EndLoc); | |||
2227 | } | |||
2228 | ||||
2229 | /// Build a new OpenMP 'use' clause. | |||
2230 | /// | |||
2231 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2232 | /// Subclasses may override this routine to provide different behavior. | |||
2233 | OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc, | |||
2234 | SourceLocation LParenLoc, | |||
2235 | SourceLocation VarLoc, SourceLocation EndLoc) { | |||
2236 | return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc, | |||
2237 | VarLoc, EndLoc); | |||
2238 | } | |||
2239 | ||||
2240 | /// Build a new OpenMP 'destroy' clause. | |||
2241 | /// | |||
2242 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2243 | /// Subclasses may override this routine to provide different behavior. | |||
2244 | OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, | |||
2245 | SourceLocation LParenLoc, | |||
2246 | SourceLocation VarLoc, | |||
2247 | SourceLocation EndLoc) { | |||
2248 | return getSema().ActOnOpenMPDestroyClause(InteropVar, StartLoc, LParenLoc, | |||
2249 | VarLoc, EndLoc); | |||
2250 | } | |||
2251 | ||||
2252 | /// Build a new OpenMP 'novariants' clause. | |||
2253 | /// | |||
2254 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2255 | /// Subclasses may override this routine to provide different behavior. | |||
2256 | OMPClause *RebuildOMPNovariantsClause(Expr *Condition, | |||
2257 | SourceLocation StartLoc, | |||
2258 | SourceLocation LParenLoc, | |||
2259 | SourceLocation EndLoc) { | |||
2260 | return getSema().ActOnOpenMPNovariantsClause(Condition, StartLoc, LParenLoc, | |||
2261 | EndLoc); | |||
2262 | } | |||
2263 | ||||
2264 | /// Build a new OpenMP 'nocontext' clause. | |||
2265 | /// | |||
2266 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2267 | /// Subclasses may override this routine to provide different behavior. | |||
2268 | OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc, | |||
2269 | SourceLocation LParenLoc, | |||
2270 | SourceLocation EndLoc) { | |||
2271 | return getSema().ActOnOpenMPNocontextClause(Condition, StartLoc, LParenLoc, | |||
2272 | EndLoc); | |||
2273 | } | |||
2274 | ||||
2275 | /// Build a new OpenMP 'filter' clause. | |||
2276 | /// | |||
2277 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2278 | /// Subclasses may override this routine to provide different behavior. | |||
2279 | OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, | |||
2280 | SourceLocation LParenLoc, | |||
2281 | SourceLocation EndLoc) { | |||
2282 | return getSema().ActOnOpenMPFilterClause(ThreadID, StartLoc, LParenLoc, | |||
2283 | EndLoc); | |||
2284 | } | |||
2285 | ||||
2286 | /// Build a new OpenMP 'bind' clause. | |||
2287 | /// | |||
2288 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2289 | /// Subclasses may override this routine to provide different behavior. | |||
2290 | OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind, | |||
2291 | SourceLocation KindLoc, | |||
2292 | SourceLocation StartLoc, | |||
2293 | SourceLocation LParenLoc, | |||
2294 | SourceLocation EndLoc) { | |||
2295 | return getSema().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc, LParenLoc, | |||
2296 | EndLoc); | |||
2297 | } | |||
2298 | ||||
2299 | /// Build a new OpenMP 'align' clause. | |||
2300 | /// | |||
2301 | /// By default, performs semantic analysis to build the new OpenMP clause. | |||
2302 | /// Subclasses may override this routine to provide different behavior. | |||
2303 | OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc, | |||
2304 | SourceLocation LParenLoc, | |||
2305 | SourceLocation EndLoc) { | |||
2306 | return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc); | |||
2307 | } | |||
2308 | ||||
2309 | /// Rebuild the operand to an Objective-C \@synchronized statement. | |||
2310 | /// | |||
2311 | /// By default, performs semantic analysis to build the new statement. | |||
2312 | /// Subclasses may override this routine to provide different behavior. | |||
2313 | ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc, | |||
2314 | Expr *object) { | |||
2315 | return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object); | |||
2316 | } | |||
2317 | ||||
2318 | /// Build a new Objective-C \@synchronized statement. | |||
2319 | /// | |||
2320 | /// By default, performs semantic analysis to build the new statement. | |||
2321 | /// Subclasses may override this routine to provide different behavior. | |||
2322 | StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, | |||
2323 | Expr *Object, Stmt *Body) { | |||
2324 | return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body); | |||
2325 | } | |||
2326 | ||||
2327 | /// Build a new Objective-C \@autoreleasepool statement. | |||
2328 | /// | |||
2329 | /// By default, performs semantic analysis to build the new statement. | |||
2330 | /// Subclasses may override this routine to provide different behavior. | |||
2331 | StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc, | |||
2332 | Stmt *Body) { | |||
2333 | return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body); | |||
2334 | } | |||
2335 | ||||
2336 | /// Build a new Objective-C fast enumeration statement. | |||
2337 | /// | |||
2338 | /// By default, performs semantic analysis to build the new statement. | |||
2339 | /// Subclasses may override this routine to provide different behavior. | |||
2340 | StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc, | |||
2341 | Stmt *Element, | |||
2342 | Expr *Collection, | |||
2343 | SourceLocation RParenLoc, | |||
2344 | Stmt *Body) { | |||
2345 | StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc, | |||
2346 | Element, | |||
2347 | Collection, | |||
2348 | RParenLoc); | |||
2349 | if (ForEachStmt.isInvalid()) | |||
2350 | return StmtError(); | |||
2351 | ||||
2352 | return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body); | |||
2353 | } | |||
2354 | ||||
2355 | /// Build a new C++ exception declaration. | |||
2356 | /// | |||
2357 | /// By default, performs semantic analysis to build the new decaration. | |||
2358 | /// Subclasses may override this routine to provide different behavior. | |||
2359 | VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, | |||
2360 | TypeSourceInfo *Declarator, | |||
2361 | SourceLocation StartLoc, | |||
2362 | SourceLocation IdLoc, | |||
2363 | IdentifierInfo *Id) { | |||
2364 | VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator, | |||
2365 | StartLoc, IdLoc, Id); | |||
2366 | if (Var) | |||
2367 | getSema().CurContext->addDecl(Var); | |||
2368 | return Var; | |||
2369 | } | |||
2370 | ||||
2371 | /// Build a new C++ catch statement. | |||
2372 | /// | |||
2373 | /// By default, performs semantic analysis to build the new statement. | |||
2374 | /// Subclasses may override this routine to provide different behavior. | |||
2375 | StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc, | |||
2376 | VarDecl *ExceptionDecl, | |||
2377 | Stmt *Handler) { | |||
2378 | return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl, | |||
2379 | Handler)); | |||
2380 | } | |||
2381 | ||||
2382 | /// Build a new C++ try statement. | |||
2383 | /// | |||
2384 | /// By default, performs semantic analysis to build the new statement. | |||
2385 | /// Subclasses may override this routine to provide different behavior. | |||
2386 | StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock, | |||
2387 | ArrayRef<Stmt *> Handlers) { | |||
2388 | return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers); | |||
2389 | } | |||
2390 | ||||
2391 | /// Build a new C++0x range-based for statement. | |||
2392 | /// | |||
2393 | /// By default, performs semantic analysis to build the new statement. | |||
2394 | /// Subclasses may override this routine to provide different behavior. | |||
2395 | StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc, | |||
2396 | SourceLocation CoawaitLoc, Stmt *Init, | |||
2397 | SourceLocation ColonLoc, Stmt *Range, | |||
2398 | Stmt *Begin, Stmt *End, Expr *Cond, | |||
2399 | Expr *Inc, Stmt *LoopVar, | |||
2400 | SourceLocation RParenLoc) { | |||
2401 | // If we've just learned that the range is actually an Objective-C | |||
2402 | // collection, treat this as an Objective-C fast enumeration loop. | |||
2403 | if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) { | |||
2404 | if (RangeStmt->isSingleDecl()) { | |||
2405 | if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) { | |||
2406 | if (RangeVar->isInvalidDecl()) | |||
2407 | return StmtError(); | |||
2408 | ||||
2409 | Expr *RangeExpr = RangeVar->getInit(); | |||
2410 | if (!RangeExpr->isTypeDependent() && | |||
2411 | RangeExpr->getType()->isObjCObjectPointerType()) { | |||
2412 | // FIXME: Support init-statements in Objective-C++20 ranged for | |||
2413 | // statement. | |||
2414 | if (Init) { | |||
2415 | return SemaRef.Diag(Init->getBeginLoc(), | |||
2416 | diag::err_objc_for_range_init_stmt) | |||
2417 | << Init->getSourceRange(); | |||
2418 | } | |||
2419 | return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar, | |||
2420 | RangeExpr, RParenLoc); | |||
2421 | } | |||
2422 | } | |||
2423 | } | |||
2424 | } | |||
2425 | ||||
2426 | return getSema().BuildCXXForRangeStmt(ForLoc, CoawaitLoc, Init, ColonLoc, | |||
2427 | Range, Begin, End, Cond, Inc, LoopVar, | |||
2428 | RParenLoc, Sema::BFRK_Rebuild); | |||
2429 | } | |||
2430 | ||||
2431 | /// Build a new C++0x range-based for statement. | |||
2432 | /// | |||
2433 | /// By default, performs semantic analysis to build the new statement. | |||
2434 | /// Subclasses may override this routine to provide different behavior. | |||
2435 | StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, | |||
2436 | bool IsIfExists, | |||
2437 | NestedNameSpecifierLoc QualifierLoc, | |||
2438 | DeclarationNameInfo NameInfo, | |||
2439 | Stmt *Nested) { | |||
2440 | return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists, | |||
2441 | QualifierLoc, NameInfo, Nested); | |||
2442 | } | |||
2443 | ||||
2444 | /// Attach body to a C++0x range-based for statement. | |||
2445 | /// | |||
2446 | /// By default, performs semantic analysis to finish the new statement. | |||
2447 | /// Subclasses may override this routine to provide different behavior. | |||
2448 | StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) { | |||
2449 | return getSema().FinishCXXForRangeStmt(ForRange, Body); | |||
2450 | } | |||
2451 | ||||
2452 | StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, | |||
2453 | Stmt *TryBlock, Stmt *Handler) { | |||
2454 | return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler); | |||
2455 | } | |||
2456 | ||||
2457 | StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, | |||
2458 | Stmt *Block) { | |||
2459 | return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block); | |||
2460 | } | |||
2461 | ||||
2462 | StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) { | |||
2463 | return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block); | |||
2464 | } | |||
2465 | ||||
2466 | ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc, | |||
2467 | SourceLocation LParen, | |||
2468 | SourceLocation RParen, | |||
2469 | TypeSourceInfo *TSI) { | |||
2470 | return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI); | |||
2471 | } | |||
2472 | ||||
2473 | /// Build a new predefined expression. | |||
2474 | /// | |||
2475 | /// By default, performs semantic analysis to build the new expression. | |||
2476 | /// Subclasses may override this routine to provide different behavior. | |||
2477 | ExprResult RebuildPredefinedExpr(SourceLocation Loc, | |||
2478 | PredefinedExpr::IdentKind IK) { | |||
2479 | return getSema().BuildPredefinedExpr(Loc, IK); | |||
2480 | } | |||
2481 | ||||
2482 | /// Build a new expression that references a declaration. | |||
2483 | /// | |||
2484 | /// By default, performs semantic analysis to build the new expression. | |||
2485 | /// Subclasses may override this routine to provide different behavior. | |||
2486 | ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS, | |||
2487 | LookupResult &R, | |||
2488 | bool RequiresADL) { | |||
2489 | return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL); | |||
2490 | } | |||
2491 | ||||
2492 | ||||
2493 | /// Build a new expression that references a declaration. | |||
2494 | /// | |||
2495 | /// By default, performs semantic analysis to build the new expression. | |||
2496 | /// Subclasses may override this routine to provide different behavior. | |||
2497 | ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, | |||
2498 | ValueDecl *VD, | |||
2499 | const DeclarationNameInfo &NameInfo, | |||
2500 | NamedDecl *Found, | |||
2501 | TemplateArgumentListInfo *TemplateArgs) { | |||
2502 | CXXScopeSpec SS; | |||
2503 | SS.Adopt(QualifierLoc); | |||
2504 | return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found, | |||
2505 | TemplateArgs); | |||
2506 | } | |||
2507 | ||||
2508 | /// Build a new expression in parentheses. | |||
2509 | /// | |||
2510 | /// By default, performs semantic analysis to build the new expression. | |||
2511 | /// Subclasses may override this routine to provide different behavior. | |||
2512 | ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen, | |||
2513 | SourceLocation RParen) { | |||
2514 | return getSema().ActOnParenExpr(LParen, RParen, SubExpr); | |||
2515 | } | |||
2516 | ||||
2517 | /// Build a new pseudo-destructor expression. | |||
2518 | /// | |||
2519 | /// By default, performs semantic analysis to build the new expression. | |||
2520 | /// Subclasses may override this routine to provide different behavior. | |||
2521 | ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base, | |||
2522 | SourceLocation OperatorLoc, | |||
2523 | bool isArrow, | |||
2524 | CXXScopeSpec &SS, | |||
2525 | TypeSourceInfo *ScopeType, | |||
2526 | SourceLocation CCLoc, | |||
2527 | SourceLocation TildeLoc, | |||
2528 | PseudoDestructorTypeStorage Destroyed); | |||
2529 | ||||
2530 | /// Build a new unary operator expression. | |||
2531 | /// | |||
2532 | /// By default, performs semantic analysis to build the new expression. | |||
2533 | /// Subclasses may override this routine to provide different behavior. | |||
2534 | ExprResult RebuildUnaryOperator(SourceLocation OpLoc, | |||
2535 | UnaryOperatorKind Opc, | |||
2536 | Expr *SubExpr) { | |||
2537 | return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr); | |||
2538 | } | |||
2539 | ||||
2540 | /// Build a new builtin offsetof expression. | |||
2541 | /// | |||
2542 | /// By default, performs semantic analysis to build the new expression. | |||
2543 | /// Subclasses may override this routine to provide different behavior. | |||
2544 | ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc, | |||
2545 | TypeSourceInfo *Type, | |||
2546 | ArrayRef<Sema::OffsetOfComponent> Components, | |||
2547 | SourceLocation RParenLoc) { | |||
2548 | return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components, | |||
2549 | RParenLoc); | |||
2550 | } | |||
2551 | ||||
2552 | /// Build a new sizeof, alignof or vec_step expression with a | |||
2553 | /// type argument. | |||
2554 | /// | |||
2555 | /// By default, performs semantic analysis to build the new expression. | |||
2556 | /// Subclasses may override this routine to provide different behavior. | |||
2557 | ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo, | |||
2558 | SourceLocation OpLoc, | |||
2559 | UnaryExprOrTypeTrait ExprKind, | |||
2560 | SourceRange R) { | |||
2561 | return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R); | |||
2562 | } | |||
2563 | ||||
2564 | /// Build a new sizeof, alignof or vec step expression with an | |||
2565 | /// expression argument. | |||
2566 | /// | |||
2567 | /// By default, performs semantic analysis to build the new expression. | |||
2568 | /// Subclasses may override this routine to provide different behavior. | |||
2569 | ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc, | |||
2570 | UnaryExprOrTypeTrait ExprKind, | |||
2571 | SourceRange R) { | |||
2572 | ExprResult Result | |||
2573 | = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind); | |||
2574 | if (Result.isInvalid()) | |||
2575 | return ExprError(); | |||
2576 | ||||
2577 | return Result; | |||
2578 | } | |||
2579 | ||||
2580 | /// Build a new array subscript expression. | |||
2581 | /// | |||
2582 | /// By default, performs semantic analysis to build the new expression. | |||
2583 | /// Subclasses may override this routine to provide different behavior. | |||
2584 | ExprResult RebuildArraySubscriptExpr(Expr *LHS, | |||
2585 | SourceLocation LBracketLoc, | |||
2586 | Expr *RHS, | |||
2587 | SourceLocation RBracketLoc) { | |||
2588 | return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS, | |||
2589 | LBracketLoc, RHS, | |||
2590 | RBracketLoc); | |||
2591 | } | |||
2592 | ||||
2593 | /// Build a new matrix subscript expression. | |||
2594 | /// | |||
2595 | /// By default, performs semantic analysis to build the new expression. | |||
2596 | /// Subclasses may override this routine to provide different behavior. | |||
2597 | ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, | |||
2598 | Expr *ColumnIdx, | |||
2599 | SourceLocation RBracketLoc) { | |||
2600 | return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx, | |||
2601 | RBracketLoc); | |||
2602 | } | |||
2603 | ||||
2604 | /// Build a new array section expression. | |||
2605 | /// | |||
2606 | /// By default, performs semantic analysis to build the new expression. | |||
2607 | /// Subclasses may override this routine to provide different behavior. | |||
2608 | ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc, | |||
2609 | Expr *LowerBound, | |||
2610 | SourceLocation ColonLocFirst, | |||
2611 | SourceLocation ColonLocSecond, | |||
2612 | Expr *Length, Expr *Stride, | |||
2613 | SourceLocation RBracketLoc) { | |||
2614 | return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound, | |||
2615 | ColonLocFirst, ColonLocSecond, | |||
2616 | Length, Stride, RBracketLoc); | |||
2617 | } | |||
2618 | ||||
2619 | /// Build a new array shaping expression. | |||
2620 | /// | |||
2621 | /// By default, performs semantic analysis to build the new expression. | |||
2622 | /// Subclasses may override this routine to provide different behavior. | |||
2623 | ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, | |||
2624 | SourceLocation RParenLoc, | |||
2625 | ArrayRef<Expr *> Dims, | |||
2626 | ArrayRef<SourceRange> BracketsRanges) { | |||
2627 | return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims, | |||
2628 | BracketsRanges); | |||
2629 | } | |||
2630 | ||||
2631 | /// Build a new iterator expression. | |||
2632 | /// | |||
2633 | /// By default, performs semantic analysis to build the new expression. | |||
2634 | /// Subclasses may override this routine to provide different behavior. | |||
2635 | ExprResult RebuildOMPIteratorExpr( | |||
2636 | SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, | |||
2637 | ArrayRef<Sema::OMPIteratorData> Data) { | |||
2638 | return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc, | |||
2639 | LLoc, RLoc, Data); | |||
2640 | } | |||
2641 | ||||
2642 | /// Build a new call expression. | |||
2643 | /// | |||
2644 | /// By default, performs semantic analysis to build the new expression. | |||
2645 | /// Subclasses may override this routine to provide different behavior. | |||
2646 | ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, | |||
2647 | MultiExprArg Args, | |||
2648 | SourceLocation RParenLoc, | |||
2649 | Expr *ExecConfig = nullptr) { | |||
2650 | return getSema().ActOnCallExpr( | |||
2651 | /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig); | |||
2652 | } | |||
2653 | ||||
2654 | ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc, | |||
2655 | MultiExprArg Args, | |||
2656 | SourceLocation RParenLoc) { | |||
2657 | return getSema().ActOnArraySubscriptExpr( | |||
2658 | /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc); | |||
2659 | } | |||
2660 | ||||
2661 | /// Build a new member access expression. | |||
2662 | /// | |||
2663 | /// By default, performs semantic analysis to build the new expression. | |||
2664 | /// Subclasses may override this routine to provide different behavior. | |||
2665 | ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, | |||
2666 | bool isArrow, | |||
2667 | NestedNameSpecifierLoc QualifierLoc, | |||
2668 | SourceLocation TemplateKWLoc, | |||
2669 | const DeclarationNameInfo &MemberNameInfo, | |||
2670 | ValueDecl *Member, | |||
2671 | NamedDecl *FoundDecl, | |||
2672 | const TemplateArgumentListInfo *ExplicitTemplateArgs, | |||
2673 | NamedDecl *FirstQualifierInScope) { | |||
2674 | ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base, | |||
2675 | isArrow); | |||
2676 | if (!Member->getDeclName()) { | |||
2677 | // We have a reference to an unnamed field. This is always the | |||
2678 | // base of an anonymous struct/union member access, i.e. the | |||
2679 | // field is always of record type. | |||
2680 | assert(Member->getType()->isRecordType() &&(static_cast <bool> (Member->getType()->isRecordType () && "unnamed member not of record type?") ? void (0 ) : __assert_fail ("Member->getType()->isRecordType() && \"unnamed member not of record type?\"" , "clang/lib/Sema/TreeTransform.h", 2681, __extension__ __PRETTY_FUNCTION__ )) | |||
2681 | "unnamed member not of record type?")(static_cast <bool> (Member->getType()->isRecordType () && "unnamed member not of record type?") ? void (0 ) : __assert_fail ("Member->getType()->isRecordType() && \"unnamed member not of record type?\"" , "clang/lib/Sema/TreeTransform.h", 2681, __extension__ __PRETTY_FUNCTION__ )); | |||
2682 | ||||
2683 | BaseResult = | |||
2684 | getSema().PerformObjectMemberConversion(BaseResult.get(), | |||
2685 | QualifierLoc.getNestedNameSpecifier(), | |||
2686 | FoundDecl, Member); | |||
2687 | if (BaseResult.isInvalid()) | |||
2688 | return ExprError(); | |||
2689 | Base = BaseResult.get(); | |||
2690 | ||||
2691 | CXXScopeSpec EmptySS; | |||
2692 | return getSema().BuildFieldReferenceExpr( | |||
2693 | Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member), | |||
2694 | DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo); | |||
2695 | } | |||
2696 | ||||
2697 | CXXScopeSpec SS; | |||
2698 | SS.Adopt(QualifierLoc); | |||
2699 | ||||
2700 | Base = BaseResult.get(); | |||
2701 | QualType BaseType = Base->getType(); | |||
2702 | ||||
2703 | if (isArrow && !BaseType->isPointerType()) | |||
2704 | return ExprError(); | |||
2705 | ||||
2706 | // FIXME: this involves duplicating earlier analysis in a lot of | |||
2707 | // cases; we should avoid this when possible. | |||
2708 | LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName); | |||
2709 | R.addDecl(FoundDecl); | |||
2710 | R.resolveKind(); | |||
2711 | ||||
2712 | return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow, | |||
2713 | SS, TemplateKWLoc, | |||
2714 | FirstQualifierInScope, | |||
2715 | R, ExplicitTemplateArgs, | |||
2716 | /*S*/nullptr); | |||
2717 | } | |||
2718 | ||||
2719 | /// Build a new binary operator expression. | |||
2720 | /// | |||
2721 | /// By default, performs semantic analysis to build the new expression. | |||
2722 | /// Subclasses may override this routine to provide different behavior. | |||
2723 | ExprResult RebuildBinaryOperator(SourceLocation OpLoc, | |||
2724 | BinaryOperatorKind Opc, | |||
2725 | Expr *LHS, Expr *RHS) { | |||
2726 | return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS); | |||
2727 | } | |||
2728 | ||||
2729 | /// Build a new rewritten operator expression. | |||
2730 | /// | |||
2731 | /// By default, performs semantic analysis to build the new expression. | |||
2732 | /// Subclasses may override this routine to provide different behavior. | |||
2733 | ExprResult RebuildCXXRewrittenBinaryOperator( | |||
2734 | SourceLocation OpLoc, BinaryOperatorKind Opcode, | |||
2735 | const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) { | |||
2736 | return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS, | |||
2737 | RHS, /*RequiresADL*/false); | |||
2738 | } | |||
2739 | ||||
2740 | /// Build a new conditional operator expression. | |||
2741 | /// | |||
2742 | /// By default, performs semantic analysis to build the new expression. | |||
2743 | /// Subclasses may override this routine to provide different behavior. | |||
2744 | ExprResult RebuildConditionalOperator(Expr *Cond, | |||
2745 | SourceLocation QuestionLoc, | |||
2746 | Expr *LHS, | |||
2747 | SourceLocation ColonLoc, | |||
2748 | Expr *RHS) { | |||
2749 | return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond, | |||
2750 | LHS, RHS); | |||
2751 | } | |||
2752 | ||||
2753 | /// Build a new C-style cast expression. | |||
2754 | /// | |||
2755 | /// By default, performs semantic analysis to build the new expression. | |||
2756 | /// Subclasses may override this routine to provide different behavior. | |||
2757 | ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc, | |||
2758 | TypeSourceInfo *TInfo, | |||
2759 | SourceLocation RParenLoc, | |||
2760 | Expr *SubExpr) { | |||
2761 | return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, | |||
2762 | SubExpr); | |||
2763 | } | |||
2764 | ||||
2765 | /// Build a new compound literal expression. | |||
2766 | /// | |||
2767 | /// By default, performs semantic analysis to build the new expression. | |||
2768 | /// Subclasses may override this routine to provide different behavior. | |||
2769 | ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc, | |||
2770 | TypeSourceInfo *TInfo, | |||
2771 | SourceLocation RParenLoc, | |||
2772 | Expr *Init) { | |||
2773 | return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, | |||
2774 | Init); | |||
2775 | } | |||
2776 | ||||
2777 | /// Build a new extended vector element access expression. | |||
2778 | /// | |||
2779 | /// By default, performs semantic analysis to build the new expression. | |||
2780 | /// Subclasses may override this routine to provide different behavior. | |||
2781 | ExprResult RebuildExtVectorElementExpr(Expr *Base, | |||
2782 | SourceLocation OpLoc, | |||
2783 | SourceLocation AccessorLoc, | |||
2784 | IdentifierInfo &Accessor) { | |||
2785 | ||||
2786 | CXXScopeSpec SS; | |||
2787 | DeclarationNameInfo NameInfo(&Accessor, AccessorLoc); | |||
2788 | return getSema().BuildMemberReferenceExpr(Base, Base->getType(), | |||
2789 | OpLoc, /*IsArrow*/ false, | |||
2790 | SS, SourceLocation(), | |||
2791 | /*FirstQualifierInScope*/ nullptr, | |||
2792 | NameInfo, | |||
2793 | /* TemplateArgs */ nullptr, | |||
2794 | /*S*/ nullptr); | |||
2795 | } | |||
2796 | ||||
2797 | /// Build a new initializer list expression. | |||
2798 | /// | |||
2799 | /// By default, performs semantic analysis to build the new expression. | |||
2800 | /// Subclasses may override this routine to provide different behavior. | |||
2801 | ExprResult RebuildInitList(SourceLocation LBraceLoc, | |||
2802 | MultiExprArg Inits, | |||
2803 | SourceLocation RBraceLoc) { | |||
2804 | return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc); | |||
2805 | } | |||
2806 | ||||
2807 | /// Build a new designated initializer expression. | |||
2808 | /// | |||
2809 | /// By default, performs semantic analysis to build the new expression. | |||
2810 | /// Subclasses may override this routine to provide different behavior. | |||
2811 | ExprResult RebuildDesignatedInitExpr(Designation &Desig, | |||
2812 | MultiExprArg ArrayExprs, | |||
2813 | SourceLocation EqualOrColonLoc, | |||
2814 | bool GNUSyntax, | |||
2815 | Expr *Init) { | |||
2816 | ExprResult Result | |||
2817 | = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax, | |||
2818 | Init); | |||
2819 | if (Result.isInvalid()) | |||
2820 | return ExprError(); | |||
2821 | ||||
2822 | return Result; | |||
2823 | } | |||
2824 | ||||
2825 | /// Build a new value-initialized expression. | |||
2826 | /// | |||
2827 | /// By default, builds the implicit value initialization without performing | |||
2828 | /// any semantic analysis. Subclasses may override this routine to provide | |||
2829 | /// different behavior. | |||
2830 | ExprResult RebuildImplicitValueInitExpr(QualType T) { | |||
2831 | return new (SemaRef.Context) ImplicitValueInitExpr(T); | |||
2832 | } | |||
2833 | ||||
2834 | /// Build a new \c va_arg expression. | |||
2835 | /// | |||
2836 | /// By default, performs semantic analysis to build the new expression. | |||
2837 | /// Subclasses may override this routine to provide different behavior. | |||
2838 | ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, | |||
2839 | Expr *SubExpr, TypeSourceInfo *TInfo, | |||
2840 | SourceLocation RParenLoc) { | |||
2841 | return getSema().BuildVAArgExpr(BuiltinLoc, | |||
2842 | SubExpr, TInfo, | |||
2843 | RParenLoc); | |||
2844 | } | |||
2845 | ||||
2846 | /// Build a new expression list in parentheses. | |||
2847 | /// | |||
2848 | /// By default, performs semantic analysis to build the new expression. | |||
2849 | /// Subclasses may override this routine to provide different behavior. | |||
2850 | ExprResult RebuildParenListExpr(SourceLocation LParenLoc, | |||
2851 | MultiExprArg SubExprs, | |||
2852 | SourceLocation RParenLoc) { | |||
2853 | return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs); | |||
2854 | } | |||
2855 | ||||
2856 | /// Build a new address-of-label expression. | |||
2857 | /// | |||
2858 | /// By default, performs semantic analysis, using the name of the label | |||
2859 | /// rather than attempting to map the label statement itself. | |||
2860 | /// Subclasses may override this routine to provide different behavior. | |||
2861 | ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc, | |||
2862 | SourceLocation LabelLoc, LabelDecl *Label) { | |||
2863 | return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label); | |||
2864 | } | |||
2865 | ||||
2866 | /// Build a new GNU statement expression. | |||
2867 | /// | |||
2868 | /// By default, performs semantic analysis to build the new expression. | |||
2869 | /// Subclasses may override this routine to provide different behavior. | |||
2870 | ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt, | |||
2871 | SourceLocation RParenLoc, unsigned TemplateDepth) { | |||
2872 | return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc, | |||
2873 | TemplateDepth); | |||
2874 | } | |||
2875 | ||||
2876 | /// Build a new __builtin_choose_expr expression. | |||
2877 | /// | |||
2878 | /// By default, performs semantic analysis to build the new expression. | |||
2879 | /// Subclasses may override this routine to provide different behavior. | |||
2880 | ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc, | |||
2881 | Expr *Cond, Expr *LHS, Expr *RHS, | |||
2882 | SourceLocation RParenLoc) { | |||
2883 | return SemaRef.ActOnChooseExpr(BuiltinLoc, | |||
2884 | Cond, LHS, RHS, | |||
2885 | RParenLoc); | |||
2886 | } | |||
2887 | ||||
2888 | /// Build a new generic selection expression. | |||
2889 | /// | |||
2890 | /// By default, performs semantic analysis to build the new expression. | |||
2891 | /// Subclasses may override this routine to provide different behavior. | |||
2892 | ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc, | |||
2893 | SourceLocation DefaultLoc, | |||
2894 | SourceLocation RParenLoc, | |||
2895 | Expr *ControllingExpr, | |||
2896 | ArrayRef<TypeSourceInfo *> Types, | |||
2897 | ArrayRef<Expr *> Exprs) { | |||
2898 | return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc, | |||
2899 | ControllingExpr, Types, Exprs); | |||
2900 | } | |||
2901 | ||||
2902 | /// Build a new overloaded operator call expression. | |||
2903 | /// | |||
2904 | /// By default, performs semantic analysis to build the new expression. | |||
2905 | /// The semantic analysis provides the behavior of template instantiation, | |||
2906 | /// copying with transformations that turn what looks like an overloaded | |||
2907 | /// operator call into a use of a builtin operator, performing | |||
2908 | /// argument-dependent lookup, etc. Subclasses may override this routine to | |||
2909 | /// provide different behavior. | |||
2910 | ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, | |||
2911 | SourceLocation OpLoc, | |||
2912 | Expr *Callee, | |||
2913 | Expr *First, | |||
2914 | Expr *Second); | |||
2915 | ||||
2916 | /// Build a new C++ "named" cast expression, such as static_cast or | |||
2917 | /// reinterpret_cast. | |||
2918 | /// | |||
2919 | /// By default, this routine dispatches to one of the more-specific routines | |||
2920 | /// for a particular named case, e.g., RebuildCXXStaticCastExpr(). | |||
2921 | /// Subclasses may override this routine to provide different behavior. | |||
2922 | ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc, | |||
2923 | Stmt::StmtClass Class, | |||
2924 | SourceLocation LAngleLoc, | |||
2925 | TypeSourceInfo *TInfo, | |||
2926 | SourceLocation RAngleLoc, | |||
2927 | SourceLocation LParenLoc, | |||
2928 | Expr *SubExpr, | |||
2929 | SourceLocation RParenLoc) { | |||
2930 | switch (Class) { | |||
2931 | case Stmt::CXXStaticCastExprClass: | |||
2932 | return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo, | |||
2933 | RAngleLoc, LParenLoc, | |||
2934 | SubExpr, RParenLoc); | |||
2935 | ||||
2936 | case Stmt::CXXDynamicCastExprClass: | |||
2937 | return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo, | |||
2938 | RAngleLoc, LParenLoc, | |||
2939 | SubExpr, RParenLoc); | |||
2940 | ||||
2941 | case Stmt::CXXReinterpretCastExprClass: | |||
2942 | return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo, | |||
2943 | RAngleLoc, LParenLoc, | |||
2944 | SubExpr, | |||
2945 | RParenLoc); | |||
2946 | ||||
2947 | case Stmt::CXXConstCastExprClass: | |||
2948 | return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo, | |||
2949 | RAngleLoc, LParenLoc, | |||
2950 | SubExpr, RParenLoc); | |||
2951 | ||||
2952 | case Stmt::CXXAddrspaceCastExprClass: | |||
2953 | return getDerived().RebuildCXXAddrspaceCastExpr( | |||
2954 | OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc); | |||
2955 | ||||
2956 | default: | |||
2957 | llvm_unreachable("Invalid C++ named cast")::llvm::llvm_unreachable_internal("Invalid C++ named cast", "clang/lib/Sema/TreeTransform.h" , 2957); | |||
2958 | } | |||
2959 | } | |||
2960 | ||||
2961 | /// Build a new C++ static_cast expression. | |||
2962 | /// | |||
2963 | /// By default, performs semantic analysis to build the new expression. | |||
2964 | /// Subclasses may override this routine to provide different behavior. | |||
2965 | ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc, | |||
2966 | SourceLocation LAngleLoc, | |||
2967 | TypeSourceInfo *TInfo, | |||
2968 | SourceLocation RAngleLoc, | |||
2969 | SourceLocation LParenLoc, | |||
2970 | Expr *SubExpr, | |||
2971 | SourceLocation RParenLoc) { | |||
2972 | return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast, | |||
2973 | TInfo, SubExpr, | |||
2974 | SourceRange(LAngleLoc, RAngleLoc), | |||
2975 | SourceRange(LParenLoc, RParenLoc)); | |||
2976 | } | |||
2977 | ||||
2978 | /// Build a new C++ dynamic_cast expression. | |||
2979 | /// | |||
2980 | /// By default, performs semantic analysis to build the new expression. | |||
2981 | /// Subclasses may override this routine to provide different behavior. | |||
2982 | ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc, | |||
2983 | SourceLocation LAngleLoc, | |||
2984 | TypeSourceInfo *TInfo, | |||
2985 | SourceLocation RAngleLoc, | |||
2986 | SourceLocation LParenLoc, | |||
2987 | Expr *SubExpr, | |||
2988 | SourceLocation RParenLoc) { | |||
2989 | return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast, | |||
2990 | TInfo, SubExpr, | |||
2991 | SourceRange(LAngleLoc, RAngleLoc), | |||
2992 | SourceRange(LParenLoc, RParenLoc)); | |||
2993 | } | |||
2994 | ||||
2995 | /// Build a new C++ reinterpret_cast expression. | |||
2996 | /// | |||
2997 | /// By default, performs semantic analysis to build the new expression. | |||
2998 | /// Subclasses may override this routine to provide different behavior. | |||
2999 | ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc, | |||
3000 | SourceLocation LAngleLoc, | |||
3001 | TypeSourceInfo *TInfo, | |||
3002 | SourceLocation RAngleLoc, | |||
3003 | SourceLocation LParenLoc, | |||
3004 | Expr *SubExpr, | |||
3005 | SourceLocation RParenLoc) { | |||
3006 | return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast, | |||
3007 | TInfo, SubExpr, | |||
3008 | SourceRange(LAngleLoc, RAngleLoc), | |||
3009 | SourceRange(LParenLoc, RParenLoc)); | |||
3010 | } | |||
3011 | ||||
3012 | /// Build a new C++ const_cast expression. | |||
3013 | /// | |||
3014 | /// By default, performs semantic analysis to build the new expression. | |||
3015 | /// Subclasses may override this routine to provide different behavior. | |||
3016 | ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc, | |||
3017 | SourceLocation LAngleLoc, | |||
3018 | TypeSourceInfo *TInfo, | |||
3019 | SourceLocation RAngleLoc, | |||
3020 | SourceLocation LParenLoc, | |||
3021 | Expr *SubExpr, | |||
3022 | SourceLocation RParenLoc) { | |||
3023 | return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast, | |||
3024 | TInfo, SubExpr, | |||
3025 | SourceRange(LAngleLoc, RAngleLoc), | |||
3026 | SourceRange(LParenLoc, RParenLoc)); | |||
3027 | } | |||
3028 | ||||
3029 | ExprResult | |||
3030 | RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, | |||
3031 | TypeSourceInfo *TInfo, SourceLocation RAngleLoc, | |||
3032 | SourceLocation LParenLoc, Expr *SubExpr, | |||
3033 | SourceLocation RParenLoc) { | |||
3034 | return getSema().BuildCXXNamedCast( | |||
3035 | OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr, | |||
3036 | SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc)); | |||
3037 | } | |||
3038 | ||||
3039 | /// Build a new C++ functional-style cast expression. | |||
3040 | /// | |||
3041 | /// By default, performs semantic analysis to build the new expression. | |||
3042 | /// Subclasses may override this routine to provide different behavior. | |||
3043 | ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, | |||
3044 | SourceLocation LParenLoc, | |||
3045 | Expr *Sub, | |||
3046 | SourceLocation RParenLoc, | |||
3047 | bool ListInitialization) { | |||
3048 | return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc, | |||
3049 | MultiExprArg(&Sub, 1), RParenLoc, | |||
3050 | ListInitialization); | |||
3051 | } | |||
3052 | ||||
3053 | /// Build a new C++ __builtin_bit_cast expression. | |||
3054 | /// | |||
3055 | /// By default, performs semantic analysis to build the new expression. | |||
3056 | /// Subclasses may override this routine to provide different behavior. | |||
3057 | ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc, | |||
3058 | TypeSourceInfo *TSI, Expr *Sub, | |||
3059 | SourceLocation RParenLoc) { | |||
3060 | return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc); | |||
3061 | } | |||
3062 | ||||
3063 | /// Build a new C++ typeid(type) expression. | |||
3064 | /// | |||
3065 | /// By default, performs semantic analysis to build the new expression. | |||
3066 | /// Subclasses may override this routine to provide different behavior. | |||
3067 | ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, | |||
3068 | SourceLocation TypeidLoc, | |||
3069 | TypeSourceInfo *Operand, | |||
3070 | SourceLocation RParenLoc) { | |||
3071 | return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, | |||
3072 | RParenLoc); | |||
3073 | } | |||
3074 | ||||
3075 | ||||
3076 | /// Build a new C++ typeid(expr) expression. | |||
3077 | /// | |||
3078 | /// By default, performs semantic analysis to build the new expression. | |||
3079 | /// Subclasses may override this routine to provide different behavior. | |||
3080 | ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, | |||
3081 | SourceLocation TypeidLoc, | |||
3082 | Expr *Operand, | |||
3083 | SourceLocation RParenLoc) { | |||
3084 | return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, | |||
3085 | RParenLoc); | |||
3086 | } | |||
3087 | ||||
3088 | /// Build a new C++ __uuidof(type) expression. | |||
3089 | /// | |||
3090 | /// By default, performs semantic analysis to build the new expression. | |||
3091 | /// Subclasses may override this routine to provide different behavior. | |||
3092 | ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc, | |||
3093 | TypeSourceInfo *Operand, | |||
3094 | SourceLocation RParenLoc) { | |||
3095 | return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc); | |||
3096 | } | |||
3097 | ||||
3098 | /// Build a new C++ __uuidof(expr) expression. | |||
3099 | /// | |||
3100 | /// By default, performs semantic analysis to build the new expression. | |||
3101 | /// Subclasses may override this routine to provide different behavior. | |||
3102 | ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc, | |||
3103 | Expr *Operand, SourceLocation RParenLoc) { | |||
3104 | return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc); | |||
3105 | } | |||
3106 | ||||
3107 | /// Build a new C++ "this" expression. | |||
3108 | /// | |||
3109 | /// By default, builds a new "this" expression without performing any | |||
3110 | /// semantic analysis. Subclasses may override this routine to provide | |||
3111 | /// different behavior. | |||
3112 | ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, | |||
3113 | QualType ThisType, | |||
3114 | bool isImplicit) { | |||
3115 | return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit); | |||
3116 | } | |||
3117 | ||||
3118 | /// Build a new C++ throw expression. | |||
3119 | /// | |||
3120 | /// By default, performs semantic analysis to build the new expression. | |||
3121 | /// Subclasses may override this routine to provide different behavior. | |||
3122 | ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub, | |||
3123 | bool IsThrownVariableInScope) { | |||
3124 | return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope); | |||
3125 | } | |||
3126 | ||||
3127 | /// Build a new C++ default-argument expression. | |||
3128 | /// | |||
3129 | /// By default, builds a new default-argument expression, which does not | |||
3130 | /// require any semantic analysis. Subclasses may override this routine to | |||
3131 | /// provide different behavior. | |||
3132 | ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param) { | |||
3133 | return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param, | |||
3134 | getSema().CurContext); | |||
3135 | } | |||
3136 | ||||
3137 | /// Build a new C++11 default-initialization expression. | |||
3138 | /// | |||
3139 | /// By default, builds a new default field initialization expression, which | |||
3140 | /// does not require any semantic analysis. Subclasses may override this | |||
3141 | /// routine to provide different behavior. | |||
3142 | ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, | |||
3143 | FieldDecl *Field) { | |||
3144 | return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field, | |||
3145 | getSema().CurContext); | |||
3146 | } | |||
3147 | ||||
3148 | /// Build a new C++ zero-initialization expression. | |||
3149 | /// | |||
3150 | /// By default, performs semantic analysis to build the new expression. | |||
3151 | /// Subclasses may override this routine to provide different behavior. | |||
3152 | ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo, | |||
3153 | SourceLocation LParenLoc, | |||
3154 | SourceLocation RParenLoc) { | |||
3155 | return getSema().BuildCXXTypeConstructExpr( | |||
3156 | TSInfo, LParenLoc, None, RParenLoc, /*ListInitialization=*/false); | |||
3157 | } | |||
3158 | ||||
3159 | /// Build a new C++ "new" expression. | |||
3160 | /// | |||
3161 | /// By default, performs semantic analysis to build the new expression. | |||
3162 | /// Subclasses may override this routine to provide different behavior. | |||
3163 | ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, | |||
3164 | bool UseGlobal, | |||
3165 | SourceLocation PlacementLParen, | |||
3166 | MultiExprArg PlacementArgs, | |||
3167 | SourceLocation PlacementRParen, | |||
3168 | SourceRange TypeIdParens, | |||
3169 | QualType AllocatedType, | |||
3170 | TypeSourceInfo *AllocatedTypeInfo, | |||
3171 | Optional<Expr *> ArraySize, | |||
3172 | SourceRange DirectInitRange, | |||
3173 | Expr *Initializer) { | |||
3174 | return getSema().BuildCXXNew(StartLoc, UseGlobal, | |||
3175 | PlacementLParen, | |||
3176 | PlacementArgs, | |||
3177 | PlacementRParen, | |||
3178 | TypeIdParens, | |||
3179 | AllocatedType, | |||
3180 | AllocatedTypeInfo, | |||
3181 | ArraySize, | |||
3182 | DirectInitRange, | |||
3183 | Initializer); | |||
3184 | } | |||
3185 | ||||
3186 | /// Build a new C++ "delete" expression. | |||
3187 | /// | |||
3188 | /// By default, performs semantic analysis to build the new expression. | |||
3189 | /// Subclasses may override this routine to provide different behavior. | |||
3190 | ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc, | |||
3191 | bool IsGlobalDelete, | |||
3192 | bool IsArrayForm, | |||
3193 | Expr *Operand) { | |||
3194 | return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm, | |||
3195 | Operand); | |||
3196 | } | |||
3197 | ||||
3198 | /// Build a new type trait expression. | |||
3199 | /// | |||
3200 | /// By default, performs semantic analysis to build the new expression. | |||
3201 | /// Subclasses may override this routine to provide different behavior. | |||
3202 | ExprResult RebuildTypeTrait(TypeTrait Trait, | |||
3203 | SourceLocation StartLoc, | |||
3204 | ArrayRef<TypeSourceInfo *> Args, | |||
3205 | SourceLocation RParenLoc) { | |||
3206 | return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc); | |||
3207 | } | |||
3208 | ||||
3209 | /// Build a new array type trait expression. | |||
3210 | /// | |||
3211 | /// By default, performs semantic analysis to build the new expression. | |||
3212 | /// Subclasses may override this routine to provide different behavior. | |||
3213 | ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait, | |||
3214 | SourceLocation StartLoc, | |||
3215 | TypeSourceInfo *TSInfo, | |||
3216 | Expr *DimExpr, | |||
3217 | SourceLocation RParenLoc) { | |||
3218 | return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc); | |||
3219 | } | |||
3220 | ||||
3221 | /// Build a new expression trait expression. | |||
3222 | /// | |||
3223 | /// By default, performs semantic analysis to build the new expression. | |||
3224 | /// Subclasses may override this routine to provide different behavior. | |||
3225 | ExprResult RebuildExpressionTrait(ExpressionTrait Trait, | |||
3226 | SourceLocation StartLoc, | |||
3227 | Expr *Queried, | |||
3228 | SourceLocation RParenLoc) { | |||
3229 | return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc); | |||
3230 | } | |||
3231 | ||||
3232 | /// Build a new (previously unresolved) declaration reference | |||
3233 | /// expression. | |||
3234 | /// | |||
3235 | /// By default, performs semantic analysis to build the new expression. | |||
3236 | /// Subclasses may override this routine to provide different behavior. | |||
3237 | ExprResult RebuildDependentScopeDeclRefExpr( | |||
3238 | NestedNameSpecifierLoc QualifierLoc, | |||
3239 | SourceLocation TemplateKWLoc, | |||
3240 | const DeclarationNameInfo &NameInfo, | |||
3241 | const TemplateArgumentListInfo *TemplateArgs, | |||
3242 | bool IsAddressOfOperand, | |||
3243 | TypeSourceInfo **RecoveryTSI) { | |||
3244 | CXXScopeSpec SS; | |||
3245 | SS.Adopt(QualifierLoc); | |||
3246 | ||||
3247 | if (TemplateArgs || TemplateKWLoc.isValid()) | |||
3248 | return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo, | |||
3249 | TemplateArgs); | |||
3250 | ||||
3251 | return getSema().BuildQualifiedDeclarationNameExpr( | |||
3252 | SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI); | |||
3253 | } | |||
3254 | ||||
3255 | /// Build a new template-id expression. | |||
3256 | /// | |||
3257 | /// By default, performs semantic analysis to build the new expression. | |||
3258 | /// Subclasses may override this routine to provide different behavior. | |||
3259 | ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS, | |||
3260 | SourceLocation TemplateKWLoc, | |||
3261 | LookupResult &R, | |||
3262 | bool RequiresADL, | |||
3263 | const TemplateArgumentListInfo *TemplateArgs) { | |||
3264 | return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL, | |||
3265 | TemplateArgs); | |||
3266 | } | |||
3267 | ||||
3268 | /// Build a new object-construction expression. | |||
3269 | /// | |||
3270 | /// By default, performs semantic analysis to build the new expression. | |||
3271 | /// Subclasses may override this routine to provide different behavior. | |||
3272 | ExprResult RebuildCXXConstructExpr(QualType T, | |||
3273 | SourceLocation Loc, | |||
3274 | CXXConstructorDecl *Constructor, | |||
3275 | bool IsElidable, | |||
3276 | MultiExprArg Args, | |||
3277 | bool HadMultipleCandidates, | |||
3278 | bool ListInitialization, | |||
3279 | bool StdInitListInitialization, | |||
3280 | bool RequiresZeroInit, | |||
3281 | CXXConstructExpr::ConstructionKind ConstructKind, | |||
3282 | SourceRange ParenRange) { | |||
3283 | // Reconstruct the constructor we originally found, which might be | |||
3284 | // different if this is a call to an inherited constructor. | |||
3285 | CXXConstructorDecl *FoundCtor = Constructor; | |||
3286 | if (Constructor->isInheritingConstructor()) | |||
3287 | FoundCtor = Constructor->getInheritedConstructor().getConstructor(); | |||
3288 | ||||
3289 | SmallVector<Expr *, 8> ConvertedArgs; | |||
3290 | if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc, | |||
3291 | ConvertedArgs)) | |||
3292 | return ExprError(); | |||
3293 | ||||
3294 | return getSema().BuildCXXConstructExpr(Loc, T, Constructor, | |||
3295 | IsElidable, | |||
3296 | ConvertedArgs, | |||
3297 | HadMultipleCandidates, | |||
3298 | ListInitialization, | |||
3299 | StdInitListInitialization, | |||
3300 | RequiresZeroInit, ConstructKind, | |||
3301 | ParenRange); | |||
3302 | } | |||
3303 | ||||
3304 | /// Build a new implicit construction via inherited constructor | |||
3305 | /// expression. | |||
3306 | ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc, | |||
3307 | CXXConstructorDecl *Constructor, | |||
3308 | bool ConstructsVBase, | |||
3309 | bool InheritedFromVBase) { | |||
3310 | return new (getSema().Context) CXXInheritedCtorInitExpr( | |||
3311 | Loc, T, Constructor, ConstructsVBase, InheritedFromVBase); | |||
3312 | } | |||
3313 | ||||
3314 | /// Build a new object-construction expression. | |||
3315 | /// | |||
3316 | /// By default, performs semantic analysis to build the new expression. | |||
3317 | /// Subclasses may override this routine to provide different behavior. | |||
3318 | ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo, | |||
3319 | SourceLocation LParenOrBraceLoc, | |||
3320 | MultiExprArg Args, | |||
3321 | SourceLocation RParenOrBraceLoc, | |||
3322 | bool ListInitialization) { | |||
3323 | return getSema().BuildCXXTypeConstructExpr( | |||
3324 | TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization); | |||
3325 | } | |||
3326 | ||||
3327 | /// Build a new object-construction expression. | |||
3328 | /// | |||
3329 | /// By default, performs semantic analysis to build the new expression. | |||
3330 | /// Subclasses may override this routine to provide different behavior. | |||
3331 | ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo, | |||
3332 | SourceLocation LParenLoc, | |||
3333 | MultiExprArg Args, | |||
3334 | SourceLocation RParenLoc, | |||
3335 | bool ListInitialization) { | |||
3336 | return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args, | |||
3337 | RParenLoc, ListInitialization); | |||
3338 | } | |||
3339 | ||||
3340 | /// Build a new member reference expression. | |||
3341 | /// | |||
3342 | /// By default, performs semantic analysis to build the new expression. | |||
3343 | /// Subclasses may override this routine to provide different behavior. | |||
3344 | ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE, | |||
3345 | QualType BaseType, | |||
3346 | bool IsArrow, | |||
3347 | SourceLocation OperatorLoc, | |||
3348 | NestedNameSpecifierLoc QualifierLoc, | |||
3349 | SourceLocation TemplateKWLoc, | |||
3350 | NamedDecl *FirstQualifierInScope, | |||
3351 | const DeclarationNameInfo &MemberNameInfo, | |||
3352 | const TemplateArgumentListInfo *TemplateArgs) { | |||
3353 | CXXScopeSpec SS; | |||
3354 | SS.Adopt(QualifierLoc); | |||
3355 | ||||
3356 | return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, | |||
3357 | OperatorLoc, IsArrow, | |||
3358 | SS, TemplateKWLoc, | |||
3359 | FirstQualifierInScope, | |||
3360 | MemberNameInfo, | |||
3361 | TemplateArgs, /*S*/nullptr); | |||
3362 | } | |||
3363 | ||||
3364 | /// Build a new member reference expression. | |||
3365 | /// | |||
3366 | /// By default, performs semantic analysis to build the new expression. | |||
3367 | /// Subclasses may override this routine to provide different behavior. | |||
3368 | ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType, | |||
3369 | SourceLocation OperatorLoc, | |||
3370 | bool IsArrow, | |||
3371 | NestedNameSpecifierLoc QualifierLoc, | |||
3372 | SourceLocation TemplateKWLoc, | |||
3373 | NamedDecl *FirstQualifierInScope, | |||
3374 | LookupResult &R, | |||
3375 | const TemplateArgumentListInfo *TemplateArgs) { | |||
3376 | CXXScopeSpec SS; | |||
3377 | SS.Adopt(QualifierLoc); | |||
3378 | ||||
3379 | return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, | |||
3380 | OperatorLoc, IsArrow, | |||
3381 | SS, TemplateKWLoc, | |||
3382 | FirstQualifierInScope, | |||
3383 | R, TemplateArgs, /*S*/nullptr); | |||
3384 | } | |||
3385 | ||||
3386 | /// Build a new noexcept expression. | |||
3387 | /// | |||
3388 | /// By default, performs semantic analysis to build the new expression. | |||
3389 | /// Subclasses may override this routine to provide different behavior. | |||
3390 | ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) { | |||
3391 | return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd()); | |||
3392 | } | |||
3393 | ||||
3394 | /// Build a new expression to compute the length of a parameter pack. | |||
3395 | ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, | |||
3396 | NamedDecl *Pack, | |||
3397 | SourceLocation PackLoc, | |||
3398 | SourceLocation RParenLoc, | |||
3399 | Optional<unsigned> Length, | |||
3400 | ArrayRef<TemplateArgument> PartialArgs) { | |||
3401 | return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc, | |||
3402 | RParenLoc, Length, PartialArgs); | |||
3403 | } | |||
3404 | ||||
3405 | /// Build a new expression representing a call to a source location | |||
3406 | /// builtin. | |||
3407 | /// | |||
3408 | /// By default, performs semantic analysis to build the new expression. | |||
3409 | /// Subclasses may override this routine to provide different behavior. | |||
3410 | ExprResult RebuildSourceLocExpr(SourceLocExpr::IdentKind Kind, | |||
3411 | QualType ResultTy, SourceLocation BuiltinLoc, | |||
3412 | SourceLocation RPLoc, | |||
3413 | DeclContext *ParentContext) { | |||
3414 | return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc, | |||
3415 | ParentContext); | |||
3416 | } | |||
3417 | ||||
3418 | /// Build a new Objective-C boxed expression. | |||
3419 | /// | |||
3420 | /// By default, performs semantic analysis to build the new expression. | |||
3421 | /// Subclasses may override this routine to provide different behavior. | |||
3422 | ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS, | |||
3423 | SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, | |||
3424 | NamedDecl *FoundDecl, ConceptDecl *NamedConcept, | |||
3425 | TemplateArgumentListInfo *TALI) { | |||
3426 | CXXScopeSpec SS; | |||
3427 | SS.Adopt(NNS); | |||
3428 | ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc, | |||
3429 | ConceptNameInfo, | |||
3430 | FoundDecl, | |||
3431 | NamedConcept, TALI); | |||
3432 | if (Result.isInvalid()) | |||
3433 | return ExprError(); | |||
3434 | return Result; | |||
3435 | } | |||
3436 | ||||
3437 | /// \brief Build a new requires expression. | |||
3438 | /// | |||
3439 | /// By default, performs semantic analysis to build the new expression. | |||
3440 | /// Subclasses may override this routine to provide different behavior. | |||
3441 | ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc, | |||
3442 | RequiresExprBodyDecl *Body, | |||
3443 | ArrayRef<ParmVarDecl *> LocalParameters, | |||
3444 | ArrayRef<concepts::Requirement *> Requirements, | |||
3445 | SourceLocation ClosingBraceLoc) { | |||
3446 | return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, | |||
3447 | LocalParameters, Requirements, ClosingBraceLoc); | |||
3448 | } | |||
3449 | ||||
3450 | concepts::TypeRequirement * | |||
3451 | RebuildTypeRequirement( | |||
3452 | concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { | |||
3453 | return SemaRef.BuildTypeRequirement(SubstDiag); | |||
3454 | } | |||
3455 | ||||
3456 | concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) { | |||
3457 | return SemaRef.BuildTypeRequirement(T); | |||
3458 | } | |||
3459 | ||||
3460 | concepts::ExprRequirement * | |||
3461 | RebuildExprRequirement( | |||
3462 | concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple, | |||
3463 | SourceLocation NoexceptLoc, | |||
3464 | concepts::ExprRequirement::ReturnTypeRequirement Ret) { | |||
3465 | return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc, | |||
3466 | std::move(Ret)); | |||
3467 | } | |||
3468 | ||||
3469 | concepts::ExprRequirement * | |||
3470 | RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc, | |||
3471 | concepts::ExprRequirement::ReturnTypeRequirement Ret) { | |||
3472 | return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc, | |||
3473 | std::move(Ret)); | |||
3474 | } | |||
3475 | ||||
3476 | concepts::NestedRequirement * | |||
3477 | RebuildNestedRequirement( | |||
3478 | concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { | |||
3479 | return SemaRef.BuildNestedRequirement(SubstDiag); | |||
3480 | } | |||
3481 | ||||
3482 | concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) { | |||
3483 | return SemaRef.BuildNestedRequirement(Constraint); | |||
3484 | } | |||
3485 | ||||
3486 | /// \brief Build a new Objective-C boxed expression. | |||
3487 | /// | |||
3488 | /// By default, performs semantic analysis to build the new expression. | |||
3489 | /// Subclasses may override this routine to provide different behavior. | |||
3490 | ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { | |||
3491 | return getSema().BuildObjCBoxedExpr(SR, ValueExpr); | |||
3492 | } | |||
3493 | ||||
3494 | /// Build a new Objective-C array literal. | |||
3495 | /// | |||
3496 | /// By default, performs semantic analysis to build the new expression. | |||
3497 | /// Subclasses may override this routine to provide different behavior. | |||
3498 | ExprResult RebuildObjCArrayLiteral(SourceRange Range, | |||
3499 | Expr **Elements, unsigned NumElements) { | |||
3500 | return getSema().BuildObjCArrayLiteral(Range, | |||
3501 | MultiExprArg(Elements, NumElements)); | |||
3502 | } | |||
3503 | ||||
3504 | ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, | |||
3505 | Expr *Base, Expr *Key, | |||
3506 | ObjCMethodDecl *getterMethod, | |||
3507 | ObjCMethodDecl *setterMethod) { | |||
3508 | return getSema().BuildObjCSubscriptExpression(RB, Base, Key, | |||
3509 | getterMethod, setterMethod); | |||
3510 | } | |||
3511 | ||||
3512 | /// Build a new Objective-C dictionary literal. | |||
3513 | /// | |||
3514 | /// By default, performs semantic analysis to build the new expression. | |||
3515 | /// Subclasses may override this routine to provide different behavior. | |||
3516 | ExprResult RebuildObjCDictionaryLiteral(SourceRange Range, | |||
3517 | MutableArrayRef<ObjCDictionaryElement> Elements) { | |||
3518 | return getSema().BuildObjCDictionaryLiteral(Range, Elements); | |||
3519 | } | |||
3520 | ||||
3521 | /// Build a new Objective-C \@encode expression. | |||
3522 | /// | |||
3523 | /// By default, performs semantic analysis to build the new expression. | |||
3524 | /// Subclasses may override this routine to provide different behavior. | |||
3525 | ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, | |||
3526 | TypeSourceInfo *EncodeTypeInfo, | |||
3527 | SourceLocation RParenLoc) { | |||
3528 | return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc); | |||
3529 | } | |||
3530 | ||||
3531 | /// Build a new Objective-C class message. | |||
3532 | ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo, | |||
3533 | Selector Sel, | |||
3534 | ArrayRef<SourceLocation> SelectorLocs, | |||
3535 | ObjCMethodDecl *Method, | |||
3536 | SourceLocation LBracLoc, | |||
3537 | MultiExprArg Args, | |||
3538 | SourceLocation RBracLoc) { | |||
3539 | return SemaRef.BuildClassMessage(ReceiverTypeInfo, | |||
3540 | ReceiverTypeInfo->getType(), | |||
3541 | /*SuperLoc=*/SourceLocation(), | |||
3542 | Sel, Method, LBracLoc, SelectorLocs, | |||
3543 | RBracLoc, Args); | |||
3544 | } | |||
3545 | ||||
3546 | /// Build a new Objective-C instance message. | |||
3547 | ExprResult RebuildObjCMessageExpr(Expr *Receiver, | |||
3548 | Selector Sel, | |||
3549 | ArrayRef<SourceLocation> SelectorLocs, | |||
3550 | ObjCMethodDecl *Method, | |||
3551 | SourceLocation LBracLoc, | |||
3552 | MultiExprArg Args, | |||
3553 | SourceLocation RBracLoc) { | |||
3554 | return SemaRef.BuildInstanceMessage(Receiver, | |||
3555 | Receiver->getType(), | |||
3556 | /*SuperLoc=*/SourceLocation(), | |||
3557 | Sel, Method, LBracLoc, SelectorLocs, | |||
3558 | RBracLoc, Args); | |||
3559 | } | |||
3560 | ||||
3561 | /// Build a new Objective-C instance/class message to 'super'. | |||
3562 | ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc, | |||
3563 | Selector Sel, | |||
3564 | ArrayRef<SourceLocation> SelectorLocs, | |||
3565 | QualType SuperType, | |||
3566 | ObjCMethodDecl *Method, | |||
3567 | SourceLocation LBracLoc, | |||
3568 | MultiExprArg Args, | |||
3569 | SourceLocation RBracLoc) { | |||
3570 | return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(nullptr, | |||
3571 | SuperType, | |||
3572 | SuperLoc, | |||
3573 | Sel, Method, LBracLoc, SelectorLocs, | |||
3574 | RBracLoc, Args) | |||
3575 | : SemaRef.BuildClassMessage(nullptr, | |||
3576 | SuperType, | |||
3577 | SuperLoc, | |||
3578 | Sel, Method, LBracLoc, SelectorLocs, | |||
3579 | RBracLoc, Args); | |||
3580 | ||||
3581 | ||||
3582 | } | |||
3583 | ||||
3584 | /// Build a new Objective-C ivar reference expression. | |||
3585 | /// | |||
3586 | /// By default, performs semantic analysis to build the new expression. | |||
3587 | /// Subclasses may override this routine to provide different behavior. | |||
3588 | ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar, | |||
3589 | SourceLocation IvarLoc, | |||
3590 | bool IsArrow, bool IsFreeIvar) { | |||
3591 | CXXScopeSpec SS; | |||
3592 | DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc); | |||
3593 | ExprResult Result = getSema().BuildMemberReferenceExpr( | |||
3594 | BaseArg, BaseArg->getType(), | |||
3595 | /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(), | |||
3596 | /*FirstQualifierInScope=*/nullptr, NameInfo, | |||
3597 | /*TemplateArgs=*/nullptr, | |||
3598 | /*S=*/nullptr); | |||
3599 | if (IsFreeIvar && Result.isUsable()) | |||
3600 | cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar); | |||
3601 | return Result; | |||
3602 | } | |||
3603 | ||||
3604 | /// Build a new Objective-C property reference expression. | |||
3605 | /// | |||
3606 | /// By default, performs semantic analysis to build the new expression. | |||
3607 | /// Subclasses may override this routine to provide different behavior. | |||
3608 | ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, | |||
3609 | ObjCPropertyDecl *Property, | |||
3610 | SourceLocation PropertyLoc) { | |||
3611 | CXXScopeSpec SS; | |||
3612 | DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc); | |||
3613 | return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(), | |||
3614 | /*FIXME:*/PropertyLoc, | |||
3615 | /*IsArrow=*/false, | |||
3616 | SS, SourceLocation(), | |||
3617 | /*FirstQualifierInScope=*/nullptr, | |||
3618 | NameInfo, | |||
3619 | /*TemplateArgs=*/nullptr, | |||
3620 | /*S=*/nullptr); | |||
3621 | } | |||
3622 | ||||
3623 | /// Build a new Objective-C property reference expression. | |||
3624 | /// | |||
3625 | /// By default, performs semantic analysis to build the new expression. | |||
3626 | /// Subclasses may override this routine to provide different behavior. | |||
3627 | ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T, | |||
3628 | ObjCMethodDecl *Getter, | |||
3629 | ObjCMethodDecl *Setter, | |||
3630 | SourceLocation PropertyLoc) { | |||
3631 | // Since these expressions can only be value-dependent, we do not | |||
3632 | // need to perform semantic analysis again. | |||
3633 | return Owned( | |||
3634 | new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T, | |||
3635 | VK_LValue, OK_ObjCProperty, | |||
3636 | PropertyLoc, Base)); | |||
3637 | } | |||
3638 | ||||
3639 | /// Build a new Objective-C "isa" expression. | |||
3640 | /// | |||
3641 | /// By default, performs semantic analysis to build the new expression. | |||
3642 | /// Subclasses may override this routine to provide different behavior. | |||
3643 | ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc, | |||
3644 | SourceLocation OpLoc, bool IsArrow) { | |||
3645 | CXXScopeSpec SS; | |||
3646 | DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc); | |||
3647 | return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(), | |||
3648 | OpLoc, IsArrow, | |||
3649 | SS, SourceLocation(), | |||
3650 | /*FirstQualifierInScope=*/nullptr, | |||
3651 | NameInfo, | |||
3652 | /*TemplateArgs=*/nullptr, | |||
3653 | /*S=*/nullptr); | |||
3654 | } | |||
3655 | ||||
3656 | /// Build a new shuffle vector expression. | |||
3657 | /// | |||
3658 | /// By default, performs semantic analysis to build the new expression. | |||
3659 | /// Subclasses may override this routine to provide different behavior. | |||
3660 | ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc, | |||
3661 | MultiExprArg SubExprs, | |||
3662 | SourceLocation RParenLoc) { | |||
3663 | // Find the declaration for __builtin_shufflevector | |||
3664 | const IdentifierInfo &Name | |||
3665 | = SemaRef.Context.Idents.get("__builtin_shufflevector"); | |||
3666 | TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl(); | |||
3667 | DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name)); | |||
3668 | assert(!Lookup.empty() && "No __builtin_shufflevector?")(static_cast <bool> (!Lookup.empty() && "No __builtin_shufflevector?" ) ? void (0) : __assert_fail ("!Lookup.empty() && \"No __builtin_shufflevector?\"" , "clang/lib/Sema/TreeTransform.h", 3668, __extension__ __PRETTY_FUNCTION__ )); | |||
3669 | ||||
3670 | // Build a reference to the __builtin_shufflevector builtin | |||
3671 | FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front()); | |||
3672 | Expr *Callee = new (SemaRef.Context) | |||
3673 | DeclRefExpr(SemaRef.Context, Builtin, false, | |||
3674 | SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc); | |||
3675 | QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType()); | |||
3676 | Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy, | |||
3677 | CK_BuiltinFnToFnPtr).get(); | |||
3678 | ||||
3679 | // Build the CallExpr | |||
3680 | ExprResult TheCall = CallExpr::Create( | |||
3681 | SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(), | |||
3682 | Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc, | |||
3683 | FPOptionsOverride()); | |||
3684 | ||||
3685 | // Type-check the __builtin_shufflevector expression. | |||
3686 | return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get())); | |||
3687 | } | |||
3688 | ||||
3689 | /// Build a new convert vector expression. | |||
3690 | ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc, | |||
3691 | Expr *SrcExpr, TypeSourceInfo *DstTInfo, | |||
3692 | SourceLocation RParenLoc) { | |||
3693 | return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo, | |||
3694 | BuiltinLoc, RParenLoc); | |||
3695 | } | |||
3696 | ||||
3697 | /// Build a new template argument pack expansion. | |||
3698 | /// | |||
3699 | /// By default, performs semantic analysis to build a new pack expansion | |||
3700 | /// for a template argument. Subclasses may override this routine to provide | |||
3701 | /// different behavior. | |||
3702 | TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern, | |||
3703 | SourceLocation EllipsisLoc, | |||
3704 | Optional<unsigned> NumExpansions) { | |||
3705 | switch (Pattern.getArgument().getKind()) { | |||
3706 | case TemplateArgument::Expression: { | |||
3707 | ExprResult Result | |||
3708 | = getSema().CheckPackExpansion(Pattern.getSourceExpression(), | |||
3709 | EllipsisLoc, NumExpansions); | |||
3710 | if (Result.isInvalid()) | |||
3711 | return TemplateArgumentLoc(); | |||
3712 | ||||
3713 | return TemplateArgumentLoc(Result.get(), Result.get()); | |||
3714 | } | |||
3715 | ||||
3716 | case TemplateArgument::Template: | |||
3717 | return TemplateArgumentLoc( | |||
3718 | SemaRef.Context, | |||
3719 | TemplateArgument(Pattern.getArgument().getAsTemplate(), | |||
3720 | NumExpansions), | |||
3721 | Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(), | |||
3722 | EllipsisLoc); | |||
3723 | ||||
3724 | case TemplateArgument::Null: | |||
3725 | case TemplateArgument::Integral: | |||
3726 | case TemplateArgument::Declaration: | |||
3727 | case TemplateArgument::Pack: | |||
3728 | case TemplateArgument::TemplateExpansion: | |||
3729 | case TemplateArgument::NullPtr: | |||
3730 | llvm_unreachable("Pack expansion pattern has no parameter packs")::llvm::llvm_unreachable_internal("Pack expansion pattern has no parameter packs" , "clang/lib/Sema/TreeTransform.h", 3730); | |||
3731 | ||||
3732 | case TemplateArgument::Type: | |||
3733 | if (TypeSourceInfo *Expansion | |||
3734 | = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(), | |||
3735 | EllipsisLoc, | |||
3736 | NumExpansions)) | |||
3737 | return TemplateArgumentLoc(TemplateArgument(Expansion->getType()), | |||
3738 | Expansion); | |||
3739 | break; | |||
3740 | } | |||
3741 | ||||
3742 | return TemplateArgumentLoc(); | |||
3743 | } | |||
3744 | ||||
3745 | /// Build a new expression pack expansion. | |||
3746 | /// | |||
3747 | /// By default, performs semantic analysis to build a new pack expansion | |||
3748 | /// for an expression. Subclasses may override this routine to provide | |||
3749 | /// different behavior. | |||
3750 | ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, | |||
3751 | Optional<unsigned> NumExpansions) { | |||
3752 | return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions); | |||
3753 | } | |||
3754 | ||||
3755 | /// Build a new C++1z fold-expression. | |||
3756 | /// | |||
3757 | /// By default, performs semantic analysis in order to build a new fold | |||
3758 | /// expression. | |||
3759 | ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE, | |||
3760 | SourceLocation LParenLoc, Expr *LHS, | |||
3761 | BinaryOperatorKind Operator, | |||
3762 | SourceLocation EllipsisLoc, Expr *RHS, | |||
3763 | SourceLocation RParenLoc, | |||
3764 | Optional<unsigned> NumExpansions) { | |||
3765 | return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator, | |||
3766 | EllipsisLoc, RHS, RParenLoc, | |||
3767 | NumExpansions); | |||
3768 | } | |||
3769 | ||||
3770 | /// Build an empty C++1z fold-expression with the given operator. | |||
3771 | /// | |||
3772 | /// By default, produces the fallback value for the fold-expression, or | |||
3773 | /// produce an error if there is no fallback value. | |||
3774 | ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, | |||
3775 | BinaryOperatorKind Operator) { | |||
3776 | return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator); | |||
3777 | } | |||
3778 | ||||
3779 | /// Build a new atomic operation expression. | |||
3780 | /// | |||
3781 | /// By default, performs semantic analysis to build the new expression. | |||
3782 | /// Subclasses may override this routine to provide different behavior. | |||
3783 | ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs, | |||
3784 | AtomicExpr::AtomicOp Op, | |||
3785 | SourceLocation RParenLoc) { | |||
3786 | // Use this for all of the locations, since we don't know the difference | |||
3787 | // between the call and the expr at this point. | |||
3788 | SourceRange Range{BuiltinLoc, RParenLoc}; | |||
3789 | return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op, | |||
3790 | Sema::AtomicArgumentOrder::AST); | |||
3791 | } | |||
3792 | ||||
3793 | ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc, | |||
3794 | ArrayRef<Expr *> SubExprs, QualType Type) { | |||
3795 | return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type); | |||
3796 | } | |||
3797 | ||||
3798 | private: | |||
3799 | TypeLoc TransformTypeInObjectScope(TypeLoc TL, | |||
3800 | QualType ObjectType, | |||
3801 | NamedDecl *FirstQualifierInScope, | |||
3802 | CXXScopeSpec &SS); | |||
3803 | ||||
3804 | TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo, | |||
3805 | QualType ObjectType, | |||
3806 | NamedDecl *FirstQualifierInScope, | |||
3807 | CXXScopeSpec &SS); | |||
3808 | ||||
3809 | TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType, | |||
3810 | NamedDecl *FirstQualifierInScope, | |||
3811 | CXXScopeSpec &SS); | |||
3812 | ||||
3813 | QualType TransformDependentNameType(TypeLocBuilder &TLB, | |||
3814 | DependentNameTypeLoc TL, | |||
3815 | bool DeducibleTSTContext); | |||
3816 | }; | |||
3817 | ||||
3818 | template <typename Derived> | |||
3819 | StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) { | |||
3820 | if (!S) | |||
3821 | return S; | |||
3822 | ||||
3823 | switch (S->getStmtClass()) { | |||
3824 | case Stmt::NoStmtClass: break; | |||
3825 | ||||
3826 | // Transform individual statement nodes | |||
3827 | // Pass SDK into statements that can produce a value | |||
3828 | #define STMT(Node, Parent) \ | |||
3829 | case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S)); | |||
3830 | #define VALUESTMT(Node, Parent) \ | |||
3831 | case Stmt::Node##Class: \ | |||
3832 | return getDerived().Transform##Node(cast<Node>(S), SDK); | |||
3833 | #define ABSTRACT_STMT(Node) | |||
3834 | #define EXPR(Node, Parent) | |||
3835 | #include "clang/AST/StmtNodes.inc" | |||
3836 | ||||
3837 | // Transform expressions by calling TransformExpr. | |||
3838 | #define STMT(Node, Parent) | |||
3839 | #define ABSTRACT_STMT(Stmt) | |||
3840 | #define EXPR(Node, Parent) case Stmt::Node##Class: | |||
3841 | #include "clang/AST/StmtNodes.inc" | |||
3842 | { | |||
3843 | ExprResult E = getDerived().TransformExpr(cast<Expr>(S)); | |||
3844 | ||||
3845 | if (SDK == SDK_StmtExprResult) | |||
3846 | E = getSema().ActOnStmtExprResult(E); | |||
3847 | return getSema().ActOnExprStmt(E, SDK == SDK_Discarded); | |||
3848 | } | |||
3849 | } | |||
3850 | ||||
3851 | return S; | |||
3852 | } | |||
3853 | ||||
3854 | template<typename Derived> | |||
3855 | OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) { | |||
3856 | if (!S) | |||
3857 | return S; | |||
3858 | ||||
3859 | switch (S->getClauseKind()) { | |||
3860 | default: break; | |||
3861 | // Transform individual clause nodes | |||
3862 | #define GEN_CLANG_CLAUSE_CLASS | |||
3863 | #define CLAUSE_CLASS(Enum, Str, Class) \ | |||
3864 | case Enum: \ | |||
3865 | return getDerived().Transform##Class(cast<Class>(S)); | |||
3866 | #include "llvm/Frontend/OpenMP/OMP.inc" | |||
3867 | } | |||
3868 | ||||
3869 | return S; | |||
3870 | } | |||
3871 | ||||
3872 | ||||
3873 | template<typename Derived> | |||
3874 | ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) { | |||
3875 | if (!E) | |||
3876 | return E; | |||
3877 | ||||
3878 | switch (E->getStmtClass()) { | |||
3879 | case Stmt::NoStmtClass: break; | |||
3880 | #define STMT(Node, Parent) case Stmt::Node##Class: break; | |||
3881 | #define ABSTRACT_STMT(Stmt) | |||
3882 | #define EXPR(Node, Parent) \ | |||
3883 | case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E)); | |||
3884 | #include "clang/AST/StmtNodes.inc" | |||
3885 | } | |||
3886 | ||||
3887 | return E; | |||
3888 | } | |||
3889 | ||||
3890 | template<typename Derived> | |||
3891 | ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init, | |||
3892 | bool NotCopyInit) { | |||
3893 | // Initializers are instantiated like expressions, except that various outer | |||
3894 | // layers are stripped. | |||
3895 | if (!Init) | |||
3896 | return Init; | |||
3897 | ||||
3898 | if (auto *FE = dyn_cast<FullExpr>(Init)) | |||
3899 | Init = FE->getSubExpr(); | |||
3900 | ||||
3901 | if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) { | |||
3902 | OpaqueValueExpr *OVE = AIL->getCommonExpr(); | |||
3903 | Init = OVE->getSourceExpr(); | |||
3904 | } | |||
3905 | ||||
3906 | if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) | |||
3907 | Init = MTE->getSubExpr(); | |||
3908 | ||||
3909 | while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init)) | |||
3910 | Init = Binder->getSubExpr(); | |||
3911 | ||||
3912 | if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init)) | |||
3913 | Init = ICE->getSubExprAsWritten(); | |||
3914 | ||||
3915 | if (CXXStdInitializerListExpr *ILE = | |||
3916 | dyn_cast<CXXStdInitializerListExpr>(Init)) | |||
3917 | return TransformInitializer(ILE->getSubExpr(), NotCopyInit); | |||
3918 | ||||
3919 | // If this is copy-initialization, we only need to reconstruct | |||
3920 | // InitListExprs. Other forms of copy-initialization will be a no-op if | |||
3921 | // the initializer is already the right type. | |||
3922 | CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init); | |||
3923 | if (!NotCopyInit && !(Construct && Construct->isListInitialization())) | |||
3924 | return getDerived().TransformExpr(Init); | |||
3925 | ||||
3926 | // Revert value-initialization back to empty parens. | |||
3927 | if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) { | |||
3928 | SourceRange Parens = VIE->getSourceRange(); | |||
3929 | return getDerived().RebuildParenListExpr(Parens.getBegin(), None, | |||
3930 | Parens.getEnd()); | |||
3931 | } | |||
3932 | ||||
3933 | // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization. | |||
3934 | if (isa<ImplicitValueInitExpr>(Init)) | |||
3935 | return getDerived().RebuildParenListExpr(SourceLocation(), None, | |||
3936 | SourceLocation()); | |||
3937 | ||||
3938 | // Revert initialization by constructor back to a parenthesized or braced list | |||
3939 | // of expressions. Any other form of initializer can just be reused directly. | |||
3940 | if (!Construct || isa<CXXTemporaryObjectExpr>(Construct)) | |||
3941 | return getDerived().TransformExpr(Init); | |||
3942 | ||||
3943 | // If the initialization implicitly converted an initializer list to a | |||
3944 | // std::initializer_list object, unwrap the std::initializer_list too. | |||
3945 | if (Construct && Construct->isStdInitListInitialization()) | |||
3946 | return TransformInitializer(Construct->getArg(0), NotCopyInit); | |||
3947 | ||||
3948 | // Enter a list-init context if this was list initialization. | |||
3949 | EnterExpressionEvaluationContext Context( | |||
3950 | getSema(), EnterExpressionEvaluationContext::InitList, | |||
3951 | Construct->isListInitialization()); | |||
3952 | ||||
3953 | SmallVector<Expr*, 8> NewArgs; | |||
3954 | bool ArgChanged = false; | |||
3955 | if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(), | |||
3956 | /*IsCall*/true, NewArgs, &ArgChanged)) | |||
3957 | return ExprError(); | |||
3958 | ||||
3959 | // If this was list initialization, revert to syntactic list form. | |||
3960 | if (Construct->isListInitialization()) | |||
3961 | return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs, | |||
3962 | Construct->getEndLoc()); | |||
3963 | ||||
3964 | // Build a ParenListExpr to represent anything else. | |||
3965 | SourceRange Parens = Construct->getParenOrBraceRange(); | |||
3966 | if (Parens.isInvalid()) { | |||
3967 | // This was a variable declaration's initialization for which no initializer | |||
3968 | // was specified. | |||
3969 | assert(NewArgs.empty() &&(static_cast <bool> (NewArgs.empty() && "no parens or braces but have direct init with arguments?" ) ? void (0) : __assert_fail ("NewArgs.empty() && \"no parens or braces but have direct init with arguments?\"" , "clang/lib/Sema/TreeTransform.h", 3970, __extension__ __PRETTY_FUNCTION__ )) | |||
3970 | "no parens or braces but have direct init with arguments?")(static_cast <bool> (NewArgs.empty() && "no parens or braces but have direct init with arguments?" ) ? void (0) : __assert_fail ("NewArgs.empty() && \"no parens or braces but have direct init with arguments?\"" , "clang/lib/Sema/TreeTransform.h", 3970, __extension__ __PRETTY_FUNCTION__ )); | |||
3971 | return ExprEmpty(); | |||
3972 | } | |||
3973 | return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs, | |||
3974 | Parens.getEnd()); | |||
3975 | } | |||
3976 | ||||
3977 | template<typename Derived> | |||
3978 | bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs, | |||
3979 | unsigned NumInputs, | |||
3980 | bool IsCall, | |||
3981 | SmallVectorImpl<Expr *> &Outputs, | |||
3982 | bool *ArgChanged) { | |||
3983 | for (unsigned I = 0; I != NumInputs; ++I) { | |||
3984 | // If requested, drop call arguments that need to be dropped. | |||
3985 | if (IsCall && getDerived().DropCallArgument(Inputs[I])) { | |||
3986 | if (ArgChanged) | |||
3987 | *ArgChanged = true; | |||
3988 | ||||
3989 | break; | |||
3990 | } | |||
3991 | ||||
3992 | if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) { | |||
3993 | Expr *Pattern = Expansion->getPattern(); | |||
3994 | ||||
3995 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
3996 | getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); | |||
3997 | assert(!Unexpanded.empty() && "Pack expansion without parameter packs?")(static_cast <bool> (!Unexpanded.empty() && "Pack expansion without parameter packs?" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Pack expansion without parameter packs?\"" , "clang/lib/Sema/TreeTransform.h", 3997, __extension__ __PRETTY_FUNCTION__ )); | |||
3998 | ||||
3999 | // Determine whether the set of unexpanded parameter packs can and should | |||
4000 | // be expanded. | |||
4001 | bool Expand = true; | |||
4002 | bool RetainExpansion = false; | |||
4003 | Optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions(); | |||
4004 | Optional<unsigned> NumExpansions = OrigNumExpansions; | |||
4005 | if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(), | |||
4006 | Pattern->getSourceRange(), | |||
4007 | Unexpanded, | |||
4008 | Expand, RetainExpansion, | |||
4009 | NumExpansions)) | |||
4010 | return true; | |||
4011 | ||||
4012 | if (!Expand) { | |||
4013 | // The transform has determined that we should perform a simple | |||
4014 | // transformation on the pack expansion, producing another pack | |||
4015 | // expansion. | |||
4016 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
4017 | ExprResult OutPattern = getDerived().TransformExpr(Pattern); | |||
4018 | if (OutPattern.isInvalid()) | |||
4019 | return true; | |||
4020 | ||||
4021 | ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(), | |||
4022 | Expansion->getEllipsisLoc(), | |||
4023 | NumExpansions); | |||
4024 | if (Out.isInvalid()) | |||
4025 | return true; | |||
4026 | ||||
4027 | if (ArgChanged) | |||
4028 | *ArgChanged = true; | |||
4029 | Outputs.push_back(Out.get()); | |||
4030 | continue; | |||
4031 | } | |||
4032 | ||||
4033 | // Record right away that the argument was changed. This needs | |||
4034 | // to happen even if the array expands to nothing. | |||
4035 | if (ArgChanged) *ArgChanged = true; | |||
4036 | ||||
4037 | // The transform has determined that we should perform an elementwise | |||
4038 | // expansion of the pattern. Do so. | |||
4039 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
4040 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); | |||
4041 | ExprResult Out = getDerived().TransformExpr(Pattern); | |||
4042 | if (Out.isInvalid()) | |||
4043 | return true; | |||
4044 | ||||
4045 | if (Out.get()->containsUnexpandedParameterPack()) { | |||
4046 | Out = getDerived().RebuildPackExpansion( | |||
4047 | Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions); | |||
4048 | if (Out.isInvalid()) | |||
4049 | return true; | |||
4050 | } | |||
4051 | ||||
4052 | Outputs.push_back(Out.get()); | |||
4053 | } | |||
4054 | ||||
4055 | // If we're supposed to retain a pack expansion, do so by temporarily | |||
4056 | // forgetting the partially-substituted parameter pack. | |||
4057 | if (RetainExpansion) { | |||
4058 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
4059 | ||||
4060 | ExprResult Out = getDerived().TransformExpr(Pattern); | |||
4061 | if (Out.isInvalid()) | |||
4062 | return true; | |||
4063 | ||||
4064 | Out = getDerived().RebuildPackExpansion( | |||
4065 | Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions); | |||
4066 | if (Out.isInvalid()) | |||
4067 | return true; | |||
4068 | ||||
4069 | Outputs.push_back(Out.get()); | |||
4070 | } | |||
4071 | ||||
4072 | continue; | |||
4073 | } | |||
4074 | ||||
4075 | ExprResult Result = | |||
4076 | IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false) | |||
4077 | : getDerived().TransformExpr(Inputs[I]); | |||
4078 | if (Result.isInvalid()) | |||
4079 | return true; | |||
4080 | ||||
4081 | if (Result.get() != Inputs[I] && ArgChanged) | |||
4082 | *ArgChanged = true; | |||
4083 | ||||
4084 | Outputs.push_back(Result.get()); | |||
4085 | } | |||
4086 | ||||
4087 | return false; | |||
4088 | } | |||
4089 | ||||
4090 | template <typename Derived> | |||
4091 | Sema::ConditionResult TreeTransform<Derived>::TransformCondition( | |||
4092 | SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) { | |||
4093 | if (Var) { | |||
4094 | VarDecl *ConditionVar = cast_or_null<VarDecl>( | |||
4095 | getDerived().TransformDefinition(Var->getLocation(), Var)); | |||
4096 | ||||
4097 | if (!ConditionVar) | |||
4098 | return Sema::ConditionError(); | |||
4099 | ||||
4100 | return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind); | |||
4101 | } | |||
4102 | ||||
4103 | if (Expr) { | |||
4104 | ExprResult CondExpr = getDerived().TransformExpr(Expr); | |||
4105 | ||||
4106 | if (CondExpr.isInvalid()) | |||
4107 | return Sema::ConditionError(); | |||
4108 | ||||
4109 | return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind, | |||
4110 | /*MissingOK=*/true); | |||
4111 | } | |||
4112 | ||||
4113 | return Sema::ConditionResult(); | |||
4114 | } | |||
4115 | ||||
4116 | template <typename Derived> | |||
4117 | NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc( | |||
4118 | NestedNameSpecifierLoc NNS, QualType ObjectType, | |||
4119 | NamedDecl *FirstQualifierInScope) { | |||
4120 | SmallVector<NestedNameSpecifierLoc, 4> Qualifiers; | |||
4121 | for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier; | |||
4122 | Qualifier = Qualifier.getPrefix()) | |||
4123 | Qualifiers.push_back(Qualifier); | |||
4124 | ||||
4125 | CXXScopeSpec SS; | |||
4126 | while (!Qualifiers.empty()) { | |||
4127 | NestedNameSpecifierLoc Q = Qualifiers.pop_back_val(); | |||
4128 | NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier(); | |||
4129 | ||||
4130 | switch (QNNS->getKind()) { | |||
4131 | case NestedNameSpecifier::Identifier: { | |||
4132 | Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(), | |||
4133 | Q.getLocalBeginLoc(), Q.getLocalEndLoc(), | |||
4134 | ObjectType); | |||
4135 | if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false, | |||
4136 | SS, FirstQualifierInScope, false)) | |||
4137 | return NestedNameSpecifierLoc(); | |||
4138 | break; | |||
4139 | } | |||
4140 | ||||
4141 | case NestedNameSpecifier::Namespace: { | |||
4142 | NamespaceDecl *NS = | |||
4143 | cast_or_null<NamespaceDecl>(getDerived().TransformDecl( | |||
4144 | Q.getLocalBeginLoc(), QNNS->getAsNamespace())); | |||
4145 | SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc()); | |||
4146 | break; | |||
4147 | } | |||
4148 | ||||
4149 | case NestedNameSpecifier::NamespaceAlias: { | |||
4150 | NamespaceAliasDecl *Alias = | |||
4151 | cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl( | |||
4152 | Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias())); | |||
4153 | SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(), | |||
4154 | Q.getLocalEndLoc()); | |||
4155 | break; | |||
4156 | } | |||
4157 | ||||
4158 | case NestedNameSpecifier::Global: | |||
4159 | // There is no meaningful transformation that one could perform on the | |||
4160 | // global scope. | |||
4161 | SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc()); | |||
4162 | break; | |||
4163 | ||||
4164 | case NestedNameSpecifier::Super: { | |||
4165 | CXXRecordDecl *RD = | |||
4166 | cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( | |||
4167 | SourceLocation(), QNNS->getAsRecordDecl())); | |||
4168 | SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc()); | |||
4169 | break; | |||
4170 | } | |||
4171 | ||||
4172 | case NestedNameSpecifier::TypeSpecWithTemplate: | |||
4173 | case NestedNameSpecifier::TypeSpec: { | |||
4174 | TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType, | |||
4175 | FirstQualifierInScope, SS); | |||
4176 | ||||
4177 | if (!TL) | |||
4178 | return NestedNameSpecifierLoc(); | |||
4179 | ||||
4180 | if (TL.getType()->isDependentType() || TL.getType()->isRecordType() || | |||
4181 | (SemaRef.getLangOpts().CPlusPlus11 && | |||
4182 | TL.getType()->isEnumeralType())) { | |||
4183 | assert(!TL.getType().hasLocalQualifiers() &&(static_cast <bool> (!TL.getType().hasLocalQualifiers() && "Can't get cv-qualifiers here") ? void (0) : __assert_fail ("!TL.getType().hasLocalQualifiers() && \"Can't get cv-qualifiers here\"" , "clang/lib/Sema/TreeTransform.h", 4184, __extension__ __PRETTY_FUNCTION__ )) | |||
4184 | "Can't get cv-qualifiers here")(static_cast <bool> (!TL.getType().hasLocalQualifiers() && "Can't get cv-qualifiers here") ? void (0) : __assert_fail ("!TL.getType().hasLocalQualifiers() && \"Can't get cv-qualifiers here\"" , "clang/lib/Sema/TreeTransform.h", 4184, __extension__ __PRETTY_FUNCTION__ )); | |||
4185 | if (TL.getType()->isEnumeralType()) | |||
4186 | SemaRef.Diag(TL.getBeginLoc(), | |||
4187 | diag::warn_cxx98_compat_enum_nested_name_spec); | |||
4188 | SS.Extend(SemaRef.Context, /*FIXME:*/ SourceLocation(), TL, | |||
4189 | Q.getLocalEndLoc()); | |||
4190 | break; | |||
4191 | } | |||
4192 | // If the nested-name-specifier is an invalid type def, don't emit an | |||
4193 | // error because a previous error should have already been emitted. | |||
4194 | TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>(); | |||
4195 | if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) { | |||
4196 | SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) | |||
4197 | << TL.getType() << SS.getRange(); | |||
4198 | } | |||
4199 | return NestedNameSpecifierLoc(); | |||
4200 | } | |||
4201 | } | |||
4202 | ||||
4203 | // The qualifier-in-scope and object type only apply to the leftmost entity. | |||
4204 | FirstQualifierInScope = nullptr; | |||
4205 | ObjectType = QualType(); | |||
4206 | } | |||
4207 | ||||
4208 | // Don't rebuild the nested-name-specifier if we don't have to. | |||
4209 | if (SS.getScopeRep() == NNS.getNestedNameSpecifier() && | |||
4210 | !getDerived().AlwaysRebuild()) | |||
4211 | return NNS; | |||
4212 | ||||
4213 | // If we can re-use the source-location data from the original | |||
4214 | // nested-name-specifier, do so. | |||
4215 | if (SS.location_size() == NNS.getDataLength() && | |||
4216 | memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0) | |||
4217 | return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData()); | |||
4218 | ||||
4219 | // Allocate new nested-name-specifier location information. | |||
4220 | return SS.getWithLocInContext(SemaRef.Context); | |||
4221 | } | |||
4222 | ||||
4223 | template<typename Derived> | |||
4224 | DeclarationNameInfo | |||
4225 | TreeTransform<Derived> | |||
4226 | ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) { | |||
4227 | DeclarationName Name = NameInfo.getName(); | |||
4228 | if (!Name) | |||
4229 | return DeclarationNameInfo(); | |||
4230 | ||||
4231 | switch (Name.getNameKind()) { | |||
4232 | case DeclarationName::Identifier: | |||
4233 | case DeclarationName::ObjCZeroArgSelector: | |||
4234 | case DeclarationName::ObjCOneArgSelector: | |||
4235 | case DeclarationName::ObjCMultiArgSelector: | |||
4236 | case DeclarationName::CXXOperatorName: | |||
4237 | case DeclarationName::CXXLiteralOperatorName: | |||
4238 | case DeclarationName::CXXUsingDirective: | |||
4239 | return NameInfo; | |||
4240 | ||||
4241 | case DeclarationName::CXXDeductionGuideName: { | |||
4242 | TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate(); | |||
4243 | TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>( | |||
4244 | getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate)); | |||
4245 | if (!NewTemplate) | |||
4246 | return DeclarationNameInfo(); | |||
4247 | ||||
4248 | DeclarationNameInfo NewNameInfo(NameInfo); | |||
4249 | NewNameInfo.setName( | |||
4250 | SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate)); | |||
4251 | return NewNameInfo; | |||
4252 | } | |||
4253 | ||||
4254 | case DeclarationName::CXXConstructorName: | |||
4255 | case DeclarationName::CXXDestructorName: | |||
4256 | case DeclarationName::CXXConversionFunctionName: { | |||
4257 | TypeSourceInfo *NewTInfo; | |||
4258 | CanQualType NewCanTy; | |||
4259 | if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) { | |||
4260 | NewTInfo = getDerived().TransformType(OldTInfo); | |||
4261 | if (!NewTInfo) | |||
4262 | return DeclarationNameInfo(); | |||
4263 | NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType()); | |||
4264 | } | |||
4265 | else { | |||
4266 | NewTInfo = nullptr; | |||
4267 | TemporaryBase Rebase(*this, NameInfo.getLoc(), Name); | |||
4268 | QualType NewT = getDerived().TransformType(Name.getCXXNameType()); | |||
4269 | if (NewT.isNull()) | |||
4270 | return DeclarationNameInfo(); | |||
4271 | NewCanTy = SemaRef.Context.getCanonicalType(NewT); | |||
4272 | } | |||
4273 | ||||
4274 | DeclarationName NewName | |||
4275 | = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(), | |||
4276 | NewCanTy); | |||
4277 | DeclarationNameInfo NewNameInfo(NameInfo); | |||
4278 | NewNameInfo.setName(NewName); | |||
4279 | NewNameInfo.setNamedTypeInfo(NewTInfo); | |||
4280 | return NewNameInfo; | |||
4281 | } | |||
4282 | } | |||
4283 | ||||
4284 | llvm_unreachable("Unknown name kind.")::llvm::llvm_unreachable_internal("Unknown name kind.", "clang/lib/Sema/TreeTransform.h" , 4284); | |||
4285 | } | |||
4286 | ||||
4287 | template<typename Derived> | |||
4288 | TemplateName | |||
4289 | TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS, | |||
4290 | TemplateName Name, | |||
4291 | SourceLocation NameLoc, | |||
4292 | QualType ObjectType, | |||
4293 | NamedDecl *FirstQualifierInScope, | |||
4294 | bool AllowInjectedClassName) { | |||
4295 | if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) { | |||
4296 | TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl(); | |||
4297 | assert(Template && "qualified template name must refer to a template")(static_cast <bool> (Template && "qualified template name must refer to a template" ) ? void (0) : __assert_fail ("Template && \"qualified template name must refer to a template\"" , "clang/lib/Sema/TreeTransform.h", 4297, __extension__ __PRETTY_FUNCTION__ )); | |||
4298 | ||||
4299 | TemplateDecl *TransTemplate | |||
4300 | = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, | |||
4301 | Template)); | |||
4302 | if (!TransTemplate) | |||
4303 | return TemplateName(); | |||
4304 | ||||
4305 | if (!getDerived().AlwaysRebuild() && | |||
4306 | SS.getScopeRep() == QTN->getQualifier() && | |||
4307 | TransTemplate == Template) | |||
4308 | return Name; | |||
4309 | ||||
4310 | return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(), | |||
4311 | TransTemplate); | |||
4312 | } | |||
4313 | ||||
4314 | if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) { | |||
4315 | if (SS.getScopeRep()) { | |||
4316 | // These apply to the scope specifier, not the template. | |||
4317 | ObjectType = QualType(); | |||
4318 | FirstQualifierInScope = nullptr; | |||
4319 | } | |||
4320 | ||||
4321 | if (!getDerived().AlwaysRebuild() && | |||
4322 | SS.getScopeRep() == DTN->getQualifier() && | |||
4323 | ObjectType.isNull()) | |||
4324 | return Name; | |||
4325 | ||||
4326 | // FIXME: Preserve the location of the "template" keyword. | |||
4327 | SourceLocation TemplateKWLoc = NameLoc; | |||
4328 | ||||
4329 | if (DTN->isIdentifier()) { | |||
4330 | return getDerived().RebuildTemplateName(SS, | |||
4331 | TemplateKWLoc, | |||
4332 | *DTN->getIdentifier(), | |||
4333 | NameLoc, | |||
4334 | ObjectType, | |||
4335 | FirstQualifierInScope, | |||
4336 | AllowInjectedClassName); | |||
4337 | } | |||
4338 | ||||
4339 | return getDerived().RebuildTemplateName(SS, TemplateKWLoc, | |||
4340 | DTN->getOperator(), NameLoc, | |||
4341 | ObjectType, AllowInjectedClassName); | |||
4342 | } | |||
4343 | ||||
4344 | if (TemplateDecl *Template = Name.getAsTemplateDecl()) { | |||
4345 | TemplateDecl *TransTemplate | |||
4346 | = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, | |||
4347 | Template)); | |||
4348 | if (!TransTemplate) | |||
4349 | return TemplateName(); | |||
4350 | ||||
4351 | if (!getDerived().AlwaysRebuild() && | |||
4352 | TransTemplate == Template) | |||
4353 | return Name; | |||
4354 | ||||
4355 | return TemplateName(TransTemplate); | |||
4356 | } | |||
4357 | ||||
4358 | if (SubstTemplateTemplateParmPackStorage *SubstPack | |||
4359 | = Name.getAsSubstTemplateTemplateParmPack()) { | |||
4360 | TemplateTemplateParmDecl *TransParam | |||
4361 | = cast_or_null<TemplateTemplateParmDecl>( | |||
4362 | getDerived().TransformDecl(NameLoc, SubstPack->getParameterPack())); | |||
4363 | if (!TransParam) | |||
4364 | return TemplateName(); | |||
4365 | ||||
4366 | if (!getDerived().AlwaysRebuild() && | |||
4367 | TransParam == SubstPack->getParameterPack()) | |||
4368 | return Name; | |||
4369 | ||||
4370 | return getDerived().RebuildTemplateName(TransParam, | |||
4371 | SubstPack->getArgumentPack()); | |||
4372 | } | |||
4373 | ||||
4374 | // These should be getting filtered out before they reach the AST. | |||
4375 | llvm_unreachable("overloaded function decl survived to here")::llvm::llvm_unreachable_internal("overloaded function decl survived to here" , "clang/lib/Sema/TreeTransform.h", 4375); | |||
4376 | } | |||
4377 | ||||
4378 | template<typename Derived> | |||
4379 | void TreeTransform<Derived>::InventTemplateArgumentLoc( | |||
4380 | const TemplateArgument &Arg, | |||
4381 | TemplateArgumentLoc &Output) { | |||
4382 | Output = getSema().getTrivialTemplateArgumentLoc( | |||
4383 | Arg, QualType(), getDerived().getBaseLocation()); | |||
4384 | } | |||
4385 | ||||
4386 | template <typename Derived> | |||
4387 | bool TreeTransform<Derived>::TransformTemplateArgument( | |||
4388 | const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output, | |||
4389 | bool Uneval) { | |||
4390 | const TemplateArgument &Arg = Input.getArgument(); | |||
4391 | switch (Arg.getKind()) { | |||
4392 | case TemplateArgument::Null: | |||
4393 | case TemplateArgument::Pack: | |||
4394 | llvm_unreachable("Unexpected TemplateArgument")::llvm::llvm_unreachable_internal("Unexpected TemplateArgument" , "clang/lib/Sema/TreeTransform.h", 4394); | |||
4395 | ||||
4396 | case TemplateArgument::Integral: | |||
4397 | case TemplateArgument::NullPtr: | |||
4398 | case TemplateArgument::Declaration: { | |||
4399 | // Transform a resolved template argument straight to a resolved template | |||
4400 | // argument. We get here when substituting into an already-substituted | |||
4401 | // template type argument during concept satisfaction checking. | |||
4402 | QualType T = Arg.getNonTypeTemplateArgumentType(); | |||
4403 | QualType NewT = getDerived().TransformType(T); | |||
4404 | if (NewT.isNull()) | |||
4405 | return true; | |||
4406 | ||||
4407 | ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration | |||
4408 | ? Arg.getAsDecl() | |||
4409 | : nullptr; | |||
4410 | ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl( | |||
4411 | getDerived().getBaseLocation(), D)) | |||
4412 | : nullptr; | |||
4413 | if (D && !NewD) | |||
4414 | return true; | |||
4415 | ||||
4416 | if (NewT == T && D == NewD) | |||
4417 | Output = Input; | |||
4418 | else if (Arg.getKind() == TemplateArgument::Integral) | |||
4419 | Output = TemplateArgumentLoc( | |||
4420 | TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT), | |||
4421 | TemplateArgumentLocInfo()); | |||
4422 | else if (Arg.getKind() == TemplateArgument::NullPtr) | |||
4423 | Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true), | |||
4424 | TemplateArgumentLocInfo()); | |||
4425 | else | |||
4426 | Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT), | |||
4427 | TemplateArgumentLocInfo()); | |||
4428 | ||||
4429 | return false; | |||
4430 | } | |||
4431 | ||||
4432 | case TemplateArgument::Type: { | |||
4433 | TypeSourceInfo *DI = Input.getTypeSourceInfo(); | |||
4434 | if (!DI) | |||
4435 | DI = InventTypeSourceInfo(Input.getArgument().getAsType()); | |||
4436 | ||||
4437 | DI = getDerived().TransformType(DI); | |||
4438 | if (!DI) | |||
4439 | return true; | |||
4440 | ||||
4441 | Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI); | |||
4442 | return false; | |||
4443 | } | |||
4444 | ||||
4445 | case TemplateArgument::Template: { | |||
4446 | NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc(); | |||
4447 | if (QualifierLoc) { | |||
4448 | QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); | |||
4449 | if (!QualifierLoc) | |||
4450 | return true; | |||
4451 | } | |||
4452 | ||||
4453 | CXXScopeSpec SS; | |||
4454 | SS.Adopt(QualifierLoc); | |||
4455 | TemplateName Template = getDerived().TransformTemplateName( | |||
4456 | SS, Arg.getAsTemplate(), Input.getTemplateNameLoc()); | |||
4457 | if (Template.isNull()) | |||
4458 | return true; | |||
4459 | ||||
4460 | Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template), | |||
4461 | QualifierLoc, Input.getTemplateNameLoc()); | |||
4462 | return false; | |||
4463 | } | |||
4464 | ||||
4465 | case TemplateArgument::TemplateExpansion: | |||
4466 | llvm_unreachable("Caller should expand pack expansions")::llvm::llvm_unreachable_internal("Caller should expand pack expansions" , "clang/lib/Sema/TreeTransform.h", 4466); | |||
4467 | ||||
4468 | case TemplateArgument::Expression: { | |||
4469 | // Template argument expressions are constant expressions. | |||
4470 | EnterExpressionEvaluationContext Unevaluated( | |||
4471 | getSema(), | |||
4472 | Uneval ? Sema::ExpressionEvaluationContext::Unevaluated | |||
4473 | : Sema::ExpressionEvaluationContext::ConstantEvaluated, | |||
4474 | /*LambdaContextDecl=*/nullptr, /*ExprContext=*/ | |||
4475 | Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument); | |||
4476 | ||||
4477 | Expr *InputExpr = Input.getSourceExpression(); | |||
4478 | if (!InputExpr) | |||
4479 | InputExpr = Input.getArgument().getAsExpr(); | |||
4480 | ||||
4481 | ExprResult E = getDerived().TransformExpr(InputExpr); | |||
4482 | E = SemaRef.ActOnConstantExpression(E); | |||
4483 | if (E.isInvalid()) | |||
4484 | return true; | |||
4485 | Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get()); | |||
4486 | return false; | |||
4487 | } | |||
4488 | } | |||
4489 | ||||
4490 | // Work around bogus GCC warning | |||
4491 | return true; | |||
4492 | } | |||
4493 | ||||
4494 | /// Iterator adaptor that invents template argument location information | |||
4495 | /// for each of the template arguments in its underlying iterator. | |||
4496 | template<typename Derived, typename InputIterator> | |||
4497 | class TemplateArgumentLocInventIterator { | |||
4498 | TreeTransform<Derived> &Self; | |||
4499 | InputIterator Iter; | |||
4500 | ||||
4501 | public: | |||
4502 | typedef TemplateArgumentLoc value_type; | |||
4503 | typedef TemplateArgumentLoc reference; | |||
4504 | typedef typename std::iterator_traits<InputIterator>::difference_type | |||
4505 | difference_type; | |||
4506 | typedef std::input_iterator_tag iterator_category; | |||
4507 | ||||
4508 | class pointer { | |||
4509 | TemplateArgumentLoc Arg; | |||
4510 | ||||
4511 | public: | |||
4512 | explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { } | |||
4513 | ||||
4514 | const TemplateArgumentLoc *operator->() const { return &Arg; } | |||
4515 | }; | |||
4516 | ||||
4517 | TemplateArgumentLocInventIterator() { } | |||
4518 | ||||
4519 | explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self, | |||
4520 | InputIterator Iter) | |||
4521 | : Self(Self), Iter(Iter) { } | |||
4522 | ||||
4523 | TemplateArgumentLocInventIterator &operator++() { | |||
4524 | ++Iter; | |||
4525 | return *this; | |||
4526 | } | |||
4527 | ||||
4528 | TemplateArgumentLocInventIterator operator++(int) { | |||
4529 | TemplateArgumentLocInventIterator Old(*this); | |||
4530 | ++(*this); | |||
4531 | return Old; | |||
4532 | } | |||
4533 | ||||
4534 | reference operator*() const { | |||
4535 | TemplateArgumentLoc Result; | |||
4536 | Self.InventTemplateArgumentLoc(*Iter, Result); | |||
4537 | return Result; | |||
4538 | } | |||
4539 | ||||
4540 | pointer operator->() const { return pointer(**this); } | |||
4541 | ||||
4542 | friend bool operator==(const TemplateArgumentLocInventIterator &X, | |||
4543 | const TemplateArgumentLocInventIterator &Y) { | |||
4544 | return X.Iter == Y.Iter; | |||
4545 | } | |||
4546 | ||||
4547 | friend bool operator!=(const TemplateArgumentLocInventIterator &X, | |||
4548 | const TemplateArgumentLocInventIterator &Y) { | |||
4549 | return X.Iter != Y.Iter; | |||
4550 | } | |||
4551 | }; | |||
4552 | ||||
4553 | template<typename Derived> | |||
4554 | template<typename InputIterator> | |||
4555 | bool TreeTransform<Derived>::TransformTemplateArguments( | |||
4556 | InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs, | |||
4557 | bool Uneval) { | |||
4558 | for (; First != Last; ++First) { | |||
4559 | TemplateArgumentLoc Out; | |||
4560 | TemplateArgumentLoc In = *First; | |||
4561 | ||||
4562 | if (In.getArgument().getKind() == TemplateArgument::Pack) { | |||
4563 | // Unpack argument packs, which we translate them into separate | |||
4564 | // arguments. | |||
4565 | // FIXME: We could do much better if we could guarantee that the | |||
4566 | // TemplateArgumentLocInfo for the pack expansion would be usable for | |||
4567 | // all of the template arguments in the argument pack. | |||
4568 | typedef TemplateArgumentLocInventIterator<Derived, | |||
4569 | TemplateArgument::pack_iterator> | |||
4570 | PackLocIterator; | |||
4571 | if (TransformTemplateArguments(PackLocIterator(*this, | |||
4572 | In.getArgument().pack_begin()), | |||
4573 | PackLocIterator(*this, | |||
4574 | In.getArgument().pack_end()), | |||
4575 | Outputs, Uneval)) | |||
4576 | return true; | |||
4577 | ||||
4578 | continue; | |||
4579 | } | |||
4580 | ||||
4581 | if (In.getArgument().isPackExpansion()) { | |||
4582 | // We have a pack expansion, for which we will be substituting into | |||
4583 | // the pattern. | |||
4584 | SourceLocation Ellipsis; | |||
4585 | Optional<unsigned> OrigNumExpansions; | |||
4586 | TemplateArgumentLoc Pattern | |||
4587 | = getSema().getTemplateArgumentPackExpansionPattern( | |||
4588 | In, Ellipsis, OrigNumExpansions); | |||
4589 | ||||
4590 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
4591 | getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); | |||
4592 | assert(!Unexpanded.empty() && "Pack expansion without parameter packs?")(static_cast <bool> (!Unexpanded.empty() && "Pack expansion without parameter packs?" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Pack expansion without parameter packs?\"" , "clang/lib/Sema/TreeTransform.h", 4592, __extension__ __PRETTY_FUNCTION__ )); | |||
4593 | ||||
4594 | // Determine whether the set of unexpanded parameter packs can and should | |||
4595 | // be expanded. | |||
4596 | bool Expand = true; | |||
4597 | bool RetainExpansion = false; | |||
4598 | Optional<unsigned> NumExpansions = OrigNumExpansions; | |||
4599 | if (getDerived().TryExpandParameterPacks(Ellipsis, | |||
4600 | Pattern.getSourceRange(), | |||
4601 | Unexpanded, | |||
4602 | Expand, | |||
4603 | RetainExpansion, | |||
4604 | NumExpansions)) | |||
4605 | return true; | |||
4606 | ||||
4607 | if (!Expand) { | |||
4608 | // The transform has determined that we should perform a simple | |||
4609 | // transformation on the pack expansion, producing another pack | |||
4610 | // expansion. | |||
4611 | TemplateArgumentLoc OutPattern; | |||
4612 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
4613 | if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval)) | |||
4614 | return true; | |||
4615 | ||||
4616 | Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis, | |||
4617 | NumExpansions); | |||
4618 | if (Out.getArgument().isNull()) | |||
4619 | return true; | |||
4620 | ||||
4621 | Outputs.addArgument(Out); | |||
4622 | continue; | |||
4623 | } | |||
4624 | ||||
4625 | // The transform has determined that we should perform an elementwise | |||
4626 | // expansion of the pattern. Do so. | |||
4627 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
4628 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); | |||
4629 | ||||
4630 | if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval)) | |||
4631 | return true; | |||
4632 | ||||
4633 | if (Out.getArgument().containsUnexpandedParameterPack()) { | |||
4634 | Out = getDerived().RebuildPackExpansion(Out, Ellipsis, | |||
4635 | OrigNumExpansions); | |||
4636 | if (Out.getArgument().isNull()) | |||
4637 | return true; | |||
4638 | } | |||
4639 | ||||
4640 | Outputs.addArgument(Out); | |||
4641 | } | |||
4642 | ||||
4643 | // If we're supposed to retain a pack expansion, do so by temporarily | |||
4644 | // forgetting the partially-substituted parameter pack. | |||
4645 | if (RetainExpansion) { | |||
4646 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
4647 | ||||
4648 | if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval)) | |||
4649 | return true; | |||
4650 | ||||
4651 | Out = getDerived().RebuildPackExpansion(Out, Ellipsis, | |||
4652 | OrigNumExpansions); | |||
4653 | if (Out.getArgument().isNull()) | |||
4654 | return true; | |||
4655 | ||||
4656 | Outputs.addArgument(Out); | |||
4657 | } | |||
4658 | ||||
4659 | continue; | |||
4660 | } | |||
4661 | ||||
4662 | // The simple case: | |||
4663 | if (getDerived().TransformTemplateArgument(In, Out, Uneval)) | |||
4664 | return true; | |||
4665 | ||||
4666 | Outputs.addArgument(Out); | |||
4667 | } | |||
4668 | ||||
4669 | return false; | |||
4670 | ||||
4671 | } | |||
4672 | ||||
4673 | //===----------------------------------------------------------------------===// | |||
4674 | // Type transformation | |||
4675 | //===----------------------------------------------------------------------===// | |||
4676 | ||||
4677 | template<typename Derived> | |||
4678 | QualType TreeTransform<Derived>::TransformType(QualType T) { | |||
4679 | if (getDerived().AlreadyTransformed(T)) | |||
4680 | return T; | |||
4681 | ||||
4682 | // Temporary workaround. All of these transformations should | |||
4683 | // eventually turn into transformations on TypeLocs. | |||
4684 | TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T, | |||
4685 | getDerived().getBaseLocation()); | |||
4686 | ||||
4687 | TypeSourceInfo *NewDI = getDerived().TransformType(DI); | |||
4688 | ||||
4689 | if (!NewDI) | |||
4690 | return QualType(); | |||
4691 | ||||
4692 | return NewDI->getType(); | |||
4693 | } | |||
4694 | ||||
4695 | template<typename Derived> | |||
4696 | TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) { | |||
4697 | // Refine the base location to the type's location. | |||
4698 | TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(), | |||
4699 | getDerived().getBaseEntity()); | |||
4700 | if (getDerived().AlreadyTransformed(DI->getType())) | |||
4701 | return DI; | |||
4702 | ||||
4703 | TypeLocBuilder TLB; | |||
4704 | ||||
4705 | TypeLoc TL = DI->getTypeLoc(); | |||
4706 | TLB.reserve(TL.getFullDataSize()); | |||
4707 | ||||
4708 | QualType Result = getDerived().TransformType(TLB, TL); | |||
4709 | if (Result.isNull()) | |||
4710 | return nullptr; | |||
4711 | ||||
4712 | return TLB.getTypeSourceInfo(SemaRef.Context, Result); | |||
4713 | } | |||
4714 | ||||
4715 | template<typename Derived> | |||
4716 | QualType | |||
4717 | TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) { | |||
4718 | switch (T.getTypeLocClass()) { | |||
4719 | #define ABSTRACT_TYPELOC(CLASS, PARENT) | |||
4720 | #define TYPELOC(CLASS, PARENT) \ | |||
4721 | case TypeLoc::CLASS: \ | |||
4722 | return getDerived().Transform##CLASS##Type(TLB, \ | |||
4723 | T.castAs<CLASS##TypeLoc>()); | |||
4724 | #include "clang/AST/TypeLocNodes.def" | |||
4725 | } | |||
4726 | ||||
4727 | llvm_unreachable("unhandled type loc!")::llvm::llvm_unreachable_internal("unhandled type loc!", "clang/lib/Sema/TreeTransform.h" , 4727); | |||
4728 | } | |||
4729 | ||||
4730 | template<typename Derived> | |||
4731 | QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) { | |||
4732 | if (!isa<DependentNameType>(T)) | |||
4733 | return TransformType(T); | |||
4734 | ||||
4735 | if (getDerived().AlreadyTransformed(T)) | |||
4736 | return T; | |||
4737 | TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T, | |||
4738 | getDerived().getBaseLocation()); | |||
4739 | TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI); | |||
4740 | return NewDI ? NewDI->getType() : QualType(); | |||
4741 | } | |||
4742 | ||||
4743 | template<typename Derived> | |||
4744 | TypeSourceInfo * | |||
4745 | TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) { | |||
4746 | if (!isa<DependentNameType>(DI->getType())) | |||
4747 | return TransformType(DI); | |||
4748 | ||||
4749 | // Refine the base location to the type's location. | |||
4750 | TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(), | |||
4751 | getDerived().getBaseEntity()); | |||
4752 | if (getDerived().AlreadyTransformed(DI->getType())) | |||
4753 | return DI; | |||
4754 | ||||
4755 | TypeLocBuilder TLB; | |||
4756 | ||||
4757 | TypeLoc TL = DI->getTypeLoc(); | |||
4758 | TLB.reserve(TL.getFullDataSize()); | |||
4759 | ||||
4760 | auto QTL = TL.getAs<QualifiedTypeLoc>(); | |||
4761 | if (QTL) | |||
4762 | TL = QTL.getUnqualifiedLoc(); | |||
4763 | ||||
4764 | auto DNTL = TL.castAs<DependentNameTypeLoc>(); | |||
4765 | ||||
4766 | QualType Result = getDerived().TransformDependentNameType( | |||
4767 | TLB, DNTL, /*DeducedTSTContext*/true); | |||
4768 | if (Result.isNull()) | |||
4769 | return nullptr; | |||
4770 | ||||
4771 | if (QTL) { | |||
4772 | Result = getDerived().RebuildQualifiedType(Result, QTL); | |||
4773 | if (Result.isNull()) | |||
4774 | return nullptr; | |||
4775 | TLB.TypeWasModifiedSafely(Result); | |||
4776 | } | |||
4777 | ||||
4778 | return TLB.getTypeSourceInfo(SemaRef.Context, Result); | |||
4779 | } | |||
4780 | ||||
4781 | template<typename Derived> | |||
4782 | QualType | |||
4783 | TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, | |||
4784 | QualifiedTypeLoc T) { | |||
4785 | QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc()); | |||
4786 | if (Result.isNull()) | |||
4787 | return QualType(); | |||
4788 | ||||
4789 | Result = getDerived().RebuildQualifiedType(Result, T); | |||
4790 | ||||
4791 | if (Result.isNull()) | |||
4792 | return QualType(); | |||
4793 | ||||
4794 | // RebuildQualifiedType might have updated the type, but not in a way | |||
4795 | // that invalidates the TypeLoc. (There's no location information for | |||
4796 | // qualifiers.) | |||
4797 | TLB.TypeWasModifiedSafely(Result); | |||
4798 | ||||
4799 | return Result; | |||
4800 | } | |||
4801 | ||||
4802 | template <typename Derived> | |||
4803 | QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T, | |||
4804 | QualifiedTypeLoc TL) { | |||
4805 | ||||
4806 | SourceLocation Loc = TL.getBeginLoc(); | |||
4807 | Qualifiers Quals = TL.getType().getLocalQualifiers(); | |||
4808 | ||||
4809 | if ((T.getAddressSpace() != LangAS::Default && | |||
4810 | Quals.getAddressSpace() != LangAS::Default) && | |||
4811 | T.getAddressSpace() != Quals.getAddressSpace()) { | |||
4812 | SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst) | |||
4813 | << TL.getType() << T; | |||
4814 | return QualType(); | |||
4815 | } | |||
4816 | ||||
4817 | // C++ [dcl.fct]p7: | |||
4818 | // [When] adding cv-qualifications on top of the function type [...] the | |||
4819 | // cv-qualifiers are ignored. | |||
4820 | if (T->isFunctionType()) { | |||
4821 | T = SemaRef.getASTContext().getAddrSpaceQualType(T, | |||
4822 | Quals.getAddressSpace()); | |||
4823 | return T; | |||
4824 | } | |||
4825 | ||||
4826 | // C++ [dcl.ref]p1: | |||
4827 | // when the cv-qualifiers are introduced through the use of a typedef-name | |||
4828 | // or decltype-specifier [...] the cv-qualifiers are ignored. | |||
4829 | // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be | |||
4830 | // applied to a reference type. | |||
4831 | if (T->isReferenceType()) { | |||
4832 | // The only qualifier that applies to a reference type is restrict. | |||
4833 | if (!Quals.hasRestrict()) | |||
4834 | return T; | |||
4835 | Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict); | |||
4836 | } | |||
4837 | ||||
4838 | // Suppress Objective-C lifetime qualifiers if they don't make sense for the | |||
4839 | // resulting type. | |||
4840 | if (Quals.hasObjCLifetime()) { | |||
4841 | if (!T->isObjCLifetimeType() && !T->isDependentType()) | |||
4842 | Quals.removeObjCLifetime(); | |||
4843 | else if (T.getObjCLifetime()) { | |||
4844 | // Objective-C ARC: | |||
4845 | // A lifetime qualifier applied to a substituted template parameter | |||
4846 | // overrides the lifetime qualifier from the template argument. | |||
4847 | const AutoType *AutoTy; | |||
4848 | if (const SubstTemplateTypeParmType *SubstTypeParam | |||
4849 | = dyn_cast<SubstTemplateTypeParmType>(T)) { | |||
4850 | QualType Replacement = SubstTypeParam->getReplacementType(); | |||
4851 | Qualifiers Qs = Replacement.getQualifiers(); | |||
4852 | Qs.removeObjCLifetime(); | |||
4853 | Replacement = SemaRef.Context.getQualifiedType( | |||
4854 | Replacement.getUnqualifiedType(), Qs); | |||
4855 | T = SemaRef.Context.getSubstTemplateTypeParmType( | |||
4856 | SubstTypeParam->getReplacedParameter(), Replacement, | |||
4857 | SubstTypeParam->getPackIndex()); | |||
4858 | } else if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) { | |||
4859 | // 'auto' types behave the same way as template parameters. | |||
4860 | QualType Deduced = AutoTy->getDeducedType(); | |||
4861 | Qualifiers Qs = Deduced.getQualifiers(); | |||
4862 | Qs.removeObjCLifetime(); | |||
4863 | Deduced = | |||
4864 | SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs); | |||
4865 | T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(), | |||
4866 | AutoTy->isDependentType(), | |||
4867 | /*isPack=*/false, | |||
4868 | AutoTy->getTypeConstraintConcept(), | |||
4869 | AutoTy->getTypeConstraintArguments()); | |||
4870 | } else { | |||
4871 | // Otherwise, complain about the addition of a qualifier to an | |||
4872 | // already-qualified type. | |||
4873 | // FIXME: Why is this check not in Sema::BuildQualifiedType? | |||
4874 | SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T; | |||
4875 | Quals.removeObjCLifetime(); | |||
4876 | } | |||
4877 | } | |||
4878 | } | |||
4879 | ||||
4880 | return SemaRef.BuildQualifiedType(T, Loc, Quals); | |||
4881 | } | |||
4882 | ||||
4883 | template<typename Derived> | |||
4884 | TypeLoc | |||
4885 | TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL, | |||
4886 | QualType ObjectType, | |||
4887 | NamedDecl *UnqualLookup, | |||
4888 | CXXScopeSpec &SS) { | |||
4889 | if (getDerived().AlreadyTransformed(TL.getType())) | |||
4890 | return TL; | |||
4891 | ||||
4892 | TypeSourceInfo *TSI = | |||
4893 | TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS); | |||
4894 | if (TSI) | |||
4895 | return TSI->getTypeLoc(); | |||
4896 | return TypeLoc(); | |||
4897 | } | |||
4898 | ||||
4899 | template<typename Derived> | |||
4900 | TypeSourceInfo * | |||
4901 | TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo, | |||
4902 | QualType ObjectType, | |||
4903 | NamedDecl *UnqualLookup, | |||
4904 | CXXScopeSpec &SS) { | |||
4905 | if (getDerived().AlreadyTransformed(TSInfo->getType())) | |||
4906 | return TSInfo; | |||
4907 | ||||
4908 | return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType, | |||
4909 | UnqualLookup, SS); | |||
4910 | } | |||
4911 | ||||
4912 | template <typename Derived> | |||
4913 | TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope( | |||
4914 | TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup, | |||
4915 | CXXScopeSpec &SS) { | |||
4916 | QualType T = TL.getType(); | |||
4917 | assert(!getDerived().AlreadyTransformed(T))(static_cast <bool> (!getDerived().AlreadyTransformed(T )) ? void (0) : __assert_fail ("!getDerived().AlreadyTransformed(T)" , "clang/lib/Sema/TreeTransform.h", 4917, __extension__ __PRETTY_FUNCTION__ )); | |||
4918 | ||||
4919 | TypeLocBuilder TLB; | |||
4920 | QualType Result; | |||
4921 | ||||
4922 | if (isa<TemplateSpecializationType>(T)) { | |||
4923 | TemplateSpecializationTypeLoc SpecTL = | |||
4924 | TL.castAs<TemplateSpecializationTypeLoc>(); | |||
4925 | ||||
4926 | TemplateName Template = getDerived().TransformTemplateName( | |||
4927 | SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(), | |||
4928 | ObjectType, UnqualLookup, /*AllowInjectedClassName*/true); | |||
4929 | if (Template.isNull()) | |||
4930 | return nullptr; | |||
4931 | ||||
4932 | Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, | |||
4933 | Template); | |||
4934 | } else if (isa<DependentTemplateSpecializationType>(T)) { | |||
4935 | DependentTemplateSpecializationTypeLoc SpecTL = | |||
4936 | TL.castAs<DependentTemplateSpecializationTypeLoc>(); | |||
4937 | ||||
4938 | TemplateName Template | |||
4939 | = getDerived().RebuildTemplateName(SS, | |||
4940 | SpecTL.getTemplateKeywordLoc(), | |||
4941 | *SpecTL.getTypePtr()->getIdentifier(), | |||
4942 | SpecTL.getTemplateNameLoc(), | |||
4943 | ObjectType, UnqualLookup, | |||
4944 | /*AllowInjectedClassName*/true); | |||
4945 | if (Template.isNull()) | |||
4946 | return nullptr; | |||
4947 | ||||
4948 | Result = getDerived().TransformDependentTemplateSpecializationType(TLB, | |||
4949 | SpecTL, | |||
4950 | Template, | |||
4951 | SS); | |||
4952 | } else { | |||
4953 | // Nothing special needs to be done for these. | |||
4954 | Result = getDerived().TransformType(TLB, TL); | |||
4955 | } | |||
4956 | ||||
4957 | if (Result.isNull()) | |||
4958 | return nullptr; | |||
4959 | ||||
4960 | return TLB.getTypeSourceInfo(SemaRef.Context, Result); | |||
4961 | } | |||
4962 | ||||
4963 | template <class TyLoc> static inline | |||
4964 | QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) { | |||
4965 | TyLoc NewT = TLB.push<TyLoc>(T.getType()); | |||
4966 | NewT.setNameLoc(T.getNameLoc()); | |||
4967 | return T.getType(); | |||
4968 | } | |||
4969 | ||||
4970 | template<typename Derived> | |||
4971 | QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB, | |||
4972 | BuiltinTypeLoc T) { | |||
4973 | BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType()); | |||
4974 | NewT.setBuiltinLoc(T.getBuiltinLoc()); | |||
4975 | if (T.needsExtraLocalData()) | |||
4976 | NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs(); | |||
4977 | return T.getType(); | |||
4978 | } | |||
4979 | ||||
4980 | template<typename Derived> | |||
4981 | QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB, | |||
4982 | ComplexTypeLoc T) { | |||
4983 | // FIXME: recurse? | |||
4984 | return TransformTypeSpecType(TLB, T); | |||
4985 | } | |||
4986 | ||||
4987 | template <typename Derived> | |||
4988 | QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB, | |||
4989 | AdjustedTypeLoc TL) { | |||
4990 | // Adjustments applied during transformation are handled elsewhere. | |||
4991 | return getDerived().TransformType(TLB, TL.getOriginalLoc()); | |||
4992 | } | |||
4993 | ||||
4994 | template<typename Derived> | |||
4995 | QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB, | |||
4996 | DecayedTypeLoc TL) { | |||
4997 | QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc()); | |||
4998 | if (OriginalType.isNull()) | |||
4999 | return QualType(); | |||
5000 | ||||
5001 | QualType Result = TL.getType(); | |||
5002 | if (getDerived().AlwaysRebuild() || | |||
5003 | OriginalType != TL.getOriginalLoc().getType()) | |||
5004 | Result = SemaRef.Context.getDecayedType(OriginalType); | |||
5005 | TLB.push<DecayedTypeLoc>(Result); | |||
5006 | // Nothing to set for DecayedTypeLoc. | |||
5007 | return Result; | |||
5008 | } | |||
5009 | ||||
5010 | template<typename Derived> | |||
5011 | QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB, | |||
5012 | PointerTypeLoc TL) { | |||
5013 | QualType PointeeType | |||
5014 | = getDerived().TransformType(TLB, TL.getPointeeLoc()); | |||
5015 | if (PointeeType.isNull()) | |||
5016 | return QualType(); | |||
5017 | ||||
5018 | QualType Result = TL.getType(); | |||
5019 | if (PointeeType->getAs<ObjCObjectType>()) { | |||
5020 | // A dependent pointer type 'T *' has is being transformed such | |||
5021 | // that an Objective-C class type is being replaced for 'T'. The | |||
5022 | // resulting pointer type is an ObjCObjectPointerType, not a | |||
5023 | // PointerType. | |||
5024 | Result = SemaRef.Context.getObjCObjectPointerType(PointeeType); | |||
5025 | ||||
5026 | ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result); | |||
5027 | NewT.setStarLoc(TL.getStarLoc()); | |||
5028 | return Result; | |||
5029 | } | |||
5030 | ||||
5031 | if (getDerived().AlwaysRebuild() || | |||
5032 | PointeeType != TL.getPointeeLoc().getType()) { | |||
5033 | Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc()); | |||
5034 | if (Result.isNull()) | |||
5035 | return QualType(); | |||
5036 | } | |||
5037 | ||||
5038 | // Objective-C ARC can add lifetime qualifiers to the type that we're | |||
5039 | // pointing to. | |||
5040 | TLB.TypeWasModifiedSafely(Result->getPointeeType()); | |||
5041 | ||||
5042 | PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result); | |||
5043 | NewT.setSigilLoc(TL.getSigilLoc()); | |||
5044 | return Result; | |||
5045 | } | |||
5046 | ||||
5047 | template<typename Derived> | |||
5048 | QualType | |||
5049 | TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB, | |||
5050 | BlockPointerTypeLoc TL) { | |||
5051 | QualType PointeeType | |||
5052 | = getDerived().TransformType(TLB, TL.getPointeeLoc()); | |||
5053 | if (PointeeType.isNull()) | |||
5054 | return QualType(); | |||
5055 | ||||
5056 | QualType Result = TL.getType(); | |||
5057 | if (getDerived().AlwaysRebuild() || | |||
5058 | PointeeType != TL.getPointeeLoc().getType()) { | |||
5059 | Result = getDerived().RebuildBlockPointerType(PointeeType, | |||
5060 | TL.getSigilLoc()); | |||
5061 | if (Result.isNull()) | |||
5062 | return QualType(); | |||
5063 | } | |||
5064 | ||||
5065 | BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result); | |||
5066 | NewT.setSigilLoc(TL.getSigilLoc()); | |||
5067 | return Result; | |||
5068 | } | |||
5069 | ||||
5070 | /// Transforms a reference type. Note that somewhat paradoxically we | |||
5071 | /// don't care whether the type itself is an l-value type or an r-value | |||
5072 | /// type; we only care if the type was *written* as an l-value type | |||
5073 | /// or an r-value type. | |||
5074 | template<typename Derived> | |||
5075 | QualType | |||
5076 | TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB, | |||
5077 | ReferenceTypeLoc TL) { | |||
5078 | const ReferenceType *T = TL.getTypePtr(); | |||
5079 | ||||
5080 | // Note that this works with the pointee-as-written. | |||
5081 | QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); | |||
5082 | if (PointeeType.isNull()) | |||
5083 | return QualType(); | |||
5084 | ||||
5085 | QualType Result = TL.getType(); | |||
5086 | if (getDerived().AlwaysRebuild() || | |||
5087 | PointeeType != T->getPointeeTypeAsWritten()) { | |||
5088 | Result = getDerived().RebuildReferenceType(PointeeType, | |||
5089 | T->isSpelledAsLValue(), | |||
5090 | TL.getSigilLoc()); | |||
5091 | if (Result.isNull()) | |||
5092 | return QualType(); | |||
5093 | } | |||
5094 | ||||
5095 | // Objective-C ARC can add lifetime qualifiers to the type that we're | |||
5096 | // referring to. | |||
5097 | TLB.TypeWasModifiedSafely( | |||
5098 | Result->castAs<ReferenceType>()->getPointeeTypeAsWritten()); | |||
5099 | ||||
5100 | // r-value references can be rebuilt as l-value references. | |||
5101 | ReferenceTypeLoc NewTL; | |||
5102 | if (isa<LValueReferenceType>(Result)) | |||
5103 | NewTL = TLB.push<LValueReferenceTypeLoc>(Result); | |||
5104 | else | |||
5105 | NewTL = TLB.push<RValueReferenceTypeLoc>(Result); | |||
5106 | NewTL.setSigilLoc(TL.getSigilLoc()); | |||
5107 | ||||
5108 | return Result; | |||
5109 | } | |||
5110 | ||||
5111 | template<typename Derived> | |||
5112 | QualType | |||
5113 | TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB, | |||
5114 | LValueReferenceTypeLoc TL) { | |||
5115 | return TransformReferenceType(TLB, TL); | |||
5116 | } | |||
5117 | ||||
5118 | template<typename Derived> | |||
5119 | QualType | |||
5120 | TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB, | |||
5121 | RValueReferenceTypeLoc TL) { | |||
5122 | return TransformReferenceType(TLB, TL); | |||
5123 | } | |||
5124 | ||||
5125 | template<typename Derived> | |||
5126 | QualType | |||
5127 | TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB, | |||
5128 | MemberPointerTypeLoc TL) { | |||
5129 | QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); | |||
5130 | if (PointeeType.isNull()) | |||
5131 | return QualType(); | |||
5132 | ||||
5133 | TypeSourceInfo* OldClsTInfo = TL.getClassTInfo(); | |||
5134 | TypeSourceInfo *NewClsTInfo = nullptr; | |||
5135 | if (OldClsTInfo) { | |||
5136 | NewClsTInfo = getDerived().TransformType(OldClsTInfo); | |||
5137 | if (!NewClsTInfo) | |||
5138 | return QualType(); | |||
5139 | } | |||
5140 | ||||
5141 | const MemberPointerType *T = TL.getTypePtr(); | |||
5142 | QualType OldClsType = QualType(T->getClass(), 0); | |||
5143 | QualType NewClsType; | |||
5144 | if (NewClsTInfo) | |||
5145 | NewClsType = NewClsTInfo->getType(); | |||
5146 | else { | |||
5147 | NewClsType = getDerived().TransformType(OldClsType); | |||
5148 | if (NewClsType.isNull()) | |||
5149 | return QualType(); | |||
5150 | } | |||
5151 | ||||
5152 | QualType Result = TL.getType(); | |||
5153 | if (getDerived().AlwaysRebuild() || | |||
5154 | PointeeType != T->getPointeeType() || | |||
5155 | NewClsType != OldClsType) { | |||
5156 | Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType, | |||
5157 | TL.getStarLoc()); | |||
5158 | if (Result.isNull()) | |||
5159 | return QualType(); | |||
5160 | } | |||
5161 | ||||
5162 | // If we had to adjust the pointee type when building a member pointer, make | |||
5163 | // sure to push TypeLoc info for it. | |||
5164 | const MemberPointerType *MPT = Result->getAs<MemberPointerType>(); | |||
5165 | if (MPT && PointeeType != MPT->getPointeeType()) { | |||
5166 | assert(isa<AdjustedType>(MPT->getPointeeType()))(static_cast <bool> (isa<AdjustedType>(MPT->getPointeeType ())) ? void (0) : __assert_fail ("isa<AdjustedType>(MPT->getPointeeType())" , "clang/lib/Sema/TreeTransform.h", 5166, __extension__ __PRETTY_FUNCTION__ )); | |||
5167 | TLB.push<AdjustedTypeLoc>(MPT->getPointeeType()); | |||
5168 | } | |||
5169 | ||||
5170 | MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result); | |||
5171 | NewTL.setSigilLoc(TL.getSigilLoc()); | |||
5172 | NewTL.setClassTInfo(NewClsTInfo); | |||
5173 | ||||
5174 | return Result; | |||
5175 | } | |||
5176 | ||||
5177 | template<typename Derived> | |||
5178 | QualType | |||
5179 | TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB, | |||
5180 | ConstantArrayTypeLoc TL) { | |||
5181 | const ConstantArrayType *T = TL.getTypePtr(); | |||
5182 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5183 | if (ElementType.isNull()) | |||
5184 | return QualType(); | |||
5185 | ||||
5186 | // Prefer the expression from the TypeLoc; the other may have been uniqued. | |||
5187 | Expr *OldSize = TL.getSizeExpr(); | |||
5188 | if (!OldSize) | |||
5189 | OldSize = const_cast<Expr*>(T->getSizeExpr()); | |||
5190 | Expr *NewSize = nullptr; | |||
5191 | if (OldSize) { | |||
5192 | EnterExpressionEvaluationContext Unevaluated( | |||
5193 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
5194 | NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>(); | |||
5195 | NewSize = SemaRef.ActOnConstantExpression(NewSize).get(); | |||
5196 | } | |||
5197 | ||||
5198 | QualType Result = TL.getType(); | |||
5199 | if (getDerived().AlwaysRebuild() || | |||
5200 | ElementType != T->getElementType() || | |||
5201 | (T->getSizeExpr() && NewSize != OldSize)) { | |||
5202 | Result = getDerived().RebuildConstantArrayType(ElementType, | |||
5203 | T->getSizeModifier(), | |||
5204 | T->getSize(), NewSize, | |||
5205 | T->getIndexTypeCVRQualifiers(), | |||
5206 | TL.getBracketsRange()); | |||
5207 | if (Result.isNull()) | |||
5208 | return QualType(); | |||
5209 | } | |||
5210 | ||||
5211 | // We might have either a ConstantArrayType or a VariableArrayType now: | |||
5212 | // a ConstantArrayType is allowed to have an element type which is a | |||
5213 | // VariableArrayType if the type is dependent. Fortunately, all array | |||
5214 | // types have the same location layout. | |||
5215 | ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); | |||
5216 | NewTL.setLBracketLoc(TL.getLBracketLoc()); | |||
5217 | NewTL.setRBracketLoc(TL.getRBracketLoc()); | |||
5218 | NewTL.setSizeExpr(NewSize); | |||
5219 | ||||
5220 | return Result; | |||
5221 | } | |||
5222 | ||||
5223 | template<typename Derived> | |||
5224 | QualType TreeTransform<Derived>::TransformIncompleteArrayType( | |||
5225 | TypeLocBuilder &TLB, | |||
5226 | IncompleteArrayTypeLoc TL) { | |||
5227 | const IncompleteArrayType *T = TL.getTypePtr(); | |||
5228 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5229 | if (ElementType.isNull()) | |||
5230 | return QualType(); | |||
5231 | ||||
5232 | QualType Result = TL.getType(); | |||
5233 | if (getDerived().AlwaysRebuild() || | |||
5234 | ElementType != T->getElementType()) { | |||
5235 | Result = getDerived().RebuildIncompleteArrayType(ElementType, | |||
5236 | T->getSizeModifier(), | |||
5237 | T->getIndexTypeCVRQualifiers(), | |||
5238 | TL.getBracketsRange()); | |||
5239 | if (Result.isNull()) | |||
5240 | return QualType(); | |||
5241 | } | |||
5242 | ||||
5243 | IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result); | |||
5244 | NewTL.setLBracketLoc(TL.getLBracketLoc()); | |||
5245 | NewTL.setRBracketLoc(TL.getRBracketLoc()); | |||
5246 | NewTL.setSizeExpr(nullptr); | |||
5247 | ||||
5248 | return Result; | |||
5249 | } | |||
5250 | ||||
5251 | template<typename Derived> | |||
5252 | QualType | |||
5253 | TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB, | |||
5254 | VariableArrayTypeLoc TL) { | |||
5255 | const VariableArrayType *T = TL.getTypePtr(); | |||
5256 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5257 | if (ElementType.isNull()) | |||
5258 | return QualType(); | |||
5259 | ||||
5260 | ExprResult SizeResult; | |||
5261 | { | |||
5262 | EnterExpressionEvaluationContext Context( | |||
5263 | SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); | |||
5264 | SizeResult = getDerived().TransformExpr(T->getSizeExpr()); | |||
5265 | } | |||
5266 | if (SizeResult.isInvalid()) | |||
5267 | return QualType(); | |||
5268 | SizeResult = | |||
5269 | SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false); | |||
5270 | if (SizeResult.isInvalid()) | |||
5271 | return QualType(); | |||
5272 | ||||
5273 | Expr *Size = SizeResult.get(); | |||
5274 | ||||
5275 | QualType Result = TL.getType(); | |||
5276 | if (getDerived().AlwaysRebuild() || | |||
5277 | ElementType != T->getElementType() || | |||
5278 | Size != T->getSizeExpr()) { | |||
5279 | Result = getDerived().RebuildVariableArrayType(ElementType, | |||
5280 | T->getSizeModifier(), | |||
5281 | Size, | |||
5282 | T->getIndexTypeCVRQualifiers(), | |||
5283 | TL.getBracketsRange()); | |||
5284 | if (Result.isNull()) | |||
5285 | return QualType(); | |||
5286 | } | |||
5287 | ||||
5288 | // We might have constant size array now, but fortunately it has the same | |||
5289 | // location layout. | |||
5290 | ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); | |||
5291 | NewTL.setLBracketLoc(TL.getLBracketLoc()); | |||
5292 | NewTL.setRBracketLoc(TL.getRBracketLoc()); | |||
5293 | NewTL.setSizeExpr(Size); | |||
5294 | ||||
5295 | return Result; | |||
5296 | } | |||
5297 | ||||
5298 | template<typename Derived> | |||
5299 | QualType | |||
5300 | TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, | |||
5301 | DependentSizedArrayTypeLoc TL) { | |||
5302 | const DependentSizedArrayType *T = TL.getTypePtr(); | |||
5303 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5304 | if (ElementType.isNull()) | |||
5305 | return QualType(); | |||
5306 | ||||
5307 | // Array bounds are constant expressions. | |||
5308 | EnterExpressionEvaluationContext Unevaluated( | |||
5309 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
5310 | ||||
5311 | // Prefer the expression from the TypeLoc; the other may have been uniqued. | |||
5312 | Expr *origSize = TL.getSizeExpr(); | |||
5313 | if (!origSize) origSize = T->getSizeExpr(); | |||
5314 | ||||
5315 | ExprResult sizeResult | |||
5316 | = getDerived().TransformExpr(origSize); | |||
5317 | sizeResult = SemaRef.ActOnConstantExpression(sizeResult); | |||
5318 | if (sizeResult.isInvalid()) | |||
5319 | return QualType(); | |||
5320 | ||||
5321 | Expr *size = sizeResult.get(); | |||
5322 | ||||
5323 | QualType Result = TL.getType(); | |||
5324 | if (getDerived().AlwaysRebuild() || | |||
5325 | ElementType != T->getElementType() || | |||
5326 | size != origSize) { | |||
5327 | Result = getDerived().RebuildDependentSizedArrayType(ElementType, | |||
5328 | T->getSizeModifier(), | |||
5329 | size, | |||
5330 | T->getIndexTypeCVRQualifiers(), | |||
5331 | TL.getBracketsRange()); | |||
5332 | if (Result.isNull()) | |||
5333 | return QualType(); | |||
5334 | } | |||
5335 | ||||
5336 | // We might have any sort of array type now, but fortunately they | |||
5337 | // all have the same location layout. | |||
5338 | ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); | |||
5339 | NewTL.setLBracketLoc(TL.getLBracketLoc()); | |||
5340 | NewTL.setRBracketLoc(TL.getRBracketLoc()); | |||
5341 | NewTL.setSizeExpr(size); | |||
5342 | ||||
5343 | return Result; | |||
5344 | } | |||
5345 | ||||
5346 | template <typename Derived> | |||
5347 | QualType TreeTransform<Derived>::TransformDependentVectorType( | |||
5348 | TypeLocBuilder &TLB, DependentVectorTypeLoc TL) { | |||
5349 | const DependentVectorType *T = TL.getTypePtr(); | |||
5350 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5351 | if (ElementType.isNull()) | |||
5352 | return QualType(); | |||
5353 | ||||
5354 | EnterExpressionEvaluationContext Unevaluated( | |||
5355 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
5356 | ||||
5357 | ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); | |||
5358 | Size = SemaRef.ActOnConstantExpression(Size); | |||
5359 | if (Size.isInvalid()) | |||
5360 | return QualType(); | |||
5361 | ||||
5362 | QualType Result = TL.getType(); | |||
5363 | if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() || | |||
5364 | Size.get() != T->getSizeExpr()) { | |||
5365 | Result = getDerived().RebuildDependentVectorType( | |||
5366 | ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind()); | |||
5367 | if (Result.isNull()) | |||
5368 | return QualType(); | |||
5369 | } | |||
5370 | ||||
5371 | // Result might be dependent or not. | |||
5372 | if (isa<DependentVectorType>(Result)) { | |||
5373 | DependentVectorTypeLoc NewTL = | |||
5374 | TLB.push<DependentVectorTypeLoc>(Result); | |||
5375 | NewTL.setNameLoc(TL.getNameLoc()); | |||
5376 | } else { | |||
5377 | VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result); | |||
5378 | NewTL.setNameLoc(TL.getNameLoc()); | |||
5379 | } | |||
5380 | ||||
5381 | return Result; | |||
5382 | } | |||
5383 | ||||
5384 | template<typename Derived> | |||
5385 | QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType( | |||
5386 | TypeLocBuilder &TLB, | |||
5387 | DependentSizedExtVectorTypeLoc TL) { | |||
5388 | const DependentSizedExtVectorType *T = TL.getTypePtr(); | |||
5389 | ||||
5390 | // FIXME: ext vector locs should be nested | |||
5391 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5392 | if (ElementType.isNull()) | |||
5393 | return QualType(); | |||
5394 | ||||
5395 | // Vector sizes are constant expressions. | |||
5396 | EnterExpressionEvaluationContext Unevaluated( | |||
5397 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
5398 | ||||
5399 | ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); | |||
5400 | Size = SemaRef.ActOnConstantExpression(Size); | |||
5401 | if (Size.isInvalid()) | |||
5402 | return QualType(); | |||
5403 | ||||
5404 | QualType Result = TL.getType(); | |||
5405 | if (getDerived().AlwaysRebuild() || | |||
5406 | ElementType != T->getElementType() || | |||
5407 | Size.get() != T->getSizeExpr()) { | |||
5408 | Result = getDerived().RebuildDependentSizedExtVectorType(ElementType, | |||
5409 | Size.get(), | |||
5410 | T->getAttributeLoc()); | |||
5411 | if (Result.isNull()) | |||
5412 | return QualType(); | |||
5413 | } | |||
5414 | ||||
5415 | // Result might be dependent or not. | |||
5416 | if (isa<DependentSizedExtVectorType>(Result)) { | |||
5417 | DependentSizedExtVectorTypeLoc NewTL | |||
5418 | = TLB.push<DependentSizedExtVectorTypeLoc>(Result); | |||
5419 | NewTL.setNameLoc(TL.getNameLoc()); | |||
5420 | } else { | |||
5421 | ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result); | |||
5422 | NewTL.setNameLoc(TL.getNameLoc()); | |||
5423 | } | |||
5424 | ||||
5425 | return Result; | |||
5426 | } | |||
5427 | ||||
5428 | template <typename Derived> | |||
5429 | QualType | |||
5430 | TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB, | |||
5431 | ConstantMatrixTypeLoc TL) { | |||
5432 | const ConstantMatrixType *T = TL.getTypePtr(); | |||
5433 | QualType ElementType = getDerived().TransformType(T->getElementType()); | |||
5434 | if (ElementType.isNull()) | |||
5435 | return QualType(); | |||
5436 | ||||
5437 | QualType Result = TL.getType(); | |||
5438 | if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) { | |||
5439 | Result = getDerived().RebuildConstantMatrixType( | |||
5440 | ElementType, T->getNumRows(), T->getNumColumns()); | |||
5441 | if (Result.isNull()) | |||
5442 | return QualType(); | |||
5443 | } | |||
5444 | ||||
5445 | ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result); | |||
5446 | NewTL.setAttrNameLoc(TL.getAttrNameLoc()); | |||
5447 | NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange()); | |||
5448 | NewTL.setAttrRowOperand(TL.getAttrRowOperand()); | |||
5449 | NewTL.setAttrColumnOperand(TL.getAttrColumnOperand()); | |||
5450 | ||||
5451 | return Result; | |||
5452 | } | |||
5453 | ||||
5454 | template <typename Derived> | |||
5455 | QualType TreeTransform<Derived>::TransformDependentSizedMatrixType( | |||
5456 | TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) { | |||
5457 | const DependentSizedMatrixType *T = TL.getTypePtr(); | |||
5458 | ||||
5459 | QualType ElementType = getDerived().TransformType(T->getElementType()); | |||
5460 | if (ElementType.isNull()) { | |||
5461 | return QualType(); | |||
5462 | } | |||
5463 | ||||
5464 | // Matrix dimensions are constant expressions. | |||
5465 | EnterExpressionEvaluationContext Unevaluated( | |||
5466 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
5467 | ||||
5468 | Expr *origRows = TL.getAttrRowOperand(); | |||
5469 | if (!origRows) | |||
5470 | origRows = T->getRowExpr(); | |||
5471 | Expr *origColumns = TL.getAttrColumnOperand(); | |||
5472 | if (!origColumns) | |||
5473 | origColumns = T->getColumnExpr(); | |||
5474 | ||||
5475 | ExprResult rowResult = getDerived().TransformExpr(origRows); | |||
5476 | rowResult = SemaRef.ActOnConstantExpression(rowResult); | |||
5477 | if (rowResult.isInvalid()) | |||
5478 | return QualType(); | |||
5479 | ||||
5480 | ExprResult columnResult = getDerived().TransformExpr(origColumns); | |||
5481 | columnResult = SemaRef.ActOnConstantExpression(columnResult); | |||
5482 | if (columnResult.isInvalid()) | |||
5483 | return QualType(); | |||
5484 | ||||
5485 | Expr *rows = rowResult.get(); | |||
5486 | Expr *columns = columnResult.get(); | |||
5487 | ||||
5488 | QualType Result = TL.getType(); | |||
5489 | if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() || | |||
5490 | rows != origRows || columns != origColumns) { | |||
5491 | Result = getDerived().RebuildDependentSizedMatrixType( | |||
5492 | ElementType, rows, columns, T->getAttributeLoc()); | |||
5493 | ||||
5494 | if (Result.isNull()) | |||
5495 | return QualType(); | |||
5496 | } | |||
5497 | ||||
5498 | // We might have any sort of matrix type now, but fortunately they | |||
5499 | // all have the same location layout. | |||
5500 | MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result); | |||
5501 | NewTL.setAttrNameLoc(TL.getAttrNameLoc()); | |||
5502 | NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange()); | |||
5503 | NewTL.setAttrRowOperand(rows); | |||
5504 | NewTL.setAttrColumnOperand(columns); | |||
5505 | return Result; | |||
5506 | } | |||
5507 | ||||
5508 | template <typename Derived> | |||
5509 | QualType TreeTransform<Derived>::TransformDependentAddressSpaceType( | |||
5510 | TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) { | |||
5511 | const DependentAddressSpaceType *T = TL.getTypePtr(); | |||
5512 | ||||
5513 | QualType pointeeType = getDerived().TransformType(T->getPointeeType()); | |||
5514 | ||||
5515 | if (pointeeType.isNull()) | |||
5516 | return QualType(); | |||
5517 | ||||
5518 | // Address spaces are constant expressions. | |||
5519 | EnterExpressionEvaluationContext Unevaluated( | |||
5520 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
5521 | ||||
5522 | ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr()); | |||
5523 | AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace); | |||
5524 | if (AddrSpace.isInvalid()) | |||
5525 | return QualType(); | |||
5526 | ||||
5527 | QualType Result = TL.getType(); | |||
5528 | if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() || | |||
5529 | AddrSpace.get() != T->getAddrSpaceExpr()) { | |||
5530 | Result = getDerived().RebuildDependentAddressSpaceType( | |||
5531 | pointeeType, AddrSpace.get(), T->getAttributeLoc()); | |||
5532 | if (Result.isNull()) | |||
5533 | return QualType(); | |||
5534 | } | |||
5535 | ||||
5536 | // Result might be dependent or not. | |||
5537 | if (isa<DependentAddressSpaceType>(Result)) { | |||
5538 | DependentAddressSpaceTypeLoc NewTL = | |||
5539 | TLB.push<DependentAddressSpaceTypeLoc>(Result); | |||
5540 | ||||
5541 | NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange()); | |||
5542 | NewTL.setAttrExprOperand(TL.getAttrExprOperand()); | |||
5543 | NewTL.setAttrNameLoc(TL.getAttrNameLoc()); | |||
5544 | ||||
5545 | } else { | |||
5546 | TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo( | |||
5547 | Result, getDerived().getBaseLocation()); | |||
5548 | TransformType(TLB, DI->getTypeLoc()); | |||
5549 | } | |||
5550 | ||||
5551 | return Result; | |||
5552 | } | |||
5553 | ||||
5554 | template <typename Derived> | |||
5555 | QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB, | |||
5556 | VectorTypeLoc TL) { | |||
5557 | const VectorType *T = TL.getTypePtr(); | |||
5558 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5559 | if (ElementType.isNull()) | |||
5560 | return QualType(); | |||
5561 | ||||
5562 | QualType Result = TL.getType(); | |||
5563 | if (getDerived().AlwaysRebuild() || | |||
5564 | ElementType != T->getElementType()) { | |||
5565 | Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(), | |||
5566 | T->getVectorKind()); | |||
5567 | if (Result.isNull()) | |||
5568 | return QualType(); | |||
5569 | } | |||
5570 | ||||
5571 | VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result); | |||
5572 | NewTL.setNameLoc(TL.getNameLoc()); | |||
5573 | ||||
5574 | return Result; | |||
5575 | } | |||
5576 | ||||
5577 | template<typename Derived> | |||
5578 | QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB, | |||
5579 | ExtVectorTypeLoc TL) { | |||
5580 | const VectorType *T = TL.getTypePtr(); | |||
5581 | QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); | |||
5582 | if (ElementType.isNull()) | |||
5583 | return QualType(); | |||
5584 | ||||
5585 | QualType Result = TL.getType(); | |||
5586 | if (getDerived().AlwaysRebuild() || | |||
5587 | ElementType != T->getElementType()) { | |||
5588 | Result = getDerived().RebuildExtVectorType(ElementType, | |||
5589 | T->getNumElements(), | |||
5590 | /*FIXME*/ SourceLocation()); | |||
5591 | if (Result.isNull()) | |||
5592 | return QualType(); | |||
5593 | } | |||
5594 | ||||
5595 | ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result); | |||
5596 | NewTL.setNameLoc(TL.getNameLoc()); | |||
5597 | ||||
5598 | return Result; | |||
5599 | } | |||
5600 | ||||
5601 | template <typename Derived> | |||
5602 | ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam( | |||
5603 | ParmVarDecl *OldParm, int indexAdjustment, Optional<unsigned> NumExpansions, | |||
5604 | bool ExpectParameterPack) { | |||
5605 | TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo(); | |||
5606 | TypeSourceInfo *NewDI = nullptr; | |||
5607 | ||||
5608 | if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) { | |||
5609 | // If we're substituting into a pack expansion type and we know the | |||
5610 | // length we want to expand to, just substitute for the pattern. | |||
5611 | TypeLoc OldTL = OldDI->getTypeLoc(); | |||
5612 | PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>(); | |||
5613 | ||||
5614 | TypeLocBuilder TLB; | |||
5615 | TypeLoc NewTL = OldDI->getTypeLoc(); | |||
5616 | TLB.reserve(NewTL.getFullDataSize()); | |||
5617 | ||||
5618 | QualType Result = getDerived().TransformType(TLB, | |||
5619 | OldExpansionTL.getPatternLoc()); | |||
5620 | if (Result.isNull()) | |||
5621 | return nullptr; | |||
5622 | ||||
5623 | Result = RebuildPackExpansionType(Result, | |||
5624 | OldExpansionTL.getPatternLoc().getSourceRange(), | |||
5625 | OldExpansionTL.getEllipsisLoc(), | |||
5626 | NumExpansions); | |||
5627 | if (Result.isNull()) | |||
5628 | return nullptr; | |||
5629 | ||||
5630 | PackExpansionTypeLoc NewExpansionTL | |||
5631 | = TLB.push<PackExpansionTypeLoc>(Result); | |||
5632 | NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc()); | |||
5633 | NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result); | |||
5634 | } else | |||
5635 | NewDI = getDerived().TransformType(OldDI); | |||
5636 | if (!NewDI) | |||
5637 | return nullptr; | |||
5638 | ||||
5639 | if (NewDI == OldDI && indexAdjustment == 0) | |||
5640 | return OldParm; | |||
5641 | ||||
5642 | ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context, | |||
5643 | OldParm->getDeclContext(), | |||
5644 | OldParm->getInnerLocStart(), | |||
5645 | OldParm->getLocation(), | |||
5646 | OldParm->getIdentifier(), | |||
5647 | NewDI->getType(), | |||
5648 | NewDI, | |||
5649 | OldParm->getStorageClass(), | |||
5650 | /* DefArg */ nullptr); | |||
5651 | newParm->setScopeInfo(OldParm->getFunctionScopeDepth(), | |||
5652 | OldParm->getFunctionScopeIndex() + indexAdjustment); | |||
5653 | transformedLocalDecl(OldParm, {newParm}); | |||
5654 | return newParm; | |||
5655 | } | |||
5656 | ||||
5657 | template <typename Derived> | |||
5658 | bool TreeTransform<Derived>::TransformFunctionTypeParams( | |||
5659 | SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, | |||
5660 | const QualType *ParamTypes, | |||
5661 | const FunctionProtoType::ExtParameterInfo *ParamInfos, | |||
5662 | SmallVectorImpl<QualType> &OutParamTypes, | |||
5663 | SmallVectorImpl<ParmVarDecl *> *PVars, | |||
5664 | Sema::ExtParameterInfoBuilder &PInfos) { | |||
5665 | int indexAdjustment = 0; | |||
5666 | ||||
5667 | unsigned NumParams = Params.size(); | |||
5668 | for (unsigned i = 0; i != NumParams; ++i) { | |||
5669 | if (ParmVarDecl *OldParm = Params[i]) { | |||
5670 | assert(OldParm->getFunctionScopeIndex() == i)(static_cast <bool> (OldParm->getFunctionScopeIndex( ) == i) ? void (0) : __assert_fail ("OldParm->getFunctionScopeIndex() == i" , "clang/lib/Sema/TreeTransform.h", 5670, __extension__ __PRETTY_FUNCTION__ )); | |||
5671 | ||||
5672 | Optional<unsigned> NumExpansions; | |||
5673 | ParmVarDecl *NewParm = nullptr; | |||
5674 | if (OldParm->isParameterPack()) { | |||
5675 | // We have a function parameter pack that may need to be expanded. | |||
5676 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
5677 | ||||
5678 | // Find the parameter packs that could be expanded. | |||
5679 | TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc(); | |||
5680 | PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>(); | |||
5681 | TypeLoc Pattern = ExpansionTL.getPatternLoc(); | |||
5682 | SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); | |||
5683 | ||||
5684 | // Determine whether we should expand the parameter packs. | |||
5685 | bool ShouldExpand = false; | |||
5686 | bool RetainExpansion = false; | |||
5687 | Optional<unsigned> OrigNumExpansions; | |||
5688 | if (Unexpanded.size() > 0) { | |||
5689 | OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions(); | |||
5690 | NumExpansions = OrigNumExpansions; | |||
5691 | if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), | |||
5692 | Pattern.getSourceRange(), | |||
5693 | Unexpanded, | |||
5694 | ShouldExpand, | |||
5695 | RetainExpansion, | |||
5696 | NumExpansions)) { | |||
5697 | return true; | |||
5698 | } | |||
5699 | } else { | |||
5700 | #ifndef NDEBUG | |||
5701 | const AutoType *AT = | |||
5702 | Pattern.getType().getTypePtr()->getContainedAutoType(); | |||
5703 | assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&(static_cast <bool> ((AT && (!AT->isDeduced( ) || AT->getDeducedType().isNull())) && "Could not find parameter packs or undeduced auto type!" ) ? void (0) : __assert_fail ("(AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) && \"Could not find parameter packs or undeduced auto type!\"" , "clang/lib/Sema/TreeTransform.h", 5704, __extension__ __PRETTY_FUNCTION__ )) | |||
5704 | "Could not find parameter packs or undeduced auto type!")(static_cast <bool> ((AT && (!AT->isDeduced( ) || AT->getDeducedType().isNull())) && "Could not find parameter packs or undeduced auto type!" ) ? void (0) : __assert_fail ("(AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) && \"Could not find parameter packs or undeduced auto type!\"" , "clang/lib/Sema/TreeTransform.h", 5704, __extension__ __PRETTY_FUNCTION__ )); | |||
5705 | #endif | |||
5706 | } | |||
5707 | ||||
5708 | if (ShouldExpand) { | |||
5709 | // Expand the function parameter pack into multiple, separate | |||
5710 | // parameters. | |||
5711 | getDerived().ExpandingFunctionParameterPack(OldParm); | |||
5712 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
5713 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); | |||
5714 | ParmVarDecl *NewParm | |||
5715 | = getDerived().TransformFunctionTypeParam(OldParm, | |||
5716 | indexAdjustment++, | |||
5717 | OrigNumExpansions, | |||
5718 | /*ExpectParameterPack=*/false); | |||
5719 | if (!NewParm) | |||
5720 | return true; | |||
5721 | ||||
5722 | if (ParamInfos) | |||
5723 | PInfos.set(OutParamTypes.size(), ParamInfos[i]); | |||
5724 | OutParamTypes.push_back(NewParm->getType()); | |||
5725 | if (PVars) | |||
5726 | PVars->push_back(NewParm); | |||
5727 | } | |||
5728 | ||||
5729 | // If we're supposed to retain a pack expansion, do so by temporarily | |||
5730 | // forgetting the partially-substituted parameter pack. | |||
5731 | if (RetainExpansion) { | |||
5732 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
5733 | ParmVarDecl *NewParm | |||
5734 | = getDerived().TransformFunctionTypeParam(OldParm, | |||
5735 | indexAdjustment++, | |||
5736 | OrigNumExpansions, | |||
5737 | /*ExpectParameterPack=*/false); | |||
5738 | if (!NewParm) | |||
5739 | return true; | |||
5740 | ||||
5741 | if (ParamInfos) | |||
5742 | PInfos.set(OutParamTypes.size(), ParamInfos[i]); | |||
5743 | OutParamTypes.push_back(NewParm->getType()); | |||
5744 | if (PVars) | |||
5745 | PVars->push_back(NewParm); | |||
5746 | } | |||
5747 | ||||
5748 | // The next parameter should have the same adjustment as the | |||
5749 | // last thing we pushed, but we post-incremented indexAdjustment | |||
5750 | // on every push. Also, if we push nothing, the adjustment should | |||
5751 | // go down by one. | |||
5752 | indexAdjustment--; | |||
5753 | ||||
5754 | // We're done with the pack expansion. | |||
5755 | continue; | |||
5756 | } | |||
5757 | ||||
5758 | // We'll substitute the parameter now without expanding the pack | |||
5759 | // expansion. | |||
5760 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
5761 | NewParm = getDerived().TransformFunctionTypeParam(OldParm, | |||
5762 | indexAdjustment, | |||
5763 | NumExpansions, | |||
5764 | /*ExpectParameterPack=*/true); | |||
5765 | assert(NewParm->isParameterPack() &&(static_cast <bool> (NewParm->isParameterPack() && "Parameter pack no longer a parameter pack after " "transformation." ) ? void (0) : __assert_fail ("NewParm->isParameterPack() && \"Parameter pack no longer a parameter pack after \" \"transformation.\"" , "clang/lib/Sema/TreeTransform.h", 5767, __extension__ __PRETTY_FUNCTION__ )) | |||
5766 | "Parameter pack no longer a parameter pack after "(static_cast <bool> (NewParm->isParameterPack() && "Parameter pack no longer a parameter pack after " "transformation." ) ? void (0) : __assert_fail ("NewParm->isParameterPack() && \"Parameter pack no longer a parameter pack after \" \"transformation.\"" , "clang/lib/Sema/TreeTransform.h", 5767, __extension__ __PRETTY_FUNCTION__ )) | |||
5767 | "transformation.")(static_cast <bool> (NewParm->isParameterPack() && "Parameter pack no longer a parameter pack after " "transformation." ) ? void (0) : __assert_fail ("NewParm->isParameterPack() && \"Parameter pack no longer a parameter pack after \" \"transformation.\"" , "clang/lib/Sema/TreeTransform.h", 5767, __extension__ __PRETTY_FUNCTION__ )); | |||
5768 | } else { | |||
5769 | NewParm = getDerived().TransformFunctionTypeParam( | |||
5770 | OldParm, indexAdjustment, None, /*ExpectParameterPack=*/ false); | |||
5771 | } | |||
5772 | ||||
5773 | if (!NewParm) | |||
5774 | return true; | |||
5775 | ||||
5776 | if (ParamInfos) | |||
5777 | PInfos.set(OutParamTypes.size(), ParamInfos[i]); | |||
5778 | OutParamTypes.push_back(NewParm->getType()); | |||
5779 | if (PVars) | |||
5780 | PVars->push_back(NewParm); | |||
5781 | continue; | |||
5782 | } | |||
5783 | ||||
5784 | // Deal with the possibility that we don't have a parameter | |||
5785 | // declaration for this parameter. | |||
5786 | QualType OldType = ParamTypes[i]; | |||
5787 | bool IsPackExpansion = false; | |||
5788 | Optional<unsigned> NumExpansions; | |||
5789 | QualType NewType; | |||
5790 | if (const PackExpansionType *Expansion | |||
5791 | = dyn_cast<PackExpansionType>(OldType)) { | |||
5792 | // We have a function parameter pack that may need to be expanded. | |||
5793 | QualType Pattern = Expansion->getPattern(); | |||
5794 | NumExpansions = Expansion->getNumExpansions(); | |||
5795 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
5796 | getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); | |||
5797 | ||||
5798 | // Determine whether we should expand the parameter packs. | |||
5799 | bool ShouldExpand = false; | |||
5800 | bool RetainExpansion = false; | |||
5801 | if (getDerived().TryExpandParameterPacks(Loc, SourceRange(), | |||
5802 | Unexpanded, | |||
5803 | ShouldExpand, | |||
5804 | RetainExpansion, | |||
5805 | NumExpansions)) { | |||
5806 | return true; | |||
5807 | } | |||
5808 | ||||
5809 | if (ShouldExpand) { | |||
5810 | // Expand the function parameter pack into multiple, separate | |||
5811 | // parameters. | |||
5812 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
5813 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); | |||
5814 | QualType NewType = getDerived().TransformType(Pattern); | |||
5815 | if (NewType.isNull()) | |||
5816 | return true; | |||
5817 | ||||
5818 | if (NewType->containsUnexpandedParameterPack()) { | |||
5819 | NewType = | |||
5820 | getSema().getASTContext().getPackExpansionType(NewType, None); | |||
5821 | ||||
5822 | if (NewType.isNull()) | |||
5823 | return true; | |||
5824 | } | |||
5825 | ||||
5826 | if (ParamInfos) | |||
5827 | PInfos.set(OutParamTypes.size(), ParamInfos[i]); | |||
5828 | OutParamTypes.push_back(NewType); | |||
5829 | if (PVars) | |||
5830 | PVars->push_back(nullptr); | |||
5831 | } | |||
5832 | ||||
5833 | // We're done with the pack expansion. | |||
5834 | continue; | |||
5835 | } | |||
5836 | ||||
5837 | // If we're supposed to retain a pack expansion, do so by temporarily | |||
5838 | // forgetting the partially-substituted parameter pack. | |||
5839 | if (RetainExpansion) { | |||
5840 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
5841 | QualType NewType = getDerived().TransformType(Pattern); | |||
5842 | if (NewType.isNull()) | |||
5843 | return true; | |||
5844 | ||||
5845 | if (ParamInfos) | |||
5846 | PInfos.set(OutParamTypes.size(), ParamInfos[i]); | |||
5847 | OutParamTypes.push_back(NewType); | |||
5848 | if (PVars) | |||
5849 | PVars->push_back(nullptr); | |||
5850 | } | |||
5851 | ||||
5852 | // We'll substitute the parameter now without expanding the pack | |||
5853 | // expansion. | |||
5854 | OldType = Expansion->getPattern(); | |||
5855 | IsPackExpansion = true; | |||
5856 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
5857 | NewType = getDerived().TransformType(OldType); | |||
5858 | } else { | |||
5859 | NewType = getDerived().TransformType(OldType); | |||
5860 | } | |||
5861 | ||||
5862 | if (NewType.isNull()) | |||
5863 | return true; | |||
5864 | ||||
5865 | if (IsPackExpansion) | |||
5866 | NewType = getSema().Context.getPackExpansionType(NewType, | |||
5867 | NumExpansions); | |||
5868 | ||||
5869 | if (ParamInfos) | |||
5870 | PInfos.set(OutParamTypes.size(), ParamInfos[i]); | |||
5871 | OutParamTypes.push_back(NewType); | |||
5872 | if (PVars) | |||
5873 | PVars->push_back(nullptr); | |||
5874 | } | |||
5875 | ||||
5876 | #ifndef NDEBUG | |||
5877 | if (PVars) { | |||
5878 | for (unsigned i = 0, e = PVars->size(); i != e; ++i) | |||
5879 | if (ParmVarDecl *parm = (*PVars)[i]) | |||
5880 | assert(parm->getFunctionScopeIndex() == i)(static_cast <bool> (parm->getFunctionScopeIndex() == i) ? void (0) : __assert_fail ("parm->getFunctionScopeIndex() == i" , "clang/lib/Sema/TreeTransform.h", 5880, __extension__ __PRETTY_FUNCTION__ )); | |||
5881 | } | |||
5882 | #endif | |||
5883 | ||||
5884 | return false; | |||
5885 | } | |||
5886 | ||||
5887 | template<typename Derived> | |||
5888 | QualType | |||
5889 | TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, | |||
5890 | FunctionProtoTypeLoc TL) { | |||
5891 | SmallVector<QualType, 4> ExceptionStorage; | |||
5892 | TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. | |||
5893 | return getDerived().TransformFunctionProtoType( | |||
5894 | TLB, TL, nullptr, Qualifiers(), | |||
5895 | [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { | |||
5896 | return This->getDerived().TransformExceptionSpec( | |||
5897 | TL.getBeginLoc(), ESI, ExceptionStorage, Changed); | |||
5898 | }); | |||
5899 | } | |||
5900 | ||||
5901 | template<typename Derived> template<typename Fn> | |||
5902 | QualType TreeTransform<Derived>::TransformFunctionProtoType( | |||
5903 | TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, | |||
5904 | Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) { | |||
5905 | ||||
5906 | // Transform the parameters and return type. | |||
5907 | // | |||
5908 | // We are required to instantiate the params and return type in source order. | |||
5909 | // When the function has a trailing return type, we instantiate the | |||
5910 | // parameters before the return type, since the return type can then refer | |||
5911 | // to the parameters themselves (via decltype, sizeof, etc.). | |||
5912 | // | |||
5913 | SmallVector<QualType, 4> ParamTypes; | |||
5914 | SmallVector<ParmVarDecl*, 4> ParamDecls; | |||
5915 | Sema::ExtParameterInfoBuilder ExtParamInfos; | |||
5916 | const FunctionProtoType *T = TL.getTypePtr(); | |||
5917 | ||||
5918 | QualType ResultType; | |||
5919 | ||||
5920 | if (T->hasTrailingReturn()) { | |||
5921 | if (getDerived().TransformFunctionTypeParams( | |||
5922 | TL.getBeginLoc(), TL.getParams(), | |||
5923 | TL.getTypePtr()->param_type_begin(), | |||
5924 | T->getExtParameterInfosOrNull(), | |||
5925 | ParamTypes, &ParamDecls, ExtParamInfos)) | |||
5926 | return QualType(); | |||
5927 | ||||
5928 | { | |||
5929 | // C++11 [expr.prim.general]p3: | |||
5930 | // If a declaration declares a member function or member function | |||
5931 | // template of a class X, the expression this is a prvalue of type | |||
5932 | // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq | |||
5933 | // and the end of the function-definition, member-declarator, or | |||
5934 | // declarator. | |||
5935 | Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals); | |||
5936 | ||||
5937 | ResultType = getDerived().TransformType(TLB, TL.getReturnLoc()); | |||
5938 | if (ResultType.isNull()) | |||
5939 | return QualType(); | |||
5940 | } | |||
5941 | } | |||
5942 | else { | |||
5943 | ResultType = getDerived().TransformType(TLB, TL.getReturnLoc()); | |||
5944 | if (ResultType.isNull()) | |||
5945 | return QualType(); | |||
5946 | ||||
5947 | if (getDerived().TransformFunctionTypeParams( | |||
5948 | TL.getBeginLoc(), TL.getParams(), | |||
5949 | TL.getTypePtr()->param_type_begin(), | |||
5950 | T->getExtParameterInfosOrNull(), | |||
5951 | ParamTypes, &ParamDecls, ExtParamInfos)) | |||
5952 | return QualType(); | |||
5953 | } | |||
5954 | ||||
5955 | FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo(); | |||
5956 | ||||
5957 | bool EPIChanged = false; | |||
5958 | if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged)) | |||
5959 | return QualType(); | |||
5960 | ||||
5961 | // Handle extended parameter information. | |||
5962 | if (auto NewExtParamInfos = | |||
5963 | ExtParamInfos.getPointerOrNull(ParamTypes.size())) { | |||
5964 | if (!EPI.ExtParameterInfos || | |||
5965 | llvm::makeArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) | |||
5966 | != llvm::makeArrayRef(NewExtParamInfos, ParamTypes.size())) { | |||
5967 | EPIChanged = true; | |||
5968 | } | |||
5969 | EPI.ExtParameterInfos = NewExtParamInfos; | |||
5970 | } else if (EPI.ExtParameterInfos) { | |||
5971 | EPIChanged = true; | |||
5972 | EPI.ExtParameterInfos = nullptr; | |||
5973 | } | |||
5974 | ||||
5975 | QualType Result = TL.getType(); | |||
5976 | if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() || | |||
5977 | T->getParamTypes() != llvm::makeArrayRef(ParamTypes) || EPIChanged) { | |||
5978 | Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI); | |||
5979 | if (Result.isNull()) | |||
5980 | return QualType(); | |||
5981 | } | |||
5982 | ||||
5983 | FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result); | |||
5984 | NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); | |||
5985 | NewTL.setLParenLoc(TL.getLParenLoc()); | |||
5986 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
5987 | NewTL.setExceptionSpecRange(TL.getExceptionSpecRange()); | |||
5988 | NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); | |||
5989 | for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i) | |||
5990 | NewTL.setParam(i, ParamDecls[i]); | |||
5991 | ||||
5992 | return Result; | |||
5993 | } | |||
5994 | ||||
5995 | template<typename Derived> | |||
5996 | bool TreeTransform<Derived>::TransformExceptionSpec( | |||
5997 | SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI, | |||
5998 | SmallVectorImpl<QualType> &Exceptions, bool &Changed) { | |||
5999 | assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated)(static_cast <bool> (ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated) ? void (0) : __assert_fail ("ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated" , "clang/lib/Sema/TreeTransform.h", 5999, __extension__ __PRETTY_FUNCTION__ )); | |||
6000 | ||||
6001 | // Instantiate a dynamic noexcept expression, if any. | |||
6002 | if (isComputedNoexcept(ESI.Type)) { | |||
6003 | EnterExpressionEvaluationContext Unevaluated( | |||
6004 | getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
6005 | ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr); | |||
6006 | if (NoexceptExpr.isInvalid()) | |||
6007 | return true; | |||
6008 | ||||
6009 | ExceptionSpecificationType EST = ESI.Type; | |||
6010 | NoexceptExpr = | |||
6011 | getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST); | |||
6012 | if (NoexceptExpr.isInvalid()) | |||
6013 | return true; | |||
6014 | ||||
6015 | if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type) | |||
6016 | Changed = true; | |||
6017 | ESI.NoexceptExpr = NoexceptExpr.get(); | |||
6018 | ESI.Type = EST; | |||
6019 | } | |||
6020 | ||||
6021 | if (ESI.Type != EST_Dynamic) | |||
6022 | return false; | |||
6023 | ||||
6024 | // Instantiate a dynamic exception specification's type. | |||
6025 | for (QualType T : ESI.Exceptions) { | |||
6026 | if (const PackExpansionType *PackExpansion = | |||
6027 | T->getAs<PackExpansionType>()) { | |||
6028 | Changed = true; | |||
6029 | ||||
6030 | // We have a pack expansion. Instantiate it. | |||
6031 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
6032 | SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), | |||
6033 | Unexpanded); | |||
6034 | assert(!Unexpanded.empty() && "Pack expansion without parameter packs?")(static_cast <bool> (!Unexpanded.empty() && "Pack expansion without parameter packs?" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Pack expansion without parameter packs?\"" , "clang/lib/Sema/TreeTransform.h", 6034, __extension__ __PRETTY_FUNCTION__ )); | |||
6035 | ||||
6036 | // Determine whether the set of unexpanded parameter packs can and | |||
6037 | // should | |||
6038 | // be expanded. | |||
6039 | bool Expand = false; | |||
6040 | bool RetainExpansion = false; | |||
6041 | Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); | |||
6042 | // FIXME: Track the location of the ellipsis (and track source location | |||
6043 | // information for the types in the exception specification in general). | |||
6044 | if (getDerived().TryExpandParameterPacks( | |||
6045 | Loc, SourceRange(), Unexpanded, Expand, | |||
6046 | RetainExpansion, NumExpansions)) | |||
6047 | return true; | |||
6048 | ||||
6049 | if (!Expand) { | |||
6050 | // We can't expand this pack expansion into separate arguments yet; | |||
6051 | // just substitute into the pattern and create a new pack expansion | |||
6052 | // type. | |||
6053 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
6054 | QualType U = getDerived().TransformType(PackExpansion->getPattern()); | |||
6055 | if (U.isNull()) | |||
6056 | return true; | |||
6057 | ||||
6058 | U = SemaRef.Context.getPackExpansionType(U, NumExpansions); | |||
6059 | Exceptions.push_back(U); | |||
6060 | continue; | |||
6061 | } | |||
6062 | ||||
6063 | // Substitute into the pack expansion pattern for each slice of the | |||
6064 | // pack. | |||
6065 | for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { | |||
6066 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx); | |||
6067 | ||||
6068 | QualType U = getDerived().TransformType(PackExpansion->getPattern()); | |||
6069 | if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc)) | |||
6070 | return true; | |||
6071 | ||||
6072 | Exceptions.push_back(U); | |||
6073 | } | |||
6074 | } else { | |||
6075 | QualType U = getDerived().TransformType(T); | |||
6076 | if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc)) | |||
6077 | return true; | |||
6078 | if (T != U) | |||
6079 | Changed = true; | |||
6080 | ||||
6081 | Exceptions.push_back(U); | |||
6082 | } | |||
6083 | } | |||
6084 | ||||
6085 | ESI.Exceptions = Exceptions; | |||
6086 | if (ESI.Exceptions.empty()) | |||
6087 | ESI.Type = EST_DynamicNone; | |||
6088 | return false; | |||
6089 | } | |||
6090 | ||||
6091 | template<typename Derived> | |||
6092 | QualType TreeTransform<Derived>::TransformFunctionNoProtoType( | |||
6093 | TypeLocBuilder &TLB, | |||
6094 | FunctionNoProtoTypeLoc TL) { | |||
6095 | const FunctionNoProtoType *T = TL.getTypePtr(); | |||
6096 | QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc()); | |||
6097 | if (ResultType.isNull()) | |||
6098 | return QualType(); | |||
6099 | ||||
6100 | QualType Result = TL.getType(); | |||
6101 | if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType()) | |||
6102 | Result = getDerived().RebuildFunctionNoProtoType(ResultType); | |||
6103 | ||||
6104 | FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result); | |||
6105 | NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); | |||
6106 | NewTL.setLParenLoc(TL.getLParenLoc()); | |||
6107 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
6108 | NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); | |||
6109 | ||||
6110 | return Result; | |||
6111 | } | |||
6112 | ||||
6113 | template <typename Derived> | |||
6114 | QualType TreeTransform<Derived>::TransformUnresolvedUsingType( | |||
6115 | TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) { | |||
6116 | const UnresolvedUsingType *T = TL.getTypePtr(); | |||
6117 | Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()); | |||
6118 | if (!D) | |||
6119 | return QualType(); | |||
6120 | ||||
6121 | QualType Result = TL.getType(); | |||
6122 | if (getDerived().AlwaysRebuild() || D != T->getDecl()) { | |||
6123 | Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D); | |||
6124 | if (Result.isNull()) | |||
6125 | return QualType(); | |||
6126 | } | |||
6127 | ||||
6128 | // We might get an arbitrary type spec type back. We should at | |||
6129 | // least always get a type spec type, though. | |||
6130 | TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result); | |||
6131 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6132 | ||||
6133 | return Result; | |||
6134 | } | |||
6135 | ||||
6136 | template <typename Derived> | |||
6137 | QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB, | |||
6138 | UsingTypeLoc TL) { | |||
6139 | const UsingType *T = TL.getTypePtr(); | |||
6140 | ||||
6141 | auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl( | |||
6142 | TL.getLocalSourceRange().getBegin(), T->getFoundDecl())); | |||
6143 | if (!Found) | |||
6144 | return QualType(); | |||
6145 | ||||
6146 | QualType Underlying = getDerived().TransformType(T->desugar()); | |||
6147 | if (Underlying.isNull()) | |||
6148 | return QualType(); | |||
6149 | ||||
6150 | QualType Result = TL.getType(); | |||
6151 | if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() || | |||
6152 | Underlying != T->getUnderlyingType()) { | |||
6153 | Result = getDerived().RebuildUsingType(Found, Underlying); | |||
6154 | if (Result.isNull()) | |||
6155 | return QualType(); | |||
6156 | } | |||
6157 | ||||
6158 | TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc()); | |||
6159 | return Result; | |||
6160 | } | |||
6161 | ||||
6162 | template<typename Derived> | |||
6163 | QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB, | |||
6164 | TypedefTypeLoc TL) { | |||
6165 | const TypedefType *T = TL.getTypePtr(); | |||
6166 | TypedefNameDecl *Typedef | |||
6167 | = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(), | |||
6168 | T->getDecl())); | |||
6169 | if (!Typedef) | |||
6170 | return QualType(); | |||
6171 | ||||
6172 | QualType Result = TL.getType(); | |||
6173 | if (getDerived().AlwaysRebuild() || | |||
6174 | Typedef != T->getDecl()) { | |||
6175 | Result = getDerived().RebuildTypedefType(Typedef); | |||
6176 | if (Result.isNull()) | |||
6177 | return QualType(); | |||
6178 | } | |||
6179 | ||||
6180 | TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result); | |||
6181 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6182 | ||||
6183 | return Result; | |||
6184 | } | |||
6185 | ||||
6186 | template<typename Derived> | |||
6187 | QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB, | |||
6188 | TypeOfExprTypeLoc TL) { | |||
6189 | // typeof expressions are not potentially evaluated contexts | |||
6190 | EnterExpressionEvaluationContext Unevaluated( | |||
6191 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, | |||
6192 | Sema::ReuseLambdaContextDecl); | |||
6193 | ||||
6194 | ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr()); | |||
6195 | if (E.isInvalid()) | |||
6196 | return QualType(); | |||
6197 | ||||
6198 | E = SemaRef.HandleExprEvaluationContextForTypeof(E.get()); | |||
6199 | if (E.isInvalid()) | |||
6200 | return QualType(); | |||
6201 | ||||
6202 | QualType Result = TL.getType(); | |||
6203 | bool IsUnqual = Result->getAs<TypeOfExprType>()->isUnqual(); | |||
| ||||
6204 | if (getDerived().AlwaysRebuild() || | |||
6205 | E.get() != TL.getUnderlyingExpr()) { | |||
6206 | Result = getDerived().RebuildTypeOfExprType( | |||
6207 | E.get(), TL.getTypeofLoc(), | |||
6208 | IsUnqual ? TypeOfKind::Unqualified : TypeOfKind::Qualified); | |||
6209 | if (Result.isNull()) | |||
6210 | return QualType(); | |||
6211 | } | |||
6212 | ||||
6213 | TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result); | |||
6214 | NewTL.setTypeofLoc(TL.getTypeofLoc()); | |||
6215 | NewTL.setLParenLoc(TL.getLParenLoc()); | |||
6216 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
6217 | ||||
6218 | return Result; | |||
6219 | } | |||
6220 | ||||
6221 | template<typename Derived> | |||
6222 | QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB, | |||
6223 | TypeOfTypeLoc TL) { | |||
6224 | TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo(); | |||
6225 | TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI); | |||
6226 | if (!New_Under_TI) | |||
6227 | return QualType(); | |||
6228 | ||||
6229 | QualType Result = TL.getType(); | |||
6230 | bool IsUnqual = Result->getAs<TypeOfType>()->isUnqual(); | |||
6231 | if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) { | |||
6232 | Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), | |||
6233 | IsUnqual ? TypeOfKind::Unqualified | |||
6234 | : TypeOfKind::Qualified); | |||
6235 | if (Result.isNull()) | |||
6236 | return QualType(); | |||
6237 | } | |||
6238 | ||||
6239 | TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result); | |||
6240 | NewTL.setTypeofLoc(TL.getTypeofLoc()); | |||
6241 | NewTL.setLParenLoc(TL.getLParenLoc()); | |||
6242 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
6243 | NewTL.setUnmodifiedTInfo(New_Under_TI); | |||
6244 | ||||
6245 | return Result; | |||
6246 | } | |||
6247 | ||||
6248 | template<typename Derived> | |||
6249 | QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, | |||
6250 | DecltypeTypeLoc TL) { | |||
6251 | const DecltypeType *T = TL.getTypePtr(); | |||
6252 | ||||
6253 | // decltype expressions are not potentially evaluated contexts | |||
6254 | EnterExpressionEvaluationContext Unevaluated( | |||
6255 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, | |||
6256 | Sema::ExpressionEvaluationContextRecord::EK_Decltype); | |||
6257 | ||||
6258 | ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr()); | |||
6259 | if (E.isInvalid()) | |||
6260 | return QualType(); | |||
6261 | ||||
6262 | E = getSema().ActOnDecltypeExpression(E.get()); | |||
6263 | if (E.isInvalid()) | |||
6264 | return QualType(); | |||
6265 | ||||
6266 | QualType Result = TL.getType(); | |||
6267 | if (getDerived().AlwaysRebuild() || | |||
6268 | E.get() != T->getUnderlyingExpr()) { | |||
6269 | Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc()); | |||
6270 | if (Result.isNull()) | |||
6271 | return QualType(); | |||
6272 | } | |||
6273 | else E.get(); | |||
6274 | ||||
6275 | DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result); | |||
6276 | NewTL.setDecltypeLoc(TL.getDecltypeLoc()); | |||
6277 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
6278 | return Result; | |||
6279 | } | |||
6280 | ||||
6281 | template<typename Derived> | |||
6282 | QualType TreeTransform<Derived>::TransformUnaryTransformType( | |||
6283 | TypeLocBuilder &TLB, | |||
6284 | UnaryTransformTypeLoc TL) { | |||
6285 | QualType Result = TL.getType(); | |||
6286 | if (Result->isDependentType()) { | |||
6287 | const UnaryTransformType *T = TL.getTypePtr(); | |||
6288 | QualType NewBase = | |||
6289 | getDerived().TransformType(TL.getUnderlyingTInfo())->getType(); | |||
6290 | Result = getDerived().RebuildUnaryTransformType(NewBase, | |||
6291 | T->getUTTKind(), | |||
6292 | TL.getKWLoc()); | |||
6293 | if (Result.isNull()) | |||
6294 | return QualType(); | |||
6295 | } | |||
6296 | ||||
6297 | UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result); | |||
6298 | NewTL.setKWLoc(TL.getKWLoc()); | |||
6299 | NewTL.setParensRange(TL.getParensRange()); | |||
6300 | NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo()); | |||
6301 | return Result; | |||
6302 | } | |||
6303 | ||||
6304 | template<typename Derived> | |||
6305 | QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType( | |||
6306 | TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) { | |||
6307 | const DeducedTemplateSpecializationType *T = TL.getTypePtr(); | |||
6308 | ||||
6309 | CXXScopeSpec SS; | |||
6310 | TemplateName TemplateName = getDerived().TransformTemplateName( | |||
6311 | SS, T->getTemplateName(), TL.getTemplateNameLoc()); | |||
6312 | if (TemplateName.isNull()) | |||
6313 | return QualType(); | |||
6314 | ||||
6315 | QualType OldDeduced = T->getDeducedType(); | |||
6316 | QualType NewDeduced; | |||
6317 | if (!OldDeduced.isNull()) { | |||
6318 | NewDeduced = getDerived().TransformType(OldDeduced); | |||
6319 | if (NewDeduced.isNull()) | |||
6320 | return QualType(); | |||
6321 | } | |||
6322 | ||||
6323 | QualType Result = getDerived().RebuildDeducedTemplateSpecializationType( | |||
6324 | TemplateName, NewDeduced); | |||
6325 | if (Result.isNull()) | |||
6326 | return QualType(); | |||
6327 | ||||
6328 | DeducedTemplateSpecializationTypeLoc NewTL = | |||
6329 | TLB.push<DeducedTemplateSpecializationTypeLoc>(Result); | |||
6330 | NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
6331 | ||||
6332 | return Result; | |||
6333 | } | |||
6334 | ||||
6335 | template<typename Derived> | |||
6336 | QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB, | |||
6337 | RecordTypeLoc TL) { | |||
6338 | const RecordType *T = TL.getTypePtr(); | |||
6339 | RecordDecl *Record | |||
6340 | = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(), | |||
6341 | T->getDecl())); | |||
6342 | if (!Record) | |||
6343 | return QualType(); | |||
6344 | ||||
6345 | QualType Result = TL.getType(); | |||
6346 | if (getDerived().AlwaysRebuild() || | |||
6347 | Record != T->getDecl()) { | |||
6348 | Result = getDerived().RebuildRecordType(Record); | |||
6349 | if (Result.isNull()) | |||
6350 | return QualType(); | |||
6351 | } | |||
6352 | ||||
6353 | RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result); | |||
6354 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6355 | ||||
6356 | return Result; | |||
6357 | } | |||
6358 | ||||
6359 | template<typename Derived> | |||
6360 | QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB, | |||
6361 | EnumTypeLoc TL) { | |||
6362 | const EnumType *T = TL.getTypePtr(); | |||
6363 | EnumDecl *Enum | |||
6364 | = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(), | |||
6365 | T->getDecl())); | |||
6366 | if (!Enum) | |||
6367 | return QualType(); | |||
6368 | ||||
6369 | QualType Result = TL.getType(); | |||
6370 | if (getDerived().AlwaysRebuild() || | |||
6371 | Enum != T->getDecl()) { | |||
6372 | Result = getDerived().RebuildEnumType(Enum); | |||
6373 | if (Result.isNull()) | |||
6374 | return QualType(); | |||
6375 | } | |||
6376 | ||||
6377 | EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result); | |||
6378 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6379 | ||||
6380 | return Result; | |||
6381 | } | |||
6382 | ||||
6383 | template<typename Derived> | |||
6384 | QualType TreeTransform<Derived>::TransformInjectedClassNameType( | |||
6385 | TypeLocBuilder &TLB, | |||
6386 | InjectedClassNameTypeLoc TL) { | |||
6387 | Decl *D = getDerived().TransformDecl(TL.getNameLoc(), | |||
6388 | TL.getTypePtr()->getDecl()); | |||
6389 | if (!D) return QualType(); | |||
6390 | ||||
6391 | QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D)); | |||
6392 | TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc()); | |||
6393 | return T; | |||
6394 | } | |||
6395 | ||||
6396 | template<typename Derived> | |||
6397 | QualType TreeTransform<Derived>::TransformTemplateTypeParmType( | |||
6398 | TypeLocBuilder &TLB, | |||
6399 | TemplateTypeParmTypeLoc TL) { | |||
6400 | return TransformTypeSpecType(TLB, TL); | |||
6401 | } | |||
6402 | ||||
6403 | template<typename Derived> | |||
6404 | QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType( | |||
6405 | TypeLocBuilder &TLB, | |||
6406 | SubstTemplateTypeParmTypeLoc TL) { | |||
6407 | const SubstTemplateTypeParmType *T = TL.getTypePtr(); | |||
6408 | ||||
6409 | // Substitute into the replacement type, which itself might involve something | |||
6410 | // that needs to be transformed. This only tends to occur with default | |||
6411 | // template arguments of template template parameters. | |||
6412 | TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName()); | |||
6413 | QualType Replacement = getDerived().TransformType(T->getReplacementType()); | |||
6414 | if (Replacement.isNull()) | |||
6415 | return QualType(); | |||
6416 | ||||
6417 | QualType Result = SemaRef.Context.getSubstTemplateTypeParmType( | |||
6418 | T->getReplacedParameter(), Replacement, T->getPackIndex()); | |||
6419 | ||||
6420 | // Propagate type-source information. | |||
6421 | SubstTemplateTypeParmTypeLoc NewTL | |||
6422 | = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); | |||
6423 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6424 | return Result; | |||
6425 | ||||
6426 | } | |||
6427 | ||||
6428 | template<typename Derived> | |||
6429 | QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType( | |||
6430 | TypeLocBuilder &TLB, | |||
6431 | SubstTemplateTypeParmPackTypeLoc TL) { | |||
6432 | return TransformTypeSpecType(TLB, TL); | |||
6433 | } | |||
6434 | ||||
6435 | template<typename Derived> | |||
6436 | QualType TreeTransform<Derived>::TransformTemplateSpecializationType( | |||
6437 | TypeLocBuilder &TLB, | |||
6438 | TemplateSpecializationTypeLoc TL) { | |||
6439 | const TemplateSpecializationType *T = TL.getTypePtr(); | |||
6440 | ||||
6441 | // The nested-name-specifier never matters in a TemplateSpecializationType, | |||
6442 | // because we can't have a dependent nested-name-specifier anyway. | |||
6443 | CXXScopeSpec SS; | |||
6444 | TemplateName Template | |||
6445 | = getDerived().TransformTemplateName(SS, T->getTemplateName(), | |||
6446 | TL.getTemplateNameLoc()); | |||
6447 | if (Template.isNull()) | |||
6448 | return QualType(); | |||
6449 | ||||
6450 | return getDerived().TransformTemplateSpecializationType(TLB, TL, Template); | |||
6451 | } | |||
6452 | ||||
6453 | template<typename Derived> | |||
6454 | QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB, | |||
6455 | AtomicTypeLoc TL) { | |||
6456 | QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc()); | |||
6457 | if (ValueType.isNull()) | |||
6458 | return QualType(); | |||
6459 | ||||
6460 | QualType Result = TL.getType(); | |||
6461 | if (getDerived().AlwaysRebuild() || | |||
6462 | ValueType != TL.getValueLoc().getType()) { | |||
6463 | Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc()); | |||
6464 | if (Result.isNull()) | |||
6465 | return QualType(); | |||
6466 | } | |||
6467 | ||||
6468 | AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result); | |||
6469 | NewTL.setKWLoc(TL.getKWLoc()); | |||
6470 | NewTL.setLParenLoc(TL.getLParenLoc()); | |||
6471 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
6472 | ||||
6473 | return Result; | |||
6474 | } | |||
6475 | ||||
6476 | template <typename Derived> | |||
6477 | QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB, | |||
6478 | PipeTypeLoc TL) { | |||
6479 | QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc()); | |||
6480 | if (ValueType.isNull()) | |||
6481 | return QualType(); | |||
6482 | ||||
6483 | QualType Result = TL.getType(); | |||
6484 | if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) { | |||
6485 | const PipeType *PT = Result->castAs<PipeType>(); | |||
6486 | bool isReadPipe = PT->isReadOnly(); | |||
6487 | Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe); | |||
6488 | if (Result.isNull()) | |||
6489 | return QualType(); | |||
6490 | } | |||
6491 | ||||
6492 | PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result); | |||
6493 | NewTL.setKWLoc(TL.getKWLoc()); | |||
6494 | ||||
6495 | return Result; | |||
6496 | } | |||
6497 | ||||
6498 | template <typename Derived> | |||
6499 | QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB, | |||
6500 | BitIntTypeLoc TL) { | |||
6501 | const BitIntType *EIT = TL.getTypePtr(); | |||
6502 | QualType Result = TL.getType(); | |||
6503 | ||||
6504 | if (getDerived().AlwaysRebuild()) { | |||
6505 | Result = getDerived().RebuildBitIntType(EIT->isUnsigned(), | |||
6506 | EIT->getNumBits(), TL.getNameLoc()); | |||
6507 | if (Result.isNull()) | |||
6508 | return QualType(); | |||
6509 | } | |||
6510 | ||||
6511 | BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result); | |||
6512 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6513 | return Result; | |||
6514 | } | |||
6515 | ||||
6516 | template <typename Derived> | |||
6517 | QualType TreeTransform<Derived>::TransformDependentBitIntType( | |||
6518 | TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) { | |||
6519 | const DependentBitIntType *EIT = TL.getTypePtr(); | |||
6520 | ||||
6521 | EnterExpressionEvaluationContext Unevaluated( | |||
6522 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
6523 | ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr()); | |||
6524 | BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr); | |||
6525 | ||||
6526 | if (BitsExpr.isInvalid()) | |||
6527 | return QualType(); | |||
6528 | ||||
6529 | QualType Result = TL.getType(); | |||
6530 | ||||
6531 | if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) { | |||
6532 | Result = getDerived().RebuildDependentBitIntType( | |||
6533 | EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc()); | |||
6534 | ||||
6535 | if (Result.isNull()) | |||
6536 | return QualType(); | |||
6537 | } | |||
6538 | ||||
6539 | if (isa<DependentBitIntType>(Result)) { | |||
6540 | DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result); | |||
6541 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6542 | } else { | |||
6543 | BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result); | |||
6544 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6545 | } | |||
6546 | return Result; | |||
6547 | } | |||
6548 | ||||
6549 | /// Simple iterator that traverses the template arguments in a | |||
6550 | /// container that provides a \c getArgLoc() member function. | |||
6551 | /// | |||
6552 | /// This iterator is intended to be used with the iterator form of | |||
6553 | /// \c TreeTransform<Derived>::TransformTemplateArguments(). | |||
6554 | template<typename ArgLocContainer> | |||
6555 | class TemplateArgumentLocContainerIterator { | |||
6556 | ArgLocContainer *Container; | |||
6557 | unsigned Index; | |||
6558 | ||||
6559 | public: | |||
6560 | typedef TemplateArgumentLoc value_type; | |||
6561 | typedef TemplateArgumentLoc reference; | |||
6562 | typedef int difference_type; | |||
6563 | typedef std::input_iterator_tag iterator_category; | |||
6564 | ||||
6565 | class pointer { | |||
6566 | TemplateArgumentLoc Arg; | |||
6567 | ||||
6568 | public: | |||
6569 | explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { } | |||
6570 | ||||
6571 | const TemplateArgumentLoc *operator->() const { | |||
6572 | return &Arg; | |||
6573 | } | |||
6574 | }; | |||
6575 | ||||
6576 | ||||
6577 | TemplateArgumentLocContainerIterator() {} | |||
6578 | ||||
6579 | TemplateArgumentLocContainerIterator(ArgLocContainer &Container, | |||
6580 | unsigned Index) | |||
6581 | : Container(&Container), Index(Index) { } | |||
6582 | ||||
6583 | TemplateArgumentLocContainerIterator &operator++() { | |||
6584 | ++Index; | |||
6585 | return *this; | |||
6586 | } | |||
6587 | ||||
6588 | TemplateArgumentLocContainerIterator operator++(int) { | |||
6589 | TemplateArgumentLocContainerIterator Old(*this); | |||
6590 | ++(*this); | |||
6591 | return Old; | |||
6592 | } | |||
6593 | ||||
6594 | TemplateArgumentLoc operator*() const { | |||
6595 | return Container->getArgLoc(Index); | |||
6596 | } | |||
6597 | ||||
6598 | pointer operator->() const { | |||
6599 | return pointer(Container->getArgLoc(Index)); | |||
6600 | } | |||
6601 | ||||
6602 | friend bool operator==(const TemplateArgumentLocContainerIterator &X, | |||
6603 | const TemplateArgumentLocContainerIterator &Y) { | |||
6604 | return X.Container == Y.Container && X.Index == Y.Index; | |||
6605 | } | |||
6606 | ||||
6607 | friend bool operator!=(const TemplateArgumentLocContainerIterator &X, | |||
6608 | const TemplateArgumentLocContainerIterator &Y) { | |||
6609 | return !(X == Y); | |||
6610 | } | |||
6611 | }; | |||
6612 | ||||
6613 | template<typename Derived> | |||
6614 | QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, | |||
6615 | AutoTypeLoc TL) { | |||
6616 | const AutoType *T = TL.getTypePtr(); | |||
6617 | QualType OldDeduced = T->getDeducedType(); | |||
6618 | QualType NewDeduced; | |||
6619 | if (!OldDeduced.isNull()) { | |||
6620 | NewDeduced = getDerived().TransformType(OldDeduced); | |||
6621 | if (NewDeduced.isNull()) | |||
6622 | return QualType(); | |||
6623 | } | |||
6624 | ||||
6625 | ConceptDecl *NewCD = nullptr; | |||
6626 | TemplateArgumentListInfo NewTemplateArgs; | |||
6627 | NestedNameSpecifierLoc NewNestedNameSpec; | |||
6628 | if (T->isConstrained()) { | |||
6629 | NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl( | |||
6630 | TL.getConceptNameLoc(), T->getTypeConstraintConcept())); | |||
6631 | ||||
6632 | NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); | |||
6633 | NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); | |||
6634 | typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator; | |||
6635 | if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), | |||
6636 | ArgIterator(TL, | |||
6637 | TL.getNumArgs()), | |||
6638 | NewTemplateArgs)) | |||
6639 | return QualType(); | |||
6640 | ||||
6641 | if (TL.getNestedNameSpecifierLoc()) { | |||
6642 | NewNestedNameSpec | |||
6643 | = getDerived().TransformNestedNameSpecifierLoc( | |||
6644 | TL.getNestedNameSpecifierLoc()); | |||
6645 | if (!NewNestedNameSpec) | |||
6646 | return QualType(); | |||
6647 | } | |||
6648 | } | |||
6649 | ||||
6650 | QualType Result = TL.getType(); | |||
6651 | if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced || | |||
6652 | T->isDependentType() || T->isConstrained()) { | |||
6653 | // FIXME: Maybe don't rebuild if all template arguments are the same. | |||
6654 | llvm::SmallVector<TemplateArgument, 4> NewArgList; | |||
6655 | NewArgList.reserve(NewTemplateArgs.size()); | |||
6656 | for (const auto &ArgLoc : NewTemplateArgs.arguments()) | |||
6657 | NewArgList.push_back(ArgLoc.getArgument()); | |||
6658 | Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD, | |||
6659 | NewArgList); | |||
6660 | if (Result.isNull()) | |||
6661 | return QualType(); | |||
6662 | } | |||
6663 | ||||
6664 | AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); | |||
6665 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6666 | NewTL.setNestedNameSpecifierLoc(NewNestedNameSpec); | |||
6667 | NewTL.setTemplateKWLoc(TL.getTemplateKWLoc()); | |||
6668 | NewTL.setConceptNameLoc(TL.getConceptNameLoc()); | |||
6669 | NewTL.setFoundDecl(TL.getFoundDecl()); | |||
6670 | NewTL.setLAngleLoc(TL.getLAngleLoc()); | |||
6671 | NewTL.setRAngleLoc(TL.getRAngleLoc()); | |||
6672 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
6673 | for (unsigned I = 0; I < NewTL.getNumArgs(); ++I) | |||
6674 | NewTL.setArgLocInfo(I, NewTemplateArgs.arguments()[I].getLocInfo()); | |||
6675 | ||||
6676 | return Result; | |||
6677 | } | |||
6678 | ||||
6679 | template <typename Derived> | |||
6680 | QualType TreeTransform<Derived>::TransformTemplateSpecializationType( | |||
6681 | TypeLocBuilder &TLB, | |||
6682 | TemplateSpecializationTypeLoc TL, | |||
6683 | TemplateName Template) { | |||
6684 | TemplateArgumentListInfo NewTemplateArgs; | |||
6685 | NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); | |||
6686 | NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); | |||
6687 | typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc> | |||
6688 | ArgIterator; | |||
6689 | if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), | |||
6690 | ArgIterator(TL, TL.getNumArgs()), | |||
6691 | NewTemplateArgs)) | |||
6692 | return QualType(); | |||
6693 | ||||
6694 | // FIXME: maybe don't rebuild if all the template arguments are the same. | |||
6695 | ||||
6696 | QualType Result = | |||
6697 | getDerived().RebuildTemplateSpecializationType(Template, | |||
6698 | TL.getTemplateNameLoc(), | |||
6699 | NewTemplateArgs); | |||
6700 | ||||
6701 | if (!Result.isNull()) { | |||
6702 | // Specializations of template template parameters are represented as | |||
6703 | // TemplateSpecializationTypes, and substitution of type alias templates | |||
6704 | // within a dependent context can transform them into | |||
6705 | // DependentTemplateSpecializationTypes. | |||
6706 | if (isa<DependentTemplateSpecializationType>(Result)) { | |||
6707 | DependentTemplateSpecializationTypeLoc NewTL | |||
6708 | = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); | |||
6709 | NewTL.setElaboratedKeywordLoc(SourceLocation()); | |||
6710 | NewTL.setQualifierLoc(NestedNameSpecifierLoc()); | |||
6711 | NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); | |||
6712 | NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
6713 | NewTL.setLAngleLoc(TL.getLAngleLoc()); | |||
6714 | NewTL.setRAngleLoc(TL.getRAngleLoc()); | |||
6715 | for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) | |||
6716 | NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); | |||
6717 | return Result; | |||
6718 | } | |||
6719 | ||||
6720 | TemplateSpecializationTypeLoc NewTL | |||
6721 | = TLB.push<TemplateSpecializationTypeLoc>(Result); | |||
6722 | NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); | |||
6723 | NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
6724 | NewTL.setLAngleLoc(TL.getLAngleLoc()); | |||
6725 | NewTL.setRAngleLoc(TL.getRAngleLoc()); | |||
6726 | for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) | |||
6727 | NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); | |||
6728 | } | |||
6729 | ||||
6730 | return Result; | |||
6731 | } | |||
6732 | ||||
6733 | template <typename Derived> | |||
6734 | QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( | |||
6735 | TypeLocBuilder &TLB, | |||
6736 | DependentTemplateSpecializationTypeLoc TL, | |||
6737 | TemplateName Template, | |||
6738 | CXXScopeSpec &SS) { | |||
6739 | TemplateArgumentListInfo NewTemplateArgs; | |||
6740 | NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); | |||
6741 | NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); | |||
6742 | typedef TemplateArgumentLocContainerIterator< | |||
6743 | DependentTemplateSpecializationTypeLoc> ArgIterator; | |||
6744 | if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), | |||
6745 | ArgIterator(TL, TL.getNumArgs()), | |||
6746 | NewTemplateArgs)) | |||
6747 | return QualType(); | |||
6748 | ||||
6749 | // FIXME: maybe don't rebuild if all the template arguments are the same. | |||
6750 | ||||
6751 | if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { | |||
6752 | QualType Result | |||
6753 | = getSema().Context.getDependentTemplateSpecializationType( | |||
6754 | TL.getTypePtr()->getKeyword(), | |||
6755 | DTN->getQualifier(), | |||
6756 | DTN->getIdentifier(), | |||
6757 | NewTemplateArgs); | |||
6758 | ||||
6759 | DependentTemplateSpecializationTypeLoc NewTL | |||
6760 | = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); | |||
6761 | NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); | |||
6762 | NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context)); | |||
6763 | NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); | |||
6764 | NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
6765 | NewTL.setLAngleLoc(TL.getLAngleLoc()); | |||
6766 | NewTL.setRAngleLoc(TL.getRAngleLoc()); | |||
6767 | for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) | |||
6768 | NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); | |||
6769 | return Result; | |||
6770 | } | |||
6771 | ||||
6772 | QualType Result | |||
6773 | = getDerived().RebuildTemplateSpecializationType(Template, | |||
6774 | TL.getTemplateNameLoc(), | |||
6775 | NewTemplateArgs); | |||
6776 | ||||
6777 | if (!Result.isNull()) { | |||
6778 | /// FIXME: Wrap this in an elaborated-type-specifier? | |||
6779 | TemplateSpecializationTypeLoc NewTL | |||
6780 | = TLB.push<TemplateSpecializationTypeLoc>(Result); | |||
6781 | NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); | |||
6782 | NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
6783 | NewTL.setLAngleLoc(TL.getLAngleLoc()); | |||
6784 | NewTL.setRAngleLoc(TL.getRAngleLoc()); | |||
6785 | for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) | |||
6786 | NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); | |||
6787 | } | |||
6788 | ||||
6789 | return Result; | |||
6790 | } | |||
6791 | ||||
6792 | template<typename Derived> | |||
6793 | QualType | |||
6794 | TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, | |||
6795 | ElaboratedTypeLoc TL) { | |||
6796 | const ElaboratedType *T = TL.getTypePtr(); | |||
6797 | ||||
6798 | NestedNameSpecifierLoc QualifierLoc; | |||
6799 | // NOTE: the qualifier in an ElaboratedType is optional. | |||
6800 | if (TL.getQualifierLoc()) { | |||
6801 | QualifierLoc | |||
6802 | = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); | |||
6803 | if (!QualifierLoc) | |||
6804 | return QualType(); | |||
6805 | } | |||
6806 | ||||
6807 | QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc()); | |||
6808 | if (NamedT.isNull()) | |||
6809 | return QualType(); | |||
6810 | ||||
6811 | // C++0x [dcl.type.elab]p2: | |||
6812 | // If the identifier resolves to a typedef-name or the simple-template-id | |||
6813 | // resolves to an alias template specialization, the | |||
6814 | // elaborated-type-specifier is ill-formed. | |||
6815 | if (T->getKeyword() != ETK_None && T->getKeyword() != ETK_Typename) { | |||
6816 | if (const TemplateSpecializationType *TST = | |||
6817 | NamedT->getAs<TemplateSpecializationType>()) { | |||
6818 | TemplateName Template = TST->getTemplateName(); | |||
6819 | if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>( | |||
6820 | Template.getAsTemplateDecl())) { | |||
6821 | SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(), | |||
6822 | diag::err_tag_reference_non_tag) | |||
6823 | << TAT << Sema::NTK_TypeAliasTemplate | |||
6824 | << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()); | |||
6825 | SemaRef.Diag(TAT->getLocation(), diag::note_declared_at); | |||
6826 | } | |||
6827 | } | |||
6828 | } | |||
6829 | ||||
6830 | QualType Result = TL.getType(); | |||
6831 | if (getDerived().AlwaysRebuild() || | |||
6832 | QualifierLoc != TL.getQualifierLoc() || | |||
6833 | NamedT != T->getNamedType()) { | |||
6834 | Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(), | |||
6835 | T->getKeyword(), | |||
6836 | QualifierLoc, NamedT); | |||
6837 | if (Result.isNull()) | |||
6838 | return QualType(); | |||
6839 | } | |||
6840 | ||||
6841 | ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); | |||
6842 | NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); | |||
6843 | NewTL.setQualifierLoc(QualifierLoc); | |||
6844 | return Result; | |||
6845 | } | |||
6846 | ||||
6847 | template<typename Derived> | |||
6848 | QualType TreeTransform<Derived>::TransformAttributedType( | |||
6849 | TypeLocBuilder &TLB, | |||
6850 | AttributedTypeLoc TL) { | |||
6851 | const AttributedType *oldType = TL.getTypePtr(); | |||
6852 | QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc()); | |||
6853 | if (modifiedType.isNull()) | |||
6854 | return QualType(); | |||
6855 | ||||
6856 | // oldAttr can be null if we started with a QualType rather than a TypeLoc. | |||
6857 | const Attr *oldAttr = TL.getAttr(); | |||
6858 | const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr; | |||
6859 | if (oldAttr && !newAttr) | |||
6860 | return QualType(); | |||
6861 | ||||
6862 | QualType result = TL.getType(); | |||
6863 | ||||
6864 | // FIXME: dependent operand expressions? | |||
6865 | if (getDerived().AlwaysRebuild() || | |||
6866 | modifiedType != oldType->getModifiedType()) { | |||
6867 | // TODO: this is really lame; we should really be rebuilding the | |||
6868 | // equivalent type from first principles. | |||
6869 | QualType equivalentType | |||
6870 | = getDerived().TransformType(oldType->getEquivalentType()); | |||
6871 | if (equivalentType.isNull()) | |||
6872 | return QualType(); | |||
6873 | ||||
6874 | // Check whether we can add nullability; it is only represented as | |||
6875 | // type sugar, and therefore cannot be diagnosed in any other way. | |||
6876 | if (auto nullability = oldType->getImmediateNullability()) { | |||
6877 | if (!modifiedType->canHaveNullability()) { | |||
6878 | SemaRef.Diag(TL.getAttr()->getLocation(), | |||
6879 | diag::err_nullability_nonpointer) | |||
6880 | << DiagNullabilityKind(*nullability, false) << modifiedType; | |||
6881 | return QualType(); | |||
6882 | } | |||
6883 | } | |||
6884 | ||||
6885 | result = SemaRef.Context.getAttributedType(TL.getAttrKind(), | |||
6886 | modifiedType, | |||
6887 | equivalentType); | |||
6888 | } | |||
6889 | ||||
6890 | AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result); | |||
6891 | newTL.setAttr(newAttr); | |||
6892 | return result; | |||
6893 | } | |||
6894 | ||||
6895 | template <typename Derived> | |||
6896 | QualType TreeTransform<Derived>::TransformBTFTagAttributedType( | |||
6897 | TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) { | |||
6898 | // The BTFTagAttributedType is available for C only. | |||
6899 | llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType")::llvm::llvm_unreachable_internal("Unexpected TreeTransform for BTFTagAttributedType" , "clang/lib/Sema/TreeTransform.h", 6899); | |||
6900 | } | |||
6901 | ||||
6902 | template<typename Derived> | |||
6903 | QualType | |||
6904 | TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB, | |||
6905 | ParenTypeLoc TL) { | |||
6906 | QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc()); | |||
6907 | if (Inner.isNull()) | |||
6908 | return QualType(); | |||
6909 | ||||
6910 | QualType Result = TL.getType(); | |||
6911 | if (getDerived().AlwaysRebuild() || | |||
6912 | Inner != TL.getInnerLoc().getType()) { | |||
6913 | Result = getDerived().RebuildParenType(Inner); | |||
6914 | if (Result.isNull()) | |||
6915 | return QualType(); | |||
6916 | } | |||
6917 | ||||
6918 | ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result); | |||
6919 | NewTL.setLParenLoc(TL.getLParenLoc()); | |||
6920 | NewTL.setRParenLoc(TL.getRParenLoc()); | |||
6921 | return Result; | |||
6922 | } | |||
6923 | ||||
6924 | template <typename Derived> | |||
6925 | QualType | |||
6926 | TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB, | |||
6927 | MacroQualifiedTypeLoc TL) { | |||
6928 | QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc()); | |||
6929 | if (Inner.isNull()) | |||
6930 | return QualType(); | |||
6931 | ||||
6932 | QualType Result = TL.getType(); | |||
6933 | if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) { | |||
6934 | Result = | |||
6935 | getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier()); | |||
6936 | if (Result.isNull()) | |||
6937 | return QualType(); | |||
6938 | } | |||
6939 | ||||
6940 | MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result); | |||
6941 | NewTL.setExpansionLoc(TL.getExpansionLoc()); | |||
6942 | return Result; | |||
6943 | } | |||
6944 | ||||
6945 | template<typename Derived> | |||
6946 | QualType TreeTransform<Derived>::TransformDependentNameType( | |||
6947 | TypeLocBuilder &TLB, DependentNameTypeLoc TL) { | |||
6948 | return TransformDependentNameType(TLB, TL, false); | |||
6949 | } | |||
6950 | ||||
6951 | template<typename Derived> | |||
6952 | QualType TreeTransform<Derived>::TransformDependentNameType( | |||
6953 | TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) { | |||
6954 | const DependentNameType *T = TL.getTypePtr(); | |||
6955 | ||||
6956 | NestedNameSpecifierLoc QualifierLoc | |||
6957 | = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); | |||
6958 | if (!QualifierLoc) | |||
6959 | return QualType(); | |||
6960 | ||||
6961 | QualType Result | |||
6962 | = getDerived().RebuildDependentNameType(T->getKeyword(), | |||
6963 | TL.getElaboratedKeywordLoc(), | |||
6964 | QualifierLoc, | |||
6965 | T->getIdentifier(), | |||
6966 | TL.getNameLoc(), | |||
6967 | DeducedTSTContext); | |||
6968 | if (Result.isNull()) | |||
6969 | return QualType(); | |||
6970 | ||||
6971 | if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) { | |||
6972 | QualType NamedT = ElabT->getNamedType(); | |||
6973 | TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); | |||
6974 | ||||
6975 | ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); | |||
6976 | NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); | |||
6977 | NewTL.setQualifierLoc(QualifierLoc); | |||
6978 | } else { | |||
6979 | DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); | |||
6980 | NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); | |||
6981 | NewTL.setQualifierLoc(QualifierLoc); | |||
6982 | NewTL.setNameLoc(TL.getNameLoc()); | |||
6983 | } | |||
6984 | return Result; | |||
6985 | } | |||
6986 | ||||
6987 | template<typename Derived> | |||
6988 | QualType TreeTransform<Derived>:: | |||
6989 | TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, | |||
6990 | DependentTemplateSpecializationTypeLoc TL) { | |||
6991 | NestedNameSpecifierLoc QualifierLoc; | |||
6992 | if (TL.getQualifierLoc()) { | |||
6993 | QualifierLoc | |||
6994 | = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); | |||
6995 | if (!QualifierLoc) | |||
6996 | return QualType(); | |||
6997 | } | |||
6998 | ||||
6999 | return getDerived() | |||
7000 | .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc); | |||
7001 | } | |||
7002 | ||||
7003 | template<typename Derived> | |||
7004 | QualType TreeTransform<Derived>:: | |||
7005 | TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, | |||
7006 | DependentTemplateSpecializationTypeLoc TL, | |||
7007 | NestedNameSpecifierLoc QualifierLoc) { | |||
7008 | const DependentTemplateSpecializationType *T = TL.getTypePtr(); | |||
7009 | ||||
7010 | TemplateArgumentListInfo NewTemplateArgs; | |||
7011 | NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); | |||
7012 | NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); | |||
7013 | ||||
7014 | typedef TemplateArgumentLocContainerIterator< | |||
7015 | DependentTemplateSpecializationTypeLoc> ArgIterator; | |||
7016 | if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), | |||
7017 | ArgIterator(TL, TL.getNumArgs()), | |||
7018 | NewTemplateArgs)) | |||
7019 | return QualType(); | |||
7020 | ||||
7021 | QualType Result = getDerived().RebuildDependentTemplateSpecializationType( | |||
7022 | T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(), | |||
7023 | T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs, | |||
7024 | /*AllowInjectedClassName*/ false); | |||
7025 | if (Result.isNull()) | |||
7026 | return QualType(); | |||
7027 | ||||
7028 | if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) { | |||
7029 | QualType NamedT = ElabT->getNamedType(); | |||
7030 | ||||
7031 | // Copy information relevant to the template specialization. | |||
7032 | TemplateSpecializationTypeLoc NamedTL | |||
7033 | = TLB.push<TemplateSpecializationTypeLoc>(NamedT); | |||
7034 | NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); | |||
7035 | NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
7036 | NamedTL.setLAngleLoc(TL.getLAngleLoc()); | |||
7037 | NamedTL.setRAngleLoc(TL.getRAngleLoc()); | |||
7038 | for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) | |||
7039 | NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); | |||
7040 | ||||
7041 | // Copy information relevant to the elaborated type. | |||
7042 | ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); | |||
7043 | NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); | |||
7044 | NewTL.setQualifierLoc(QualifierLoc); | |||
7045 | } else if (isa<DependentTemplateSpecializationType>(Result)) { | |||
7046 | DependentTemplateSpecializationTypeLoc SpecTL | |||
7047 | = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); | |||
7048 | SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); | |||
7049 | SpecTL.setQualifierLoc(QualifierLoc); | |||
7050 | SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); | |||
7051 | SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
7052 | SpecTL.setLAngleLoc(TL.getLAngleLoc()); | |||
7053 | SpecTL.setRAngleLoc(TL.getRAngleLoc()); | |||
7054 | for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) | |||
7055 | SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); | |||
7056 | } else { | |||
7057 | TemplateSpecializationTypeLoc SpecTL | |||
7058 | = TLB.push<TemplateSpecializationTypeLoc>(Result); | |||
7059 | SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); | |||
7060 | SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); | |||
7061 | SpecTL.setLAngleLoc(TL.getLAngleLoc()); | |||
7062 | SpecTL.setRAngleLoc(TL.getRAngleLoc()); | |||
7063 | for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) | |||
7064 | SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); | |||
7065 | } | |||
7066 | return Result; | |||
7067 | } | |||
7068 | ||||
7069 | template<typename Derived> | |||
7070 | QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB, | |||
7071 | PackExpansionTypeLoc TL) { | |||
7072 | QualType Pattern | |||
7073 | = getDerived().TransformType(TLB, TL.getPatternLoc()); | |||
7074 | if (Pattern.isNull()) | |||
7075 | return QualType(); | |||
7076 | ||||
7077 | QualType Result = TL.getType(); | |||
7078 | if (getDerived().AlwaysRebuild() || | |||
7079 | Pattern != TL.getPatternLoc().getType()) { | |||
7080 | Result = getDerived().RebuildPackExpansionType(Pattern, | |||
7081 | TL.getPatternLoc().getSourceRange(), | |||
7082 | TL.getEllipsisLoc(), | |||
7083 | TL.getTypePtr()->getNumExpansions()); | |||
7084 | if (Result.isNull()) | |||
7085 | return QualType(); | |||
7086 | } | |||
7087 | ||||
7088 | PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result); | |||
7089 | NewT.setEllipsisLoc(TL.getEllipsisLoc()); | |||
7090 | return Result; | |||
7091 | } | |||
7092 | ||||
7093 | template<typename Derived> | |||
7094 | QualType | |||
7095 | TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB, | |||
7096 | ObjCInterfaceTypeLoc TL) { | |||
7097 | // ObjCInterfaceType is never dependent. | |||
7098 | TLB.pushFullCopy(TL); | |||
7099 | return TL.getType(); | |||
7100 | } | |||
7101 | ||||
7102 | template<typename Derived> | |||
7103 | QualType | |||
7104 | TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB, | |||
7105 | ObjCTypeParamTypeLoc TL) { | |||
7106 | const ObjCTypeParamType *T = TL.getTypePtr(); | |||
7107 | ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>( | |||
7108 | getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl())); | |||
7109 | if (!OTP) | |||
7110 | return QualType(); | |||
7111 | ||||
7112 | QualType Result = TL.getType(); | |||
7113 | if (getDerived().AlwaysRebuild() || | |||
7114 | OTP != T->getDecl()) { | |||
7115 | Result = getDerived().RebuildObjCTypeParamType(OTP, | |||
7116 | TL.getProtocolLAngleLoc(), | |||
7117 | llvm::makeArrayRef(TL.getTypePtr()->qual_begin(), | |||
7118 | TL.getNumProtocols()), | |||
7119 | TL.getProtocolLocs(), | |||
7120 | TL.getProtocolRAngleLoc()); | |||
7121 | if (Result.isNull()) | |||
7122 | return QualType(); | |||
7123 | } | |||
7124 | ||||
7125 | ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result); | |||
7126 | if (TL.getNumProtocols()) { | |||
7127 | NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc()); | |||
7128 | for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i) | |||
7129 | NewTL.setProtocolLoc(i, TL.getProtocolLoc(i)); | |||
7130 | NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc()); | |||
7131 | } | |||
7132 | return Result; | |||
7133 | } | |||
7134 | ||||
7135 | template<typename Derived> | |||
7136 | QualType | |||
7137 | TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB, | |||
7138 | ObjCObjectTypeLoc TL) { | |||
7139 | // Transform base type. | |||
7140 | QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc()); | |||
7141 | if (BaseType.isNull()) | |||
7142 | return QualType(); | |||
7143 | ||||
7144 | bool AnyChanged = BaseType != TL.getBaseLoc().getType(); | |||
7145 | ||||
7146 | // Transform type arguments. | |||
7147 | SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos; | |||
7148 | for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) { | |||
7149 | TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i); | |||
7150 | TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc(); | |||
7151 | QualType TypeArg = TypeArgInfo->getType(); | |||
7152 | if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) { | |||
7153 | AnyChanged = true; | |||
7154 | ||||
7155 | // We have a pack expansion. Instantiate it. | |||
7156 | const auto *PackExpansion = PackExpansionLoc.getType() | |||
7157 | ->castAs<PackExpansionType>(); | |||
7158 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
7159 | SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), | |||
7160 | Unexpanded); | |||
7161 | assert(!Unexpanded.empty() && "Pack expansion without parameter packs?")(static_cast <bool> (!Unexpanded.empty() && "Pack expansion without parameter packs?" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Pack expansion without parameter packs?\"" , "clang/lib/Sema/TreeTransform.h", 7161, __extension__ __PRETTY_FUNCTION__ )); | |||
7162 | ||||
7163 | // Determine whether the set of unexpanded parameter packs can | |||
7164 | // and should be expanded. | |||
7165 | TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc(); | |||
7166 | bool Expand = false; | |||
7167 | bool RetainExpansion = false; | |||
7168 | Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); | |||
7169 | if (getDerived().TryExpandParameterPacks( | |||
7170 | PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(), | |||
7171 | Unexpanded, Expand, RetainExpansion, NumExpansions)) | |||
7172 | return QualType(); | |||
7173 | ||||
7174 | if (!Expand) { | |||
7175 | // We can't expand this pack expansion into separate arguments yet; | |||
7176 | // just substitute into the pattern and create a new pack expansion | |||
7177 | // type. | |||
7178 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
7179 | ||||
7180 | TypeLocBuilder TypeArgBuilder; | |||
7181 | TypeArgBuilder.reserve(PatternLoc.getFullDataSize()); | |||
7182 | QualType NewPatternType = getDerived().TransformType(TypeArgBuilder, | |||
7183 | PatternLoc); | |||
7184 | if (NewPatternType.isNull()) | |||
7185 | return QualType(); | |||
7186 | ||||
7187 | QualType NewExpansionType = SemaRef.Context.getPackExpansionType( | |||
7188 | NewPatternType, NumExpansions); | |||
7189 | auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType); | |||
7190 | NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc()); | |||
7191 | NewTypeArgInfos.push_back( | |||
7192 | TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType)); | |||
7193 | continue; | |||
7194 | } | |||
7195 | ||||
7196 | // Substitute into the pack expansion pattern for each slice of the | |||
7197 | // pack. | |||
7198 | for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { | |||
7199 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx); | |||
7200 | ||||
7201 | TypeLocBuilder TypeArgBuilder; | |||
7202 | TypeArgBuilder.reserve(PatternLoc.getFullDataSize()); | |||
7203 | ||||
7204 | QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder, | |||
7205 | PatternLoc); | |||
7206 | if (NewTypeArg.isNull()) | |||
7207 | return QualType(); | |||
7208 | ||||
7209 | NewTypeArgInfos.push_back( | |||
7210 | TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg)); | |||
7211 | } | |||
7212 | ||||
7213 | continue; | |||
7214 | } | |||
7215 | ||||
7216 | TypeLocBuilder TypeArgBuilder; | |||
7217 | TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize()); | |||
7218 | QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder, TypeArgLoc); | |||
7219 | if (NewTypeArg.isNull()) | |||
7220 | return QualType(); | |||
7221 | ||||
7222 | // If nothing changed, just keep the old TypeSourceInfo. | |||
7223 | if (NewTypeArg == TypeArg) { | |||
7224 | NewTypeArgInfos.push_back(TypeArgInfo); | |||
7225 | continue; | |||
7226 | } | |||
7227 | ||||
7228 | NewTypeArgInfos.push_back( | |||
7229 | TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg)); | |||
7230 | AnyChanged = true; | |||
7231 | } | |||
7232 | ||||
7233 | QualType Result = TL.getType(); | |||
7234 | if (getDerived().AlwaysRebuild() || AnyChanged) { | |||
7235 | // Rebuild the type. | |||
7236 | Result = getDerived().RebuildObjCObjectType( | |||
7237 | BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos, | |||
7238 | TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(), | |||
7239 | llvm::makeArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()), | |||
7240 | TL.getProtocolLocs(), TL.getProtocolRAngleLoc()); | |||
7241 | ||||
7242 | if (Result.isNull()) | |||
7243 | return QualType(); | |||
7244 | } | |||
7245 | ||||
7246 | ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result); | |||
7247 | NewT.setHasBaseTypeAsWritten(true); | |||
7248 | NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc()); | |||
7249 | for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) | |||
7250 | NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]); | |||
7251 | NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc()); | |||
7252 | NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc()); | |||
7253 | for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i) | |||
7254 | NewT.setProtocolLoc(i, TL.getProtocolLoc(i)); | |||
7255 | NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc()); | |||
7256 | return Result; | |||
7257 | } | |||
7258 | ||||
7259 | template<typename Derived> | |||
7260 | QualType | |||
7261 | TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB, | |||
7262 | ObjCObjectPointerTypeLoc TL) { | |||
7263 | QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); | |||
7264 | if (PointeeType.isNull()) | |||
7265 | return QualType(); | |||
7266 | ||||
7267 | QualType Result = TL.getType(); | |||
7268 | if (getDerived().AlwaysRebuild() || | |||
7269 | PointeeType != TL.getPointeeLoc().getType()) { | |||
7270 | Result = getDerived().RebuildObjCObjectPointerType(PointeeType, | |||
7271 | TL.getStarLoc()); | |||
7272 | if (Result.isNull()) | |||
7273 | return QualType(); | |||
7274 | } | |||
7275 | ||||
7276 | ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result); | |||
7277 | NewT.setStarLoc(TL.getStarLoc()); | |||
7278 | return Result; | |||
7279 | } | |||
7280 | ||||
7281 | //===----------------------------------------------------------------------===// | |||
7282 | // Statement transformation | |||
7283 | //===----------------------------------------------------------------------===// | |||
7284 | template<typename Derived> | |||
7285 | StmtResult | |||
7286 | TreeTransform<Derived>::TransformNullStmt(NullStmt *S) { | |||
7287 | return S; | |||
7288 | } | |||
7289 | ||||
7290 | template<typename Derived> | |||
7291 | StmtResult | |||
7292 | TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) { | |||
7293 | return getDerived().TransformCompoundStmt(S, false); | |||
7294 | } | |||
7295 | ||||
7296 | template<typename Derived> | |||
7297 | StmtResult | |||
7298 | TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S, | |||
7299 | bool IsStmtExpr) { | |||
7300 | Sema::CompoundScopeRAII CompoundScope(getSema()); | |||
7301 | ||||
7302 | const Stmt *ExprResult = S->getStmtExprResult(); | |||
7303 | bool SubStmtInvalid = false; | |||
7304 | bool SubStmtChanged = false; | |||
7305 | SmallVector<Stmt*, 8> Statements; | |||
7306 | for (auto *B : S->body()) { | |||
7307 | StmtResult Result = getDerived().TransformStmt( | |||
7308 | B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded); | |||
7309 | ||||
7310 | if (Result.isInvalid()) { | |||
7311 | // Immediately fail if this was a DeclStmt, since it's very | |||
7312 | // likely that this will cause problems for future statements. | |||
7313 | if (isa<DeclStmt>(B)) | |||
7314 | return StmtError(); | |||
7315 | ||||
7316 | // Otherwise, just keep processing substatements and fail later. | |||
7317 | SubStmtInvalid = true; | |||
7318 | continue; | |||
7319 | } | |||
7320 | ||||
7321 | SubStmtChanged = SubStmtChanged || Result.get() != B; | |||
7322 | Statements.push_back(Result.getAs<Stmt>()); | |||
7323 | } | |||
7324 | ||||
7325 | if (SubStmtInvalid) | |||
7326 | return StmtError(); | |||
7327 | ||||
7328 | if (!getDerived().AlwaysRebuild() && | |||
7329 | !SubStmtChanged) | |||
7330 | return S; | |||
7331 | ||||
7332 | return getDerived().RebuildCompoundStmt(S->getLBracLoc(), | |||
7333 | Statements, | |||
7334 | S->getRBracLoc(), | |||
7335 | IsStmtExpr); | |||
7336 | } | |||
7337 | ||||
7338 | template<typename Derived> | |||
7339 | StmtResult | |||
7340 | TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) { | |||
7341 | ExprResult LHS, RHS; | |||
7342 | { | |||
7343 | EnterExpressionEvaluationContext Unevaluated( | |||
7344 | SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
7345 | ||||
7346 | // Transform the left-hand case value. | |||
7347 | LHS = getDerived().TransformExpr(S->getLHS()); | |||
7348 | LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS); | |||
7349 | if (LHS.isInvalid()) | |||
7350 | return StmtError(); | |||
7351 | ||||
7352 | // Transform the right-hand case value (for the GNU case-range extension). | |||
7353 | RHS = getDerived().TransformExpr(S->getRHS()); | |||
7354 | RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS); | |||
7355 | if (RHS.isInvalid()) | |||
7356 | return StmtError(); | |||
7357 | } | |||
7358 | ||||
7359 | // Build the case statement. | |||
7360 | // Case statements are always rebuilt so that they will attached to their | |||
7361 | // transformed switch statement. | |||
7362 | StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(), | |||
7363 | LHS.get(), | |||
7364 | S->getEllipsisLoc(), | |||
7365 | RHS.get(), | |||
7366 | S->getColonLoc()); | |||
7367 | if (Case.isInvalid()) | |||
7368 | return StmtError(); | |||
7369 | ||||
7370 | // Transform the statement following the case | |||
7371 | StmtResult SubStmt = | |||
7372 | getDerived().TransformStmt(S->getSubStmt()); | |||
7373 | if (SubStmt.isInvalid()) | |||
7374 | return StmtError(); | |||
7375 | ||||
7376 | // Attach the body to the case statement | |||
7377 | return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get()); | |||
7378 | } | |||
7379 | ||||
7380 | template <typename Derived> | |||
7381 | StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) { | |||
7382 | // Transform the statement following the default case | |||
7383 | StmtResult SubStmt = | |||
7384 | getDerived().TransformStmt(S->getSubStmt()); | |||
7385 | if (SubStmt.isInvalid()) | |||
7386 | return StmtError(); | |||
7387 | ||||
7388 | // Default statements are always rebuilt | |||
7389 | return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(), | |||
7390 | SubStmt.get()); | |||
7391 | } | |||
7392 | ||||
7393 | template<typename Derived> | |||
7394 | StmtResult | |||
7395 | TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) { | |||
7396 | StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK); | |||
7397 | if (SubStmt.isInvalid()) | |||
7398 | return StmtError(); | |||
7399 | ||||
7400 | Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(), | |||
7401 | S->getDecl()); | |||
7402 | if (!LD) | |||
7403 | return StmtError(); | |||
7404 | ||||
7405 | // If we're transforming "in-place" (we're not creating new local | |||
7406 | // declarations), assume we're replacing the old label statement | |||
7407 | // and clear out the reference to it. | |||
7408 | if (LD == S->getDecl()) | |||
7409 | S->getDecl()->setStmt(nullptr); | |||
7410 | ||||
7411 | // FIXME: Pass the real colon location in. | |||
7412 | return getDerived().RebuildLabelStmt(S->getIdentLoc(), | |||
7413 | cast<LabelDecl>(LD), SourceLocation(), | |||
7414 | SubStmt.get()); | |||
7415 | } | |||
7416 | ||||
7417 | template <typename Derived> | |||
7418 | const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) { | |||
7419 | if (!R) | |||
7420 | return R; | |||
7421 | ||||
7422 | switch (R->getKind()) { | |||
7423 | // Transform attributes with a pragma spelling by calling TransformXXXAttr. | |||
7424 | #define ATTR(X) | |||
7425 | #define PRAGMA_SPELLING_ATTR(X) \ | |||
7426 | case attr::X: \ | |||
7427 | return getDerived().Transform##X##Attr(cast<X##Attr>(R)); | |||
7428 | #include "clang/Basic/AttrList.inc" | |||
7429 | default: | |||
7430 | return R; | |||
7431 | } | |||
7432 | } | |||
7433 | ||||
7434 | template <typename Derived> | |||
7435 | StmtResult | |||
7436 | TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S, | |||
7437 | StmtDiscardKind SDK) { | |||
7438 | bool AttrsChanged = false; | |||
7439 | SmallVector<const Attr *, 1> Attrs; | |||
7440 | ||||
7441 | // Visit attributes and keep track if any are transformed. | |||
7442 | for (const auto *I : S->getAttrs()) { | |||
7443 | const Attr *R = getDerived().TransformAttr(I); | |||
7444 | AttrsChanged |= (I != R); | |||
7445 | if (R) | |||
7446 | Attrs.push_back(R); | |||
7447 | } | |||
7448 | ||||
7449 | StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK); | |||
7450 | if (SubStmt.isInvalid()) | |||
7451 | return StmtError(); | |||
7452 | ||||
7453 | if (SubStmt.get() == S->getSubStmt() && !AttrsChanged) | |||
7454 | return S; | |||
7455 | ||||
7456 | // If transforming the attributes failed for all of the attributes in the | |||
7457 | // statement, don't make an AttributedStmt without attributes. | |||
7458 | if (Attrs.empty()) | |||
7459 | return SubStmt; | |||
7460 | ||||
7461 | return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs, | |||
7462 | SubStmt.get()); | |||
7463 | } | |||
7464 | ||||
7465 | template<typename Derived> | |||
7466 | StmtResult | |||
7467 | TreeTransform<Derived>::TransformIfStmt(IfStmt *S) { | |||
7468 | // Transform the initialization statement | |||
7469 | StmtResult Init = getDerived().TransformStmt(S->getInit()); | |||
7470 | if (Init.isInvalid()) | |||
7471 | return StmtError(); | |||
7472 | ||||
7473 | Sema::ConditionResult Cond; | |||
7474 | if (!S->isConsteval()) { | |||
7475 | // Transform the condition | |||
7476 | Cond = getDerived().TransformCondition( | |||
7477 | S->getIfLoc(), S->getConditionVariable(), S->getCond(), | |||
7478 | S->isConstexpr() ? Sema::ConditionKind::ConstexprIf | |||
7479 | : Sema::ConditionKind::Boolean); | |||
7480 | if (Cond.isInvalid()) | |||
7481 | return StmtError(); | |||
7482 | } | |||
7483 | ||||
7484 | // If this is a constexpr if, determine which arm we should instantiate. | |||
7485 | llvm::Optional<bool> ConstexprConditionValue; | |||
7486 | if (S->isConstexpr()) | |||
7487 | ConstexprConditionValue = Cond.getKnownValue(); | |||
7488 | ||||
7489 | // Transform the "then" branch. | |||
7490 | StmtResult Then; | |||
7491 | if (!ConstexprConditionValue || *ConstexprConditionValue) { | |||
7492 | Then = getDerived().TransformStmt(S->getThen()); | |||
7493 | if (Then.isInvalid()) | |||
7494 | return StmtError(); | |||
7495 | } else { | |||
7496 | Then = new (getSema().Context) NullStmt(S->getThen()->getBeginLoc()); | |||
7497 | } | |||
7498 | ||||
7499 | // Transform the "else" branch. | |||
7500 | StmtResult Else; | |||
7501 | if (!ConstexprConditionValue || !*ConstexprConditionValue) { | |||
7502 | Else = getDerived().TransformStmt(S->getElse()); | |||
7503 | if (Else.isInvalid()) | |||
7504 | return StmtError(); | |||
7505 | } | |||
7506 | ||||
7507 | if (!getDerived().AlwaysRebuild() && | |||
7508 | Init.get() == S->getInit() && | |||
7509 | Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) && | |||
7510 | Then.get() == S->getThen() && | |||
7511 | Else.get() == S->getElse()) | |||
7512 | return S; | |||
7513 | ||||
7514 | return getDerived().RebuildIfStmt( | |||
7515 | S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond, | |||
7516 | S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get()); | |||
7517 | } | |||
7518 | ||||
7519 | template<typename Derived> | |||
7520 | StmtResult | |||
7521 | TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) { | |||
7522 | // Transform the initialization statement | |||
7523 | StmtResult Init = getDerived().TransformStmt(S->getInit()); | |||
7524 | if (Init.isInvalid()) | |||
7525 | return StmtError(); | |||
7526 | ||||
7527 | // Transform the condition. | |||
7528 | Sema::ConditionResult Cond = getDerived().TransformCondition( | |||
7529 | S->getSwitchLoc(), S->getConditionVariable(), S->getCond(), | |||
7530 | Sema::ConditionKind::Switch); | |||
7531 | if (Cond.isInvalid()) | |||
7532 | return StmtError(); | |||
7533 | ||||
7534 | // Rebuild the switch statement. | |||
7535 | StmtResult Switch = | |||
7536 | getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(), | |||
7537 | Init.get(), Cond, S->getRParenLoc()); | |||
7538 | if (Switch.isInvalid()) | |||
7539 | return StmtError(); | |||
7540 | ||||
7541 | // Transform the body of the switch statement. | |||
7542 | StmtResult Body = getDerived().TransformStmt(S->getBody()); | |||
7543 | if (Body.isInvalid()) | |||
7544 | return StmtError(); | |||
7545 | ||||
7546 | // Complete the switch statement. | |||
7547 | return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(), | |||
7548 | Body.get()); | |||
7549 | } | |||
7550 | ||||
7551 | template<typename Derived> | |||
7552 | StmtResult | |||
7553 | TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) { | |||
7554 | // Transform the condition | |||
7555 | Sema::ConditionResult Cond = getDerived().TransformCondition( | |||
7556 | S->getWhileLoc(), S->getConditionVariable(), S->getCond(), | |||
7557 | Sema::ConditionKind::Boolean); | |||
7558 | if (Cond.isInvalid()) | |||
7559 | return StmtError(); | |||
7560 | ||||
7561 | // Transform the body | |||
7562 | StmtResult Body = getDerived().TransformStmt(S->getBody()); | |||
7563 | if (Body.isInvalid()) | |||
7564 | return StmtError(); | |||
7565 | ||||
7566 | if (!getDerived().AlwaysRebuild() && | |||
7567 | Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) && | |||
7568 | Body.get() == S->getBody()) | |||
7569 | return Owned(S); | |||
7570 | ||||
7571 | return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(), | |||
7572 | Cond, S->getRParenLoc(), Body.get()); | |||
7573 | } | |||
7574 | ||||
7575 | template<typename Derived> | |||
7576 | StmtResult | |||
7577 | TreeTransform<Derived>::TransformDoStmt(DoStmt *S) { | |||
7578 | // Transform the body | |||
7579 | StmtResult Body = getDerived().TransformStmt(S->getBody()); | |||
7580 | if (Body.isInvalid()) | |||
7581 | return StmtError(); | |||
7582 | ||||
7583 | // Transform the condition | |||
7584 | ExprResult Cond = getDerived().TransformExpr(S->getCond()); | |||
7585 | if (Cond.isInvalid()) | |||
7586 | return StmtError(); | |||
7587 | ||||
7588 | if (!getDerived().AlwaysRebuild() && | |||
7589 | Cond.get() == S->getCond() && | |||
7590 | Body.get() == S->getBody()) | |||
7591 | return S; | |||
7592 | ||||
7593 | return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(), | |||
7594 | /*FIXME:*/S->getWhileLoc(), Cond.get(), | |||
7595 | S->getRParenLoc()); | |||
7596 | } | |||
7597 | ||||
7598 | template<typename Derived> | |||
7599 | StmtResult | |||
7600 | TreeTransform<Derived>::TransformForStmt(ForStmt *S) { | |||
7601 | if (getSema().getLangOpts().OpenMP) | |||
7602 | getSema().startOpenMPLoop(); | |||
7603 | ||||
7604 | // Transform the initialization statement | |||
7605 | StmtResult Init = getDerived().TransformStmt(S->getInit()); | |||
7606 | if (Init.isInvalid()) | |||
7607 | return StmtError(); | |||
7608 | ||||
7609 | // In OpenMP loop region loop control variable must be captured and be | |||
7610 | // private. Perform analysis of first part (if any). | |||
7611 | if (getSema().getLangOpts().OpenMP && Init.isUsable()) | |||
7612 | getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get()); | |||
7613 | ||||
7614 | // Transform the condition | |||
7615 | Sema::ConditionResult Cond = getDerived().TransformCondition( | |||
7616 | S->getForLoc(), S->getConditionVariable(), S->getCond(), | |||
7617 | Sema::ConditionKind::Boolean); | |||
7618 | if (Cond.isInvalid()) | |||
7619 | return StmtError(); | |||
7620 | ||||
7621 | // Transform the increment | |||
7622 | ExprResult Inc = getDerived().TransformExpr(S->getInc()); | |||
7623 | if (Inc.isInvalid()) | |||
7624 | return StmtError(); | |||
7625 | ||||
7626 | Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get())); | |||
7627 | if (S->getInc() && !FullInc.get()) | |||
7628 | return StmtError(); | |||
7629 | ||||
7630 | // Transform the body | |||
7631 | StmtResult Body = getDerived().TransformStmt(S->getBody()); | |||
7632 | if (Body.isInvalid()) | |||
7633 | return StmtError(); | |||
7634 | ||||
7635 | if (!getDerived().AlwaysRebuild() && | |||
7636 | Init.get() == S->getInit() && | |||
7637 | Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) && | |||
7638 | Inc.get() == S->getInc() && | |||
7639 | Body.get() == S->getBody()) | |||
7640 | return S; | |||
7641 | ||||
7642 | return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(), | |||
7643 | Init.get(), Cond, FullInc, | |||
7644 | S->getRParenLoc(), Body.get()); | |||
7645 | } | |||
7646 | ||||
7647 | template<typename Derived> | |||
7648 | StmtResult | |||
7649 | TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) { | |||
7650 | Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(), | |||
7651 | S->getLabel()); | |||
7652 | if (!LD) | |||
7653 | return StmtError(); | |||
7654 | ||||
7655 | // Goto statements must always be rebuilt, to resolve the label. | |||
7656 | return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(), | |||
7657 | cast<LabelDecl>(LD)); | |||
7658 | } | |||
7659 | ||||
7660 | template<typename Derived> | |||
7661 | StmtResult | |||
7662 | TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) { | |||
7663 | ExprResult Target = getDerived().TransformExpr(S->getTarget()); | |||
7664 | if (Target.isInvalid()) | |||
7665 | return StmtError(); | |||
7666 | Target = SemaRef.MaybeCreateExprWithCleanups(Target.get()); | |||
7667 | ||||
7668 | if (!getDerived().AlwaysRebuild() && | |||
7669 | Target.get() == S->getTarget()) | |||
7670 | return S; | |||
7671 | ||||
7672 | return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(), | |||
7673 | Target.get()); | |||
7674 | } | |||
7675 | ||||
7676 | template<typename Derived> | |||
7677 | StmtResult | |||
7678 | TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) { | |||
7679 | return S; | |||
7680 | } | |||
7681 | ||||
7682 | template<typename Derived> | |||
7683 | StmtResult | |||
7684 | TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) { | |||
7685 | return S; | |||
7686 | } | |||
7687 | ||||
7688 | template<typename Derived> | |||
7689 | StmtResult | |||
7690 | TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) { | |||
7691 | ExprResult Result = getDerived().TransformInitializer(S->getRetValue(), | |||
7692 | /*NotCopyInit*/false); | |||
7693 | if (Result.isInvalid()) | |||
7694 | return StmtError(); | |||
7695 | ||||
7696 | // FIXME: We always rebuild the return statement because there is no way | |||
7697 | // to tell whether the return type of the function has changed. | |||
7698 | return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get()); | |||
7699 | } | |||
7700 | ||||
7701 | template<typename Derived> | |||
7702 | StmtResult | |||
7703 | TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) { | |||
7704 | bool DeclChanged = false; | |||
7705 | SmallVector<Decl *, 4> Decls; | |||
7706 | for (auto *D : S->decls()) { | |||
7707 | Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D); | |||
7708 | if (!Transformed) | |||
7709 | return StmtError(); | |||
7710 | ||||
7711 | if (Transformed != D) | |||
7712 | DeclChanged = true; | |||
7713 | ||||
7714 | Decls.push_back(Transformed); | |||
7715 | } | |||
7716 | ||||
7717 | if (!getDerived().AlwaysRebuild() && !DeclChanged) | |||
7718 | return S; | |||
7719 | ||||
7720 | return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc()); | |||
7721 | } | |||
7722 | ||||
7723 | template<typename Derived> | |||
7724 | StmtResult | |||
7725 | TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) { | |||
7726 | ||||
7727 | SmallVector<Expr*, 8> Constraints; | |||
7728 | SmallVector<Expr*, 8> Exprs; | |||
7729 | SmallVector<IdentifierInfo *, 4> Names; | |||
7730 | ||||
7731 | ExprResult AsmString; | |||
7732 | SmallVector<Expr*, 8> Clobbers; | |||
7733 | ||||
7734 | bool ExprsChanged = false; | |||
7735 | ||||
7736 | // Go through the outputs. | |||
7737 | for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) { | |||
7738 | Names.push_back(S->getOutputIdentifier(I)); | |||
7739 | ||||
7740 | // No need to transform the constraint literal. | |||
7741 | Constraints.push_back(S->getOutputConstraintLiteral(I)); | |||
7742 | ||||
7743 | // Transform the output expr. | |||
7744 | Expr *OutputExpr = S->getOutputExpr(I); | |||
7745 | ExprResult Result = getDerived().TransformExpr(OutputExpr); | |||
7746 | if (Result.isInvalid()) | |||
7747 | return StmtError(); | |||
7748 | ||||
7749 | ExprsChanged |= Result.get() != OutputExpr; | |||
7750 | ||||
7751 | Exprs.push_back(Result.get()); | |||
7752 | } | |||
7753 | ||||
7754 | // Go through the inputs. | |||
7755 | for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) { | |||
7756 | Names.push_back(S->getInputIdentifier(I)); | |||
7757 | ||||
7758 | // No need to transform the constraint literal. | |||
7759 | Constraints.push_back(S->getInputConstraintLiteral(I)); | |||
7760 | ||||
7761 | // Transform the input expr. | |||
7762 | Expr *InputExpr = S->getInputExpr(I); | |||
7763 | ExprResult Result = getDerived().TransformExpr(InputExpr); | |||
7764 | if (Result.isInvalid()) | |||
7765 | return StmtError(); | |||
7766 | ||||
7767 | ExprsChanged |= Result.get() != InputExpr; | |||
7768 | ||||
7769 | Exprs.push_back(Result.get()); | |||
7770 | } | |||
7771 | ||||
7772 | // Go through the Labels. | |||
7773 | for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) { | |||
7774 | Names.push_back(S->getLabelIdentifier(I)); | |||
7775 | ||||
7776 | ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I)); | |||
7777 | if (Result.isInvalid()) | |||
7778 | return StmtError(); | |||
7779 | ExprsChanged |= Result.get() != S->getLabelExpr(I); | |||
7780 | Exprs.push_back(Result.get()); | |||
7781 | } | |||
7782 | if (!getDerived().AlwaysRebuild() && !ExprsChanged) | |||
7783 | return S; | |||
7784 | ||||
7785 | // Go through the clobbers. | |||
7786 | for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) | |||
7787 | Clobbers.push_back(S->getClobberStringLiteral(I)); | |||
7788 | ||||
7789 | // No need to transform the asm string literal. | |||
7790 | AsmString = S->getAsmString(); | |||
7791 | return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(), | |||
7792 | S->isVolatile(), S->getNumOutputs(), | |||
7793 | S->getNumInputs(), Names.data(), | |||
7794 | Constraints, Exprs, AsmString.get(), | |||
7795 | Clobbers, S->getNumLabels(), | |||
7796 | S->getRParenLoc()); | |||
7797 | } | |||
7798 | ||||
7799 | template<typename Derived> | |||
7800 | StmtResult | |||
7801 | TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) { | |||
7802 | ArrayRef<Token> AsmToks = | |||
7803 | llvm::makeArrayRef(S->getAsmToks(), S->getNumAsmToks()); | |||
7804 | ||||
7805 | bool HadError = false, HadChange = false; | |||
7806 | ||||
7807 | ArrayRef<Expr*> SrcExprs = S->getAllExprs(); | |||
7808 | SmallVector<Expr*, 8> TransformedExprs; | |||
7809 | TransformedExprs.reserve(SrcExprs.size()); | |||
7810 | for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) { | |||
7811 | ExprResult Result = getDerived().TransformExpr(SrcExprs[i]); | |||
7812 | if (!Result.isUsable()) { | |||
7813 | HadError = true; | |||
7814 | } else { | |||
7815 | HadChange |= (Result.get() != SrcExprs[i]); | |||
7816 | TransformedExprs.push_back(Result.get()); | |||
7817 | } | |||
7818 | } | |||
7819 | ||||
7820 | if (HadError) return StmtError(); | |||
7821 | if (!HadChange && !getDerived().AlwaysRebuild()) | |||
7822 | return Owned(S); | |||
7823 | ||||
7824 | return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(), | |||
7825 | AsmToks, S->getAsmString(), | |||
7826 | S->getNumOutputs(), S->getNumInputs(), | |||
7827 | S->getAllConstraints(), S->getClobbers(), | |||
7828 | TransformedExprs, S->getEndLoc()); | |||
7829 | } | |||
7830 | ||||
7831 | // C++ Coroutines TS | |||
7832 | ||||
7833 | template<typename Derived> | |||
7834 | StmtResult | |||
7835 | TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) { | |||
7836 | auto *ScopeInfo = SemaRef.getCurFunction(); | |||
7837 | auto *FD = cast<FunctionDecl>(SemaRef.CurContext); | |||
7838 | assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&(static_cast <bool> (FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && "expected clean scope info") ? void (0) : __assert_fail ("FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && \"expected clean scope info\"" , "clang/lib/Sema/TreeTransform.h", 7842, __extension__ __PRETTY_FUNCTION__ )) | |||
7839 | ScopeInfo->NeedsCoroutineSuspends &&(static_cast <bool> (FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && "expected clean scope info") ? void (0) : __assert_fail ("FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && \"expected clean scope info\"" , "clang/lib/Sema/TreeTransform.h", 7842, __extension__ __PRETTY_FUNCTION__ )) | |||
7840 | ScopeInfo->CoroutineSuspends.first == nullptr &&(static_cast <bool> (FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && "expected clean scope info") ? void (0) : __assert_fail ("FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && \"expected clean scope info\"" , "clang/lib/Sema/TreeTransform.h", 7842, __extension__ __PRETTY_FUNCTION__ )) | |||
7841 | ScopeInfo->CoroutineSuspends.second == nullptr &&(static_cast <bool> (FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && "expected clean scope info") ? void (0) : __assert_fail ("FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && \"expected clean scope info\"" , "clang/lib/Sema/TreeTransform.h", 7842, __extension__ __PRETTY_FUNCTION__ )) | |||
7842 | "expected clean scope info")(static_cast <bool> (FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && "expected clean scope info") ? void (0) : __assert_fail ("FD && ScopeInfo && !ScopeInfo->CoroutinePromise && ScopeInfo->NeedsCoroutineSuspends && ScopeInfo->CoroutineSuspends.first == nullptr && ScopeInfo->CoroutineSuspends.second == nullptr && \"expected clean scope info\"" , "clang/lib/Sema/TreeTransform.h", 7842, __extension__ __PRETTY_FUNCTION__ )); | |||
7843 | ||||
7844 | // Set that we have (possibly-invalid) suspend points before we do anything | |||
7845 | // that may fail. | |||
7846 | ScopeInfo->setNeedsCoroutineSuspends(false); | |||
7847 | ||||
7848 | // We re-build the coroutine promise object (and the coroutine parameters its | |||
7849 | // type and constructor depend on) based on the types used in our current | |||
7850 | // function. We must do so, and set it on the current FunctionScopeInfo, | |||
7851 | // before attempting to transform the other parts of the coroutine body | |||
7852 | // statement, such as the implicit suspend statements (because those | |||
7853 | // statements reference the FunctionScopeInfo::CoroutinePromise). | |||
7854 | if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation())) | |||
7855 | return StmtError(); | |||
7856 | auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation()); | |||
7857 | if (!Promise) | |||
7858 | return StmtError(); | |||
7859 | getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise}); | |||
7860 | ScopeInfo->CoroutinePromise = Promise; | |||
7861 | ||||
7862 | // Transform the implicit coroutine statements constructed using dependent | |||
7863 | // types during the previous parse: initial and final suspensions, the return | |||
7864 | // object, and others. We also transform the coroutine function's body. | |||
7865 | StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt()); | |||
7866 | if (InitSuspend.isInvalid()) | |||
7867 | return StmtError(); | |||
7868 | StmtResult FinalSuspend = | |||
7869 | getDerived().TransformStmt(S->getFinalSuspendStmt()); | |||
7870 | if (FinalSuspend.isInvalid() || | |||
7871 | !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get())) | |||
7872 | return StmtError(); | |||
7873 | ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get()); | |||
7874 | assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()))(static_cast <bool> (isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get())) ? void (0) : __assert_fail ("isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get())" , "clang/lib/Sema/TreeTransform.h", 7874, __extension__ __PRETTY_FUNCTION__ )); | |||
7875 | ||||
7876 | StmtResult BodyRes = getDerived().TransformStmt(S->getBody()); | |||
7877 | if (BodyRes.isInvalid()) | |||
7878 | return StmtError(); | |||
7879 | ||||
7880 | CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get()); | |||
7881 | if (Builder.isInvalid()) | |||
7882 | return StmtError(); | |||
7883 | ||||
7884 | Expr *ReturnObject = S->getReturnValueInit(); | |||
7885 | assert(ReturnObject && "the return object is expected to be valid")(static_cast <bool> (ReturnObject && "the return object is expected to be valid" ) ? void (0) : __assert_fail ("ReturnObject && \"the return object is expected to be valid\"" , "clang/lib/Sema/TreeTransform.h", 7885, __extension__ __PRETTY_FUNCTION__ )); | |||
7886 | ExprResult Res = getDerived().TransformInitializer(ReturnObject, | |||
7887 | /*NoCopyInit*/ false); | |||
7888 | if (Res.isInvalid()) | |||
7889 | return StmtError(); | |||
7890 | Builder.ReturnValue = Res.get(); | |||
7891 | ||||
7892 | // If during the previous parse the coroutine still had a dependent promise | |||
7893 | // statement, we may need to build some implicit coroutine statements | |||
7894 | // (such as exception and fallthrough handlers) for the first time. | |||
7895 | if (S->hasDependentPromiseType()) { | |||
7896 | // We can only build these statements, however, if the current promise type | |||
7897 | // is not dependent. | |||
7898 | if (!Promise->getType()->isDependentType()) { | |||
7899 | assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&(static_cast <bool> (!S->getFallthroughHandler() && !S->getExceptionHandler() && !S->getReturnStmtOnAllocFailure () && !S->getDeallocate() && "these nodes should not have been built yet" ) ? void (0) : __assert_fail ("!S->getFallthroughHandler() && !S->getExceptionHandler() && !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() && \"these nodes should not have been built yet\"" , "clang/lib/Sema/TreeTransform.h", 7901, __extension__ __PRETTY_FUNCTION__ )) | |||
7900 | !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&(static_cast <bool> (!S->getFallthroughHandler() && !S->getExceptionHandler() && !S->getReturnStmtOnAllocFailure () && !S->getDeallocate() && "these nodes should not have been built yet" ) ? void (0) : __assert_fail ("!S->getFallthroughHandler() && !S->getExceptionHandler() && !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() && \"these nodes should not have been built yet\"" , "clang/lib/Sema/TreeTransform.h", 7901, __extension__ __PRETTY_FUNCTION__ )) | |||
7901 | "these nodes should not have been built yet")(static_cast <bool> (!S->getFallthroughHandler() && !S->getExceptionHandler() && !S->getReturnStmtOnAllocFailure () && !S->getDeallocate() && "these nodes should not have been built yet" ) ? void (0) : __assert_fail ("!S->getFallthroughHandler() && !S->getExceptionHandler() && !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() && \"these nodes should not have been built yet\"" , "clang/lib/Sema/TreeTransform.h", 7901, __extension__ __PRETTY_FUNCTION__ )); | |||
7902 | if (!Builder.buildDependentStatements()) | |||
7903 | return StmtError(); | |||
7904 | } | |||
7905 | } else { | |||
7906 | if (auto *OnFallthrough = S->getFallthroughHandler()) { | |||
7907 | StmtResult Res = getDerived().TransformStmt(OnFallthrough); | |||
7908 | if (Res.isInvalid()) | |||
7909 | return StmtError(); | |||
7910 | Builder.OnFallthrough = Res.get(); | |||
7911 | } | |||
7912 | ||||
7913 | if (auto *OnException = S->getExceptionHandler()) { | |||
7914 | StmtResult Res = getDerived().TransformStmt(OnException); | |||
7915 | if (Res.isInvalid()) | |||
7916 | return StmtError(); | |||
7917 | Builder.OnException = Res.get(); | |||
7918 | } | |||
7919 | ||||
7920 | if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) { | |||
7921 | StmtResult Res = getDerived().TransformStmt(OnAllocFailure); | |||
7922 | if (Res.isInvalid()) | |||
7923 | return StmtError(); | |||
7924 | Builder.ReturnStmtOnAllocFailure = Res.get(); | |||
7925 | } | |||
7926 | ||||
7927 | // Transform any additional statements we may have already built | |||
7928 | assert(S->getAllocate() && S->getDeallocate() &&(static_cast <bool> (S->getAllocate() && S-> getDeallocate() && "allocation and deallocation calls must already be built" ) ? void (0) : __assert_fail ("S->getAllocate() && S->getDeallocate() && \"allocation and deallocation calls must already be built\"" , "clang/lib/Sema/TreeTransform.h", 7929, __extension__ __PRETTY_FUNCTION__ )) | |||
7929 | "allocation and deallocation calls must already be built")(static_cast <bool> (S->getAllocate() && S-> getDeallocate() && "allocation and deallocation calls must already be built" ) ? void (0) : __assert_fail ("S->getAllocate() && S->getDeallocate() && \"allocation and deallocation calls must already be built\"" , "clang/lib/Sema/TreeTransform.h", 7929, __extension__ __PRETTY_FUNCTION__ )); | |||
7930 | ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate()); | |||
7931 | if (AllocRes.isInvalid()) | |||
7932 | return StmtError(); | |||
7933 | Builder.Allocate = AllocRes.get(); | |||
7934 | ||||
7935 | ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate()); | |||
7936 | if (DeallocRes.isInvalid()) | |||
7937 | return StmtError(); | |||
7938 | Builder.Deallocate = DeallocRes.get(); | |||
7939 | ||||
7940 | if (auto *ReturnStmt = S->getReturnStmt()) { | |||
7941 | StmtResult Res = getDerived().TransformStmt(ReturnStmt); | |||
7942 | if (Res.isInvalid()) | |||
7943 | return StmtError(); | |||
7944 | Builder.ReturnStmt = Res.get(); | |||
7945 | } | |||
7946 | } | |||
7947 | ||||
7948 | return getDerived().RebuildCoroutineBodyStmt(Builder); | |||
7949 | } | |||
7950 | ||||
7951 | template<typename Derived> | |||
7952 | StmtResult | |||
7953 | TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) { | |||
7954 | ExprResult Result = getDerived().TransformInitializer(S->getOperand(), | |||
7955 | /*NotCopyInit*/false); | |||
7956 | if (Result.isInvalid()) | |||
7957 | return StmtError(); | |||
7958 | ||||
7959 | // Always rebuild; we don't know if this needs to be injected into a new | |||
7960 | // context or if the promise type has changed. | |||
7961 | return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(), | |||
7962 | S->isImplicit()); | |||
7963 | } | |||
7964 | ||||
7965 | template <typename Derived> | |||
7966 | ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) { | |||
7967 | ExprResult Operand = getDerived().TransformInitializer(E->getOperand(), | |||
7968 | /*NotCopyInit*/ false); | |||
7969 | if (Operand.isInvalid()) | |||
7970 | return ExprError(); | |||
7971 | ||||
7972 | // Rebuild the common-expr from the operand rather than transforming it | |||
7973 | // separately. | |||
7974 | ||||
7975 | // FIXME: getCurScope() should not be used during template instantiation. | |||
7976 | // We should pick up the set of unqualified lookup results for operator | |||
7977 | // co_await during the initial parse. | |||
7978 | ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr( | |||
7979 | getSema().getCurScope(), E->getKeywordLoc()); | |||
7980 | ||||
7981 | // Always rebuild; we don't know if this needs to be injected into a new | |||
7982 | // context or if the promise type has changed. | |||
7983 | return getDerived().RebuildCoawaitExpr( | |||
7984 | E->getKeywordLoc(), Operand.get(), | |||
7985 | cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit()); | |||
7986 | } | |||
7987 | ||||
7988 | template <typename Derived> | |||
7989 | ExprResult | |||
7990 | TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) { | |||
7991 | ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(), | |||
7992 | /*NotCopyInit*/ false); | |||
7993 | if (OperandResult.isInvalid()) | |||
7994 | return ExprError(); | |||
7995 | ||||
7996 | ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr( | |||
7997 | E->getOperatorCoawaitLookup()); | |||
7998 | ||||
7999 | if (LookupResult.isInvalid()) | |||
8000 | return ExprError(); | |||
8001 | ||||
8002 | // Always rebuild; we don't know if this needs to be injected into a new | |||
8003 | // context or if the promise type has changed. | |||
8004 | return getDerived().RebuildDependentCoawaitExpr( | |||
8005 | E->getKeywordLoc(), OperandResult.get(), | |||
8006 | cast<UnresolvedLookupExpr>(LookupResult.get())); | |||
8007 | } | |||
8008 | ||||
8009 | template<typename Derived> | |||
8010 | ExprResult | |||
8011 | TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) { | |||
8012 | ExprResult Result = getDerived().TransformInitializer(E->getOperand(), | |||
8013 | /*NotCopyInit*/false); | |||
8014 | if (Result.isInvalid()) | |||
8015 | return ExprError(); | |||
8016 | ||||
8017 | // Always rebuild; we don't know if this needs to be injected into a new | |||
8018 | // context or if the promise type has changed. | |||
8019 | return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get()); | |||
8020 | } | |||
8021 | ||||
8022 | // Objective-C Statements. | |||
8023 | ||||
8024 | template<typename Derived> | |||
8025 | StmtResult | |||
8026 | TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) { | |||
8027 | // Transform the body of the @try. | |||
8028 | StmtResult TryBody = getDerived().TransformStmt(S->getTryBody()); | |||
8029 | if (TryBody.isInvalid()) | |||
8030 | return StmtError(); | |||
8031 | ||||
8032 | // Transform the @catch statements (if present). | |||
8033 | bool AnyCatchChanged = false; | |||
8034 | SmallVector<Stmt*, 8> CatchStmts; | |||
8035 | for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { | |||
8036 | StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I)); | |||
8037 | if (Catch.isInvalid()) | |||
8038 | return StmtError(); | |||
8039 | if (Catch.get() != S->getCatchStmt(I)) | |||
8040 | AnyCatchChanged = true; | |||
8041 | CatchStmts.push_back(Catch.get()); | |||
8042 | } | |||
8043 | ||||
8044 | // Transform the @finally statement (if present). | |||
8045 | StmtResult Finally; | |||
8046 | if (S->getFinallyStmt()) { | |||
8047 | Finally = getDerived().TransformStmt(S->getFinallyStmt()); | |||
8048 | if (Finally.isInvalid()) | |||
8049 | return StmtError(); | |||
8050 | } | |||
8051 | ||||
8052 | // If nothing changed, just retain this statement. | |||
8053 | if (!getDerived().AlwaysRebuild() && | |||
8054 | TryBody.get() == S->getTryBody() && | |||
8055 | !AnyCatchChanged && | |||
8056 | Finally.get() == S->getFinallyStmt()) | |||
8057 | return S; | |||
8058 | ||||
8059 | // Build a new statement. | |||
8060 | return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(), | |||
8061 | CatchStmts, Finally.get()); | |||
8062 | } | |||
8063 | ||||
8064 | template<typename Derived> | |||
8065 | StmtResult | |||
8066 | TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) { | |||
8067 | // Transform the @catch parameter, if there is one. | |||
8068 | VarDecl *Var = nullptr; | |||
8069 | if (VarDecl *FromVar = S->getCatchParamDecl()) { | |||
8070 | TypeSourceInfo *TSInfo = nullptr; | |||
8071 | if (FromVar->getTypeSourceInfo()) { | |||
8072 | TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo()); | |||
8073 | if (!TSInfo) | |||
8074 | return StmtError(); | |||
8075 | } | |||
8076 | ||||
8077 | QualType T; | |||
8078 | if (TSInfo) | |||
8079 | T = TSInfo->getType(); | |||
8080 | else { | |||
8081 | T = getDerived().TransformType(FromVar->getType()); | |||
8082 | if (T.isNull()) | |||
8083 | return StmtError(); | |||
8084 | } | |||
8085 | ||||
8086 | Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T); | |||
8087 | if (!Var) | |||
8088 | return StmtError(); | |||
8089 | } | |||
8090 | ||||
8091 | StmtResult Body = getDerived().TransformStmt(S->getCatchBody()); | |||
8092 | if (Body.isInvalid()) | |||
8093 | return StmtError(); | |||
8094 | ||||
8095 | return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), | |||
8096 | S->getRParenLoc(), | |||
8097 | Var, Body.get()); | |||
8098 | } | |||
8099 | ||||
8100 | template<typename Derived> | |||
8101 | StmtResult | |||
8102 | TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { | |||
8103 | // Transform the body. | |||
8104 | StmtResult Body = getDerived().TransformStmt(S->getFinallyBody()); | |||
8105 | if (Body.isInvalid()) | |||
8106 | return StmtError(); | |||
8107 | ||||
8108 | // If nothing changed, just retain this statement. | |||
8109 | if (!getDerived().AlwaysRebuild() && | |||
8110 | Body.get() == S->getFinallyBody()) | |||
8111 | return S; | |||
8112 | ||||
8113 | // Build a new statement. | |||
8114 | return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(), | |||
8115 | Body.get()); | |||
8116 | } | |||
8117 | ||||
8118 | template<typename Derived> | |||
8119 | StmtResult | |||
8120 | TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) { | |||
8121 | ExprResult Operand; | |||
8122 | if (S->getThrowExpr()) { | |||
8123 | Operand = getDerived().TransformExpr(S->getThrowExpr()); | |||
8124 | if (Operand.isInvalid()) | |||
8125 | return StmtError(); | |||
8126 | } | |||
8127 | ||||
8128 | if (!getDerived().AlwaysRebuild() && | |||
8129 | Operand.get() == S->getThrowExpr()) | |||
8130 | return S; | |||
8131 | ||||
8132 | return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get()); | |||
8133 | } | |||
8134 | ||||
8135 | template<typename Derived> | |||
8136 | StmtResult | |||
8137 | TreeTransform<Derived>::TransformObjCAtSynchronizedStmt( | |||
8138 | ObjCAtSynchronizedStmt *S) { | |||
8139 | // Transform the object we are locking. | |||
8140 | ExprResult Object = getDerived().TransformExpr(S->getSynchExpr()); | |||
8141 | if (Object.isInvalid()) | |||
8142 | return StmtError(); | |||
8143 | Object = | |||
8144 | getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(), | |||
8145 | Object.get()); | |||
8146 | if (Object.isInvalid()) | |||
8147 | return StmtError(); | |||
8148 | ||||
8149 | // Transform the body. | |||
8150 | StmtResult Body = getDerived().TransformStmt(S->getSynchBody()); | |||
8151 | if (Body.isInvalid()) | |||
8152 | return StmtError(); | |||
8153 | ||||
8154 | // If nothing change, just retain the current statement. | |||
8155 | if (!getDerived().AlwaysRebuild() && | |||
8156 | Object.get() == S->getSynchExpr() && | |||
8157 | Body.get() == S->getSynchBody()) | |||
8158 | return S; | |||
8159 | ||||
8160 | // Build a new statement. | |||
8161 | return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(), | |||
8162 | Object.get(), Body.get()); | |||
8163 | } | |||
8164 | ||||
8165 | template<typename Derived> | |||
8166 | StmtResult | |||
8167 | TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt( | |||
8168 | ObjCAutoreleasePoolStmt *S) { | |||
8169 | // Transform the body. | |||
8170 | StmtResult Body = getDerived().TransformStmt(S->getSubStmt()); | |||
8171 | if (Body.isInvalid()) | |||
8172 | return StmtError(); | |||
8173 | ||||
8174 | // If nothing changed, just retain this statement. | |||
8175 | if (!getDerived().AlwaysRebuild() && | |||
8176 | Body.get() == S->getSubStmt()) | |||
8177 | return S; | |||
8178 | ||||
8179 | // Build a new statement. | |||
8180 | return getDerived().RebuildObjCAutoreleasePoolStmt( | |||
8181 | S->getAtLoc(), Body.get()); | |||
8182 | } | |||
8183 | ||||
8184 | template<typename Derived> | |||
8185 | StmtResult | |||
8186 | TreeTransform<Derived>::TransformObjCForCollectionStmt( | |||
8187 | ObjCForCollectionStmt *S) { | |||
8188 | // Transform the element statement. | |||
8189 | StmtResult Element = | |||
8190 | getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded); | |||
8191 | if (Element.isInvalid()) | |||
8192 | return StmtError(); | |||
8193 | ||||
8194 | // Transform the collection expression. | |||
8195 | ExprResult Collection = getDerived().TransformExpr(S->getCollection()); | |||
8196 | if (Collection.isInvalid()) | |||
8197 | return StmtError(); | |||
8198 | ||||
8199 | // Transform the body. | |||
8200 | StmtResult Body = getDerived().TransformStmt(S->getBody()); | |||
8201 | if (Body.isInvalid()) | |||
8202 | return StmtError(); | |||
8203 | ||||
8204 | // If nothing changed, just retain this statement. | |||
8205 | if (!getDerived().AlwaysRebuild() && | |||
8206 | Element.get() == S->getElement() && | |||
8207 | Collection.get() == S->getCollection() && | |||
8208 | Body.get() == S->getBody()) | |||
8209 | return S; | |||
8210 | ||||
8211 | // Build a new statement. | |||
8212 | return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(), | |||
8213 | Element.get(), | |||
8214 | Collection.get(), | |||
8215 | S->getRParenLoc(), | |||
8216 | Body.get()); | |||
8217 | } | |||
8218 | ||||
8219 | template <typename Derived> | |||
8220 | StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) { | |||
8221 | // Transform the exception declaration, if any. | |||
8222 | VarDecl *Var = nullptr; | |||
8223 | if (VarDecl *ExceptionDecl = S->getExceptionDecl()) { | |||
8224 | TypeSourceInfo *T = | |||
8225 | getDerived().TransformType(ExceptionDecl->getTypeSourceInfo()); | |||
8226 | if (!T) | |||
8227 | return StmtError(); | |||
8228 | ||||
8229 | Var = getDerived().RebuildExceptionDecl( | |||
8230 | ExceptionDecl, T, ExceptionDecl->getInnerLocStart(), | |||
8231 | ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier()); | |||
8232 | if (!Var || Var->isInvalidDecl()) | |||
8233 | return StmtError(); | |||
8234 | } | |||
8235 | ||||
8236 | // Transform the actual exception handler. | |||
8237 | StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock()); | |||
8238 | if (Handler.isInvalid()) | |||
8239 | return StmtError(); | |||
8240 | ||||
8241 | if (!getDerived().AlwaysRebuild() && !Var && | |||
8242 | Handler.get() == S->getHandlerBlock()) | |||
8243 | return S; | |||
8244 | ||||
8245 | return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get()); | |||
8246 | } | |||
8247 | ||||
8248 | template <typename Derived> | |||
8249 | StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) { | |||
8250 | // Transform the try block itself. | |||
8251 | StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); | |||
8252 | if (TryBlock.isInvalid()) | |||
8253 | return StmtError(); | |||
8254 | ||||
8255 | // Transform the handlers. | |||
8256 | bool HandlerChanged = false; | |||
8257 | SmallVector<Stmt *, 8> Handlers; | |||
8258 | for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) { | |||
8259 | StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I)); | |||
8260 | if (Handler.isInvalid()) | |||
8261 | return StmtError(); | |||
8262 | ||||
8263 | HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I); | |||
8264 | Handlers.push_back(Handler.getAs<Stmt>()); | |||
8265 | } | |||
8266 | ||||
8267 | if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && | |||
8268 | !HandlerChanged) | |||
8269 | return S; | |||
8270 | ||||
8271 | return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(), | |||
8272 | Handlers); | |||
8273 | } | |||
8274 | ||||
8275 | template<typename Derived> | |||
8276 | StmtResult | |||
8277 | TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) { | |||
8278 | StmtResult Init = | |||
8279 | S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult(); | |||
8280 | if (Init.isInvalid()) | |||
8281 | return StmtError(); | |||
8282 | ||||
8283 | StmtResult Range = getDerived().TransformStmt(S->getRangeStmt()); | |||
8284 | if (Range.isInvalid()) | |||
8285 | return StmtError(); | |||
8286 | ||||
8287 | StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt()); | |||
8288 | if (Begin.isInvalid()) | |||
8289 | return StmtError(); | |||
8290 | StmtResult End = getDerived().TransformStmt(S->getEndStmt()); | |||
8291 | if (End.isInvalid()) | |||
8292 | return StmtError(); | |||
8293 | ||||
8294 | ExprResult Cond = getDerived().TransformExpr(S->getCond()); | |||
8295 | if (Cond.isInvalid()) | |||
8296 | return StmtError(); | |||
8297 | if (Cond.get()) | |||
8298 | Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get()); | |||
8299 | if (Cond.isInvalid()) | |||
8300 | return StmtError(); | |||
8301 | if (Cond.get()) | |||
8302 | Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get()); | |||
8303 | ||||
8304 | ExprResult Inc = getDerived().TransformExpr(S->getInc()); | |||
8305 | if (Inc.isInvalid()) | |||
8306 | return StmtError(); | |||
8307 | if (Inc.get()) | |||
8308 | Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get()); | |||
8309 | ||||
8310 | StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt()); | |||
8311 | if (LoopVar.isInvalid()) | |||
8312 | return StmtError(); | |||
8313 | ||||
8314 | StmtResult NewStmt = S; | |||
8315 | if (getDerived().AlwaysRebuild() || | |||
8316 | Init.get() != S->getInit() || | |||
8317 | Range.get() != S->getRangeStmt() || | |||
8318 | Begin.get() != S->getBeginStmt() || | |||
8319 | End.get() != S->getEndStmt() || | |||
8320 | Cond.get() != S->getCond() || | |||
8321 | Inc.get() != S->getInc() || | |||
8322 | LoopVar.get() != S->getLoopVarStmt()) { | |||
8323 | NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(), | |||
8324 | S->getCoawaitLoc(), Init.get(), | |||
8325 | S->getColonLoc(), Range.get(), | |||
8326 | Begin.get(), End.get(), | |||
8327 | Cond.get(), | |||
8328 | Inc.get(), LoopVar.get(), | |||
8329 | S->getRParenLoc()); | |||
8330 | if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) { | |||
8331 | // Might not have attached any initializer to the loop variable. | |||
8332 | getSema().ActOnInitializerError( | |||
8333 | cast<DeclStmt>(LoopVar.get())->getSingleDecl()); | |||
8334 | return StmtError(); | |||
8335 | } | |||
8336 | } | |||
8337 | ||||
8338 | StmtResult Body = getDerived().TransformStmt(S->getBody()); | |||
8339 | if (Body.isInvalid()) | |||
8340 | return StmtError(); | |||
8341 | ||||
8342 | // Body has changed but we didn't rebuild the for-range statement. Rebuild | |||
8343 | // it now so we have a new statement to attach the body to. | |||
8344 | if (Body.get() != S->getBody() && NewStmt.get() == S) { | |||
8345 | NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(), | |||
8346 | S->getCoawaitLoc(), Init.get(), | |||
8347 | S->getColonLoc(), Range.get(), | |||
8348 | Begin.get(), End.get(), | |||
8349 | Cond.get(), | |||
8350 | Inc.get(), LoopVar.get(), | |||
8351 | S->getRParenLoc()); | |||
8352 | if (NewStmt.isInvalid()) | |||
8353 | return StmtError(); | |||
8354 | } | |||
8355 | ||||
8356 | if (NewStmt.get() == S) | |||
8357 | return S; | |||
8358 | ||||
8359 | return FinishCXXForRangeStmt(NewStmt.get(), Body.get()); | |||
8360 | } | |||
8361 | ||||
8362 | template<typename Derived> | |||
8363 | StmtResult | |||
8364 | TreeTransform<Derived>::TransformMSDependentExistsStmt( | |||
8365 | MSDependentExistsStmt *S) { | |||
8366 | // Transform the nested-name-specifier, if any. | |||
8367 | NestedNameSpecifierLoc QualifierLoc; | |||
8368 | if (S->getQualifierLoc()) { | |||
8369 | QualifierLoc | |||
8370 | = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc()); | |||
8371 | if (!QualifierLoc) | |||
8372 | return StmtError(); | |||
8373 | } | |||
8374 | ||||
8375 | // Transform the declaration name. | |||
8376 | DeclarationNameInfo NameInfo = S->getNameInfo(); | |||
8377 | if (NameInfo.getName()) { | |||
8378 | NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); | |||
8379 | if (!NameInfo.getName()) | |||
8380 | return StmtError(); | |||
8381 | } | |||
8382 | ||||
8383 | // Check whether anything changed. | |||
8384 | if (!getDerived().AlwaysRebuild() && | |||
8385 | QualifierLoc == S->getQualifierLoc() && | |||
8386 | NameInfo.getName() == S->getNameInfo().getName()) | |||
8387 | return S; | |||
8388 | ||||
8389 | // Determine whether this name exists, if we can. | |||
8390 | CXXScopeSpec SS; | |||
8391 | SS.Adopt(QualifierLoc); | |||
8392 | bool Dependent = false; | |||
8393 | switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) { | |||
8394 | case Sema::IER_Exists: | |||
8395 | if (S->isIfExists()) | |||
8396 | break; | |||
8397 | ||||
8398 | return new (getSema().Context) NullStmt(S->getKeywordLoc()); | |||
8399 | ||||
8400 | case Sema::IER_DoesNotExist: | |||
8401 | if (S->isIfNotExists()) | |||
8402 | break; | |||
8403 | ||||
8404 | return new (getSema().Context) NullStmt(S->getKeywordLoc()); | |||
8405 | ||||
8406 | case Sema::IER_Dependent: | |||
8407 | Dependent = true; | |||
8408 | break; | |||
8409 | ||||
8410 | case Sema::IER_Error: | |||
8411 | return StmtError(); | |||
8412 | } | |||
8413 | ||||
8414 | // We need to continue with the instantiation, so do so now. | |||
8415 | StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt()); | |||
8416 | if (SubStmt.isInvalid()) | |||
8417 | return StmtError(); | |||
8418 | ||||
8419 | // If we have resolved the name, just transform to the substatement. | |||
8420 | if (!Dependent) | |||
8421 | return SubStmt; | |||
8422 | ||||
8423 | // The name is still dependent, so build a dependent expression again. | |||
8424 | return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(), | |||
8425 | S->isIfExists(), | |||
8426 | QualifierLoc, | |||
8427 | NameInfo, | |||
8428 | SubStmt.get()); | |||
8429 | } | |||
8430 | ||||
8431 | template<typename Derived> | |||
8432 | ExprResult | |||
8433 | TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) { | |||
8434 | NestedNameSpecifierLoc QualifierLoc; | |||
8435 | if (E->getQualifierLoc()) { | |||
8436 | QualifierLoc | |||
8437 | = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); | |||
8438 | if (!QualifierLoc) | |||
8439 | return ExprError(); | |||
8440 | } | |||
8441 | ||||
8442 | MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>( | |||
8443 | getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl())); | |||
8444 | if (!PD) | |||
8445 | return ExprError(); | |||
8446 | ||||
8447 | ExprResult Base = getDerived().TransformExpr(E->getBaseExpr()); | |||
8448 | if (Base.isInvalid()) | |||
8449 | return ExprError(); | |||
8450 | ||||
8451 | return new (SemaRef.getASTContext()) | |||
8452 | MSPropertyRefExpr(Base.get(), PD, E->isArrow(), | |||
8453 | SemaRef.getASTContext().PseudoObjectTy, VK_LValue, | |||
8454 | QualifierLoc, E->getMemberLoc()); | |||
8455 | } | |||
8456 | ||||
8457 | template <typename Derived> | |||
8458 | ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr( | |||
8459 | MSPropertySubscriptExpr *E) { | |||
8460 | auto BaseRes = getDerived().TransformExpr(E->getBase()); | |||
8461 | if (BaseRes.isInvalid()) | |||
8462 | return ExprError(); | |||
8463 | auto IdxRes = getDerived().TransformExpr(E->getIdx()); | |||
8464 | if (IdxRes.isInvalid()) | |||
8465 | return ExprError(); | |||
8466 | ||||
8467 | if (!getDerived().AlwaysRebuild() && | |||
8468 | BaseRes.get() == E->getBase() && | |||
8469 | IdxRes.get() == E->getIdx()) | |||
8470 | return E; | |||
8471 | ||||
8472 | return getDerived().RebuildArraySubscriptExpr( | |||
8473 | BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc()); | |||
8474 | } | |||
8475 | ||||
8476 | template <typename Derived> | |||
8477 | StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { | |||
8478 | StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); | |||
8479 | if (TryBlock.isInvalid()) | |||
8480 | return StmtError(); | |||
8481 | ||||
8482 | StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler()); | |||
8483 | if (Handler.isInvalid()) | |||
8484 | return StmtError(); | |||
8485 | ||||
8486 | if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && | |||
8487 | Handler.get() == S->getHandler()) | |||
8488 | return S; | |||
8489 | ||||
8490 | return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(), | |||
8491 | TryBlock.get(), Handler.get()); | |||
8492 | } | |||
8493 | ||||
8494 | template <typename Derived> | |||
8495 | StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) { | |||
8496 | StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); | |||
8497 | if (Block.isInvalid()) | |||
8498 | return StmtError(); | |||
8499 | ||||
8500 | return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get()); | |||
8501 | } | |||
8502 | ||||
8503 | template <typename Derived> | |||
8504 | StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) { | |||
8505 | ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr()); | |||
8506 | if (FilterExpr.isInvalid()) | |||
8507 | return StmtError(); | |||
8508 | ||||
8509 | StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); | |||
8510 | if (Block.isInvalid()) | |||
8511 | return StmtError(); | |||
8512 | ||||
8513 | return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(), | |||
8514 | Block.get()); | |||
8515 | } | |||
8516 | ||||
8517 | template <typename Derived> | |||
8518 | StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) { | |||
8519 | if (isa<SEHFinallyStmt>(Handler)) | |||
8520 | return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler)); | |||
8521 | else | |||
8522 | return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler)); | |||
8523 | } | |||
8524 | ||||
8525 | template<typename Derived> | |||
8526 | StmtResult | |||
8527 | TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) { | |||
8528 | return S; | |||
8529 | } | |||
8530 | ||||
8531 | //===----------------------------------------------------------------------===// | |||
8532 | // OpenMP directive transformation | |||
8533 | //===----------------------------------------------------------------------===// | |||
8534 | ||||
8535 | template <typename Derived> | |||
8536 | StmtResult | |||
8537 | TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) { | |||
8538 | // OMPCanonicalLoops are eliminated during transformation, since they will be | |||
8539 | // recomputed by semantic analysis of the associated OMPLoopBasedDirective | |||
8540 | // after transformation. | |||
8541 | return getDerived().TransformStmt(L->getLoopStmt()); | |||
8542 | } | |||
8543 | ||||
8544 | template <typename Derived> | |||
8545 | StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective( | |||
8546 | OMPExecutableDirective *D) { | |||
8547 | ||||
8548 | // Transform the clauses | |||
8549 | llvm::SmallVector<OMPClause *, 16> TClauses; | |||
8550 | ArrayRef<OMPClause *> Clauses = D->clauses(); | |||
8551 | TClauses.reserve(Clauses.size()); | |||
8552 | for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); | |||
8553 | I != E; ++I) { | |||
8554 | if (*I) { | |||
8555 | getDerived().getSema().StartOpenMPClause((*I)->getClauseKind()); | |||
8556 | OMPClause *Clause = getDerived().TransformOMPClause(*I); | |||
8557 | getDerived().getSema().EndOpenMPClause(); | |||
8558 | if (Clause) | |||
8559 | TClauses.push_back(Clause); | |||
8560 | } else { | |||
8561 | TClauses.push_back(nullptr); | |||
8562 | } | |||
8563 | } | |||
8564 | StmtResult AssociatedStmt; | |||
8565 | if (D->hasAssociatedStmt() && D->getAssociatedStmt()) { | |||
8566 | getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(), | |||
8567 | /*CurScope=*/nullptr); | |||
8568 | StmtResult Body; | |||
8569 | { | |||
8570 | Sema::CompoundScopeRAII CompoundScope(getSema()); | |||
8571 | Stmt *CS; | |||
8572 | if (D->getDirectiveKind() == OMPD_atomic || | |||
8573 | D->getDirectiveKind() == OMPD_critical || | |||
8574 | D->getDirectiveKind() == OMPD_section || | |||
8575 | D->getDirectiveKind() == OMPD_master) | |||
8576 | CS = D->getAssociatedStmt(); | |||
8577 | else | |||
8578 | CS = D->getRawStmt(); | |||
8579 | Body = getDerived().TransformStmt(CS); | |||
8580 | if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) && | |||
8581 | getSema().getLangOpts().OpenMPIRBuilder) | |||
8582 | Body = getDerived().RebuildOMPCanonicalLoop(Body.get()); | |||
8583 | } | |||
8584 | AssociatedStmt = | |||
8585 | getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses); | |||
8586 | if (AssociatedStmt.isInvalid()) { | |||
8587 | return StmtError(); | |||
8588 | } | |||
8589 | } | |||
8590 | if (TClauses.size() != Clauses.size()) { | |||
8591 | return StmtError(); | |||
8592 | } | |||
8593 | ||||
8594 | // Transform directive name for 'omp critical' directive. | |||
8595 | DeclarationNameInfo DirName; | |||
8596 | if (D->getDirectiveKind() == OMPD_critical) { | |||
8597 | DirName = cast<OMPCriticalDirective>(D)->getDirectiveName(); | |||
8598 | DirName = getDerived().TransformDeclarationNameInfo(DirName); | |||
8599 | } | |||
8600 | OpenMPDirectiveKind CancelRegion = OMPD_unknown; | |||
8601 | if (D->getDirectiveKind() == OMPD_cancellation_point) { | |||
8602 | CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion(); | |||
8603 | } else if (D->getDirectiveKind() == OMPD_cancel) { | |||
8604 | CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion(); | |||
8605 | } | |||
8606 | ||||
8607 | return getDerived().RebuildOMPExecutableDirective( | |||
8608 | D->getDirectiveKind(), DirName, CancelRegion, TClauses, | |||
8609 | AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc()); | |||
8610 | } | |||
8611 | ||||
8612 | template <typename Derived> | |||
8613 | StmtResult | |||
8614 | TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) { | |||
8615 | // TODO: Fix This | |||
8616 | SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported) | |||
8617 | << getOpenMPDirectiveName(D->getDirectiveKind()); | |||
8618 | return StmtError(); | |||
8619 | } | |||
8620 | ||||
8621 | template <typename Derived> | |||
8622 | StmtResult | |||
8623 | TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) { | |||
8624 | DeclarationNameInfo DirName; | |||
8625 | getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr, | |||
8626 | D->getBeginLoc()); | |||
8627 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8628 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8629 | return Res; | |||
8630 | } | |||
8631 | ||||
8632 | template <typename Derived> | |||
8633 | StmtResult | |||
8634 | TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) { | |||
8635 | DeclarationNameInfo DirName; | |||
8636 | getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr, | |||
8637 | D->getBeginLoc()); | |||
8638 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8639 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8640 | return Res; | |||
8641 | } | |||
8642 | ||||
8643 | template <typename Derived> | |||
8644 | StmtResult | |||
8645 | TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) { | |||
8646 | DeclarationNameInfo DirName; | |||
8647 | getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName, | |||
8648 | nullptr, D->getBeginLoc()); | |||
8649 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8650 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8651 | return Res; | |||
8652 | } | |||
8653 | ||||
8654 | template <typename Derived> | |||
8655 | StmtResult | |||
8656 | TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) { | |||
8657 | DeclarationNameInfo DirName; | |||
8658 | getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName, | |||
8659 | nullptr, D->getBeginLoc()); | |||
8660 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8661 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8662 | return Res; | |||
8663 | } | |||
8664 | ||||
8665 | template <typename Derived> | |||
8666 | StmtResult | |||
8667 | TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) { | |||
8668 | DeclarationNameInfo DirName; | |||
8669 | getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr, | |||
8670 | D->getBeginLoc()); | |||
8671 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8672 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8673 | return Res; | |||
8674 | } | |||
8675 | ||||
8676 | template <typename Derived> | |||
8677 | StmtResult | |||
8678 | TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) { | |||
8679 | DeclarationNameInfo DirName; | |||
8680 | getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr, | |||
8681 | D->getBeginLoc()); | |||
8682 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8683 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8684 | return Res; | |||
8685 | } | |||
8686 | ||||
8687 | template <typename Derived> | |||
8688 | StmtResult | |||
8689 | TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) { | |||
8690 | DeclarationNameInfo DirName; | |||
8691 | getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr, | |||
8692 | D->getBeginLoc()); | |||
8693 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8694 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8695 | return Res; | |||
8696 | } | |||
8697 | ||||
8698 | template <typename Derived> | |||
8699 | StmtResult | |||
8700 | TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) { | |||
8701 | DeclarationNameInfo DirName; | |||
8702 | getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr, | |||
8703 | D->getBeginLoc()); | |||
8704 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8705 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8706 | return Res; | |||
8707 | } | |||
8708 | ||||
8709 | template <typename Derived> | |||
8710 | StmtResult | |||
8711 | TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) { | |||
8712 | DeclarationNameInfo DirName; | |||
8713 | getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr, | |||
8714 | D->getBeginLoc()); | |||
8715 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8716 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8717 | return Res; | |||
8718 | } | |||
8719 | ||||
8720 | template <typename Derived> | |||
8721 | StmtResult | |||
8722 | TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) { | |||
8723 | DeclarationNameInfo DirName; | |||
8724 | getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr, | |||
8725 | D->getBeginLoc()); | |||
8726 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8727 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8728 | return Res; | |||
8729 | } | |||
8730 | ||||
8731 | template <typename Derived> | |||
8732 | StmtResult | |||
8733 | TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) { | |||
8734 | getDerived().getSema().StartOpenMPDSABlock( | |||
8735 | OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc()); | |||
8736 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8737 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8738 | return Res; | |||
8739 | } | |||
8740 | ||||
8741 | template <typename Derived> | |||
8742 | StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective( | |||
8743 | OMPParallelForDirective *D) { | |||
8744 | DeclarationNameInfo DirName; | |||
8745 | getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName, | |||
8746 | nullptr, D->getBeginLoc()); | |||
8747 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8748 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8749 | return Res; | |||
8750 | } | |||
8751 | ||||
8752 | template <typename Derived> | |||
8753 | StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective( | |||
8754 | OMPParallelForSimdDirective *D) { | |||
8755 | DeclarationNameInfo DirName; | |||
8756 | getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName, | |||
8757 | nullptr, D->getBeginLoc()); | |||
8758 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8759 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8760 | return Res; | |||
8761 | } | |||
8762 | ||||
8763 | template <typename Derived> | |||
8764 | StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective( | |||
8765 | OMPParallelMasterDirective *D) { | |||
8766 | DeclarationNameInfo DirName; | |||
8767 | getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_master, DirName, | |||
8768 | nullptr, D->getBeginLoc()); | |||
8769 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8770 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8771 | return Res; | |||
8772 | } | |||
8773 | ||||
8774 | template <typename Derived> | |||
8775 | StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective( | |||
8776 | OMPParallelMaskedDirective *D) { | |||
8777 | DeclarationNameInfo DirName; | |||
8778 | getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_masked, DirName, | |||
8779 | nullptr, D->getBeginLoc()); | |||
8780 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8781 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8782 | return Res; | |||
8783 | } | |||
8784 | ||||
8785 | template <typename Derived> | |||
8786 | StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective( | |||
8787 | OMPParallelSectionsDirective *D) { | |||
8788 | DeclarationNameInfo DirName; | |||
8789 | getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName, | |||
8790 | nullptr, D->getBeginLoc()); | |||
8791 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8792 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8793 | return Res; | |||
8794 | } | |||
8795 | ||||
8796 | template <typename Derived> | |||
8797 | StmtResult | |||
8798 | TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) { | |||
8799 | DeclarationNameInfo DirName; | |||
8800 | getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr, | |||
8801 | D->getBeginLoc()); | |||
8802 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8803 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8804 | return Res; | |||
8805 | } | |||
8806 | ||||
8807 | template <typename Derived> | |||
8808 | StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective( | |||
8809 | OMPTaskyieldDirective *D) { | |||
8810 | DeclarationNameInfo DirName; | |||
8811 | getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr, | |||
8812 | D->getBeginLoc()); | |||
8813 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8814 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8815 | return Res; | |||
8816 | } | |||
8817 | ||||
8818 | template <typename Derived> | |||
8819 | StmtResult | |||
8820 | TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) { | |||
8821 | DeclarationNameInfo DirName; | |||
8822 | getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr, | |||
8823 | D->getBeginLoc()); | |||
8824 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8825 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8826 | return Res; | |||
8827 | } | |||
8828 | ||||
8829 | template <typename Derived> | |||
8830 | StmtResult | |||
8831 | TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) { | |||
8832 | DeclarationNameInfo DirName; | |||
8833 | getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr, | |||
8834 | D->getBeginLoc()); | |||
8835 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8836 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8837 | return Res; | |||
8838 | } | |||
8839 | ||||
8840 | template <typename Derived> | |||
8841 | StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective( | |||
8842 | OMPTaskgroupDirective *D) { | |||
8843 | DeclarationNameInfo DirName; | |||
8844 | getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr, | |||
8845 | D->getBeginLoc()); | |||
8846 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8847 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8848 | return Res; | |||
8849 | } | |||
8850 | ||||
8851 | template <typename Derived> | |||
8852 | StmtResult | |||
8853 | TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) { | |||
8854 | DeclarationNameInfo DirName; | |||
8855 | getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr, | |||
8856 | D->getBeginLoc()); | |||
8857 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8858 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8859 | return Res; | |||
8860 | } | |||
8861 | ||||
8862 | template <typename Derived> | |||
8863 | StmtResult | |||
8864 | TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) { | |||
8865 | DeclarationNameInfo DirName; | |||
8866 | getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr, | |||
8867 | D->getBeginLoc()); | |||
8868 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8869 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8870 | return Res; | |||
8871 | } | |||
8872 | ||||
8873 | template <typename Derived> | |||
8874 | StmtResult | |||
8875 | TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) { | |||
8876 | DeclarationNameInfo DirName; | |||
8877 | getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr, | |||
8878 | D->getBeginLoc()); | |||
8879 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8880 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8881 | return Res; | |||
8882 | } | |||
8883 | ||||
8884 | template <typename Derived> | |||
8885 | StmtResult | |||
8886 | TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) { | |||
8887 | DeclarationNameInfo DirName; | |||
8888 | getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr, | |||
8889 | D->getBeginLoc()); | |||
8890 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8891 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8892 | return Res; | |||
8893 | } | |||
8894 | ||||
8895 | template <typename Derived> | |||
8896 | StmtResult | |||
8897 | TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) { | |||
8898 | DeclarationNameInfo DirName; | |||
8899 | getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr, | |||
8900 | D->getBeginLoc()); | |||
8901 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8902 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8903 | return Res; | |||
8904 | } | |||
8905 | ||||
8906 | template <typename Derived> | |||
8907 | StmtResult | |||
8908 | TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) { | |||
8909 | DeclarationNameInfo DirName; | |||
8910 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr, | |||
8911 | D->getBeginLoc()); | |||
8912 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8913 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8914 | return Res; | |||
8915 | } | |||
8916 | ||||
8917 | template <typename Derived> | |||
8918 | StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective( | |||
8919 | OMPTargetDataDirective *D) { | |||
8920 | DeclarationNameInfo DirName; | |||
8921 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_data, DirName, nullptr, | |||
8922 | D->getBeginLoc()); | |||
8923 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8924 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8925 | return Res; | |||
8926 | } | |||
8927 | ||||
8928 | template <typename Derived> | |||
8929 | StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective( | |||
8930 | OMPTargetEnterDataDirective *D) { | |||
8931 | DeclarationNameInfo DirName; | |||
8932 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_enter_data, DirName, | |||
8933 | nullptr, D->getBeginLoc()); | |||
8934 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8935 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8936 | return Res; | |||
8937 | } | |||
8938 | ||||
8939 | template <typename Derived> | |||
8940 | StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective( | |||
8941 | OMPTargetExitDataDirective *D) { | |||
8942 | DeclarationNameInfo DirName; | |||
8943 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName, | |||
8944 | nullptr, D->getBeginLoc()); | |||
8945 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8946 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8947 | return Res; | |||
8948 | } | |||
8949 | ||||
8950 | template <typename Derived> | |||
8951 | StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective( | |||
8952 | OMPTargetParallelDirective *D) { | |||
8953 | DeclarationNameInfo DirName; | |||
8954 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel, DirName, | |||
8955 | nullptr, D->getBeginLoc()); | |||
8956 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8957 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8958 | return Res; | |||
8959 | } | |||
8960 | ||||
8961 | template <typename Derived> | |||
8962 | StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective( | |||
8963 | OMPTargetParallelForDirective *D) { | |||
8964 | DeclarationNameInfo DirName; | |||
8965 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName, | |||
8966 | nullptr, D->getBeginLoc()); | |||
8967 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8968 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8969 | return Res; | |||
8970 | } | |||
8971 | ||||
8972 | template <typename Derived> | |||
8973 | StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective( | |||
8974 | OMPTargetUpdateDirective *D) { | |||
8975 | DeclarationNameInfo DirName; | |||
8976 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName, | |||
8977 | nullptr, D->getBeginLoc()); | |||
8978 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8979 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8980 | return Res; | |||
8981 | } | |||
8982 | ||||
8983 | template <typename Derived> | |||
8984 | StmtResult | |||
8985 | TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) { | |||
8986 | DeclarationNameInfo DirName; | |||
8987 | getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr, | |||
8988 | D->getBeginLoc()); | |||
8989 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
8990 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
8991 | return Res; | |||
8992 | } | |||
8993 | ||||
8994 | template <typename Derived> | |||
8995 | StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective( | |||
8996 | OMPCancellationPointDirective *D) { | |||
8997 | DeclarationNameInfo DirName; | |||
8998 | getDerived().getSema().StartOpenMPDSABlock(OMPD_cancellation_point, DirName, | |||
8999 | nullptr, D->getBeginLoc()); | |||
9000 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9001 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9002 | return Res; | |||
9003 | } | |||
9004 | ||||
9005 | template <typename Derived> | |||
9006 | StmtResult | |||
9007 | TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) { | |||
9008 | DeclarationNameInfo DirName; | |||
9009 | getDerived().getSema().StartOpenMPDSABlock(OMPD_cancel, DirName, nullptr, | |||
9010 | D->getBeginLoc()); | |||
9011 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9012 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9013 | return Res; | |||
9014 | } | |||
9015 | ||||
9016 | template <typename Derived> | |||
9017 | StmtResult | |||
9018 | TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) { | |||
9019 | DeclarationNameInfo DirName; | |||
9020 | getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr, | |||
9021 | D->getBeginLoc()); | |||
9022 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9023 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9024 | return Res; | |||
9025 | } | |||
9026 | ||||
9027 | template <typename Derived> | |||
9028 | StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective( | |||
9029 | OMPTaskLoopSimdDirective *D) { | |||
9030 | DeclarationNameInfo DirName; | |||
9031 | getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop_simd, DirName, | |||
9032 | nullptr, D->getBeginLoc()); | |||
9033 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9034 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9035 | return Res; | |||
9036 | } | |||
9037 | ||||
9038 | template <typename Derived> | |||
9039 | StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective( | |||
9040 | OMPMasterTaskLoopDirective *D) { | |||
9041 | DeclarationNameInfo DirName; | |||
9042 | getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop, DirName, | |||
9043 | nullptr, D->getBeginLoc()); | |||
9044 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9045 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9046 | return Res; | |||
9047 | } | |||
9048 | ||||
9049 | template <typename Derived> | |||
9050 | StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective( | |||
9051 | OMPMaskedTaskLoopDirective *D) { | |||
9052 | DeclarationNameInfo DirName; | |||
9053 | getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop, DirName, | |||
9054 | nullptr, D->getBeginLoc()); | |||
9055 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9056 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9057 | return Res; | |||
9058 | } | |||
9059 | ||||
9060 | template <typename Derived> | |||
9061 | StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective( | |||
9062 | OMPMasterTaskLoopSimdDirective *D) { | |||
9063 | DeclarationNameInfo DirName; | |||
9064 | getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop_simd, DirName, | |||
9065 | nullptr, D->getBeginLoc()); | |||
9066 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9067 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9068 | return Res; | |||
9069 | } | |||
9070 | ||||
9071 | template <typename Derived> | |||
9072 | StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective( | |||
9073 | OMPMaskedTaskLoopSimdDirective *D) { | |||
9074 | DeclarationNameInfo DirName; | |||
9075 | getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop_simd, DirName, | |||
9076 | nullptr, D->getBeginLoc()); | |||
9077 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9078 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9079 | return Res; | |||
9080 | } | |||
9081 | ||||
9082 | template <typename Derived> | |||
9083 | StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective( | |||
9084 | OMPParallelMasterTaskLoopDirective *D) { | |||
9085 | DeclarationNameInfo DirName; | |||
9086 | getDerived().getSema().StartOpenMPDSABlock( | |||
9087 | OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc()); | |||
9088 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9089 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9090 | return Res; | |||
9091 | } | |||
9092 | ||||
9093 | template <typename Derived> | |||
9094 | StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective( | |||
9095 | OMPParallelMaskedTaskLoopDirective *D) { | |||
9096 | DeclarationNameInfo DirName; | |||
9097 | getDerived().getSema().StartOpenMPDSABlock( | |||
9098 | OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc()); | |||
9099 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9100 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9101 | return Res; | |||
9102 | } | |||
9103 | ||||
9104 | template <typename Derived> | |||
9105 | StmtResult | |||
9106 | TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective( | |||
9107 | OMPParallelMasterTaskLoopSimdDirective *D) { | |||
9108 | DeclarationNameInfo DirName; | |||
9109 | getDerived().getSema().StartOpenMPDSABlock( | |||
9110 | OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc()); | |||
9111 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9112 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9113 | return Res; | |||
9114 | } | |||
9115 | ||||
9116 | template <typename Derived> | |||
9117 | StmtResult | |||
9118 | TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective( | |||
9119 | OMPParallelMaskedTaskLoopSimdDirective *D) { | |||
9120 | DeclarationNameInfo DirName; | |||
9121 | getDerived().getSema().StartOpenMPDSABlock( | |||
9122 | OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc()); | |||
9123 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9124 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9125 | return Res; | |||
9126 | } | |||
9127 | ||||
9128 | template <typename Derived> | |||
9129 | StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective( | |||
9130 | OMPDistributeDirective *D) { | |||
9131 | DeclarationNameInfo DirName; | |||
9132 | getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute, DirName, nullptr, | |||
9133 | D->getBeginLoc()); | |||
9134 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9135 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9136 | return Res; | |||
9137 | } | |||
9138 | ||||
9139 | template <typename Derived> | |||
9140 | StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective( | |||
9141 | OMPDistributeParallelForDirective *D) { | |||
9142 | DeclarationNameInfo DirName; | |||
9143 | getDerived().getSema().StartOpenMPDSABlock( | |||
9144 | OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc()); | |||
9145 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9146 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9147 | return Res; | |||
9148 | } | |||
9149 | ||||
9150 | template <typename Derived> | |||
9151 | StmtResult | |||
9152 | TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective( | |||
9153 | OMPDistributeParallelForSimdDirective *D) { | |||
9154 | DeclarationNameInfo DirName; | |||
9155 | getDerived().getSema().StartOpenMPDSABlock( | |||
9156 | OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc()); | |||
9157 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9158 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9159 | return Res; | |||
9160 | } | |||
9161 | ||||
9162 | template <typename Derived> | |||
9163 | StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective( | |||
9164 | OMPDistributeSimdDirective *D) { | |||
9165 | DeclarationNameInfo DirName; | |||
9166 | getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute_simd, DirName, | |||
9167 | nullptr, D->getBeginLoc()); | |||
9168 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9169 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9170 | return Res; | |||
9171 | } | |||
9172 | ||||
9173 | template <typename Derived> | |||
9174 | StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective( | |||
9175 | OMPTargetParallelForSimdDirective *D) { | |||
9176 | DeclarationNameInfo DirName; | |||
9177 | getDerived().getSema().StartOpenMPDSABlock( | |||
9178 | OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc()); | |||
9179 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9180 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9181 | return Res; | |||
9182 | } | |||
9183 | ||||
9184 | template <typename Derived> | |||
9185 | StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective( | |||
9186 | OMPTargetSimdDirective *D) { | |||
9187 | DeclarationNameInfo DirName; | |||
9188 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_simd, DirName, nullptr, | |||
9189 | D->getBeginLoc()); | |||
9190 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9191 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9192 | return Res; | |||
9193 | } | |||
9194 | ||||
9195 | template <typename Derived> | |||
9196 | StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective( | |||
9197 | OMPTeamsDistributeDirective *D) { | |||
9198 | DeclarationNameInfo DirName; | |||
9199 | getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_distribute, DirName, | |||
9200 | nullptr, D->getBeginLoc()); | |||
9201 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9202 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9203 | return Res; | |||
9204 | } | |||
9205 | ||||
9206 | template <typename Derived> | |||
9207 | StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective( | |||
9208 | OMPTeamsDistributeSimdDirective *D) { | |||
9209 | DeclarationNameInfo DirName; | |||
9210 | getDerived().getSema().StartOpenMPDSABlock( | |||
9211 | OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc()); | |||
9212 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9213 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9214 | return Res; | |||
9215 | } | |||
9216 | ||||
9217 | template <typename Derived> | |||
9218 | StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective( | |||
9219 | OMPTeamsDistributeParallelForSimdDirective *D) { | |||
9220 | DeclarationNameInfo DirName; | |||
9221 | getDerived().getSema().StartOpenMPDSABlock( | |||
9222 | OMPD_teams_distribute_parallel_for_simd, DirName, nullptr, | |||
9223 | D->getBeginLoc()); | |||
9224 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9225 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9226 | return Res; | |||
9227 | } | |||
9228 | ||||
9229 | template <typename Derived> | |||
9230 | StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective( | |||
9231 | OMPTeamsDistributeParallelForDirective *D) { | |||
9232 | DeclarationNameInfo DirName; | |||
9233 | getDerived().getSema().StartOpenMPDSABlock( | |||
9234 | OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc()); | |||
9235 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9236 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9237 | return Res; | |||
9238 | } | |||
9239 | ||||
9240 | template <typename Derived> | |||
9241 | StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective( | |||
9242 | OMPTargetTeamsDirective *D) { | |||
9243 | DeclarationNameInfo DirName; | |||
9244 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName, | |||
9245 | nullptr, D->getBeginLoc()); | |||
9246 | auto Res = getDerived().TransformOMPExecutableDirective(D); | |||
9247 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9248 | return Res; | |||
9249 | } | |||
9250 | ||||
9251 | template <typename Derived> | |||
9252 | StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective( | |||
9253 | OMPTargetTeamsDistributeDirective *D) { | |||
9254 | DeclarationNameInfo DirName; | |||
9255 | getDerived().getSema().StartOpenMPDSABlock( | |||
9256 | OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc()); | |||
9257 | auto Res = getDerived().TransformOMPExecutableDirective(D); | |||
9258 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9259 | return Res; | |||
9260 | } | |||
9261 | ||||
9262 | template <typename Derived> | |||
9263 | StmtResult | |||
9264 | TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective( | |||
9265 | OMPTargetTeamsDistributeParallelForDirective *D) { | |||
9266 | DeclarationNameInfo DirName; | |||
9267 | getDerived().getSema().StartOpenMPDSABlock( | |||
9268 | OMPD_target_teams_distribute_parallel_for, DirName, nullptr, | |||
9269 | D->getBeginLoc()); | |||
9270 | auto Res = getDerived().TransformOMPExecutableDirective(D); | |||
9271 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9272 | return Res; | |||
9273 | } | |||
9274 | ||||
9275 | template <typename Derived> | |||
9276 | StmtResult TreeTransform<Derived>:: | |||
9277 | TransformOMPTargetTeamsDistributeParallelForSimdDirective( | |||
9278 | OMPTargetTeamsDistributeParallelForSimdDirective *D) { | |||
9279 | DeclarationNameInfo DirName; | |||
9280 | getDerived().getSema().StartOpenMPDSABlock( | |||
9281 | OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr, | |||
9282 | D->getBeginLoc()); | |||
9283 | auto Res = getDerived().TransformOMPExecutableDirective(D); | |||
9284 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9285 | return Res; | |||
9286 | } | |||
9287 | ||||
9288 | template <typename Derived> | |||
9289 | StmtResult | |||
9290 | TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective( | |||
9291 | OMPTargetTeamsDistributeSimdDirective *D) { | |||
9292 | DeclarationNameInfo DirName; | |||
9293 | getDerived().getSema().StartOpenMPDSABlock( | |||
9294 | OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc()); | |||
9295 | auto Res = getDerived().TransformOMPExecutableDirective(D); | |||
9296 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9297 | return Res; | |||
9298 | } | |||
9299 | ||||
9300 | template <typename Derived> | |||
9301 | StmtResult | |||
9302 | TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) { | |||
9303 | DeclarationNameInfo DirName; | |||
9304 | getDerived().getSema().StartOpenMPDSABlock(OMPD_interop, DirName, nullptr, | |||
9305 | D->getBeginLoc()); | |||
9306 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9307 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9308 | return Res; | |||
9309 | } | |||
9310 | ||||
9311 | template <typename Derived> | |||
9312 | StmtResult | |||
9313 | TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) { | |||
9314 | DeclarationNameInfo DirName; | |||
9315 | getDerived().getSema().StartOpenMPDSABlock(OMPD_dispatch, DirName, nullptr, | |||
9316 | D->getBeginLoc()); | |||
9317 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9318 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9319 | return Res; | |||
9320 | } | |||
9321 | ||||
9322 | template <typename Derived> | |||
9323 | StmtResult | |||
9324 | TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) { | |||
9325 | DeclarationNameInfo DirName; | |||
9326 | getDerived().getSema().StartOpenMPDSABlock(OMPD_masked, DirName, nullptr, | |||
9327 | D->getBeginLoc()); | |||
9328 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9329 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9330 | return Res; | |||
9331 | } | |||
9332 | ||||
9333 | template <typename Derived> | |||
9334 | StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective( | |||
9335 | OMPGenericLoopDirective *D) { | |||
9336 | DeclarationNameInfo DirName; | |||
9337 | getDerived().getSema().StartOpenMPDSABlock(OMPD_loop, DirName, nullptr, | |||
9338 | D->getBeginLoc()); | |||
9339 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9340 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9341 | return Res; | |||
9342 | } | |||
9343 | ||||
9344 | template <typename Derived> | |||
9345 | StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective( | |||
9346 | OMPTeamsGenericLoopDirective *D) { | |||
9347 | DeclarationNameInfo DirName; | |||
9348 | getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_loop, DirName, nullptr, | |||
9349 | D->getBeginLoc()); | |||
9350 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9351 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9352 | return Res; | |||
9353 | } | |||
9354 | ||||
9355 | template <typename Derived> | |||
9356 | StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective( | |||
9357 | OMPTargetTeamsGenericLoopDirective *D) { | |||
9358 | DeclarationNameInfo DirName; | |||
9359 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams_loop, DirName, | |||
9360 | nullptr, D->getBeginLoc()); | |||
9361 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9362 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9363 | return Res; | |||
9364 | } | |||
9365 | ||||
9366 | template <typename Derived> | |||
9367 | StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective( | |||
9368 | OMPParallelGenericLoopDirective *D) { | |||
9369 | DeclarationNameInfo DirName; | |||
9370 | getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_loop, DirName, | |||
9371 | nullptr, D->getBeginLoc()); | |||
9372 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9373 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9374 | return Res; | |||
9375 | } | |||
9376 | ||||
9377 | template <typename Derived> | |||
9378 | StmtResult | |||
9379 | TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective( | |||
9380 | OMPTargetParallelGenericLoopDirective *D) { | |||
9381 | DeclarationNameInfo DirName; | |||
9382 | getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_loop, DirName, | |||
9383 | nullptr, D->getBeginLoc()); | |||
9384 | StmtResult Res = getDerived().TransformOMPExecutableDirective(D); | |||
9385 | getDerived().getSema().EndOpenMPDSABlock(Res.get()); | |||
9386 | return Res; | |||
9387 | } | |||
9388 | ||||
9389 | //===----------------------------------------------------------------------===// | |||
9390 | // OpenMP clause transformation | |||
9391 | //===----------------------------------------------------------------------===// | |||
9392 | template <typename Derived> | |||
9393 | OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) { | |||
9394 | ExprResult Cond = getDerived().TransformExpr(C->getCondition()); | |||
9395 | if (Cond.isInvalid()) | |||
9396 | return nullptr; | |||
9397 | return getDerived().RebuildOMPIfClause( | |||
9398 | C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(), | |||
9399 | C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc()); | |||
9400 | } | |||
9401 | ||||
9402 | template <typename Derived> | |||
9403 | OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) { | |||
9404 | ExprResult Cond = getDerived().TransformExpr(C->getCondition()); | |||
9405 | if (Cond.isInvalid()) | |||
9406 | return nullptr; | |||
9407 | return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(), | |||
9408 | C->getLParenLoc(), C->getEndLoc()); | |||
9409 | } | |||
9410 | ||||
9411 | template <typename Derived> | |||
9412 | OMPClause * | |||
9413 | TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) { | |||
9414 | ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads()); | |||
9415 | if (NumThreads.isInvalid()) | |||
9416 | return nullptr; | |||
9417 | return getDerived().RebuildOMPNumThreadsClause( | |||
9418 | NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9419 | } | |||
9420 | ||||
9421 | template <typename Derived> | |||
9422 | OMPClause * | |||
9423 | TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) { | |||
9424 | ExprResult E = getDerived().TransformExpr(C->getSafelen()); | |||
9425 | if (E.isInvalid()) | |||
9426 | return nullptr; | |||
9427 | return getDerived().RebuildOMPSafelenClause( | |||
9428 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9429 | } | |||
9430 | ||||
9431 | template <typename Derived> | |||
9432 | OMPClause * | |||
9433 | TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) { | |||
9434 | ExprResult E = getDerived().TransformExpr(C->getAllocator()); | |||
9435 | if (E.isInvalid()) | |||
9436 | return nullptr; | |||
9437 | return getDerived().RebuildOMPAllocatorClause( | |||
9438 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9439 | } | |||
9440 | ||||
9441 | template <typename Derived> | |||
9442 | OMPClause * | |||
9443 | TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) { | |||
9444 | ExprResult E = getDerived().TransformExpr(C->getSimdlen()); | |||
9445 | if (E.isInvalid()) | |||
9446 | return nullptr; | |||
9447 | return getDerived().RebuildOMPSimdlenClause( | |||
9448 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9449 | } | |||
9450 | ||||
9451 | template <typename Derived> | |||
9452 | OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) { | |||
9453 | SmallVector<Expr *, 4> TransformedSizes; | |||
9454 | TransformedSizes.reserve(C->getNumSizes()); | |||
9455 | bool Changed = false; | |||
9456 | for (Expr *E : C->getSizesRefs()) { | |||
9457 | if (!E) { | |||
9458 | TransformedSizes.push_back(nullptr); | |||
9459 | continue; | |||
9460 | } | |||
9461 | ||||
9462 | ExprResult T = getDerived().TransformExpr(E); | |||
9463 | if (T.isInvalid()) | |||
9464 | return nullptr; | |||
9465 | if (E != T.get()) | |||
9466 | Changed = true; | |||
9467 | TransformedSizes.push_back(T.get()); | |||
9468 | } | |||
9469 | ||||
9470 | if (!Changed && !getDerived().AlwaysRebuild()) | |||
9471 | return C; | |||
9472 | return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(), | |||
9473 | C->getLParenLoc(), C->getEndLoc()); | |||
9474 | } | |||
9475 | ||||
9476 | template <typename Derived> | |||
9477 | OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) { | |||
9478 | if (!getDerived().AlwaysRebuild()) | |||
9479 | return C; | |||
9480 | return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc()); | |||
9481 | } | |||
9482 | ||||
9483 | template <typename Derived> | |||
9484 | OMPClause * | |||
9485 | TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) { | |||
9486 | ExprResult T = getDerived().TransformExpr(C->getFactor()); | |||
9487 | if (T.isInvalid()) | |||
9488 | return nullptr; | |||
9489 | Expr *Factor = T.get(); | |||
9490 | bool Changed = Factor != C->getFactor(); | |||
9491 | ||||
9492 | if (!Changed && !getDerived().AlwaysRebuild()) | |||
9493 | return C; | |||
9494 | return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(), | |||
9495 | C->getEndLoc()); | |||
9496 | } | |||
9497 | ||||
9498 | template <typename Derived> | |||
9499 | OMPClause * | |||
9500 | TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) { | |||
9501 | ExprResult E = getDerived().TransformExpr(C->getNumForLoops()); | |||
9502 | if (E.isInvalid()) | |||
9503 | return nullptr; | |||
9504 | return getDerived().RebuildOMPCollapseClause( | |||
9505 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9506 | } | |||
9507 | ||||
9508 | template <typename Derived> | |||
9509 | OMPClause * | |||
9510 | TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) { | |||
9511 | return getDerived().RebuildOMPDefaultClause( | |||
9512 | C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(), | |||
9513 | C->getLParenLoc(), C->getEndLoc()); | |||
9514 | } | |||
9515 | ||||
9516 | template <typename Derived> | |||
9517 | OMPClause * | |||
9518 | TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) { | |||
9519 | return getDerived().RebuildOMPProcBindClause( | |||
9520 | C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(), | |||
9521 | C->getLParenLoc(), C->getEndLoc()); | |||
9522 | } | |||
9523 | ||||
9524 | template <typename Derived> | |||
9525 | OMPClause * | |||
9526 | TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) { | |||
9527 | ExprResult E = getDerived().TransformExpr(C->getChunkSize()); | |||
9528 | if (E.isInvalid()) | |||
9529 | return nullptr; | |||
9530 | return getDerived().RebuildOMPScheduleClause( | |||
9531 | C->getFirstScheduleModifier(), C->getSecondScheduleModifier(), | |||
9532 | C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(), | |||
9533 | C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(), | |||
9534 | C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc()); | |||
9535 | } | |||
9536 | ||||
9537 | template <typename Derived> | |||
9538 | OMPClause * | |||
9539 | TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) { | |||
9540 | ExprResult E; | |||
9541 | if (auto *Num = C->getNumForLoops()) { | |||
9542 | E = getDerived().TransformExpr(Num); | |||
9543 | if (E.isInvalid()) | |||
9544 | return nullptr; | |||
9545 | } | |||
9546 | return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(), | |||
9547 | C->getLParenLoc(), E.get()); | |||
9548 | } | |||
9549 | ||||
9550 | template <typename Derived> | |||
9551 | OMPClause * | |||
9552 | TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) { | |||
9553 | ExprResult E; | |||
9554 | if (Expr *Evt = C->getEventHandler()) { | |||
9555 | E = getDerived().TransformExpr(Evt); | |||
9556 | if (E.isInvalid()) | |||
9557 | return nullptr; | |||
9558 | } | |||
9559 | return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(), | |||
9560 | C->getLParenLoc(), C->getEndLoc()); | |||
9561 | } | |||
9562 | ||||
9563 | template <typename Derived> | |||
9564 | OMPClause * | |||
9565 | TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) { | |||
9566 | // No need to rebuild this clause, no template-dependent parameters. | |||
9567 | return C; | |||
9568 | } | |||
9569 | ||||
9570 | template <typename Derived> | |||
9571 | OMPClause * | |||
9572 | TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) { | |||
9573 | // No need to rebuild this clause, no template-dependent parameters. | |||
9574 | return C; | |||
9575 | } | |||
9576 | ||||
9577 | template <typename Derived> | |||
9578 | OMPClause * | |||
9579 | TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) { | |||
9580 | // No need to rebuild this clause, no template-dependent parameters. | |||
9581 | return C; | |||
9582 | } | |||
9583 | ||||
9584 | template <typename Derived> | |||
9585 | OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) { | |||
9586 | // No need to rebuild this clause, no template-dependent parameters. | |||
9587 | return C; | |||
9588 | } | |||
9589 | ||||
9590 | template <typename Derived> | |||
9591 | OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) { | |||
9592 | // No need to rebuild this clause, no template-dependent parameters. | |||
9593 | return C; | |||
9594 | } | |||
9595 | ||||
9596 | template <typename Derived> | |||
9597 | OMPClause * | |||
9598 | TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) { | |||
9599 | // No need to rebuild this clause, no template-dependent parameters. | |||
9600 | return C; | |||
9601 | } | |||
9602 | ||||
9603 | template <typename Derived> | |||
9604 | OMPClause * | |||
9605 | TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) { | |||
9606 | // No need to rebuild this clause, no template-dependent parameters. | |||
9607 | return C; | |||
9608 | } | |||
9609 | ||||
9610 | template <typename Derived> | |||
9611 | OMPClause * | |||
9612 | TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) { | |||
9613 | // No need to rebuild this clause, no template-dependent parameters. | |||
9614 | return C; | |||
9615 | } | |||
9616 | ||||
9617 | template <typename Derived> | |||
9618 | OMPClause * | |||
9619 | TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) { | |||
9620 | // No need to rebuild this clause, no template-dependent parameters. | |||
9621 | return C; | |||
9622 | } | |||
9623 | ||||
9624 | template <typename Derived> | |||
9625 | OMPClause * | |||
9626 | TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) { | |||
9627 | // No need to rebuild this clause, no template-dependent parameters. | |||
9628 | return C; | |||
9629 | } | |||
9630 | ||||
9631 | template <typename Derived> | |||
9632 | OMPClause * | |||
9633 | TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) { | |||
9634 | // No need to rebuild this clause, no template-dependent parameters. | |||
9635 | return C; | |||
9636 | } | |||
9637 | ||||
9638 | template <typename Derived> | |||
9639 | OMPClause * | |||
9640 | TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) { | |||
9641 | // No need to rebuild this clause, no template-dependent parameters. | |||
9642 | return C; | |||
9643 | } | |||
9644 | ||||
9645 | template <typename Derived> | |||
9646 | OMPClause * | |||
9647 | TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) { | |||
9648 | // No need to rebuild this clause, no template-dependent parameters. | |||
9649 | return C; | |||
9650 | } | |||
9651 | ||||
9652 | template <typename Derived> | |||
9653 | OMPClause * | |||
9654 | TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) { | |||
9655 | // No need to rebuild this clause, no template-dependent parameters. | |||
9656 | return C; | |||
9657 | } | |||
9658 | ||||
9659 | template <typename Derived> | |||
9660 | OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) { | |||
9661 | // No need to rebuild this clause, no template-dependent parameters. | |||
9662 | return C; | |||
9663 | } | |||
9664 | ||||
9665 | template <typename Derived> | |||
9666 | OMPClause * | |||
9667 | TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) { | |||
9668 | // No need to rebuild this clause, no template-dependent parameters. | |||
9669 | return C; | |||
9670 | } | |||
9671 | ||||
9672 | template <typename Derived> | |||
9673 | OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) { | |||
9674 | ExprResult IVR = getDerived().TransformExpr(C->getInteropVar()); | |||
9675 | if (IVR.isInvalid()) | |||
9676 | return nullptr; | |||
9677 | ||||
9678 | OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync()); | |||
9679 | InteropInfo.PreferTypes.reserve(C->varlist_size() - 1); | |||
9680 | for (Expr *E : llvm::drop_begin(C->varlists())) { | |||
9681 | ExprResult ER = getDerived().TransformExpr(cast<Expr>(E)); | |||
9682 | if (ER.isInvalid()) | |||
9683 | return nullptr; | |||
9684 | InteropInfo.PreferTypes.push_back(ER.get()); | |||
9685 | } | |||
9686 | return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo, | |||
9687 | C->getBeginLoc(), C->getLParenLoc(), | |||
9688 | C->getVarLoc(), C->getEndLoc()); | |||
9689 | } | |||
9690 | ||||
9691 | template <typename Derived> | |||
9692 | OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) { | |||
9693 | ExprResult ER = getDerived().TransformExpr(C->getInteropVar()); | |||
9694 | if (ER.isInvalid()) | |||
9695 | return nullptr; | |||
9696 | return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(), | |||
9697 | C->getLParenLoc(), C->getVarLoc(), | |||
9698 | C->getEndLoc()); | |||
9699 | } | |||
9700 | ||||
9701 | template <typename Derived> | |||
9702 | OMPClause * | |||
9703 | TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) { | |||
9704 | ExprResult ER; | |||
9705 | if (Expr *IV = C->getInteropVar()) { | |||
9706 | ER = getDerived().TransformExpr(IV); | |||
9707 | if (ER.isInvalid()) | |||
9708 | return nullptr; | |||
9709 | } | |||
9710 | return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(), | |||
9711 | C->getLParenLoc(), C->getVarLoc(), | |||
9712 | C->getEndLoc()); | |||
9713 | } | |||
9714 | ||||
9715 | template <typename Derived> | |||
9716 | OMPClause * | |||
9717 | TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) { | |||
9718 | ExprResult Cond = getDerived().TransformExpr(C->getCondition()); | |||
9719 | if (Cond.isInvalid()) | |||
9720 | return nullptr; | |||
9721 | return getDerived().RebuildOMPNovariantsClause( | |||
9722 | Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9723 | } | |||
9724 | ||||
9725 | template <typename Derived> | |||
9726 | OMPClause * | |||
9727 | TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) { | |||
9728 | ExprResult Cond = getDerived().TransformExpr(C->getCondition()); | |||
9729 | if (Cond.isInvalid()) | |||
9730 | return nullptr; | |||
9731 | return getDerived().RebuildOMPNocontextClause( | |||
9732 | Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9733 | } | |||
9734 | ||||
9735 | template <typename Derived> | |||
9736 | OMPClause * | |||
9737 | TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) { | |||
9738 | ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID()); | |||
9739 | if (ThreadID.isInvalid()) | |||
9740 | return nullptr; | |||
9741 | return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(), | |||
9742 | C->getLParenLoc(), C->getEndLoc()); | |||
9743 | } | |||
9744 | ||||
9745 | template <typename Derived> | |||
9746 | OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) { | |||
9747 | ExprResult E = getDerived().TransformExpr(C->getAlignment()); | |||
9748 | if (E.isInvalid()) | |||
9749 | return nullptr; | |||
9750 | return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(), | |||
9751 | C->getLParenLoc(), C->getEndLoc()); | |||
9752 | } | |||
9753 | ||||
9754 | template <typename Derived> | |||
9755 | OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause( | |||
9756 | OMPUnifiedAddressClause *C) { | |||
9757 | llvm_unreachable("unified_address clause cannot appear in dependent context")::llvm::llvm_unreachable_internal("unified_address clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9757); | |||
9758 | } | |||
9759 | ||||
9760 | template <typename Derived> | |||
9761 | OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause( | |||
9762 | OMPUnifiedSharedMemoryClause *C) { | |||
9763 | llvm_unreachable(::llvm::llvm_unreachable_internal("unified_shared_memory clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9764) | |||
9764 | "unified_shared_memory clause cannot appear in dependent context")::llvm::llvm_unreachable_internal("unified_shared_memory clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9764); | |||
9765 | } | |||
9766 | ||||
9767 | template <typename Derived> | |||
9768 | OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause( | |||
9769 | OMPReverseOffloadClause *C) { | |||
9770 | llvm_unreachable("reverse_offload clause cannot appear in dependent context")::llvm::llvm_unreachable_internal("reverse_offload clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9770); | |||
9771 | } | |||
9772 | ||||
9773 | template <typename Derived> | |||
9774 | OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause( | |||
9775 | OMPDynamicAllocatorsClause *C) { | |||
9776 | llvm_unreachable(::llvm::llvm_unreachable_internal("dynamic_allocators clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9777) | |||
9777 | "dynamic_allocators clause cannot appear in dependent context")::llvm::llvm_unreachable_internal("dynamic_allocators clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9777); | |||
9778 | } | |||
9779 | ||||
9780 | template <typename Derived> | |||
9781 | OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause( | |||
9782 | OMPAtomicDefaultMemOrderClause *C) { | |||
9783 | llvm_unreachable(::llvm::llvm_unreachable_internal("atomic_default_mem_order clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9784) | |||
9784 | "atomic_default_mem_order clause cannot appear in dependent context")::llvm::llvm_unreachable_internal("atomic_default_mem_order clause cannot appear in dependent context" , "clang/lib/Sema/TreeTransform.h", 9784); | |||
9785 | } | |||
9786 | ||||
9787 | template <typename Derived> | |||
9788 | OMPClause * | |||
9789 | TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) { | |||
9790 | llvm::SmallVector<Expr *, 16> Vars; | |||
9791 | Vars.reserve(C->varlist_size()); | |||
9792 | for (auto *VE : C->varlists()) { | |||
9793 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9794 | if (EVar.isInvalid()) | |||
9795 | return nullptr; | |||
9796 | Vars.push_back(EVar.get()); | |||
9797 | } | |||
9798 | return getDerived().RebuildOMPPrivateClause( | |||
9799 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9800 | } | |||
9801 | ||||
9802 | template <typename Derived> | |||
9803 | OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause( | |||
9804 | OMPFirstprivateClause *C) { | |||
9805 | llvm::SmallVector<Expr *, 16> Vars; | |||
9806 | Vars.reserve(C->varlist_size()); | |||
9807 | for (auto *VE : C->varlists()) { | |||
9808 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9809 | if (EVar.isInvalid()) | |||
9810 | return nullptr; | |||
9811 | Vars.push_back(EVar.get()); | |||
9812 | } | |||
9813 | return getDerived().RebuildOMPFirstprivateClause( | |||
9814 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
9815 | } | |||
9816 | ||||
9817 | template <typename Derived> | |||
9818 | OMPClause * | |||
9819 | TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) { | |||
9820 | llvm::SmallVector<Expr *, 16> Vars; | |||
9821 | Vars.reserve(C->varlist_size()); | |||
9822 | for (auto *VE : C->varlists()) { | |||
9823 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9824 | if (EVar.isInvalid()) | |||
9825 | return nullptr; | |||
9826 | Vars.push_back(EVar.get()); | |||
9827 | } | |||
9828 | return getDerived().RebuildOMPLastprivateClause( | |||
9829 | Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(), | |||
9830 | C->getLParenLoc(), C->getEndLoc()); | |||
9831 | } | |||
9832 | ||||
9833 | template <typename Derived> | |||
9834 | OMPClause * | |||
9835 | TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) { | |||
9836 | llvm::SmallVector<Expr *, 16> Vars; | |||
9837 | Vars.reserve(C->varlist_size()); | |||
9838 | for (auto *VE : C->varlists()) { | |||
9839 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9840 | if (EVar.isInvalid()) | |||
9841 | return nullptr; | |||
9842 | Vars.push_back(EVar.get()); | |||
9843 | } | |||
9844 | return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(), | |||
9845 | C->getLParenLoc(), C->getEndLoc()); | |||
9846 | } | |||
9847 | ||||
9848 | template <typename Derived> | |||
9849 | OMPClause * | |||
9850 | TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) { | |||
9851 | llvm::SmallVector<Expr *, 16> Vars; | |||
9852 | Vars.reserve(C->varlist_size()); | |||
9853 | for (auto *VE : C->varlists()) { | |||
9854 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9855 | if (EVar.isInvalid()) | |||
9856 | return nullptr; | |||
9857 | Vars.push_back(EVar.get()); | |||
9858 | } | |||
9859 | CXXScopeSpec ReductionIdScopeSpec; | |||
9860 | ReductionIdScopeSpec.Adopt(C->getQualifierLoc()); | |||
9861 | ||||
9862 | DeclarationNameInfo NameInfo = C->getNameInfo(); | |||
9863 | if (NameInfo.getName()) { | |||
9864 | NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); | |||
9865 | if (!NameInfo.getName()) | |||
9866 | return nullptr; | |||
9867 | } | |||
9868 | // Build a list of all UDR decls with the same names ranged by the Scopes. | |||
9869 | // The Scope boundary is a duplication of the previous decl. | |||
9870 | llvm::SmallVector<Expr *, 16> UnresolvedReductions; | |||
9871 | for (auto *E : C->reduction_ops()) { | |||
9872 | // Transform all the decls. | |||
9873 | if (E) { | |||
9874 | auto *ULE = cast<UnresolvedLookupExpr>(E); | |||
9875 | UnresolvedSet<8> Decls; | |||
9876 | for (auto *D : ULE->decls()) { | |||
9877 | NamedDecl *InstD = | |||
9878 | cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D)); | |||
9879 | Decls.addDecl(InstD, InstD->getAccess()); | |||
9880 | } | |||
9881 | UnresolvedReductions.push_back( | |||
9882 | UnresolvedLookupExpr::Create( | |||
9883 | SemaRef.Context, /*NamingClass=*/nullptr, | |||
9884 | ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), | |||
9885 | NameInfo, /*ADL=*/true, ULE->isOverloaded(), | |||
9886 | Decls.begin(), Decls.end())); | |||
9887 | } else | |||
9888 | UnresolvedReductions.push_back(nullptr); | |||
9889 | } | |||
9890 | return getDerived().RebuildOMPReductionClause( | |||
9891 | Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(), | |||
9892 | C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(), | |||
9893 | ReductionIdScopeSpec, NameInfo, UnresolvedReductions); | |||
9894 | } | |||
9895 | ||||
9896 | template <typename Derived> | |||
9897 | OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause( | |||
9898 | OMPTaskReductionClause *C) { | |||
9899 | llvm::SmallVector<Expr *, 16> Vars; | |||
9900 | Vars.reserve(C->varlist_size()); | |||
9901 | for (auto *VE : C->varlists()) { | |||
9902 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9903 | if (EVar.isInvalid()) | |||
9904 | return nullptr; | |||
9905 | Vars.push_back(EVar.get()); | |||
9906 | } | |||
9907 | CXXScopeSpec ReductionIdScopeSpec; | |||
9908 | ReductionIdScopeSpec.Adopt(C->getQualifierLoc()); | |||
9909 | ||||
9910 | DeclarationNameInfo NameInfo = C->getNameInfo(); | |||
9911 | if (NameInfo.getName()) { | |||
9912 | NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); | |||
9913 | if (!NameInfo.getName()) | |||
9914 | return nullptr; | |||
9915 | } | |||
9916 | // Build a list of all UDR decls with the same names ranged by the Scopes. | |||
9917 | // The Scope boundary is a duplication of the previous decl. | |||
9918 | llvm::SmallVector<Expr *, 16> UnresolvedReductions; | |||
9919 | for (auto *E : C->reduction_ops()) { | |||
9920 | // Transform all the decls. | |||
9921 | if (E) { | |||
9922 | auto *ULE = cast<UnresolvedLookupExpr>(E); | |||
9923 | UnresolvedSet<8> Decls; | |||
9924 | for (auto *D : ULE->decls()) { | |||
9925 | NamedDecl *InstD = | |||
9926 | cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D)); | |||
9927 | Decls.addDecl(InstD, InstD->getAccess()); | |||
9928 | } | |||
9929 | UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( | |||
9930 | SemaRef.Context, /*NamingClass=*/nullptr, | |||
9931 | ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, | |||
9932 | /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end())); | |||
9933 | } else | |||
9934 | UnresolvedReductions.push_back(nullptr); | |||
9935 | } | |||
9936 | return getDerived().RebuildOMPTaskReductionClause( | |||
9937 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), | |||
9938 | C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions); | |||
9939 | } | |||
9940 | ||||
9941 | template <typename Derived> | |||
9942 | OMPClause * | |||
9943 | TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) { | |||
9944 | llvm::SmallVector<Expr *, 16> Vars; | |||
9945 | Vars.reserve(C->varlist_size()); | |||
9946 | for (auto *VE : C->varlists()) { | |||
9947 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9948 | if (EVar.isInvalid()) | |||
9949 | return nullptr; | |||
9950 | Vars.push_back(EVar.get()); | |||
9951 | } | |||
9952 | CXXScopeSpec ReductionIdScopeSpec; | |||
9953 | ReductionIdScopeSpec.Adopt(C->getQualifierLoc()); | |||
9954 | ||||
9955 | DeclarationNameInfo NameInfo = C->getNameInfo(); | |||
9956 | if (NameInfo.getName()) { | |||
9957 | NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); | |||
9958 | if (!NameInfo.getName()) | |||
9959 | return nullptr; | |||
9960 | } | |||
9961 | // Build a list of all UDR decls with the same names ranged by the Scopes. | |||
9962 | // The Scope boundary is a duplication of the previous decl. | |||
9963 | llvm::SmallVector<Expr *, 16> UnresolvedReductions; | |||
9964 | for (auto *E : C->reduction_ops()) { | |||
9965 | // Transform all the decls. | |||
9966 | if (E) { | |||
9967 | auto *ULE = cast<UnresolvedLookupExpr>(E); | |||
9968 | UnresolvedSet<8> Decls; | |||
9969 | for (auto *D : ULE->decls()) { | |||
9970 | NamedDecl *InstD = | |||
9971 | cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D)); | |||
9972 | Decls.addDecl(InstD, InstD->getAccess()); | |||
9973 | } | |||
9974 | UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( | |||
9975 | SemaRef.Context, /*NamingClass=*/nullptr, | |||
9976 | ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, | |||
9977 | /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end())); | |||
9978 | } else | |||
9979 | UnresolvedReductions.push_back(nullptr); | |||
9980 | } | |||
9981 | return getDerived().RebuildOMPInReductionClause( | |||
9982 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), | |||
9983 | C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions); | |||
9984 | } | |||
9985 | ||||
9986 | template <typename Derived> | |||
9987 | OMPClause * | |||
9988 | TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) { | |||
9989 | llvm::SmallVector<Expr *, 16> Vars; | |||
9990 | Vars.reserve(C->varlist_size()); | |||
9991 | for (auto *VE : C->varlists()) { | |||
9992 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
9993 | if (EVar.isInvalid()) | |||
9994 | return nullptr; | |||
9995 | Vars.push_back(EVar.get()); | |||
9996 | } | |||
9997 | ExprResult Step = getDerived().TransformExpr(C->getStep()); | |||
9998 | if (Step.isInvalid()) | |||
9999 | return nullptr; | |||
10000 | return getDerived().RebuildOMPLinearClause( | |||
10001 | Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(), | |||
10002 | C->getModifierLoc(), C->getColonLoc(), C->getEndLoc()); | |||
10003 | } | |||
10004 | ||||
10005 | template <typename Derived> | |||
10006 | OMPClause * | |||
10007 | TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) { | |||
10008 | llvm::SmallVector<Expr *, 16> Vars; | |||
10009 | Vars.reserve(C->varlist_size()); | |||
10010 | for (auto *VE : C->varlists()) { | |||
10011 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10012 | if (EVar.isInvalid()) | |||
10013 | return nullptr; | |||
10014 | Vars.push_back(EVar.get()); | |||
10015 | } | |||
10016 | ExprResult Alignment = getDerived().TransformExpr(C->getAlignment()); | |||
10017 | if (Alignment.isInvalid()) | |||
10018 | return nullptr; | |||
10019 | return getDerived().RebuildOMPAlignedClause( | |||
10020 | Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(), | |||
10021 | C->getColonLoc(), C->getEndLoc()); | |||
10022 | } | |||
10023 | ||||
10024 | template <typename Derived> | |||
10025 | OMPClause * | |||
10026 | TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) { | |||
10027 | llvm::SmallVector<Expr *, 16> Vars; | |||
10028 | Vars.reserve(C->varlist_size()); | |||
10029 | for (auto *VE : C->varlists()) { | |||
10030 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10031 | if (EVar.isInvalid()) | |||
10032 | return nullptr; | |||
10033 | Vars.push_back(EVar.get()); | |||
10034 | } | |||
10035 | return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(), | |||
10036 | C->getLParenLoc(), C->getEndLoc()); | |||
10037 | } | |||
10038 | ||||
10039 | template <typename Derived> | |||
10040 | OMPClause * | |||
10041 | TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) { | |||
10042 | llvm::SmallVector<Expr *, 16> Vars; | |||
10043 | Vars.reserve(C->varlist_size()); | |||
10044 | for (auto *VE : C->varlists()) { | |||
10045 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10046 | if (EVar.isInvalid()) | |||
10047 | return nullptr; | |||
10048 | Vars.push_back(EVar.get()); | |||
10049 | } | |||
10050 | return getDerived().RebuildOMPCopyprivateClause( | |||
10051 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10052 | } | |||
10053 | ||||
10054 | template <typename Derived> | |||
10055 | OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) { | |||
10056 | llvm::SmallVector<Expr *, 16> Vars; | |||
10057 | Vars.reserve(C->varlist_size()); | |||
10058 | for (auto *VE : C->varlists()) { | |||
10059 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10060 | if (EVar.isInvalid()) | |||
10061 | return nullptr; | |||
10062 | Vars.push_back(EVar.get()); | |||
10063 | } | |||
10064 | return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(), | |||
10065 | C->getLParenLoc(), C->getEndLoc()); | |||
10066 | } | |||
10067 | ||||
10068 | template <typename Derived> | |||
10069 | OMPClause * | |||
10070 | TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) { | |||
10071 | ExprResult E = getDerived().TransformExpr(C->getDepobj()); | |||
10072 | if (E.isInvalid()) | |||
10073 | return nullptr; | |||
10074 | return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(), | |||
10075 | C->getLParenLoc(), C->getEndLoc()); | |||
10076 | } | |||
10077 | ||||
10078 | template <typename Derived> | |||
10079 | OMPClause * | |||
10080 | TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) { | |||
10081 | llvm::SmallVector<Expr *, 16> Vars; | |||
10082 | Expr *DepModifier = C->getModifier(); | |||
10083 | if (DepModifier) { | |||
10084 | ExprResult DepModRes = getDerived().TransformExpr(DepModifier); | |||
10085 | if (DepModRes.isInvalid()) | |||
10086 | return nullptr; | |||
10087 | DepModifier = DepModRes.get(); | |||
10088 | } | |||
10089 | Vars.reserve(C->varlist_size()); | |||
10090 | for (auto *VE : C->varlists()) { | |||
10091 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10092 | if (EVar.isInvalid()) | |||
10093 | return nullptr; | |||
10094 | Vars.push_back(EVar.get()); | |||
10095 | } | |||
10096 | return getDerived().RebuildOMPDependClause( | |||
10097 | {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(), | |||
10098 | C->getOmpAllMemoryLoc()}, | |||
10099 | DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10100 | } | |||
10101 | ||||
10102 | template <typename Derived> | |||
10103 | OMPClause * | |||
10104 | TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) { | |||
10105 | ExprResult E = getDerived().TransformExpr(C->getDevice()); | |||
10106 | if (E.isInvalid()) | |||
10107 | return nullptr; | |||
10108 | return getDerived().RebuildOMPDeviceClause( | |||
10109 | C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(), | |||
10110 | C->getModifierLoc(), C->getEndLoc()); | |||
10111 | } | |||
10112 | ||||
10113 | template <typename Derived, class T> | |||
10114 | bool transformOMPMappableExprListClause( | |||
10115 | TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C, | |||
10116 | llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec, | |||
10117 | DeclarationNameInfo &MapperIdInfo, | |||
10118 | llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) { | |||
10119 | // Transform expressions in the list. | |||
10120 | Vars.reserve(C->varlist_size()); | |||
10121 | for (auto *VE : C->varlists()) { | |||
10122 | ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE)); | |||
10123 | if (EVar.isInvalid()) | |||
10124 | return true; | |||
10125 | Vars.push_back(EVar.get()); | |||
10126 | } | |||
10127 | // Transform mapper scope specifier and identifier. | |||
10128 | NestedNameSpecifierLoc QualifierLoc; | |||
10129 | if (C->getMapperQualifierLoc()) { | |||
10130 | QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc( | |||
10131 | C->getMapperQualifierLoc()); | |||
10132 | if (!QualifierLoc) | |||
10133 | return true; | |||
10134 | } | |||
10135 | MapperIdScopeSpec.Adopt(QualifierLoc); | |||
10136 | MapperIdInfo = C->getMapperIdInfo(); | |||
10137 | if (MapperIdInfo.getName()) { | |||
10138 | MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo); | |||
10139 | if (!MapperIdInfo.getName()) | |||
10140 | return true; | |||
10141 | } | |||
10142 | // Build a list of all candidate OMPDeclareMapperDecls, which is provided by | |||
10143 | // the previous user-defined mapper lookup in dependent environment. | |||
10144 | for (auto *E : C->mapperlists()) { | |||
10145 | // Transform all the decls. | |||
10146 | if (E) { | |||
10147 | auto *ULE = cast<UnresolvedLookupExpr>(E); | |||
10148 | UnresolvedSet<8> Decls; | |||
10149 | for (auto *D : ULE->decls()) { | |||
10150 | NamedDecl *InstD = | |||
10151 | cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D)); | |||
10152 | Decls.addDecl(InstD, InstD->getAccess()); | |||
10153 | } | |||
10154 | UnresolvedMappers.push_back(UnresolvedLookupExpr::Create( | |||
10155 | TT.getSema().Context, /*NamingClass=*/nullptr, | |||
10156 | MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context), | |||
10157 | MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), | |||
10158 | Decls.end())); | |||
10159 | } else { | |||
10160 | UnresolvedMappers.push_back(nullptr); | |||
10161 | } | |||
10162 | } | |||
10163 | return false; | |||
10164 | } | |||
10165 | ||||
10166 | template <typename Derived> | |||
10167 | OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) { | |||
10168 | OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10169 | llvm::SmallVector<Expr *, 16> Vars; | |||
10170 | CXXScopeSpec MapperIdScopeSpec; | |||
10171 | DeclarationNameInfo MapperIdInfo; | |||
10172 | llvm::SmallVector<Expr *, 16> UnresolvedMappers; | |||
10173 | if (transformOMPMappableExprListClause<Derived, OMPMapClause>( | |||
10174 | *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers)) | |||
10175 | return nullptr; | |||
10176 | return getDerived().RebuildOMPMapClause( | |||
10177 | C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), MapperIdScopeSpec, | |||
10178 | MapperIdInfo, C->getMapType(), C->isImplicitMapType(), C->getMapLoc(), | |||
10179 | C->getColonLoc(), Vars, Locs, UnresolvedMappers); | |||
10180 | } | |||
10181 | ||||
10182 | template <typename Derived> | |||
10183 | OMPClause * | |||
10184 | TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) { | |||
10185 | Expr *Allocator = C->getAllocator(); | |||
10186 | if (Allocator) { | |||
10187 | ExprResult AllocatorRes = getDerived().TransformExpr(Allocator); | |||
10188 | if (AllocatorRes.isInvalid()) | |||
10189 | return nullptr; | |||
10190 | Allocator = AllocatorRes.get(); | |||
10191 | } | |||
10192 | llvm::SmallVector<Expr *, 16> Vars; | |||
10193 | Vars.reserve(C->varlist_size()); | |||
10194 | for (auto *VE : C->varlists()) { | |||
10195 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10196 | if (EVar.isInvalid()) | |||
10197 | return nullptr; | |||
10198 | Vars.push_back(EVar.get()); | |||
10199 | } | |||
10200 | return getDerived().RebuildOMPAllocateClause( | |||
10201 | Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), | |||
10202 | C->getEndLoc()); | |||
10203 | } | |||
10204 | ||||
10205 | template <typename Derived> | |||
10206 | OMPClause * | |||
10207 | TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) { | |||
10208 | ExprResult E = getDerived().TransformExpr(C->getNumTeams()); | |||
10209 | if (E.isInvalid()) | |||
10210 | return nullptr; | |||
10211 | return getDerived().RebuildOMPNumTeamsClause( | |||
10212 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10213 | } | |||
10214 | ||||
10215 | template <typename Derived> | |||
10216 | OMPClause * | |||
10217 | TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) { | |||
10218 | ExprResult E = getDerived().TransformExpr(C->getThreadLimit()); | |||
10219 | if (E.isInvalid()) | |||
10220 | return nullptr; | |||
10221 | return getDerived().RebuildOMPThreadLimitClause( | |||
10222 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10223 | } | |||
10224 | ||||
10225 | template <typename Derived> | |||
10226 | OMPClause * | |||
10227 | TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) { | |||
10228 | ExprResult E = getDerived().TransformExpr(C->getPriority()); | |||
10229 | if (E.isInvalid()) | |||
10230 | return nullptr; | |||
10231 | return getDerived().RebuildOMPPriorityClause( | |||
10232 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10233 | } | |||
10234 | ||||
10235 | template <typename Derived> | |||
10236 | OMPClause * | |||
10237 | TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) { | |||
10238 | ExprResult E = getDerived().TransformExpr(C->getGrainsize()); | |||
10239 | if (E.isInvalid()) | |||
10240 | return nullptr; | |||
10241 | return getDerived().RebuildOMPGrainsizeClause( | |||
10242 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10243 | } | |||
10244 | ||||
10245 | template <typename Derived> | |||
10246 | OMPClause * | |||
10247 | TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) { | |||
10248 | ExprResult E = getDerived().TransformExpr(C->getNumTasks()); | |||
10249 | if (E.isInvalid()) | |||
10250 | return nullptr; | |||
10251 | return getDerived().RebuildOMPNumTasksClause( | |||
10252 | E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10253 | } | |||
10254 | ||||
10255 | template <typename Derived> | |||
10256 | OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) { | |||
10257 | ExprResult E = getDerived().TransformExpr(C->getHint()); | |||
10258 | if (E.isInvalid()) | |||
10259 | return nullptr; | |||
10260 | return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(), | |||
10261 | C->getLParenLoc(), C->getEndLoc()); | |||
10262 | } | |||
10263 | ||||
10264 | template <typename Derived> | |||
10265 | OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause( | |||
10266 | OMPDistScheduleClause *C) { | |||
10267 | ExprResult E = getDerived().TransformExpr(C->getChunkSize()); | |||
10268 | if (E.isInvalid()) | |||
10269 | return nullptr; | |||
10270 | return getDerived().RebuildOMPDistScheduleClause( | |||
10271 | C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(), | |||
10272 | C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc()); | |||
10273 | } | |||
10274 | ||||
10275 | template <typename Derived> | |||
10276 | OMPClause * | |||
10277 | TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) { | |||
10278 | // Rebuild Defaultmap Clause since we need to invoke the checking of | |||
10279 | // defaultmap(none:variable-category) after template initialization. | |||
10280 | return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(), | |||
10281 | C->getDefaultmapKind(), | |||
10282 | C->getBeginLoc(), | |||
10283 | C->getLParenLoc(), | |||
10284 | C->getDefaultmapModifierLoc(), | |||
10285 | C->getDefaultmapKindLoc(), | |||
10286 | C->getEndLoc()); | |||
10287 | } | |||
10288 | ||||
10289 | template <typename Derived> | |||
10290 | OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) { | |||
10291 | OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10292 | llvm::SmallVector<Expr *, 16> Vars; | |||
10293 | CXXScopeSpec MapperIdScopeSpec; | |||
10294 | DeclarationNameInfo MapperIdInfo; | |||
10295 | llvm::SmallVector<Expr *, 16> UnresolvedMappers; | |||
10296 | if (transformOMPMappableExprListClause<Derived, OMPToClause>( | |||
10297 | *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers)) | |||
10298 | return nullptr; | |||
10299 | return getDerived().RebuildOMPToClause( | |||
10300 | C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec, | |||
10301 | MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers); | |||
10302 | } | |||
10303 | ||||
10304 | template <typename Derived> | |||
10305 | OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) { | |||
10306 | OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10307 | llvm::SmallVector<Expr *, 16> Vars; | |||
10308 | CXXScopeSpec MapperIdScopeSpec; | |||
10309 | DeclarationNameInfo MapperIdInfo; | |||
10310 | llvm::SmallVector<Expr *, 16> UnresolvedMappers; | |||
10311 | if (transformOMPMappableExprListClause<Derived, OMPFromClause>( | |||
10312 | *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers)) | |||
10313 | return nullptr; | |||
10314 | return getDerived().RebuildOMPFromClause( | |||
10315 | C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec, | |||
10316 | MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers); | |||
10317 | } | |||
10318 | ||||
10319 | template <typename Derived> | |||
10320 | OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause( | |||
10321 | OMPUseDevicePtrClause *C) { | |||
10322 | llvm::SmallVector<Expr *, 16> Vars; | |||
10323 | Vars.reserve(C->varlist_size()); | |||
10324 | for (auto *VE : C->varlists()) { | |||
10325 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10326 | if (EVar.isInvalid()) | |||
10327 | return nullptr; | |||
10328 | Vars.push_back(EVar.get()); | |||
10329 | } | |||
10330 | OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10331 | return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs); | |||
10332 | } | |||
10333 | ||||
10334 | template <typename Derived> | |||
10335 | OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause( | |||
10336 | OMPUseDeviceAddrClause *C) { | |||
10337 | llvm::SmallVector<Expr *, 16> Vars; | |||
10338 | Vars.reserve(C->varlist_size()); | |||
10339 | for (auto *VE : C->varlists()) { | |||
10340 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10341 | if (EVar.isInvalid()) | |||
10342 | return nullptr; | |||
10343 | Vars.push_back(EVar.get()); | |||
10344 | } | |||
10345 | OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10346 | return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs); | |||
10347 | } | |||
10348 | ||||
10349 | template <typename Derived> | |||
10350 | OMPClause * | |||
10351 | TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { | |||
10352 | llvm::SmallVector<Expr *, 16> Vars; | |||
10353 | Vars.reserve(C->varlist_size()); | |||
10354 | for (auto *VE : C->varlists()) { | |||
10355 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10356 | if (EVar.isInvalid()) | |||
10357 | return nullptr; | |||
10358 | Vars.push_back(EVar.get()); | |||
10359 | } | |||
10360 | OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10361 | return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs); | |||
10362 | } | |||
10363 | ||||
10364 | template <typename Derived> | |||
10365 | OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause( | |||
10366 | OMPHasDeviceAddrClause *C) { | |||
10367 | llvm::SmallVector<Expr *, 16> Vars; | |||
10368 | Vars.reserve(C->varlist_size()); | |||
10369 | for (auto *VE : C->varlists()) { | |||
10370 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10371 | if (EVar.isInvalid()) | |||
10372 | return nullptr; | |||
10373 | Vars.push_back(EVar.get()); | |||
10374 | } | |||
10375 | OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10376 | return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs); | |||
10377 | } | |||
10378 | ||||
10379 | template <typename Derived> | |||
10380 | OMPClause * | |||
10381 | TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) { | |||
10382 | llvm::SmallVector<Expr *, 16> Vars; | |||
10383 | Vars.reserve(C->varlist_size()); | |||
10384 | for (auto *VE : C->varlists()) { | |||
10385 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10386 | if (EVar.isInvalid()) | |||
10387 | return nullptr; | |||
10388 | Vars.push_back(EVar.get()); | |||
10389 | } | |||
10390 | return getDerived().RebuildOMPNontemporalClause( | |||
10391 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10392 | } | |||
10393 | ||||
10394 | template <typename Derived> | |||
10395 | OMPClause * | |||
10396 | TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) { | |||
10397 | llvm::SmallVector<Expr *, 16> Vars; | |||
10398 | Vars.reserve(C->varlist_size()); | |||
10399 | for (auto *VE : C->varlists()) { | |||
10400 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10401 | if (EVar.isInvalid()) | |||
10402 | return nullptr; | |||
10403 | Vars.push_back(EVar.get()); | |||
10404 | } | |||
10405 | return getDerived().RebuildOMPInclusiveClause( | |||
10406 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10407 | } | |||
10408 | ||||
10409 | template <typename Derived> | |||
10410 | OMPClause * | |||
10411 | TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) { | |||
10412 | llvm::SmallVector<Expr *, 16> Vars; | |||
10413 | Vars.reserve(C->varlist_size()); | |||
10414 | for (auto *VE : C->varlists()) { | |||
10415 | ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); | |||
10416 | if (EVar.isInvalid()) | |||
10417 | return nullptr; | |||
10418 | Vars.push_back(EVar.get()); | |||
10419 | } | |||
10420 | return getDerived().RebuildOMPExclusiveClause( | |||
10421 | Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10422 | } | |||
10423 | ||||
10424 | template <typename Derived> | |||
10425 | OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause( | |||
10426 | OMPUsesAllocatorsClause *C) { | |||
10427 | SmallVector<Sema::UsesAllocatorsData, 16> Data; | |||
10428 | Data.reserve(C->getNumberOfAllocators()); | |||
10429 | for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) { | |||
10430 | OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I); | |||
10431 | ExprResult Allocator = getDerived().TransformExpr(D.Allocator); | |||
10432 | if (Allocator.isInvalid()) | |||
10433 | continue; | |||
10434 | ExprResult AllocatorTraits; | |||
10435 | if (Expr *AT = D.AllocatorTraits) { | |||
10436 | AllocatorTraits = getDerived().TransformExpr(AT); | |||
10437 | if (AllocatorTraits.isInvalid()) | |||
10438 | continue; | |||
10439 | } | |||
10440 | Sema::UsesAllocatorsData &NewD = Data.emplace_back(); | |||
10441 | NewD.Allocator = Allocator.get(); | |||
10442 | NewD.AllocatorTraits = AllocatorTraits.get(); | |||
10443 | NewD.LParenLoc = D.LParenLoc; | |||
10444 | NewD.RParenLoc = D.RParenLoc; | |||
10445 | } | |||
10446 | return getDerived().RebuildOMPUsesAllocatorsClause( | |||
10447 | Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); | |||
10448 | } | |||
10449 | ||||
10450 | template <typename Derived> | |||
10451 | OMPClause * | |||
10452 | TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) { | |||
10453 | SmallVector<Expr *, 4> Locators; | |||
10454 | Locators.reserve(C->varlist_size()); | |||
10455 | ExprResult ModifierRes; | |||
10456 | if (Expr *Modifier = C->getModifier()) { | |||
10457 | ModifierRes = getDerived().TransformExpr(Modifier); | |||
10458 | if (ModifierRes.isInvalid()) | |||
10459 | return nullptr; | |||
10460 | } | |||
10461 | for (Expr *E : C->varlists()) { | |||
10462 | ExprResult Locator = getDerived().TransformExpr(E); | |||
10463 | if (Locator.isInvalid()) | |||
10464 | continue; | |||
10465 | Locators.push_back(Locator.get()); | |||
10466 | } | |||
10467 | return getDerived().RebuildOMPAffinityClause( | |||
10468 | C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(), | |||
10469 | ModifierRes.get(), Locators); | |||
10470 | } | |||
10471 | ||||
10472 | template <typename Derived> | |||
10473 | OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) { | |||
10474 | return getDerived().RebuildOMPOrderClause(C->getKind(), C->getKindKwLoc(), | |||
10475 | C->getBeginLoc(), C->getLParenLoc(), | |||
10476 | C->getEndLoc()); | |||
10477 | } | |||
10478 | ||||
10479 | template <typename Derived> | |||
10480 | OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) { | |||
10481 | return getDerived().RebuildOMPBindClause( | |||
10482 | C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(), | |||
10483 | C->getLParenLoc(), C->getEndLoc()); | |||
10484 | } | |||
10485 | ||||
10486 | //===----------------------------------------------------------------------===// | |||
10487 | // Expression transformation | |||
10488 | //===----------------------------------------------------------------------===// | |||
10489 | template<typename Derived> | |||
10490 | ExprResult | |||
10491 | TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) { | |||
10492 | return TransformExpr(E->getSubExpr()); | |||
10493 | } | |||
10494 | ||||
10495 | template <typename Derived> | |||
10496 | ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr( | |||
10497 | SYCLUniqueStableNameExpr *E) { | |||
10498 | if (!E->isTypeDependent()) | |||
10499 | return E; | |||
10500 | ||||
10501 | TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo()); | |||
10502 | ||||
10503 | if (!NewT) | |||
10504 | return ExprError(); | |||
10505 | ||||
10506 | if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT) | |||
10507 | return E; | |||
10508 | ||||
10509 | return getDerived().RebuildSYCLUniqueStableNameExpr( | |||
10510 | E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT); | |||
10511 | } | |||
10512 | ||||
10513 | template<typename Derived> | |||
10514 | ExprResult | |||
10515 | TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) { | |||
10516 | if (!E->isTypeDependent()) | |||
10517 | return E; | |||
10518 | ||||
10519 | return getDerived().RebuildPredefinedExpr(E->getLocation(), | |||
10520 | E->getIdentKind()); | |||
10521 | } | |||
10522 | ||||
10523 | template<typename Derived> | |||
10524 | ExprResult | |||
10525 | TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) { | |||
10526 | NestedNameSpecifierLoc QualifierLoc; | |||
10527 | if (E->getQualifierLoc()) { | |||
10528 | QualifierLoc | |||
10529 | = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); | |||
10530 | if (!QualifierLoc) | |||
10531 | return ExprError(); | |||
10532 | } | |||
10533 | ||||
10534 | ValueDecl *ND | |||
10535 | = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(), | |||
10536 | E->getDecl())); | |||
10537 | if (!ND) | |||
10538 | return ExprError(); | |||
10539 | ||||
10540 | NamedDecl *Found = ND; | |||
10541 | if (E->getFoundDecl() != E->getDecl()) { | |||
10542 | Found = cast_or_null<NamedDecl>( | |||
10543 | getDerived().TransformDecl(E->getLocation(), E->getFoundDecl())); | |||
10544 | if (!Found) | |||
10545 | return ExprError(); | |||
10546 | } | |||
10547 | ||||
10548 | DeclarationNameInfo NameInfo = E->getNameInfo(); | |||
10549 | if (NameInfo.getName()) { | |||
10550 | NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); | |||
10551 | if (!NameInfo.getName()) | |||
10552 | return ExprError(); | |||
10553 | } | |||
10554 | ||||
10555 | if (!getDerived().AlwaysRebuild() && | |||
10556 | QualifierLoc == E->getQualifierLoc() && | |||
10557 | ND == E->getDecl() && | |||
10558 | Found == E->getFoundDecl() && | |||
10559 | NameInfo.getName() == E->getDecl()->getDeclName() && | |||
10560 | !E->hasExplicitTemplateArgs()) { | |||
10561 | ||||
10562 | // Mark it referenced in the new context regardless. | |||
10563 | // FIXME: this is a bit instantiation-specific. | |||
10564 | SemaRef.MarkDeclRefReferenced(E); | |||
10565 | ||||
10566 | return E; | |||
10567 | } | |||
10568 | ||||
10569 | TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr; | |||
10570 | if (E->hasExplicitTemplateArgs()) { | |||
10571 | TemplateArgs = &TransArgs; | |||
10572 | TransArgs.setLAngleLoc(E->getLAngleLoc()); | |||
10573 | TransArgs.setRAngleLoc(E->getRAngleLoc()); | |||
10574 | if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), | |||
10575 | E->getNumTemplateArgs(), | |||
10576 | TransArgs)) | |||
10577 | return ExprError(); | |||
10578 | } | |||
10579 | ||||
10580 | return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo, | |||
10581 | Found, TemplateArgs); | |||
10582 | } | |||
10583 | ||||
10584 | template<typename Derived> | |||
10585 | ExprResult | |||
10586 | TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) { | |||
10587 | return E; | |||
10588 | } | |||
10589 | ||||
10590 | template <typename Derived> | |||
10591 | ExprResult TreeTransform<Derived>::TransformFixedPointLiteral( | |||
10592 | FixedPointLiteral *E) { | |||
10593 | return E; | |||
10594 | } | |||
10595 | ||||
10596 | template<typename Derived> | |||
10597 | ExprResult | |||
10598 | TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) { | |||
10599 | return E; | |||
10600 | } | |||
10601 | ||||
10602 | template<typename Derived> | |||
10603 | ExprResult | |||
10604 | TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) { | |||
10605 | return E; | |||
10606 | } | |||
10607 | ||||
10608 | template<typename Derived> | |||
10609 | ExprResult | |||
10610 | TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) { | |||
10611 | return E; | |||
10612 | } | |||
10613 | ||||
10614 | template<typename Derived> | |||
10615 | ExprResult | |||
10616 | TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) { | |||
10617 | return E; | |||
10618 | } | |||
10619 | ||||
10620 | template<typename Derived> | |||
10621 | ExprResult | |||
10622 | TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) { | |||
10623 | return getDerived().TransformCallExpr(E); | |||
10624 | } | |||
10625 | ||||
10626 | template<typename Derived> | |||
10627 | ExprResult | |||
10628 | TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) { | |||
10629 | ExprResult ControllingExpr = | |||
10630 | getDerived().TransformExpr(E->getControllingExpr()); | |||
10631 | if (ControllingExpr.isInvalid()) | |||
10632 | return ExprError(); | |||
10633 | ||||
10634 | SmallVector<Expr *, 4> AssocExprs; | |||
10635 | SmallVector<TypeSourceInfo *, 4> AssocTypes; | |||
10636 | for (const GenericSelectionExpr::Association Assoc : E->associations()) { | |||
10637 | TypeSourceInfo *TSI = Assoc.getTypeSourceInfo(); | |||
10638 | if (TSI) { | |||
10639 | TypeSourceInfo *AssocType = getDerived().TransformType(TSI); | |||
10640 | if (!AssocType) | |||
10641 | return ExprError(); | |||
10642 | AssocTypes.push_back(AssocType); | |||
10643 | } else { | |||
10644 | AssocTypes.push_back(nullptr); | |||
10645 | } | |||
10646 | ||||
10647 | ExprResult AssocExpr = | |||
10648 | getDerived().TransformExpr(Assoc.getAssociationExpr()); | |||
10649 | if (AssocExpr.isInvalid()) | |||
10650 | return ExprError(); | |||
10651 | AssocExprs.push_back(AssocExpr.get()); | |||
10652 | } | |||
10653 | ||||
10654 | return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(), | |||
10655 | E->getDefaultLoc(), | |||
10656 | E->getRParenLoc(), | |||
10657 | ControllingExpr.get(), | |||
10658 | AssocTypes, | |||
10659 | AssocExprs); | |||
10660 | } | |||
10661 | ||||
10662 | template<typename Derived> | |||
10663 | ExprResult | |||
10664 | TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) { | |||
10665 | ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); | |||
10666 | if (SubExpr.isInvalid()) | |||
10667 | return ExprError(); | |||
10668 | ||||
10669 | if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) | |||
10670 | return E; | |||
10671 | ||||
10672 | return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(), | |||
10673 | E->getRParen()); | |||
10674 | } | |||
10675 | ||||
10676 | /// The operand of a unary address-of operator has special rules: it's | |||
10677 | /// allowed to refer to a non-static member of a class even if there's no 'this' | |||
10678 | /// object available. | |||
10679 | template<typename Derived> | |||
10680 | ExprResult | |||
10681 | TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) { | |||
10682 | if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E)) | |||
10683 | return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr); | |||
10684 | else | |||
10685 | return getDerived().TransformExpr(E); | |||
10686 | } | |||
10687 | ||||
10688 | template<typename Derived> | |||
10689 | ExprResult | |||
10690 | TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) { | |||
10691 | ExprResult SubExpr; | |||
10692 | if (E->getOpcode() == UO_AddrOf) | |||
10693 | SubExpr = TransformAddressOfOperand(E->getSubExpr()); | |||
10694 | else | |||
10695 | SubExpr = TransformExpr(E->getSubExpr()); | |||
10696 | if (SubExpr.isInvalid()) | |||
10697 | return ExprError(); | |||
10698 | ||||
10699 | if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) | |||
10700 | return E; | |||
10701 | ||||
10702 | return getDerived().RebuildUnaryOperator(E->getOperatorLoc(), | |||
10703 | E->getOpcode(), | |||
10704 | SubExpr.get()); | |||
10705 | } | |||
10706 | ||||
10707 | template<typename Derived> | |||
10708 | ExprResult | |||
10709 | TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) { | |||
10710 | // Transform the type. | |||
10711 | TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo()); | |||
10712 | if (!Type) | |||
10713 | return ExprError(); | |||
10714 | ||||
10715 | // Transform all of the components into components similar to what the | |||
10716 | // parser uses. | |||
10717 | // FIXME: It would be slightly more efficient in the non-dependent case to | |||
10718 | // just map FieldDecls, rather than requiring the rebuilder to look for | |||
10719 | // the fields again. However, __builtin_offsetof is rare enough in | |||
10720 | // template code that we don't care. | |||
10721 | bool ExprChanged = false; | |||
10722 | typedef Sema::OffsetOfComponent Component; | |||
10723 | SmallVector<Component, 4> Components; | |||
10724 | for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) { | |||
10725 | const OffsetOfNode &ON = E->getComponent(I); | |||
10726 | Component Comp; | |||
10727 | Comp.isBrackets = true; | |||
10728 | Comp.LocStart = ON.getSourceRange().getBegin(); | |||
10729 | Comp.LocEnd = ON.getSourceRange().getEnd(); | |||
10730 | switch (ON.getKind()) { | |||
10731 | case OffsetOfNode::Array: { | |||
10732 | Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex()); | |||
10733 | ExprResult Index = getDerived().TransformExpr(FromIndex); | |||
10734 | if (Index.isInvalid()) | |||
10735 | return ExprError(); | |||
10736 | ||||
10737 | ExprChanged = ExprChanged || Index.get() != FromIndex; | |||
10738 | Comp.isBrackets = true; | |||
10739 | Comp.U.E = Index.get(); | |||
10740 | break; | |||
10741 | } | |||
10742 | ||||
10743 | case OffsetOfNode::Field: | |||
10744 | case OffsetOfNode::Identifier: | |||
10745 | Comp.isBrackets = false; | |||
10746 | Comp.U.IdentInfo = ON.getFieldName(); | |||
10747 | if (!Comp.U.IdentInfo) | |||
10748 | continue; | |||
10749 | ||||
10750 | break; | |||
10751 | ||||
10752 | case OffsetOfNode::Base: | |||
10753 | // Will be recomputed during the rebuild. | |||
10754 | continue; | |||
10755 | } | |||
10756 | ||||
10757 | Components.push_back(Comp); | |||
10758 | } | |||
10759 | ||||
10760 | // If nothing changed, retain the existing expression. | |||
10761 | if (!getDerived().AlwaysRebuild() && | |||
10762 | Type == E->getTypeSourceInfo() && | |||
10763 | !ExprChanged) | |||
10764 | return E; | |||
10765 | ||||
10766 | // Build a new offsetof expression. | |||
10767 | return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, | |||
10768 | Components, E->getRParenLoc()); | |||
10769 | } | |||
10770 | ||||
10771 | template<typename Derived> | |||
10772 | ExprResult | |||
10773 | TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) { | |||
10774 | assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&(static_cast <bool> ((!E->getSourceExpr() || getDerived ().AlreadyTransformed(E->getType())) && "opaque value expression requires transformation" ) ? void (0) : __assert_fail ("(!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) && \"opaque value expression requires transformation\"" , "clang/lib/Sema/TreeTransform.h", 10775, __extension__ __PRETTY_FUNCTION__ )) | |||
10775 | "opaque value expression requires transformation")(static_cast <bool> ((!E->getSourceExpr() || getDerived ().AlreadyTransformed(E->getType())) && "opaque value expression requires transformation" ) ? void (0) : __assert_fail ("(!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) && \"opaque value expression requires transformation\"" , "clang/lib/Sema/TreeTransform.h", 10775, __extension__ __PRETTY_FUNCTION__ )); | |||
10776 | return E; | |||
10777 | } | |||
10778 | ||||
10779 | template<typename Derived> | |||
10780 | ExprResult | |||
10781 | TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) { | |||
10782 | return E; | |||
10783 | } | |||
10784 | ||||
10785 | template <typename Derived> | |||
10786 | ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) { | |||
10787 | llvm::SmallVector<Expr *, 8> Children; | |||
10788 | bool Changed = false; | |||
10789 | for (Expr *C : E->subExpressions()) { | |||
10790 | ExprResult NewC = getDerived().TransformExpr(C); | |||
10791 | if (NewC.isInvalid()) | |||
10792 | return ExprError(); | |||
10793 | Children.push_back(NewC.get()); | |||
10794 | ||||
10795 | Changed |= NewC.get() != C; | |||
10796 | } | |||
10797 | if (!getDerived().AlwaysRebuild() && !Changed) | |||
10798 | return E; | |||
10799 | return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), | |||
10800 | Children, E->getType()); | |||
10801 | } | |||
10802 | ||||
10803 | template<typename Derived> | |||
10804 | ExprResult | |||
10805 | TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) { | |||
10806 | // Rebuild the syntactic form. The original syntactic form has | |||
10807 | // opaque-value expressions in it, so strip those away and rebuild | |||
10808 | // the result. This is a really awful way of doing this, but the | |||
10809 | // better solution (rebuilding the semantic expressions and | |||
10810 | // rebinding OVEs as necessary) doesn't work; we'd need | |||
10811 | // TreeTransform to not strip away implicit conversions. | |||
10812 | Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E); | |||
10813 | ExprResult result = getDerived().TransformExpr(newSyntacticForm); | |||
10814 | if (result.isInvalid()) return ExprError(); | |||
10815 | ||||
10816 | // If that gives us a pseudo-object result back, the pseudo-object | |||
10817 | // expression must have been an lvalue-to-rvalue conversion which we | |||
10818 | // should reapply. | |||
10819 | if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject)) | |||
10820 | result = SemaRef.checkPseudoObjectRValue(result.get()); | |||
10821 | ||||
10822 | return result; | |||
10823 | } | |||
10824 | ||||
10825 | template<typename Derived> | |||
10826 | ExprResult | |||
10827 | TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr( | |||
10828 | UnaryExprOrTypeTraitExpr *E) { | |||
10829 | if (E->isArgumentType()) { | |||
10830 | TypeSourceInfo *OldT = E->getArgumentTypeInfo(); | |||
10831 | ||||
10832 | TypeSourceInfo *NewT = getDerived().TransformType(OldT); | |||
10833 | if (!NewT) | |||
10834 | return ExprError(); | |||
10835 | ||||
10836 | if (!getDerived().AlwaysRebuild() && OldT == NewT) | |||
10837 | return E; | |||
10838 | ||||
10839 | return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(), | |||
10840 | E->getKind(), | |||
10841 | E->getSourceRange()); | |||
10842 | } | |||
10843 | ||||
10844 | // C++0x [expr.sizeof]p1: | |||
10845 | // The operand is either an expression, which is an unevaluated operand | |||
10846 | // [...] | |||
10847 | EnterExpressionEvaluationContext Unevaluated( | |||
10848 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, | |||
10849 | Sema::ReuseLambdaContextDecl); | |||
10850 | ||||
10851 | // Try to recover if we have something like sizeof(T::X) where X is a type. | |||
10852 | // Notably, there must be *exactly* one set of parens if X is a type. | |||
10853 | TypeSourceInfo *RecoveryTSI = nullptr; | |||
10854 | ExprResult SubExpr; | |||
10855 | auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr()); | |||
10856 | if (auto *DRE = | |||
10857 | PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr) | |||
10858 | SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr( | |||
10859 | PE, DRE, false, &RecoveryTSI); | |||
10860 | else | |||
10861 | SubExpr = getDerived().TransformExpr(E->getArgumentExpr()); | |||
10862 | ||||
10863 | if (RecoveryTSI) { | |||
10864 | return getDerived().RebuildUnaryExprOrTypeTrait( | |||
10865 | RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange()); | |||
10866 | } else if (SubExpr.isInvalid()) | |||
10867 | return ExprError(); | |||
10868 | ||||
10869 | if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr()) | |||
10870 | return E; | |||
10871 | ||||
10872 | return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(), | |||
10873 | E->getOperatorLoc(), | |||
10874 | E->getKind(), | |||
10875 | E->getSourceRange()); | |||
10876 | } | |||
10877 | ||||
10878 | template<typename Derived> | |||
10879 | ExprResult | |||
10880 | TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) { | |||
10881 | ExprResult LHS = getDerived().TransformExpr(E->getLHS()); | |||
10882 | if (LHS.isInvalid()) | |||
10883 | return ExprError(); | |||
10884 | ||||
10885 | ExprResult RHS = getDerived().TransformExpr(E->getRHS()); | |||
10886 | if (RHS.isInvalid()) | |||
10887 | return ExprError(); | |||
10888 | ||||
10889 | ||||
10890 | if (!getDerived().AlwaysRebuild() && | |||
10891 | LHS.get() == E->getLHS() && | |||
10892 | RHS.get() == E->getRHS()) | |||
10893 | return E; | |||
10894 | ||||
10895 | return getDerived().RebuildArraySubscriptExpr( | |||
10896 | LHS.get(), | |||
10897 | /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc()); | |||
10898 | } | |||
10899 | ||||
10900 | template <typename Derived> | |||
10901 | ExprResult | |||
10902 | TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) { | |||
10903 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
10904 | if (Base.isInvalid()) | |||
10905 | return ExprError(); | |||
10906 | ||||
10907 | ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx()); | |||
10908 | if (RowIdx.isInvalid()) | |||
10909 | return ExprError(); | |||
10910 | ||||
10911 | ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx()); | |||
10912 | if (ColumnIdx.isInvalid()) | |||
10913 | return ExprError(); | |||
10914 | ||||
10915 | if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && | |||
10916 | RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx()) | |||
10917 | return E; | |||
10918 | ||||
10919 | return getDerived().RebuildMatrixSubscriptExpr( | |||
10920 | Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc()); | |||
10921 | } | |||
10922 | ||||
10923 | template <typename Derived> | |||
10924 | ExprResult | |||
10925 | TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) { | |||
10926 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
10927 | if (Base.isInvalid()) | |||
10928 | return ExprError(); | |||
10929 | ||||
10930 | ExprResult LowerBound; | |||
10931 | if (E->getLowerBound()) { | |||
10932 | LowerBound = getDerived().TransformExpr(E->getLowerBound()); | |||
10933 | if (LowerBound.isInvalid()) | |||
10934 | return ExprError(); | |||
10935 | } | |||
10936 | ||||
10937 | ExprResult Length; | |||
10938 | if (E->getLength()) { | |||
10939 | Length = getDerived().TransformExpr(E->getLength()); | |||
10940 | if (Length.isInvalid()) | |||
10941 | return ExprError(); | |||
10942 | } | |||
10943 | ||||
10944 | ExprResult Stride; | |||
10945 | if (Expr *Str = E->getStride()) { | |||
10946 | Stride = getDerived().TransformExpr(Str); | |||
10947 | if (Stride.isInvalid()) | |||
10948 | return ExprError(); | |||
10949 | } | |||
10950 | ||||
10951 | if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && | |||
10952 | LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength()) | |||
10953 | return E; | |||
10954 | ||||
10955 | return getDerived().RebuildOMPArraySectionExpr( | |||
10956 | Base.get(), E->getBase()->getEndLoc(), LowerBound.get(), | |||
10957 | E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(), | |||
10958 | E->getRBracketLoc()); | |||
10959 | } | |||
10960 | ||||
10961 | template <typename Derived> | |||
10962 | ExprResult | |||
10963 | TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) { | |||
10964 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
10965 | if (Base.isInvalid()) | |||
10966 | return ExprError(); | |||
10967 | ||||
10968 | SmallVector<Expr *, 4> Dims; | |||
10969 | bool ErrorFound = false; | |||
10970 | for (Expr *Dim : E->getDimensions()) { | |||
10971 | ExprResult DimRes = getDerived().TransformExpr(Dim); | |||
10972 | if (DimRes.isInvalid()) { | |||
10973 | ErrorFound = true; | |||
10974 | continue; | |||
10975 | } | |||
10976 | Dims.push_back(DimRes.get()); | |||
10977 | } | |||
10978 | ||||
10979 | if (ErrorFound) | |||
10980 | return ExprError(); | |||
10981 | return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(), | |||
10982 | E->getRParenLoc(), Dims, | |||
10983 | E->getBracketsRanges()); | |||
10984 | } | |||
10985 | ||||
10986 | template <typename Derived> | |||
10987 | ExprResult | |||
10988 | TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) { | |||
10989 | unsigned NumIterators = E->numOfIterators(); | |||
10990 | SmallVector<Sema::OMPIteratorData, 4> Data(NumIterators); | |||
10991 | ||||
10992 | bool ErrorFound = false; | |||
10993 | bool NeedToRebuild = getDerived().AlwaysRebuild(); | |||
10994 | for (unsigned I = 0; I < NumIterators; ++I) { | |||
10995 | auto *D = cast<VarDecl>(E->getIteratorDecl(I)); | |||
10996 | Data[I].DeclIdent = D->getIdentifier(); | |||
10997 | Data[I].DeclIdentLoc = D->getLocation(); | |||
10998 | if (D->getLocation() == D->getBeginLoc()) { | |||
10999 | assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&(static_cast <bool> (SemaRef.Context.hasSameType(D-> getType(), SemaRef.Context.IntTy) && "Implicit type must be int." ) ? void (0) : __assert_fail ("SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) && \"Implicit type must be int.\"" , "clang/lib/Sema/TreeTransform.h", 11000, __extension__ __PRETTY_FUNCTION__ )) | |||
11000 | "Implicit type must be int.")(static_cast <bool> (SemaRef.Context.hasSameType(D-> getType(), SemaRef.Context.IntTy) && "Implicit type must be int." ) ? void (0) : __assert_fail ("SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) && \"Implicit type must be int.\"" , "clang/lib/Sema/TreeTransform.h", 11000, __extension__ __PRETTY_FUNCTION__ )); | |||
11001 | } else { | |||
11002 | TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo()); | |||
11003 | QualType DeclTy = getDerived().TransformType(D->getType()); | |||
11004 | Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI); | |||
11005 | } | |||
11006 | OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); | |||
11007 | ExprResult Begin = getDerived().TransformExpr(Range.Begin); | |||
11008 | ExprResult End = getDerived().TransformExpr(Range.End); | |||
11009 | ExprResult Step = getDerived().TransformExpr(Range.Step); | |||
11010 | ErrorFound = ErrorFound || | |||
11011 | !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() && | |||
11012 | !Data[I].Type.get().isNull())) || | |||
11013 | Begin.isInvalid() || End.isInvalid() || Step.isInvalid(); | |||
11014 | if (ErrorFound) | |||
11015 | continue; | |||
11016 | Data[I].Range.Begin = Begin.get(); | |||
11017 | Data[I].Range.End = End.get(); | |||
11018 | Data[I].Range.Step = Step.get(); | |||
11019 | Data[I].AssignLoc = E->getAssignLoc(I); | |||
11020 | Data[I].ColonLoc = E->getColonLoc(I); | |||
11021 | Data[I].SecColonLoc = E->getSecondColonLoc(I); | |||
11022 | NeedToRebuild = | |||
11023 | NeedToRebuild || | |||
11024 | (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() != | |||
11025 | D->getType().getTypePtrOrNull()) || | |||
11026 | Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End || | |||
11027 | Range.Step != Data[I].Range.Step; | |||
11028 | } | |||
11029 | if (ErrorFound) | |||
11030 | return ExprError(); | |||
11031 | if (!NeedToRebuild) | |||
11032 | return E; | |||
11033 | ||||
11034 | ExprResult Res = getDerived().RebuildOMPIteratorExpr( | |||
11035 | E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data); | |||
11036 | if (!Res.isUsable()) | |||
11037 | return Res; | |||
11038 | auto *IE = cast<OMPIteratorExpr>(Res.get()); | |||
11039 | for (unsigned I = 0; I < NumIterators; ++I) | |||
11040 | getDerived().transformedLocalDecl(E->getIteratorDecl(I), | |||
11041 | IE->getIteratorDecl(I)); | |||
11042 | return Res; | |||
11043 | } | |||
11044 | ||||
11045 | template<typename Derived> | |||
11046 | ExprResult | |||
11047 | TreeTransform<Derived>::TransformCallExpr(CallExpr *E) { | |||
11048 | // Transform the callee. | |||
11049 | ExprResult Callee = getDerived().TransformExpr(E->getCallee()); | |||
11050 | if (Callee.isInvalid()) | |||
11051 | return ExprError(); | |||
11052 | ||||
11053 | // Transform arguments. | |||
11054 | bool ArgChanged = false; | |||
11055 | SmallVector<Expr*, 8> Args; | |||
11056 | if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, | |||
11057 | &ArgChanged)) | |||
11058 | return ExprError(); | |||
11059 | ||||
11060 | if (!getDerived().AlwaysRebuild() && | |||
11061 | Callee.get() == E->getCallee() && | |||
11062 | !ArgChanged) | |||
11063 | return SemaRef.MaybeBindToTemporary(E); | |||
11064 | ||||
11065 | // FIXME: Wrong source location information for the '('. | |||
11066 | SourceLocation FakeLParenLoc | |||
11067 | = ((Expr *)Callee.get())->getSourceRange().getBegin(); | |||
11068 | ||||
11069 | Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); | |||
11070 | if (E->hasStoredFPFeatures()) { | |||
11071 | FPOptionsOverride NewOverrides = E->getFPFeatures(); | |||
11072 | getSema().CurFPFeatures = | |||
11073 | NewOverrides.applyOverrides(getSema().getLangOpts()); | |||
11074 | getSema().FpPragmaStack.CurrentValue = NewOverrides; | |||
11075 | } | |||
11076 | ||||
11077 | return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc, | |||
11078 | Args, | |||
11079 | E->getRParenLoc()); | |||
11080 | } | |||
11081 | ||||
11082 | template<typename Derived> | |||
11083 | ExprResult | |||
11084 | TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { | |||
11085 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
11086 | if (Base.isInvalid()) | |||
11087 | return ExprError(); | |||
11088 | ||||
11089 | NestedNameSpecifierLoc QualifierLoc; | |||
11090 | if (E->hasQualifier()) { | |||
11091 | QualifierLoc | |||
11092 | = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); | |||
11093 | ||||
11094 | if (!QualifierLoc) | |||
11095 | return ExprError(); | |||
11096 | } | |||
11097 | SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); | |||
11098 | ||||
11099 | ValueDecl *Member | |||
11100 | = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(), | |||
11101 | E->getMemberDecl())); | |||
11102 | if (!Member) | |||
11103 | return ExprError(); | |||
11104 | ||||
11105 | NamedDecl *FoundDecl = E->getFoundDecl(); | |||
11106 | if (FoundDecl == E->getMemberDecl()) { | |||
11107 | FoundDecl = Member; | |||
11108 | } else { | |||
11109 | FoundDecl = cast_or_null<NamedDecl>( | |||
11110 | getDerived().TransformDecl(E->getMemberLoc(), FoundDecl)); | |||
11111 | if (!FoundDecl) | |||
11112 | return ExprError(); | |||
11113 | } | |||
11114 | ||||
11115 | if (!getDerived().AlwaysRebuild() && | |||
11116 | Base.get() == E->getBase() && | |||
11117 | QualifierLoc == E->getQualifierLoc() && | |||
11118 | Member == E->getMemberDecl() && | |||
11119 | FoundDecl == E->getFoundDecl() && | |||
11120 | !E->hasExplicitTemplateArgs()) { | |||
11121 | ||||
11122 | // Skip for member expression of (this->f), rebuilt thisi->f is needed | |||
11123 | // for Openmp where the field need to be privatizized in the case. | |||
11124 | if (!(isa<CXXThisExpr>(E->getBase()) && | |||
11125 | getSema().isOpenMPRebuildMemberExpr(cast<ValueDecl>(Member)))) { | |||
11126 | // Mark it referenced in the new context regardless. | |||
11127 | // FIXME: this is a bit instantiation-specific. | |||
11128 | SemaRef.MarkMemberReferenced(E); | |||
11129 | return E; | |||
11130 | } | |||
11131 | } | |||
11132 | ||||
11133 | TemplateArgumentListInfo TransArgs; | |||
11134 | if (E->hasExplicitTemplateArgs()) { | |||
11135 | TransArgs.setLAngleLoc(E->getLAngleLoc()); | |||
11136 | TransArgs.setRAngleLoc(E->getRAngleLoc()); | |||
11137 | if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), | |||
11138 | E->getNumTemplateArgs(), | |||
11139 | TransArgs)) | |||
11140 | return ExprError(); | |||
11141 | } | |||
11142 | ||||
11143 | // FIXME: Bogus source location for the operator | |||
11144 | SourceLocation FakeOperatorLoc = | |||
11145 | SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd()); | |||
11146 | ||||
11147 | // FIXME: to do this check properly, we will need to preserve the | |||
11148 | // first-qualifier-in-scope here, just in case we had a dependent | |||
11149 | // base (and therefore couldn't do the check) and a | |||
11150 | // nested-name-qualifier (and therefore could do the lookup). | |||
11151 | NamedDecl *FirstQualifierInScope = nullptr; | |||
11152 | DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo(); | |||
11153 | if (MemberNameInfo.getName()) { | |||
11154 | MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo); | |||
11155 | if (!MemberNameInfo.getName()) | |||
11156 | return ExprError(); | |||
11157 | } | |||
11158 | ||||
11159 | return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, | |||
11160 | E->isArrow(), | |||
11161 | QualifierLoc, | |||
11162 | TemplateKWLoc, | |||
11163 | MemberNameInfo, | |||
11164 | Member, | |||
11165 | FoundDecl, | |||
11166 | (E->hasExplicitTemplateArgs() | |||
11167 | ? &TransArgs : nullptr), | |||
11168 | FirstQualifierInScope); | |||
11169 | } | |||
11170 | ||||
11171 | template<typename Derived> | |||
11172 | ExprResult | |||
11173 | TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) { | |||
11174 | ExprResult LHS = getDerived().TransformExpr(E->getLHS()); | |||
11175 | if (LHS.isInvalid()) | |||
11176 | return ExprError(); | |||
11177 | ||||
11178 | ExprResult RHS = getDerived().TransformExpr(E->getRHS()); | |||
11179 | if (RHS.isInvalid()) | |||
11180 | return ExprError(); | |||
11181 | ||||
11182 | if (!getDerived().AlwaysRebuild() && | |||
11183 | LHS.get() == E->getLHS() && | |||
11184 | RHS.get() == E->getRHS()) | |||
11185 | return E; | |||
11186 | ||||
11187 | if (E->isCompoundAssignmentOp()) | |||
11188 | // FPFeatures has already been established from trailing storage | |||
11189 | return getDerived().RebuildBinaryOperator( | |||
11190 | E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get()); | |||
11191 | Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); | |||
11192 | FPOptionsOverride NewOverrides(E->getFPFeatures()); | |||
11193 | getSema().CurFPFeatures = | |||
11194 | NewOverrides.applyOverrides(getSema().getLangOpts()); | |||
11195 | getSema().FpPragmaStack.CurrentValue = NewOverrides; | |||
11196 | return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(), | |||
11197 | LHS.get(), RHS.get()); | |||
11198 | } | |||
11199 | ||||
11200 | template <typename Derived> | |||
11201 | ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator( | |||
11202 | CXXRewrittenBinaryOperator *E) { | |||
11203 | CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm(); | |||
11204 | ||||
11205 | ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS)); | |||
11206 | if (LHS.isInvalid()) | |||
11207 | return ExprError(); | |||
11208 | ||||
11209 | ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS)); | |||
11210 | if (RHS.isInvalid()) | |||
11211 | return ExprError(); | |||
11212 | ||||
11213 | // Extract the already-resolved callee declarations so that we can restrict | |||
11214 | // ourselves to using them as the unqualified lookup results when rebuilding. | |||
11215 | UnresolvedSet<2> UnqualLookups; | |||
11216 | bool ChangedAnyLookups = false; | |||
11217 | Expr *PossibleBinOps[] = {E->getSemanticForm(), | |||
11218 | const_cast<Expr *>(Decomp.InnerBinOp)}; | |||
11219 | for (Expr *PossibleBinOp : PossibleBinOps) { | |||
11220 | auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit()); | |||
11221 | if (!Op) | |||
11222 | continue; | |||
11223 | auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit()); | |||
11224 | if (!Callee || isa<CXXMethodDecl>(Callee->getDecl())) | |||
11225 | continue; | |||
11226 | ||||
11227 | // Transform the callee in case we built a call to a local extern | |||
11228 | // declaration. | |||
11229 | NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl( | |||
11230 | E->getOperatorLoc(), Callee->getFoundDecl())); | |||
11231 | if (!Found) | |||
11232 | return ExprError(); | |||
11233 | if (Found != Callee->getFoundDecl()) | |||
11234 | ChangedAnyLookups = true; | |||
11235 | UnqualLookups.addDecl(Found); | |||
11236 | } | |||
11237 | ||||
11238 | if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups && | |||
11239 | LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) { | |||
11240 | // Mark all functions used in the rewrite as referenced. Note that when | |||
11241 | // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be | |||
11242 | // function calls, and/or there might be a user-defined conversion sequence | |||
11243 | // applied to the operands of the <. | |||
11244 | // FIXME: this is a bit instantiation-specific. | |||
11245 | const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS}; | |||
11246 | SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt); | |||
11247 | return E; | |||
11248 | } | |||
11249 | ||||
11250 | return getDerived().RebuildCXXRewrittenBinaryOperator( | |||
11251 | E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get()); | |||
11252 | } | |||
11253 | ||||
11254 | template<typename Derived> | |||
11255 | ExprResult | |||
11256 | TreeTransform<Derived>::TransformCompoundAssignOperator( | |||
11257 | CompoundAssignOperator *E) { | |||
11258 | Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); | |||
11259 | FPOptionsOverride NewOverrides(E->getFPFeatures()); | |||
11260 | getSema().CurFPFeatures = | |||
11261 | NewOverrides.applyOverrides(getSema().getLangOpts()); | |||
11262 | getSema().FpPragmaStack.CurrentValue = NewOverrides; | |||
11263 | return getDerived().TransformBinaryOperator(E); | |||
11264 | } | |||
11265 | ||||
11266 | template<typename Derived> | |||
11267 | ExprResult TreeTransform<Derived>:: | |||
11268 | TransformBinaryConditionalOperator(BinaryConditionalOperator *e) { | |||
11269 | // Just rebuild the common and RHS expressions and see whether we | |||
11270 | // get any changes. | |||
11271 | ||||
11272 | ExprResult commonExpr = getDerived().TransformExpr(e->getCommon()); | |||
11273 | if (commonExpr.isInvalid()) | |||
11274 | return ExprError(); | |||
11275 | ||||
11276 | ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr()); | |||
11277 | if (rhs.isInvalid()) | |||
11278 | return ExprError(); | |||
11279 | ||||
11280 | if (!getDerived().AlwaysRebuild() && | |||
11281 | commonExpr.get() == e->getCommon() && | |||
11282 | rhs.get() == e->getFalseExpr()) | |||
11283 | return e; | |||
11284 | ||||
11285 | return getDerived().RebuildConditionalOperator(commonExpr.get(), | |||
11286 | e->getQuestionLoc(), | |||
11287 | nullptr, | |||
11288 | e->getColonLoc(), | |||
11289 | rhs.get()); | |||
11290 | } | |||
11291 | ||||
11292 | template<typename Derived> | |||
11293 | ExprResult | |||
11294 | TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) { | |||
11295 | ExprResult Cond = getDerived().TransformExpr(E->getCond()); | |||
11296 | if (Cond.isInvalid()) | |||
11297 | return ExprError(); | |||
11298 | ||||
11299 | ExprResult LHS = getDerived().TransformExpr(E->getLHS()); | |||
11300 | if (LHS.isInvalid()) | |||
11301 | return ExprError(); | |||
11302 | ||||
11303 | ExprResult RHS = getDerived().TransformExpr(E->getRHS()); | |||
11304 | if (RHS.isInvalid()) | |||
11305 | return ExprError(); | |||
11306 | ||||
11307 | if (!getDerived().AlwaysRebuild() && | |||
11308 | Cond.get() == E->getCond() && | |||
11309 | LHS.get() == E->getLHS() && | |||
11310 | RHS.get() == E->getRHS()) | |||
11311 | return E; | |||
11312 | ||||
11313 | return getDerived().RebuildConditionalOperator(Cond.get(), | |||
11314 | E->getQuestionLoc(), | |||
11315 | LHS.get(), | |||
11316 | E->getColonLoc(), | |||
11317 | RHS.get()); | |||
11318 | } | |||
11319 | ||||
11320 | template<typename Derived> | |||
11321 | ExprResult | |||
11322 | TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) { | |||
11323 | // Implicit casts are eliminated during transformation, since they | |||
11324 | // will be recomputed by semantic analysis after transformation. | |||
11325 | return getDerived().TransformExpr(E->getSubExprAsWritten()); | |||
11326 | } | |||
11327 | ||||
11328 | template<typename Derived> | |||
11329 | ExprResult | |||
11330 | TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) { | |||
11331 | TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten()); | |||
11332 | if (!Type) | |||
11333 | return ExprError(); | |||
11334 | ||||
11335 | ExprResult SubExpr | |||
11336 | = getDerived().TransformExpr(E->getSubExprAsWritten()); | |||
11337 | if (SubExpr.isInvalid()) | |||
11338 | return ExprError(); | |||
11339 | ||||
11340 | if (!getDerived().AlwaysRebuild() && | |||
11341 | Type == E->getTypeInfoAsWritten() && | |||
11342 | SubExpr.get() == E->getSubExpr()) | |||
11343 | return E; | |||
11344 | ||||
11345 | return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(), | |||
11346 | Type, | |||
11347 | E->getRParenLoc(), | |||
11348 | SubExpr.get()); | |||
11349 | } | |||
11350 | ||||
11351 | template<typename Derived> | |||
11352 | ExprResult | |||
11353 | TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) { | |||
11354 | TypeSourceInfo *OldT = E->getTypeSourceInfo(); | |||
11355 | TypeSourceInfo *NewT = getDerived().TransformType(OldT); | |||
11356 | if (!NewT) | |||
11357 | return ExprError(); | |||
11358 | ||||
11359 | ExprResult Init = getDerived().TransformExpr(E->getInitializer()); | |||
11360 | if (Init.isInvalid()) | |||
11361 | return ExprError(); | |||
11362 | ||||
11363 | if (!getDerived().AlwaysRebuild() && | |||
11364 | OldT == NewT && | |||
11365 | Init.get() == E->getInitializer()) | |||
11366 | return SemaRef.MaybeBindToTemporary(E); | |||
11367 | ||||
11368 | // Note: the expression type doesn't necessarily match the | |||
11369 | // type-as-written, but that's okay, because it should always be | |||
11370 | // derivable from the initializer. | |||
11371 | ||||
11372 | return getDerived().RebuildCompoundLiteralExpr( | |||
11373 | E->getLParenLoc(), NewT, | |||
11374 | /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get()); | |||
11375 | } | |||
11376 | ||||
11377 | template<typename Derived> | |||
11378 | ExprResult | |||
11379 | TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) { | |||
11380 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
11381 | if (Base.isInvalid()) | |||
11382 | return ExprError(); | |||
11383 | ||||
11384 | if (!getDerived().AlwaysRebuild() && | |||
11385 | Base.get() == E->getBase()) | |||
11386 | return E; | |||
11387 | ||||
11388 | // FIXME: Bad source location | |||
11389 | SourceLocation FakeOperatorLoc = | |||
11390 | SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc()); | |||
11391 | return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc, | |||
11392 | E->getAccessorLoc(), | |||
11393 | E->getAccessor()); | |||
11394 | } | |||
11395 | ||||
11396 | template<typename Derived> | |||
11397 | ExprResult | |||
11398 | TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) { | |||
11399 | if (InitListExpr *Syntactic = E->getSyntacticForm()) | |||
11400 | E = Syntactic; | |||
11401 | ||||
11402 | bool InitChanged = false; | |||
11403 | ||||
11404 | EnterExpressionEvaluationContext Context( | |||
11405 | getSema(), EnterExpressionEvaluationContext::InitList); | |||
11406 | ||||
11407 | SmallVector<Expr*, 4> Inits; | |||
11408 | if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false, | |||
11409 | Inits, &InitChanged)) | |||
11410 | return ExprError(); | |||
11411 | ||||
11412 | if (!getDerived().AlwaysRebuild() && !InitChanged) { | |||
11413 | // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr | |||
11414 | // in some cases. We can't reuse it in general, because the syntactic and | |||
11415 | // semantic forms are linked, and we can't know that semantic form will | |||
11416 | // match even if the syntactic form does. | |||
11417 | } | |||
11418 | ||||
11419 | return getDerived().RebuildInitList(E->getLBraceLoc(), Inits, | |||
11420 | E->getRBraceLoc()); | |||
11421 | } | |||
11422 | ||||
11423 | template<typename Derived> | |||
11424 | ExprResult | |||
11425 | TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) { | |||
11426 | Designation Desig; | |||
11427 | ||||
11428 | // transform the initializer value | |||
11429 | ExprResult Init = getDerived().TransformExpr(E->getInit()); | |||
11430 | if (Init.isInvalid()) | |||
11431 | return ExprError(); | |||
11432 | ||||
11433 | // transform the designators. | |||
11434 | SmallVector<Expr*, 4> ArrayExprs; | |||
11435 | bool ExprChanged = false; | |||
11436 | for (const DesignatedInitExpr::Designator &D : E->designators()) { | |||
11437 | if (D.isFieldDesignator()) { | |||
11438 | Desig.AddDesignator(Designator::getField(D.getFieldName(), | |||
11439 | D.getDotLoc(), | |||
11440 | D.getFieldLoc())); | |||
11441 | if (D.getField()) { | |||
11442 | FieldDecl *Field = cast_or_null<FieldDecl>( | |||
11443 | getDerived().TransformDecl(D.getFieldLoc(), D.getField())); | |||
11444 | if (Field != D.getField()) | |||
11445 | // Rebuild the expression when the transformed FieldDecl is | |||
11446 | // different to the already assigned FieldDecl. | |||
11447 | ExprChanged = true; | |||
11448 | } else { | |||
11449 | // Ensure that the designator expression is rebuilt when there isn't | |||
11450 | // a resolved FieldDecl in the designator as we don't want to assign | |||
11451 | // a FieldDecl to a pattern designator that will be instantiated again. | |||
11452 | ExprChanged = true; | |||
11453 | } | |||
11454 | continue; | |||
11455 | } | |||
11456 | ||||
11457 | if (D.isArrayDesignator()) { | |||
11458 | ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D)); | |||
11459 | if (Index.isInvalid()) | |||
11460 | return ExprError(); | |||
11461 | ||||
11462 | Desig.AddDesignator( | |||
11463 | Designator::getArray(Index.get(), D.getLBracketLoc())); | |||
11464 | ||||
11465 | ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D); | |||
11466 | ArrayExprs.push_back(Index.get()); | |||
11467 | continue; | |||
11468 | } | |||
11469 | ||||
11470 | assert(D.isArrayRangeDesignator() && "New kind of designator?")(static_cast <bool> (D.isArrayRangeDesignator() && "New kind of designator?") ? void (0) : __assert_fail ("D.isArrayRangeDesignator() && \"New kind of designator?\"" , "clang/lib/Sema/TreeTransform.h", 11470, __extension__ __PRETTY_FUNCTION__ )); | |||
11471 | ExprResult Start | |||
11472 | = getDerived().TransformExpr(E->getArrayRangeStart(D)); | |||
11473 | if (Start.isInvalid()) | |||
11474 | return ExprError(); | |||
11475 | ||||
11476 | ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D)); | |||
11477 | if (End.isInvalid()) | |||
11478 | return ExprError(); | |||
11479 | ||||
11480 | Desig.AddDesignator(Designator::getArrayRange(Start.get(), | |||
11481 | End.get(), | |||
11482 | D.getLBracketLoc(), | |||
11483 | D.getEllipsisLoc())); | |||
11484 | ||||
11485 | ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) || | |||
11486 | End.get() != E->getArrayRangeEnd(D); | |||
11487 | ||||
11488 | ArrayExprs.push_back(Start.get()); | |||
11489 | ArrayExprs.push_back(End.get()); | |||
11490 | } | |||
11491 | ||||
11492 | if (!getDerived().AlwaysRebuild() && | |||
11493 | Init.get() == E->getInit() && | |||
11494 | !ExprChanged) | |||
11495 | return E; | |||
11496 | ||||
11497 | return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs, | |||
11498 | E->getEqualOrColonLoc(), | |||
11499 | E->usesGNUSyntax(), Init.get()); | |||
11500 | } | |||
11501 | ||||
11502 | // Seems that if TransformInitListExpr() only works on the syntactic form of an | |||
11503 | // InitListExpr, then a DesignatedInitUpdateExpr is not encountered. | |||
11504 | template<typename Derived> | |||
11505 | ExprResult | |||
11506 | TreeTransform<Derived>::TransformDesignatedInitUpdateExpr( | |||
11507 | DesignatedInitUpdateExpr *E) { | |||
11508 | llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "::llvm::llvm_unreachable_internal("Unexpected DesignatedInitUpdateExpr in syntactic form of " "initializer", "clang/lib/Sema/TreeTransform.h", 11509) | |||
11509 | "initializer")::llvm::llvm_unreachable_internal("Unexpected DesignatedInitUpdateExpr in syntactic form of " "initializer", "clang/lib/Sema/TreeTransform.h", 11509); | |||
11510 | return ExprError(); | |||
11511 | } | |||
11512 | ||||
11513 | template<typename Derived> | |||
11514 | ExprResult | |||
11515 | TreeTransform<Derived>::TransformNoInitExpr( | |||
11516 | NoInitExpr *E) { | |||
11517 | llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer")::llvm::llvm_unreachable_internal("Unexpected NoInitExpr in syntactic form of initializer" , "clang/lib/Sema/TreeTransform.h", 11517); | |||
11518 | return ExprError(); | |||
11519 | } | |||
11520 | ||||
11521 | template<typename Derived> | |||
11522 | ExprResult | |||
11523 | TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) { | |||
11524 | llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer")::llvm::llvm_unreachable_internal("Unexpected ArrayInitLoopExpr outside of initializer" , "clang/lib/Sema/TreeTransform.h", 11524); | |||
11525 | return ExprError(); | |||
11526 | } | |||
11527 | ||||
11528 | template<typename Derived> | |||
11529 | ExprResult | |||
11530 | TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) { | |||
11531 | llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer")::llvm::llvm_unreachable_internal("Unexpected ArrayInitIndexExpr outside of initializer" , "clang/lib/Sema/TreeTransform.h", 11531); | |||
11532 | return ExprError(); | |||
11533 | } | |||
11534 | ||||
11535 | template<typename Derived> | |||
11536 | ExprResult | |||
11537 | TreeTransform<Derived>::TransformImplicitValueInitExpr( | |||
11538 | ImplicitValueInitExpr *E) { | |||
11539 | TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName()); | |||
11540 | ||||
11541 | // FIXME: Will we ever have proper type location here? Will we actually | |||
11542 | // need to transform the type? | |||
11543 | QualType T = getDerived().TransformType(E->getType()); | |||
11544 | if (T.isNull()) | |||
11545 | return ExprError(); | |||
11546 | ||||
11547 | if (!getDerived().AlwaysRebuild() && | |||
11548 | T == E->getType()) | |||
11549 | return E; | |||
11550 | ||||
11551 | return getDerived().RebuildImplicitValueInitExpr(T); | |||
11552 | } | |||
11553 | ||||
11554 | template<typename Derived> | |||
11555 | ExprResult | |||
11556 | TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) { | |||
11557 | TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo()); | |||
11558 | if (!TInfo) | |||
11559 | return ExprError(); | |||
11560 | ||||
11561 | ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); | |||
11562 | if (SubExpr.isInvalid()) | |||
11563 | return ExprError(); | |||
11564 | ||||
11565 | if (!getDerived().AlwaysRebuild() && | |||
11566 | TInfo == E->getWrittenTypeInfo() && | |||
11567 | SubExpr.get() == E->getSubExpr()) | |||
11568 | return E; | |||
11569 | ||||
11570 | return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(), | |||
11571 | TInfo, E->getRParenLoc()); | |||
11572 | } | |||
11573 | ||||
11574 | template<typename Derived> | |||
11575 | ExprResult | |||
11576 | TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) { | |||
11577 | bool ArgumentChanged = false; | |||
11578 | SmallVector<Expr*, 4> Inits; | |||
11579 | if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits, | |||
11580 | &ArgumentChanged)) | |||
11581 | return ExprError(); | |||
11582 | ||||
11583 | return getDerived().RebuildParenListExpr(E->getLParenLoc(), | |||
11584 | Inits, | |||
11585 | E->getRParenLoc()); | |||
11586 | } | |||
11587 | ||||
11588 | /// Transform an address-of-label expression. | |||
11589 | /// | |||
11590 | /// By default, the transformation of an address-of-label expression always | |||
11591 | /// rebuilds the expression, so that the label identifier can be resolved to | |||
11592 | /// the corresponding label statement by semantic analysis. | |||
11593 | template<typename Derived> | |||
11594 | ExprResult | |||
11595 | TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) { | |||
11596 | Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(), | |||
11597 | E->getLabel()); | |||
11598 | if (!LD) | |||
11599 | return ExprError(); | |||
11600 | ||||
11601 | return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(), | |||
11602 | cast<LabelDecl>(LD)); | |||
11603 | } | |||
11604 | ||||
11605 | template<typename Derived> | |||
11606 | ExprResult | |||
11607 | TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) { | |||
11608 | SemaRef.ActOnStartStmtExpr(); | |||
11609 | StmtResult SubStmt | |||
11610 | = getDerived().TransformCompoundStmt(E->getSubStmt(), true); | |||
11611 | if (SubStmt.isInvalid()) { | |||
11612 | SemaRef.ActOnStmtExprError(); | |||
11613 | return ExprError(); | |||
11614 | } | |||
11615 | ||||
11616 | unsigned OldDepth = E->getTemplateDepth(); | |||
11617 | unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth); | |||
11618 | ||||
11619 | if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth && | |||
11620 | SubStmt.get() == E->getSubStmt()) { | |||
11621 | // Calling this an 'error' is unintuitive, but it does the right thing. | |||
11622 | SemaRef.ActOnStmtExprError(); | |||
11623 | return SemaRef.MaybeBindToTemporary(E); | |||
11624 | } | |||
11625 | ||||
11626 | return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(), | |||
11627 | E->getRParenLoc(), NewDepth); | |||
11628 | } | |||
11629 | ||||
11630 | template<typename Derived> | |||
11631 | ExprResult | |||
11632 | TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) { | |||
11633 | ExprResult Cond = getDerived().TransformExpr(E->getCond()); | |||
11634 | if (Cond.isInvalid()) | |||
11635 | return ExprError(); | |||
11636 | ||||
11637 | ExprResult LHS = getDerived().TransformExpr(E->getLHS()); | |||
11638 | if (LHS.isInvalid()) | |||
11639 | return ExprError(); | |||
11640 | ||||
11641 | ExprResult RHS = getDerived().TransformExpr(E->getRHS()); | |||
11642 | if (RHS.isInvalid()) | |||
11643 | return ExprError(); | |||
11644 | ||||
11645 | if (!getDerived().AlwaysRebuild() && | |||
11646 | Cond.get() == E->getCond() && | |||
11647 | LHS.get() == E->getLHS() && | |||
11648 | RHS.get() == E->getRHS()) | |||
11649 | return E; | |||
11650 | ||||
11651 | return getDerived().RebuildChooseExpr(E->getBuiltinLoc(), | |||
11652 | Cond.get(), LHS.get(), RHS.get(), | |||
11653 | E->getRParenLoc()); | |||
11654 | } | |||
11655 | ||||
11656 | template<typename Derived> | |||
11657 | ExprResult | |||
11658 | TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) { | |||
11659 | return E; | |||
11660 | } | |||
11661 | ||||
11662 | template<typename Derived> | |||
11663 | ExprResult | |||
11664 | TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { | |||
11665 | switch (E->getOperator()) { | |||
11666 | case OO_New: | |||
11667 | case OO_Delete: | |||
11668 | case OO_Array_New: | |||
11669 | case OO_Array_Delete: | |||
11670 | llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr")::llvm::llvm_unreachable_internal("new and delete operators cannot use CXXOperatorCallExpr" , "clang/lib/Sema/TreeTransform.h", 11670); | |||
11671 | ||||
11672 | case OO_Subscript: | |||
11673 | case OO_Call: { | |||
11674 | // This is a call to an object's operator(). | |||
11675 | assert(E->getNumArgs() >= 1 && "Object call is missing arguments")(static_cast <bool> (E->getNumArgs() >= 1 && "Object call is missing arguments") ? void (0) : __assert_fail ("E->getNumArgs() >= 1 && \"Object call is missing arguments\"" , "clang/lib/Sema/TreeTransform.h", 11675, __extension__ __PRETTY_FUNCTION__ )); | |||
11676 | ||||
11677 | // Transform the object itself. | |||
11678 | ExprResult Object = getDerived().TransformExpr(E->getArg(0)); | |||
11679 | if (Object.isInvalid()) | |||
11680 | return ExprError(); | |||
11681 | ||||
11682 | // FIXME: Poor location information | |||
11683 | SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken( | |||
11684 | static_cast<Expr *>(Object.get())->getEndLoc()); | |||
11685 | ||||
11686 | // Transform the call arguments. | |||
11687 | SmallVector<Expr*, 8> Args; | |||
11688 | if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true, | |||
11689 | Args)) | |||
11690 | return ExprError(); | |||
11691 | ||||
11692 | if (E->getOperator() == OO_Subscript) | |||
11693 | return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc, | |||
11694 | Args, E->getEndLoc()); | |||
11695 | ||||
11696 | return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args, | |||
11697 | E->getEndLoc()); | |||
11698 | } | |||
11699 | ||||
11700 | #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ | |||
11701 | case OO_##Name: \ | |||
11702 | break; | |||
11703 | ||||
11704 | #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) | |||
11705 | #include "clang/Basic/OperatorKinds.def" | |||
11706 | ||||
11707 | case OO_Conditional: | |||
11708 | llvm_unreachable("conditional operator is not actually overloadable")::llvm::llvm_unreachable_internal("conditional operator is not actually overloadable" , "clang/lib/Sema/TreeTransform.h", 11708); | |||
11709 | ||||
11710 | case OO_None: | |||
11711 | case NUM_OVERLOADED_OPERATORS: | |||
11712 | llvm_unreachable("not an overloaded operator?")::llvm::llvm_unreachable_internal("not an overloaded operator?" , "clang/lib/Sema/TreeTransform.h", 11712); | |||
11713 | } | |||
11714 | ||||
11715 | ExprResult Callee = getDerived().TransformExpr(E->getCallee()); | |||
11716 | if (Callee.isInvalid()) | |||
11717 | return ExprError(); | |||
11718 | ||||
11719 | ExprResult First; | |||
11720 | if (E->getOperator() == OO_Amp) | |||
11721 | First = getDerived().TransformAddressOfOperand(E->getArg(0)); | |||
11722 | else | |||
11723 | First = getDerived().TransformExpr(E->getArg(0)); | |||
11724 | if (First.isInvalid()) | |||
11725 | return ExprError(); | |||
11726 | ||||
11727 | ExprResult Second; | |||
11728 | if (E->getNumArgs() == 2) { | |||
11729 | Second = getDerived().TransformExpr(E->getArg(1)); | |||
11730 | if (Second.isInvalid()) | |||
11731 | return ExprError(); | |||
11732 | } | |||
11733 | ||||
11734 | if (!getDerived().AlwaysRebuild() && | |||
11735 | Callee.get() == E->getCallee() && | |||
11736 | First.get() == E->getArg(0) && | |||
11737 | (E->getNumArgs() != 2 || Second.get() == E->getArg(1))) | |||
11738 | return SemaRef.MaybeBindToTemporary(E); | |||
11739 | ||||
11740 | Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); | |||
11741 | FPOptionsOverride NewOverrides(E->getFPFeatures()); | |||
11742 | getSema().CurFPFeatures = | |||
11743 | NewOverrides.applyOverrides(getSema().getLangOpts()); | |||
11744 | getSema().FpPragmaStack.CurrentValue = NewOverrides; | |||
11745 | ||||
11746 | return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(), | |||
11747 | E->getOperatorLoc(), | |||
11748 | Callee.get(), | |||
11749 | First.get(), | |||
11750 | Second.get()); | |||
11751 | } | |||
11752 | ||||
11753 | template<typename Derived> | |||
11754 | ExprResult | |||
11755 | TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) { | |||
11756 | return getDerived().TransformCallExpr(E); | |||
11757 | } | |||
11758 | ||||
11759 | template <typename Derived> | |||
11760 | ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) { | |||
11761 | bool NeedRebuildFunc = E->getIdentKind() == SourceLocExpr::Function && | |||
11762 | getSema().CurContext != E->getParentContext(); | |||
11763 | ||||
11764 | if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc) | |||
11765 | return E; | |||
11766 | ||||
11767 | return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(), | |||
11768 | E->getBeginLoc(), E->getEndLoc(), | |||
11769 | getSema().CurContext); | |||
11770 | } | |||
11771 | ||||
11772 | template<typename Derived> | |||
11773 | ExprResult | |||
11774 | TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) { | |||
11775 | // Transform the callee. | |||
11776 | ExprResult Callee = getDerived().TransformExpr(E->getCallee()); | |||
11777 | if (Callee.isInvalid()) | |||
11778 | return ExprError(); | |||
11779 | ||||
11780 | // Transform exec config. | |||
11781 | ExprResult EC = getDerived().TransformCallExpr(E->getConfig()); | |||
11782 | if (EC.isInvalid()) | |||
11783 | return ExprError(); | |||
11784 | ||||
11785 | // Transform arguments. | |||
11786 | bool ArgChanged = false; | |||
11787 | SmallVector<Expr*, 8> Args; | |||
11788 | if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, | |||
11789 | &ArgChanged)) | |||
11790 | return ExprError(); | |||
11791 | ||||
11792 | if (!getDerived().AlwaysRebuild() && | |||
11793 | Callee.get() == E->getCallee() && | |||
11794 | !ArgChanged) | |||
11795 | return SemaRef.MaybeBindToTemporary(E); | |||
11796 | ||||
11797 | // FIXME: Wrong source location information for the '('. | |||
11798 | SourceLocation FakeLParenLoc | |||
11799 | = ((Expr *)Callee.get())->getSourceRange().getBegin(); | |||
11800 | return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc, | |||
11801 | Args, | |||
11802 | E->getRParenLoc(), EC.get()); | |||
11803 | } | |||
11804 | ||||
11805 | template<typename Derived> | |||
11806 | ExprResult | |||
11807 | TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) { | |||
11808 | TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten()); | |||
11809 | if (!Type) | |||
11810 | return ExprError(); | |||
11811 | ||||
11812 | ExprResult SubExpr | |||
11813 | = getDerived().TransformExpr(E->getSubExprAsWritten()); | |||
11814 | if (SubExpr.isInvalid()) | |||
11815 | return ExprError(); | |||
11816 | ||||
11817 | if (!getDerived().AlwaysRebuild() && | |||
11818 | Type == E->getTypeInfoAsWritten() && | |||
11819 | SubExpr.get() == E->getSubExpr()) | |||
11820 | return E; | |||
11821 | return getDerived().RebuildCXXNamedCastExpr( | |||
11822 | E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(), | |||
11823 | Type, E->getAngleBrackets().getEnd(), | |||
11824 | // FIXME. this should be '(' location | |||
11825 | E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc()); | |||
11826 | } | |||
11827 | ||||
11828 | template<typename Derived> | |||
11829 | ExprResult | |||
11830 | TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) { | |||
11831 | TypeSourceInfo *TSI = | |||
11832 | getDerived().TransformType(BCE->getTypeInfoAsWritten()); | |||
11833 | if (!TSI) | |||
11834 | return ExprError(); | |||
11835 | ||||
11836 | ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr()); | |||
11837 | if (Sub.isInvalid()) | |||
11838 | return ExprError(); | |||
11839 | ||||
11840 | return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI, | |||
11841 | Sub.get(), BCE->getEndLoc()); | |||
11842 | } | |||
11843 | ||||
11844 | template<typename Derived> | |||
11845 | ExprResult | |||
11846 | TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) { | |||
11847 | return getDerived().TransformCXXNamedCastExpr(E); | |||
11848 | } | |||
11849 | ||||
11850 | template<typename Derived> | |||
11851 | ExprResult | |||
11852 | TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) { | |||
11853 | return getDerived().TransformCXXNamedCastExpr(E); | |||
11854 | } | |||
11855 | ||||
11856 | template<typename Derived> | |||
11857 | ExprResult | |||
11858 | TreeTransform<Derived>::TransformCXXReinterpretCastExpr( | |||
11859 | CXXReinterpretCastExpr *E) { | |||
11860 | return getDerived().TransformCXXNamedCastExpr(E); | |||
11861 | } | |||
11862 | ||||
11863 | template<typename Derived> | |||
11864 | ExprResult | |||
11865 | TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) { | |||
11866 | return getDerived().TransformCXXNamedCastExpr(E); | |||
11867 | } | |||
11868 | ||||
11869 | template<typename Derived> | |||
11870 | ExprResult | |||
11871 | TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) { | |||
11872 | return getDerived().TransformCXXNamedCastExpr(E); | |||
11873 | } | |||
11874 | ||||
11875 | template<typename Derived> | |||
11876 | ExprResult | |||
11877 | TreeTransform<Derived>::TransformCXXFunctionalCastExpr( | |||
11878 | CXXFunctionalCastExpr *E) { | |||
11879 | TypeSourceInfo *Type = | |||
11880 | getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten()); | |||
11881 | if (!Type) | |||
11882 | return ExprError(); | |||
11883 | ||||
11884 | ExprResult SubExpr | |||
11885 | = getDerived().TransformExpr(E->getSubExprAsWritten()); | |||
11886 | if (SubExpr.isInvalid()) | |||
11887 | return ExprError(); | |||
11888 | ||||
11889 | if (!getDerived().AlwaysRebuild() && | |||
11890 | Type == E->getTypeInfoAsWritten() && | |||
11891 | SubExpr.get() == E->getSubExpr()) | |||
11892 | return E; | |||
11893 | ||||
11894 | return getDerived().RebuildCXXFunctionalCastExpr(Type, | |||
11895 | E->getLParenLoc(), | |||
11896 | SubExpr.get(), | |||
11897 | E->getRParenLoc(), | |||
11898 | E->isListInitialization()); | |||
11899 | } | |||
11900 | ||||
11901 | template<typename Derived> | |||
11902 | ExprResult | |||
11903 | TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { | |||
11904 | if (E->isTypeOperand()) { | |||
11905 | TypeSourceInfo *TInfo | |||
11906 | = getDerived().TransformType(E->getTypeOperandSourceInfo()); | |||
11907 | if (!TInfo) | |||
11908 | return ExprError(); | |||
11909 | ||||
11910 | if (!getDerived().AlwaysRebuild() && | |||
11911 | TInfo == E->getTypeOperandSourceInfo()) | |||
11912 | return E; | |||
11913 | ||||
11914 | return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(), | |||
11915 | TInfo, E->getEndLoc()); | |||
11916 | } | |||
11917 | ||||
11918 | // Typeid's operand is an unevaluated context, unless it's a polymorphic | |||
11919 | // type. We must not unilaterally enter unevaluated context here, as then | |||
11920 | // semantic processing can re-transform an already transformed operand. | |||
11921 | Expr *Op = E->getExprOperand(); | |||
11922 | auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated; | |||
11923 | if (E->isGLValue()) | |||
11924 | if (auto *RecordT = Op->getType()->getAs<RecordType>()) | |||
11925 | if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic()) | |||
11926 | EvalCtx = SemaRef.ExprEvalContexts.back().Context; | |||
11927 | ||||
11928 | EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx, | |||
11929 | Sema::ReuseLambdaContextDecl); | |||
11930 | ||||
11931 | ExprResult SubExpr = getDerived().TransformExpr(Op); | |||
11932 | if (SubExpr.isInvalid()) | |||
11933 | return ExprError(); | |||
11934 | ||||
11935 | if (!getDerived().AlwaysRebuild() && | |||
11936 | SubExpr.get() == E->getExprOperand()) | |||
11937 | return E; | |||
11938 | ||||
11939 | return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(), | |||
11940 | SubExpr.get(), E->getEndLoc()); | |||
11941 | } | |||
11942 | ||||
11943 | template<typename Derived> | |||
11944 | ExprResult | |||
11945 | TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) { | |||
11946 | if (E->isTypeOperand()) { | |||
11947 | TypeSourceInfo *TInfo | |||
11948 | = getDerived().TransformType(E->getTypeOperandSourceInfo()); | |||
11949 | if (!TInfo) | |||
11950 | return ExprError(); | |||
11951 | ||||
11952 | if (!getDerived().AlwaysRebuild() && | |||
11953 | TInfo == E->getTypeOperandSourceInfo()) | |||
11954 | return E; | |||
11955 | ||||
11956 | return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(), | |||
11957 | TInfo, E->getEndLoc()); | |||
11958 | } | |||
11959 | ||||
11960 | EnterExpressionEvaluationContext Unevaluated( | |||
11961 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); | |||
11962 | ||||
11963 | ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); | |||
11964 | if (SubExpr.isInvalid()) | |||
11965 | return ExprError(); | |||
11966 | ||||
11967 | if (!getDerived().AlwaysRebuild() && | |||
11968 | SubExpr.get() == E->getExprOperand()) | |||
11969 | return E; | |||
11970 | ||||
11971 | return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(), | |||
11972 | SubExpr.get(), E->getEndLoc()); | |||
11973 | } | |||
11974 | ||||
11975 | template<typename Derived> | |||
11976 | ExprResult | |||
11977 | TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { | |||
11978 | return E; | |||
11979 | } | |||
11980 | ||||
11981 | template<typename Derived> | |||
11982 | ExprResult | |||
11983 | TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr( | |||
11984 | CXXNullPtrLiteralExpr *E) { | |||
11985 | return E; | |||
11986 | } | |||
11987 | ||||
11988 | template<typename Derived> | |||
11989 | ExprResult | |||
11990 | TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) { | |||
11991 | QualType T = getSema().getCurrentThisType(); | |||
11992 | ||||
11993 | if (!getDerived().AlwaysRebuild() && T == E->getType()) { | |||
11994 | // Mark it referenced in the new context regardless. | |||
11995 | // FIXME: this is a bit instantiation-specific. | |||
11996 | getSema().MarkThisReferenced(E); | |||
11997 | return E; | |||
11998 | } | |||
11999 | ||||
12000 | return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit()); | |||
12001 | } | |||
12002 | ||||
12003 | template<typename Derived> | |||
12004 | ExprResult | |||
12005 | TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) { | |||
12006 | ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); | |||
12007 | if (SubExpr.isInvalid()) | |||
12008 | return ExprError(); | |||
12009 | ||||
12010 | if (!getDerived().AlwaysRebuild() && | |||
12011 | SubExpr.get() == E->getSubExpr()) | |||
12012 | return E; | |||
12013 | ||||
12014 | return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(), | |||
12015 | E->isThrownVariableInScope()); | |||
12016 | } | |||
12017 | ||||
12018 | template<typename Derived> | |||
12019 | ExprResult | |||
12020 | TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) { | |||
12021 | ParmVarDecl *Param = cast_or_null<ParmVarDecl>( | |||
12022 | getDerived().TransformDecl(E->getBeginLoc(), E->getParam())); | |||
12023 | if (!Param) | |||
12024 | return ExprError(); | |||
12025 | ||||
12026 | if (!getDerived().AlwaysRebuild() && Param == E->getParam() && | |||
12027 | E->getUsedContext() == SemaRef.CurContext) | |||
12028 | return E; | |||
12029 | ||||
12030 | return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param); | |||
12031 | } | |||
12032 | ||||
12033 | template<typename Derived> | |||
12034 | ExprResult | |||
12035 | TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) { | |||
12036 | FieldDecl *Field = cast_or_null<FieldDecl>( | |||
12037 | getDerived().TransformDecl(E->getBeginLoc(), E->getField())); | |||
12038 | if (!Field) | |||
12039 | return ExprError(); | |||
12040 | ||||
12041 | if (!getDerived().AlwaysRebuild() && Field == E->getField() && | |||
12042 | E->getUsedContext() == SemaRef.CurContext) | |||
12043 | return E; | |||
12044 | ||||
12045 | return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field); | |||
12046 | } | |||
12047 | ||||
12048 | template<typename Derived> | |||
12049 | ExprResult | |||
12050 | TreeTransform<Derived>::TransformCXXScalarValueInitExpr( | |||
12051 | CXXScalarValueInitExpr *E) { | |||
12052 | TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); | |||
12053 | if (!T) | |||
12054 | return ExprError(); | |||
12055 | ||||
12056 | if (!getDerived().AlwaysRebuild() && | |||
12057 | T == E->getTypeSourceInfo()) | |||
12058 | return E; | |||
12059 | ||||
12060 | return getDerived().RebuildCXXScalarValueInitExpr(T, | |||
12061 | /*FIXME:*/T->getTypeLoc().getEndLoc(), | |||
12062 | E->getRParenLoc()); | |||
12063 | } | |||
12064 | ||||
12065 | template<typename Derived> | |||
12066 | ExprResult | |||
12067 | TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { | |||
12068 | // Transform the type that we're allocating | |||
12069 | TypeSourceInfo *AllocTypeInfo = | |||
12070 | getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo()); | |||
12071 | if (!AllocTypeInfo) | |||
12072 | return ExprError(); | |||
12073 | ||||
12074 | // Transform the size of the array we're allocating (if any). | |||
12075 | Optional<Expr *> ArraySize; | |||
12076 | if (E->isArray()) { | |||
12077 | ExprResult NewArraySize; | |||
12078 | if (Optional<Expr *> OldArraySize = E->getArraySize()) { | |||
12079 | NewArraySize = getDerived().TransformExpr(*OldArraySize); | |||
12080 | if (NewArraySize.isInvalid()) | |||
12081 | return ExprError(); | |||
12082 | } | |||
12083 | ArraySize = NewArraySize.get(); | |||
12084 | } | |||
12085 | ||||
12086 | // Transform the placement arguments (if any). | |||
12087 | bool ArgumentChanged = false; | |||
12088 | SmallVector<Expr*, 8> PlacementArgs; | |||
12089 | if (getDerived().TransformExprs(E->getPlacementArgs(), | |||
12090 | E->getNumPlacementArgs(), true, | |||
12091 | PlacementArgs, &ArgumentChanged)) | |||
12092 | return ExprError(); | |||
12093 | ||||
12094 | // Transform the initializer (if any). | |||
12095 | Expr *OldInit = E->getInitializer(); | |||
12096 | ExprResult NewInit; | |||
12097 | if (OldInit) | |||
12098 | NewInit = getDerived().TransformInitializer(OldInit, true); | |||
12099 | if (NewInit.isInvalid()) | |||
12100 | return ExprError(); | |||
12101 | ||||
12102 | // Transform new operator and delete operator. | |||
12103 | FunctionDecl *OperatorNew = nullptr; | |||
12104 | if (E->getOperatorNew()) { | |||
12105 | OperatorNew = cast_or_null<FunctionDecl>( | |||
12106 | getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew())); | |||
12107 | if (!OperatorNew) | |||
12108 | return ExprError(); | |||
12109 | } | |||
12110 | ||||
12111 | FunctionDecl *OperatorDelete = nullptr; | |||
12112 | if (E->getOperatorDelete()) { | |||
12113 | OperatorDelete = cast_or_null<FunctionDecl>( | |||
12114 | getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete())); | |||
12115 | if (!OperatorDelete) | |||
12116 | return ExprError(); | |||
12117 | } | |||
12118 | ||||
12119 | if (!getDerived().AlwaysRebuild() && | |||
12120 | AllocTypeInfo == E->getAllocatedTypeSourceInfo() && | |||
12121 | ArraySize == E->getArraySize() && | |||
12122 | NewInit.get() == OldInit && | |||
12123 | OperatorNew == E->getOperatorNew() && | |||
12124 | OperatorDelete == E->getOperatorDelete() && | |||
12125 | !ArgumentChanged) { | |||
12126 | // Mark any declarations we need as referenced. | |||
12127 | // FIXME: instantiation-specific. | |||
12128 | if (OperatorNew) | |||
12129 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew); | |||
12130 | if (OperatorDelete) | |||
12131 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete); | |||
12132 | ||||
12133 | if (E->isArray() && !E->getAllocatedType()->isDependentType()) { | |||
12134 | QualType ElementType | |||
12135 | = SemaRef.Context.getBaseElementType(E->getAllocatedType()); | |||
12136 | if (const RecordType *RecordT = ElementType->getAs<RecordType>()) { | |||
12137 | CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl()); | |||
12138 | if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) { | |||
12139 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor); | |||
12140 | } | |||
12141 | } | |||
12142 | } | |||
12143 | ||||
12144 | return E; | |||
12145 | } | |||
12146 | ||||
12147 | QualType AllocType = AllocTypeInfo->getType(); | |||
12148 | if (!ArraySize) { | |||
12149 | // If no array size was specified, but the new expression was | |||
12150 | // instantiated with an array type (e.g., "new T" where T is | |||
12151 | // instantiated with "int[4]"), extract the outer bound from the | |||
12152 | // array type as our array size. We do this with constant and | |||
12153 | // dependently-sized array types. | |||
12154 | const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType); | |||
12155 | if (!ArrayT) { | |||
12156 | // Do nothing | |||
12157 | } else if (const ConstantArrayType *ConsArrayT | |||
12158 | = dyn_cast<ConstantArrayType>(ArrayT)) { | |||
12159 | ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(), | |||
12160 | SemaRef.Context.getSizeType(), | |||
12161 | /*FIXME:*/ E->getBeginLoc()); | |||
12162 | AllocType = ConsArrayT->getElementType(); | |||
12163 | } else if (const DependentSizedArrayType *DepArrayT | |||
12164 | = dyn_cast<DependentSizedArrayType>(ArrayT)) { | |||
12165 | if (DepArrayT->getSizeExpr()) { | |||
12166 | ArraySize = DepArrayT->getSizeExpr(); | |||
12167 | AllocType = DepArrayT->getElementType(); | |||
12168 | } | |||
12169 | } | |||
12170 | } | |||
12171 | ||||
12172 | return getDerived().RebuildCXXNewExpr( | |||
12173 | E->getBeginLoc(), E->isGlobalNew(), | |||
12174 | /*FIXME:*/ E->getBeginLoc(), PlacementArgs, | |||
12175 | /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType, | |||
12176 | AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get()); | |||
12177 | } | |||
12178 | ||||
12179 | template<typename Derived> | |||
12180 | ExprResult | |||
12181 | TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) { | |||
12182 | ExprResult Operand = getDerived().TransformExpr(E->getArgument()); | |||
12183 | if (Operand.isInvalid()) | |||
12184 | return ExprError(); | |||
12185 | ||||
12186 | // Transform the delete operator, if known. | |||
12187 | FunctionDecl *OperatorDelete = nullptr; | |||
12188 | if (E->getOperatorDelete()) { | |||
12189 | OperatorDelete = cast_or_null<FunctionDecl>( | |||
12190 | getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete())); | |||
12191 | if (!OperatorDelete) | |||
12192 | return ExprError(); | |||
12193 | } | |||
12194 | ||||
12195 | if (!getDerived().AlwaysRebuild() && | |||
12196 | Operand.get() == E->getArgument() && | |||
12197 | OperatorDelete == E->getOperatorDelete()) { | |||
12198 | // Mark any declarations we need as referenced. | |||
12199 | // FIXME: instantiation-specific. | |||
12200 | if (OperatorDelete) | |||
12201 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete); | |||
12202 | ||||
12203 | if (!E->getArgument()->isTypeDependent()) { | |||
12204 | QualType Destroyed = SemaRef.Context.getBaseElementType( | |||
12205 | E->getDestroyedType()); | |||
12206 | if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { | |||
12207 | CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); | |||
12208 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), | |||
12209 | SemaRef.LookupDestructor(Record)); | |||
12210 | } | |||
12211 | } | |||
12212 | ||||
12213 | return E; | |||
12214 | } | |||
12215 | ||||
12216 | return getDerived().RebuildCXXDeleteExpr( | |||
12217 | E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get()); | |||
12218 | } | |||
12219 | ||||
12220 | template<typename Derived> | |||
12221 | ExprResult | |||
12222 | TreeTransform<Derived>::TransformCXXPseudoDestructorExpr( | |||
12223 | CXXPseudoDestructorExpr *E) { | |||
12224 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
12225 | if (Base.isInvalid()) | |||
12226 | return ExprError(); | |||
12227 | ||||
12228 | ParsedType ObjectTypePtr; | |||
12229 | bool MayBePseudoDestructor = false; | |||
12230 | Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(), | |||
12231 | E->getOperatorLoc(), | |||
12232 | E->isArrow()? tok::arrow : tok::period, | |||
12233 | ObjectTypePtr, | |||
12234 | MayBePseudoDestructor); | |||
12235 | if (Base.isInvalid()) | |||
12236 | return ExprError(); | |||
12237 | ||||
12238 | QualType ObjectType = ObjectTypePtr.get(); | |||
12239 | NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc(); | |||
12240 | if (QualifierLoc) { | |||
12241 | QualifierLoc | |||
12242 | = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType); | |||
12243 | if (!QualifierLoc) | |||
12244 | return ExprError(); | |||
12245 | } | |||
12246 | CXXScopeSpec SS; | |||
12247 | SS.Adopt(QualifierLoc); | |||
12248 | ||||
12249 | PseudoDestructorTypeStorage Destroyed; | |||
12250 | if (E->getDestroyedTypeInfo()) { | |||
12251 | TypeSourceInfo *DestroyedTypeInfo | |||
12252 | = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(), | |||
12253 | ObjectType, nullptr, SS); | |||
12254 | if (!DestroyedTypeInfo) | |||
12255 | return ExprError(); | |||
12256 | Destroyed = DestroyedTypeInfo; | |||
12257 | } else if (!ObjectType.isNull() && ObjectType->isDependentType()) { | |||
12258 | // We aren't likely to be able to resolve the identifier down to a type | |||
12259 | // now anyway, so just retain the identifier. | |||
12260 | Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(), | |||
12261 | E->getDestroyedTypeLoc()); | |||
12262 | } else { | |||
12263 | // Look for a destructor known with the given name. | |||
12264 | ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(), | |||
12265 | *E->getDestroyedTypeIdentifier(), | |||
12266 | E->getDestroyedTypeLoc(), | |||
12267 | /*Scope=*/nullptr, | |||
12268 | SS, ObjectTypePtr, | |||
12269 | false); | |||
12270 | if (!T) | |||
12271 | return ExprError(); | |||
12272 | ||||
12273 | Destroyed | |||
12274 | = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T), | |||
12275 | E->getDestroyedTypeLoc()); | |||
12276 | } | |||
12277 | ||||
12278 | TypeSourceInfo *ScopeTypeInfo = nullptr; | |||
12279 | if (E->getScopeTypeInfo()) { | |||
12280 | CXXScopeSpec EmptySS; | |||
12281 | ScopeTypeInfo = getDerived().TransformTypeInObjectScope( | |||
12282 | E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS); | |||
12283 | if (!ScopeTypeInfo) | |||
12284 | return ExprError(); | |||
12285 | } | |||
12286 | ||||
12287 | return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(), | |||
12288 | E->getOperatorLoc(), | |||
12289 | E->isArrow(), | |||
12290 | SS, | |||
12291 | ScopeTypeInfo, | |||
12292 | E->getColonColonLoc(), | |||
12293 | E->getTildeLoc(), | |||
12294 | Destroyed); | |||
12295 | } | |||
12296 | ||||
12297 | template <typename Derived> | |||
12298 | bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old, | |||
12299 | bool RequiresADL, | |||
12300 | LookupResult &R) { | |||
12301 | // Transform all the decls. | |||
12302 | bool AllEmptyPacks = true; | |||
12303 | for (auto *OldD : Old->decls()) { | |||
12304 | Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD); | |||
12305 | if (!InstD) { | |||
12306 | // Silently ignore these if a UsingShadowDecl instantiated to nothing. | |||
12307 | // This can happen because of dependent hiding. | |||
12308 | if (isa<UsingShadowDecl>(OldD)) | |||
12309 | continue; | |||
12310 | else { | |||
12311 | R.clear(); | |||
12312 | return true; | |||
12313 | } | |||
12314 | } | |||
12315 | ||||
12316 | // Expand using pack declarations. | |||
12317 | NamedDecl *SingleDecl = cast<NamedDecl>(InstD); | |||
12318 | ArrayRef<NamedDecl*> Decls = SingleDecl; | |||
12319 | if (auto *UPD = dyn_cast<UsingPackDecl>(InstD)) | |||
12320 | Decls = UPD->expansions(); | |||
12321 | ||||
12322 | // Expand using declarations. | |||
12323 | for (auto *D : Decls) { | |||
12324 | if (auto *UD = dyn_cast<UsingDecl>(D)) { | |||
12325 | for (auto *SD : UD->shadows()) | |||
12326 | R.addDecl(SD); | |||
12327 | } else { | |||
12328 | R.addDecl(D); | |||
12329 | } | |||
12330 | } | |||
12331 | ||||
12332 | AllEmptyPacks &= Decls.empty(); | |||
12333 | }; | |||
12334 | ||||
12335 | // C++ [temp.res]/8.4.2: | |||
12336 | // The program is ill-formed, no diagnostic required, if [...] lookup for | |||
12337 | // a name in the template definition found a using-declaration, but the | |||
12338 | // lookup in the corresponding scope in the instantiation odoes not find | |||
12339 | // any declarations because the using-declaration was a pack expansion and | |||
12340 | // the corresponding pack is empty | |||
12341 | if (AllEmptyPacks && !RequiresADL) { | |||
12342 | getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty) | |||
12343 | << isa<UnresolvedMemberExpr>(Old) << Old->getName(); | |||
12344 | return true; | |||
12345 | } | |||
12346 | ||||
12347 | // Resolve a kind, but don't do any further analysis. If it's | |||
12348 | // ambiguous, the callee needs to deal with it. | |||
12349 | R.resolveKind(); | |||
12350 | return false; | |||
12351 | } | |||
12352 | ||||
12353 | template<typename Derived> | |||
12354 | ExprResult | |||
12355 | TreeTransform<Derived>::TransformUnresolvedLookupExpr( | |||
12356 | UnresolvedLookupExpr *Old) { | |||
12357 | LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(), | |||
12358 | Sema::LookupOrdinaryName); | |||
12359 | ||||
12360 | // Transform the declaration set. | |||
12361 | if (TransformOverloadExprDecls(Old, Old->requiresADL(), R)) | |||
12362 | return ExprError(); | |||
12363 | ||||
12364 | // Rebuild the nested-name qualifier, if present. | |||
12365 | CXXScopeSpec SS; | |||
12366 | if (Old->getQualifierLoc()) { | |||
12367 | NestedNameSpecifierLoc QualifierLoc | |||
12368 | = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); | |||
12369 | if (!QualifierLoc) | |||
12370 | return ExprError(); | |||
12371 | ||||
12372 | SS.Adopt(QualifierLoc); | |||
12373 | } | |||
12374 | ||||
12375 | if (Old->getNamingClass()) { | |||
12376 | CXXRecordDecl *NamingClass | |||
12377 | = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( | |||
12378 | Old->getNameLoc(), | |||
12379 | Old->getNamingClass())); | |||
12380 | if (!NamingClass) { | |||
12381 | R.clear(); | |||
12382 | return ExprError(); | |||
12383 | } | |||
12384 | ||||
12385 | R.setNamingClass(NamingClass); | |||
12386 | } | |||
12387 | ||||
12388 | SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); | |||
12389 | ||||
12390 | // If we have neither explicit template arguments, nor the template keyword, | |||
12391 | // it's a normal declaration name or member reference. | |||
12392 | if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) { | |||
12393 | NamedDecl *D = R.getAsSingle<NamedDecl>(); | |||
12394 | // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an | |||
12395 | // instance member. In other contexts, BuildPossibleImplicitMemberExpr will | |||
12396 | // give a good diagnostic. | |||
12397 | if (D && D->isCXXInstanceMember()) { | |||
12398 | return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, | |||
12399 | /*TemplateArgs=*/nullptr, | |||
12400 | /*Scope=*/nullptr); | |||
12401 | } | |||
12402 | ||||
12403 | return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); | |||
12404 | } | |||
12405 | ||||
12406 | // If we have template arguments, rebuild them, then rebuild the | |||
12407 | // templateid expression. | |||
12408 | TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc()); | |||
12409 | if (Old->hasExplicitTemplateArgs() && | |||
12410 | getDerived().TransformTemplateArguments(Old->getTemplateArgs(), | |||
12411 | Old->getNumTemplateArgs(), | |||
12412 | TransArgs)) { | |||
12413 | R.clear(); | |||
12414 | return ExprError(); | |||
12415 | } | |||
12416 | ||||
12417 | return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, | |||
12418 | Old->requiresADL(), &TransArgs); | |||
12419 | } | |||
12420 | ||||
12421 | template<typename Derived> | |||
12422 | ExprResult | |||
12423 | TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) { | |||
12424 | bool ArgChanged = false; | |||
12425 | SmallVector<TypeSourceInfo *, 4> Args; | |||
12426 | for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { | |||
12427 | TypeSourceInfo *From = E->getArg(I); | |||
12428 | TypeLoc FromTL = From->getTypeLoc(); | |||
12429 | if (!FromTL.getAs<PackExpansionTypeLoc>()) { | |||
12430 | TypeLocBuilder TLB; | |||
12431 | TLB.reserve(FromTL.getFullDataSize()); | |||
12432 | QualType To = getDerived().TransformType(TLB, FromTL); | |||
12433 | if (To.isNull()) | |||
12434 | return ExprError(); | |||
12435 | ||||
12436 | if (To == From->getType()) | |||
12437 | Args.push_back(From); | |||
12438 | else { | |||
12439 | Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); | |||
12440 | ArgChanged = true; | |||
12441 | } | |||
12442 | continue; | |||
12443 | } | |||
12444 | ||||
12445 | ArgChanged = true; | |||
12446 | ||||
12447 | // We have a pack expansion. Instantiate it. | |||
12448 | PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>(); | |||
12449 | TypeLoc PatternTL = ExpansionTL.getPatternLoc(); | |||
12450 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
12451 | SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded); | |||
12452 | ||||
12453 | // Determine whether the set of unexpanded parameter packs can and should | |||
12454 | // be expanded. | |||
12455 | bool Expand = true; | |||
12456 | bool RetainExpansion = false; | |||
12457 | Optional<unsigned> OrigNumExpansions = | |||
12458 | ExpansionTL.getTypePtr()->getNumExpansions(); | |||
12459 | Optional<unsigned> NumExpansions = OrigNumExpansions; | |||
12460 | if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), | |||
12461 | PatternTL.getSourceRange(), | |||
12462 | Unexpanded, | |||
12463 | Expand, RetainExpansion, | |||
12464 | NumExpansions)) | |||
12465 | return ExprError(); | |||
12466 | ||||
12467 | if (!Expand) { | |||
12468 | // The transform has determined that we should perform a simple | |||
12469 | // transformation on the pack expansion, producing another pack | |||
12470 | // expansion. | |||
12471 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
12472 | ||||
12473 | TypeLocBuilder TLB; | |||
12474 | TLB.reserve(From->getTypeLoc().getFullDataSize()); | |||
12475 | ||||
12476 | QualType To = getDerived().TransformType(TLB, PatternTL); | |||
12477 | if (To.isNull()) | |||
12478 | return ExprError(); | |||
12479 | ||||
12480 | To = getDerived().RebuildPackExpansionType(To, | |||
12481 | PatternTL.getSourceRange(), | |||
12482 | ExpansionTL.getEllipsisLoc(), | |||
12483 | NumExpansions); | |||
12484 | if (To.isNull()) | |||
12485 | return ExprError(); | |||
12486 | ||||
12487 | PackExpansionTypeLoc ToExpansionTL | |||
12488 | = TLB.push<PackExpansionTypeLoc>(To); | |||
12489 | ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); | |||
12490 | Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); | |||
12491 | continue; | |||
12492 | } | |||
12493 | ||||
12494 | // Expand the pack expansion by substituting for each argument in the | |||
12495 | // pack(s). | |||
12496 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
12497 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); | |||
12498 | TypeLocBuilder TLB; | |||
12499 | TLB.reserve(PatternTL.getFullDataSize()); | |||
12500 | QualType To = getDerived().TransformType(TLB, PatternTL); | |||
12501 | if (To.isNull()) | |||
12502 | return ExprError(); | |||
12503 | ||||
12504 | if (To->containsUnexpandedParameterPack()) { | |||
12505 | To = getDerived().RebuildPackExpansionType(To, | |||
12506 | PatternTL.getSourceRange(), | |||
12507 | ExpansionTL.getEllipsisLoc(), | |||
12508 | NumExpansions); | |||
12509 | if (To.isNull()) | |||
12510 | return ExprError(); | |||
12511 | ||||
12512 | PackExpansionTypeLoc ToExpansionTL | |||
12513 | = TLB.push<PackExpansionTypeLoc>(To); | |||
12514 | ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); | |||
12515 | } | |||
12516 | ||||
12517 | Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); | |||
12518 | } | |||
12519 | ||||
12520 | if (!RetainExpansion) | |||
12521 | continue; | |||
12522 | ||||
12523 | // If we're supposed to retain a pack expansion, do so by temporarily | |||
12524 | // forgetting the partially-substituted parameter pack. | |||
12525 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
12526 | ||||
12527 | TypeLocBuilder TLB; | |||
12528 | TLB.reserve(From->getTypeLoc().getFullDataSize()); | |||
12529 | ||||
12530 | QualType To = getDerived().TransformType(TLB, PatternTL); | |||
12531 | if (To.isNull()) | |||
12532 | return ExprError(); | |||
12533 | ||||
12534 | To = getDerived().RebuildPackExpansionType(To, | |||
12535 | PatternTL.getSourceRange(), | |||
12536 | ExpansionTL.getEllipsisLoc(), | |||
12537 | NumExpansions); | |||
12538 | if (To.isNull()) | |||
12539 | return ExprError(); | |||
12540 | ||||
12541 | PackExpansionTypeLoc ToExpansionTL | |||
12542 | = TLB.push<PackExpansionTypeLoc>(To); | |||
12543 | ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); | |||
12544 | Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); | |||
12545 | } | |||
12546 | ||||
12547 | if (!getDerived().AlwaysRebuild() && !ArgChanged) | |||
12548 | return E; | |||
12549 | ||||
12550 | return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args, | |||
12551 | E->getEndLoc()); | |||
12552 | } | |||
12553 | ||||
12554 | template<typename Derived> | |||
12555 | ExprResult | |||
12556 | TreeTransform<Derived>::TransformConceptSpecializationExpr( | |||
12557 | ConceptSpecializationExpr *E) { | |||
12558 | const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten(); | |||
12559 | TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc); | |||
12560 | if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(), | |||
12561 | Old->NumTemplateArgs, TransArgs)) | |||
12562 | return ExprError(); | |||
12563 | ||||
12564 | return getDerived().RebuildConceptSpecializationExpr( | |||
12565 | E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(), | |||
12566 | E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(), | |||
12567 | &TransArgs); | |||
12568 | } | |||
12569 | ||||
12570 | template<typename Derived> | |||
12571 | ExprResult | |||
12572 | TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) { | |||
12573 | SmallVector<ParmVarDecl*, 4> TransParams; | |||
12574 | SmallVector<QualType, 4> TransParamTypes; | |||
12575 | Sema::ExtParameterInfoBuilder ExtParamInfos; | |||
12576 | ||||
12577 | // C++2a [expr.prim.req]p2 | |||
12578 | // Expressions appearing within a requirement-body are unevaluated operands. | |||
12579 | EnterExpressionEvaluationContext Ctx( | |||
12580 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); | |||
12581 | ||||
12582 | RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create( | |||
12583 | getSema().Context, getSema().CurContext, | |||
12584 | E->getBody()->getBeginLoc()); | |||
12585 | ||||
12586 | Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false); | |||
12587 | ||||
12588 | if (getDerived().TransformFunctionTypeParams(E->getRequiresKWLoc(), | |||
12589 | E->getLocalParameters(), | |||
12590 | /*ParamTypes=*/nullptr, | |||
12591 | /*ParamInfos=*/nullptr, | |||
12592 | TransParamTypes, &TransParams, | |||
12593 | ExtParamInfos)) | |||
12594 | return ExprError(); | |||
12595 | ||||
12596 | for (ParmVarDecl *Param : TransParams) | |||
12597 | Param->setDeclContext(Body); | |||
12598 | ||||
12599 | SmallVector<concepts::Requirement *, 4> TransReqs; | |||
12600 | if (getDerived().TransformRequiresExprRequirements(E->getRequirements(), | |||
12601 | TransReqs)) | |||
12602 | return ExprError(); | |||
12603 | ||||
12604 | for (concepts::Requirement *Req : TransReqs) { | |||
12605 | if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) { | |||
12606 | if (ER->getReturnTypeRequirement().isTypeConstraint()) { | |||
12607 | ER->getReturnTypeRequirement() | |||
12608 | .getTypeConstraintTemplateParameterList()->getParam(0) | |||
12609 | ->setDeclContext(Body); | |||
12610 | } | |||
12611 | } | |||
12612 | } | |||
12613 | ||||
12614 | return getDerived().RebuildRequiresExpr(E->getRequiresKWLoc(), Body, | |||
12615 | TransParams, TransReqs, | |||
12616 | E->getRBraceLoc()); | |||
12617 | } | |||
12618 | ||||
12619 | template<typename Derived> | |||
12620 | bool TreeTransform<Derived>::TransformRequiresExprRequirements( | |||
12621 | ArrayRef<concepts::Requirement *> Reqs, | |||
12622 | SmallVectorImpl<concepts::Requirement *> &Transformed) { | |||
12623 | for (concepts::Requirement *Req : Reqs) { | |||
12624 | concepts::Requirement *TransReq = nullptr; | |||
12625 | if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) | |||
12626 | TransReq = getDerived().TransformTypeRequirement(TypeReq); | |||
12627 | else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) | |||
12628 | TransReq = getDerived().TransformExprRequirement(ExprReq); | |||
12629 | else | |||
12630 | TransReq = getDerived().TransformNestedRequirement( | |||
12631 | cast<concepts::NestedRequirement>(Req)); | |||
12632 | if (!TransReq) | |||
12633 | return true; | |||
12634 | Transformed.push_back(TransReq); | |||
12635 | } | |||
12636 | return false; | |||
12637 | } | |||
12638 | ||||
12639 | template<typename Derived> | |||
12640 | concepts::TypeRequirement * | |||
12641 | TreeTransform<Derived>::TransformTypeRequirement( | |||
12642 | concepts::TypeRequirement *Req) { | |||
12643 | if (Req->isSubstitutionFailure()) { | |||
12644 | if (getDerived().AlwaysRebuild()) | |||
12645 | return getDerived().RebuildTypeRequirement( | |||
12646 | Req->getSubstitutionDiagnostic()); | |||
12647 | return Req; | |||
12648 | } | |||
12649 | TypeSourceInfo *TransType = getDerived().TransformType(Req->getType()); | |||
12650 | if (!TransType) | |||
12651 | return nullptr; | |||
12652 | return getDerived().RebuildTypeRequirement(TransType); | |||
12653 | } | |||
12654 | ||||
12655 | template<typename Derived> | |||
12656 | concepts::ExprRequirement * | |||
12657 | TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) { | |||
12658 | llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr; | |||
12659 | if (Req->isExprSubstitutionFailure()) | |||
12660 | TransExpr = Req->getExprSubstitutionDiagnostic(); | |||
12661 | else { | |||
12662 | ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr()); | |||
12663 | if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType()) | |||
12664 | TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get()); | |||
12665 | if (TransExprRes.isInvalid()) | |||
12666 | return nullptr; | |||
12667 | TransExpr = TransExprRes.get(); | |||
12668 | } | |||
12669 | ||||
12670 | llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq; | |||
12671 | const auto &RetReq = Req->getReturnTypeRequirement(); | |||
12672 | if (RetReq.isEmpty()) | |||
12673 | TransRetReq.emplace(); | |||
12674 | else if (RetReq.isSubstitutionFailure()) | |||
12675 | TransRetReq.emplace(RetReq.getSubstitutionDiagnostic()); | |||
12676 | else if (RetReq.isTypeConstraint()) { | |||
12677 | TemplateParameterList *OrigTPL = | |||
12678 | RetReq.getTypeConstraintTemplateParameterList(); | |||
12679 | TemplateParameterList *TPL = | |||
12680 | getDerived().TransformTemplateParameterList(OrigTPL); | |||
12681 | if (!TPL) | |||
12682 | return nullptr; | |||
12683 | TransRetReq.emplace(TPL); | |||
12684 | } | |||
12685 | assert(TransRetReq && "All code paths leading here must set TransRetReq")(static_cast <bool> (TransRetReq && "All code paths leading here must set TransRetReq" ) ? void (0) : __assert_fail ("TransRetReq && \"All code paths leading here must set TransRetReq\"" , "clang/lib/Sema/TreeTransform.h", 12685, __extension__ __PRETTY_FUNCTION__ )); | |||
12686 | if (Expr *E = TransExpr.dyn_cast<Expr *>()) | |||
12687 | return getDerived().RebuildExprRequirement(E, Req->isSimple(), | |||
12688 | Req->getNoexceptLoc(), | |||
12689 | std::move(*TransRetReq)); | |||
12690 | return getDerived().RebuildExprRequirement( | |||
12691 | TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(), | |||
12692 | Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq)); | |||
12693 | } | |||
12694 | ||||
12695 | template<typename Derived> | |||
12696 | concepts::NestedRequirement * | |||
12697 | TreeTransform<Derived>::TransformNestedRequirement( | |||
12698 | concepts::NestedRequirement *Req) { | |||
12699 | if (Req->isSubstitutionFailure()) { | |||
12700 | if (getDerived().AlwaysRebuild()) | |||
12701 | return getDerived().RebuildNestedRequirement( | |||
12702 | Req->getSubstitutionDiagnostic()); | |||
12703 | return Req; | |||
12704 | } | |||
12705 | ExprResult TransConstraint = | |||
12706 | getDerived().TransformExpr(Req->getConstraintExpr()); | |||
12707 | if (TransConstraint.isInvalid()) | |||
12708 | return nullptr; | |||
12709 | return getDerived().RebuildNestedRequirement(TransConstraint.get()); | |||
12710 | } | |||
12711 | ||||
12712 | template<typename Derived> | |||
12713 | ExprResult | |||
12714 | TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { | |||
12715 | TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo()); | |||
12716 | if (!T) | |||
12717 | return ExprError(); | |||
12718 | ||||
12719 | if (!getDerived().AlwaysRebuild() && | |||
12720 | T == E->getQueriedTypeSourceInfo()) | |||
12721 | return E; | |||
12722 | ||||
12723 | ExprResult SubExpr; | |||
12724 | { | |||
12725 | EnterExpressionEvaluationContext Unevaluated( | |||
12726 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); | |||
12727 | SubExpr = getDerived().TransformExpr(E->getDimensionExpression()); | |||
12728 | if (SubExpr.isInvalid()) | |||
12729 | return ExprError(); | |||
12730 | ||||
12731 | if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression()) | |||
12732 | return E; | |||
12733 | } | |||
12734 | ||||
12735 | return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T, | |||
12736 | SubExpr.get(), E->getEndLoc()); | |||
12737 | } | |||
12738 | ||||
12739 | template<typename Derived> | |||
12740 | ExprResult | |||
12741 | TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) { | |||
12742 | ExprResult SubExpr; | |||
12743 | { | |||
12744 | EnterExpressionEvaluationContext Unevaluated( | |||
12745 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); | |||
12746 | SubExpr = getDerived().TransformExpr(E->getQueriedExpression()); | |||
12747 | if (SubExpr.isInvalid()) | |||
12748 | return ExprError(); | |||
12749 | ||||
12750 | if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression()) | |||
12751 | return E; | |||
12752 | } | |||
12753 | ||||
12754 | return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(), | |||
12755 | SubExpr.get(), E->getEndLoc()); | |||
12756 | } | |||
12757 | ||||
12758 | template <typename Derived> | |||
12759 | ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr( | |||
12760 | ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken, | |||
12761 | TypeSourceInfo **RecoveryTSI) { | |||
12762 | ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr( | |||
12763 | DRE, AddrTaken, RecoveryTSI); | |||
12764 | ||||
12765 | // Propagate both errors and recovered types, which return ExprEmpty. | |||
12766 | if (!NewDRE.isUsable()) | |||
12767 | return NewDRE; | |||
12768 | ||||
12769 | // We got an expr, wrap it up in parens. | |||
12770 | if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE) | |||
12771 | return PE; | |||
12772 | return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(), | |||
12773 | PE->getRParen()); | |||
12774 | } | |||
12775 | ||||
12776 | template <typename Derived> | |||
12777 | ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( | |||
12778 | DependentScopeDeclRefExpr *E) { | |||
12779 | return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false, | |||
12780 | nullptr); | |||
12781 | } | |||
12782 | ||||
12783 | template <typename Derived> | |||
12784 | ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( | |||
12785 | DependentScopeDeclRefExpr *E, bool IsAddressOfOperand, | |||
12786 | TypeSourceInfo **RecoveryTSI) { | |||
12787 | assert(E->getQualifierLoc())(static_cast <bool> (E->getQualifierLoc()) ? void (0 ) : __assert_fail ("E->getQualifierLoc()", "clang/lib/Sema/TreeTransform.h" , 12787, __extension__ __PRETTY_FUNCTION__)); | |||
12788 | NestedNameSpecifierLoc QualifierLoc = | |||
12789 | getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); | |||
12790 | if (!QualifierLoc) | |||
12791 | return ExprError(); | |||
12792 | SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); | |||
12793 | ||||
12794 | // TODO: If this is a conversion-function-id, verify that the | |||
12795 | // destination type name (if present) resolves the same way after | |||
12796 | // instantiation as it did in the local scope. | |||
12797 | ||||
12798 | DeclarationNameInfo NameInfo = | |||
12799 | getDerived().TransformDeclarationNameInfo(E->getNameInfo()); | |||
12800 | if (!NameInfo.getName()) | |||
12801 | return ExprError(); | |||
12802 | ||||
12803 | if (!E->hasExplicitTemplateArgs()) { | |||
12804 | if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() && | |||
12805 | // Note: it is sufficient to compare the Name component of NameInfo: | |||
12806 | // if name has not changed, DNLoc has not changed either. | |||
12807 | NameInfo.getName() == E->getDeclName()) | |||
12808 | return E; | |||
12809 | ||||
12810 | return getDerived().RebuildDependentScopeDeclRefExpr( | |||
12811 | QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr, | |||
12812 | IsAddressOfOperand, RecoveryTSI); | |||
12813 | } | |||
12814 | ||||
12815 | TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc()); | |||
12816 | if (getDerived().TransformTemplateArguments( | |||
12817 | E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs)) | |||
12818 | return ExprError(); | |||
12819 | ||||
12820 | return getDerived().RebuildDependentScopeDeclRefExpr( | |||
12821 | QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand, | |||
12822 | RecoveryTSI); | |||
12823 | } | |||
12824 | ||||
12825 | template<typename Derived> | |||
12826 | ExprResult | |||
12827 | TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { | |||
12828 | // CXXConstructExprs other than for list-initialization and | |||
12829 | // CXXTemporaryObjectExpr are always implicit, so when we have | |||
12830 | // a 1-argument construction we just transform that argument. | |||
12831 | if (getDerived().AllowSkippingCXXConstructExpr() && | |||
12832 | ((E->getNumArgs() == 1 || | |||
12833 | (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) && | |||
12834 | (!getDerived().DropCallArgument(E->getArg(0))) && | |||
12835 | !E->isListInitialization())) | |||
12836 | return getDerived().TransformInitializer(E->getArg(0), | |||
12837 | /*DirectInit*/ false); | |||
12838 | ||||
12839 | TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName()); | |||
12840 | ||||
12841 | QualType T = getDerived().TransformType(E->getType()); | |||
12842 | if (T.isNull()) | |||
12843 | return ExprError(); | |||
12844 | ||||
12845 | CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>( | |||
12846 | getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor())); | |||
12847 | if (!Constructor) | |||
12848 | return ExprError(); | |||
12849 | ||||
12850 | bool ArgumentChanged = false; | |||
12851 | SmallVector<Expr*, 8> Args; | |||
12852 | { | |||
12853 | EnterExpressionEvaluationContext Context( | |||
12854 | getSema(), EnterExpressionEvaluationContext::InitList, | |||
12855 | E->isListInitialization()); | |||
12856 | if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, | |||
12857 | &ArgumentChanged)) | |||
12858 | return ExprError(); | |||
12859 | } | |||
12860 | ||||
12861 | if (!getDerived().AlwaysRebuild() && | |||
12862 | T == E->getType() && | |||
12863 | Constructor == E->getConstructor() && | |||
12864 | !ArgumentChanged) { | |||
12865 | // Mark the constructor as referenced. | |||
12866 | // FIXME: Instantiation-specific | |||
12867 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor); | |||
12868 | return E; | |||
12869 | } | |||
12870 | ||||
12871 | return getDerived().RebuildCXXConstructExpr( | |||
12872 | T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args, | |||
12873 | E->hadMultipleCandidates(), E->isListInitialization(), | |||
12874 | E->isStdInitListInitialization(), E->requiresZeroInitialization(), | |||
12875 | E->getConstructionKind(), E->getParenOrBraceRange()); | |||
12876 | } | |||
12877 | ||||
12878 | template<typename Derived> | |||
12879 | ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr( | |||
12880 | CXXInheritedCtorInitExpr *E) { | |||
12881 | QualType T = getDerived().TransformType(E->getType()); | |||
12882 | if (T.isNull()) | |||
12883 | return ExprError(); | |||
12884 | ||||
12885 | CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>( | |||
12886 | getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor())); | |||
12887 | if (!Constructor) | |||
12888 | return ExprError(); | |||
12889 | ||||
12890 | if (!getDerived().AlwaysRebuild() && | |||
12891 | T == E->getType() && | |||
12892 | Constructor == E->getConstructor()) { | |||
12893 | // Mark the constructor as referenced. | |||
12894 | // FIXME: Instantiation-specific | |||
12895 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor); | |||
12896 | return E; | |||
12897 | } | |||
12898 | ||||
12899 | return getDerived().RebuildCXXInheritedCtorInitExpr( | |||
12900 | T, E->getLocation(), Constructor, | |||
12901 | E->constructsVBase(), E->inheritedFromVBase()); | |||
12902 | } | |||
12903 | ||||
12904 | /// Transform a C++ temporary-binding expression. | |||
12905 | /// | |||
12906 | /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just | |||
12907 | /// transform the subexpression and return that. | |||
12908 | template<typename Derived> | |||
12909 | ExprResult | |||
12910 | TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { | |||
12911 | if (auto *Dtor = E->getTemporary()->getDestructor()) | |||
12912 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), | |||
12913 | const_cast<CXXDestructorDecl *>(Dtor)); | |||
12914 | return getDerived().TransformExpr(E->getSubExpr()); | |||
12915 | } | |||
12916 | ||||
12917 | /// Transform a C++ expression that contains cleanups that should | |||
12918 | /// be run after the expression is evaluated. | |||
12919 | /// | |||
12920 | /// Since ExprWithCleanups nodes are implicitly generated, we | |||
12921 | /// just transform the subexpression and return that. | |||
12922 | template<typename Derived> | |||
12923 | ExprResult | |||
12924 | TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) { | |||
12925 | return getDerived().TransformExpr(E->getSubExpr()); | |||
12926 | } | |||
12927 | ||||
12928 | template<typename Derived> | |||
12929 | ExprResult | |||
12930 | TreeTransform<Derived>::TransformCXXTemporaryObjectExpr( | |||
12931 | CXXTemporaryObjectExpr *E) { | |||
12932 | TypeSourceInfo *T = | |||
12933 | getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo()); | |||
12934 | if (!T) | |||
12935 | return ExprError(); | |||
12936 | ||||
12937 | CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>( | |||
12938 | getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor())); | |||
12939 | if (!Constructor) | |||
12940 | return ExprError(); | |||
12941 | ||||
12942 | bool ArgumentChanged = false; | |||
12943 | SmallVector<Expr*, 8> Args; | |||
12944 | Args.reserve(E->getNumArgs()); | |||
12945 | { | |||
12946 | EnterExpressionEvaluationContext Context( | |||
12947 | getSema(), EnterExpressionEvaluationContext::InitList, | |||
12948 | E->isListInitialization()); | |||
12949 | if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, | |||
12950 | &ArgumentChanged)) | |||
12951 | return ExprError(); | |||
12952 | } | |||
12953 | ||||
12954 | if (!getDerived().AlwaysRebuild() && | |||
12955 | T == E->getTypeSourceInfo() && | |||
12956 | Constructor == E->getConstructor() && | |||
12957 | !ArgumentChanged) { | |||
12958 | // FIXME: Instantiation-specific | |||
12959 | SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor); | |||
12960 | return SemaRef.MaybeBindToTemporary(E); | |||
12961 | } | |||
12962 | ||||
12963 | // FIXME: We should just pass E->isListInitialization(), but we're not | |||
12964 | // prepared to handle list-initialization without a child InitListExpr. | |||
12965 | SourceLocation LParenLoc = T->getTypeLoc().getEndLoc(); | |||
12966 | return getDerived().RebuildCXXTemporaryObjectExpr( | |||
12967 | T, LParenLoc, Args, E->getEndLoc(), | |||
12968 | /*ListInitialization=*/LParenLoc.isInvalid()); | |||
12969 | } | |||
12970 | ||||
12971 | template<typename Derived> | |||
12972 | ExprResult | |||
12973 | TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { | |||
12974 | // Transform any init-capture expressions before entering the scope of the | |||
12975 | // lambda body, because they are not semantically within that scope. | |||
12976 | typedef std::pair<ExprResult, QualType> InitCaptureInfoTy; | |||
12977 | struct TransformedInitCapture { | |||
12978 | // The location of the ... if the result is retaining a pack expansion. | |||
12979 | SourceLocation EllipsisLoc; | |||
12980 | // Zero or more expansions of the init-capture. | |||
12981 | SmallVector<InitCaptureInfoTy, 4> Expansions; | |||
12982 | }; | |||
12983 | SmallVector<TransformedInitCapture, 4> InitCaptures; | |||
12984 | InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin()); | |||
12985 | for (LambdaExpr::capture_iterator C = E->capture_begin(), | |||
12986 | CEnd = E->capture_end(); | |||
12987 | C != CEnd; ++C) { | |||
12988 | if (!E->isInitCapture(C)) | |||
12989 | continue; | |||
12990 | ||||
12991 | TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()]; | |||
12992 | auto *OldVD = cast<VarDecl>(C->getCapturedVar()); | |||
12993 | ||||
12994 | auto SubstInitCapture = [&](SourceLocation EllipsisLoc, | |||
12995 | Optional<unsigned> NumExpansions) { | |||
12996 | ExprResult NewExprInitResult = getDerived().TransformInitializer( | |||
12997 | OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit); | |||
12998 | ||||
12999 | if (NewExprInitResult.isInvalid()) { | |||
13000 | Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType())); | |||
13001 | return; | |||
13002 | } | |||
13003 | Expr *NewExprInit = NewExprInitResult.get(); | |||
13004 | ||||
13005 | QualType NewInitCaptureType = | |||
13006 | getSema().buildLambdaInitCaptureInitialization( | |||
13007 | C->getLocation(), OldVD->getType()->isReferenceType(), | |||
13008 | EllipsisLoc, NumExpansions, OldVD->getIdentifier(), | |||
13009 | cast<VarDecl>(C->getCapturedVar())->getInitStyle() != | |||
13010 | VarDecl::CInit, | |||
13011 | NewExprInit); | |||
13012 | Result.Expansions.push_back( | |||
13013 | InitCaptureInfoTy(NewExprInit, NewInitCaptureType)); | |||
13014 | }; | |||
13015 | ||||
13016 | // If this is an init-capture pack, consider expanding the pack now. | |||
13017 | if (OldVD->isParameterPack()) { | |||
13018 | PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo() | |||
13019 | ->getTypeLoc() | |||
13020 | .castAs<PackExpansionTypeLoc>(); | |||
13021 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
13022 | SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded); | |||
13023 | ||||
13024 | // Determine whether the set of unexpanded parameter packs can and should | |||
13025 | // be expanded. | |||
13026 | bool Expand = true; | |||
13027 | bool RetainExpansion = false; | |||
13028 | Optional<unsigned> OrigNumExpansions = | |||
13029 | ExpansionTL.getTypePtr()->getNumExpansions(); | |||
13030 | Optional<unsigned> NumExpansions = OrigNumExpansions; | |||
13031 | if (getDerived().TryExpandParameterPacks( | |||
13032 | ExpansionTL.getEllipsisLoc(), | |||
13033 | OldVD->getInit()->getSourceRange(), Unexpanded, Expand, | |||
13034 | RetainExpansion, NumExpansions)) | |||
13035 | return ExprError(); | |||
13036 | if (Expand) { | |||
13037 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
13038 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); | |||
13039 | SubstInitCapture(SourceLocation(), None); | |||
13040 | } | |||
13041 | } | |||
13042 | if (!Expand || RetainExpansion) { | |||
13043 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
13044 | SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions); | |||
13045 | Result.EllipsisLoc = ExpansionTL.getEllipsisLoc(); | |||
13046 | } | |||
13047 | } else { | |||
13048 | SubstInitCapture(SourceLocation(), None); | |||
13049 | } | |||
13050 | } | |||
13051 | ||||
13052 | LambdaScopeInfo *LSI = getSema().PushLambdaScope(); | |||
13053 | Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); | |||
13054 | ||||
13055 | // Transform the template parameters, and add them to the current | |||
13056 | // instantiation scope. The null case is handled correctly. | |||
13057 | auto TPL = getDerived().TransformTemplateParameterList( | |||
13058 | E->getTemplateParameterList()); | |||
13059 | LSI->GLTemplateParameterList = TPL; | |||
13060 | ||||
13061 | // Transform the type of the original lambda's call operator. | |||
13062 | // The transformation MUST be done in the CurrentInstantiationScope since | |||
13063 | // it introduces a mapping of the original to the newly created | |||
13064 | // transformed parameters. | |||
13065 | TypeSourceInfo *NewCallOpTSI = nullptr; | |||
13066 | { | |||
13067 | TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); | |||
13068 | FunctionProtoTypeLoc OldCallOpFPTL = | |||
13069 | OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); | |||
13070 | ||||
13071 | TypeLocBuilder NewCallOpTLBuilder; | |||
13072 | SmallVector<QualType, 4> ExceptionStorage; | |||
13073 | TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. | |||
13074 | QualType NewCallOpType = TransformFunctionProtoType( | |||
13075 | NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(), | |||
13076 | [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { | |||
13077 | return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI, | |||
13078 | ExceptionStorage, Changed); | |||
13079 | }); | |||
13080 | if (NewCallOpType.isNull()) | |||
13081 | return ExprError(); | |||
13082 | NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, | |||
13083 | NewCallOpType); | |||
13084 | } | |||
13085 | ||||
13086 | // Create the local class that will describe the lambda. | |||
13087 | ||||
13088 | // FIXME: DependencyKind below is wrong when substituting inside a templated | |||
13089 | // context that isn't a DeclContext (such as a variable template), or when | |||
13090 | // substituting an unevaluated lambda inside of a function's parameter's type | |||
13091 | // - as parameter types are not instantiated from within a function's DC. We | |||
13092 | // use isUnevaluatedContext() to distinguish the function parameter case. | |||
13093 | CXXRecordDecl::LambdaDependencyKind DependencyKind = | |||
13094 | CXXRecordDecl::LDK_Unknown; | |||
13095 | if (getSema().isUnevaluatedContext() && | |||
13096 | (getSema().CurContext->isFileContext() || | |||
13097 | !getSema().CurContext->getParent()->isDependentContext())) | |||
13098 | DependencyKind = CXXRecordDecl::LDK_NeverDependent; | |||
13099 | ||||
13100 | CXXRecordDecl *OldClass = E->getLambdaClass(); | |||
13101 | CXXRecordDecl *Class = | |||
13102 | getSema().createLambdaClosureType(E->getIntroducerRange(), NewCallOpTSI, | |||
13103 | DependencyKind, E->getCaptureDefault()); | |||
13104 | ||||
13105 | getDerived().transformedLocalDecl(OldClass, {Class}); | |||
13106 | ||||
13107 | Optional<std::tuple<bool, unsigned, unsigned, Decl *>> Mangling; | |||
13108 | if (getDerived().ReplacingOriginal()) | |||
13109 | Mangling = std::make_tuple(OldClass->hasKnownLambdaInternalLinkage(), | |||
13110 | OldClass->getLambdaManglingNumber(), | |||
13111 | OldClass->getDeviceLambdaManglingNumber(), | |||
13112 | OldClass->getLambdaContextDecl()); | |||
13113 | ||||
13114 | // Build the call operator. | |||
13115 | CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition( | |||
13116 | Class, E->getIntroducerRange(), NewCallOpTSI, | |||
13117 | E->getCallOperator()->getEndLoc(), | |||
13118 | NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(), | |||
13119 | E->getCallOperator()->getConstexprKind(), | |||
13120 | E->getCallOperator()->getStorageClass(), | |||
13121 | E->getCallOperator()->getTrailingRequiresClause()); | |||
13122 | ||||
13123 | LSI->CallOperator = NewCallOperator; | |||
13124 | ||||
13125 | getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); | |||
13126 | getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator}); | |||
13127 | ||||
13128 | // Number the lambda for linkage purposes if necessary. | |||
13129 | getSema().handleLambdaNumbering(Class, NewCallOperator, Mangling); | |||
13130 | ||||
13131 | // Introduce the context of the call operator. | |||
13132 | Sema::ContextRAII SavedContext(getSema(), NewCallOperator, | |||
13133 | /*NewThisContext*/false); | |||
13134 | ||||
13135 | // Enter the scope of the lambda. | |||
13136 | getSema().buildLambdaScope(LSI, NewCallOperator, | |||
13137 | E->getIntroducerRange(), | |||
13138 | E->getCaptureDefault(), | |||
13139 | E->getCaptureDefaultLoc(), | |||
13140 | E->hasExplicitParameters(), | |||
13141 | E->hasExplicitResultType(), | |||
13142 | E->isMutable()); | |||
13143 | ||||
13144 | bool Invalid = false; | |||
13145 | ||||
13146 | // Transform captures. | |||
13147 | for (LambdaExpr::capture_iterator C = E->capture_begin(), | |||
13148 | CEnd = E->capture_end(); | |||
13149 | C != CEnd; ++C) { | |||
13150 | // When we hit the first implicit capture, tell Sema that we've finished | |||
13151 | // the list of explicit captures. | |||
13152 | if (C->isImplicit()) | |||
13153 | break; | |||
13154 | ||||
13155 | // Capturing 'this' is trivial. | |||
13156 | if (C->capturesThis()) { | |||
13157 | getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(), | |||
13158 | /*BuildAndDiagnose*/ true, nullptr, | |||
13159 | C->getCaptureKind() == LCK_StarThis); | |||
13160 | continue; | |||
13161 | } | |||
13162 | // Captured expression will be recaptured during captured variables | |||
13163 | // rebuilding. | |||
13164 | if (C->capturesVLAType()) | |||
13165 | continue; | |||
13166 | ||||
13167 | // Rebuild init-captures, including the implied field declaration. | |||
13168 | if (E->isInitCapture(C)) { | |||
13169 | TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()]; | |||
13170 | ||||
13171 | auto *OldVD = cast<VarDecl>(C->getCapturedVar()); | |||
13172 | llvm::SmallVector<Decl*, 4> NewVDs; | |||
13173 | ||||
13174 | for (InitCaptureInfoTy &Info : NewC.Expansions) { | |||
13175 | ExprResult Init = Info.first; | |||
13176 | QualType InitQualType = Info.second; | |||
13177 | if (Init.isInvalid() || InitQualType.isNull()) { | |||
13178 | Invalid = true; | |||
13179 | break; | |||
13180 | } | |||
13181 | VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl( | |||
13182 | OldVD->getLocation(), InitQualType, NewC.EllipsisLoc, | |||
13183 | OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get()); | |||
13184 | if (!NewVD) { | |||
13185 | Invalid = true; | |||
13186 | break; | |||
13187 | } | |||
13188 | NewVDs.push_back(NewVD); | |||
13189 | getSema().addInitCapture(LSI, NewVD); | |||
13190 | } | |||
13191 | ||||
13192 | if (Invalid) | |||
13193 | break; | |||
13194 | ||||
13195 | getDerived().transformedLocalDecl(OldVD, NewVDs); | |||
13196 | continue; | |||
13197 | } | |||
13198 | ||||
13199 | assert(C->capturesVariable() && "unexpected kind of lambda capture")(static_cast <bool> (C->capturesVariable() && "unexpected kind of lambda capture") ? void (0) : __assert_fail ("C->capturesVariable() && \"unexpected kind of lambda capture\"" , "clang/lib/Sema/TreeTransform.h", 13199, __extension__ __PRETTY_FUNCTION__ )); | |||
13200 | ||||
13201 | // Determine the capture kind for Sema. | |||
13202 | Sema::TryCaptureKind Kind | |||
13203 | = C->isImplicit()? Sema::TryCapture_Implicit | |||
13204 | : C->getCaptureKind() == LCK_ByCopy | |||
13205 | ? Sema::TryCapture_ExplicitByVal | |||
13206 | : Sema::TryCapture_ExplicitByRef; | |||
13207 | SourceLocation EllipsisLoc; | |||
13208 | if (C->isPackExpansion()) { | |||
13209 | UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation()); | |||
13210 | bool ShouldExpand = false; | |||
13211 | bool RetainExpansion = false; | |||
13212 | Optional<unsigned> NumExpansions; | |||
13213 | if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(), | |||
13214 | C->getLocation(), | |||
13215 | Unexpanded, | |||
13216 | ShouldExpand, RetainExpansion, | |||
13217 | NumExpansions)) { | |||
13218 | Invalid = true; | |||
13219 | continue; | |||
13220 | } | |||
13221 | ||||
13222 | if (ShouldExpand) { | |||
13223 | // The transform has determined that we should perform an expansion; | |||
13224 | // transform and capture each of the arguments. | |||
13225 | // expansion of the pattern. Do so. | |||
13226 | auto *Pack = cast<VarDecl>(C->getCapturedVar()); | |||
13227 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
13228 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); | |||
13229 | VarDecl *CapturedVar | |||
13230 | = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), | |||
13231 | Pack)); | |||
13232 | if (!CapturedVar) { | |||
13233 | Invalid = true; | |||
13234 | continue; | |||
13235 | } | |||
13236 | ||||
13237 | // Capture the transformed variable. | |||
13238 | getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind); | |||
13239 | } | |||
13240 | ||||
13241 | // FIXME: Retain a pack expansion if RetainExpansion is true. | |||
13242 | ||||
13243 | continue; | |||
13244 | } | |||
13245 | ||||
13246 | EllipsisLoc = C->getEllipsisLoc(); | |||
13247 | } | |||
13248 | ||||
13249 | // Transform the captured variable. | |||
13250 | VarDecl *CapturedVar | |||
13251 | = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), | |||
13252 | C->getCapturedVar())); | |||
13253 | if (!CapturedVar || CapturedVar->isInvalidDecl()) { | |||
13254 | Invalid = true; | |||
13255 | continue; | |||
13256 | } | |||
13257 | ||||
13258 | // Capture the transformed variable. | |||
13259 | getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind, | |||
13260 | EllipsisLoc); | |||
13261 | } | |||
13262 | getSema().finishLambdaExplicitCaptures(LSI); | |||
13263 | ||||
13264 | // FIXME: Sema's lambda-building mechanism expects us to push an expression | |||
13265 | // evaluation context even if we're not transforming the function body. | |||
13266 | getSema().PushExpressionEvaluationContext( | |||
13267 | Sema::ExpressionEvaluationContext::PotentiallyEvaluated); | |||
13268 | ||||
13269 | // Instantiate the body of the lambda expression. | |||
13270 | StmtResult Body = | |||
13271 | Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody()); | |||
13272 | ||||
13273 | // ActOnLambda* will pop the function scope for us. | |||
13274 | FuncScopeCleanup.disable(); | |||
13275 | ||||
13276 | if (Body.isInvalid()) { | |||
13277 | SavedContext.pop(); | |||
13278 | getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr, | |||
13279 | /*IsInstantiation=*/true); | |||
13280 | return ExprError(); | |||
13281 | } | |||
13282 | ||||
13283 | // Copy the LSI before ActOnFinishFunctionBody removes it. | |||
13284 | // FIXME: This is dumb. Store the lambda information somewhere that outlives | |||
13285 | // the call operator. | |||
13286 | auto LSICopy = *LSI; | |||
13287 | getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(), | |||
13288 | /*IsInstantiation*/ true); | |||
13289 | SavedContext.pop(); | |||
13290 | ||||
13291 | return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(), | |||
13292 | &LSICopy); | |||
13293 | } | |||
13294 | ||||
13295 | template<typename Derived> | |||
13296 | StmtResult | |||
13297 | TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) { | |||
13298 | return TransformStmt(S); | |||
13299 | } | |||
13300 | ||||
13301 | template<typename Derived> | |||
13302 | StmtResult | |||
13303 | TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) { | |||
13304 | // Transform captures. | |||
13305 | for (LambdaExpr::capture_iterator C = E->capture_begin(), | |||
13306 | CEnd = E->capture_end(); | |||
13307 | C != CEnd; ++C) { | |||
13308 | // When we hit the first implicit capture, tell Sema that we've finished | |||
13309 | // the list of explicit captures. | |||
13310 | if (!C->isImplicit()) | |||
13311 | continue; | |||
13312 | ||||
13313 | // Capturing 'this' is trivial. | |||
13314 | if (C->capturesThis()) { | |||
13315 | getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(), | |||
13316 | /*BuildAndDiagnose*/ true, nullptr, | |||
13317 | C->getCaptureKind() == LCK_StarThis); | |||
13318 | continue; | |||
13319 | } | |||
13320 | // Captured expression will be recaptured during captured variables | |||
13321 | // rebuilding. | |||
13322 | if (C->capturesVLAType()) | |||
13323 | continue; | |||
13324 | ||||
13325 | assert(C->capturesVariable() && "unexpected kind of lambda capture")(static_cast <bool> (C->capturesVariable() && "unexpected kind of lambda capture") ? void (0) : __assert_fail ("C->capturesVariable() && \"unexpected kind of lambda capture\"" , "clang/lib/Sema/TreeTransform.h", 13325, __extension__ __PRETTY_FUNCTION__ )); | |||
13326 | assert(!E->isInitCapture(C) && "implicit init-capture?")(static_cast <bool> (!E->isInitCapture(C) && "implicit init-capture?") ? void (0) : __assert_fail ("!E->isInitCapture(C) && \"implicit init-capture?\"" , "clang/lib/Sema/TreeTransform.h", 13326, __extension__ __PRETTY_FUNCTION__ )); | |||
13327 | ||||
13328 | // Transform the captured variable. | |||
13329 | VarDecl *CapturedVar = cast_or_null<VarDecl>( | |||
13330 | getDerived().TransformDecl(C->getLocation(), C->getCapturedVar())); | |||
13331 | if (!CapturedVar || CapturedVar->isInvalidDecl()) | |||
13332 | return StmtError(); | |||
13333 | ||||
13334 | // Capture the transformed variable. | |||
13335 | getSema().tryCaptureVariable(CapturedVar, C->getLocation()); | |||
13336 | } | |||
13337 | ||||
13338 | return S; | |||
13339 | } | |||
13340 | ||||
13341 | template<typename Derived> | |||
13342 | ExprResult | |||
13343 | TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr( | |||
13344 | CXXUnresolvedConstructExpr *E) { | |||
13345 | TypeSourceInfo *T = | |||
13346 | getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo()); | |||
13347 | if (!T) | |||
13348 | return ExprError(); | |||
13349 | ||||
13350 | bool ArgumentChanged = false; | |||
13351 | SmallVector<Expr*, 8> Args; | |||
13352 | Args.reserve(E->getNumArgs()); | |||
13353 | { | |||
13354 | EnterExpressionEvaluationContext Context( | |||
13355 | getSema(), EnterExpressionEvaluationContext::InitList, | |||
13356 | E->isListInitialization()); | |||
13357 | if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args, | |||
13358 | &ArgumentChanged)) | |||
13359 | return ExprError(); | |||
13360 | } | |||
13361 | ||||
13362 | if (!getDerived().AlwaysRebuild() && | |||
13363 | T == E->getTypeSourceInfo() && | |||
13364 | !ArgumentChanged) | |||
13365 | return E; | |||
13366 | ||||
13367 | // FIXME: we're faking the locations of the commas | |||
13368 | return getDerived().RebuildCXXUnresolvedConstructExpr( | |||
13369 | T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization()); | |||
13370 | } | |||
13371 | ||||
13372 | template<typename Derived> | |||
13373 | ExprResult | |||
13374 | TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr( | |||
13375 | CXXDependentScopeMemberExpr *E) { | |||
13376 | // Transform the base of the expression. | |||
13377 | ExprResult Base((Expr*) nullptr); | |||
13378 | Expr *OldBase; | |||
13379 | QualType BaseType; | |||
13380 | QualType ObjectType; | |||
13381 | if (!E->isImplicitAccess()) { | |||
13382 | OldBase = E->getBase(); | |||
13383 | Base = getDerived().TransformExpr(OldBase); | |||
13384 | if (Base.isInvalid()) | |||
13385 | return ExprError(); | |||
13386 | ||||
13387 | // Start the member reference and compute the object's type. | |||
13388 | ParsedType ObjectTy; | |||
13389 | bool MayBePseudoDestructor = false; | |||
13390 | Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(), | |||
13391 | E->getOperatorLoc(), | |||
13392 | E->isArrow()? tok::arrow : tok::period, | |||
13393 | ObjectTy, | |||
13394 | MayBePseudoDestructor); | |||
13395 | if (Base.isInvalid()) | |||
13396 | return ExprError(); | |||
13397 | ||||
13398 | ObjectType = ObjectTy.get(); | |||
13399 | BaseType = ((Expr*) Base.get())->getType(); | |||
13400 | } else { | |||
13401 | OldBase = nullptr; | |||
13402 | BaseType = getDerived().TransformType(E->getBaseType()); | |||
13403 | ObjectType = BaseType->castAs<PointerType>()->getPointeeType(); | |||
13404 | } | |||
13405 | ||||
13406 | // Transform the first part of the nested-name-specifier that qualifies | |||
13407 | // the member name. | |||
13408 | NamedDecl *FirstQualifierInScope | |||
13409 | = getDerived().TransformFirstQualifierInScope( | |||
13410 | E->getFirstQualifierFoundInScope(), | |||
13411 | E->getQualifierLoc().getBeginLoc()); | |||
13412 | ||||
13413 | NestedNameSpecifierLoc QualifierLoc; | |||
13414 | if (E->getQualifier()) { | |||
13415 | QualifierLoc | |||
13416 | = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(), | |||
13417 | ObjectType, | |||
13418 | FirstQualifierInScope); | |||
13419 | if (!QualifierLoc) | |||
13420 | return ExprError(); | |||
13421 | } | |||
13422 | ||||
13423 | SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); | |||
13424 | ||||
13425 | // TODO: If this is a conversion-function-id, verify that the | |||
13426 | // destination type name (if present) resolves the same way after | |||
13427 | // instantiation as it did in the local scope. | |||
13428 | ||||
13429 | DeclarationNameInfo NameInfo | |||
13430 | = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo()); | |||
13431 | if (!NameInfo.getName()) | |||
13432 | return ExprError(); | |||
13433 | ||||
13434 | if (!E->hasExplicitTemplateArgs()) { | |||
13435 | // This is a reference to a member without an explicitly-specified | |||
13436 | // template argument list. Optimize for this common case. | |||
13437 | if (!getDerived().AlwaysRebuild() && | |||
13438 | Base.get() == OldBase && | |||
13439 | BaseType == E->getBaseType() && | |||
13440 | QualifierLoc == E->getQualifierLoc() && | |||
13441 | NameInfo.getName() == E->getMember() && | |||
13442 | FirstQualifierInScope == E->getFirstQualifierFoundInScope()) | |||
13443 | return E; | |||
13444 | ||||
13445 | return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(), | |||
13446 | BaseType, | |||
13447 | E->isArrow(), | |||
13448 | E->getOperatorLoc(), | |||
13449 | QualifierLoc, | |||
13450 | TemplateKWLoc, | |||
13451 | FirstQualifierInScope, | |||
13452 | NameInfo, | |||
13453 | /*TemplateArgs*/nullptr); | |||
13454 | } | |||
13455 | ||||
13456 | TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc()); | |||
13457 | if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), | |||
13458 | E->getNumTemplateArgs(), | |||
13459 | TransArgs)) | |||
13460 | return ExprError(); | |||
13461 | ||||
13462 | return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(), | |||
13463 | BaseType, | |||
13464 | E->isArrow(), | |||
13465 | E->getOperatorLoc(), | |||
13466 | QualifierLoc, | |||
13467 | TemplateKWLoc, | |||
13468 | FirstQualifierInScope, | |||
13469 | NameInfo, | |||
13470 | &TransArgs); | |||
13471 | } | |||
13472 | ||||
13473 | template <typename Derived> | |||
13474 | ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr( | |||
13475 | UnresolvedMemberExpr *Old) { | |||
13476 | // Transform the base of the expression. | |||
13477 | ExprResult Base((Expr *)nullptr); | |||
13478 | QualType BaseType; | |||
13479 | if (!Old->isImplicitAccess()) { | |||
13480 | Base = getDerived().TransformExpr(Old->getBase()); | |||
13481 | if (Base.isInvalid()) | |||
13482 | return ExprError(); | |||
13483 | Base = | |||
13484 | getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow()); | |||
13485 | if (Base.isInvalid()) | |||
13486 | return ExprError(); | |||
13487 | BaseType = Base.get()->getType(); | |||
13488 | } else { | |||
13489 | BaseType = getDerived().TransformType(Old->getBaseType()); | |||
13490 | } | |||
13491 | ||||
13492 | NestedNameSpecifierLoc QualifierLoc; | |||
13493 | if (Old->getQualifierLoc()) { | |||
13494 | QualifierLoc = | |||
13495 | getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); | |||
13496 | if (!QualifierLoc) | |||
13497 | return ExprError(); | |||
13498 | } | |||
13499 | ||||
13500 | SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); | |||
13501 | ||||
13502 | LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName); | |||
13503 | ||||
13504 | // Transform the declaration set. | |||
13505 | if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R)) | |||
13506 | return ExprError(); | |||
13507 | ||||
13508 | // Determine the naming class. | |||
13509 | if (Old->getNamingClass()) { | |||
13510 | CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>( | |||
13511 | getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass())); | |||
13512 | if (!NamingClass) | |||
13513 | return ExprError(); | |||
13514 | ||||
13515 | R.setNamingClass(NamingClass); | |||
13516 | } | |||
13517 | ||||
13518 | TemplateArgumentListInfo TransArgs; | |||
13519 | if (Old->hasExplicitTemplateArgs()) { | |||
13520 | TransArgs.setLAngleLoc(Old->getLAngleLoc()); | |||
13521 | TransArgs.setRAngleLoc(Old->getRAngleLoc()); | |||
13522 | if (getDerived().TransformTemplateArguments( | |||
13523 | Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs)) | |||
13524 | return ExprError(); | |||
13525 | } | |||
13526 | ||||
13527 | // FIXME: to do this check properly, we will need to preserve the | |||
13528 | // first-qualifier-in-scope here, just in case we had a dependent | |||
13529 | // base (and therefore couldn't do the check) and a | |||
13530 | // nested-name-qualifier (and therefore could do the lookup). | |||
13531 | NamedDecl *FirstQualifierInScope = nullptr; | |||
13532 | ||||
13533 | return getDerived().RebuildUnresolvedMemberExpr( | |||
13534 | Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc, | |||
13535 | TemplateKWLoc, FirstQualifierInScope, R, | |||
13536 | (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr)); | |||
13537 | } | |||
13538 | ||||
13539 | template<typename Derived> | |||
13540 | ExprResult | |||
13541 | TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) { | |||
13542 | EnterExpressionEvaluationContext Unevaluated( | |||
13543 | SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); | |||
13544 | ExprResult SubExpr = getDerived().TransformExpr(E->getOperand()); | |||
13545 | if (SubExpr.isInvalid()) | |||
13546 | return ExprError(); | |||
13547 | ||||
13548 | if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand()) | |||
13549 | return E; | |||
13550 | ||||
13551 | return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get()); | |||
13552 | } | |||
13553 | ||||
13554 | template<typename Derived> | |||
13555 | ExprResult | |||
13556 | TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) { | |||
13557 | ExprResult Pattern = getDerived().TransformExpr(E->getPattern()); | |||
13558 | if (Pattern.isInvalid()) | |||
13559 | return ExprError(); | |||
13560 | ||||
13561 | if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern()) | |||
13562 | return E; | |||
13563 | ||||
13564 | return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(), | |||
13565 | E->getNumExpansions()); | |||
13566 | } | |||
13567 | ||||
13568 | template<typename Derived> | |||
13569 | ExprResult | |||
13570 | TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { | |||
13571 | // If E is not value-dependent, then nothing will change when we transform it. | |||
13572 | // Note: This is an instantiation-centric view. | |||
13573 | if (!E->isValueDependent()) | |||
13574 | return E; | |||
13575 | ||||
13576 | EnterExpressionEvaluationContext Unevaluated( | |||
13577 | getSema(), Sema::ExpressionEvaluationContext::Unevaluated); | |||
13578 | ||||
13579 | ArrayRef<TemplateArgument> PackArgs; | |||
13580 | TemplateArgument ArgStorage; | |||
13581 | ||||
13582 | // Find the argument list to transform. | |||
13583 | if (E->isPartiallySubstituted()) { | |||
13584 | PackArgs = E->getPartialArguments(); | |||
13585 | } else if (E->isValueDependent()) { | |||
13586 | UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc()); | |||
13587 | bool ShouldExpand = false; | |||
13588 | bool RetainExpansion = false; | |||
13589 | Optional<unsigned> NumExpansions; | |||
13590 | if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(), | |||
13591 | Unexpanded, | |||
13592 | ShouldExpand, RetainExpansion, | |||
13593 | NumExpansions)) | |||
13594 | return ExprError(); | |||
13595 | ||||
13596 | // If we need to expand the pack, build a template argument from it and | |||
13597 | // expand that. | |||
13598 | if (ShouldExpand) { | |||
13599 | auto *Pack = E->getPack(); | |||
13600 | if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) { | |||
13601 | ArgStorage = getSema().Context.getPackExpansionType( | |||
13602 | getSema().Context.getTypeDeclType(TTPD), None); | |||
13603 | } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) { | |||
13604 | ArgStorage = TemplateArgument(TemplateName(TTPD), None); | |||
13605 | } else { | |||
13606 | auto *VD = cast<ValueDecl>(Pack); | |||
13607 | ExprResult DRE = getSema().BuildDeclRefExpr( | |||
13608 | VD, VD->getType().getNonLValueExprType(getSema().Context), | |||
13609 | VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue, | |||
13610 | E->getPackLoc()); | |||
13611 | if (DRE.isInvalid()) | |||
13612 | return ExprError(); | |||
13613 | ArgStorage = new (getSema().Context) PackExpansionExpr( | |||
13614 | getSema().Context.DependentTy, DRE.get(), E->getPackLoc(), None); | |||
13615 | } | |||
13616 | PackArgs = ArgStorage; | |||
13617 | } | |||
13618 | } | |||
13619 | ||||
13620 | // If we're not expanding the pack, just transform the decl. | |||
13621 | if (!PackArgs.size()) { | |||
13622 | auto *Pack = cast_or_null<NamedDecl>( | |||
13623 | getDerived().TransformDecl(E->getPackLoc(), E->getPack())); | |||
13624 | if (!Pack) | |||
13625 | return ExprError(); | |||
13626 | return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack, | |||
13627 | E->getPackLoc(), | |||
13628 | E->getRParenLoc(), None, None); | |||
13629 | } | |||
13630 | ||||
13631 | // Try to compute the result without performing a partial substitution. | |||
13632 | Optional<unsigned> Result = 0; | |||
13633 | for (const TemplateArgument &Arg : PackArgs) { | |||
13634 | if (!Arg.isPackExpansion()) { | |||
13635 | Result = *Result + 1; | |||
13636 | continue; | |||
13637 | } | |||
13638 | ||||
13639 | TemplateArgumentLoc ArgLoc; | |||
13640 | InventTemplateArgumentLoc(Arg, ArgLoc); | |||
13641 | ||||
13642 | // Find the pattern of the pack expansion. | |||
13643 | SourceLocation Ellipsis; | |||
13644 | Optional<unsigned> OrigNumExpansions; | |||
13645 | TemplateArgumentLoc Pattern = | |||
13646 | getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis, | |||
13647 | OrigNumExpansions); | |||
13648 | ||||
13649 | // Substitute under the pack expansion. Do not expand the pack (yet). | |||
13650 | TemplateArgumentLoc OutPattern; | |||
13651 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
13652 | if (getDerived().TransformTemplateArgument(Pattern, OutPattern, | |||
13653 | /*Uneval*/ true)) | |||
13654 | return true; | |||
13655 | ||||
13656 | // See if we can determine the number of arguments from the result. | |||
13657 | Optional<unsigned> NumExpansions = | |||
13658 | getSema().getFullyPackExpandedSize(OutPattern.getArgument()); | |||
13659 | if (!NumExpansions) { | |||
13660 | // No: we must be in an alias template expansion, and we're going to need | |||
13661 | // to actually expand the packs. | |||
13662 | Result = None; | |||
13663 | break; | |||
13664 | } | |||
13665 | ||||
13666 | Result = *Result + *NumExpansions; | |||
13667 | } | |||
13668 | ||||
13669 | // Common case: we could determine the number of expansions without | |||
13670 | // substituting. | |||
13671 | if (Result) | |||
13672 | return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), | |||
13673 | E->getPackLoc(), | |||
13674 | E->getRParenLoc(), *Result, None); | |||
13675 | ||||
13676 | TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(), | |||
13677 | E->getPackLoc()); | |||
13678 | { | |||
13679 | TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity()); | |||
13680 | typedef TemplateArgumentLocInventIterator< | |||
13681 | Derived, const TemplateArgument*> PackLocIterator; | |||
13682 | if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()), | |||
13683 | PackLocIterator(*this, PackArgs.end()), | |||
13684 | TransformedPackArgs, /*Uneval*/true)) | |||
13685 | return ExprError(); | |||
13686 | } | |||
13687 | ||||
13688 | // Check whether we managed to fully-expand the pack. | |||
13689 | // FIXME: Is it possible for us to do so and not hit the early exit path? | |||
13690 | SmallVector<TemplateArgument, 8> Args; | |||
13691 | bool PartialSubstitution = false; | |||
13692 | for (auto &Loc : TransformedPackArgs.arguments()) { | |||
13693 | Args.push_back(Loc.getArgument()); | |||
13694 | if (Loc.getArgument().isPackExpansion()) | |||
13695 | PartialSubstitution = true; | |||
13696 | } | |||
13697 | ||||
13698 | if (PartialSubstitution) | |||
13699 | return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), | |||
13700 | E->getPackLoc(), | |||
13701 | E->getRParenLoc(), None, Args); | |||
13702 | ||||
13703 | return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), | |||
13704 | E->getPackLoc(), E->getRParenLoc(), | |||
13705 | Args.size(), None); | |||
13706 | } | |||
13707 | ||||
13708 | template<typename Derived> | |||
13709 | ExprResult | |||
13710 | TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr( | |||
13711 | SubstNonTypeTemplateParmPackExpr *E) { | |||
13712 | // Default behavior is to do nothing with this transformation. | |||
13713 | return E; | |||
13714 | } | |||
13715 | ||||
13716 | template<typename Derived> | |||
13717 | ExprResult | |||
13718 | TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr( | |||
13719 | SubstNonTypeTemplateParmExpr *E) { | |||
13720 | // Default behavior is to do nothing with this transformation. | |||
13721 | return E; | |||
13722 | } | |||
13723 | ||||
13724 | template<typename Derived> | |||
13725 | ExprResult | |||
13726 | TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) { | |||
13727 | // Default behavior is to do nothing with this transformation. | |||
13728 | return E; | |||
13729 | } | |||
13730 | ||||
13731 | template<typename Derived> | |||
13732 | ExprResult | |||
13733 | TreeTransform<Derived>::TransformMaterializeTemporaryExpr( | |||
13734 | MaterializeTemporaryExpr *E) { | |||
13735 | return getDerived().TransformExpr(E->getSubExpr()); | |||
13736 | } | |||
13737 | ||||
13738 | template<typename Derived> | |||
13739 | ExprResult | |||
13740 | TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) { | |||
13741 | UnresolvedLookupExpr *Callee = nullptr; | |||
13742 | if (Expr *OldCallee = E->getCallee()) { | |||
13743 | ExprResult CalleeResult = getDerived().TransformExpr(OldCallee); | |||
13744 | if (CalleeResult.isInvalid()) | |||
13745 | return ExprError(); | |||
13746 | Callee = cast<UnresolvedLookupExpr>(CalleeResult.get()); | |||
13747 | } | |||
13748 | ||||
13749 | Expr *Pattern = E->getPattern(); | |||
13750 | ||||
13751 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
13752 | getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); | |||
13753 | assert(!Unexpanded.empty() && "Pack expansion without parameter packs?")(static_cast <bool> (!Unexpanded.empty() && "Pack expansion without parameter packs?" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Pack expansion without parameter packs?\"" , "clang/lib/Sema/TreeTransform.h", 13753, __extension__ __PRETTY_FUNCTION__ )); | |||
13754 | ||||
13755 | // Determine whether the set of unexpanded parameter packs can and should | |||
13756 | // be expanded. | |||
13757 | bool Expand = true; | |||
13758 | bool RetainExpansion = false; | |||
13759 | Optional<unsigned> OrigNumExpansions = E->getNumExpansions(), | |||
13760 | NumExpansions = OrigNumExpansions; | |||
13761 | if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(), | |||
13762 | Pattern->getSourceRange(), | |||
13763 | Unexpanded, | |||
13764 | Expand, RetainExpansion, | |||
13765 | NumExpansions)) | |||
13766 | return true; | |||
13767 | ||||
13768 | if (!Expand) { | |||
13769 | // Do not expand any packs here, just transform and rebuild a fold | |||
13770 | // expression. | |||
13771 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
13772 | ||||
13773 | ExprResult LHS = | |||
13774 | E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult(); | |||
13775 | if (LHS.isInvalid()) | |||
13776 | return true; | |||
13777 | ||||
13778 | ExprResult RHS = | |||
13779 | E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult(); | |||
13780 | if (RHS.isInvalid()) | |||
13781 | return true; | |||
13782 | ||||
13783 | if (!getDerived().AlwaysRebuild() && | |||
13784 | LHS.get() == E->getLHS() && RHS.get() == E->getRHS()) | |||
13785 | return E; | |||
13786 | ||||
13787 | return getDerived().RebuildCXXFoldExpr( | |||
13788 | Callee, E->getBeginLoc(), LHS.get(), E->getOperator(), | |||
13789 | E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions); | |||
13790 | } | |||
13791 | ||||
13792 | // Formally a fold expression expands to nested parenthesized expressions. | |||
13793 | // Enforce this limit to avoid creating trees so deep we can't safely traverse | |||
13794 | // them. | |||
13795 | if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) { | |||
13796 | SemaRef.Diag(E->getEllipsisLoc(), | |||
13797 | clang::diag::err_fold_expression_limit_exceeded) | |||
13798 | << *NumExpansions << SemaRef.getLangOpts().BracketDepth | |||
13799 | << E->getSourceRange(); | |||
13800 | SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth); | |||
13801 | return ExprError(); | |||
13802 | } | |||
13803 | ||||
13804 | // The transform has determined that we should perform an elementwise | |||
13805 | // expansion of the pattern. Do so. | |||
13806 | ExprResult Result = getDerived().TransformExpr(E->getInit()); | |||
13807 | if (Result.isInvalid()) | |||
13808 | return true; | |||
13809 | bool LeftFold = E->isLeftFold(); | |||
13810 | ||||
13811 | // If we're retaining an expansion for a right fold, it is the innermost | |||
13812 | // component and takes the init (if any). | |||
13813 | if (!LeftFold && RetainExpansion) { | |||
13814 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
13815 | ||||
13816 | ExprResult Out = getDerived().TransformExpr(Pattern); | |||
13817 | if (Out.isInvalid()) | |||
13818 | return true; | |||
13819 | ||||
13820 | Result = getDerived().RebuildCXXFoldExpr( | |||
13821 | Callee, E->getBeginLoc(), Out.get(), E->getOperator(), | |||
13822 | E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions); | |||
13823 | if (Result.isInvalid()) | |||
13824 | return true; | |||
13825 | } | |||
13826 | ||||
13827 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
13828 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex( | |||
13829 | getSema(), LeftFold ? I : *NumExpansions - I - 1); | |||
13830 | ExprResult Out = getDerived().TransformExpr(Pattern); | |||
13831 | if (Out.isInvalid()) | |||
13832 | return true; | |||
13833 | ||||
13834 | if (Out.get()->containsUnexpandedParameterPack()) { | |||
13835 | // We still have a pack; retain a pack expansion for this slice. | |||
13836 | Result = getDerived().RebuildCXXFoldExpr( | |||
13837 | Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(), | |||
13838 | E->getOperator(), E->getEllipsisLoc(), | |||
13839 | LeftFold ? Out.get() : Result.get(), E->getEndLoc(), | |||
13840 | OrigNumExpansions); | |||
13841 | } else if (Result.isUsable()) { | |||
13842 | // We've got down to a single element; build a binary operator. | |||
13843 | Expr *LHS = LeftFold ? Result.get() : Out.get(); | |||
13844 | Expr *RHS = LeftFold ? Out.get() : Result.get(); | |||
13845 | if (Callee) | |||
13846 | Result = getDerived().RebuildCXXOperatorCallExpr( | |||
13847 | BinaryOperator::getOverloadedOperator(E->getOperator()), | |||
13848 | E->getEllipsisLoc(), Callee, LHS, RHS); | |||
13849 | else | |||
13850 | Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(), | |||
13851 | E->getOperator(), LHS, RHS); | |||
13852 | } else | |||
13853 | Result = Out; | |||
13854 | ||||
13855 | if (Result.isInvalid()) | |||
13856 | return true; | |||
13857 | } | |||
13858 | ||||
13859 | // If we're retaining an expansion for a left fold, it is the outermost | |||
13860 | // component and takes the complete expansion so far as its init (if any). | |||
13861 | if (LeftFold && RetainExpansion) { | |||
13862 | ForgetPartiallySubstitutedPackRAII Forget(getDerived()); | |||
13863 | ||||
13864 | ExprResult Out = getDerived().TransformExpr(Pattern); | |||
13865 | if (Out.isInvalid()) | |||
13866 | return true; | |||
13867 | ||||
13868 | Result = getDerived().RebuildCXXFoldExpr( | |||
13869 | Callee, E->getBeginLoc(), Result.get(), E->getOperator(), | |||
13870 | E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions); | |||
13871 | if (Result.isInvalid()) | |||
13872 | return true; | |||
13873 | } | |||
13874 | ||||
13875 | // If we had no init and an empty pack, and we're not retaining an expansion, | |||
13876 | // then produce a fallback value or error. | |||
13877 | if (Result.isUnset()) | |||
13878 | return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(), | |||
13879 | E->getOperator()); | |||
13880 | ||||
13881 | return Result; | |||
13882 | } | |||
13883 | ||||
13884 | template<typename Derived> | |||
13885 | ExprResult | |||
13886 | TreeTransform<Derived>::TransformCXXStdInitializerListExpr( | |||
13887 | CXXStdInitializerListExpr *E) { | |||
13888 | return getDerived().TransformExpr(E->getSubExpr()); | |||
13889 | } | |||
13890 | ||||
13891 | template<typename Derived> | |||
13892 | ExprResult | |||
13893 | TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) { | |||
13894 | return SemaRef.MaybeBindToTemporary(E); | |||
13895 | } | |||
13896 | ||||
13897 | template<typename Derived> | |||
13898 | ExprResult | |||
13899 | TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) { | |||
13900 | return E; | |||
13901 | } | |||
13902 | ||||
13903 | template<typename Derived> | |||
13904 | ExprResult | |||
13905 | TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) { | |||
13906 | ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); | |||
13907 | if (SubExpr.isInvalid()) | |||
13908 | return ExprError(); | |||
13909 | ||||
13910 | if (!getDerived().AlwaysRebuild() && | |||
13911 | SubExpr.get() == E->getSubExpr()) | |||
13912 | return E; | |||
13913 | ||||
13914 | return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get()); | |||
13915 | } | |||
13916 | ||||
13917 | template<typename Derived> | |||
13918 | ExprResult | |||
13919 | TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) { | |||
13920 | // Transform each of the elements. | |||
13921 | SmallVector<Expr *, 8> Elements; | |||
13922 | bool ArgChanged = false; | |||
13923 | if (getDerived().TransformExprs(E->getElements(), E->getNumElements(), | |||
13924 | /*IsCall=*/false, Elements, &ArgChanged)) | |||
13925 | return ExprError(); | |||
13926 | ||||
13927 | if (!getDerived().AlwaysRebuild() && !ArgChanged) | |||
13928 | return SemaRef.MaybeBindToTemporary(E); | |||
13929 | ||||
13930 | return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(), | |||
13931 | Elements.data(), | |||
13932 | Elements.size()); | |||
13933 | } | |||
13934 | ||||
13935 | template<typename Derived> | |||
13936 | ExprResult | |||
13937 | TreeTransform<Derived>::TransformObjCDictionaryLiteral( | |||
13938 | ObjCDictionaryLiteral *E) { | |||
13939 | // Transform each of the elements. | |||
13940 | SmallVector<ObjCDictionaryElement, 8> Elements; | |||
13941 | bool ArgChanged = false; | |||
13942 | for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { | |||
13943 | ObjCDictionaryElement OrigElement = E->getKeyValueElement(I); | |||
13944 | ||||
13945 | if (OrigElement.isPackExpansion()) { | |||
13946 | // This key/value element is a pack expansion. | |||
13947 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | |||
13948 | getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded); | |||
13949 | getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded); | |||
13950 | assert(!Unexpanded.empty() && "Pack expansion without parameter packs?")(static_cast <bool> (!Unexpanded.empty() && "Pack expansion without parameter packs?" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Pack expansion without parameter packs?\"" , "clang/lib/Sema/TreeTransform.h", 13950, __extension__ __PRETTY_FUNCTION__ )); | |||
13951 | ||||
13952 | // Determine whether the set of unexpanded parameter packs can | |||
13953 | // and should be expanded. | |||
13954 | bool Expand = true; | |||
13955 | bool RetainExpansion = false; | |||
13956 | Optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions; | |||
13957 | Optional<unsigned> NumExpansions = OrigNumExpansions; | |||
13958 | SourceRange PatternRange(OrigElement.Key->getBeginLoc(), | |||
13959 | OrigElement.Value->getEndLoc()); | |||
13960 | if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc, | |||
13961 | PatternRange, Unexpanded, Expand, | |||
13962 | RetainExpansion, NumExpansions)) | |||
13963 | return ExprError(); | |||
13964 | ||||
13965 | if (!Expand) { | |||
13966 | // The transform has determined that we should perform a simple | |||
13967 | // transformation on the pack expansion, producing another pack | |||
13968 | // expansion. | |||
13969 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); | |||
13970 | ExprResult Key = getDerived().TransformExpr(OrigElement.Key); | |||
13971 | if (Key.isInvalid()) | |||
13972 | return ExprError(); | |||
13973 | ||||
13974 | if (Key.get() != OrigElement.Key) | |||
13975 | ArgChanged = true; | |||
13976 | ||||
13977 | ExprResult Value = getDerived().TransformExpr(OrigElement.Value); | |||
13978 | if (Value.isInvalid()) | |||
13979 | return ExprError(); | |||
13980 | ||||
13981 | if (Value.get() != OrigElement.Value) | |||
13982 | ArgChanged = true; | |||
13983 | ||||
13984 | ObjCDictionaryElement Expansion = { | |||
13985 | Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions | |||
13986 | }; | |||
13987 | Elements.push_back(Expansion); | |||
13988 | continue; | |||
13989 | } | |||
13990 | ||||
13991 | // Record right away that the argument was changed. This needs | |||
13992 | // to happen even if the array expands to nothing. | |||
13993 | ArgChanged = true; | |||
13994 | ||||
13995 | // The transform has determined that we should perform an elementwise | |||
13996 | // expansion of the pattern. Do so. | |||
13997 | for (unsigned I = 0; I != *NumExpansions; ++I) { | |||
13998 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); | |||
13999 | ExprResult Key = getDerived().TransformExpr(OrigElement.Key); | |||
14000 | if (Key.isInvalid()) | |||
14001 | return ExprError(); | |||
14002 | ||||
14003 | ExprResult Value = getDerived().TransformExpr(OrigElement.Value); | |||
14004 | if (Value.isInvalid()) | |||
14005 | return ExprError(); | |||
14006 | ||||
14007 | ObjCDictionaryElement Element = { | |||
14008 | Key.get(), Value.get(), SourceLocation(), NumExpansions | |||
14009 | }; | |||
14010 | ||||
14011 | // If any unexpanded parameter packs remain, we still have a | |||
14012 | // pack expansion. | |||
14013 | // FIXME: Can this really happen? | |||
14014 | if (Key.get()->containsUnexpandedParameterPack() || | |||
14015 | Value.get()->containsUnexpandedParameterPack()) | |||
14016 | Element.EllipsisLoc = OrigElement.EllipsisLoc; | |||
14017 | ||||
14018 | Elements.push_back(Element); | |||
14019 | } | |||
14020 | ||||
14021 | // FIXME: Retain a pack expansion if RetainExpansion is true. | |||
14022 | ||||
14023 | // We've finished with this pack expansion. | |||
14024 | continue; | |||
14025 | } | |||
14026 | ||||
14027 | // Transform and check key. | |||
14028 | ExprResult Key = getDerived().TransformExpr(OrigElement.Key); | |||
14029 | if (Key.isInvalid()) | |||
14030 | return ExprError(); | |||
14031 | ||||
14032 | if (Key.get() != OrigElement.Key) | |||
14033 | ArgChanged = true; | |||
14034 | ||||
14035 | // Transform and check value. | |||
14036 | ExprResult Value | |||
14037 | = getDerived().TransformExpr(OrigElement.Value); | |||
14038 | if (Value.isInvalid()) | |||
14039 | return ExprError(); | |||
14040 | ||||
14041 | if (Value.get() != OrigElement.Value) | |||
14042 | ArgChanged = true; | |||
14043 | ||||
14044 | ObjCDictionaryElement Element = { | |||
14045 | Key.get(), Value.get(), SourceLocation(), None | |||
14046 | }; | |||
14047 | Elements.push_back(Element); | |||
14048 | } | |||
14049 | ||||
14050 | if (!getDerived().AlwaysRebuild() && !ArgChanged) | |||
14051 | return SemaRef.MaybeBindToTemporary(E); | |||
14052 | ||||
14053 | return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(), | |||
14054 | Elements); | |||
14055 | } | |||
14056 | ||||
14057 | template<typename Derived> | |||
14058 | ExprResult | |||
14059 | TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) { | |||
14060 | TypeSourceInfo *EncodedTypeInfo | |||
14061 | = getDerived().TransformType(E->getEncodedTypeSourceInfo()); | |||
14062 | if (!EncodedTypeInfo) | |||
14063 | return ExprError(); | |||
14064 | ||||
14065 | if (!getDerived().AlwaysRebuild() && | |||
14066 | EncodedTypeInfo == E->getEncodedTypeSourceInfo()) | |||
14067 | return E; | |||
14068 | ||||
14069 | return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(), | |||
14070 | EncodedTypeInfo, | |||
14071 | E->getRParenLoc()); | |||
14072 | } | |||
14073 | ||||
14074 | template<typename Derived> | |||
14075 | ExprResult TreeTransform<Derived>:: | |||
14076 | TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { | |||
14077 | // This is a kind of implicit conversion, and it needs to get dropped | |||
14078 | // and recomputed for the same general reasons that ImplicitCastExprs | |||
14079 | // do, as well a more specific one: this expression is only valid when | |||
14080 | // it appears *immediately* as an argument expression. | |||
14081 | return getDerived().TransformExpr(E->getSubExpr()); | |||
14082 | } | |||
14083 | ||||
14084 | template<typename Derived> | |||
14085 | ExprResult TreeTransform<Derived>:: | |||
14086 | TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { | |||
14087 | TypeSourceInfo *TSInfo | |||
14088 | = getDerived().TransformType(E->getTypeInfoAsWritten()); | |||
14089 | if (!TSInfo) | |||
14090 | return ExprError(); | |||
14091 | ||||
14092 | ExprResult Result = getDerived().TransformExpr(E->getSubExpr()); | |||
14093 | if (Result.isInvalid()) | |||
14094 | return ExprError(); | |||
14095 | ||||
14096 | if (!getDerived().AlwaysRebuild() && | |||
14097 | TSInfo == E->getTypeInfoAsWritten() && | |||
14098 | Result.get() == E->getSubExpr()) | |||
14099 | return E; | |||
14100 | ||||
14101 | return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(), | |||
14102 | E->getBridgeKeywordLoc(), TSInfo, | |||
14103 | Result.get()); | |||
14104 | } | |||
14105 | ||||
14106 | template <typename Derived> | |||
14107 | ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr( | |||
14108 | ObjCAvailabilityCheckExpr *E) { | |||
14109 | return E; | |||
14110 | } | |||
14111 | ||||
14112 | template<typename Derived> | |||
14113 | ExprResult | |||
14114 | TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) { | |||
14115 | // Transform arguments. | |||
14116 | bool ArgChanged = false; | |||
14117 | SmallVector<Expr*, 8> Args; | |||
14118 | Args.reserve(E->getNumArgs()); | |||
14119 | if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args, | |||
14120 | &ArgChanged)) | |||
14121 | return ExprError(); | |||
14122 | ||||
14123 | if (E->getReceiverKind() == ObjCMessageExpr::Class) { | |||
14124 | // Class message: transform the receiver type. | |||
14125 | TypeSourceInfo *ReceiverTypeInfo | |||
14126 | = getDerived().TransformType(E->getClassReceiverTypeInfo()); | |||
14127 | if (!ReceiverTypeInfo) | |||
14128 | return ExprError(); | |||
14129 | ||||
14130 | // If nothing changed, just retain the existing message send. | |||
14131 | if (!getDerived().AlwaysRebuild() && | |||
14132 | ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged) | |||
14133 | return SemaRef.MaybeBindToTemporary(E); | |||
14134 | ||||
14135 | // Build a new class message send. | |||
14136 | SmallVector<SourceLocation, 16> SelLocs; | |||
14137 | E->getSelectorLocs(SelLocs); | |||
14138 | return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo, | |||
14139 | E->getSelector(), | |||
14140 | SelLocs, | |||
14141 | E->getMethodDecl(), | |||
14142 | E->getLeftLoc(), | |||
14143 | Args, | |||
14144 | E->getRightLoc()); | |||
14145 | } | |||
14146 | else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass || | |||
14147 | E->getReceiverKind() == ObjCMessageExpr::SuperInstance) { | |||
14148 | if (!E->getMethodDecl()) | |||
14149 | return ExprError(); | |||
14150 | ||||
14151 | // Build a new class message send to 'super'. | |||
14152 | SmallVector<SourceLocation, 16> SelLocs; | |||
14153 | E->getSelectorLocs(SelLocs); | |||
14154 | return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(), | |||
14155 | E->getSelector(), | |||
14156 | SelLocs, | |||
14157 | E->getReceiverType(), | |||
14158 | E->getMethodDecl(), | |||
14159 | E->getLeftLoc(), | |||
14160 | Args, | |||
14161 | E->getRightLoc()); | |||
14162 | } | |||
14163 | ||||
14164 | // Instance message: transform the receiver | |||
14165 | assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&(static_cast <bool> (E->getReceiverKind() == ObjCMessageExpr ::Instance && "Only class and instance messages may be instantiated" ) ? void (0) : __assert_fail ("E->getReceiverKind() == ObjCMessageExpr::Instance && \"Only class and instance messages may be instantiated\"" , "clang/lib/Sema/TreeTransform.h", 14166, __extension__ __PRETTY_FUNCTION__ )) | |||
14166 | "Only class and instance messages may be instantiated")(static_cast <bool> (E->getReceiverKind() == ObjCMessageExpr ::Instance && "Only class and instance messages may be instantiated" ) ? void (0) : __assert_fail ("E->getReceiverKind() == ObjCMessageExpr::Instance && \"Only class and instance messages may be instantiated\"" , "clang/lib/Sema/TreeTransform.h", 14166, __extension__ __PRETTY_FUNCTION__ )); | |||
14167 | ExprResult Receiver | |||
14168 | = getDerived().TransformExpr(E->getInstanceReceiver()); | |||
14169 | if (Receiver.isInvalid()) | |||
14170 | return ExprError(); | |||
14171 | ||||
14172 | // If nothing changed, just retain the existing message send. | |||
14173 | if (!getDerived().AlwaysRebuild() && | |||
14174 | Receiver.get() == E->getInstanceReceiver() && !ArgChanged) | |||
14175 | return SemaRef.MaybeBindToTemporary(E); | |||
14176 | ||||
14177 | // Build a new instance message send. | |||
14178 | SmallVector<SourceLocation, 16> SelLocs; | |||
14179 | E->getSelectorLocs(SelLocs); | |||
14180 | return getDerived().RebuildObjCMessageExpr(Receiver.get(), | |||
14181 | E->getSelector(), | |||
14182 | SelLocs, | |||
14183 | E->getMethodDecl(), | |||
14184 | E->getLeftLoc(), | |||
14185 | Args, | |||
14186 | E->getRightLoc()); | |||
14187 | } | |||
14188 | ||||
14189 | template<typename Derived> | |||
14190 | ExprResult | |||
14191 | TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) { | |||
14192 | return E; | |||
14193 | } | |||
14194 | ||||
14195 | template<typename Derived> | |||
14196 | ExprResult | |||
14197 | TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) { | |||
14198 | return E; | |||
14199 | } | |||
14200 | ||||
14201 | template<typename Derived> | |||
14202 | ExprResult | |||
14203 | TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) { | |||
14204 | // Transform the base expression. | |||
14205 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
14206 | if (Base.isInvalid()) | |||
14207 | return ExprError(); | |||
14208 | ||||
14209 | // We don't need to transform the ivar; it will never change. | |||
14210 | ||||
14211 | // If nothing changed, just retain the existing expression. | |||
14212 | if (!getDerived().AlwaysRebuild() && | |||
14213 | Base.get() == E->getBase()) | |||
14214 | return E; | |||
14215 | ||||
14216 | return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(), | |||
14217 | E->getLocation(), | |||
14218 | E->isArrow(), E->isFreeIvar()); | |||
14219 | } | |||
14220 | ||||
14221 | template<typename Derived> | |||
14222 | ExprResult | |||
14223 | TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { | |||
14224 | // 'super' and types never change. Property never changes. Just | |||
14225 | // retain the existing expression. | |||
14226 | if (!E->isObjectReceiver()) | |||
14227 | return E; | |||
14228 | ||||
14229 | // Transform the base expression. | |||
14230 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
14231 | if (Base.isInvalid()) | |||
14232 | return ExprError(); | |||
14233 | ||||
14234 | // We don't need to transform the property; it will never change. | |||
14235 | ||||
14236 | // If nothing changed, just retain the existing expression. | |||
14237 | if (!getDerived().AlwaysRebuild() && | |||
14238 | Base.get() == E->getBase()) | |||
14239 | return E; | |||
14240 | ||||
14241 | if (E->isExplicitProperty()) | |||
14242 | return getDerived().RebuildObjCPropertyRefExpr(Base.get(), | |||
14243 | E->getExplicitProperty(), | |||
14244 | E->getLocation()); | |||
14245 | ||||
14246 | return getDerived().RebuildObjCPropertyRefExpr(Base.get(), | |||
14247 | SemaRef.Context.PseudoObjectTy, | |||
14248 | E->getImplicitPropertyGetter(), | |||
14249 | E->getImplicitPropertySetter(), | |||
14250 | E->getLocation()); | |||
14251 | } | |||
14252 | ||||
14253 | template<typename Derived> | |||
14254 | ExprResult | |||
14255 | TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) { | |||
14256 | // Transform the base expression. | |||
14257 | ExprResult Base = getDerived().TransformExpr(E->getBaseExpr()); | |||
14258 | if (Base.isInvalid()) | |||
14259 | return ExprError(); | |||
14260 | ||||
14261 | // Transform the key expression. | |||
14262 | ExprResult Key = getDerived().TransformExpr(E->getKeyExpr()); | |||
14263 | if (Key.isInvalid()) | |||
14264 | return ExprError(); | |||
14265 | ||||
14266 | // If nothing changed, just retain the existing expression. | |||
14267 | if (!getDerived().AlwaysRebuild() && | |||
14268 | Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr()) | |||
14269 | return E; | |||
14270 | ||||
14271 | return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(), | |||
14272 | Base.get(), Key.get(), | |||
14273 | E->getAtIndexMethodDecl(), | |||
14274 | E->setAtIndexMethodDecl()); | |||
14275 | } | |||
14276 | ||||
14277 | template<typename Derived> | |||
14278 | ExprResult | |||
14279 | TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) { | |||
14280 | // Transform the base expression. | |||
14281 | ExprResult Base = getDerived().TransformExpr(E->getBase()); | |||
14282 | if (Base.isInvalid()) | |||
14283 | return ExprError(); | |||
14284 | ||||
14285 | // If nothing changed, just retain the existing expression. | |||
14286 | if (!getDerived().AlwaysRebuild() && | |||
14287 | Base.get() == E->getBase()) | |||
14288 | return E; | |||
14289 | ||||
14290 | return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(), | |||
14291 | E->getOpLoc(), | |||
14292 | E->isArrow()); | |||
14293 | } | |||
14294 | ||||
14295 | template<typename Derived> | |||
14296 | ExprResult | |||
14297 | TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) { | |||
14298 | bool ArgumentChanged = false; | |||
14299 | SmallVector<Expr*, 8> SubExprs; | |||
14300 | SubExprs.reserve(E->getNumSubExprs()); | |||
14301 | if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, | |||
14302 | SubExprs, &ArgumentChanged)) | |||
14303 | return ExprError(); | |||
14304 | ||||
14305 | if (!getDerived().AlwaysRebuild() && | |||
14306 | !ArgumentChanged) | |||
14307 | return E; | |||
14308 | ||||
14309 | return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(), | |||
14310 | SubExprs, | |||
14311 | E->getRParenLoc()); | |||
14312 | } | |||
14313 | ||||
14314 | template<typename Derived> | |||
14315 | ExprResult | |||
14316 | TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) { | |||
14317 | ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr()); | |||
14318 | if (SrcExpr.isInvalid()) | |||
14319 | return ExprError(); | |||
14320 | ||||
14321 | TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo()); | |||
14322 | if (!Type) | |||
14323 | return ExprError(); | |||
14324 | ||||
14325 | if (!getDerived().AlwaysRebuild() && | |||
14326 | Type == E->getTypeSourceInfo() && | |||
14327 | SrcExpr.get() == E->getSrcExpr()) | |||
14328 | return E; | |||
14329 | ||||
14330 | return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(), | |||
14331 | SrcExpr.get(), Type, | |||
14332 | E->getRParenLoc()); | |||
14333 | } | |||
14334 | ||||
14335 | template<typename Derived> | |||
14336 | ExprResult | |||
14337 | TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { | |||
14338 | BlockDecl *oldBlock = E->getBlockDecl(); | |||
14339 | ||||
14340 | SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr); | |||
14341 | BlockScopeInfo *blockScope = SemaRef.getCurBlock(); | |||
14342 | ||||
14343 | blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic()); | |||
14344 | blockScope->TheDecl->setBlockMissingReturnType( | |||
14345 | oldBlock->blockMissingReturnType()); | |||
14346 | ||||
14347 | SmallVector<ParmVarDecl*, 4> params; | |||
14348 | SmallVector<QualType, 4> paramTypes; | |||
14349 | ||||
14350 | const FunctionProtoType *exprFunctionType = E->getFunctionType(); | |||
14351 | ||||
14352 | // Parameter substitution. | |||
14353 | Sema::ExtParameterInfoBuilder extParamInfos; | |||
14354 | if (getDerived().TransformFunctionTypeParams( | |||
14355 | E->getCaretLocation(), oldBlock->parameters(), nullptr, | |||
14356 | exprFunctionType->getExtParameterInfosOrNull(), paramTypes, ¶ms, | |||
14357 | extParamInfos)) { | |||
14358 | getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr); | |||
14359 | return ExprError(); | |||
14360 | } | |||
14361 | ||||
14362 | QualType exprResultType = | |||
14363 | getDerived().TransformType(exprFunctionType->getReturnType()); | |||
14364 | ||||
14365 | auto epi = exprFunctionType->getExtProtoInfo(); | |||
14366 | epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size()); | |||
14367 | ||||
14368 | QualType functionType = | |||
14369 | getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi); | |||
14370 | blockScope->FunctionType = functionType; | |||
14371 | ||||
14372 | // Set the parameters on the block decl. | |||
14373 | if (!params.empty()) | |||
14374 | blockScope->TheDecl->setParams(params); | |||
14375 | ||||
14376 | if (!oldBlock->blockMissingReturnType()) { | |||
14377 | blockScope->HasImplicitReturnType = false; | |||
14378 | blockScope->ReturnType = exprResultType; | |||
14379 | } | |||
14380 | ||||
14381 | // Transform the body | |||
14382 | StmtResult body = getDerived().TransformStmt(E->getBody()); | |||
14383 | if (body.isInvalid()) { | |||
14384 | getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr); | |||
14385 | return ExprError(); | |||
14386 | } | |||
14387 | ||||
14388 | #ifndef NDEBUG | |||
14389 | // In builds with assertions, make sure that we captured everything we | |||
14390 | // captured before. | |||
14391 | if (!SemaRef.getDiagnostics().hasErrorOccurred()) { | |||
14392 | for (const auto &I : oldBlock->captures()) { | |||
14393 | VarDecl *oldCapture = I.getVariable(); | |||
14394 | ||||
14395 | // Ignore parameter packs. | |||
14396 | if (oldCapture->isParameterPack()) | |||
14397 | continue; | |||
14398 | ||||
14399 | VarDecl *newCapture = | |||
14400 | cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(), | |||
14401 | oldCapture)); | |||
14402 | assert(blockScope->CaptureMap.count(newCapture))(static_cast <bool> (blockScope->CaptureMap.count(newCapture )) ? void (0) : __assert_fail ("blockScope->CaptureMap.count(newCapture)" , "clang/lib/Sema/TreeTransform.h", 14402, __extension__ __PRETTY_FUNCTION__ )); | |||
14403 | } | |||
14404 | assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured())(static_cast <bool> (oldBlock->capturesCXXThis() == blockScope ->isCXXThisCaptured()) ? void (0) : __assert_fail ("oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured()" , "clang/lib/Sema/TreeTransform.h", 14404, __extension__ __PRETTY_FUNCTION__ )); | |||
14405 | } | |||
14406 | #endif | |||
14407 | ||||
14408 | return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(), | |||
14409 | /*Scope=*/nullptr); | |||
14410 | } | |||
14411 | ||||
14412 | template<typename Derived> | |||
14413 | ExprResult | |||
14414 | TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) { | |||
14415 | ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr()); | |||
14416 | if (SrcExpr.isInvalid()) | |||
14417 | return ExprError(); | |||
14418 | ||||
14419 | QualType Type = getDerived().TransformType(E->getType()); | |||
14420 | ||||
14421 | return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(), | |||
14422 | E->getRParenLoc()); | |||
14423 | } | |||
14424 | ||||
14425 | template<typename Derived> | |||
14426 | ExprResult | |||
14427 | TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) { | |||
14428 | bool ArgumentChanged = false; | |||
14429 | SmallVector<Expr*, 8> SubExprs; | |||
14430 | SubExprs.reserve(E->getNumSubExprs()); | |||
14431 | if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, | |||
14432 | SubExprs, &ArgumentChanged)) | |||
14433 | return ExprError(); | |||
14434 | ||||
14435 | if (!getDerived().AlwaysRebuild() && | |||
14436 | !ArgumentChanged) | |||
14437 | return E; | |||
14438 | ||||
14439 | return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs, | |||
14440 | E->getOp(), E->getRParenLoc()); | |||
14441 | } | |||
14442 | ||||
14443 | //===----------------------------------------------------------------------===// | |||
14444 | // Type reconstruction | |||
14445 | //===----------------------------------------------------------------------===// | |||
14446 | ||||
14447 | template<typename Derived> | |||
14448 | QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType, | |||
14449 | SourceLocation Star) { | |||
14450 | return SemaRef.BuildPointerType(PointeeType, Star, | |||
14451 | getDerived().getBaseEntity()); | |||
14452 | } | |||
14453 | ||||
14454 | template<typename Derived> | |||
14455 | QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType, | |||
14456 | SourceLocation Star) { | |||
14457 | return SemaRef.BuildBlockPointerType(PointeeType, Star, | |||
14458 | getDerived().getBaseEntity()); | |||
14459 | } | |||
14460 | ||||
14461 | template<typename Derived> | |||
14462 | QualType | |||
14463 | TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType, | |||
14464 | bool WrittenAsLValue, | |||
14465 | SourceLocation Sigil) { | |||
14466 | return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, | |||
14467 | Sigil, getDerived().getBaseEntity()); | |||
14468 | } | |||
14469 | ||||
14470 | template<typename Derived> | |||
14471 | QualType | |||
14472 | TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType, | |||
14473 | QualType ClassType, | |||
14474 | SourceLocation Sigil) { | |||
14475 | return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil, | |||
14476 | getDerived().getBaseEntity()); | |||
14477 | } | |||
14478 | ||||
14479 | template<typename Derived> | |||
14480 | QualType TreeTransform<Derived>::RebuildObjCTypeParamType( | |||
14481 | const ObjCTypeParamDecl *Decl, | |||
14482 | SourceLocation ProtocolLAngleLoc, | |||
14483 | ArrayRef<ObjCProtocolDecl *> Protocols, | |||
14484 | ArrayRef<SourceLocation> ProtocolLocs, | |||
14485 | SourceLocation ProtocolRAngleLoc) { | |||
14486 | return SemaRef.BuildObjCTypeParamType(Decl, | |||
14487 | ProtocolLAngleLoc, Protocols, | |||
14488 | ProtocolLocs, ProtocolRAngleLoc, | |||
14489 | /*FailOnError=*/true); | |||
14490 | } | |||
14491 | ||||
14492 | template<typename Derived> | |||
14493 | QualType TreeTransform<Derived>::RebuildObjCObjectType( | |||
14494 | QualType BaseType, | |||
14495 | SourceLocation Loc, | |||
14496 | SourceLocation TypeArgsLAngleLoc, | |||
14497 | ArrayRef<TypeSourceInfo *> TypeArgs, | |||
14498 | SourceLocation TypeArgsRAngleLoc, | |||
14499 | SourceLocation ProtocolLAngleLoc, | |||
14500 | ArrayRef<ObjCProtocolDecl *> Protocols, | |||
14501 | ArrayRef<SourceLocation> ProtocolLocs, | |||
14502 | SourceLocation ProtocolRAngleLoc) { | |||
14503 | return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, | |||
14504 | TypeArgs, TypeArgsRAngleLoc, | |||
14505 | ProtocolLAngleLoc, Protocols, ProtocolLocs, | |||
14506 | ProtocolRAngleLoc, | |||
14507 | /*FailOnError=*/true); | |||
14508 | } | |||
14509 | ||||
14510 | template<typename Derived> | |||
14511 | QualType TreeTransform<Derived>::RebuildObjCObjectPointerType( | |||
14512 | QualType PointeeType, | |||
14513 | SourceLocation Star) { | |||
14514 | return SemaRef.Context.getObjCObjectPointerType(PointeeType); | |||
14515 | } | |||
14516 | ||||
14517 | template<typename Derived> | |||
14518 | QualType | |||
14519 | TreeTransform<Derived>::RebuildArrayType(QualType ElementType, | |||
14520 | ArrayType::ArraySizeModifier SizeMod, | |||
14521 | const llvm::APInt *Size, | |||
14522 | Expr *SizeExpr, | |||
14523 | unsigned IndexTypeQuals, | |||
14524 | SourceRange BracketsRange) { | |||
14525 | if (SizeExpr || !Size) | |||
14526 | return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr, | |||
14527 | IndexTypeQuals, BracketsRange, | |||
14528 | getDerived().getBaseEntity()); | |||
14529 | ||||
14530 | QualType Types[] = { | |||
14531 | SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy, | |||
14532 | SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy, | |||
14533 | SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty | |||
14534 | }; | |||
14535 | QualType SizeType; | |||
14536 | for (const auto &T : Types) | |||
14537 | if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) { | |||
14538 | SizeType = T; | |||
14539 | break; | |||
14540 | } | |||
14541 | ||||
14542 | // Note that we can return a VariableArrayType here in the case where | |||
14543 | // the element type was a dependent VariableArrayType. | |||
14544 | IntegerLiteral *ArraySize | |||
14545 | = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType, | |||
14546 | /*FIXME*/BracketsRange.getBegin()); | |||
14547 | return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize, | |||
14548 | IndexTypeQuals, BracketsRange, | |||
14549 | getDerived().getBaseEntity()); | |||
14550 | } | |||
14551 | ||||
14552 | template<typename Derived> | |||
14553 | QualType | |||
14554 | TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType, | |||
14555 | ArrayType::ArraySizeModifier SizeMod, | |||
14556 | const llvm::APInt &Size, | |||
14557 | Expr *SizeExpr, | |||
14558 | unsigned IndexTypeQuals, | |||
14559 | SourceRange BracketsRange) { | |||
14560 | return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr, | |||
14561 | IndexTypeQuals, BracketsRange); | |||
14562 | } | |||
14563 | ||||
14564 | template<typename Derived> | |||
14565 | QualType | |||
14566 | TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType, | |||
14567 | ArrayType::ArraySizeModifier SizeMod, | |||
14568 | unsigned IndexTypeQuals, | |||
14569 | SourceRange BracketsRange) { | |||
14570 | return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr, | |||
14571 | IndexTypeQuals, BracketsRange); | |||
14572 | } | |||
14573 | ||||
14574 | template<typename Derived> | |||
14575 | QualType | |||
14576 | TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType, | |||
14577 | ArrayType::ArraySizeModifier SizeMod, | |||
14578 | Expr *SizeExpr, | |||
14579 | unsigned IndexTypeQuals, | |||
14580 | SourceRange BracketsRange) { | |||
14581 | return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, | |||
14582 | SizeExpr, | |||
14583 | IndexTypeQuals, BracketsRange); | |||
14584 | } | |||
14585 | ||||
14586 | template<typename Derived> | |||
14587 | QualType | |||
14588 | TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType, | |||
14589 | ArrayType::ArraySizeModifier SizeMod, | |||
14590 | Expr *SizeExpr, | |||
14591 | unsigned IndexTypeQuals, | |||
14592 | SourceRange BracketsRange) { | |||
14593 | return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, | |||
14594 | SizeExpr, | |||
14595 | IndexTypeQuals, BracketsRange); | |||
14596 | } | |||
14597 | ||||
14598 | template <typename Derived> | |||
14599 | QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType( | |||
14600 | QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) { | |||
14601 | return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr, | |||
14602 | AttributeLoc); | |||
14603 | } | |||
14604 | ||||
14605 | template <typename Derived> | |||
14606 | QualType | |||
14607 | TreeTransform<Derived>::RebuildVectorType(QualType ElementType, | |||
14608 | unsigned NumElements, | |||
14609 | VectorType::VectorKind VecKind) { | |||
14610 | // FIXME: semantic checking! | |||
14611 | return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind); | |||
14612 | } | |||
14613 | ||||
14614 | template <typename Derived> | |||
14615 | QualType TreeTransform<Derived>::RebuildDependentVectorType( | |||
14616 | QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc, | |||
14617 | VectorType::VectorKind VecKind) { | |||
14618 | return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc); | |||
14619 | } | |||
14620 | ||||
14621 | template<typename Derived> | |||
14622 | QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType, | |||
14623 | unsigned NumElements, | |||
14624 | SourceLocation AttributeLoc) { | |||
14625 | llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy), | |||
14626 | NumElements, true); | |||
14627 | IntegerLiteral *VectorSize | |||
14628 | = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy, | |||
14629 | AttributeLoc); | |||
14630 | return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc); | |||
14631 | } | |||
14632 | ||||
14633 | template<typename Derived> | |||
14634 | QualType | |||
14635 | TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType, | |||
14636 | Expr *SizeExpr, | |||
14637 | SourceLocation AttributeLoc) { | |||
14638 | return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc); | |||
14639 | } | |||
14640 | ||||
14641 | template <typename Derived> | |||
14642 | QualType TreeTransform<Derived>::RebuildConstantMatrixType( | |||
14643 | QualType ElementType, unsigned NumRows, unsigned NumColumns) { | |||
14644 | return SemaRef.Context.getConstantMatrixType(ElementType, NumRows, | |||
14645 | NumColumns); | |||
14646 | } | |||
14647 | ||||
14648 | template <typename Derived> | |||
14649 | QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType( | |||
14650 | QualType ElementType, Expr *RowExpr, Expr *ColumnExpr, | |||
14651 | SourceLocation AttributeLoc) { | |||
14652 | return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr, | |||
14653 | AttributeLoc); | |||
14654 | } | |||
14655 | ||||
14656 | template<typename Derived> | |||
14657 | QualType TreeTransform<Derived>::RebuildFunctionProtoType( | |||
14658 | QualType T, | |||
14659 | MutableArrayRef<QualType> ParamTypes, | |||
14660 | const FunctionProtoType::ExtProtoInfo &EPI) { | |||
14661 | return SemaRef.BuildFunctionType(T, ParamTypes, | |||
14662 | getDerived().getBaseLocation(), | |||
14663 | getDerived().getBaseEntity(), | |||
14664 | EPI); | |||
14665 | } | |||
14666 | ||||
14667 | template<typename Derived> | |||
14668 | QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) { | |||
14669 | return SemaRef.Context.getFunctionNoProtoType(T); | |||
14670 | } | |||
14671 | ||||
14672 | template<typename Derived> | |||
14673 | QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc, | |||
14674 | Decl *D) { | |||
14675 | assert(D && "no decl found")(static_cast <bool> (D && "no decl found") ? void (0) : __assert_fail ("D && \"no decl found\"", "clang/lib/Sema/TreeTransform.h" , 14675, __extension__ __PRETTY_FUNCTION__)); | |||
14676 | if (D->isInvalidDecl()) return QualType(); | |||
14677 | ||||
14678 | // FIXME: Doesn't account for ObjCInterfaceDecl! | |||
14679 | if (auto *UPD = dyn_cast<UsingPackDecl>(D)) { | |||
14680 | // A valid resolved using typename pack expansion decl can have multiple | |||
14681 | // UsingDecls, but they must each have exactly one type, and it must be | |||
14682 | // the same type in every case. But we must have at least one expansion! | |||
14683 | if (UPD->expansions().empty()) { | |||
14684 | getSema().Diag(Loc, diag::err_using_pack_expansion_empty) | |||
14685 | << UPD->isCXXClassMember() << UPD; | |||
14686 | return QualType(); | |||
14687 | } | |||
14688 | ||||
14689 | // We might still have some unresolved types. Try to pick a resolved type | |||
14690 | // if we can. The final instantiation will check that the remaining | |||
14691 | // unresolved types instantiate to the type we pick. | |||
14692 | QualType FallbackT; | |||
14693 | QualType T; | |||
14694 | for (auto *E : UPD->expansions()) { | |||
14695 | QualType ThisT = RebuildUnresolvedUsingType(Loc, E); | |||
14696 | if (ThisT.isNull()) | |||
14697 | continue; | |||
14698 | else if (ThisT->getAs<UnresolvedUsingType>()) | |||
14699 | FallbackT = ThisT; | |||
14700 | else if (T.isNull()) | |||
14701 | T = ThisT; | |||
14702 | else | |||
14703 | assert(getSema().Context.hasSameType(ThisT, T) &&(static_cast <bool> (getSema().Context.hasSameType(ThisT , T) && "mismatched resolved types in using pack expansion" ) ? void (0) : __assert_fail ("getSema().Context.hasSameType(ThisT, T) && \"mismatched resolved types in using pack expansion\"" , "clang/lib/Sema/TreeTransform.h", 14704, __extension__ __PRETTY_FUNCTION__ )) | |||
14704 | "mismatched resolved types in using pack expansion")(static_cast <bool> (getSema().Context.hasSameType(ThisT , T) && "mismatched resolved types in using pack expansion" ) ? void (0) : __assert_fail ("getSema().Context.hasSameType(ThisT, T) && \"mismatched resolved types in using pack expansion\"" , "clang/lib/Sema/TreeTransform.h", 14704, __extension__ __PRETTY_FUNCTION__ )); | |||
14705 | } | |||
14706 | return T.isNull() ? FallbackT : T; | |||
14707 | } else if (auto *Using = dyn_cast<UsingDecl>(D)) { | |||
14708 | assert(Using->hasTypename() &&(static_cast <bool> (Using->hasTypename() && "UnresolvedUsingTypenameDecl transformed to non-typename using" ) ? void (0) : __assert_fail ("Using->hasTypename() && \"UnresolvedUsingTypenameDecl transformed to non-typename using\"" , "clang/lib/Sema/TreeTransform.h", 14709, __extension__ __PRETTY_FUNCTION__ )) | |||
14709 | "UnresolvedUsingTypenameDecl transformed to non-typename using")(static_cast <bool> (Using->hasTypename() && "UnresolvedUsingTypenameDecl transformed to non-typename using" ) ? void (0) : __assert_fail ("Using->hasTypename() && \"UnresolvedUsingTypenameDecl transformed to non-typename using\"" , "clang/lib/Sema/TreeTransform.h", 14709, __extension__ __PRETTY_FUNCTION__ )); | |||
14710 | ||||
14711 | // A valid resolved using typename decl points to exactly one type decl. | |||
14712 | assert(++Using->shadow_begin() == Using->shadow_end())(static_cast <bool> (++Using->shadow_begin() == Using ->shadow_end()) ? void (0) : __assert_fail ("++Using->shadow_begin() == Using->shadow_end()" , "clang/lib/Sema/TreeTransform.h", 14712, __extension__ __PRETTY_FUNCTION__ )); | |||
14713 | ||||
14714 | UsingShadowDecl *Shadow = *Using->shadow_begin(); | |||
14715 | if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc)) | |||
14716 | return QualType(); | |||
14717 | return SemaRef.Context.getUsingType( | |||
14718 | Shadow, SemaRef.Context.getTypeDeclType( | |||
14719 | cast<TypeDecl>(Shadow->getTargetDecl()))); | |||
14720 | } else { | |||
14721 | assert(isa<UnresolvedUsingTypenameDecl>(D) &&(static_cast <bool> (isa<UnresolvedUsingTypenameDecl >(D) && "UnresolvedUsingTypenameDecl transformed to non-using decl" ) ? void (0) : __assert_fail ("isa<UnresolvedUsingTypenameDecl>(D) && \"UnresolvedUsingTypenameDecl transformed to non-using decl\"" , "clang/lib/Sema/TreeTransform.h", 14722, __extension__ __PRETTY_FUNCTION__ )) | |||
14722 | "UnresolvedUsingTypenameDecl transformed to non-using decl")(static_cast <bool> (isa<UnresolvedUsingTypenameDecl >(D) && "UnresolvedUsingTypenameDecl transformed to non-using decl" ) ? void (0) : __assert_fail ("isa<UnresolvedUsingTypenameDecl>(D) && \"UnresolvedUsingTypenameDecl transformed to non-using decl\"" , "clang/lib/Sema/TreeTransform.h", 14722, __extension__ __PRETTY_FUNCTION__ )); | |||
14723 | return SemaRef.Context.getTypeDeclType( | |||
14724 | cast<UnresolvedUsingTypenameDecl>(D)); | |||
14725 | } | |||
14726 | } | |||
14727 | ||||
14728 | template <typename Derived> | |||
14729 | QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation, | |||
14730 | TypeOfKind Kind) { | |||
14731 | return SemaRef.BuildTypeofExprType(E, Kind); | |||
14732 | } | |||
14733 | ||||
14734 | template<typename Derived> | |||
14735 | QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying, | |||
14736 | TypeOfKind Kind) { | |||
14737 | return SemaRef.Context.getTypeOfType(Underlying, Kind); | |||
14738 | } | |||
14739 | ||||
14740 | template <typename Derived> | |||
14741 | QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) { | |||
14742 | return SemaRef.BuildDecltypeType(E); | |||
14743 | } | |||
14744 | ||||
14745 | template<typename Derived> | |||
14746 | QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType, | |||
14747 | UnaryTransformType::UTTKind UKind, | |||
14748 | SourceLocation Loc) { | |||
14749 | return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc); | |||
14750 | } | |||
14751 | ||||
14752 | template<typename Derived> | |||
14753 | QualType TreeTransform<Derived>::RebuildTemplateSpecializationType( | |||
14754 | TemplateName Template, | |||
14755 | SourceLocation TemplateNameLoc, | |||
14756 | TemplateArgumentListInfo &TemplateArgs) { | |||
14757 | return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); | |||
14758 | } | |||
14759 | ||||
14760 | template<typename Derived> | |||
14761 | QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType, | |||
14762 | SourceLocation KWLoc) { | |||
14763 | return SemaRef.BuildAtomicType(ValueType, KWLoc); | |||
14764 | } | |||
14765 | ||||
14766 | template<typename Derived> | |||
14767 | QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType, | |||
14768 | SourceLocation KWLoc, | |||
14769 | bool isReadPipe) { | |||
14770 | return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc) | |||
14771 | : SemaRef.BuildWritePipeType(ValueType, KWLoc); | |||
14772 | } | |||
14773 | ||||
14774 | template <typename Derived> | |||
14775 | QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned, | |||
14776 | unsigned NumBits, | |||
14777 | SourceLocation Loc) { | |||
14778 | llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy), | |||
14779 | NumBits, true); | |||
14780 | IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP, | |||
14781 | SemaRef.Context.IntTy, Loc); | |||
14782 | return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc); | |||
14783 | } | |||
14784 | ||||
14785 | template <typename Derived> | |||
14786 | QualType TreeTransform<Derived>::RebuildDependentBitIntType( | |||
14787 | bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) { | |||
14788 | return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc); | |||
14789 | } | |||
14790 | ||||
14791 | template<typename Derived> | |||
14792 | TemplateName | |||
14793 | TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, | |||
14794 | bool TemplateKW, | |||
14795 | TemplateDecl *Template) { | |||
14796 | return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW, | |||
14797 | TemplateName(Template)); | |||
14798 | } | |||
14799 | ||||
14800 | template<typename Derived> | |||
14801 | TemplateName | |||
14802 | TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, | |||
14803 | SourceLocation TemplateKWLoc, | |||
14804 | const IdentifierInfo &Name, | |||
14805 | SourceLocation NameLoc, | |||
14806 | QualType ObjectType, | |||
14807 | NamedDecl *FirstQualifierInScope, | |||
14808 | bool AllowInjectedClassName) { | |||
14809 | UnqualifiedId TemplateName; | |||
14810 | TemplateName.setIdentifier(&Name, NameLoc); | |||
14811 | Sema::TemplateTy Template; | |||
14812 | getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc, | |||
14813 | TemplateName, ParsedType::make(ObjectType), | |||
14814 | /*EnteringContext=*/false, Template, | |||
14815 | AllowInjectedClassName); | |||
14816 | return Template.get(); | |||
14817 | } | |||
14818 | ||||
14819 | template<typename Derived> | |||
14820 | TemplateName | |||
14821 | TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, | |||
14822 | SourceLocation TemplateKWLoc, | |||
14823 | OverloadedOperatorKind Operator, | |||
14824 | SourceLocation NameLoc, | |||
14825 | QualType ObjectType, | |||
14826 | bool AllowInjectedClassName) { | |||
14827 | UnqualifiedId Name; | |||
14828 | // FIXME: Bogus location information. | |||
14829 | SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; | |||
14830 | Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations); | |||
14831 | Sema::TemplateTy Template; | |||
14832 | getSema().ActOnTemplateName( | |||
14833 | /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType), | |||
14834 | /*EnteringContext=*/false, Template, AllowInjectedClassName); | |||
14835 | return Template.get(); | |||
14836 | } | |||
14837 | ||||
14838 | template<typename Derived> | |||
14839 | ExprResult | |||
14840 | TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, | |||
14841 | SourceLocation OpLoc, | |||
14842 | Expr *OrigCallee, | |||
14843 | Expr *First, | |||
14844 | Expr *Second) { | |||
14845 | Expr *Callee = OrigCallee->IgnoreParenCasts(); | |||
14846 | bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus); | |||
14847 | ||||
14848 | if (First->getObjectKind() == OK_ObjCProperty) { | |||
14849 | BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); | |||
14850 | if (BinaryOperator::isAssignmentOp(Opc)) | |||
14851 | return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc, | |||
14852 | First, Second); | |||
14853 | ExprResult Result = SemaRef.CheckPlaceholderExpr(First); | |||
14854 | if (Result.isInvalid()) | |||
14855 | return ExprError(); | |||
14856 | First = Result.get(); | |||
14857 | } | |||
14858 | ||||
14859 | if (Second && Second->getObjectKind() == OK_ObjCProperty) { | |||
14860 | ExprResult Result = SemaRef.CheckPlaceholderExpr(Second); | |||
14861 | if (Result.isInvalid()) | |||
14862 | return ExprError(); | |||
14863 | Second = Result.get(); | |||
14864 | } | |||
14865 | ||||
14866 | // Determine whether this should be a builtin operation. | |||
14867 | if (Op == OO_Subscript) { | |||
14868 | if (!First->getType()->isOverloadableType() && | |||
14869 | !Second->getType()->isOverloadableType()) | |||
14870 | return getSema().CreateBuiltinArraySubscriptExpr( | |||
14871 | First, Callee->getBeginLoc(), Second, OpLoc); | |||
14872 | } else if (Op == OO_Arrow) { | |||
14873 | // It is possible that the type refers to a RecoveryExpr created earlier | |||
14874 | // in the tree transformation. | |||
14875 | if (First->getType()->isDependentType()) | |||
14876 | return ExprError(); | |||
14877 | // -> is never a builtin operation. | |||
14878 | return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc); | |||
14879 | } else if (Second == nullptr || isPostIncDec) { | |||
14880 | if (!First->getType()->isOverloadableType() || | |||
14881 | (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) { | |||
14882 | // The argument is not of overloadable type, or this is an expression | |||
14883 | // of the form &Class::member, so try to create a built-in unary | |||
14884 | // operation. | |||
14885 | UnaryOperatorKind Opc | |||
14886 | = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec); | |||
14887 | ||||
14888 | return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First); | |||
14889 | } | |||
14890 | } else { | |||
14891 | if (!First->getType()->isOverloadableType() && | |||
14892 | !Second->getType()->isOverloadableType()) { | |||
14893 | // Neither of the arguments is an overloadable type, so try to | |||
14894 | // create a built-in binary operation. | |||
14895 | BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); | |||
14896 | ExprResult Result | |||
14897 | = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second); | |||
14898 | if (Result.isInvalid()) | |||
14899 | return ExprError(); | |||
14900 | ||||
14901 | return Result; | |||
14902 | } | |||
14903 | } | |||
14904 | ||||
14905 | // Compute the transformed set of functions (and function templates) to be | |||
14906 | // used during overload resolution. | |||
14907 | UnresolvedSet<16> Functions; | |||
14908 | bool RequiresADL; | |||
14909 | ||||
14910 | if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) { | |||
14911 | Functions.append(ULE->decls_begin(), ULE->decls_end()); | |||
14912 | // If the overload could not be resolved in the template definition | |||
14913 | // (because we had a dependent argument), ADL is performed as part of | |||
14914 | // template instantiation. | |||
14915 | RequiresADL = ULE->requiresADL(); | |||
14916 | } else { | |||
14917 | // If we've resolved this to a particular non-member function, just call | |||
14918 | // that function. If we resolved it to a member function, | |||
14919 | // CreateOverloaded* will find that function for us. | |||
14920 | NamedDecl *ND = cast<DeclRefExpr>(Callee)->getDecl(); | |||
14921 | if (!isa<CXXMethodDecl>(ND)) | |||
14922 | Functions.addDecl(ND); | |||
14923 | RequiresADL = false; | |||
14924 | } | |||
14925 | ||||
14926 | // Add any functions found via argument-dependent lookup. | |||
14927 | Expr *Args[2] = { First, Second }; | |||
14928 | unsigned NumArgs = 1 + (Second != nullptr); | |||
14929 | ||||
14930 | // Create the overloaded operator invocation for unary operators. | |||
14931 | if (NumArgs == 1 || isPostIncDec) { | |||
14932 | UnaryOperatorKind Opc | |||
14933 | = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec); | |||
14934 | return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First, | |||
14935 | RequiresADL); | |||
14936 | } | |||
14937 | ||||
14938 | if (Op == OO_Subscript) { | |||
14939 | SourceLocation LBrace; | |||
14940 | SourceLocation RBrace; | |||
14941 | ||||
14942 | if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) { | |||
14943 | DeclarationNameLoc NameLoc = DRE->getNameInfo().getInfo(); | |||
14944 | LBrace = NameLoc.getCXXOperatorNameBeginLoc(); | |||
14945 | RBrace = NameLoc.getCXXOperatorNameEndLoc(); | |||
14946 | } else { | |||
14947 | LBrace = Callee->getBeginLoc(); | |||
14948 | RBrace = OpLoc; | |||
14949 | } | |||
14950 | ||||
14951 | return SemaRef.CreateOverloadedArraySubscriptExpr(LBrace, RBrace, | |||
14952 | First, Second); | |||
14953 | } | |||
14954 | ||||
14955 | // Create the overloaded operator invocation for binary operators. | |||
14956 | BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); | |||
14957 | ExprResult Result = SemaRef.CreateOverloadedBinOp( | |||
14958 | OpLoc, Opc, Functions, Args[0], Args[1], RequiresADL); | |||
14959 | if (Result.isInvalid()) | |||
14960 | return ExprError(); | |||
14961 | ||||
14962 | return Result; | |||
14963 | } | |||
14964 | ||||
14965 | template<typename Derived> | |||
14966 | ExprResult | |||
14967 | TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base, | |||
14968 | SourceLocation OperatorLoc, | |||
14969 | bool isArrow, | |||
14970 | CXXScopeSpec &SS, | |||
14971 | TypeSourceInfo *ScopeType, | |||
14972 | SourceLocation CCLoc, | |||
14973 | SourceLocation TildeLoc, | |||
14974 | PseudoDestructorTypeStorage Destroyed) { | |||
14975 | QualType BaseType = Base->getType(); | |||
14976 | if (Base->isTypeDependent() || Destroyed.getIdentifier() || | |||
14977 | (!isArrow && !BaseType->getAs<RecordType>()) || | |||
14978 | (isArrow && BaseType->getAs<PointerType>() && | |||
14979 | !BaseType->castAs<PointerType>()->getPointeeType() | |||
14980 | ->template getAs<RecordType>())){ | |||
14981 | // This pseudo-destructor expression is still a pseudo-destructor. | |||
14982 | return SemaRef.BuildPseudoDestructorExpr( | |||
14983 | Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType, | |||
14984 | CCLoc, TildeLoc, Destroyed); | |||
14985 | } | |||
14986 | ||||
14987 | TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo(); | |||
14988 | DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName( | |||
14989 | SemaRef.Context.getCanonicalType(DestroyedType->getType()))); | |||
14990 | DeclarationNameInfo NameInfo(Name, Destroyed.getLocation()); | |||
14991 | NameInfo.setNamedTypeInfo(DestroyedType); | |||
14992 | ||||
14993 | // The scope type is now known to be a valid nested name specifier | |||
14994 | // component. Tack it on to the end of the nested name specifier. | |||
14995 | if (ScopeType) { | |||
14996 | if (!ScopeType->getType()->getAs<TagType>()) { | |||
14997 | getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(), | |||
14998 | diag::err_expected_class_or_namespace) | |||
14999 | << ScopeType->getType() << getSema().getLangOpts().CPlusPlus; | |||
15000 | return ExprError(); | |||
15001 | } | |||
15002 | SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(), | |||
15003 | CCLoc); | |||
15004 | } | |||
15005 | ||||
15006 | SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. | |||
15007 | return getSema().BuildMemberReferenceExpr(Base, BaseType, | |||
15008 | OperatorLoc, isArrow, | |||
15009 | SS, TemplateKWLoc, | |||
15010 | /*FIXME: FirstQualifier*/ nullptr, | |||
15011 | NameInfo, | |||
15012 | /*TemplateArgs*/ nullptr, | |||
15013 | /*S*/nullptr); | |||
15014 | } | |||
15015 | ||||
15016 | template<typename Derived> | |||
15017 | StmtResult | |||
15018 | TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) { | |||
15019 | SourceLocation Loc = S->getBeginLoc(); | |||
15020 | CapturedDecl *CD = S->getCapturedDecl(); | |||
15021 | unsigned NumParams = CD->getNumParams(); | |||
15022 | unsigned ContextParamPos = CD->getContextParamPosition(); | |||
15023 | SmallVector<Sema::CapturedParamNameType, 4> Params; | |||
15024 | for (unsigned I = 0; I < NumParams; ++I) { | |||
15025 | if (I != ContextParamPos) { | |||
15026 | Params.push_back( | |||
15027 | std::make_pair( | |||
15028 | CD->getParam(I)->getName(), | |||
15029 | getDerived().TransformType(CD->getParam(I)->getType()))); | |||
15030 | } else { | |||
15031 | Params.push_back(std::make_pair(StringRef(), QualType())); | |||
15032 | } | |||
15033 | } | |||
15034 | getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr, | |||
15035 | S->getCapturedRegionKind(), Params); | |||
15036 | StmtResult Body; | |||
15037 | { | |||
15038 | Sema::CompoundScopeRAII CompoundScope(getSema()); | |||
15039 | Body = getDerived().TransformStmt(S->getCapturedStmt()); | |||
15040 | } | |||
15041 | ||||
15042 | if (Body.isInvalid()) { | |||
15043 | getSema().ActOnCapturedRegionError(); | |||
15044 | return StmtError(); | |||
15045 | } | |||
15046 | ||||
15047 | return getSema().ActOnCapturedRegionEnd(Body.get()); | |||
15048 | } | |||
15049 | ||||
15050 | } // end namespace clang | |||
15051 | ||||
15052 | #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H |
1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ |
2 | |* *| |
3 | |* An x-macro database of Clang type nodes *| |
4 | |* *| |
5 | |* Automatically generated file, do not edit! *| |
6 | |* *| |
7 | \*===----------------------------------------------------------------------===*/ |
8 | |
9 | #ifndef ABSTRACT_TYPE |
10 | # define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base) |
11 | #endif |
12 | #ifndef NON_CANONICAL_TYPE |
13 | # define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base) |
14 | #endif |
15 | #ifndef DEPENDENT_TYPE |
16 | # define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base) |
17 | #endif |
18 | #ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE |
19 | # define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base) |
20 | #endif |
21 | NON_CANONICAL_TYPE(Adjusted, Type) |
22 | NON_CANONICAL_TYPE(Decayed, AdjustedType) |
23 | ABSTRACT_TYPE(Array, Type) |
24 | TYPE(ConstantArray, ArrayType) |
25 | DEPENDENT_TYPE(DependentSizedArray, ArrayType) |
26 | TYPE(IncompleteArray, ArrayType) |
27 | TYPE(VariableArray, ArrayType) |
28 | TYPE(Atomic, Type) |
29 | NON_CANONICAL_TYPE(Attributed, Type) |
30 | NON_CANONICAL_TYPE(BTFTagAttributed, Type) |
31 | TYPE(BitInt, Type) |
32 | TYPE(BlockPointer, Type) |
33 | TYPE(Builtin, Type) |
34 | TYPE(Complex, Type) |
35 | NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type) |
36 | ABSTRACT_TYPE(Deduced, Type) |
37 | TYPE(Auto, DeducedType) |
38 | TYPE(DeducedTemplateSpecialization, DeducedType) |
39 | DEPENDENT_TYPE(DependentAddressSpace, Type) |
40 | DEPENDENT_TYPE(DependentBitInt, Type) |
41 | DEPENDENT_TYPE(DependentName, Type) |
42 | DEPENDENT_TYPE(DependentSizedExtVector, Type) |
43 | DEPENDENT_TYPE(DependentTemplateSpecialization, Type) |
44 | DEPENDENT_TYPE(DependentVector, Type) |
45 | NON_CANONICAL_TYPE(Elaborated, Type) |
46 | ABSTRACT_TYPE(Function, Type) |
47 | TYPE(FunctionNoProto, FunctionType) |
48 | TYPE(FunctionProto, FunctionType) |
49 | DEPENDENT_TYPE(InjectedClassName, Type) |
50 | NON_CANONICAL_TYPE(MacroQualified, Type) |
51 | ABSTRACT_TYPE(Matrix, Type) |
52 | TYPE(ConstantMatrix, MatrixType) |
53 | DEPENDENT_TYPE(DependentSizedMatrix, MatrixType) |
54 | TYPE(MemberPointer, Type) |
55 | TYPE(ObjCObjectPointer, Type) |
56 | TYPE(ObjCObject, Type) |
57 | TYPE(ObjCInterface, ObjCObjectType) |
58 | NON_CANONICAL_TYPE(ObjCTypeParam, Type) |
59 | DEPENDENT_TYPE(PackExpansion, Type) |
60 | NON_CANONICAL_TYPE(Paren, Type) |
61 | TYPE(Pipe, Type) |
62 | TYPE(Pointer, Type) |
63 | ABSTRACT_TYPE(Reference, Type) |
64 | TYPE(LValueReference, ReferenceType) |
65 | TYPE(RValueReference, ReferenceType) |
66 | DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type) |
67 | NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type) |
68 | ABSTRACT_TYPE(Tag, Type) |
69 | TYPE(Enum, TagType) |
70 | TYPE(Record, TagType) |
71 | NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type) |
72 | DEPENDENT_TYPE(TemplateTypeParm, Type) |
73 | NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type) |
74 | NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type) |
75 | NON_CANONICAL_TYPE(Typedef, Type) |
76 | NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type) |
77 | DEPENDENT_TYPE(UnresolvedUsing, Type) |
78 | NON_CANONICAL_TYPE(Using, Type) |
79 | TYPE(Vector, Type) |
80 | TYPE(ExtVector, VectorType) |
81 | #ifdef LAST_TYPE |
82 | LAST_TYPE(ExtVector) |
83 | #undef LAST_TYPE |
84 | #endif |
85 | #ifdef LEAF_TYPE |
86 | LEAF_TYPE(Builtin) |
87 | LEAF_TYPE(Enum) |
88 | LEAF_TYPE(InjectedClassName) |
89 | LEAF_TYPE(ObjCInterface) |
90 | LEAF_TYPE(Record) |
91 | LEAF_TYPE(TemplateTypeParm) |
92 | #undef LEAF_TYPE |
93 | #endif |
94 | #undef TYPE |
95 | #undef ABSTRACT_TYPE |
96 | #undef ABSTRACT_TYPE |
97 | #undef NON_CANONICAL_TYPE |
98 | #undef DEPENDENT_TYPE |
99 | #undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE |