xref: /minix3/external/bsd/llvm/dist/clang/lib/Sema/SemaStmt.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file implements semantic analysis for statements.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "clang/Sema/SemaInternal.h"
15f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
16f4a2713aSLionel Sambuc #include "clang/AST/ASTDiagnostic.h"
17f4a2713aSLionel Sambuc #include "clang/AST/CharUnits.h"
18f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h"
19f4a2713aSLionel Sambuc #include "clang/AST/EvaluatedExprVisitor.h"
20f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h"
21f4a2713aSLionel Sambuc #include "clang/AST/ExprObjC.h"
22*0a6a1f1dSLionel Sambuc #include "clang/AST/RecursiveASTVisitor.h"
23f4a2713aSLionel Sambuc #include "clang/AST/StmtCXX.h"
24f4a2713aSLionel Sambuc #include "clang/AST/StmtObjC.h"
25f4a2713aSLionel Sambuc #include "clang/AST/TypeLoc.h"
26f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
27f4a2713aSLionel Sambuc #include "clang/Sema/Initialization.h"
28f4a2713aSLionel Sambuc #include "clang/Sema/Lookup.h"
29f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
30f4a2713aSLionel Sambuc #include "clang/Sema/ScopeInfo.h"
31f4a2713aSLionel Sambuc #include "llvm/ADT/ArrayRef.h"
32f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
33f4a2713aSLionel Sambuc #include "llvm/ADT/SmallPtrSet.h"
34f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
35f4a2713aSLionel Sambuc #include "llvm/ADT/SmallVector.h"
36f4a2713aSLionel Sambuc using namespace clang;
37f4a2713aSLionel Sambuc using namespace sema;
38f4a2713aSLionel Sambuc 
ActOnExprStmt(ExprResult FE)39f4a2713aSLionel Sambuc StmtResult Sema::ActOnExprStmt(ExprResult FE) {
40f4a2713aSLionel Sambuc   if (FE.isInvalid())
41f4a2713aSLionel Sambuc     return StmtError();
42f4a2713aSLionel Sambuc 
43f4a2713aSLionel Sambuc   FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(),
44f4a2713aSLionel Sambuc                            /*DiscardedValue*/ true);
45f4a2713aSLionel Sambuc   if (FE.isInvalid())
46f4a2713aSLionel Sambuc     return StmtError();
47f4a2713aSLionel Sambuc 
48f4a2713aSLionel Sambuc   // C99 6.8.3p2: The expression in an expression statement is evaluated as a
49f4a2713aSLionel Sambuc   // void expression for its side effects.  Conversion to void allows any
50f4a2713aSLionel Sambuc   // operand, even incomplete types.
51f4a2713aSLionel Sambuc 
52f4a2713aSLionel Sambuc   // Same thing in for stmt first clause (when expr) and third clause.
53*0a6a1f1dSLionel Sambuc   return StmtResult(FE.getAs<Stmt>());
54f4a2713aSLionel Sambuc }
55f4a2713aSLionel Sambuc 
56f4a2713aSLionel Sambuc 
ActOnExprStmtError()57f4a2713aSLionel Sambuc StmtResult Sema::ActOnExprStmtError() {
58f4a2713aSLionel Sambuc   DiscardCleanupsInEvaluationContext();
59f4a2713aSLionel Sambuc   return StmtError();
60f4a2713aSLionel Sambuc }
61f4a2713aSLionel Sambuc 
ActOnNullStmt(SourceLocation SemiLoc,bool HasLeadingEmptyMacro)62f4a2713aSLionel Sambuc StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,
63f4a2713aSLionel Sambuc                                bool HasLeadingEmptyMacro) {
64*0a6a1f1dSLionel Sambuc   return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);
65f4a2713aSLionel Sambuc }
66f4a2713aSLionel Sambuc 
ActOnDeclStmt(DeclGroupPtrTy dg,SourceLocation StartLoc,SourceLocation EndLoc)67f4a2713aSLionel Sambuc StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
68f4a2713aSLionel Sambuc                                SourceLocation EndLoc) {
69f4a2713aSLionel Sambuc   DeclGroupRef DG = dg.get();
70f4a2713aSLionel Sambuc 
71f4a2713aSLionel Sambuc   // If we have an invalid decl, just return an error.
72f4a2713aSLionel Sambuc   if (DG.isNull()) return StmtError();
73f4a2713aSLionel Sambuc 
74*0a6a1f1dSLionel Sambuc   return new (Context) DeclStmt(DG, StartLoc, EndLoc);
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc 
ActOnForEachDeclStmt(DeclGroupPtrTy dg)77f4a2713aSLionel Sambuc void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
78f4a2713aSLionel Sambuc   DeclGroupRef DG = dg.get();
79f4a2713aSLionel Sambuc 
80f4a2713aSLionel Sambuc   // If we don't have a declaration, or we have an invalid declaration,
81f4a2713aSLionel Sambuc   // just return.
82f4a2713aSLionel Sambuc   if (DG.isNull() || !DG.isSingleDecl())
83f4a2713aSLionel Sambuc     return;
84f4a2713aSLionel Sambuc 
85f4a2713aSLionel Sambuc   Decl *decl = DG.getSingleDecl();
86f4a2713aSLionel Sambuc   if (!decl || decl->isInvalidDecl())
87f4a2713aSLionel Sambuc     return;
88f4a2713aSLionel Sambuc 
89f4a2713aSLionel Sambuc   // Only variable declarations are permitted.
90f4a2713aSLionel Sambuc   VarDecl *var = dyn_cast<VarDecl>(decl);
91f4a2713aSLionel Sambuc   if (!var) {
92f4a2713aSLionel Sambuc     Diag(decl->getLocation(), diag::err_non_variable_decl_in_for);
93f4a2713aSLionel Sambuc     decl->setInvalidDecl();
94f4a2713aSLionel Sambuc     return;
95f4a2713aSLionel Sambuc   }
96f4a2713aSLionel Sambuc 
97f4a2713aSLionel Sambuc   // foreach variables are never actually initialized in the way that
98f4a2713aSLionel Sambuc   // the parser came up with.
99*0a6a1f1dSLionel Sambuc   var->setInit(nullptr);
100f4a2713aSLionel Sambuc 
101f4a2713aSLionel Sambuc   // In ARC, we don't need to retain the iteration variable of a fast
102f4a2713aSLionel Sambuc   // enumeration loop.  Rather than actually trying to catch that
103f4a2713aSLionel Sambuc   // during declaration processing, we remove the consequences here.
104f4a2713aSLionel Sambuc   if (getLangOpts().ObjCAutoRefCount) {
105f4a2713aSLionel Sambuc     QualType type = var->getType();
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc     // Only do this if we inferred the lifetime.  Inferred lifetime
108f4a2713aSLionel Sambuc     // will show up as a local qualifier because explicit lifetime
109f4a2713aSLionel Sambuc     // should have shown up as an AttributedType instead.
110f4a2713aSLionel Sambuc     if (type.getLocalQualifiers().getObjCLifetime() == Qualifiers::OCL_Strong) {
111f4a2713aSLionel Sambuc       // Add 'const' and mark the variable as pseudo-strong.
112f4a2713aSLionel Sambuc       var->setType(type.withConst());
113f4a2713aSLionel Sambuc       var->setARCPseudoStrong(true);
114f4a2713aSLionel Sambuc     }
115f4a2713aSLionel Sambuc   }
116f4a2713aSLionel Sambuc }
117f4a2713aSLionel Sambuc 
118*0a6a1f1dSLionel Sambuc /// \brief Diagnose unused comparisons, both builtin and overloaded operators.
119*0a6a1f1dSLionel Sambuc /// For '==' and '!=', suggest fixits for '=' or '|='.
120f4a2713aSLionel Sambuc ///
121f4a2713aSLionel Sambuc /// Adding a cast to void (or other expression wrappers) will prevent the
122f4a2713aSLionel Sambuc /// warning from firing.
DiagnoseUnusedComparison(Sema & S,const Expr * E)123f4a2713aSLionel Sambuc static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) {
124f4a2713aSLionel Sambuc   SourceLocation Loc;
125*0a6a1f1dSLionel Sambuc   bool IsNotEqual, CanAssign, IsRelational;
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc   if (const BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {
128*0a6a1f1dSLionel Sambuc     if (!Op->isComparisonOp())
129f4a2713aSLionel Sambuc       return false;
130f4a2713aSLionel Sambuc 
131*0a6a1f1dSLionel Sambuc     IsRelational = Op->isRelationalOp();
132f4a2713aSLionel Sambuc     Loc = Op->getOperatorLoc();
133f4a2713aSLionel Sambuc     IsNotEqual = Op->getOpcode() == BO_NE;
134f4a2713aSLionel Sambuc     CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();
135f4a2713aSLionel Sambuc   } else if (const CXXOperatorCallExpr *Op = dyn_cast<CXXOperatorCallExpr>(E)) {
136*0a6a1f1dSLionel Sambuc     switch (Op->getOperator()) {
137*0a6a1f1dSLionel Sambuc     default:
138f4a2713aSLionel Sambuc       return false;
139*0a6a1f1dSLionel Sambuc     case OO_EqualEqual:
140*0a6a1f1dSLionel Sambuc     case OO_ExclaimEqual:
141*0a6a1f1dSLionel Sambuc       IsRelational = false;
142*0a6a1f1dSLionel Sambuc       break;
143*0a6a1f1dSLionel Sambuc     case OO_Less:
144*0a6a1f1dSLionel Sambuc     case OO_Greater:
145*0a6a1f1dSLionel Sambuc     case OO_GreaterEqual:
146*0a6a1f1dSLionel Sambuc     case OO_LessEqual:
147*0a6a1f1dSLionel Sambuc       IsRelational = true;
148*0a6a1f1dSLionel Sambuc       break;
149*0a6a1f1dSLionel Sambuc     }
150f4a2713aSLionel Sambuc 
151f4a2713aSLionel Sambuc     Loc = Op->getOperatorLoc();
152f4a2713aSLionel Sambuc     IsNotEqual = Op->getOperator() == OO_ExclaimEqual;
153f4a2713aSLionel Sambuc     CanAssign = Op->getArg(0)->IgnoreParenImpCasts()->isLValue();
154f4a2713aSLionel Sambuc   } else {
155f4a2713aSLionel Sambuc     // Not a typo-prone comparison.
156f4a2713aSLionel Sambuc     return false;
157f4a2713aSLionel Sambuc   }
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc   // Suppress warnings when the operator, suspicious as it may be, comes from
160f4a2713aSLionel Sambuc   // a macro expansion.
161f4a2713aSLionel Sambuc   if (S.SourceMgr.isMacroBodyExpansion(Loc))
162f4a2713aSLionel Sambuc     return false;
163f4a2713aSLionel Sambuc 
164f4a2713aSLionel Sambuc   S.Diag(Loc, diag::warn_unused_comparison)
165*0a6a1f1dSLionel Sambuc     << (unsigned)IsRelational << (unsigned)IsNotEqual << E->getSourceRange();
166f4a2713aSLionel Sambuc 
167f4a2713aSLionel Sambuc   // If the LHS is a plausible entity to assign to, provide a fixit hint to
168f4a2713aSLionel Sambuc   // correct common typos.
169*0a6a1f1dSLionel Sambuc   if (!IsRelational && CanAssign) {
170f4a2713aSLionel Sambuc     if (IsNotEqual)
171f4a2713aSLionel Sambuc       S.Diag(Loc, diag::note_inequality_comparison_to_or_assign)
172f4a2713aSLionel Sambuc         << FixItHint::CreateReplacement(Loc, "|=");
173f4a2713aSLionel Sambuc     else
174f4a2713aSLionel Sambuc       S.Diag(Loc, diag::note_equality_comparison_to_assign)
175f4a2713aSLionel Sambuc         << FixItHint::CreateReplacement(Loc, "=");
176f4a2713aSLionel Sambuc   }
177f4a2713aSLionel Sambuc 
178f4a2713aSLionel Sambuc   return true;
179f4a2713aSLionel Sambuc }
180f4a2713aSLionel Sambuc 
DiagnoseUnusedExprResult(const Stmt * S)181f4a2713aSLionel Sambuc void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
182f4a2713aSLionel Sambuc   if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
183f4a2713aSLionel Sambuc     return DiagnoseUnusedExprResult(Label->getSubStmt());
184f4a2713aSLionel Sambuc 
185f4a2713aSLionel Sambuc   const Expr *E = dyn_cast_or_null<Expr>(S);
186f4a2713aSLionel Sambuc   if (!E)
187f4a2713aSLionel Sambuc     return;
188*0a6a1f1dSLionel Sambuc 
189*0a6a1f1dSLionel Sambuc   // If we are in an unevaluated expression context, then there can be no unused
190*0a6a1f1dSLionel Sambuc   // results because the results aren't expected to be used in the first place.
191*0a6a1f1dSLionel Sambuc   if (isUnevaluatedContext())
192*0a6a1f1dSLionel Sambuc     return;
193*0a6a1f1dSLionel Sambuc 
194f4a2713aSLionel Sambuc   SourceLocation ExprLoc = E->IgnoreParens()->getExprLoc();
195f4a2713aSLionel Sambuc   // In most cases, we don't want to warn if the expression is written in a
196f4a2713aSLionel Sambuc   // macro body, or if the macro comes from a system header. If the offending
197f4a2713aSLionel Sambuc   // expression is a call to a function with the warn_unused_result attribute,
198f4a2713aSLionel Sambuc   // we warn no matter the location. Because of the order in which the various
199f4a2713aSLionel Sambuc   // checks need to happen, we factor out the macro-related test here.
200f4a2713aSLionel Sambuc   bool ShouldSuppress =
201f4a2713aSLionel Sambuc       SourceMgr.isMacroBodyExpansion(ExprLoc) ||
202f4a2713aSLionel Sambuc       SourceMgr.isInSystemMacro(ExprLoc);
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc   const Expr *WarnExpr;
205f4a2713aSLionel Sambuc   SourceLocation Loc;
206f4a2713aSLionel Sambuc   SourceRange R1, R2;
207f4a2713aSLionel Sambuc   if (!E->isUnusedResultAWarning(WarnExpr, Loc, R1, R2, Context))
208f4a2713aSLionel Sambuc     return;
209f4a2713aSLionel Sambuc 
210f4a2713aSLionel Sambuc   // If this is a GNU statement expression expanded from a macro, it is probably
211f4a2713aSLionel Sambuc   // unused because it is a function-like macro that can be used as either an
212f4a2713aSLionel Sambuc   // expression or statement.  Don't warn, because it is almost certainly a
213f4a2713aSLionel Sambuc   // false positive.
214f4a2713aSLionel Sambuc   if (isa<StmtExpr>(E) && Loc.isMacroID())
215f4a2713aSLionel Sambuc     return;
216f4a2713aSLionel Sambuc 
217f4a2713aSLionel Sambuc   // Okay, we have an unused result.  Depending on what the base expression is,
218f4a2713aSLionel Sambuc   // we might want to make a more specific diagnostic.  Check for one of these
219f4a2713aSLionel Sambuc   // cases now.
220f4a2713aSLionel Sambuc   unsigned DiagID = diag::warn_unused_expr;
221f4a2713aSLionel Sambuc   if (const ExprWithCleanups *Temps = dyn_cast<ExprWithCleanups>(E))
222f4a2713aSLionel Sambuc     E = Temps->getSubExpr();
223f4a2713aSLionel Sambuc   if (const CXXBindTemporaryExpr *TempExpr = dyn_cast<CXXBindTemporaryExpr>(E))
224f4a2713aSLionel Sambuc     E = TempExpr->getSubExpr();
225f4a2713aSLionel Sambuc 
226f4a2713aSLionel Sambuc   if (DiagnoseUnusedComparison(*this, E))
227f4a2713aSLionel Sambuc     return;
228f4a2713aSLionel Sambuc 
229f4a2713aSLionel Sambuc   E = WarnExpr;
230f4a2713aSLionel Sambuc   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
231f4a2713aSLionel Sambuc     if (E->getType()->isVoidType())
232f4a2713aSLionel Sambuc       return;
233f4a2713aSLionel Sambuc 
234f4a2713aSLionel Sambuc     // If the callee has attribute pure, const, or warn_unused_result, warn with
235f4a2713aSLionel Sambuc     // a more specific message to make it clear what is happening. If the call
236f4a2713aSLionel Sambuc     // is written in a macro body, only warn if it has the warn_unused_result
237f4a2713aSLionel Sambuc     // attribute.
238f4a2713aSLionel Sambuc     if (const Decl *FD = CE->getCalleeDecl()) {
239*0a6a1f1dSLionel Sambuc       if (FD->hasAttr<WarnUnusedResultAttr>()) {
240f4a2713aSLionel Sambuc         Diag(Loc, diag::warn_unused_result) << R1 << R2;
241f4a2713aSLionel Sambuc         return;
242f4a2713aSLionel Sambuc       }
243f4a2713aSLionel Sambuc       if (ShouldSuppress)
244f4a2713aSLionel Sambuc         return;
245*0a6a1f1dSLionel Sambuc       if (FD->hasAttr<PureAttr>()) {
246f4a2713aSLionel Sambuc         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
247f4a2713aSLionel Sambuc         return;
248f4a2713aSLionel Sambuc       }
249*0a6a1f1dSLionel Sambuc       if (FD->hasAttr<ConstAttr>()) {
250f4a2713aSLionel Sambuc         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
251f4a2713aSLionel Sambuc         return;
252f4a2713aSLionel Sambuc       }
253f4a2713aSLionel Sambuc     }
254f4a2713aSLionel Sambuc   } else if (ShouldSuppress)
255f4a2713aSLionel Sambuc     return;
256f4a2713aSLionel Sambuc 
257f4a2713aSLionel Sambuc   if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
258f4a2713aSLionel Sambuc     if (getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {
259f4a2713aSLionel Sambuc       Diag(Loc, diag::err_arc_unused_init_message) << R1;
260f4a2713aSLionel Sambuc       return;
261f4a2713aSLionel Sambuc     }
262f4a2713aSLionel Sambuc     const ObjCMethodDecl *MD = ME->getMethodDecl();
263*0a6a1f1dSLionel Sambuc     if (MD) {
264*0a6a1f1dSLionel Sambuc       if (MD->hasAttr<WarnUnusedResultAttr>()) {
265f4a2713aSLionel Sambuc         Diag(Loc, diag::warn_unused_result) << R1 << R2;
266f4a2713aSLionel Sambuc         return;
267f4a2713aSLionel Sambuc       }
268*0a6a1f1dSLionel Sambuc       if (MD->isPropertyAccessor()) {
269*0a6a1f1dSLionel Sambuc         Diag(Loc, diag::warn_unused_property_expr);
270*0a6a1f1dSLionel Sambuc         return;
271*0a6a1f1dSLionel Sambuc       }
272*0a6a1f1dSLionel Sambuc     }
273f4a2713aSLionel Sambuc   } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
274f4a2713aSLionel Sambuc     const Expr *Source = POE->getSyntacticForm();
275f4a2713aSLionel Sambuc     if (isa<ObjCSubscriptRefExpr>(Source))
276f4a2713aSLionel Sambuc       DiagID = diag::warn_unused_container_subscript_expr;
277f4a2713aSLionel Sambuc     else
278f4a2713aSLionel Sambuc       DiagID = diag::warn_unused_property_expr;
279f4a2713aSLionel Sambuc   } else if (const CXXFunctionalCastExpr *FC
280f4a2713aSLionel Sambuc                                        = dyn_cast<CXXFunctionalCastExpr>(E)) {
281f4a2713aSLionel Sambuc     if (isa<CXXConstructExpr>(FC->getSubExpr()) ||
282f4a2713aSLionel Sambuc         isa<CXXTemporaryObjectExpr>(FC->getSubExpr()))
283f4a2713aSLionel Sambuc       return;
284f4a2713aSLionel Sambuc   }
285f4a2713aSLionel Sambuc   // Diagnose "(void*) blah" as a typo for "(void) blah".
286f4a2713aSLionel Sambuc   else if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(E)) {
287f4a2713aSLionel Sambuc     TypeSourceInfo *TI = CE->getTypeInfoAsWritten();
288f4a2713aSLionel Sambuc     QualType T = TI->getType();
289f4a2713aSLionel Sambuc 
290f4a2713aSLionel Sambuc     // We really do want to use the non-canonical type here.
291f4a2713aSLionel Sambuc     if (T == Context.VoidPtrTy) {
292f4a2713aSLionel Sambuc       PointerTypeLoc TL = TI->getTypeLoc().castAs<PointerTypeLoc>();
293f4a2713aSLionel Sambuc 
294f4a2713aSLionel Sambuc       Diag(Loc, diag::warn_unused_voidptr)
295f4a2713aSLionel Sambuc         << FixItHint::CreateRemoval(TL.getStarLoc());
296f4a2713aSLionel Sambuc       return;
297f4a2713aSLionel Sambuc     }
298f4a2713aSLionel Sambuc   }
299f4a2713aSLionel Sambuc 
300f4a2713aSLionel Sambuc   if (E->isGLValue() && E->getType().isVolatileQualified()) {
301f4a2713aSLionel Sambuc     Diag(Loc, diag::warn_unused_volatile) << R1 << R2;
302f4a2713aSLionel Sambuc     return;
303f4a2713aSLionel Sambuc   }
304f4a2713aSLionel Sambuc 
305*0a6a1f1dSLionel Sambuc   DiagRuntimeBehavior(Loc, nullptr, PDiag(DiagID) << R1 << R2);
306f4a2713aSLionel Sambuc }
307f4a2713aSLionel Sambuc 
ActOnStartOfCompoundStmt()308f4a2713aSLionel Sambuc void Sema::ActOnStartOfCompoundStmt() {
309f4a2713aSLionel Sambuc   PushCompoundScope();
310f4a2713aSLionel Sambuc }
311f4a2713aSLionel Sambuc 
ActOnFinishOfCompoundStmt()312f4a2713aSLionel Sambuc void Sema::ActOnFinishOfCompoundStmt() {
313f4a2713aSLionel Sambuc   PopCompoundScope();
314f4a2713aSLionel Sambuc }
315f4a2713aSLionel Sambuc 
getCurCompoundScope() const316f4a2713aSLionel Sambuc sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
317f4a2713aSLionel Sambuc   return getCurFunction()->CompoundScopes.back();
318f4a2713aSLionel Sambuc }
319f4a2713aSLionel Sambuc 
ActOnCompoundStmt(SourceLocation L,SourceLocation R,ArrayRef<Stmt * > Elts,bool isStmtExpr)320f4a2713aSLionel Sambuc StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
321f4a2713aSLionel Sambuc                                    ArrayRef<Stmt *> Elts, bool isStmtExpr) {
322f4a2713aSLionel Sambuc   const unsigned NumElts = Elts.size();
323f4a2713aSLionel Sambuc 
324f4a2713aSLionel Sambuc   // If we're in C89 mode, check that we don't have any decls after stmts.  If
325f4a2713aSLionel Sambuc   // so, emit an extension diagnostic.
326f4a2713aSLionel Sambuc   if (!getLangOpts().C99 && !getLangOpts().CPlusPlus) {
327f4a2713aSLionel Sambuc     // Note that __extension__ can be around a decl.
328f4a2713aSLionel Sambuc     unsigned i = 0;
329f4a2713aSLionel Sambuc     // Skip over all declarations.
330f4a2713aSLionel Sambuc     for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)
331f4a2713aSLionel Sambuc       /*empty*/;
332f4a2713aSLionel Sambuc 
333f4a2713aSLionel Sambuc     // We found the end of the list or a statement.  Scan for another declstmt.
334f4a2713aSLionel Sambuc     for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)
335f4a2713aSLionel Sambuc       /*empty*/;
336f4a2713aSLionel Sambuc 
337f4a2713aSLionel Sambuc     if (i != NumElts) {
338f4a2713aSLionel Sambuc       Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
339f4a2713aSLionel Sambuc       Diag(D->getLocation(), diag::ext_mixed_decls_code);
340f4a2713aSLionel Sambuc     }
341f4a2713aSLionel Sambuc   }
342f4a2713aSLionel Sambuc   // Warn about unused expressions in statements.
343f4a2713aSLionel Sambuc   for (unsigned i = 0; i != NumElts; ++i) {
344f4a2713aSLionel Sambuc     // Ignore statements that are last in a statement expression.
345f4a2713aSLionel Sambuc     if (isStmtExpr && i == NumElts - 1)
346f4a2713aSLionel Sambuc       continue;
347f4a2713aSLionel Sambuc 
348f4a2713aSLionel Sambuc     DiagnoseUnusedExprResult(Elts[i]);
349f4a2713aSLionel Sambuc   }
350f4a2713aSLionel Sambuc 
351f4a2713aSLionel Sambuc   // Check for suspicious empty body (null statement) in `for' and `while'
352f4a2713aSLionel Sambuc   // statements.  Don't do anything for template instantiations, this just adds
353f4a2713aSLionel Sambuc   // noise.
354f4a2713aSLionel Sambuc   if (NumElts != 0 && !CurrentInstantiationScope &&
355f4a2713aSLionel Sambuc       getCurCompoundScope().HasEmptyLoopBodies) {
356f4a2713aSLionel Sambuc     for (unsigned i = 0; i != NumElts - 1; ++i)
357f4a2713aSLionel Sambuc       DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
358f4a2713aSLionel Sambuc   }
359f4a2713aSLionel Sambuc 
360*0a6a1f1dSLionel Sambuc   return new (Context) CompoundStmt(Context, Elts, L, R);
361f4a2713aSLionel Sambuc }
362f4a2713aSLionel Sambuc 
363f4a2713aSLionel Sambuc StmtResult
ActOnCaseStmt(SourceLocation CaseLoc,Expr * LHSVal,SourceLocation DotDotDotLoc,Expr * RHSVal,SourceLocation ColonLoc)364f4a2713aSLionel Sambuc Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
365f4a2713aSLionel Sambuc                     SourceLocation DotDotDotLoc, Expr *RHSVal,
366f4a2713aSLionel Sambuc                     SourceLocation ColonLoc) {
367*0a6a1f1dSLionel Sambuc   assert(LHSVal && "missing expression in case statement");
368f4a2713aSLionel Sambuc 
369f4a2713aSLionel Sambuc   if (getCurFunction()->SwitchStack.empty()) {
370f4a2713aSLionel Sambuc     Diag(CaseLoc, diag::err_case_not_in_switch);
371f4a2713aSLionel Sambuc     return StmtError();
372f4a2713aSLionel Sambuc   }
373f4a2713aSLionel Sambuc 
374*0a6a1f1dSLionel Sambuc   ExprResult LHS =
375*0a6a1f1dSLionel Sambuc       CorrectDelayedTyposInExpr(LHSVal, [this](class Expr *E) {
376*0a6a1f1dSLionel Sambuc         if (!getLangOpts().CPlusPlus11)
377*0a6a1f1dSLionel Sambuc           return VerifyIntegerConstantExpression(E);
378*0a6a1f1dSLionel Sambuc         if (Expr *CondExpr =
379*0a6a1f1dSLionel Sambuc                 getCurFunction()->SwitchStack.back()->getCond()) {
380*0a6a1f1dSLionel Sambuc           QualType CondType = CondExpr->getType();
381*0a6a1f1dSLionel Sambuc           llvm::APSInt TempVal;
382*0a6a1f1dSLionel Sambuc           return CheckConvertedConstantExpression(E, CondType, TempVal,
383*0a6a1f1dSLionel Sambuc                                                         CCEK_CaseValue);
384*0a6a1f1dSLionel Sambuc         }
385*0a6a1f1dSLionel Sambuc         return ExprError();
386*0a6a1f1dSLionel Sambuc       });
387*0a6a1f1dSLionel Sambuc   if (LHS.isInvalid())
388*0a6a1f1dSLionel Sambuc     return StmtError();
389*0a6a1f1dSLionel Sambuc   LHSVal = LHS.get();
390*0a6a1f1dSLionel Sambuc 
391f4a2713aSLionel Sambuc   if (!getLangOpts().CPlusPlus11) {
392f4a2713aSLionel Sambuc     // C99 6.8.4.2p3: The expression shall be an integer constant.
393f4a2713aSLionel Sambuc     // However, GCC allows any evaluatable integer expression.
394f4a2713aSLionel Sambuc     if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent()) {
395*0a6a1f1dSLionel Sambuc       LHSVal = VerifyIntegerConstantExpression(LHSVal).get();
396f4a2713aSLionel Sambuc       if (!LHSVal)
397f4a2713aSLionel Sambuc         return StmtError();
398f4a2713aSLionel Sambuc     }
399f4a2713aSLionel Sambuc 
400f4a2713aSLionel Sambuc     // GCC extension: The expression shall be an integer constant.
401f4a2713aSLionel Sambuc 
402f4a2713aSLionel Sambuc     if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent()) {
403*0a6a1f1dSLionel Sambuc       RHSVal = VerifyIntegerConstantExpression(RHSVal).get();
404f4a2713aSLionel Sambuc       // Recover from an error by just forgetting about it.
405f4a2713aSLionel Sambuc     }
406f4a2713aSLionel Sambuc   }
407f4a2713aSLionel Sambuc 
408*0a6a1f1dSLionel Sambuc   LHS = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
409*0a6a1f1dSLionel Sambuc                                  getLangOpts().CPlusPlus11);
410*0a6a1f1dSLionel Sambuc   if (LHS.isInvalid())
411*0a6a1f1dSLionel Sambuc     return StmtError();
412f4a2713aSLionel Sambuc 
413*0a6a1f1dSLionel Sambuc   auto RHS = RHSVal ? ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false,
414*0a6a1f1dSLionel Sambuc                                           getLangOpts().CPlusPlus11)
415*0a6a1f1dSLionel Sambuc                     : ExprResult();
416*0a6a1f1dSLionel Sambuc   if (RHS.isInvalid())
417*0a6a1f1dSLionel Sambuc     return StmtError();
418*0a6a1f1dSLionel Sambuc 
419*0a6a1f1dSLionel Sambuc   CaseStmt *CS = new (Context)
420*0a6a1f1dSLionel Sambuc       CaseStmt(LHS.get(), RHS.get(), CaseLoc, DotDotDotLoc, ColonLoc);
421f4a2713aSLionel Sambuc   getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
422*0a6a1f1dSLionel Sambuc   return CS;
423f4a2713aSLionel Sambuc }
424f4a2713aSLionel Sambuc 
425f4a2713aSLionel Sambuc /// ActOnCaseStmtBody - This installs a statement as the body of a case.
ActOnCaseStmtBody(Stmt * caseStmt,Stmt * SubStmt)426f4a2713aSLionel Sambuc void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) {
427f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(SubStmt);
428f4a2713aSLionel Sambuc 
429f4a2713aSLionel Sambuc   CaseStmt *CS = static_cast<CaseStmt*>(caseStmt);
430f4a2713aSLionel Sambuc   CS->setSubStmt(SubStmt);
431f4a2713aSLionel Sambuc }
432f4a2713aSLionel Sambuc 
433f4a2713aSLionel Sambuc StmtResult
ActOnDefaultStmt(SourceLocation DefaultLoc,SourceLocation ColonLoc,Stmt * SubStmt,Scope * CurScope)434f4a2713aSLionel Sambuc Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
435f4a2713aSLionel Sambuc                        Stmt *SubStmt, Scope *CurScope) {
436f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(SubStmt);
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc   if (getCurFunction()->SwitchStack.empty()) {
439f4a2713aSLionel Sambuc     Diag(DefaultLoc, diag::err_default_not_in_switch);
440*0a6a1f1dSLionel Sambuc     return SubStmt;
441f4a2713aSLionel Sambuc   }
442f4a2713aSLionel Sambuc 
443f4a2713aSLionel Sambuc   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
444f4a2713aSLionel Sambuc   getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
445*0a6a1f1dSLionel Sambuc   return DS;
446f4a2713aSLionel Sambuc }
447f4a2713aSLionel Sambuc 
448f4a2713aSLionel Sambuc StmtResult
ActOnLabelStmt(SourceLocation IdentLoc,LabelDecl * TheDecl,SourceLocation ColonLoc,Stmt * SubStmt)449f4a2713aSLionel Sambuc Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
450f4a2713aSLionel Sambuc                      SourceLocation ColonLoc, Stmt *SubStmt) {
451f4a2713aSLionel Sambuc   // If the label was multiply defined, reject it now.
452f4a2713aSLionel Sambuc   if (TheDecl->getStmt()) {
453f4a2713aSLionel Sambuc     Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();
454f4a2713aSLionel Sambuc     Diag(TheDecl->getLocation(), diag::note_previous_definition);
455*0a6a1f1dSLionel Sambuc     return SubStmt;
456f4a2713aSLionel Sambuc   }
457f4a2713aSLionel Sambuc 
458f4a2713aSLionel Sambuc   // Otherwise, things are good.  Fill in the declaration and return it.
459f4a2713aSLionel Sambuc   LabelStmt *LS = new (Context) LabelStmt(IdentLoc, TheDecl, SubStmt);
460f4a2713aSLionel Sambuc   TheDecl->setStmt(LS);
461f4a2713aSLionel Sambuc   if (!TheDecl->isGnuLocal()) {
462f4a2713aSLionel Sambuc     TheDecl->setLocStart(IdentLoc);
463*0a6a1f1dSLionel Sambuc     if (!TheDecl->isMSAsmLabel()) {
464*0a6a1f1dSLionel Sambuc       // Don't update the location of MS ASM labels.  These will result in
465*0a6a1f1dSLionel Sambuc       // a diagnostic, and changing the location here will mess that up.
466f4a2713aSLionel Sambuc       TheDecl->setLocation(IdentLoc);
467f4a2713aSLionel Sambuc     }
468*0a6a1f1dSLionel Sambuc   }
469*0a6a1f1dSLionel Sambuc   return LS;
470f4a2713aSLionel Sambuc }
471f4a2713aSLionel Sambuc 
ActOnAttributedStmt(SourceLocation AttrLoc,ArrayRef<const Attr * > Attrs,Stmt * SubStmt)472f4a2713aSLionel Sambuc StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc,
473f4a2713aSLionel Sambuc                                      ArrayRef<const Attr*> Attrs,
474f4a2713aSLionel Sambuc                                      Stmt *SubStmt) {
475f4a2713aSLionel Sambuc   // Fill in the declaration and return it.
476f4a2713aSLionel Sambuc   AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt);
477*0a6a1f1dSLionel Sambuc   return LS;
478f4a2713aSLionel Sambuc }
479f4a2713aSLionel Sambuc 
480f4a2713aSLionel Sambuc StmtResult
ActOnIfStmt(SourceLocation IfLoc,FullExprArg CondVal,Decl * CondVar,Stmt * thenStmt,SourceLocation ElseLoc,Stmt * elseStmt)481f4a2713aSLionel Sambuc Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
482f4a2713aSLionel Sambuc                   Stmt *thenStmt, SourceLocation ElseLoc,
483f4a2713aSLionel Sambuc                   Stmt *elseStmt) {
484f4a2713aSLionel Sambuc   // If the condition was invalid, discard the if statement.  We could recover
485f4a2713aSLionel Sambuc   // better by replacing it with a valid expr, but don't do that yet.
486f4a2713aSLionel Sambuc   if (!CondVal.get() && !CondVar) {
487f4a2713aSLionel Sambuc     getCurFunction()->setHasDroppedStmt();
488f4a2713aSLionel Sambuc     return StmtError();
489f4a2713aSLionel Sambuc   }
490f4a2713aSLionel Sambuc 
491f4a2713aSLionel Sambuc   ExprResult CondResult(CondVal.release());
492f4a2713aSLionel Sambuc 
493*0a6a1f1dSLionel Sambuc   VarDecl *ConditionVar = nullptr;
494f4a2713aSLionel Sambuc   if (CondVar) {
495f4a2713aSLionel Sambuc     ConditionVar = cast<VarDecl>(CondVar);
496f4a2713aSLionel Sambuc     CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
497f4a2713aSLionel Sambuc     if (CondResult.isInvalid())
498f4a2713aSLionel Sambuc       return StmtError();
499f4a2713aSLionel Sambuc   }
500*0a6a1f1dSLionel Sambuc   Expr *ConditionExpr = CondResult.getAs<Expr>();
501f4a2713aSLionel Sambuc   if (!ConditionExpr)
502f4a2713aSLionel Sambuc     return StmtError();
503f4a2713aSLionel Sambuc 
504f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(thenStmt);
505f4a2713aSLionel Sambuc 
506f4a2713aSLionel Sambuc   if (!elseStmt) {
507f4a2713aSLionel Sambuc     DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,
508f4a2713aSLionel Sambuc                           diag::warn_empty_if_body);
509f4a2713aSLionel Sambuc   }
510f4a2713aSLionel Sambuc 
511f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(elseStmt);
512f4a2713aSLionel Sambuc 
513*0a6a1f1dSLionel Sambuc   return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
514*0a6a1f1dSLionel Sambuc                               thenStmt, ElseLoc, elseStmt);
515f4a2713aSLionel Sambuc }
516f4a2713aSLionel Sambuc 
517f4a2713aSLionel Sambuc namespace {
518f4a2713aSLionel Sambuc   struct CaseCompareFunctor {
operator ()__anon7fb9f6900211::CaseCompareFunctor519f4a2713aSLionel Sambuc     bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
520f4a2713aSLionel Sambuc                     const llvm::APSInt &RHS) {
521f4a2713aSLionel Sambuc       return LHS.first < RHS;
522f4a2713aSLionel Sambuc     }
operator ()__anon7fb9f6900211::CaseCompareFunctor523f4a2713aSLionel Sambuc     bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
524f4a2713aSLionel Sambuc                     const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
525f4a2713aSLionel Sambuc       return LHS.first < RHS.first;
526f4a2713aSLionel Sambuc     }
operator ()__anon7fb9f6900211::CaseCompareFunctor527f4a2713aSLionel Sambuc     bool operator()(const llvm::APSInt &LHS,
528f4a2713aSLionel Sambuc                     const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
529f4a2713aSLionel Sambuc       return LHS < RHS.first;
530f4a2713aSLionel Sambuc     }
531f4a2713aSLionel Sambuc   };
532f4a2713aSLionel Sambuc }
533f4a2713aSLionel Sambuc 
534f4a2713aSLionel Sambuc /// CmpCaseVals - Comparison predicate for sorting case values.
535f4a2713aSLionel Sambuc ///
CmpCaseVals(const std::pair<llvm::APSInt,CaseStmt * > & lhs,const std::pair<llvm::APSInt,CaseStmt * > & rhs)536f4a2713aSLionel Sambuc static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,
537f4a2713aSLionel Sambuc                         const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
538f4a2713aSLionel Sambuc   if (lhs.first < rhs.first)
539f4a2713aSLionel Sambuc     return true;
540f4a2713aSLionel Sambuc 
541f4a2713aSLionel Sambuc   if (lhs.first == rhs.first &&
542f4a2713aSLionel Sambuc       lhs.second->getCaseLoc().getRawEncoding()
543f4a2713aSLionel Sambuc        < rhs.second->getCaseLoc().getRawEncoding())
544f4a2713aSLionel Sambuc     return true;
545f4a2713aSLionel Sambuc   return false;
546f4a2713aSLionel Sambuc }
547f4a2713aSLionel Sambuc 
548f4a2713aSLionel Sambuc /// CmpEnumVals - Comparison predicate for sorting enumeration values.
549f4a2713aSLionel Sambuc ///
CmpEnumVals(const std::pair<llvm::APSInt,EnumConstantDecl * > & lhs,const std::pair<llvm::APSInt,EnumConstantDecl * > & rhs)550f4a2713aSLionel Sambuc static bool CmpEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
551f4a2713aSLionel Sambuc                         const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
552f4a2713aSLionel Sambuc {
553f4a2713aSLionel Sambuc   return lhs.first < rhs.first;
554f4a2713aSLionel Sambuc }
555f4a2713aSLionel Sambuc 
556f4a2713aSLionel Sambuc /// EqEnumVals - Comparison preficate for uniqing enumeration values.
557f4a2713aSLionel Sambuc ///
EqEnumVals(const std::pair<llvm::APSInt,EnumConstantDecl * > & lhs,const std::pair<llvm::APSInt,EnumConstantDecl * > & rhs)558f4a2713aSLionel Sambuc static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
559f4a2713aSLionel Sambuc                        const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
560f4a2713aSLionel Sambuc {
561f4a2713aSLionel Sambuc   return lhs.first == rhs.first;
562f4a2713aSLionel Sambuc }
563f4a2713aSLionel Sambuc 
564f4a2713aSLionel Sambuc /// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of
565f4a2713aSLionel Sambuc /// potentially integral-promoted expression @p expr.
GetTypeBeforeIntegralPromotion(Expr * & expr)566f4a2713aSLionel Sambuc static QualType GetTypeBeforeIntegralPromotion(Expr *&expr) {
567f4a2713aSLionel Sambuc   if (ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(expr))
568f4a2713aSLionel Sambuc     expr = cleanups->getSubExpr();
569f4a2713aSLionel Sambuc   while (ImplicitCastExpr *impcast = dyn_cast<ImplicitCastExpr>(expr)) {
570f4a2713aSLionel Sambuc     if (impcast->getCastKind() != CK_IntegralCast) break;
571f4a2713aSLionel Sambuc     expr = impcast->getSubExpr();
572f4a2713aSLionel Sambuc   }
573f4a2713aSLionel Sambuc   return expr->getType();
574f4a2713aSLionel Sambuc }
575f4a2713aSLionel Sambuc 
576f4a2713aSLionel Sambuc StmtResult
ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,Expr * Cond,Decl * CondVar)577f4a2713aSLionel Sambuc Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
578f4a2713aSLionel Sambuc                              Decl *CondVar) {
579f4a2713aSLionel Sambuc   ExprResult CondResult;
580f4a2713aSLionel Sambuc 
581*0a6a1f1dSLionel Sambuc   VarDecl *ConditionVar = nullptr;
582f4a2713aSLionel Sambuc   if (CondVar) {
583f4a2713aSLionel Sambuc     ConditionVar = cast<VarDecl>(CondVar);
584f4a2713aSLionel Sambuc     CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
585f4a2713aSLionel Sambuc     if (CondResult.isInvalid())
586f4a2713aSLionel Sambuc       return StmtError();
587f4a2713aSLionel Sambuc 
588*0a6a1f1dSLionel Sambuc     Cond = CondResult.get();
589f4a2713aSLionel Sambuc   }
590f4a2713aSLionel Sambuc 
591f4a2713aSLionel Sambuc   if (!Cond)
592f4a2713aSLionel Sambuc     return StmtError();
593f4a2713aSLionel Sambuc 
594f4a2713aSLionel Sambuc   class SwitchConvertDiagnoser : public ICEConvertDiagnoser {
595f4a2713aSLionel Sambuc     Expr *Cond;
596f4a2713aSLionel Sambuc 
597f4a2713aSLionel Sambuc   public:
598f4a2713aSLionel Sambuc     SwitchConvertDiagnoser(Expr *Cond)
599f4a2713aSLionel Sambuc         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/true, false, true),
600f4a2713aSLionel Sambuc           Cond(Cond) {}
601f4a2713aSLionel Sambuc 
602*0a6a1f1dSLionel Sambuc     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
603*0a6a1f1dSLionel Sambuc                                          QualType T) override {
604f4a2713aSLionel Sambuc       return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T;
605f4a2713aSLionel Sambuc     }
606f4a2713aSLionel Sambuc 
607*0a6a1f1dSLionel Sambuc     SemaDiagnosticBuilder diagnoseIncomplete(
608*0a6a1f1dSLionel Sambuc         Sema &S, SourceLocation Loc, QualType T) override {
609f4a2713aSLionel Sambuc       return S.Diag(Loc, diag::err_switch_incomplete_class_type)
610f4a2713aSLionel Sambuc                << T << Cond->getSourceRange();
611f4a2713aSLionel Sambuc     }
612f4a2713aSLionel Sambuc 
613*0a6a1f1dSLionel Sambuc     SemaDiagnosticBuilder diagnoseExplicitConv(
614*0a6a1f1dSLionel Sambuc         Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
615f4a2713aSLionel Sambuc       return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy;
616f4a2713aSLionel Sambuc     }
617f4a2713aSLionel Sambuc 
618*0a6a1f1dSLionel Sambuc     SemaDiagnosticBuilder noteExplicitConv(
619*0a6a1f1dSLionel Sambuc         Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
620f4a2713aSLionel Sambuc       return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
621f4a2713aSLionel Sambuc         << ConvTy->isEnumeralType() << ConvTy;
622f4a2713aSLionel Sambuc     }
623f4a2713aSLionel Sambuc 
624*0a6a1f1dSLionel Sambuc     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
625*0a6a1f1dSLionel Sambuc                                             QualType T) override {
626f4a2713aSLionel Sambuc       return S.Diag(Loc, diag::err_switch_multiple_conversions) << T;
627f4a2713aSLionel Sambuc     }
628f4a2713aSLionel Sambuc 
629*0a6a1f1dSLionel Sambuc     SemaDiagnosticBuilder noteAmbiguous(
630*0a6a1f1dSLionel Sambuc         Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
631f4a2713aSLionel Sambuc       return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
632f4a2713aSLionel Sambuc       << ConvTy->isEnumeralType() << ConvTy;
633f4a2713aSLionel Sambuc     }
634f4a2713aSLionel Sambuc 
635*0a6a1f1dSLionel Sambuc     SemaDiagnosticBuilder diagnoseConversion(
636*0a6a1f1dSLionel Sambuc         Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
637f4a2713aSLionel Sambuc       llvm_unreachable("conversion functions are permitted");
638f4a2713aSLionel Sambuc     }
639f4a2713aSLionel Sambuc   } SwitchDiagnoser(Cond);
640f4a2713aSLionel Sambuc 
641f4a2713aSLionel Sambuc   CondResult =
642f4a2713aSLionel Sambuc       PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);
643f4a2713aSLionel Sambuc   if (CondResult.isInvalid()) return StmtError();
644*0a6a1f1dSLionel Sambuc   Cond = CondResult.get();
645f4a2713aSLionel Sambuc 
646f4a2713aSLionel Sambuc   // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
647f4a2713aSLionel Sambuc   CondResult = UsualUnaryConversions(Cond);
648f4a2713aSLionel Sambuc   if (CondResult.isInvalid()) return StmtError();
649*0a6a1f1dSLionel Sambuc   Cond = CondResult.get();
650f4a2713aSLionel Sambuc 
651f4a2713aSLionel Sambuc   if (!CondVar) {
652f4a2713aSLionel Sambuc     CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
653f4a2713aSLionel Sambuc     if (CondResult.isInvalid())
654f4a2713aSLionel Sambuc       return StmtError();
655*0a6a1f1dSLionel Sambuc     Cond = CondResult.get();
656f4a2713aSLionel Sambuc   }
657f4a2713aSLionel Sambuc 
658f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchIntoScope();
659f4a2713aSLionel Sambuc 
660f4a2713aSLionel Sambuc   SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
661f4a2713aSLionel Sambuc   getCurFunction()->SwitchStack.push_back(SS);
662*0a6a1f1dSLionel Sambuc   return SS;
663f4a2713aSLionel Sambuc }
664f4a2713aSLionel Sambuc 
AdjustAPSInt(llvm::APSInt & Val,unsigned BitWidth,bool IsSigned)665f4a2713aSLionel Sambuc static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
666*0a6a1f1dSLionel Sambuc   Val = Val.extOrTrunc(BitWidth);
667f4a2713aSLionel Sambuc   Val.setIsSigned(IsSigned);
668f4a2713aSLionel Sambuc }
669f4a2713aSLionel Sambuc 
670*0a6a1f1dSLionel Sambuc /// Check the specified case value is in range for the given unpromoted switch
671*0a6a1f1dSLionel Sambuc /// type.
checkCaseValue(Sema & S,SourceLocation Loc,const llvm::APSInt & Val,unsigned UnpromotedWidth,bool UnpromotedSign)672*0a6a1f1dSLionel Sambuc static void checkCaseValue(Sema &S, SourceLocation Loc, const llvm::APSInt &Val,
673*0a6a1f1dSLionel Sambuc                            unsigned UnpromotedWidth, bool UnpromotedSign) {
674*0a6a1f1dSLionel Sambuc   // If the case value was signed and negative and the switch expression is
675*0a6a1f1dSLionel Sambuc   // unsigned, don't bother to warn: this is implementation-defined behavior.
676*0a6a1f1dSLionel Sambuc   // FIXME: Introduce a second, default-ignored warning for this case?
677*0a6a1f1dSLionel Sambuc   if (UnpromotedWidth < Val.getBitWidth()) {
678*0a6a1f1dSLionel Sambuc     llvm::APSInt ConvVal(Val);
679*0a6a1f1dSLionel Sambuc     AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign);
680*0a6a1f1dSLionel Sambuc     AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned());
681*0a6a1f1dSLionel Sambuc     // FIXME: Use different diagnostics for overflow  in conversion to promoted
682*0a6a1f1dSLionel Sambuc     // type versus "switch expression cannot have this value". Use proper
683*0a6a1f1dSLionel Sambuc     // IntRange checking rather than just looking at the unpromoted type here.
684*0a6a1f1dSLionel Sambuc     if (ConvVal != Val)
685*0a6a1f1dSLionel Sambuc       S.Diag(Loc, diag::warn_case_value_overflow) << Val.toString(10)
686*0a6a1f1dSLionel Sambuc                                                   << ConvVal.toString(10);
687*0a6a1f1dSLionel Sambuc   }
688*0a6a1f1dSLionel Sambuc }
689*0a6a1f1dSLionel Sambuc 
690*0a6a1f1dSLionel Sambuc /// Returns true if we should emit a diagnostic about this case expression not
691*0a6a1f1dSLionel Sambuc /// being a part of the enum used in the switch controlling expression.
ShouldDiagnoseSwitchCaseNotInEnum(const ASTContext & Ctx,const EnumDecl * ED,const Expr * CaseExpr)692*0a6a1f1dSLionel Sambuc static bool ShouldDiagnoseSwitchCaseNotInEnum(const ASTContext &Ctx,
693*0a6a1f1dSLionel Sambuc                                               const EnumDecl *ED,
694*0a6a1f1dSLionel Sambuc                                               const Expr *CaseExpr) {
695*0a6a1f1dSLionel Sambuc   // Don't warn if the 'case' expression refers to a static const variable of
696*0a6a1f1dSLionel Sambuc   // the enum type.
697*0a6a1f1dSLionel Sambuc   CaseExpr = CaseExpr->IgnoreParenImpCasts();
698*0a6a1f1dSLionel Sambuc   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseExpr)) {
699*0a6a1f1dSLionel Sambuc     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
700*0a6a1f1dSLionel Sambuc       if (!VD->hasGlobalStorage())
701*0a6a1f1dSLionel Sambuc         return true;
702*0a6a1f1dSLionel Sambuc       QualType VarType = VD->getType();
703*0a6a1f1dSLionel Sambuc       if (!VarType.isConstQualified())
704*0a6a1f1dSLionel Sambuc         return true;
705*0a6a1f1dSLionel Sambuc       QualType EnumType = Ctx.getTypeDeclType(ED);
706*0a6a1f1dSLionel Sambuc       if (Ctx.hasSameUnqualifiedType(EnumType, VarType))
707*0a6a1f1dSLionel Sambuc         return false;
708*0a6a1f1dSLionel Sambuc     }
709*0a6a1f1dSLionel Sambuc   }
710*0a6a1f1dSLionel Sambuc   return true;
711*0a6a1f1dSLionel Sambuc }
712*0a6a1f1dSLionel Sambuc 
713f4a2713aSLionel Sambuc StmtResult
ActOnFinishSwitchStmt(SourceLocation SwitchLoc,Stmt * Switch,Stmt * BodyStmt)714f4a2713aSLionel Sambuc Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
715f4a2713aSLionel Sambuc                             Stmt *BodyStmt) {
716f4a2713aSLionel Sambuc   SwitchStmt *SS = cast<SwitchStmt>(Switch);
717f4a2713aSLionel Sambuc   assert(SS == getCurFunction()->SwitchStack.back() &&
718f4a2713aSLionel Sambuc          "switch stack missing push/pop!");
719f4a2713aSLionel Sambuc 
720f4a2713aSLionel Sambuc   getCurFunction()->SwitchStack.pop_back();
721f4a2713aSLionel Sambuc 
722*0a6a1f1dSLionel Sambuc   if (!BodyStmt) return StmtError();
723*0a6a1f1dSLionel Sambuc   SS->setBody(BodyStmt, SwitchLoc);
724*0a6a1f1dSLionel Sambuc 
725f4a2713aSLionel Sambuc   Expr *CondExpr = SS->getCond();
726f4a2713aSLionel Sambuc   if (!CondExpr) return StmtError();
727f4a2713aSLionel Sambuc 
728f4a2713aSLionel Sambuc   QualType CondType = CondExpr->getType();
729f4a2713aSLionel Sambuc 
730f4a2713aSLionel Sambuc   Expr *CondExprBeforePromotion = CondExpr;
731f4a2713aSLionel Sambuc   QualType CondTypeBeforePromotion =
732f4a2713aSLionel Sambuc       GetTypeBeforeIntegralPromotion(CondExprBeforePromotion);
733f4a2713aSLionel Sambuc 
734f4a2713aSLionel Sambuc   // C++ 6.4.2.p2:
735f4a2713aSLionel Sambuc   // Integral promotions are performed (on the switch condition).
736f4a2713aSLionel Sambuc   //
737f4a2713aSLionel Sambuc   // A case value unrepresentable by the original switch condition
738f4a2713aSLionel Sambuc   // type (before the promotion) doesn't make sense, even when it can
739f4a2713aSLionel Sambuc   // be represented by the promoted type.  Therefore we need to find
740f4a2713aSLionel Sambuc   // the pre-promotion type of the switch condition.
741f4a2713aSLionel Sambuc   if (!CondExpr->isTypeDependent()) {
742f4a2713aSLionel Sambuc     // We have already converted the expression to an integral or enumeration
743f4a2713aSLionel Sambuc     // type, when we started the switch statement. If we don't have an
744f4a2713aSLionel Sambuc     // appropriate type now, just return an error.
745f4a2713aSLionel Sambuc     if (!CondType->isIntegralOrEnumerationType())
746f4a2713aSLionel Sambuc       return StmtError();
747f4a2713aSLionel Sambuc 
748f4a2713aSLionel Sambuc     if (CondExpr->isKnownToHaveBooleanValue()) {
749f4a2713aSLionel Sambuc       // switch(bool_expr) {...} is often a programmer error, e.g.
750f4a2713aSLionel Sambuc       //   switch(n && mask) { ... }  // Doh - should be "n & mask".
751f4a2713aSLionel Sambuc       // One can always use an if statement instead of switch(bool_expr).
752f4a2713aSLionel Sambuc       Diag(SwitchLoc, diag::warn_bool_switch_condition)
753f4a2713aSLionel Sambuc           << CondExpr->getSourceRange();
754f4a2713aSLionel Sambuc     }
755f4a2713aSLionel Sambuc   }
756f4a2713aSLionel Sambuc 
757*0a6a1f1dSLionel Sambuc   // Get the bitwidth of the switched-on value after promotions. We must
758f4a2713aSLionel Sambuc   // convert the integer case values to this width before comparison.
759f4a2713aSLionel Sambuc   bool HasDependentValue
760f4a2713aSLionel Sambuc     = CondExpr->isTypeDependent() || CondExpr->isValueDependent();
761*0a6a1f1dSLionel Sambuc   unsigned CondWidth = HasDependentValue ? 0 : Context.getIntWidth(CondType);
762*0a6a1f1dSLionel Sambuc   bool CondIsSigned = CondType->isSignedIntegerOrEnumerationType();
763*0a6a1f1dSLionel Sambuc 
764*0a6a1f1dSLionel Sambuc   // Get the width and signedness that the condition might actually have, for
765*0a6a1f1dSLionel Sambuc   // warning purposes.
766*0a6a1f1dSLionel Sambuc   // FIXME: Grab an IntRange for the condition rather than using the unpromoted
767*0a6a1f1dSLionel Sambuc   // type.
768*0a6a1f1dSLionel Sambuc   unsigned CondWidthBeforePromotion
769f4a2713aSLionel Sambuc     = HasDependentValue ? 0 : Context.getIntWidth(CondTypeBeforePromotion);
770*0a6a1f1dSLionel Sambuc   bool CondIsSignedBeforePromotion
771f4a2713aSLionel Sambuc     = CondTypeBeforePromotion->isSignedIntegerOrEnumerationType();
772f4a2713aSLionel Sambuc 
773f4a2713aSLionel Sambuc   // Accumulate all of the case values in a vector so that we can sort them
774f4a2713aSLionel Sambuc   // and detect duplicates.  This vector contains the APInt for the case after
775f4a2713aSLionel Sambuc   // it has been converted to the condition type.
776f4a2713aSLionel Sambuc   typedef SmallVector<std::pair<llvm::APSInt, CaseStmt*>, 64> CaseValsTy;
777f4a2713aSLionel Sambuc   CaseValsTy CaseVals;
778f4a2713aSLionel Sambuc 
779f4a2713aSLionel Sambuc   // Keep track of any GNU case ranges we see.  The APSInt is the low value.
780f4a2713aSLionel Sambuc   typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
781f4a2713aSLionel Sambuc   CaseRangesTy CaseRanges;
782f4a2713aSLionel Sambuc 
783*0a6a1f1dSLionel Sambuc   DefaultStmt *TheDefaultStmt = nullptr;
784f4a2713aSLionel Sambuc 
785f4a2713aSLionel Sambuc   bool CaseListIsErroneous = false;
786f4a2713aSLionel Sambuc 
787f4a2713aSLionel Sambuc   for (SwitchCase *SC = SS->getSwitchCaseList(); SC && !HasDependentValue;
788f4a2713aSLionel Sambuc        SC = SC->getNextSwitchCase()) {
789f4a2713aSLionel Sambuc 
790f4a2713aSLionel Sambuc     if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
791f4a2713aSLionel Sambuc       if (TheDefaultStmt) {
792f4a2713aSLionel Sambuc         Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
793f4a2713aSLionel Sambuc         Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);
794f4a2713aSLionel Sambuc 
795f4a2713aSLionel Sambuc         // FIXME: Remove the default statement from the switch block so that
796f4a2713aSLionel Sambuc         // we'll return a valid AST.  This requires recursing down the AST and
797f4a2713aSLionel Sambuc         // finding it, not something we are set up to do right now.  For now,
798f4a2713aSLionel Sambuc         // just lop the entire switch stmt out of the AST.
799f4a2713aSLionel Sambuc         CaseListIsErroneous = true;
800f4a2713aSLionel Sambuc       }
801f4a2713aSLionel Sambuc       TheDefaultStmt = DS;
802f4a2713aSLionel Sambuc 
803f4a2713aSLionel Sambuc     } else {
804f4a2713aSLionel Sambuc       CaseStmt *CS = cast<CaseStmt>(SC);
805f4a2713aSLionel Sambuc 
806f4a2713aSLionel Sambuc       Expr *Lo = CS->getLHS();
807f4a2713aSLionel Sambuc 
808f4a2713aSLionel Sambuc       if (Lo->isTypeDependent() || Lo->isValueDependent()) {
809f4a2713aSLionel Sambuc         HasDependentValue = true;
810f4a2713aSLionel Sambuc         break;
811f4a2713aSLionel Sambuc       }
812f4a2713aSLionel Sambuc 
813f4a2713aSLionel Sambuc       llvm::APSInt LoVal;
814f4a2713aSLionel Sambuc 
815f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus11) {
816f4a2713aSLionel Sambuc         // C++11 [stmt.switch]p2: the constant-expression shall be a converted
817f4a2713aSLionel Sambuc         // constant expression of the promoted type of the switch condition.
818f4a2713aSLionel Sambuc         ExprResult ConvLo =
819f4a2713aSLionel Sambuc           CheckConvertedConstantExpression(Lo, CondType, LoVal, CCEK_CaseValue);
820f4a2713aSLionel Sambuc         if (ConvLo.isInvalid()) {
821f4a2713aSLionel Sambuc           CaseListIsErroneous = true;
822f4a2713aSLionel Sambuc           continue;
823f4a2713aSLionel Sambuc         }
824*0a6a1f1dSLionel Sambuc         Lo = ConvLo.get();
825f4a2713aSLionel Sambuc       } else {
826f4a2713aSLionel Sambuc         // We already verified that the expression has a i-c-e value (C99
827f4a2713aSLionel Sambuc         // 6.8.4.2p3) - get that value now.
828f4a2713aSLionel Sambuc         LoVal = Lo->EvaluateKnownConstInt(Context);
829f4a2713aSLionel Sambuc 
830f4a2713aSLionel Sambuc         // If the LHS is not the same type as the condition, insert an implicit
831f4a2713aSLionel Sambuc         // cast.
832*0a6a1f1dSLionel Sambuc         Lo = DefaultLvalueConversion(Lo).get();
833*0a6a1f1dSLionel Sambuc         Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).get();
834f4a2713aSLionel Sambuc       }
835f4a2713aSLionel Sambuc 
836*0a6a1f1dSLionel Sambuc       // Check the unconverted value is within the range of possible values of
837*0a6a1f1dSLionel Sambuc       // the switch expression.
838*0a6a1f1dSLionel Sambuc       checkCaseValue(*this, Lo->getLocStart(), LoVal,
839*0a6a1f1dSLionel Sambuc                      CondWidthBeforePromotion, CondIsSignedBeforePromotion);
840*0a6a1f1dSLionel Sambuc 
841*0a6a1f1dSLionel Sambuc       // Convert the value to the same width/sign as the condition.
842*0a6a1f1dSLionel Sambuc       AdjustAPSInt(LoVal, CondWidth, CondIsSigned);
843f4a2713aSLionel Sambuc 
844f4a2713aSLionel Sambuc       CS->setLHS(Lo);
845f4a2713aSLionel Sambuc 
846f4a2713aSLionel Sambuc       // If this is a case range, remember it in CaseRanges, otherwise CaseVals.
847f4a2713aSLionel Sambuc       if (CS->getRHS()) {
848f4a2713aSLionel Sambuc         if (CS->getRHS()->isTypeDependent() ||
849f4a2713aSLionel Sambuc             CS->getRHS()->isValueDependent()) {
850f4a2713aSLionel Sambuc           HasDependentValue = true;
851f4a2713aSLionel Sambuc           break;
852f4a2713aSLionel Sambuc         }
853f4a2713aSLionel Sambuc         CaseRanges.push_back(std::make_pair(LoVal, CS));
854f4a2713aSLionel Sambuc       } else
855f4a2713aSLionel Sambuc         CaseVals.push_back(std::make_pair(LoVal, CS));
856f4a2713aSLionel Sambuc     }
857f4a2713aSLionel Sambuc   }
858f4a2713aSLionel Sambuc 
859f4a2713aSLionel Sambuc   if (!HasDependentValue) {
860f4a2713aSLionel Sambuc     // If we don't have a default statement, check whether the
861f4a2713aSLionel Sambuc     // condition is constant.
862f4a2713aSLionel Sambuc     llvm::APSInt ConstantCondValue;
863f4a2713aSLionel Sambuc     bool HasConstantCond = false;
864f4a2713aSLionel Sambuc     if (!HasDependentValue && !TheDefaultStmt) {
865*0a6a1f1dSLionel Sambuc       HasConstantCond = CondExpr->EvaluateAsInt(ConstantCondValue, Context,
866f4a2713aSLionel Sambuc                                                 Expr::SE_AllowSideEffects);
867f4a2713aSLionel Sambuc       assert(!HasConstantCond ||
868f4a2713aSLionel Sambuc              (ConstantCondValue.getBitWidth() == CondWidth &&
869f4a2713aSLionel Sambuc               ConstantCondValue.isSigned() == CondIsSigned));
870f4a2713aSLionel Sambuc     }
871f4a2713aSLionel Sambuc     bool ShouldCheckConstantCond = HasConstantCond;
872f4a2713aSLionel Sambuc 
873f4a2713aSLionel Sambuc     // Sort all the scalar case values so we can easily detect duplicates.
874f4a2713aSLionel Sambuc     std::stable_sort(CaseVals.begin(), CaseVals.end(), CmpCaseVals);
875f4a2713aSLionel Sambuc 
876f4a2713aSLionel Sambuc     if (!CaseVals.empty()) {
877f4a2713aSLionel Sambuc       for (unsigned i = 0, e = CaseVals.size(); i != e; ++i) {
878f4a2713aSLionel Sambuc         if (ShouldCheckConstantCond &&
879f4a2713aSLionel Sambuc             CaseVals[i].first == ConstantCondValue)
880f4a2713aSLionel Sambuc           ShouldCheckConstantCond = false;
881f4a2713aSLionel Sambuc 
882f4a2713aSLionel Sambuc         if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {
883f4a2713aSLionel Sambuc           // If we have a duplicate, report it.
884f4a2713aSLionel Sambuc           // First, determine if either case value has a name
885f4a2713aSLionel Sambuc           StringRef PrevString, CurrString;
886f4a2713aSLionel Sambuc           Expr *PrevCase = CaseVals[i-1].second->getLHS()->IgnoreParenCasts();
887f4a2713aSLionel Sambuc           Expr *CurrCase = CaseVals[i].second->getLHS()->IgnoreParenCasts();
888f4a2713aSLionel Sambuc           if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(PrevCase)) {
889f4a2713aSLionel Sambuc             PrevString = DeclRef->getDecl()->getName();
890f4a2713aSLionel Sambuc           }
891f4a2713aSLionel Sambuc           if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(CurrCase)) {
892f4a2713aSLionel Sambuc             CurrString = DeclRef->getDecl()->getName();
893f4a2713aSLionel Sambuc           }
894f4a2713aSLionel Sambuc           SmallString<16> CaseValStr;
895f4a2713aSLionel Sambuc           CaseVals[i-1].first.toString(CaseValStr);
896f4a2713aSLionel Sambuc 
897f4a2713aSLionel Sambuc           if (PrevString == CurrString)
898f4a2713aSLionel Sambuc             Diag(CaseVals[i].second->getLHS()->getLocStart(),
899f4a2713aSLionel Sambuc                  diag::err_duplicate_case) <<
900f4a2713aSLionel Sambuc                  (PrevString.empty() ? CaseValStr.str() : PrevString);
901f4a2713aSLionel Sambuc           else
902f4a2713aSLionel Sambuc             Diag(CaseVals[i].second->getLHS()->getLocStart(),
903f4a2713aSLionel Sambuc                  diag::err_duplicate_case_differing_expr) <<
904f4a2713aSLionel Sambuc                  (PrevString.empty() ? CaseValStr.str() : PrevString) <<
905f4a2713aSLionel Sambuc                  (CurrString.empty() ? CaseValStr.str() : CurrString) <<
906f4a2713aSLionel Sambuc                  CaseValStr;
907f4a2713aSLionel Sambuc 
908f4a2713aSLionel Sambuc           Diag(CaseVals[i-1].second->getLHS()->getLocStart(),
909f4a2713aSLionel Sambuc                diag::note_duplicate_case_prev);
910f4a2713aSLionel Sambuc           // FIXME: We really want to remove the bogus case stmt from the
911f4a2713aSLionel Sambuc           // substmt, but we have no way to do this right now.
912f4a2713aSLionel Sambuc           CaseListIsErroneous = true;
913f4a2713aSLionel Sambuc         }
914f4a2713aSLionel Sambuc       }
915f4a2713aSLionel Sambuc     }
916f4a2713aSLionel Sambuc 
917f4a2713aSLionel Sambuc     // Detect duplicate case ranges, which usually don't exist at all in
918f4a2713aSLionel Sambuc     // the first place.
919f4a2713aSLionel Sambuc     if (!CaseRanges.empty()) {
920f4a2713aSLionel Sambuc       // Sort all the case ranges by their low value so we can easily detect
921f4a2713aSLionel Sambuc       // overlaps between ranges.
922f4a2713aSLionel Sambuc       std::stable_sort(CaseRanges.begin(), CaseRanges.end());
923f4a2713aSLionel Sambuc 
924f4a2713aSLionel Sambuc       // Scan the ranges, computing the high values and removing empty ranges.
925f4a2713aSLionel Sambuc       std::vector<llvm::APSInt> HiVals;
926f4a2713aSLionel Sambuc       for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
927f4a2713aSLionel Sambuc         llvm::APSInt &LoVal = CaseRanges[i].first;
928f4a2713aSLionel Sambuc         CaseStmt *CR = CaseRanges[i].second;
929f4a2713aSLionel Sambuc         Expr *Hi = CR->getRHS();
930f4a2713aSLionel Sambuc         llvm::APSInt HiVal;
931f4a2713aSLionel Sambuc 
932f4a2713aSLionel Sambuc         if (getLangOpts().CPlusPlus11) {
933f4a2713aSLionel Sambuc           // C++11 [stmt.switch]p2: the constant-expression shall be a converted
934f4a2713aSLionel Sambuc           // constant expression of the promoted type of the switch condition.
935f4a2713aSLionel Sambuc           ExprResult ConvHi =
936f4a2713aSLionel Sambuc             CheckConvertedConstantExpression(Hi, CondType, HiVal,
937f4a2713aSLionel Sambuc                                              CCEK_CaseValue);
938f4a2713aSLionel Sambuc           if (ConvHi.isInvalid()) {
939f4a2713aSLionel Sambuc             CaseListIsErroneous = true;
940f4a2713aSLionel Sambuc             continue;
941f4a2713aSLionel Sambuc           }
942*0a6a1f1dSLionel Sambuc           Hi = ConvHi.get();
943f4a2713aSLionel Sambuc         } else {
944f4a2713aSLionel Sambuc           HiVal = Hi->EvaluateKnownConstInt(Context);
945f4a2713aSLionel Sambuc 
946f4a2713aSLionel Sambuc           // If the RHS is not the same type as the condition, insert an
947f4a2713aSLionel Sambuc           // implicit cast.
948*0a6a1f1dSLionel Sambuc           Hi = DefaultLvalueConversion(Hi).get();
949*0a6a1f1dSLionel Sambuc           Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).get();
950f4a2713aSLionel Sambuc         }
951f4a2713aSLionel Sambuc 
952*0a6a1f1dSLionel Sambuc         // Check the unconverted value is within the range of possible values of
953*0a6a1f1dSLionel Sambuc         // the switch expression.
954*0a6a1f1dSLionel Sambuc         checkCaseValue(*this, Hi->getLocStart(), HiVal,
955*0a6a1f1dSLionel Sambuc                        CondWidthBeforePromotion, CondIsSignedBeforePromotion);
956*0a6a1f1dSLionel Sambuc 
957f4a2713aSLionel Sambuc         // Convert the value to the same width/sign as the condition.
958*0a6a1f1dSLionel Sambuc         AdjustAPSInt(HiVal, CondWidth, CondIsSigned);
959f4a2713aSLionel Sambuc 
960f4a2713aSLionel Sambuc         CR->setRHS(Hi);
961f4a2713aSLionel Sambuc 
962f4a2713aSLionel Sambuc         // If the low value is bigger than the high value, the case is empty.
963f4a2713aSLionel Sambuc         if (LoVal > HiVal) {
964f4a2713aSLionel Sambuc           Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range)
965f4a2713aSLionel Sambuc             << SourceRange(CR->getLHS()->getLocStart(),
966f4a2713aSLionel Sambuc                            Hi->getLocEnd());
967f4a2713aSLionel Sambuc           CaseRanges.erase(CaseRanges.begin()+i);
968f4a2713aSLionel Sambuc           --i, --e;
969f4a2713aSLionel Sambuc           continue;
970f4a2713aSLionel Sambuc         }
971f4a2713aSLionel Sambuc 
972f4a2713aSLionel Sambuc         if (ShouldCheckConstantCond &&
973f4a2713aSLionel Sambuc             LoVal <= ConstantCondValue &&
974f4a2713aSLionel Sambuc             ConstantCondValue <= HiVal)
975f4a2713aSLionel Sambuc           ShouldCheckConstantCond = false;
976f4a2713aSLionel Sambuc 
977f4a2713aSLionel Sambuc         HiVals.push_back(HiVal);
978f4a2713aSLionel Sambuc       }
979f4a2713aSLionel Sambuc 
980f4a2713aSLionel Sambuc       // Rescan the ranges, looking for overlap with singleton values and other
981f4a2713aSLionel Sambuc       // ranges.  Since the range list is sorted, we only need to compare case
982f4a2713aSLionel Sambuc       // ranges with their neighbors.
983f4a2713aSLionel Sambuc       for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
984f4a2713aSLionel Sambuc         llvm::APSInt &CRLo = CaseRanges[i].first;
985f4a2713aSLionel Sambuc         llvm::APSInt &CRHi = HiVals[i];
986f4a2713aSLionel Sambuc         CaseStmt *CR = CaseRanges[i].second;
987f4a2713aSLionel Sambuc 
988f4a2713aSLionel Sambuc         // Check to see whether the case range overlaps with any
989f4a2713aSLionel Sambuc         // singleton cases.
990*0a6a1f1dSLionel Sambuc         CaseStmt *OverlapStmt = nullptr;
991f4a2713aSLionel Sambuc         llvm::APSInt OverlapVal(32);
992f4a2713aSLionel Sambuc 
993f4a2713aSLionel Sambuc         // Find the smallest value >= the lower bound.  If I is in the
994f4a2713aSLionel Sambuc         // case range, then we have overlap.
995f4a2713aSLionel Sambuc         CaseValsTy::iterator I = std::lower_bound(CaseVals.begin(),
996f4a2713aSLionel Sambuc                                                   CaseVals.end(), CRLo,
997f4a2713aSLionel Sambuc                                                   CaseCompareFunctor());
998f4a2713aSLionel Sambuc         if (I != CaseVals.end() && I->first < CRHi) {
999f4a2713aSLionel Sambuc           OverlapVal  = I->first;   // Found overlap with scalar.
1000f4a2713aSLionel Sambuc           OverlapStmt = I->second;
1001f4a2713aSLionel Sambuc         }
1002f4a2713aSLionel Sambuc 
1003f4a2713aSLionel Sambuc         // Find the smallest value bigger than the upper bound.
1004f4a2713aSLionel Sambuc         I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
1005f4a2713aSLionel Sambuc         if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
1006f4a2713aSLionel Sambuc           OverlapVal  = (I-1)->first;      // Found overlap with scalar.
1007f4a2713aSLionel Sambuc           OverlapStmt = (I-1)->second;
1008f4a2713aSLionel Sambuc         }
1009f4a2713aSLionel Sambuc 
1010f4a2713aSLionel Sambuc         // Check to see if this case stmt overlaps with the subsequent
1011f4a2713aSLionel Sambuc         // case range.
1012f4a2713aSLionel Sambuc         if (i && CRLo <= HiVals[i-1]) {
1013f4a2713aSLionel Sambuc           OverlapVal  = HiVals[i-1];       // Found overlap with range.
1014f4a2713aSLionel Sambuc           OverlapStmt = CaseRanges[i-1].second;
1015f4a2713aSLionel Sambuc         }
1016f4a2713aSLionel Sambuc 
1017f4a2713aSLionel Sambuc         if (OverlapStmt) {
1018f4a2713aSLionel Sambuc           // If we have a duplicate, report it.
1019f4a2713aSLionel Sambuc           Diag(CR->getLHS()->getLocStart(), diag::err_duplicate_case)
1020f4a2713aSLionel Sambuc             << OverlapVal.toString(10);
1021f4a2713aSLionel Sambuc           Diag(OverlapStmt->getLHS()->getLocStart(),
1022f4a2713aSLionel Sambuc                diag::note_duplicate_case_prev);
1023f4a2713aSLionel Sambuc           // FIXME: We really want to remove the bogus case stmt from the
1024f4a2713aSLionel Sambuc           // substmt, but we have no way to do this right now.
1025f4a2713aSLionel Sambuc           CaseListIsErroneous = true;
1026f4a2713aSLionel Sambuc         }
1027f4a2713aSLionel Sambuc       }
1028f4a2713aSLionel Sambuc     }
1029f4a2713aSLionel Sambuc 
1030f4a2713aSLionel Sambuc     // Complain if we have a constant condition and we didn't find a match.
1031f4a2713aSLionel Sambuc     if (!CaseListIsErroneous && ShouldCheckConstantCond) {
1032f4a2713aSLionel Sambuc       // TODO: it would be nice if we printed enums as enums, chars as
1033f4a2713aSLionel Sambuc       // chars, etc.
1034f4a2713aSLionel Sambuc       Diag(CondExpr->getExprLoc(), diag::warn_missing_case_for_condition)
1035f4a2713aSLionel Sambuc         << ConstantCondValue.toString(10)
1036f4a2713aSLionel Sambuc         << CondExpr->getSourceRange();
1037f4a2713aSLionel Sambuc     }
1038f4a2713aSLionel Sambuc 
1039f4a2713aSLionel Sambuc     // Check to see if switch is over an Enum and handles all of its
1040f4a2713aSLionel Sambuc     // values.  We only issue a warning if there is not 'default:', but
1041f4a2713aSLionel Sambuc     // we still do the analysis to preserve this information in the AST
1042f4a2713aSLionel Sambuc     // (which can be used by flow-based analyes).
1043f4a2713aSLionel Sambuc     //
1044f4a2713aSLionel Sambuc     const EnumType *ET = CondTypeBeforePromotion->getAs<EnumType>();
1045f4a2713aSLionel Sambuc 
1046f4a2713aSLionel Sambuc     // If switch has default case, then ignore it.
1047f4a2713aSLionel Sambuc     if (!CaseListIsErroneous  && !HasConstantCond && ET) {
1048f4a2713aSLionel Sambuc       const EnumDecl *ED = ET->getDecl();
1049f4a2713aSLionel Sambuc       typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64>
1050f4a2713aSLionel Sambuc         EnumValsTy;
1051f4a2713aSLionel Sambuc       EnumValsTy EnumVals;
1052f4a2713aSLionel Sambuc 
1053f4a2713aSLionel Sambuc       // Gather all enum values, set their type and sort them,
1054f4a2713aSLionel Sambuc       // allowing easier comparison with CaseVals.
1055*0a6a1f1dSLionel Sambuc       for (auto *EDI : ED->enumerators()) {
1056f4a2713aSLionel Sambuc         llvm::APSInt Val = EDI->getInitVal();
1057f4a2713aSLionel Sambuc         AdjustAPSInt(Val, CondWidth, CondIsSigned);
1058*0a6a1f1dSLionel Sambuc         EnumVals.push_back(std::make_pair(Val, EDI));
1059f4a2713aSLionel Sambuc       }
1060f4a2713aSLionel Sambuc       std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
1061f4a2713aSLionel Sambuc       EnumValsTy::iterator EIend =
1062f4a2713aSLionel Sambuc         std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
1063f4a2713aSLionel Sambuc 
1064f4a2713aSLionel Sambuc       // See which case values aren't in enum.
1065f4a2713aSLionel Sambuc       EnumValsTy::const_iterator EI = EnumVals.begin();
1066f4a2713aSLionel Sambuc       for (CaseValsTy::const_iterator CI = CaseVals.begin();
1067f4a2713aSLionel Sambuc            CI != CaseVals.end(); CI++) {
1068f4a2713aSLionel Sambuc         while (EI != EIend && EI->first < CI->first)
1069f4a2713aSLionel Sambuc           EI++;
1070*0a6a1f1dSLionel Sambuc         if (EI == EIend || EI->first > CI->first) {
1071*0a6a1f1dSLionel Sambuc           Expr *CaseExpr = CI->second->getLHS();
1072*0a6a1f1dSLionel Sambuc           if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
1073*0a6a1f1dSLionel Sambuc             Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
1074f4a2713aSLionel Sambuc               << CondTypeBeforePromotion;
1075f4a2713aSLionel Sambuc         }
1076*0a6a1f1dSLionel Sambuc       }
1077f4a2713aSLionel Sambuc       // See which of case ranges aren't in enum
1078f4a2713aSLionel Sambuc       EI = EnumVals.begin();
1079f4a2713aSLionel Sambuc       for (CaseRangesTy::const_iterator RI = CaseRanges.begin();
1080f4a2713aSLionel Sambuc            RI != CaseRanges.end() && EI != EIend; RI++) {
1081f4a2713aSLionel Sambuc         while (EI != EIend && EI->first < RI->first)
1082f4a2713aSLionel Sambuc           EI++;
1083f4a2713aSLionel Sambuc 
1084f4a2713aSLionel Sambuc         if (EI == EIend || EI->first != RI->first) {
1085*0a6a1f1dSLionel Sambuc           Expr *CaseExpr = RI->second->getLHS();
1086*0a6a1f1dSLionel Sambuc           if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
1087*0a6a1f1dSLionel Sambuc             Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
1088f4a2713aSLionel Sambuc               << CondTypeBeforePromotion;
1089f4a2713aSLionel Sambuc         }
1090f4a2713aSLionel Sambuc 
1091f4a2713aSLionel Sambuc         llvm::APSInt Hi =
1092f4a2713aSLionel Sambuc           RI->second->getRHS()->EvaluateKnownConstInt(Context);
1093f4a2713aSLionel Sambuc         AdjustAPSInt(Hi, CondWidth, CondIsSigned);
1094f4a2713aSLionel Sambuc         while (EI != EIend && EI->first < Hi)
1095f4a2713aSLionel Sambuc           EI++;
1096*0a6a1f1dSLionel Sambuc         if (EI == EIend || EI->first != Hi) {
1097*0a6a1f1dSLionel Sambuc           Expr *CaseExpr = RI->second->getRHS();
1098*0a6a1f1dSLionel Sambuc           if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
1099*0a6a1f1dSLionel Sambuc             Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
1100f4a2713aSLionel Sambuc               << CondTypeBeforePromotion;
1101f4a2713aSLionel Sambuc         }
1102*0a6a1f1dSLionel Sambuc       }
1103f4a2713aSLionel Sambuc 
1104f4a2713aSLionel Sambuc       // Check which enum vals aren't in switch
1105f4a2713aSLionel Sambuc       CaseValsTy::const_iterator CI = CaseVals.begin();
1106f4a2713aSLionel Sambuc       CaseRangesTy::const_iterator RI = CaseRanges.begin();
1107f4a2713aSLionel Sambuc       bool hasCasesNotInSwitch = false;
1108f4a2713aSLionel Sambuc 
1109f4a2713aSLionel Sambuc       SmallVector<DeclarationName,8> UnhandledNames;
1110f4a2713aSLionel Sambuc 
1111f4a2713aSLionel Sambuc       for (EI = EnumVals.begin(); EI != EIend; EI++){
1112f4a2713aSLionel Sambuc         // Drop unneeded case values
1113f4a2713aSLionel Sambuc         while (CI != CaseVals.end() && CI->first < EI->first)
1114f4a2713aSLionel Sambuc           CI++;
1115f4a2713aSLionel Sambuc 
1116f4a2713aSLionel Sambuc         if (CI != CaseVals.end() && CI->first == EI->first)
1117f4a2713aSLionel Sambuc           continue;
1118f4a2713aSLionel Sambuc 
1119f4a2713aSLionel Sambuc         // Drop unneeded case ranges
1120f4a2713aSLionel Sambuc         for (; RI != CaseRanges.end(); RI++) {
1121f4a2713aSLionel Sambuc           llvm::APSInt Hi =
1122f4a2713aSLionel Sambuc             RI->second->getRHS()->EvaluateKnownConstInt(Context);
1123f4a2713aSLionel Sambuc           AdjustAPSInt(Hi, CondWidth, CondIsSigned);
1124f4a2713aSLionel Sambuc           if (EI->first <= Hi)
1125f4a2713aSLionel Sambuc             break;
1126f4a2713aSLionel Sambuc         }
1127f4a2713aSLionel Sambuc 
1128f4a2713aSLionel Sambuc         if (RI == CaseRanges.end() || EI->first < RI->first) {
1129f4a2713aSLionel Sambuc           hasCasesNotInSwitch = true;
1130f4a2713aSLionel Sambuc           UnhandledNames.push_back(EI->second->getDeclName());
1131f4a2713aSLionel Sambuc         }
1132f4a2713aSLionel Sambuc       }
1133f4a2713aSLionel Sambuc 
1134f4a2713aSLionel Sambuc       if (TheDefaultStmt && UnhandledNames.empty())
1135f4a2713aSLionel Sambuc         Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default);
1136f4a2713aSLionel Sambuc 
1137f4a2713aSLionel Sambuc       // Produce a nice diagnostic if multiple values aren't handled.
1138f4a2713aSLionel Sambuc       switch (UnhandledNames.size()) {
1139f4a2713aSLionel Sambuc       case 0: break;
1140f4a2713aSLionel Sambuc       case 1:
1141f4a2713aSLionel Sambuc         Diag(CondExpr->getExprLoc(), TheDefaultStmt
1142f4a2713aSLionel Sambuc           ? diag::warn_def_missing_case1 : diag::warn_missing_case1)
1143f4a2713aSLionel Sambuc           << UnhandledNames[0];
1144f4a2713aSLionel Sambuc         break;
1145f4a2713aSLionel Sambuc       case 2:
1146f4a2713aSLionel Sambuc         Diag(CondExpr->getExprLoc(), TheDefaultStmt
1147f4a2713aSLionel Sambuc           ? diag::warn_def_missing_case2 : diag::warn_missing_case2)
1148f4a2713aSLionel Sambuc           << UnhandledNames[0] << UnhandledNames[1];
1149f4a2713aSLionel Sambuc         break;
1150f4a2713aSLionel Sambuc       case 3:
1151f4a2713aSLionel Sambuc         Diag(CondExpr->getExprLoc(), TheDefaultStmt
1152f4a2713aSLionel Sambuc           ? diag::warn_def_missing_case3 : diag::warn_missing_case3)
1153f4a2713aSLionel Sambuc           << UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
1154f4a2713aSLionel Sambuc         break;
1155f4a2713aSLionel Sambuc       default:
1156f4a2713aSLionel Sambuc         Diag(CondExpr->getExprLoc(), TheDefaultStmt
1157f4a2713aSLionel Sambuc           ? diag::warn_def_missing_cases : diag::warn_missing_cases)
1158f4a2713aSLionel Sambuc           << (unsigned)UnhandledNames.size()
1159f4a2713aSLionel Sambuc           << UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
1160f4a2713aSLionel Sambuc         break;
1161f4a2713aSLionel Sambuc       }
1162f4a2713aSLionel Sambuc 
1163f4a2713aSLionel Sambuc       if (!hasCasesNotInSwitch)
1164f4a2713aSLionel Sambuc         SS->setAllEnumCasesCovered();
1165f4a2713aSLionel Sambuc     }
1166f4a2713aSLionel Sambuc   }
1167f4a2713aSLionel Sambuc 
1168*0a6a1f1dSLionel Sambuc   if (BodyStmt)
1169f4a2713aSLionel Sambuc     DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), BodyStmt,
1170f4a2713aSLionel Sambuc                           diag::warn_empty_switch_body);
1171f4a2713aSLionel Sambuc 
1172f4a2713aSLionel Sambuc   // FIXME: If the case list was broken is some way, we don't have a good system
1173f4a2713aSLionel Sambuc   // to patch it up.  Instead, just return the whole substmt as broken.
1174f4a2713aSLionel Sambuc   if (CaseListIsErroneous)
1175f4a2713aSLionel Sambuc     return StmtError();
1176f4a2713aSLionel Sambuc 
1177*0a6a1f1dSLionel Sambuc   return SS;
1178f4a2713aSLionel Sambuc }
1179f4a2713aSLionel Sambuc 
1180f4a2713aSLionel Sambuc void
DiagnoseAssignmentEnum(QualType DstType,QualType SrcType,Expr * SrcExpr)1181f4a2713aSLionel Sambuc Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
1182f4a2713aSLionel Sambuc                              Expr *SrcExpr) {
1183*0a6a1f1dSLionel Sambuc   if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))
1184f4a2713aSLionel Sambuc     return;
1185f4a2713aSLionel Sambuc 
1186f4a2713aSLionel Sambuc   if (const EnumType *ET = DstType->getAs<EnumType>())
1187*0a6a1f1dSLionel Sambuc     if (!Context.hasSameUnqualifiedType(SrcType, DstType) &&
1188f4a2713aSLionel Sambuc         SrcType->isIntegerType()) {
1189f4a2713aSLionel Sambuc       if (!SrcExpr->isTypeDependent() && !SrcExpr->isValueDependent() &&
1190f4a2713aSLionel Sambuc           SrcExpr->isIntegerConstantExpr(Context)) {
1191f4a2713aSLionel Sambuc         // Get the bitwidth of the enum value before promotions.
1192f4a2713aSLionel Sambuc         unsigned DstWidth = Context.getIntWidth(DstType);
1193f4a2713aSLionel Sambuc         bool DstIsSigned = DstType->isSignedIntegerOrEnumerationType();
1194f4a2713aSLionel Sambuc 
1195f4a2713aSLionel Sambuc         llvm::APSInt RhsVal = SrcExpr->EvaluateKnownConstInt(Context);
1196f4a2713aSLionel Sambuc         AdjustAPSInt(RhsVal, DstWidth, DstIsSigned);
1197f4a2713aSLionel Sambuc         const EnumDecl *ED = ET->getDecl();
1198f4a2713aSLionel Sambuc         typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64>
1199f4a2713aSLionel Sambuc             EnumValsTy;
1200f4a2713aSLionel Sambuc         EnumValsTy EnumVals;
1201f4a2713aSLionel Sambuc 
1202f4a2713aSLionel Sambuc         // Gather all enum values, set their type and sort them,
1203f4a2713aSLionel Sambuc         // allowing easier comparison with rhs constant.
1204*0a6a1f1dSLionel Sambuc         for (auto *EDI : ED->enumerators()) {
1205f4a2713aSLionel Sambuc           llvm::APSInt Val = EDI->getInitVal();
1206f4a2713aSLionel Sambuc           AdjustAPSInt(Val, DstWidth, DstIsSigned);
1207*0a6a1f1dSLionel Sambuc           EnumVals.push_back(std::make_pair(Val, EDI));
1208f4a2713aSLionel Sambuc         }
1209f4a2713aSLionel Sambuc         if (EnumVals.empty())
1210f4a2713aSLionel Sambuc           return;
1211f4a2713aSLionel Sambuc         std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
1212f4a2713aSLionel Sambuc         EnumValsTy::iterator EIend =
1213f4a2713aSLionel Sambuc             std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
1214f4a2713aSLionel Sambuc 
1215f4a2713aSLionel Sambuc         // See which values aren't in the enum.
1216f4a2713aSLionel Sambuc         EnumValsTy::const_iterator EI = EnumVals.begin();
1217f4a2713aSLionel Sambuc         while (EI != EIend && EI->first < RhsVal)
1218f4a2713aSLionel Sambuc           EI++;
1219f4a2713aSLionel Sambuc         if (EI == EIend || EI->first != RhsVal) {
1220f4a2713aSLionel Sambuc           Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
1221*0a6a1f1dSLionel Sambuc               << DstType.getUnqualifiedType();
1222f4a2713aSLionel Sambuc         }
1223f4a2713aSLionel Sambuc       }
1224f4a2713aSLionel Sambuc     }
1225f4a2713aSLionel Sambuc }
1226f4a2713aSLionel Sambuc 
1227f4a2713aSLionel Sambuc StmtResult
ActOnWhileStmt(SourceLocation WhileLoc,FullExprArg Cond,Decl * CondVar,Stmt * Body)1228f4a2713aSLionel Sambuc Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
1229f4a2713aSLionel Sambuc                      Decl *CondVar, Stmt *Body) {
1230f4a2713aSLionel Sambuc   ExprResult CondResult(Cond.release());
1231f4a2713aSLionel Sambuc 
1232*0a6a1f1dSLionel Sambuc   VarDecl *ConditionVar = nullptr;
1233f4a2713aSLionel Sambuc   if (CondVar) {
1234f4a2713aSLionel Sambuc     ConditionVar = cast<VarDecl>(CondVar);
1235f4a2713aSLionel Sambuc     CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
1236f4a2713aSLionel Sambuc     if (CondResult.isInvalid())
1237f4a2713aSLionel Sambuc       return StmtError();
1238f4a2713aSLionel Sambuc   }
1239*0a6a1f1dSLionel Sambuc   Expr *ConditionExpr = CondResult.get();
1240f4a2713aSLionel Sambuc   if (!ConditionExpr)
1241f4a2713aSLionel Sambuc     return StmtError();
1242*0a6a1f1dSLionel Sambuc   CheckBreakContinueBinding(ConditionExpr);
1243f4a2713aSLionel Sambuc 
1244f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(Body);
1245f4a2713aSLionel Sambuc 
1246f4a2713aSLionel Sambuc   if (isa<NullStmt>(Body))
1247f4a2713aSLionel Sambuc     getCurCompoundScope().setHasEmptyLoopBodies();
1248f4a2713aSLionel Sambuc 
1249*0a6a1f1dSLionel Sambuc   return new (Context)
1250*0a6a1f1dSLionel Sambuc       WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);
1251f4a2713aSLionel Sambuc }
1252f4a2713aSLionel Sambuc 
1253f4a2713aSLionel Sambuc StmtResult
ActOnDoStmt(SourceLocation DoLoc,Stmt * Body,SourceLocation WhileLoc,SourceLocation CondLParen,Expr * Cond,SourceLocation CondRParen)1254f4a2713aSLionel Sambuc Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
1255f4a2713aSLionel Sambuc                   SourceLocation WhileLoc, SourceLocation CondLParen,
1256f4a2713aSLionel Sambuc                   Expr *Cond, SourceLocation CondRParen) {
1257f4a2713aSLionel Sambuc   assert(Cond && "ActOnDoStmt(): missing expression");
1258f4a2713aSLionel Sambuc 
1259*0a6a1f1dSLionel Sambuc   CheckBreakContinueBinding(Cond);
1260f4a2713aSLionel Sambuc   ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
1261f4a2713aSLionel Sambuc   if (CondResult.isInvalid())
1262f4a2713aSLionel Sambuc     return StmtError();
1263*0a6a1f1dSLionel Sambuc   Cond = CondResult.get();
1264f4a2713aSLionel Sambuc 
1265f4a2713aSLionel Sambuc   CondResult = ActOnFinishFullExpr(Cond, DoLoc);
1266f4a2713aSLionel Sambuc   if (CondResult.isInvalid())
1267f4a2713aSLionel Sambuc     return StmtError();
1268*0a6a1f1dSLionel Sambuc   Cond = CondResult.get();
1269f4a2713aSLionel Sambuc 
1270f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(Body);
1271f4a2713aSLionel Sambuc 
1272*0a6a1f1dSLionel Sambuc   return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
1273f4a2713aSLionel Sambuc }
1274f4a2713aSLionel Sambuc 
1275f4a2713aSLionel Sambuc namespace {
1276f4a2713aSLionel Sambuc   // This visitor will traverse a conditional statement and store all
1277f4a2713aSLionel Sambuc   // the evaluated decls into a vector.  Simple is set to true if none
1278f4a2713aSLionel Sambuc   // of the excluded constructs are used.
1279f4a2713aSLionel Sambuc   class DeclExtractor : public EvaluatedExprVisitor<DeclExtractor> {
1280*0a6a1f1dSLionel Sambuc     llvm::SmallPtrSetImpl<VarDecl*> &Decls;
1281f4a2713aSLionel Sambuc     SmallVectorImpl<SourceRange> &Ranges;
1282f4a2713aSLionel Sambuc     bool Simple;
1283f4a2713aSLionel Sambuc   public:
1284f4a2713aSLionel Sambuc     typedef EvaluatedExprVisitor<DeclExtractor> Inherited;
1285f4a2713aSLionel Sambuc 
DeclExtractor(Sema & S,llvm::SmallPtrSetImpl<VarDecl * > & Decls,SmallVectorImpl<SourceRange> & Ranges)1286*0a6a1f1dSLionel Sambuc     DeclExtractor(Sema &S, llvm::SmallPtrSetImpl<VarDecl*> &Decls,
1287f4a2713aSLionel Sambuc                   SmallVectorImpl<SourceRange> &Ranges) :
1288f4a2713aSLionel Sambuc         Inherited(S.Context),
1289f4a2713aSLionel Sambuc         Decls(Decls),
1290f4a2713aSLionel Sambuc         Ranges(Ranges),
1291f4a2713aSLionel Sambuc         Simple(true) {}
1292f4a2713aSLionel Sambuc 
isSimple()1293f4a2713aSLionel Sambuc     bool isSimple() { return Simple; }
1294f4a2713aSLionel Sambuc 
1295f4a2713aSLionel Sambuc     // Replaces the method in EvaluatedExprVisitor.
VisitMemberExpr(MemberExpr * E)1296f4a2713aSLionel Sambuc     void VisitMemberExpr(MemberExpr* E) {
1297f4a2713aSLionel Sambuc       Simple = false;
1298f4a2713aSLionel Sambuc     }
1299f4a2713aSLionel Sambuc 
1300f4a2713aSLionel Sambuc     // Any Stmt not whitelisted will cause the condition to be marked complex.
VisitStmt(Stmt * S)1301f4a2713aSLionel Sambuc     void VisitStmt(Stmt *S) {
1302f4a2713aSLionel Sambuc       Simple = false;
1303f4a2713aSLionel Sambuc     }
1304f4a2713aSLionel Sambuc 
VisitBinaryOperator(BinaryOperator * E)1305f4a2713aSLionel Sambuc     void VisitBinaryOperator(BinaryOperator *E) {
1306f4a2713aSLionel Sambuc       Visit(E->getLHS());
1307f4a2713aSLionel Sambuc       Visit(E->getRHS());
1308f4a2713aSLionel Sambuc     }
1309f4a2713aSLionel Sambuc 
VisitCastExpr(CastExpr * E)1310f4a2713aSLionel Sambuc     void VisitCastExpr(CastExpr *E) {
1311f4a2713aSLionel Sambuc       Visit(E->getSubExpr());
1312f4a2713aSLionel Sambuc     }
1313f4a2713aSLionel Sambuc 
VisitUnaryOperator(UnaryOperator * E)1314f4a2713aSLionel Sambuc     void VisitUnaryOperator(UnaryOperator *E) {
1315f4a2713aSLionel Sambuc       // Skip checking conditionals with derefernces.
1316f4a2713aSLionel Sambuc       if (E->getOpcode() == UO_Deref)
1317f4a2713aSLionel Sambuc         Simple = false;
1318f4a2713aSLionel Sambuc       else
1319f4a2713aSLionel Sambuc         Visit(E->getSubExpr());
1320f4a2713aSLionel Sambuc     }
1321f4a2713aSLionel Sambuc 
VisitConditionalOperator(ConditionalOperator * E)1322f4a2713aSLionel Sambuc     void VisitConditionalOperator(ConditionalOperator *E) {
1323f4a2713aSLionel Sambuc       Visit(E->getCond());
1324f4a2713aSLionel Sambuc       Visit(E->getTrueExpr());
1325f4a2713aSLionel Sambuc       Visit(E->getFalseExpr());
1326f4a2713aSLionel Sambuc     }
1327f4a2713aSLionel Sambuc 
VisitParenExpr(ParenExpr * E)1328f4a2713aSLionel Sambuc     void VisitParenExpr(ParenExpr *E) {
1329f4a2713aSLionel Sambuc       Visit(E->getSubExpr());
1330f4a2713aSLionel Sambuc     }
1331f4a2713aSLionel Sambuc 
VisitBinaryConditionalOperator(BinaryConditionalOperator * E)1332f4a2713aSLionel Sambuc     void VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
1333f4a2713aSLionel Sambuc       Visit(E->getOpaqueValue()->getSourceExpr());
1334f4a2713aSLionel Sambuc       Visit(E->getFalseExpr());
1335f4a2713aSLionel Sambuc     }
1336f4a2713aSLionel Sambuc 
VisitIntegerLiteral(IntegerLiteral * E)1337f4a2713aSLionel Sambuc     void VisitIntegerLiteral(IntegerLiteral *E) { }
VisitFloatingLiteral(FloatingLiteral * E)1338f4a2713aSLionel Sambuc     void VisitFloatingLiteral(FloatingLiteral *E) { }
VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr * E)1339f4a2713aSLionel Sambuc     void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { }
VisitCharacterLiteral(CharacterLiteral * E)1340f4a2713aSLionel Sambuc     void VisitCharacterLiteral(CharacterLiteral *E) { }
VisitGNUNullExpr(GNUNullExpr * E)1341f4a2713aSLionel Sambuc     void VisitGNUNullExpr(GNUNullExpr *E) { }
VisitImaginaryLiteral(ImaginaryLiteral * E)1342f4a2713aSLionel Sambuc     void VisitImaginaryLiteral(ImaginaryLiteral *E) { }
1343f4a2713aSLionel Sambuc 
VisitDeclRefExpr(DeclRefExpr * E)1344f4a2713aSLionel Sambuc     void VisitDeclRefExpr(DeclRefExpr *E) {
1345f4a2713aSLionel Sambuc       VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
1346f4a2713aSLionel Sambuc       if (!VD) return;
1347f4a2713aSLionel Sambuc 
1348f4a2713aSLionel Sambuc       Ranges.push_back(E->getSourceRange());
1349f4a2713aSLionel Sambuc 
1350f4a2713aSLionel Sambuc       Decls.insert(VD);
1351f4a2713aSLionel Sambuc     }
1352f4a2713aSLionel Sambuc 
1353f4a2713aSLionel Sambuc   }; // end class DeclExtractor
1354f4a2713aSLionel Sambuc 
1355f4a2713aSLionel Sambuc   // DeclMatcher checks to see if the decls are used in a non-evauluated
1356f4a2713aSLionel Sambuc   // context.
1357f4a2713aSLionel Sambuc   class DeclMatcher : public EvaluatedExprVisitor<DeclMatcher> {
1358*0a6a1f1dSLionel Sambuc     llvm::SmallPtrSetImpl<VarDecl*> &Decls;
1359f4a2713aSLionel Sambuc     bool FoundDecl;
1360f4a2713aSLionel Sambuc 
1361f4a2713aSLionel Sambuc   public:
1362f4a2713aSLionel Sambuc     typedef EvaluatedExprVisitor<DeclMatcher> Inherited;
1363f4a2713aSLionel Sambuc 
DeclMatcher(Sema & S,llvm::SmallPtrSetImpl<VarDecl * > & Decls,Stmt * Statement)1364*0a6a1f1dSLionel Sambuc     DeclMatcher(Sema &S, llvm::SmallPtrSetImpl<VarDecl*> &Decls,
1365f4a2713aSLionel Sambuc                 Stmt *Statement) :
1366f4a2713aSLionel Sambuc         Inherited(S.Context), Decls(Decls), FoundDecl(false) {
1367f4a2713aSLionel Sambuc       if (!Statement) return;
1368f4a2713aSLionel Sambuc 
1369f4a2713aSLionel Sambuc       Visit(Statement);
1370f4a2713aSLionel Sambuc     }
1371f4a2713aSLionel Sambuc 
VisitReturnStmt(ReturnStmt * S)1372f4a2713aSLionel Sambuc     void VisitReturnStmt(ReturnStmt *S) {
1373f4a2713aSLionel Sambuc       FoundDecl = true;
1374f4a2713aSLionel Sambuc     }
1375f4a2713aSLionel Sambuc 
VisitBreakStmt(BreakStmt * S)1376f4a2713aSLionel Sambuc     void VisitBreakStmt(BreakStmt *S) {
1377f4a2713aSLionel Sambuc       FoundDecl = true;
1378f4a2713aSLionel Sambuc     }
1379f4a2713aSLionel Sambuc 
VisitGotoStmt(GotoStmt * S)1380f4a2713aSLionel Sambuc     void VisitGotoStmt(GotoStmt *S) {
1381f4a2713aSLionel Sambuc       FoundDecl = true;
1382f4a2713aSLionel Sambuc     }
1383f4a2713aSLionel Sambuc 
VisitCastExpr(CastExpr * E)1384f4a2713aSLionel Sambuc     void VisitCastExpr(CastExpr *E) {
1385f4a2713aSLionel Sambuc       if (E->getCastKind() == CK_LValueToRValue)
1386f4a2713aSLionel Sambuc         CheckLValueToRValueCast(E->getSubExpr());
1387f4a2713aSLionel Sambuc       else
1388f4a2713aSLionel Sambuc         Visit(E->getSubExpr());
1389f4a2713aSLionel Sambuc     }
1390f4a2713aSLionel Sambuc 
CheckLValueToRValueCast(Expr * E)1391f4a2713aSLionel Sambuc     void CheckLValueToRValueCast(Expr *E) {
1392f4a2713aSLionel Sambuc       E = E->IgnoreParenImpCasts();
1393f4a2713aSLionel Sambuc 
1394f4a2713aSLionel Sambuc       if (isa<DeclRefExpr>(E)) {
1395f4a2713aSLionel Sambuc         return;
1396f4a2713aSLionel Sambuc       }
1397f4a2713aSLionel Sambuc 
1398f4a2713aSLionel Sambuc       if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
1399f4a2713aSLionel Sambuc         Visit(CO->getCond());
1400f4a2713aSLionel Sambuc         CheckLValueToRValueCast(CO->getTrueExpr());
1401f4a2713aSLionel Sambuc         CheckLValueToRValueCast(CO->getFalseExpr());
1402f4a2713aSLionel Sambuc         return;
1403f4a2713aSLionel Sambuc       }
1404f4a2713aSLionel Sambuc 
1405f4a2713aSLionel Sambuc       if (BinaryConditionalOperator *BCO =
1406f4a2713aSLionel Sambuc               dyn_cast<BinaryConditionalOperator>(E)) {
1407f4a2713aSLionel Sambuc         CheckLValueToRValueCast(BCO->getOpaqueValue()->getSourceExpr());
1408f4a2713aSLionel Sambuc         CheckLValueToRValueCast(BCO->getFalseExpr());
1409f4a2713aSLionel Sambuc         return;
1410f4a2713aSLionel Sambuc       }
1411f4a2713aSLionel Sambuc 
1412f4a2713aSLionel Sambuc       Visit(E);
1413f4a2713aSLionel Sambuc     }
1414f4a2713aSLionel Sambuc 
VisitDeclRefExpr(DeclRefExpr * E)1415f4a2713aSLionel Sambuc     void VisitDeclRefExpr(DeclRefExpr *E) {
1416f4a2713aSLionel Sambuc       if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
1417f4a2713aSLionel Sambuc         if (Decls.count(VD))
1418f4a2713aSLionel Sambuc           FoundDecl = true;
1419f4a2713aSLionel Sambuc     }
1420f4a2713aSLionel Sambuc 
FoundDeclInUse()1421f4a2713aSLionel Sambuc     bool FoundDeclInUse() { return FoundDecl; }
1422f4a2713aSLionel Sambuc 
1423f4a2713aSLionel Sambuc   };  // end class DeclMatcher
1424f4a2713aSLionel Sambuc 
CheckForLoopConditionalStatement(Sema & S,Expr * Second,Expr * Third,Stmt * Body)1425f4a2713aSLionel Sambuc   void CheckForLoopConditionalStatement(Sema &S, Expr *Second,
1426f4a2713aSLionel Sambuc                                         Expr *Third, Stmt *Body) {
1427f4a2713aSLionel Sambuc     // Condition is empty
1428f4a2713aSLionel Sambuc     if (!Second) return;
1429f4a2713aSLionel Sambuc 
1430*0a6a1f1dSLionel Sambuc     if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,
1431*0a6a1f1dSLionel Sambuc                           Second->getLocStart()))
1432f4a2713aSLionel Sambuc       return;
1433f4a2713aSLionel Sambuc 
1434f4a2713aSLionel Sambuc     PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body);
1435f4a2713aSLionel Sambuc     llvm::SmallPtrSet<VarDecl*, 8> Decls;
1436f4a2713aSLionel Sambuc     SmallVector<SourceRange, 10> Ranges;
1437f4a2713aSLionel Sambuc     DeclExtractor DE(S, Decls, Ranges);
1438f4a2713aSLionel Sambuc     DE.Visit(Second);
1439f4a2713aSLionel Sambuc 
1440f4a2713aSLionel Sambuc     // Don't analyze complex conditionals.
1441f4a2713aSLionel Sambuc     if (!DE.isSimple()) return;
1442f4a2713aSLionel Sambuc 
1443f4a2713aSLionel Sambuc     // No decls found.
1444f4a2713aSLionel Sambuc     if (Decls.size() == 0) return;
1445f4a2713aSLionel Sambuc 
1446f4a2713aSLionel Sambuc     // Don't warn on volatile, static, or global variables.
1447*0a6a1f1dSLionel Sambuc     for (llvm::SmallPtrSetImpl<VarDecl*>::iterator I = Decls.begin(),
1448f4a2713aSLionel Sambuc                                                    E = Decls.end();
1449f4a2713aSLionel Sambuc          I != E; ++I)
1450f4a2713aSLionel Sambuc       if ((*I)->getType().isVolatileQualified() ||
1451f4a2713aSLionel Sambuc           (*I)->hasGlobalStorage()) return;
1452f4a2713aSLionel Sambuc 
1453f4a2713aSLionel Sambuc     if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||
1454f4a2713aSLionel Sambuc         DeclMatcher(S, Decls, Third).FoundDeclInUse() ||
1455f4a2713aSLionel Sambuc         DeclMatcher(S, Decls, Body).FoundDeclInUse())
1456f4a2713aSLionel Sambuc       return;
1457f4a2713aSLionel Sambuc 
1458f4a2713aSLionel Sambuc     // Load decl names into diagnostic.
1459f4a2713aSLionel Sambuc     if (Decls.size() > 4)
1460f4a2713aSLionel Sambuc       PDiag << 0;
1461f4a2713aSLionel Sambuc     else {
1462f4a2713aSLionel Sambuc       PDiag << Decls.size();
1463*0a6a1f1dSLionel Sambuc       for (llvm::SmallPtrSetImpl<VarDecl*>::iterator I = Decls.begin(),
1464f4a2713aSLionel Sambuc                                                      E = Decls.end();
1465f4a2713aSLionel Sambuc            I != E; ++I)
1466f4a2713aSLionel Sambuc         PDiag << (*I)->getDeclName();
1467f4a2713aSLionel Sambuc     }
1468f4a2713aSLionel Sambuc 
1469f4a2713aSLionel Sambuc     // Load SourceRanges into diagnostic if there is room.
1470f4a2713aSLionel Sambuc     // Otherwise, load the SourceRange of the conditional expression.
1471f4a2713aSLionel Sambuc     if (Ranges.size() <= PartialDiagnostic::MaxArguments)
1472f4a2713aSLionel Sambuc       for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(),
1473f4a2713aSLionel Sambuc                                                   E = Ranges.end();
1474f4a2713aSLionel Sambuc            I != E; ++I)
1475f4a2713aSLionel Sambuc         PDiag << *I;
1476f4a2713aSLionel Sambuc     else
1477f4a2713aSLionel Sambuc       PDiag << Second->getSourceRange();
1478f4a2713aSLionel Sambuc 
1479f4a2713aSLionel Sambuc     S.Diag(Ranges.begin()->getBegin(), PDiag);
1480f4a2713aSLionel Sambuc   }
1481f4a2713aSLionel Sambuc 
1482f4a2713aSLionel Sambuc   // If Statement is an incemement or decrement, return true and sets the
1483f4a2713aSLionel Sambuc   // variables Increment and DRE.
ProcessIterationStmt(Sema & S,Stmt * Statement,bool & Increment,DeclRefExpr * & DRE)1484f4a2713aSLionel Sambuc   bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,
1485f4a2713aSLionel Sambuc                             DeclRefExpr *&DRE) {
1486f4a2713aSLionel Sambuc     if (UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
1487f4a2713aSLionel Sambuc       switch (UO->getOpcode()) {
1488f4a2713aSLionel Sambuc         default: return false;
1489f4a2713aSLionel Sambuc         case UO_PostInc:
1490f4a2713aSLionel Sambuc         case UO_PreInc:
1491f4a2713aSLionel Sambuc           Increment = true;
1492f4a2713aSLionel Sambuc           break;
1493f4a2713aSLionel Sambuc         case UO_PostDec:
1494f4a2713aSLionel Sambuc         case UO_PreDec:
1495f4a2713aSLionel Sambuc           Increment = false;
1496f4a2713aSLionel Sambuc           break;
1497f4a2713aSLionel Sambuc       }
1498f4a2713aSLionel Sambuc       DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr());
1499f4a2713aSLionel Sambuc       return DRE;
1500f4a2713aSLionel Sambuc     }
1501f4a2713aSLionel Sambuc 
1502f4a2713aSLionel Sambuc     if (CXXOperatorCallExpr *Call = dyn_cast<CXXOperatorCallExpr>(Statement)) {
1503f4a2713aSLionel Sambuc       FunctionDecl *FD = Call->getDirectCallee();
1504f4a2713aSLionel Sambuc       if (!FD || !FD->isOverloadedOperator()) return false;
1505f4a2713aSLionel Sambuc       switch (FD->getOverloadedOperator()) {
1506f4a2713aSLionel Sambuc         default: return false;
1507f4a2713aSLionel Sambuc         case OO_PlusPlus:
1508f4a2713aSLionel Sambuc           Increment = true;
1509f4a2713aSLionel Sambuc           break;
1510f4a2713aSLionel Sambuc         case OO_MinusMinus:
1511f4a2713aSLionel Sambuc           Increment = false;
1512f4a2713aSLionel Sambuc           break;
1513f4a2713aSLionel Sambuc       }
1514f4a2713aSLionel Sambuc       DRE = dyn_cast<DeclRefExpr>(Call->getArg(0));
1515f4a2713aSLionel Sambuc       return DRE;
1516f4a2713aSLionel Sambuc     }
1517f4a2713aSLionel Sambuc 
1518f4a2713aSLionel Sambuc     return false;
1519f4a2713aSLionel Sambuc   }
1520f4a2713aSLionel Sambuc 
1521*0a6a1f1dSLionel Sambuc   // A visitor to determine if a continue or break statement is a
1522*0a6a1f1dSLionel Sambuc   // subexpression.
1523*0a6a1f1dSLionel Sambuc   class BreakContinueFinder : public EvaluatedExprVisitor<BreakContinueFinder> {
1524*0a6a1f1dSLionel Sambuc     SourceLocation BreakLoc;
1525*0a6a1f1dSLionel Sambuc     SourceLocation ContinueLoc;
1526f4a2713aSLionel Sambuc   public:
BreakContinueFinder(Sema & S,Stmt * Body)1527*0a6a1f1dSLionel Sambuc     BreakContinueFinder(Sema &S, Stmt* Body) :
1528*0a6a1f1dSLionel Sambuc         Inherited(S.Context) {
1529f4a2713aSLionel Sambuc       Visit(Body);
1530f4a2713aSLionel Sambuc     }
1531f4a2713aSLionel Sambuc 
1532*0a6a1f1dSLionel Sambuc     typedef EvaluatedExprVisitor<BreakContinueFinder> Inherited;
1533f4a2713aSLionel Sambuc 
VisitContinueStmt(ContinueStmt * E)1534f4a2713aSLionel Sambuc     void VisitContinueStmt(ContinueStmt* E) {
1535*0a6a1f1dSLionel Sambuc       ContinueLoc = E->getContinueLoc();
1536f4a2713aSLionel Sambuc     }
1537f4a2713aSLionel Sambuc 
VisitBreakStmt(BreakStmt * E)1538*0a6a1f1dSLionel Sambuc     void VisitBreakStmt(BreakStmt* E) {
1539*0a6a1f1dSLionel Sambuc       BreakLoc = E->getBreakLoc();
1540*0a6a1f1dSLionel Sambuc     }
1541f4a2713aSLionel Sambuc 
ContinueFound()1542*0a6a1f1dSLionel Sambuc     bool ContinueFound() { return ContinueLoc.isValid(); }
BreakFound()1543*0a6a1f1dSLionel Sambuc     bool BreakFound() { return BreakLoc.isValid(); }
GetContinueLoc()1544*0a6a1f1dSLionel Sambuc     SourceLocation GetContinueLoc() { return ContinueLoc; }
GetBreakLoc()1545*0a6a1f1dSLionel Sambuc     SourceLocation GetBreakLoc() { return BreakLoc; }
1546*0a6a1f1dSLionel Sambuc 
1547*0a6a1f1dSLionel Sambuc   };  // end class BreakContinueFinder
1548f4a2713aSLionel Sambuc 
1549f4a2713aSLionel Sambuc   // Emit a warning when a loop increment/decrement appears twice per loop
1550f4a2713aSLionel Sambuc   // iteration.  The conditions which trigger this warning are:
1551f4a2713aSLionel Sambuc   // 1) The last statement in the loop body and the third expression in the
1552f4a2713aSLionel Sambuc   //    for loop are both increment or both decrement of the same variable
1553f4a2713aSLionel Sambuc   // 2) No continue statements in the loop body.
CheckForRedundantIteration(Sema & S,Expr * Third,Stmt * Body)1554f4a2713aSLionel Sambuc   void CheckForRedundantIteration(Sema &S, Expr *Third, Stmt *Body) {
1555f4a2713aSLionel Sambuc     // Return when there is nothing to check.
1556f4a2713aSLionel Sambuc     if (!Body || !Third) return;
1557f4a2713aSLionel Sambuc 
1558*0a6a1f1dSLionel Sambuc     if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,
1559*0a6a1f1dSLionel Sambuc                           Third->getLocStart()))
1560f4a2713aSLionel Sambuc       return;
1561f4a2713aSLionel Sambuc 
1562f4a2713aSLionel Sambuc     // Get the last statement from the loop body.
1563f4a2713aSLionel Sambuc     CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
1564f4a2713aSLionel Sambuc     if (!CS || CS->body_empty()) return;
1565f4a2713aSLionel Sambuc     Stmt *LastStmt = CS->body_back();
1566f4a2713aSLionel Sambuc     if (!LastStmt) return;
1567f4a2713aSLionel Sambuc 
1568f4a2713aSLionel Sambuc     bool LoopIncrement, LastIncrement;
1569f4a2713aSLionel Sambuc     DeclRefExpr *LoopDRE, *LastDRE;
1570f4a2713aSLionel Sambuc 
1571f4a2713aSLionel Sambuc     if (!ProcessIterationStmt(S, Third, LoopIncrement, LoopDRE)) return;
1572f4a2713aSLionel Sambuc     if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE)) return;
1573f4a2713aSLionel Sambuc 
1574f4a2713aSLionel Sambuc     // Check that the two statements are both increments or both decrements
1575*0a6a1f1dSLionel Sambuc     // on the same variable.
1576f4a2713aSLionel Sambuc     if (LoopIncrement != LastIncrement ||
1577f4a2713aSLionel Sambuc         LoopDRE->getDecl() != LastDRE->getDecl()) return;
1578f4a2713aSLionel Sambuc 
1579*0a6a1f1dSLionel Sambuc     if (BreakContinueFinder(S, Body).ContinueFound()) return;
1580f4a2713aSLionel Sambuc 
1581f4a2713aSLionel Sambuc     S.Diag(LastDRE->getLocation(), diag::warn_redundant_loop_iteration)
1582f4a2713aSLionel Sambuc          << LastDRE->getDecl() << LastIncrement;
1583f4a2713aSLionel Sambuc     S.Diag(LoopDRE->getLocation(), diag::note_loop_iteration_here)
1584f4a2713aSLionel Sambuc          << LoopIncrement;
1585f4a2713aSLionel Sambuc   }
1586f4a2713aSLionel Sambuc 
1587f4a2713aSLionel Sambuc } // end namespace
1588f4a2713aSLionel Sambuc 
1589*0a6a1f1dSLionel Sambuc 
CheckBreakContinueBinding(Expr * E)1590*0a6a1f1dSLionel Sambuc void Sema::CheckBreakContinueBinding(Expr *E) {
1591*0a6a1f1dSLionel Sambuc   if (!E || getLangOpts().CPlusPlus)
1592*0a6a1f1dSLionel Sambuc     return;
1593*0a6a1f1dSLionel Sambuc   BreakContinueFinder BCFinder(*this, E);
1594*0a6a1f1dSLionel Sambuc   Scope *BreakParent = CurScope->getBreakParent();
1595*0a6a1f1dSLionel Sambuc   if (BCFinder.BreakFound() && BreakParent) {
1596*0a6a1f1dSLionel Sambuc     if (BreakParent->getFlags() & Scope::SwitchScope) {
1597*0a6a1f1dSLionel Sambuc       Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);
1598*0a6a1f1dSLionel Sambuc     } else {
1599*0a6a1f1dSLionel Sambuc       Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)
1600*0a6a1f1dSLionel Sambuc           << "break";
1601*0a6a1f1dSLionel Sambuc     }
1602*0a6a1f1dSLionel Sambuc   } else if (BCFinder.ContinueFound() && CurScope->getContinueParent()) {
1603*0a6a1f1dSLionel Sambuc     Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)
1604*0a6a1f1dSLionel Sambuc         << "continue";
1605*0a6a1f1dSLionel Sambuc   }
1606*0a6a1f1dSLionel Sambuc }
1607*0a6a1f1dSLionel Sambuc 
1608f4a2713aSLionel Sambuc StmtResult
ActOnForStmt(SourceLocation ForLoc,SourceLocation LParenLoc,Stmt * First,FullExprArg second,Decl * secondVar,FullExprArg third,SourceLocation RParenLoc,Stmt * Body)1609f4a2713aSLionel Sambuc Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1610f4a2713aSLionel Sambuc                    Stmt *First, FullExprArg second, Decl *secondVar,
1611f4a2713aSLionel Sambuc                    FullExprArg third,
1612f4a2713aSLionel Sambuc                    SourceLocation RParenLoc, Stmt *Body) {
1613f4a2713aSLionel Sambuc   if (!getLangOpts().CPlusPlus) {
1614f4a2713aSLionel Sambuc     if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
1615f4a2713aSLionel Sambuc       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
1616f4a2713aSLionel Sambuc       // declare identifiers for objects having storage class 'auto' or
1617f4a2713aSLionel Sambuc       // 'register'.
1618*0a6a1f1dSLionel Sambuc       for (auto *DI : DS->decls()) {
1619*0a6a1f1dSLionel Sambuc         VarDecl *VD = dyn_cast<VarDecl>(DI);
1620f4a2713aSLionel Sambuc         if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage())
1621*0a6a1f1dSLionel Sambuc           VD = nullptr;
1622*0a6a1f1dSLionel Sambuc         if (!VD) {
1623*0a6a1f1dSLionel Sambuc           Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
1624*0a6a1f1dSLionel Sambuc           DI->setInvalidDecl();
1625f4a2713aSLionel Sambuc         }
1626f4a2713aSLionel Sambuc       }
1627f4a2713aSLionel Sambuc     }
1628f4a2713aSLionel Sambuc   }
1629f4a2713aSLionel Sambuc 
1630*0a6a1f1dSLionel Sambuc   CheckBreakContinueBinding(second.get());
1631*0a6a1f1dSLionel Sambuc   CheckBreakContinueBinding(third.get());
1632*0a6a1f1dSLionel Sambuc 
1633f4a2713aSLionel Sambuc   CheckForLoopConditionalStatement(*this, second.get(), third.get(), Body);
1634f4a2713aSLionel Sambuc   CheckForRedundantIteration(*this, third.get(), Body);
1635f4a2713aSLionel Sambuc 
1636f4a2713aSLionel Sambuc   ExprResult SecondResult(second.release());
1637*0a6a1f1dSLionel Sambuc   VarDecl *ConditionVar = nullptr;
1638f4a2713aSLionel Sambuc   if (secondVar) {
1639f4a2713aSLionel Sambuc     ConditionVar = cast<VarDecl>(secondVar);
1640f4a2713aSLionel Sambuc     SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
1641f4a2713aSLionel Sambuc     if (SecondResult.isInvalid())
1642f4a2713aSLionel Sambuc       return StmtError();
1643f4a2713aSLionel Sambuc   }
1644f4a2713aSLionel Sambuc 
1645*0a6a1f1dSLionel Sambuc   Expr *Third  = third.release().getAs<Expr>();
1646f4a2713aSLionel Sambuc 
1647f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(First);
1648f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(Third);
1649f4a2713aSLionel Sambuc   DiagnoseUnusedExprResult(Body);
1650f4a2713aSLionel Sambuc 
1651f4a2713aSLionel Sambuc   if (isa<NullStmt>(Body))
1652f4a2713aSLionel Sambuc     getCurCompoundScope().setHasEmptyLoopBodies();
1653f4a2713aSLionel Sambuc 
1654*0a6a1f1dSLionel Sambuc   return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,
1655*0a6a1f1dSLionel Sambuc                                Third, Body, ForLoc, LParenLoc, RParenLoc);
1656f4a2713aSLionel Sambuc }
1657f4a2713aSLionel Sambuc 
1658f4a2713aSLionel Sambuc /// In an Objective C collection iteration statement:
1659f4a2713aSLionel Sambuc ///   for (x in y)
1660f4a2713aSLionel Sambuc /// x can be an arbitrary l-value expression.  Bind it up as a
1661f4a2713aSLionel Sambuc /// full-expression.
ActOnForEachLValueExpr(Expr * E)1662f4a2713aSLionel Sambuc StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
1663f4a2713aSLionel Sambuc   // Reduce placeholder expressions here.  Note that this rejects the
1664f4a2713aSLionel Sambuc   // use of pseudo-object l-values in this position.
1665f4a2713aSLionel Sambuc   ExprResult result = CheckPlaceholderExpr(E);
1666f4a2713aSLionel Sambuc   if (result.isInvalid()) return StmtError();
1667*0a6a1f1dSLionel Sambuc   E = result.get();
1668f4a2713aSLionel Sambuc 
1669f4a2713aSLionel Sambuc   ExprResult FullExpr = ActOnFinishFullExpr(E);
1670f4a2713aSLionel Sambuc   if (FullExpr.isInvalid())
1671f4a2713aSLionel Sambuc     return StmtError();
1672*0a6a1f1dSLionel Sambuc   return StmtResult(static_cast<Stmt*>(FullExpr.get()));
1673f4a2713aSLionel Sambuc }
1674f4a2713aSLionel Sambuc 
1675f4a2713aSLionel Sambuc ExprResult
CheckObjCForCollectionOperand(SourceLocation forLoc,Expr * collection)1676f4a2713aSLionel Sambuc Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {
1677f4a2713aSLionel Sambuc   if (!collection)
1678f4a2713aSLionel Sambuc     return ExprError();
1679f4a2713aSLionel Sambuc 
1680*0a6a1f1dSLionel Sambuc   ExprResult result = CorrectDelayedTyposInExpr(collection);
1681*0a6a1f1dSLionel Sambuc   if (!result.isUsable())
1682*0a6a1f1dSLionel Sambuc     return ExprError();
1683*0a6a1f1dSLionel Sambuc   collection = result.get();
1684*0a6a1f1dSLionel Sambuc 
1685f4a2713aSLionel Sambuc   // Bail out early if we've got a type-dependent expression.
1686*0a6a1f1dSLionel Sambuc   if (collection->isTypeDependent()) return collection;
1687f4a2713aSLionel Sambuc 
1688f4a2713aSLionel Sambuc   // Perform normal l-value conversion.
1689*0a6a1f1dSLionel Sambuc   result = DefaultFunctionArrayLvalueConversion(collection);
1690f4a2713aSLionel Sambuc   if (result.isInvalid())
1691f4a2713aSLionel Sambuc     return ExprError();
1692*0a6a1f1dSLionel Sambuc   collection = result.get();
1693f4a2713aSLionel Sambuc 
1694f4a2713aSLionel Sambuc   // The operand needs to have object-pointer type.
1695f4a2713aSLionel Sambuc   // TODO: should we do a contextual conversion?
1696f4a2713aSLionel Sambuc   const ObjCObjectPointerType *pointerType =
1697f4a2713aSLionel Sambuc     collection->getType()->getAs<ObjCObjectPointerType>();
1698f4a2713aSLionel Sambuc   if (!pointerType)
1699f4a2713aSLionel Sambuc     return Diag(forLoc, diag::err_collection_expr_type)
1700f4a2713aSLionel Sambuc              << collection->getType() << collection->getSourceRange();
1701f4a2713aSLionel Sambuc 
1702f4a2713aSLionel Sambuc   // Check that the operand provides
1703f4a2713aSLionel Sambuc   //   - countByEnumeratingWithState:objects:count:
1704f4a2713aSLionel Sambuc   const ObjCObjectType *objectType = pointerType->getObjectType();
1705f4a2713aSLionel Sambuc   ObjCInterfaceDecl *iface = objectType->getInterface();
1706f4a2713aSLionel Sambuc 
1707f4a2713aSLionel Sambuc   // If we have a forward-declared type, we can't do this check.
1708f4a2713aSLionel Sambuc   // Under ARC, it is an error not to have a forward-declared class.
1709f4a2713aSLionel Sambuc   if (iface &&
1710f4a2713aSLionel Sambuc       RequireCompleteType(forLoc, QualType(objectType, 0),
1711f4a2713aSLionel Sambuc                           getLangOpts().ObjCAutoRefCount
1712f4a2713aSLionel Sambuc                             ? diag::err_arc_collection_forward
1713f4a2713aSLionel Sambuc                             : 0,
1714f4a2713aSLionel Sambuc                           collection)) {
1715f4a2713aSLionel Sambuc     // Otherwise, if we have any useful type information, check that
1716f4a2713aSLionel Sambuc     // the type declares the appropriate method.
1717f4a2713aSLionel Sambuc   } else if (iface || !objectType->qual_empty()) {
1718f4a2713aSLionel Sambuc     IdentifierInfo *selectorIdents[] = {
1719f4a2713aSLionel Sambuc       &Context.Idents.get("countByEnumeratingWithState"),
1720f4a2713aSLionel Sambuc       &Context.Idents.get("objects"),
1721f4a2713aSLionel Sambuc       &Context.Idents.get("count")
1722f4a2713aSLionel Sambuc     };
1723f4a2713aSLionel Sambuc     Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]);
1724f4a2713aSLionel Sambuc 
1725*0a6a1f1dSLionel Sambuc     ObjCMethodDecl *method = nullptr;
1726f4a2713aSLionel Sambuc 
1727f4a2713aSLionel Sambuc     // If there's an interface, look in both the public and private APIs.
1728f4a2713aSLionel Sambuc     if (iface) {
1729f4a2713aSLionel Sambuc       method = iface->lookupInstanceMethod(selector);
1730f4a2713aSLionel Sambuc       if (!method) method = iface->lookupPrivateMethod(selector);
1731f4a2713aSLionel Sambuc     }
1732f4a2713aSLionel Sambuc 
1733f4a2713aSLionel Sambuc     // Also check protocol qualifiers.
1734f4a2713aSLionel Sambuc     if (!method)
1735f4a2713aSLionel Sambuc       method = LookupMethodInQualifiedType(selector, pointerType,
1736f4a2713aSLionel Sambuc                                            /*instance*/ true);
1737f4a2713aSLionel Sambuc 
1738f4a2713aSLionel Sambuc     // If we didn't find it anywhere, give up.
1739f4a2713aSLionel Sambuc     if (!method) {
1740f4a2713aSLionel Sambuc       Diag(forLoc, diag::warn_collection_expr_type)
1741f4a2713aSLionel Sambuc         << collection->getType() << selector << collection->getSourceRange();
1742f4a2713aSLionel Sambuc     }
1743f4a2713aSLionel Sambuc 
1744f4a2713aSLionel Sambuc     // TODO: check for an incompatible signature?
1745f4a2713aSLionel Sambuc   }
1746f4a2713aSLionel Sambuc 
1747f4a2713aSLionel Sambuc   // Wrap up any cleanups in the expression.
1748*0a6a1f1dSLionel Sambuc   return collection;
1749f4a2713aSLionel Sambuc }
1750f4a2713aSLionel Sambuc 
1751f4a2713aSLionel Sambuc StmtResult
ActOnObjCForCollectionStmt(SourceLocation ForLoc,Stmt * First,Expr * collection,SourceLocation RParenLoc)1752f4a2713aSLionel Sambuc Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
1753f4a2713aSLionel Sambuc                                  Stmt *First, Expr *collection,
1754f4a2713aSLionel Sambuc                                  SourceLocation RParenLoc) {
1755f4a2713aSLionel Sambuc 
1756f4a2713aSLionel Sambuc   ExprResult CollectionExprResult =
1757f4a2713aSLionel Sambuc     CheckObjCForCollectionOperand(ForLoc, collection);
1758f4a2713aSLionel Sambuc 
1759f4a2713aSLionel Sambuc   if (First) {
1760f4a2713aSLionel Sambuc     QualType FirstType;
1761f4a2713aSLionel Sambuc     if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
1762f4a2713aSLionel Sambuc       if (!DS->isSingleDecl())
1763f4a2713aSLionel Sambuc         return StmtError(Diag((*DS->decl_begin())->getLocation(),
1764f4a2713aSLionel Sambuc                          diag::err_toomany_element_decls));
1765f4a2713aSLionel Sambuc 
1766f4a2713aSLionel Sambuc       VarDecl *D = dyn_cast<VarDecl>(DS->getSingleDecl());
1767f4a2713aSLionel Sambuc       if (!D || D->isInvalidDecl())
1768f4a2713aSLionel Sambuc         return StmtError();
1769f4a2713aSLionel Sambuc 
1770f4a2713aSLionel Sambuc       FirstType = D->getType();
1771f4a2713aSLionel Sambuc       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
1772f4a2713aSLionel Sambuc       // declare identifiers for objects having storage class 'auto' or
1773f4a2713aSLionel Sambuc       // 'register'.
1774f4a2713aSLionel Sambuc       if (!D->hasLocalStorage())
1775f4a2713aSLionel Sambuc         return StmtError(Diag(D->getLocation(),
1776f4a2713aSLionel Sambuc                               diag::err_non_local_variable_decl_in_for));
1777f4a2713aSLionel Sambuc 
1778f4a2713aSLionel Sambuc       // If the type contained 'auto', deduce the 'auto' to 'id'.
1779f4a2713aSLionel Sambuc       if (FirstType->getContainedAutoType()) {
1780f4a2713aSLionel Sambuc         OpaqueValueExpr OpaqueId(D->getLocation(), Context.getObjCIdType(),
1781f4a2713aSLionel Sambuc                                  VK_RValue);
1782f4a2713aSLionel Sambuc         Expr *DeducedInit = &OpaqueId;
1783f4a2713aSLionel Sambuc         if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, FirstType) ==
1784f4a2713aSLionel Sambuc                 DAR_Failed)
1785f4a2713aSLionel Sambuc           DiagnoseAutoDeductionFailure(D, DeducedInit);
1786f4a2713aSLionel Sambuc         if (FirstType.isNull()) {
1787f4a2713aSLionel Sambuc           D->setInvalidDecl();
1788f4a2713aSLionel Sambuc           return StmtError();
1789f4a2713aSLionel Sambuc         }
1790f4a2713aSLionel Sambuc 
1791f4a2713aSLionel Sambuc         D->setType(FirstType);
1792f4a2713aSLionel Sambuc 
1793f4a2713aSLionel Sambuc         if (ActiveTemplateInstantiations.empty()) {
1794f4a2713aSLionel Sambuc           SourceLocation Loc =
1795f4a2713aSLionel Sambuc               D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
1796f4a2713aSLionel Sambuc           Diag(Loc, diag::warn_auto_var_is_id)
1797f4a2713aSLionel Sambuc             << D->getDeclName();
1798f4a2713aSLionel Sambuc         }
1799f4a2713aSLionel Sambuc       }
1800f4a2713aSLionel Sambuc 
1801f4a2713aSLionel Sambuc     } else {
1802f4a2713aSLionel Sambuc       Expr *FirstE = cast<Expr>(First);
1803f4a2713aSLionel Sambuc       if (!FirstE->isTypeDependent() && !FirstE->isLValue())
1804f4a2713aSLionel Sambuc         return StmtError(Diag(First->getLocStart(),
1805f4a2713aSLionel Sambuc                    diag::err_selector_element_not_lvalue)
1806f4a2713aSLionel Sambuc           << First->getSourceRange());
1807f4a2713aSLionel Sambuc 
1808f4a2713aSLionel Sambuc       FirstType = static_cast<Expr*>(First)->getType();
1809f4a2713aSLionel Sambuc       if (FirstType.isConstQualified())
1810f4a2713aSLionel Sambuc         Diag(ForLoc, diag::err_selector_element_const_type)
1811f4a2713aSLionel Sambuc           << FirstType << First->getSourceRange();
1812f4a2713aSLionel Sambuc     }
1813f4a2713aSLionel Sambuc     if (!FirstType->isDependentType() &&
1814f4a2713aSLionel Sambuc         !FirstType->isObjCObjectPointerType() &&
1815f4a2713aSLionel Sambuc         !FirstType->isBlockPointerType())
1816f4a2713aSLionel Sambuc         return StmtError(Diag(ForLoc, diag::err_selector_element_type)
1817f4a2713aSLionel Sambuc                            << FirstType << First->getSourceRange());
1818f4a2713aSLionel Sambuc   }
1819f4a2713aSLionel Sambuc 
1820f4a2713aSLionel Sambuc   if (CollectionExprResult.isInvalid())
1821f4a2713aSLionel Sambuc     return StmtError();
1822f4a2713aSLionel Sambuc 
1823*0a6a1f1dSLionel Sambuc   CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
1824f4a2713aSLionel Sambuc   if (CollectionExprResult.isInvalid())
1825f4a2713aSLionel Sambuc     return StmtError();
1826f4a2713aSLionel Sambuc 
1827*0a6a1f1dSLionel Sambuc   return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(),
1828*0a6a1f1dSLionel Sambuc                                              nullptr, ForLoc, RParenLoc);
1829f4a2713aSLionel Sambuc }
1830f4a2713aSLionel Sambuc 
1831f4a2713aSLionel Sambuc /// Finish building a variable declaration for a for-range statement.
1832f4a2713aSLionel Sambuc /// \return true if an error occurs.
FinishForRangeVarDecl(Sema & SemaRef,VarDecl * Decl,Expr * Init,SourceLocation Loc,int DiagID)1833f4a2713aSLionel Sambuc static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
1834f4a2713aSLionel Sambuc                                   SourceLocation Loc, int DiagID) {
1835f4a2713aSLionel Sambuc   // Deduce the type for the iterator variable now rather than leaving it to
1836f4a2713aSLionel Sambuc   // AddInitializerToDecl, so we can produce a more suitable diagnostic.
1837f4a2713aSLionel Sambuc   QualType InitType;
1838f4a2713aSLionel Sambuc   if ((!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) ||
1839f4a2713aSLionel Sambuc       SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitType) ==
1840f4a2713aSLionel Sambuc           Sema::DAR_Failed)
1841f4a2713aSLionel Sambuc     SemaRef.Diag(Loc, DiagID) << Init->getType();
1842f4a2713aSLionel Sambuc   if (InitType.isNull()) {
1843f4a2713aSLionel Sambuc     Decl->setInvalidDecl();
1844f4a2713aSLionel Sambuc     return true;
1845f4a2713aSLionel Sambuc   }
1846f4a2713aSLionel Sambuc   Decl->setType(InitType);
1847f4a2713aSLionel Sambuc 
1848f4a2713aSLionel Sambuc   // In ARC, infer lifetime.
1849f4a2713aSLionel Sambuc   // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if
1850f4a2713aSLionel Sambuc   // we're doing the equivalent of fast iteration.
1851f4a2713aSLionel Sambuc   if (SemaRef.getLangOpts().ObjCAutoRefCount &&
1852f4a2713aSLionel Sambuc       SemaRef.inferObjCARCLifetime(Decl))
1853f4a2713aSLionel Sambuc     Decl->setInvalidDecl();
1854f4a2713aSLionel Sambuc 
1855f4a2713aSLionel Sambuc   SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false,
1856f4a2713aSLionel Sambuc                                /*TypeMayContainAuto=*/false);
1857f4a2713aSLionel Sambuc   SemaRef.FinalizeDeclaration(Decl);
1858f4a2713aSLionel Sambuc   SemaRef.CurContext->addHiddenDecl(Decl);
1859f4a2713aSLionel Sambuc   return false;
1860f4a2713aSLionel Sambuc }
1861f4a2713aSLionel Sambuc 
1862f4a2713aSLionel Sambuc namespace {
1863f4a2713aSLionel Sambuc 
1864f4a2713aSLionel Sambuc /// Produce a note indicating which begin/end function was implicitly called
1865f4a2713aSLionel Sambuc /// by a C++11 for-range statement. This is often not obvious from the code,
1866f4a2713aSLionel Sambuc /// nor from the diagnostics produced when analysing the implicit expressions
1867f4a2713aSLionel Sambuc /// required in a for-range statement.
NoteForRangeBeginEndFunction(Sema & SemaRef,Expr * E,Sema::BeginEndFunction BEF)1868f4a2713aSLionel Sambuc void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E,
1869f4a2713aSLionel Sambuc                                   Sema::BeginEndFunction BEF) {
1870f4a2713aSLionel Sambuc   CallExpr *CE = dyn_cast<CallExpr>(E);
1871f4a2713aSLionel Sambuc   if (!CE)
1872f4a2713aSLionel Sambuc     return;
1873f4a2713aSLionel Sambuc   FunctionDecl *D = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1874f4a2713aSLionel Sambuc   if (!D)
1875f4a2713aSLionel Sambuc     return;
1876f4a2713aSLionel Sambuc   SourceLocation Loc = D->getLocation();
1877f4a2713aSLionel Sambuc 
1878f4a2713aSLionel Sambuc   std::string Description;
1879f4a2713aSLionel Sambuc   bool IsTemplate = false;
1880f4a2713aSLionel Sambuc   if (FunctionTemplateDecl *FunTmpl = D->getPrimaryTemplate()) {
1881f4a2713aSLionel Sambuc     Description = SemaRef.getTemplateArgumentBindingsText(
1882f4a2713aSLionel Sambuc       FunTmpl->getTemplateParameters(), *D->getTemplateSpecializationArgs());
1883f4a2713aSLionel Sambuc     IsTemplate = true;
1884f4a2713aSLionel Sambuc   }
1885f4a2713aSLionel Sambuc 
1886f4a2713aSLionel Sambuc   SemaRef.Diag(Loc, diag::note_for_range_begin_end)
1887f4a2713aSLionel Sambuc     << BEF << IsTemplate << Description << E->getType();
1888f4a2713aSLionel Sambuc }
1889f4a2713aSLionel Sambuc 
1890f4a2713aSLionel Sambuc /// Build a variable declaration for a for-range statement.
BuildForRangeVarDecl(Sema & SemaRef,SourceLocation Loc,QualType Type,const char * Name)1891f4a2713aSLionel Sambuc VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc,
1892f4a2713aSLionel Sambuc                               QualType Type, const char *Name) {
1893f4a2713aSLionel Sambuc   DeclContext *DC = SemaRef.CurContext;
1894f4a2713aSLionel Sambuc   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1895f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1896f4a2713aSLionel Sambuc   VarDecl *Decl = VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type,
1897f4a2713aSLionel Sambuc                                   TInfo, SC_None);
1898f4a2713aSLionel Sambuc   Decl->setImplicit();
1899f4a2713aSLionel Sambuc   return Decl;
1900f4a2713aSLionel Sambuc }
1901f4a2713aSLionel Sambuc 
1902f4a2713aSLionel Sambuc }
1903f4a2713aSLionel Sambuc 
ObjCEnumerationCollection(Expr * Collection)1904f4a2713aSLionel Sambuc static bool ObjCEnumerationCollection(Expr *Collection) {
1905f4a2713aSLionel Sambuc   return !Collection->isTypeDependent()
1906*0a6a1f1dSLionel Sambuc           && Collection->getType()->getAs<ObjCObjectPointerType>() != nullptr;
1907f4a2713aSLionel Sambuc }
1908f4a2713aSLionel Sambuc 
1909f4a2713aSLionel Sambuc /// ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
1910f4a2713aSLionel Sambuc ///
1911f4a2713aSLionel Sambuc /// C++11 [stmt.ranged]:
1912f4a2713aSLionel Sambuc ///   A range-based for statement is equivalent to
1913f4a2713aSLionel Sambuc ///
1914f4a2713aSLionel Sambuc ///   {
1915f4a2713aSLionel Sambuc ///     auto && __range = range-init;
1916f4a2713aSLionel Sambuc ///     for ( auto __begin = begin-expr,
1917f4a2713aSLionel Sambuc ///           __end = end-expr;
1918f4a2713aSLionel Sambuc ///           __begin != __end;
1919f4a2713aSLionel Sambuc ///           ++__begin ) {
1920f4a2713aSLionel Sambuc ///       for-range-declaration = *__begin;
1921f4a2713aSLionel Sambuc ///       statement
1922f4a2713aSLionel Sambuc ///     }
1923f4a2713aSLionel Sambuc ///   }
1924f4a2713aSLionel Sambuc ///
1925f4a2713aSLionel Sambuc /// The body of the loop is not available yet, since it cannot be analysed until
1926f4a2713aSLionel Sambuc /// we have determined the type of the for-range-declaration.
1927f4a2713aSLionel Sambuc StmtResult
ActOnCXXForRangeStmt(SourceLocation ForLoc,Stmt * First,SourceLocation ColonLoc,Expr * Range,SourceLocation RParenLoc,BuildForRangeKind Kind)1928f4a2713aSLionel Sambuc Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc,
1929f4a2713aSLionel Sambuc                            Stmt *First, SourceLocation ColonLoc, Expr *Range,
1930f4a2713aSLionel Sambuc                            SourceLocation RParenLoc, BuildForRangeKind Kind) {
1931f4a2713aSLionel Sambuc   if (!First)
1932f4a2713aSLionel Sambuc     return StmtError();
1933f4a2713aSLionel Sambuc 
1934f4a2713aSLionel Sambuc   if (Range && ObjCEnumerationCollection(Range))
1935f4a2713aSLionel Sambuc     return ActOnObjCForCollectionStmt(ForLoc, First, Range, RParenLoc);
1936f4a2713aSLionel Sambuc 
1937f4a2713aSLionel Sambuc   DeclStmt *DS = dyn_cast<DeclStmt>(First);
1938f4a2713aSLionel Sambuc   assert(DS && "first part of for range not a decl stmt");
1939f4a2713aSLionel Sambuc 
1940f4a2713aSLionel Sambuc   if (!DS->isSingleDecl()) {
1941f4a2713aSLionel Sambuc     Diag(DS->getStartLoc(), diag::err_type_defined_in_for_range);
1942f4a2713aSLionel Sambuc     return StmtError();
1943f4a2713aSLionel Sambuc   }
1944f4a2713aSLionel Sambuc 
1945f4a2713aSLionel Sambuc   Decl *LoopVar = DS->getSingleDecl();
1946f4a2713aSLionel Sambuc   if (LoopVar->isInvalidDecl() || !Range ||
1947f4a2713aSLionel Sambuc       DiagnoseUnexpandedParameterPack(Range, UPPC_Expression)) {
1948f4a2713aSLionel Sambuc     LoopVar->setInvalidDecl();
1949f4a2713aSLionel Sambuc     return StmtError();
1950f4a2713aSLionel Sambuc   }
1951f4a2713aSLionel Sambuc 
1952f4a2713aSLionel Sambuc   // Build  auto && __range = range-init
1953f4a2713aSLionel Sambuc   SourceLocation RangeLoc = Range->getLocStart();
1954f4a2713aSLionel Sambuc   VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc,
1955f4a2713aSLionel Sambuc                                            Context.getAutoRRefDeductType(),
1956f4a2713aSLionel Sambuc                                            "__range");
1957f4a2713aSLionel Sambuc   if (FinishForRangeVarDecl(*this, RangeVar, Range, RangeLoc,
1958f4a2713aSLionel Sambuc                             diag::err_for_range_deduction_failure)) {
1959f4a2713aSLionel Sambuc     LoopVar->setInvalidDecl();
1960f4a2713aSLionel Sambuc     return StmtError();
1961f4a2713aSLionel Sambuc   }
1962f4a2713aSLionel Sambuc 
1963f4a2713aSLionel Sambuc   // Claim the type doesn't contain auto: we've already done the checking.
1964f4a2713aSLionel Sambuc   DeclGroupPtrTy RangeGroup =
1965*0a6a1f1dSLionel Sambuc       BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
1966f4a2713aSLionel Sambuc                            /*TypeMayContainAuto=*/ false);
1967f4a2713aSLionel Sambuc   StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);
1968f4a2713aSLionel Sambuc   if (RangeDecl.isInvalid()) {
1969f4a2713aSLionel Sambuc     LoopVar->setInvalidDecl();
1970f4a2713aSLionel Sambuc     return StmtError();
1971f4a2713aSLionel Sambuc   }
1972f4a2713aSLionel Sambuc 
1973f4a2713aSLionel Sambuc   return BuildCXXForRangeStmt(ForLoc, ColonLoc, RangeDecl.get(),
1974*0a6a1f1dSLionel Sambuc                               /*BeginEndDecl=*/nullptr, /*Cond=*/nullptr,
1975*0a6a1f1dSLionel Sambuc                               /*Inc=*/nullptr, DS, RParenLoc, Kind);
1976f4a2713aSLionel Sambuc }
1977f4a2713aSLionel Sambuc 
1978f4a2713aSLionel Sambuc /// \brief Create the initialization, compare, and increment steps for
1979f4a2713aSLionel Sambuc /// the range-based for loop expression.
1980f4a2713aSLionel Sambuc /// This function does not handle array-based for loops,
1981f4a2713aSLionel Sambuc /// which are created in Sema::BuildCXXForRangeStmt.
1982f4a2713aSLionel Sambuc ///
1983f4a2713aSLionel Sambuc /// \returns a ForRangeStatus indicating success or what kind of error occurred.
1984f4a2713aSLionel Sambuc /// BeginExpr and EndExpr are set and FRS_Success is returned on success;
1985f4a2713aSLionel Sambuc /// CandidateSet and BEF are set and some non-success value is returned on
1986f4a2713aSLionel Sambuc /// failure.
BuildNonArrayForRange(Sema & SemaRef,Scope * S,Expr * BeginRange,Expr * EndRange,QualType RangeType,VarDecl * BeginVar,VarDecl * EndVar,SourceLocation ColonLoc,OverloadCandidateSet * CandidateSet,ExprResult * BeginExpr,ExprResult * EndExpr,Sema::BeginEndFunction * BEF)1987f4a2713aSLionel Sambuc static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S,
1988f4a2713aSLionel Sambuc                                             Expr *BeginRange, Expr *EndRange,
1989f4a2713aSLionel Sambuc                                             QualType RangeType,
1990f4a2713aSLionel Sambuc                                             VarDecl *BeginVar,
1991f4a2713aSLionel Sambuc                                             VarDecl *EndVar,
1992f4a2713aSLionel Sambuc                                             SourceLocation ColonLoc,
1993f4a2713aSLionel Sambuc                                             OverloadCandidateSet *CandidateSet,
1994f4a2713aSLionel Sambuc                                             ExprResult *BeginExpr,
1995f4a2713aSLionel Sambuc                                             ExprResult *EndExpr,
1996f4a2713aSLionel Sambuc                                             Sema::BeginEndFunction *BEF) {
1997f4a2713aSLionel Sambuc   DeclarationNameInfo BeginNameInfo(
1998f4a2713aSLionel Sambuc       &SemaRef.PP.getIdentifierTable().get("begin"), ColonLoc);
1999f4a2713aSLionel Sambuc   DeclarationNameInfo EndNameInfo(&SemaRef.PP.getIdentifierTable().get("end"),
2000f4a2713aSLionel Sambuc                                   ColonLoc);
2001f4a2713aSLionel Sambuc 
2002f4a2713aSLionel Sambuc   LookupResult BeginMemberLookup(SemaRef, BeginNameInfo,
2003f4a2713aSLionel Sambuc                                  Sema::LookupMemberName);
2004f4a2713aSLionel Sambuc   LookupResult EndMemberLookup(SemaRef, EndNameInfo, Sema::LookupMemberName);
2005f4a2713aSLionel Sambuc 
2006f4a2713aSLionel Sambuc   if (CXXRecordDecl *D = RangeType->getAsCXXRecordDecl()) {
2007f4a2713aSLionel Sambuc     // - if _RangeT is a class type, the unqualified-ids begin and end are
2008f4a2713aSLionel Sambuc     //   looked up in the scope of class _RangeT as if by class member access
2009f4a2713aSLionel Sambuc     //   lookup (3.4.5), and if either (or both) finds at least one
2010f4a2713aSLionel Sambuc     //   declaration, begin-expr and end-expr are __range.begin() and
2011f4a2713aSLionel Sambuc     //   __range.end(), respectively;
2012f4a2713aSLionel Sambuc     SemaRef.LookupQualifiedName(BeginMemberLookup, D);
2013f4a2713aSLionel Sambuc     SemaRef.LookupQualifiedName(EndMemberLookup, D);
2014f4a2713aSLionel Sambuc 
2015f4a2713aSLionel Sambuc     if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {
2016f4a2713aSLionel Sambuc       SourceLocation RangeLoc = BeginVar->getLocation();
2017f4a2713aSLionel Sambuc       *BEF = BeginMemberLookup.empty() ? Sema::BEF_end : Sema::BEF_begin;
2018f4a2713aSLionel Sambuc 
2019f4a2713aSLionel Sambuc       SemaRef.Diag(RangeLoc, diag::err_for_range_member_begin_end_mismatch)
2020f4a2713aSLionel Sambuc           << RangeLoc << BeginRange->getType() << *BEF;
2021f4a2713aSLionel Sambuc       return Sema::FRS_DiagnosticIssued;
2022f4a2713aSLionel Sambuc     }
2023f4a2713aSLionel Sambuc   } else {
2024f4a2713aSLionel Sambuc     // - otherwise, begin-expr and end-expr are begin(__range) and
2025f4a2713aSLionel Sambuc     //   end(__range), respectively, where begin and end are looked up with
2026f4a2713aSLionel Sambuc     //   argument-dependent lookup (3.4.2). For the purposes of this name
2027f4a2713aSLionel Sambuc     //   lookup, namespace std is an associated namespace.
2028f4a2713aSLionel Sambuc 
2029f4a2713aSLionel Sambuc   }
2030f4a2713aSLionel Sambuc 
2031f4a2713aSLionel Sambuc   *BEF = Sema::BEF_begin;
2032f4a2713aSLionel Sambuc   Sema::ForRangeStatus RangeStatus =
2033f4a2713aSLionel Sambuc       SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc, BeginVar,
2034f4a2713aSLionel Sambuc                                         Sema::BEF_begin, BeginNameInfo,
2035f4a2713aSLionel Sambuc                                         BeginMemberLookup, CandidateSet,
2036f4a2713aSLionel Sambuc                                         BeginRange, BeginExpr);
2037f4a2713aSLionel Sambuc 
2038f4a2713aSLionel Sambuc   if (RangeStatus != Sema::FRS_Success)
2039f4a2713aSLionel Sambuc     return RangeStatus;
2040f4a2713aSLionel Sambuc   if (FinishForRangeVarDecl(SemaRef, BeginVar, BeginExpr->get(), ColonLoc,
2041f4a2713aSLionel Sambuc                             diag::err_for_range_iter_deduction_failure)) {
2042f4a2713aSLionel Sambuc     NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF);
2043f4a2713aSLionel Sambuc     return Sema::FRS_DiagnosticIssued;
2044f4a2713aSLionel Sambuc   }
2045f4a2713aSLionel Sambuc 
2046f4a2713aSLionel Sambuc   *BEF = Sema::BEF_end;
2047f4a2713aSLionel Sambuc   RangeStatus =
2048f4a2713aSLionel Sambuc       SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc, EndVar,
2049f4a2713aSLionel Sambuc                                         Sema::BEF_end, EndNameInfo,
2050f4a2713aSLionel Sambuc                                         EndMemberLookup, CandidateSet,
2051f4a2713aSLionel Sambuc                                         EndRange, EndExpr);
2052f4a2713aSLionel Sambuc   if (RangeStatus != Sema::FRS_Success)
2053f4a2713aSLionel Sambuc     return RangeStatus;
2054f4a2713aSLionel Sambuc   if (FinishForRangeVarDecl(SemaRef, EndVar, EndExpr->get(), ColonLoc,
2055f4a2713aSLionel Sambuc                             diag::err_for_range_iter_deduction_failure)) {
2056f4a2713aSLionel Sambuc     NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF);
2057f4a2713aSLionel Sambuc     return Sema::FRS_DiagnosticIssued;
2058f4a2713aSLionel Sambuc   }
2059f4a2713aSLionel Sambuc   return Sema::FRS_Success;
2060f4a2713aSLionel Sambuc }
2061f4a2713aSLionel Sambuc 
2062f4a2713aSLionel Sambuc /// Speculatively attempt to dereference an invalid range expression.
2063f4a2713aSLionel Sambuc /// If the attempt fails, this function will return a valid, null StmtResult
2064f4a2713aSLionel Sambuc /// and emit no diagnostics.
RebuildForRangeWithDereference(Sema & SemaRef,Scope * S,SourceLocation ForLoc,Stmt * LoopVarDecl,SourceLocation ColonLoc,Expr * Range,SourceLocation RangeLoc,SourceLocation RParenLoc)2065f4a2713aSLionel Sambuc static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S,
2066f4a2713aSLionel Sambuc                                                  SourceLocation ForLoc,
2067f4a2713aSLionel Sambuc                                                  Stmt *LoopVarDecl,
2068f4a2713aSLionel Sambuc                                                  SourceLocation ColonLoc,
2069f4a2713aSLionel Sambuc                                                  Expr *Range,
2070f4a2713aSLionel Sambuc                                                  SourceLocation RangeLoc,
2071f4a2713aSLionel Sambuc                                                  SourceLocation RParenLoc) {
2072f4a2713aSLionel Sambuc   // Determine whether we can rebuild the for-range statement with a
2073f4a2713aSLionel Sambuc   // dereferenced range expression.
2074f4a2713aSLionel Sambuc   ExprResult AdjustedRange;
2075f4a2713aSLionel Sambuc   {
2076f4a2713aSLionel Sambuc     Sema::SFINAETrap Trap(SemaRef);
2077f4a2713aSLionel Sambuc 
2078f4a2713aSLionel Sambuc     AdjustedRange = SemaRef.BuildUnaryOp(S, RangeLoc, UO_Deref, Range);
2079f4a2713aSLionel Sambuc     if (AdjustedRange.isInvalid())
2080f4a2713aSLionel Sambuc       return StmtResult();
2081f4a2713aSLionel Sambuc 
2082f4a2713aSLionel Sambuc     StmtResult SR =
2083f4a2713aSLionel Sambuc       SemaRef.ActOnCXXForRangeStmt(ForLoc, LoopVarDecl, ColonLoc,
2084f4a2713aSLionel Sambuc                                    AdjustedRange.get(), RParenLoc,
2085f4a2713aSLionel Sambuc                                    Sema::BFRK_Check);
2086f4a2713aSLionel Sambuc     if (SR.isInvalid())
2087f4a2713aSLionel Sambuc       return StmtResult();
2088f4a2713aSLionel Sambuc   }
2089f4a2713aSLionel Sambuc 
2090f4a2713aSLionel Sambuc   // The attempt to dereference worked well enough that it could produce a valid
2091f4a2713aSLionel Sambuc   // loop. Produce a fixit, and rebuild the loop with diagnostics enabled, in
2092f4a2713aSLionel Sambuc   // case there are any other (non-fatal) problems with it.
2093f4a2713aSLionel Sambuc   SemaRef.Diag(RangeLoc, diag::err_for_range_dereference)
2094f4a2713aSLionel Sambuc     << Range->getType() << FixItHint::CreateInsertion(RangeLoc, "*");
2095f4a2713aSLionel Sambuc   return SemaRef.ActOnCXXForRangeStmt(ForLoc, LoopVarDecl, ColonLoc,
2096f4a2713aSLionel Sambuc                                       AdjustedRange.get(), RParenLoc,
2097f4a2713aSLionel Sambuc                                       Sema::BFRK_Rebuild);
2098f4a2713aSLionel Sambuc }
2099f4a2713aSLionel Sambuc 
2100f4a2713aSLionel Sambuc namespace {
2101f4a2713aSLionel Sambuc /// RAII object to automatically invalidate a declaration if an error occurs.
2102f4a2713aSLionel Sambuc struct InvalidateOnErrorScope {
InvalidateOnErrorScope__anon7fb9f6900511::InvalidateOnErrorScope2103f4a2713aSLionel Sambuc   InvalidateOnErrorScope(Sema &SemaRef, Decl *D, bool Enabled)
2104f4a2713aSLionel Sambuc       : Trap(SemaRef.Diags), D(D), Enabled(Enabled) {}
~InvalidateOnErrorScope__anon7fb9f6900511::InvalidateOnErrorScope2105f4a2713aSLionel Sambuc   ~InvalidateOnErrorScope() {
2106f4a2713aSLionel Sambuc     if (Enabled && Trap.hasErrorOccurred())
2107f4a2713aSLionel Sambuc       D->setInvalidDecl();
2108f4a2713aSLionel Sambuc   }
2109f4a2713aSLionel Sambuc 
2110f4a2713aSLionel Sambuc   DiagnosticErrorTrap Trap;
2111f4a2713aSLionel Sambuc   Decl *D;
2112f4a2713aSLionel Sambuc   bool Enabled;
2113f4a2713aSLionel Sambuc };
2114f4a2713aSLionel Sambuc }
2115f4a2713aSLionel Sambuc 
2116f4a2713aSLionel Sambuc /// BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement.
2117f4a2713aSLionel Sambuc StmtResult
BuildCXXForRangeStmt(SourceLocation ForLoc,SourceLocation ColonLoc,Stmt * RangeDecl,Stmt * BeginEnd,Expr * Cond,Expr * Inc,Stmt * LoopVarDecl,SourceLocation RParenLoc,BuildForRangeKind Kind)2118f4a2713aSLionel Sambuc Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
2119f4a2713aSLionel Sambuc                            Stmt *RangeDecl, Stmt *BeginEnd, Expr *Cond,
2120f4a2713aSLionel Sambuc                            Expr *Inc, Stmt *LoopVarDecl,
2121f4a2713aSLionel Sambuc                            SourceLocation RParenLoc, BuildForRangeKind Kind) {
2122f4a2713aSLionel Sambuc   Scope *S = getCurScope();
2123f4a2713aSLionel Sambuc 
2124f4a2713aSLionel Sambuc   DeclStmt *RangeDS = cast<DeclStmt>(RangeDecl);
2125f4a2713aSLionel Sambuc   VarDecl *RangeVar = cast<VarDecl>(RangeDS->getSingleDecl());
2126f4a2713aSLionel Sambuc   QualType RangeVarType = RangeVar->getType();
2127f4a2713aSLionel Sambuc 
2128f4a2713aSLionel Sambuc   DeclStmt *LoopVarDS = cast<DeclStmt>(LoopVarDecl);
2129f4a2713aSLionel Sambuc   VarDecl *LoopVar = cast<VarDecl>(LoopVarDS->getSingleDecl());
2130f4a2713aSLionel Sambuc 
2131f4a2713aSLionel Sambuc   // If we hit any errors, mark the loop variable as invalid if its type
2132f4a2713aSLionel Sambuc   // contains 'auto'.
2133f4a2713aSLionel Sambuc   InvalidateOnErrorScope Invalidate(*this, LoopVar,
2134f4a2713aSLionel Sambuc                                     LoopVar->getType()->isUndeducedType());
2135f4a2713aSLionel Sambuc 
2136f4a2713aSLionel Sambuc   StmtResult BeginEndDecl = BeginEnd;
2137f4a2713aSLionel Sambuc   ExprResult NotEqExpr = Cond, IncrExpr = Inc;
2138f4a2713aSLionel Sambuc 
2139f4a2713aSLionel Sambuc   if (RangeVarType->isDependentType()) {
2140f4a2713aSLionel Sambuc     // The range is implicitly used as a placeholder when it is dependent.
2141f4a2713aSLionel Sambuc     RangeVar->markUsed(Context);
2142f4a2713aSLionel Sambuc 
2143f4a2713aSLionel Sambuc     // Deduce any 'auto's in the loop variable as 'DependentTy'. We'll fill
2144f4a2713aSLionel Sambuc     // them in properly when we instantiate the loop.
2145f4a2713aSLionel Sambuc     if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check)
2146f4a2713aSLionel Sambuc       LoopVar->setType(SubstAutoType(LoopVar->getType(), Context.DependentTy));
2147f4a2713aSLionel Sambuc   } else if (!BeginEndDecl.get()) {
2148f4a2713aSLionel Sambuc     SourceLocation RangeLoc = RangeVar->getLocation();
2149f4a2713aSLionel Sambuc 
2150f4a2713aSLionel Sambuc     const QualType RangeVarNonRefType = RangeVarType.getNonReferenceType();
2151f4a2713aSLionel Sambuc 
2152f4a2713aSLionel Sambuc     ExprResult BeginRangeRef = BuildDeclRefExpr(RangeVar, RangeVarNonRefType,
2153f4a2713aSLionel Sambuc                                                 VK_LValue, ColonLoc);
2154f4a2713aSLionel Sambuc     if (BeginRangeRef.isInvalid())
2155f4a2713aSLionel Sambuc       return StmtError();
2156f4a2713aSLionel Sambuc 
2157f4a2713aSLionel Sambuc     ExprResult EndRangeRef = BuildDeclRefExpr(RangeVar, RangeVarNonRefType,
2158f4a2713aSLionel Sambuc                                               VK_LValue, ColonLoc);
2159f4a2713aSLionel Sambuc     if (EndRangeRef.isInvalid())
2160f4a2713aSLionel Sambuc       return StmtError();
2161f4a2713aSLionel Sambuc 
2162f4a2713aSLionel Sambuc     QualType AutoType = Context.getAutoDeductType();
2163f4a2713aSLionel Sambuc     Expr *Range = RangeVar->getInit();
2164f4a2713aSLionel Sambuc     if (!Range)
2165f4a2713aSLionel Sambuc       return StmtError();
2166f4a2713aSLionel Sambuc     QualType RangeType = Range->getType();
2167f4a2713aSLionel Sambuc 
2168f4a2713aSLionel Sambuc     if (RequireCompleteType(RangeLoc, RangeType,
2169f4a2713aSLionel Sambuc                             diag::err_for_range_incomplete_type))
2170f4a2713aSLionel Sambuc       return StmtError();
2171f4a2713aSLionel Sambuc 
2172f4a2713aSLionel Sambuc     // Build auto __begin = begin-expr, __end = end-expr.
2173f4a2713aSLionel Sambuc     VarDecl *BeginVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,
2174f4a2713aSLionel Sambuc                                              "__begin");
2175f4a2713aSLionel Sambuc     VarDecl *EndVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,
2176f4a2713aSLionel Sambuc                                            "__end");
2177f4a2713aSLionel Sambuc 
2178f4a2713aSLionel Sambuc     // Build begin-expr and end-expr and attach to __begin and __end variables.
2179f4a2713aSLionel Sambuc     ExprResult BeginExpr, EndExpr;
2180f4a2713aSLionel Sambuc     if (const ArrayType *UnqAT = RangeType->getAsArrayTypeUnsafe()) {
2181f4a2713aSLionel Sambuc       // - if _RangeT is an array type, begin-expr and end-expr are __range and
2182f4a2713aSLionel Sambuc       //   __range + __bound, respectively, where __bound is the array bound. If
2183f4a2713aSLionel Sambuc       //   _RangeT is an array of unknown size or an array of incomplete type,
2184f4a2713aSLionel Sambuc       //   the program is ill-formed;
2185f4a2713aSLionel Sambuc 
2186f4a2713aSLionel Sambuc       // begin-expr is __range.
2187f4a2713aSLionel Sambuc       BeginExpr = BeginRangeRef;
2188f4a2713aSLionel Sambuc       if (FinishForRangeVarDecl(*this, BeginVar, BeginRangeRef.get(), ColonLoc,
2189f4a2713aSLionel Sambuc                                 diag::err_for_range_iter_deduction_failure)) {
2190f4a2713aSLionel Sambuc         NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2191f4a2713aSLionel Sambuc         return StmtError();
2192f4a2713aSLionel Sambuc       }
2193f4a2713aSLionel Sambuc 
2194f4a2713aSLionel Sambuc       // Find the array bound.
2195f4a2713aSLionel Sambuc       ExprResult BoundExpr;
2196f4a2713aSLionel Sambuc       if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(UnqAT))
2197*0a6a1f1dSLionel Sambuc         BoundExpr = IntegerLiteral::Create(
2198*0a6a1f1dSLionel Sambuc             Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);
2199f4a2713aSLionel Sambuc       else if (const VariableArrayType *VAT =
2200f4a2713aSLionel Sambuc                dyn_cast<VariableArrayType>(UnqAT))
2201f4a2713aSLionel Sambuc         BoundExpr = VAT->getSizeExpr();
2202f4a2713aSLionel Sambuc       else {
2203f4a2713aSLionel Sambuc         // Can't be a DependentSizedArrayType or an IncompleteArrayType since
2204f4a2713aSLionel Sambuc         // UnqAT is not incomplete and Range is not type-dependent.
2205f4a2713aSLionel Sambuc         llvm_unreachable("Unexpected array type in for-range");
2206f4a2713aSLionel Sambuc       }
2207f4a2713aSLionel Sambuc 
2208f4a2713aSLionel Sambuc       // end-expr is __range + __bound.
2209f4a2713aSLionel Sambuc       EndExpr = ActOnBinOp(S, ColonLoc, tok::plus, EndRangeRef.get(),
2210f4a2713aSLionel Sambuc                            BoundExpr.get());
2211f4a2713aSLionel Sambuc       if (EndExpr.isInvalid())
2212f4a2713aSLionel Sambuc         return StmtError();
2213f4a2713aSLionel Sambuc       if (FinishForRangeVarDecl(*this, EndVar, EndExpr.get(), ColonLoc,
2214f4a2713aSLionel Sambuc                                 diag::err_for_range_iter_deduction_failure)) {
2215f4a2713aSLionel Sambuc         NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);
2216f4a2713aSLionel Sambuc         return StmtError();
2217f4a2713aSLionel Sambuc       }
2218f4a2713aSLionel Sambuc     } else {
2219*0a6a1f1dSLionel Sambuc       OverloadCandidateSet CandidateSet(RangeLoc,
2220*0a6a1f1dSLionel Sambuc                                         OverloadCandidateSet::CSK_Normal);
2221f4a2713aSLionel Sambuc       Sema::BeginEndFunction BEFFailure;
2222f4a2713aSLionel Sambuc       ForRangeStatus RangeStatus =
2223f4a2713aSLionel Sambuc           BuildNonArrayForRange(*this, S, BeginRangeRef.get(),
2224f4a2713aSLionel Sambuc                                 EndRangeRef.get(), RangeType,
2225f4a2713aSLionel Sambuc                                 BeginVar, EndVar, ColonLoc, &CandidateSet,
2226f4a2713aSLionel Sambuc                                 &BeginExpr, &EndExpr, &BEFFailure);
2227f4a2713aSLionel Sambuc 
2228f4a2713aSLionel Sambuc       if (Kind == BFRK_Build && RangeStatus == FRS_NoViableFunction &&
2229f4a2713aSLionel Sambuc           BEFFailure == BEF_begin) {
2230f4a2713aSLionel Sambuc         // If the range is being built from an array parameter, emit a
2231f4a2713aSLionel Sambuc         // a diagnostic that it is being treated as a pointer.
2232f4a2713aSLionel Sambuc         if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Range)) {
2233f4a2713aSLionel Sambuc           if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
2234f4a2713aSLionel Sambuc             QualType ArrayTy = PVD->getOriginalType();
2235f4a2713aSLionel Sambuc             QualType PointerTy = PVD->getType();
2236f4a2713aSLionel Sambuc             if (PointerTy->isPointerType() && ArrayTy->isArrayType()) {
2237f4a2713aSLionel Sambuc               Diag(Range->getLocStart(), diag::err_range_on_array_parameter)
2238f4a2713aSLionel Sambuc                 << RangeLoc << PVD << ArrayTy << PointerTy;
2239f4a2713aSLionel Sambuc               Diag(PVD->getLocation(), diag::note_declared_at);
2240f4a2713aSLionel Sambuc               return StmtError();
2241f4a2713aSLionel Sambuc             }
2242f4a2713aSLionel Sambuc           }
2243f4a2713aSLionel Sambuc         }
2244f4a2713aSLionel Sambuc 
2245f4a2713aSLionel Sambuc         // If building the range failed, try dereferencing the range expression
2246f4a2713aSLionel Sambuc         // unless a diagnostic was issued or the end function is problematic.
2247f4a2713aSLionel Sambuc         StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc,
2248f4a2713aSLionel Sambuc                                                        LoopVarDecl, ColonLoc,
2249f4a2713aSLionel Sambuc                                                        Range, RangeLoc,
2250f4a2713aSLionel Sambuc                                                        RParenLoc);
2251f4a2713aSLionel Sambuc         if (SR.isInvalid() || SR.isUsable())
2252f4a2713aSLionel Sambuc           return SR;
2253f4a2713aSLionel Sambuc       }
2254f4a2713aSLionel Sambuc 
2255f4a2713aSLionel Sambuc       // Otherwise, emit diagnostics if we haven't already.
2256f4a2713aSLionel Sambuc       if (RangeStatus == FRS_NoViableFunction) {
2257f4a2713aSLionel Sambuc         Expr *Range = BEFFailure ? EndRangeRef.get() : BeginRangeRef.get();
2258f4a2713aSLionel Sambuc         Diag(Range->getLocStart(), diag::err_for_range_invalid)
2259f4a2713aSLionel Sambuc             << RangeLoc << Range->getType() << BEFFailure;
2260f4a2713aSLionel Sambuc         CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Range);
2261f4a2713aSLionel Sambuc       }
2262f4a2713aSLionel Sambuc       // Return an error if no fix was discovered.
2263f4a2713aSLionel Sambuc       if (RangeStatus != FRS_Success)
2264f4a2713aSLionel Sambuc         return StmtError();
2265f4a2713aSLionel Sambuc     }
2266f4a2713aSLionel Sambuc 
2267f4a2713aSLionel Sambuc     assert(!BeginExpr.isInvalid() && !EndExpr.isInvalid() &&
2268f4a2713aSLionel Sambuc            "invalid range expression in for loop");
2269f4a2713aSLionel Sambuc 
2270f4a2713aSLionel Sambuc     // C++11 [dcl.spec.auto]p7: BeginType and EndType must be the same.
2271f4a2713aSLionel Sambuc     QualType BeginType = BeginVar->getType(), EndType = EndVar->getType();
2272f4a2713aSLionel Sambuc     if (!Context.hasSameType(BeginType, EndType)) {
2273f4a2713aSLionel Sambuc       Diag(RangeLoc, diag::err_for_range_begin_end_types_differ)
2274f4a2713aSLionel Sambuc         << BeginType << EndType;
2275f4a2713aSLionel Sambuc       NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2276f4a2713aSLionel Sambuc       NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);
2277f4a2713aSLionel Sambuc     }
2278f4a2713aSLionel Sambuc 
2279f4a2713aSLionel Sambuc     Decl *BeginEndDecls[] = { BeginVar, EndVar };
2280f4a2713aSLionel Sambuc     // Claim the type doesn't contain auto: we've already done the checking.
2281f4a2713aSLionel Sambuc     DeclGroupPtrTy BeginEndGroup =
2282*0a6a1f1dSLionel Sambuc         BuildDeclaratorGroup(MutableArrayRef<Decl *>(BeginEndDecls, 2),
2283f4a2713aSLionel Sambuc                              /*TypeMayContainAuto=*/ false);
2284f4a2713aSLionel Sambuc     BeginEndDecl = ActOnDeclStmt(BeginEndGroup, ColonLoc, ColonLoc);
2285f4a2713aSLionel Sambuc 
2286f4a2713aSLionel Sambuc     const QualType BeginRefNonRefType = BeginType.getNonReferenceType();
2287f4a2713aSLionel Sambuc     ExprResult BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,
2288f4a2713aSLionel Sambuc                                            VK_LValue, ColonLoc);
2289f4a2713aSLionel Sambuc     if (BeginRef.isInvalid())
2290f4a2713aSLionel Sambuc       return StmtError();
2291f4a2713aSLionel Sambuc 
2292f4a2713aSLionel Sambuc     ExprResult EndRef = BuildDeclRefExpr(EndVar, EndType.getNonReferenceType(),
2293f4a2713aSLionel Sambuc                                          VK_LValue, ColonLoc);
2294f4a2713aSLionel Sambuc     if (EndRef.isInvalid())
2295f4a2713aSLionel Sambuc       return StmtError();
2296f4a2713aSLionel Sambuc 
2297f4a2713aSLionel Sambuc     // Build and check __begin != __end expression.
2298f4a2713aSLionel Sambuc     NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,
2299f4a2713aSLionel Sambuc                            BeginRef.get(), EndRef.get());
2300f4a2713aSLionel Sambuc     NotEqExpr = ActOnBooleanCondition(S, ColonLoc, NotEqExpr.get());
2301f4a2713aSLionel Sambuc     NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
2302f4a2713aSLionel Sambuc     if (NotEqExpr.isInvalid()) {
2303f4a2713aSLionel Sambuc       Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2304f4a2713aSLionel Sambuc         << RangeLoc << 0 << BeginRangeRef.get()->getType();
2305f4a2713aSLionel Sambuc       NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2306f4a2713aSLionel Sambuc       if (!Context.hasSameType(BeginType, EndType))
2307f4a2713aSLionel Sambuc         NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);
2308f4a2713aSLionel Sambuc       return StmtError();
2309f4a2713aSLionel Sambuc     }
2310f4a2713aSLionel Sambuc 
2311f4a2713aSLionel Sambuc     // Build and check ++__begin expression.
2312f4a2713aSLionel Sambuc     BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,
2313f4a2713aSLionel Sambuc                                 VK_LValue, ColonLoc);
2314f4a2713aSLionel Sambuc     if (BeginRef.isInvalid())
2315f4a2713aSLionel Sambuc       return StmtError();
2316f4a2713aSLionel Sambuc 
2317f4a2713aSLionel Sambuc     IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get());
2318f4a2713aSLionel Sambuc     IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
2319f4a2713aSLionel Sambuc     if (IncrExpr.isInvalid()) {
2320f4a2713aSLionel Sambuc       Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2321f4a2713aSLionel Sambuc         << RangeLoc << 2 << BeginRangeRef.get()->getType() ;
2322f4a2713aSLionel Sambuc       NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2323f4a2713aSLionel Sambuc       return StmtError();
2324f4a2713aSLionel Sambuc     }
2325f4a2713aSLionel Sambuc 
2326f4a2713aSLionel Sambuc     // Build and check *__begin  expression.
2327f4a2713aSLionel Sambuc     BeginRef = BuildDeclRefExpr(BeginVar, BeginRefNonRefType,
2328f4a2713aSLionel Sambuc                                 VK_LValue, ColonLoc);
2329f4a2713aSLionel Sambuc     if (BeginRef.isInvalid())
2330f4a2713aSLionel Sambuc       return StmtError();
2331f4a2713aSLionel Sambuc 
2332f4a2713aSLionel Sambuc     ExprResult DerefExpr = ActOnUnaryOp(S, ColonLoc, tok::star, BeginRef.get());
2333f4a2713aSLionel Sambuc     if (DerefExpr.isInvalid()) {
2334f4a2713aSLionel Sambuc       Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2335f4a2713aSLionel Sambuc         << RangeLoc << 1 << BeginRangeRef.get()->getType();
2336f4a2713aSLionel Sambuc       NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2337f4a2713aSLionel Sambuc       return StmtError();
2338f4a2713aSLionel Sambuc     }
2339f4a2713aSLionel Sambuc 
2340f4a2713aSLionel Sambuc     // Attach  *__begin  as initializer for VD. Don't touch it if we're just
2341f4a2713aSLionel Sambuc     // trying to determine whether this would be a valid range.
2342f4a2713aSLionel Sambuc     if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) {
2343f4a2713aSLionel Sambuc       AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false,
2344f4a2713aSLionel Sambuc                            /*TypeMayContainAuto=*/true);
2345f4a2713aSLionel Sambuc       if (LoopVar->isInvalidDecl())
2346f4a2713aSLionel Sambuc         NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2347f4a2713aSLionel Sambuc     }
2348f4a2713aSLionel Sambuc   }
2349f4a2713aSLionel Sambuc 
2350f4a2713aSLionel Sambuc   // Don't bother to actually allocate the result if we're just trying to
2351f4a2713aSLionel Sambuc   // determine whether it would be valid.
2352f4a2713aSLionel Sambuc   if (Kind == BFRK_Check)
2353f4a2713aSLionel Sambuc     return StmtResult();
2354f4a2713aSLionel Sambuc 
2355*0a6a1f1dSLionel Sambuc   return new (Context) CXXForRangeStmt(
2356*0a6a1f1dSLionel Sambuc       RangeDS, cast_or_null<DeclStmt>(BeginEndDecl.get()), NotEqExpr.get(),
2357*0a6a1f1dSLionel Sambuc       IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, ColonLoc, RParenLoc);
2358f4a2713aSLionel Sambuc }
2359f4a2713aSLionel Sambuc 
2360f4a2713aSLionel Sambuc /// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach
2361f4a2713aSLionel Sambuc /// statement.
FinishObjCForCollectionStmt(Stmt * S,Stmt * B)2362f4a2713aSLionel Sambuc StmtResult Sema::FinishObjCForCollectionStmt(Stmt *S, Stmt *B) {
2363f4a2713aSLionel Sambuc   if (!S || !B)
2364f4a2713aSLionel Sambuc     return StmtError();
2365f4a2713aSLionel Sambuc   ObjCForCollectionStmt * ForStmt = cast<ObjCForCollectionStmt>(S);
2366f4a2713aSLionel Sambuc 
2367f4a2713aSLionel Sambuc   ForStmt->setBody(B);
2368f4a2713aSLionel Sambuc   return S;
2369f4a2713aSLionel Sambuc }
2370f4a2713aSLionel Sambuc 
2371f4a2713aSLionel Sambuc /// FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
2372f4a2713aSLionel Sambuc /// This is a separate step from ActOnCXXForRangeStmt because analysis of the
2373f4a2713aSLionel Sambuc /// body cannot be performed until after the type of the range variable is
2374f4a2713aSLionel Sambuc /// determined.
FinishCXXForRangeStmt(Stmt * S,Stmt * B)2375f4a2713aSLionel Sambuc StmtResult Sema::FinishCXXForRangeStmt(Stmt *S, Stmt *B) {
2376f4a2713aSLionel Sambuc   if (!S || !B)
2377f4a2713aSLionel Sambuc     return StmtError();
2378f4a2713aSLionel Sambuc 
2379f4a2713aSLionel Sambuc   if (isa<ObjCForCollectionStmt>(S))
2380f4a2713aSLionel Sambuc     return FinishObjCForCollectionStmt(S, B);
2381f4a2713aSLionel Sambuc 
2382f4a2713aSLionel Sambuc   CXXForRangeStmt *ForStmt = cast<CXXForRangeStmt>(S);
2383f4a2713aSLionel Sambuc   ForStmt->setBody(B);
2384f4a2713aSLionel Sambuc 
2385f4a2713aSLionel Sambuc   DiagnoseEmptyStmtBody(ForStmt->getRParenLoc(), B,
2386f4a2713aSLionel Sambuc                         diag::warn_empty_range_based_for_body);
2387f4a2713aSLionel Sambuc 
2388f4a2713aSLionel Sambuc   return S;
2389f4a2713aSLionel Sambuc }
2390f4a2713aSLionel Sambuc 
ActOnGotoStmt(SourceLocation GotoLoc,SourceLocation LabelLoc,LabelDecl * TheDecl)2391f4a2713aSLionel Sambuc StmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc,
2392f4a2713aSLionel Sambuc                                SourceLocation LabelLoc,
2393f4a2713aSLionel Sambuc                                LabelDecl *TheDecl) {
2394f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchIntoScope();
2395f4a2713aSLionel Sambuc   TheDecl->markUsed(Context);
2396*0a6a1f1dSLionel Sambuc   return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
2397f4a2713aSLionel Sambuc }
2398f4a2713aSLionel Sambuc 
2399f4a2713aSLionel Sambuc StmtResult
ActOnIndirectGotoStmt(SourceLocation GotoLoc,SourceLocation StarLoc,Expr * E)2400f4a2713aSLionel Sambuc Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
2401f4a2713aSLionel Sambuc                             Expr *E) {
2402f4a2713aSLionel Sambuc   // Convert operand to void*
2403f4a2713aSLionel Sambuc   if (!E->isTypeDependent()) {
2404f4a2713aSLionel Sambuc     QualType ETy = E->getType();
2405f4a2713aSLionel Sambuc     QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
2406*0a6a1f1dSLionel Sambuc     ExprResult ExprRes = E;
2407f4a2713aSLionel Sambuc     AssignConvertType ConvTy =
2408f4a2713aSLionel Sambuc       CheckSingleAssignmentConstraints(DestTy, ExprRes);
2409f4a2713aSLionel Sambuc     if (ExprRes.isInvalid())
2410f4a2713aSLionel Sambuc       return StmtError();
2411*0a6a1f1dSLionel Sambuc     E = ExprRes.get();
2412f4a2713aSLionel Sambuc     if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
2413f4a2713aSLionel Sambuc       return StmtError();
2414f4a2713aSLionel Sambuc   }
2415f4a2713aSLionel Sambuc 
2416f4a2713aSLionel Sambuc   ExprResult ExprRes = ActOnFinishFullExpr(E);
2417f4a2713aSLionel Sambuc   if (ExprRes.isInvalid())
2418f4a2713aSLionel Sambuc     return StmtError();
2419*0a6a1f1dSLionel Sambuc   E = ExprRes.get();
2420f4a2713aSLionel Sambuc 
2421f4a2713aSLionel Sambuc   getCurFunction()->setHasIndirectGoto();
2422f4a2713aSLionel Sambuc 
2423*0a6a1f1dSLionel Sambuc   return new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E);
2424f4a2713aSLionel Sambuc }
2425f4a2713aSLionel Sambuc 
2426f4a2713aSLionel Sambuc StmtResult
ActOnContinueStmt(SourceLocation ContinueLoc,Scope * CurScope)2427f4a2713aSLionel Sambuc Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
2428f4a2713aSLionel Sambuc   Scope *S = CurScope->getContinueParent();
2429f4a2713aSLionel Sambuc   if (!S) {
2430f4a2713aSLionel Sambuc     // C99 6.8.6.2p1: A break shall appear only in or as a loop body.
2431f4a2713aSLionel Sambuc     return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
2432f4a2713aSLionel Sambuc   }
2433f4a2713aSLionel Sambuc 
2434*0a6a1f1dSLionel Sambuc   return new (Context) ContinueStmt(ContinueLoc);
2435f4a2713aSLionel Sambuc }
2436f4a2713aSLionel Sambuc 
2437f4a2713aSLionel Sambuc StmtResult
ActOnBreakStmt(SourceLocation BreakLoc,Scope * CurScope)2438f4a2713aSLionel Sambuc Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
2439f4a2713aSLionel Sambuc   Scope *S = CurScope->getBreakParent();
2440f4a2713aSLionel Sambuc   if (!S) {
2441f4a2713aSLionel Sambuc     // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
2442f4a2713aSLionel Sambuc     return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
2443f4a2713aSLionel Sambuc   }
2444*0a6a1f1dSLionel Sambuc   if (S->isOpenMPLoopScope())
2445*0a6a1f1dSLionel Sambuc     return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
2446*0a6a1f1dSLionel Sambuc                      << "break");
2447f4a2713aSLionel Sambuc 
2448*0a6a1f1dSLionel Sambuc   return new (Context) BreakStmt(BreakLoc);
2449f4a2713aSLionel Sambuc }
2450f4a2713aSLionel Sambuc 
2451f4a2713aSLionel Sambuc /// \brief Determine whether the given expression is a candidate for
2452f4a2713aSLionel Sambuc /// copy elision in either a return statement or a throw expression.
2453f4a2713aSLionel Sambuc ///
2454f4a2713aSLionel Sambuc /// \param ReturnType If we're determining the copy elision candidate for
2455f4a2713aSLionel Sambuc /// a return statement, this is the return type of the function. If we're
2456f4a2713aSLionel Sambuc /// determining the copy elision candidate for a throw expression, this will
2457f4a2713aSLionel Sambuc /// be a NULL type.
2458f4a2713aSLionel Sambuc ///
2459f4a2713aSLionel Sambuc /// \param E The expression being returned from the function or block, or
2460f4a2713aSLionel Sambuc /// being thrown.
2461f4a2713aSLionel Sambuc ///
2462f4a2713aSLionel Sambuc /// \param AllowFunctionParameter Whether we allow function parameters to
2463f4a2713aSLionel Sambuc /// be considered NRVO candidates. C++ prohibits this for NRVO itself, but
2464f4a2713aSLionel Sambuc /// we re-use this logic to determine whether we should try to move as part of
2465f4a2713aSLionel Sambuc /// a return or throw (which does allow function parameters).
2466f4a2713aSLionel Sambuc ///
2467f4a2713aSLionel Sambuc /// \returns The NRVO candidate variable, if the return statement may use the
2468f4a2713aSLionel Sambuc /// NRVO, or NULL if there is no such candidate.
getCopyElisionCandidate(QualType ReturnType,Expr * E,bool AllowFunctionParameter)2469*0a6a1f1dSLionel Sambuc VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,
2470f4a2713aSLionel Sambuc                                        Expr *E,
2471f4a2713aSLionel Sambuc                                        bool AllowFunctionParameter) {
2472*0a6a1f1dSLionel Sambuc   if (!getLangOpts().CPlusPlus)
2473*0a6a1f1dSLionel Sambuc     return nullptr;
2474*0a6a1f1dSLionel Sambuc 
2475*0a6a1f1dSLionel Sambuc   // - in a return statement in a function [where] ...
2476*0a6a1f1dSLionel Sambuc   // ... the expression is the name of a non-volatile automatic object ...
2477*0a6a1f1dSLionel Sambuc   DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
2478*0a6a1f1dSLionel Sambuc   if (!DR || DR->refersToEnclosingVariableOrCapture())
2479*0a6a1f1dSLionel Sambuc     return nullptr;
2480*0a6a1f1dSLionel Sambuc   VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
2481*0a6a1f1dSLionel Sambuc   if (!VD)
2482*0a6a1f1dSLionel Sambuc     return nullptr;
2483*0a6a1f1dSLionel Sambuc 
2484*0a6a1f1dSLionel Sambuc   if (isCopyElisionCandidate(ReturnType, VD, AllowFunctionParameter))
2485*0a6a1f1dSLionel Sambuc     return VD;
2486*0a6a1f1dSLionel Sambuc   return nullptr;
2487f4a2713aSLionel Sambuc }
2488f4a2713aSLionel Sambuc 
isCopyElisionCandidate(QualType ReturnType,const VarDecl * VD,bool AllowFunctionParameter)2489*0a6a1f1dSLionel Sambuc bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
2490*0a6a1f1dSLionel Sambuc                                   bool AllowFunctionParameter) {
2491*0a6a1f1dSLionel Sambuc   QualType VDType = VD->getType();
2492*0a6a1f1dSLionel Sambuc   // - in a return statement in a function with ...
2493*0a6a1f1dSLionel Sambuc   // ... a class return type ...
2494*0a6a1f1dSLionel Sambuc   if (!ReturnType.isNull() && !ReturnType->isDependentType()) {
2495*0a6a1f1dSLionel Sambuc     if (!ReturnType->isRecordType())
2496*0a6a1f1dSLionel Sambuc       return false;
2497*0a6a1f1dSLionel Sambuc     // ... the same cv-unqualified type as the function return type ...
2498*0a6a1f1dSLionel Sambuc     if (!VDType->isDependentType() &&
2499*0a6a1f1dSLionel Sambuc         !Context.hasSameUnqualifiedType(ReturnType, VDType))
2500*0a6a1f1dSLionel Sambuc       return false;
2501*0a6a1f1dSLionel Sambuc   }
2502f4a2713aSLionel Sambuc 
2503f4a2713aSLionel Sambuc   // ...object (other than a function or catch-clause parameter)...
2504f4a2713aSLionel Sambuc   if (VD->getKind() != Decl::Var &&
2505f4a2713aSLionel Sambuc       !(AllowFunctionParameter && VD->getKind() == Decl::ParmVar))
2506*0a6a1f1dSLionel Sambuc     return false;
2507*0a6a1f1dSLionel Sambuc   if (VD->isExceptionVariable()) return false;
2508f4a2713aSLionel Sambuc 
2509f4a2713aSLionel Sambuc   // ...automatic...
2510*0a6a1f1dSLionel Sambuc   if (!VD->hasLocalStorage()) return false;
2511f4a2713aSLionel Sambuc 
2512f4a2713aSLionel Sambuc   // ...non-volatile...
2513*0a6a1f1dSLionel Sambuc   if (VD->getType().isVolatileQualified()) return false;
2514f4a2713aSLionel Sambuc 
2515f4a2713aSLionel Sambuc   // __block variables can't be allocated in a way that permits NRVO.
2516*0a6a1f1dSLionel Sambuc   if (VD->hasAttr<BlocksAttr>()) return false;
2517f4a2713aSLionel Sambuc 
2518f4a2713aSLionel Sambuc   // Variables with higher required alignment than their type's ABI
2519f4a2713aSLionel Sambuc   // alignment cannot use NRVO.
2520*0a6a1f1dSLionel Sambuc   if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
2521f4a2713aSLionel Sambuc       Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType()))
2522*0a6a1f1dSLionel Sambuc     return false;
2523f4a2713aSLionel Sambuc 
2524*0a6a1f1dSLionel Sambuc   return true;
2525f4a2713aSLionel Sambuc }
2526f4a2713aSLionel Sambuc 
2527f4a2713aSLionel Sambuc /// \brief Perform the initialization of a potentially-movable value, which
2528f4a2713aSLionel Sambuc /// is the result of return value.
2529f4a2713aSLionel Sambuc ///
2530f4a2713aSLionel Sambuc /// This routine implements C++0x [class.copy]p33, which attempts to treat
2531f4a2713aSLionel Sambuc /// returned lvalues as rvalues in certain cases (to prefer move construction),
2532f4a2713aSLionel Sambuc /// then falls back to treating them as lvalues if that failed.
2533f4a2713aSLionel Sambuc ExprResult
PerformMoveOrCopyInitialization(const InitializedEntity & Entity,const VarDecl * NRVOCandidate,QualType ResultType,Expr * Value,bool AllowNRVO)2534f4a2713aSLionel Sambuc Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
2535f4a2713aSLionel Sambuc                                       const VarDecl *NRVOCandidate,
2536f4a2713aSLionel Sambuc                                       QualType ResultType,
2537f4a2713aSLionel Sambuc                                       Expr *Value,
2538f4a2713aSLionel Sambuc                                       bool AllowNRVO) {
2539f4a2713aSLionel Sambuc   // C++0x [class.copy]p33:
2540f4a2713aSLionel Sambuc   //   When the criteria for elision of a copy operation are met or would
2541f4a2713aSLionel Sambuc   //   be met save for the fact that the source object is a function
2542f4a2713aSLionel Sambuc   //   parameter, and the object to be copied is designated by an lvalue,
2543f4a2713aSLionel Sambuc   //   overload resolution to select the constructor for the copy is first
2544f4a2713aSLionel Sambuc   //   performed as if the object were designated by an rvalue.
2545f4a2713aSLionel Sambuc   ExprResult Res = ExprError();
2546f4a2713aSLionel Sambuc   if (AllowNRVO &&
2547f4a2713aSLionel Sambuc       (NRVOCandidate || getCopyElisionCandidate(ResultType, Value, true))) {
2548f4a2713aSLionel Sambuc     ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack,
2549f4a2713aSLionel Sambuc                               Value->getType(), CK_NoOp, Value, VK_XValue);
2550f4a2713aSLionel Sambuc 
2551f4a2713aSLionel Sambuc     Expr *InitExpr = &AsRvalue;
2552f4a2713aSLionel Sambuc     InitializationKind Kind
2553f4a2713aSLionel Sambuc       = InitializationKind::CreateCopy(Value->getLocStart(),
2554f4a2713aSLionel Sambuc                                        Value->getLocStart());
2555f4a2713aSLionel Sambuc     InitializationSequence Seq(*this, Entity, Kind, InitExpr);
2556f4a2713aSLionel Sambuc 
2557f4a2713aSLionel Sambuc     //   [...] If overload resolution fails, or if the type of the first
2558f4a2713aSLionel Sambuc     //   parameter of the selected constructor is not an rvalue reference
2559f4a2713aSLionel Sambuc     //   to the object's type (possibly cv-qualified), overload resolution
2560f4a2713aSLionel Sambuc     //   is performed again, considering the object as an lvalue.
2561f4a2713aSLionel Sambuc     if (Seq) {
2562f4a2713aSLionel Sambuc       for (InitializationSequence::step_iterator Step = Seq.step_begin(),
2563f4a2713aSLionel Sambuc            StepEnd = Seq.step_end();
2564f4a2713aSLionel Sambuc            Step != StepEnd; ++Step) {
2565f4a2713aSLionel Sambuc         if (Step->Kind != InitializationSequence::SK_ConstructorInitialization)
2566f4a2713aSLionel Sambuc           continue;
2567f4a2713aSLionel Sambuc 
2568f4a2713aSLionel Sambuc         CXXConstructorDecl *Constructor
2569f4a2713aSLionel Sambuc         = cast<CXXConstructorDecl>(Step->Function.Function);
2570f4a2713aSLionel Sambuc 
2571f4a2713aSLionel Sambuc         const RValueReferenceType *RRefType
2572f4a2713aSLionel Sambuc           = Constructor->getParamDecl(0)->getType()
2573f4a2713aSLionel Sambuc                                                  ->getAs<RValueReferenceType>();
2574f4a2713aSLionel Sambuc 
2575f4a2713aSLionel Sambuc         // If we don't meet the criteria, break out now.
2576f4a2713aSLionel Sambuc         if (!RRefType ||
2577f4a2713aSLionel Sambuc             !Context.hasSameUnqualifiedType(RRefType->getPointeeType(),
2578f4a2713aSLionel Sambuc                             Context.getTypeDeclType(Constructor->getParent())))
2579f4a2713aSLionel Sambuc           break;
2580f4a2713aSLionel Sambuc 
2581f4a2713aSLionel Sambuc         // Promote "AsRvalue" to the heap, since we now need this
2582f4a2713aSLionel Sambuc         // expression node to persist.
2583f4a2713aSLionel Sambuc         Value = ImplicitCastExpr::Create(Context, Value->getType(),
2584*0a6a1f1dSLionel Sambuc                                          CK_NoOp, Value, nullptr, VK_XValue);
2585f4a2713aSLionel Sambuc 
2586f4a2713aSLionel Sambuc         // Complete type-checking the initialization of the return type
2587f4a2713aSLionel Sambuc         // using the constructor we found.
2588f4a2713aSLionel Sambuc         Res = Seq.Perform(*this, Entity, Kind, Value);
2589f4a2713aSLionel Sambuc       }
2590f4a2713aSLionel Sambuc     }
2591f4a2713aSLionel Sambuc   }
2592f4a2713aSLionel Sambuc 
2593f4a2713aSLionel Sambuc   // Either we didn't meet the criteria for treating an lvalue as an rvalue,
2594f4a2713aSLionel Sambuc   // above, or overload resolution failed. Either way, we need to try
2595f4a2713aSLionel Sambuc   // (again) now with the return value expression as written.
2596f4a2713aSLionel Sambuc   if (Res.isInvalid())
2597f4a2713aSLionel Sambuc     Res = PerformCopyInitialization(Entity, SourceLocation(), Value);
2598f4a2713aSLionel Sambuc 
2599f4a2713aSLionel Sambuc   return Res;
2600f4a2713aSLionel Sambuc }
2601f4a2713aSLionel Sambuc 
2602f4a2713aSLionel Sambuc /// \brief Determine whether the declared return type of the specified function
2603f4a2713aSLionel Sambuc /// contains 'auto'.
hasDeducedReturnType(FunctionDecl * FD)2604f4a2713aSLionel Sambuc static bool hasDeducedReturnType(FunctionDecl *FD) {
2605f4a2713aSLionel Sambuc   const FunctionProtoType *FPT =
2606f4a2713aSLionel Sambuc       FD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>();
2607*0a6a1f1dSLionel Sambuc   return FPT->getReturnType()->isUndeducedType();
2608f4a2713aSLionel Sambuc }
2609f4a2713aSLionel Sambuc 
2610f4a2713aSLionel Sambuc /// ActOnCapScopeReturnStmt - Utility routine to type-check return statements
2611f4a2713aSLionel Sambuc /// for capturing scopes.
2612f4a2713aSLionel Sambuc ///
2613f4a2713aSLionel Sambuc StmtResult
ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,Expr * RetValExp)2614f4a2713aSLionel Sambuc Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
2615f4a2713aSLionel Sambuc   // If this is the first return we've seen, infer the return type.
2616f4a2713aSLionel Sambuc   // [expr.prim.lambda]p4 in C++11; block literals follow the same rules.
2617f4a2713aSLionel Sambuc   CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
2618f4a2713aSLionel Sambuc   QualType FnRetType = CurCap->ReturnType;
2619f4a2713aSLionel Sambuc   LambdaScopeInfo *CurLambda = dyn_cast<LambdaScopeInfo>(CurCap);
2620f4a2713aSLionel Sambuc 
2621f4a2713aSLionel Sambuc   if (CurLambda && hasDeducedReturnType(CurLambda->CallOperator)) {
2622f4a2713aSLionel Sambuc     // In C++1y, the return type may involve 'auto'.
2623f4a2713aSLionel Sambuc     // FIXME: Blocks might have a return type of 'auto' explicitly specified.
2624f4a2713aSLionel Sambuc     FunctionDecl *FD = CurLambda->CallOperator;
2625f4a2713aSLionel Sambuc     if (CurCap->ReturnType.isNull())
2626*0a6a1f1dSLionel Sambuc       CurCap->ReturnType = FD->getReturnType();
2627f4a2713aSLionel Sambuc 
2628f4a2713aSLionel Sambuc     AutoType *AT = CurCap->ReturnType->getContainedAutoType();
2629f4a2713aSLionel Sambuc     assert(AT && "lost auto type from lambda return type");
2630f4a2713aSLionel Sambuc     if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
2631f4a2713aSLionel Sambuc       FD->setInvalidDecl();
2632f4a2713aSLionel Sambuc       return StmtError();
2633f4a2713aSLionel Sambuc     }
2634*0a6a1f1dSLionel Sambuc     CurCap->ReturnType = FnRetType = FD->getReturnType();
2635f4a2713aSLionel Sambuc   } else if (CurCap->HasImplicitReturnType) {
2636f4a2713aSLionel Sambuc     // For blocks/lambdas with implicit return types, we check each return
2637f4a2713aSLionel Sambuc     // statement individually, and deduce the common return type when the block
2638f4a2713aSLionel Sambuc     // or lambda is completed.
2639f4a2713aSLionel Sambuc     // FIXME: Fold this into the 'auto' codepath above.
2640f4a2713aSLionel Sambuc     if (RetValExp && !isa<InitListExpr>(RetValExp)) {
2641f4a2713aSLionel Sambuc       ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
2642f4a2713aSLionel Sambuc       if (Result.isInvalid())
2643f4a2713aSLionel Sambuc         return StmtError();
2644*0a6a1f1dSLionel Sambuc       RetValExp = Result.get();
2645f4a2713aSLionel Sambuc 
2646*0a6a1f1dSLionel Sambuc       // DR1048: even prior to C++14, we should use the 'auto' deduction rules
2647*0a6a1f1dSLionel Sambuc       // when deducing a return type for a lambda-expression (or by extension
2648*0a6a1f1dSLionel Sambuc       // for a block). These rules differ from the stated C++11 rules only in
2649*0a6a1f1dSLionel Sambuc       // that they remove top-level cv-qualifiers.
2650f4a2713aSLionel Sambuc       if (!CurContext->isDependentContext())
2651*0a6a1f1dSLionel Sambuc         FnRetType = RetValExp->getType().getUnqualifiedType();
2652f4a2713aSLionel Sambuc       else
2653f4a2713aSLionel Sambuc         FnRetType = CurCap->ReturnType = Context.DependentTy;
2654f4a2713aSLionel Sambuc     } else {
2655f4a2713aSLionel Sambuc       if (RetValExp) {
2656f4a2713aSLionel Sambuc         // C++11 [expr.lambda.prim]p4 bans inferring the result from an
2657f4a2713aSLionel Sambuc         // initializer list, because it is not an expression (even
2658f4a2713aSLionel Sambuc         // though we represent it as one). We still deduce 'void'.
2659f4a2713aSLionel Sambuc         Diag(ReturnLoc, diag::err_lambda_return_init_list)
2660f4a2713aSLionel Sambuc           << RetValExp->getSourceRange();
2661f4a2713aSLionel Sambuc       }
2662f4a2713aSLionel Sambuc 
2663f4a2713aSLionel Sambuc       FnRetType = Context.VoidTy;
2664f4a2713aSLionel Sambuc     }
2665f4a2713aSLionel Sambuc 
2666f4a2713aSLionel Sambuc     // Although we'll properly infer the type of the block once it's completed,
2667f4a2713aSLionel Sambuc     // make sure we provide a return type now for better error recovery.
2668f4a2713aSLionel Sambuc     if (CurCap->ReturnType.isNull())
2669f4a2713aSLionel Sambuc       CurCap->ReturnType = FnRetType;
2670f4a2713aSLionel Sambuc   }
2671f4a2713aSLionel Sambuc   assert(!FnRetType.isNull());
2672f4a2713aSLionel Sambuc 
2673f4a2713aSLionel Sambuc   if (BlockScopeInfo *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
2674f4a2713aSLionel Sambuc     if (CurBlock->FunctionType->getAs<FunctionType>()->getNoReturnAttr()) {
2675f4a2713aSLionel Sambuc       Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr);
2676f4a2713aSLionel Sambuc       return StmtError();
2677f4a2713aSLionel Sambuc     }
2678f4a2713aSLionel Sambuc   } else if (CapturedRegionScopeInfo *CurRegion =
2679f4a2713aSLionel Sambuc                  dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
2680f4a2713aSLionel Sambuc     Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();
2681f4a2713aSLionel Sambuc     return StmtError();
2682f4a2713aSLionel Sambuc   } else {
2683f4a2713aSLionel Sambuc     assert(CurLambda && "unknown kind of captured scope");
2684f4a2713aSLionel Sambuc     if (CurLambda->CallOperator->getType()->getAs<FunctionType>()
2685f4a2713aSLionel Sambuc             ->getNoReturnAttr()) {
2686f4a2713aSLionel Sambuc       Diag(ReturnLoc, diag::err_noreturn_lambda_has_return_expr);
2687f4a2713aSLionel Sambuc       return StmtError();
2688f4a2713aSLionel Sambuc     }
2689f4a2713aSLionel Sambuc   }
2690f4a2713aSLionel Sambuc 
2691f4a2713aSLionel Sambuc   // Otherwise, verify that this result type matches the previous one.  We are
2692f4a2713aSLionel Sambuc   // pickier with blocks than for normal functions because we don't have GCC
2693f4a2713aSLionel Sambuc   // compatibility to worry about here.
2694*0a6a1f1dSLionel Sambuc   const VarDecl *NRVOCandidate = nullptr;
2695f4a2713aSLionel Sambuc   if (FnRetType->isDependentType()) {
2696f4a2713aSLionel Sambuc     // Delay processing for now.  TODO: there are lots of dependent
2697f4a2713aSLionel Sambuc     // types we can conclusively prove aren't void.
2698f4a2713aSLionel Sambuc   } else if (FnRetType->isVoidType()) {
2699f4a2713aSLionel Sambuc     if (RetValExp && !isa<InitListExpr>(RetValExp) &&
2700f4a2713aSLionel Sambuc         !(getLangOpts().CPlusPlus &&
2701f4a2713aSLionel Sambuc           (RetValExp->isTypeDependent() ||
2702f4a2713aSLionel Sambuc            RetValExp->getType()->isVoidType()))) {
2703f4a2713aSLionel Sambuc       if (!getLangOpts().CPlusPlus &&
2704f4a2713aSLionel Sambuc           RetValExp->getType()->isVoidType())
2705f4a2713aSLionel Sambuc         Diag(ReturnLoc, diag::ext_return_has_void_expr) << "literal" << 2;
2706f4a2713aSLionel Sambuc       else {
2707f4a2713aSLionel Sambuc         Diag(ReturnLoc, diag::err_return_block_has_expr);
2708*0a6a1f1dSLionel Sambuc         RetValExp = nullptr;
2709f4a2713aSLionel Sambuc       }
2710f4a2713aSLionel Sambuc     }
2711f4a2713aSLionel Sambuc   } else if (!RetValExp) {
2712f4a2713aSLionel Sambuc     return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
2713f4a2713aSLionel Sambuc   } else if (!RetValExp->isTypeDependent()) {
2714f4a2713aSLionel Sambuc     // we have a non-void block with an expression, continue checking
2715f4a2713aSLionel Sambuc 
2716f4a2713aSLionel Sambuc     // C99 6.8.6.4p3(136): The return statement is not an assignment. The
2717f4a2713aSLionel Sambuc     // overlap restriction of subclause 6.5.16.1 does not apply to the case of
2718f4a2713aSLionel Sambuc     // function return.
2719f4a2713aSLionel Sambuc 
2720f4a2713aSLionel Sambuc     // In C++ the return statement is handled via a copy initialization.
2721f4a2713aSLionel Sambuc     // the C version of which boils down to CheckSingleAssignmentConstraints.
2722f4a2713aSLionel Sambuc     NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
2723f4a2713aSLionel Sambuc     InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
2724f4a2713aSLionel Sambuc                                                                    FnRetType,
2725*0a6a1f1dSLionel Sambuc                                                       NRVOCandidate != nullptr);
2726f4a2713aSLionel Sambuc     ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
2727f4a2713aSLionel Sambuc                                                      FnRetType, RetValExp);
2728f4a2713aSLionel Sambuc     if (Res.isInvalid()) {
2729f4a2713aSLionel Sambuc       // FIXME: Cleanup temporaries here, anyway?
2730f4a2713aSLionel Sambuc       return StmtError();
2731f4a2713aSLionel Sambuc     }
2732*0a6a1f1dSLionel Sambuc     RetValExp = Res.get();
2733*0a6a1f1dSLionel Sambuc     CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
2734*0a6a1f1dSLionel Sambuc   } else {
2735*0a6a1f1dSLionel Sambuc     NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
2736f4a2713aSLionel Sambuc   }
2737f4a2713aSLionel Sambuc 
2738f4a2713aSLionel Sambuc   if (RetValExp) {
2739f4a2713aSLionel Sambuc     ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
2740f4a2713aSLionel Sambuc     if (ER.isInvalid())
2741f4a2713aSLionel Sambuc       return StmtError();
2742*0a6a1f1dSLionel Sambuc     RetValExp = ER.get();
2743f4a2713aSLionel Sambuc   }
2744f4a2713aSLionel Sambuc   ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp,
2745f4a2713aSLionel Sambuc                                                 NRVOCandidate);
2746f4a2713aSLionel Sambuc 
2747f4a2713aSLionel Sambuc   // If we need to check for the named return value optimization,
2748f4a2713aSLionel Sambuc   // or if we need to infer the return type,
2749f4a2713aSLionel Sambuc   // save the return statement in our scope for later processing.
2750*0a6a1f1dSLionel Sambuc   if (CurCap->HasImplicitReturnType || NRVOCandidate)
2751f4a2713aSLionel Sambuc     FunctionScopes.back()->Returns.push_back(Result);
2752f4a2713aSLionel Sambuc 
2753*0a6a1f1dSLionel Sambuc   return Result;
2754*0a6a1f1dSLionel Sambuc }
2755*0a6a1f1dSLionel Sambuc 
2756*0a6a1f1dSLionel Sambuc namespace {
2757*0a6a1f1dSLionel Sambuc /// \brief Marks all typedefs in all local classes in a type referenced.
2758*0a6a1f1dSLionel Sambuc ///
2759*0a6a1f1dSLionel Sambuc /// In a function like
2760*0a6a1f1dSLionel Sambuc /// auto f() {
2761*0a6a1f1dSLionel Sambuc ///   struct S { typedef int a; };
2762*0a6a1f1dSLionel Sambuc ///   return S();
2763*0a6a1f1dSLionel Sambuc /// }
2764*0a6a1f1dSLionel Sambuc ///
2765*0a6a1f1dSLionel Sambuc /// the local type escapes and could be referenced in some TUs but not in
2766*0a6a1f1dSLionel Sambuc /// others. Pretend that all local typedefs are always referenced, to not warn
2767*0a6a1f1dSLionel Sambuc /// on this. This isn't necessary if f has internal linkage, or the typedef
2768*0a6a1f1dSLionel Sambuc /// is private.
2769*0a6a1f1dSLionel Sambuc class LocalTypedefNameReferencer
2770*0a6a1f1dSLionel Sambuc     : public RecursiveASTVisitor<LocalTypedefNameReferencer> {
2771*0a6a1f1dSLionel Sambuc public:
LocalTypedefNameReferencer(Sema & S)2772*0a6a1f1dSLionel Sambuc   LocalTypedefNameReferencer(Sema &S) : S(S) {}
2773*0a6a1f1dSLionel Sambuc   bool VisitRecordType(const RecordType *RT);
2774*0a6a1f1dSLionel Sambuc private:
2775*0a6a1f1dSLionel Sambuc   Sema &S;
2776*0a6a1f1dSLionel Sambuc };
VisitRecordType(const RecordType * RT)2777*0a6a1f1dSLionel Sambuc bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) {
2778*0a6a1f1dSLionel Sambuc   auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl());
2779*0a6a1f1dSLionel Sambuc   if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
2780*0a6a1f1dSLionel Sambuc       R->isDependentType())
2781*0a6a1f1dSLionel Sambuc     return true;
2782*0a6a1f1dSLionel Sambuc   for (auto *TmpD : R->decls())
2783*0a6a1f1dSLionel Sambuc     if (auto *T = dyn_cast<TypedefNameDecl>(TmpD))
2784*0a6a1f1dSLionel Sambuc       if (T->getAccess() != AS_private || R->hasFriends())
2785*0a6a1f1dSLionel Sambuc         S.MarkAnyDeclReferenced(T->getLocation(), T, /*OdrUse=*/false);
2786*0a6a1f1dSLionel Sambuc   return true;
2787*0a6a1f1dSLionel Sambuc }
2788*0a6a1f1dSLionel Sambuc }
2789*0a6a1f1dSLionel Sambuc 
getReturnTypeLoc(FunctionDecl * FD) const2790*0a6a1f1dSLionel Sambuc TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const {
2791*0a6a1f1dSLionel Sambuc   TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
2792*0a6a1f1dSLionel Sambuc   while (auto ATL = TL.getAs<AttributedTypeLoc>())
2793*0a6a1f1dSLionel Sambuc     TL = ATL.getModifiedLoc().IgnoreParens();
2794*0a6a1f1dSLionel Sambuc   return TL.castAs<FunctionProtoTypeLoc>().getReturnLoc();
2795f4a2713aSLionel Sambuc }
2796f4a2713aSLionel Sambuc 
2797f4a2713aSLionel Sambuc /// Deduce the return type for a function from a returned expression, per
2798f4a2713aSLionel Sambuc /// C++1y [dcl.spec.auto]p6.
DeduceFunctionTypeFromReturnExpr(FunctionDecl * FD,SourceLocation ReturnLoc,Expr * & RetExpr,AutoType * AT)2799f4a2713aSLionel Sambuc bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
2800f4a2713aSLionel Sambuc                                             SourceLocation ReturnLoc,
2801f4a2713aSLionel Sambuc                                             Expr *&RetExpr,
2802f4a2713aSLionel Sambuc                                             AutoType *AT) {
2803*0a6a1f1dSLionel Sambuc   TypeLoc OrigResultType = getReturnTypeLoc(FD);
2804f4a2713aSLionel Sambuc   QualType Deduced;
2805f4a2713aSLionel Sambuc 
2806f4a2713aSLionel Sambuc   if (RetExpr && isa<InitListExpr>(RetExpr)) {
2807f4a2713aSLionel Sambuc     //  If the deduction is for a return statement and the initializer is
2808f4a2713aSLionel Sambuc     //  a braced-init-list, the program is ill-formed.
2809f4a2713aSLionel Sambuc     Diag(RetExpr->getExprLoc(),
2810f4a2713aSLionel Sambuc          getCurLambda() ? diag::err_lambda_return_init_list
2811f4a2713aSLionel Sambuc                         : diag::err_auto_fn_return_init_list)
2812f4a2713aSLionel Sambuc         << RetExpr->getSourceRange();
2813f4a2713aSLionel Sambuc     return true;
2814f4a2713aSLionel Sambuc   }
2815f4a2713aSLionel Sambuc 
2816f4a2713aSLionel Sambuc   if (FD->isDependentContext()) {
2817f4a2713aSLionel Sambuc     // C++1y [dcl.spec.auto]p12:
2818f4a2713aSLionel Sambuc     //   Return type deduction [...] occurs when the definition is
2819f4a2713aSLionel Sambuc     //   instantiated even if the function body contains a return
2820f4a2713aSLionel Sambuc     //   statement with a non-type-dependent operand.
2821f4a2713aSLionel Sambuc     assert(AT->isDeduced() && "should have deduced to dependent type");
2822f4a2713aSLionel Sambuc     return false;
2823f4a2713aSLionel Sambuc   } else if (RetExpr) {
2824f4a2713aSLionel Sambuc     //  If the deduction is for a return statement and the initializer is
2825f4a2713aSLionel Sambuc     //  a braced-init-list, the program is ill-formed.
2826f4a2713aSLionel Sambuc     if (isa<InitListExpr>(RetExpr)) {
2827f4a2713aSLionel Sambuc       Diag(RetExpr->getExprLoc(), diag::err_auto_fn_return_init_list);
2828f4a2713aSLionel Sambuc       return true;
2829f4a2713aSLionel Sambuc     }
2830f4a2713aSLionel Sambuc 
2831f4a2713aSLionel Sambuc     //  Otherwise, [...] deduce a value for U using the rules of template
2832f4a2713aSLionel Sambuc     //  argument deduction.
2833f4a2713aSLionel Sambuc     DeduceAutoResult DAR = DeduceAutoType(OrigResultType, RetExpr, Deduced);
2834f4a2713aSLionel Sambuc 
2835f4a2713aSLionel Sambuc     if (DAR == DAR_Failed && !FD->isInvalidDecl())
2836f4a2713aSLionel Sambuc       Diag(RetExpr->getExprLoc(), diag::err_auto_fn_deduction_failure)
2837f4a2713aSLionel Sambuc         << OrigResultType.getType() << RetExpr->getType();
2838f4a2713aSLionel Sambuc 
2839f4a2713aSLionel Sambuc     if (DAR != DAR_Succeeded)
2840f4a2713aSLionel Sambuc       return true;
2841*0a6a1f1dSLionel Sambuc 
2842*0a6a1f1dSLionel Sambuc     // If a local type is part of the returned type, mark its fields as
2843*0a6a1f1dSLionel Sambuc     // referenced.
2844*0a6a1f1dSLionel Sambuc     LocalTypedefNameReferencer Referencer(*this);
2845*0a6a1f1dSLionel Sambuc     Referencer.TraverseType(RetExpr->getType());
2846f4a2713aSLionel Sambuc   } else {
2847f4a2713aSLionel Sambuc     //  In the case of a return with no operand, the initializer is considered
2848f4a2713aSLionel Sambuc     //  to be void().
2849f4a2713aSLionel Sambuc     //
2850f4a2713aSLionel Sambuc     // Deduction here can only succeed if the return type is exactly 'cv auto'
2851f4a2713aSLionel Sambuc     // or 'decltype(auto)', so just check for that case directly.
2852f4a2713aSLionel Sambuc     if (!OrigResultType.getType()->getAs<AutoType>()) {
2853f4a2713aSLionel Sambuc       Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)
2854f4a2713aSLionel Sambuc         << OrigResultType.getType();
2855f4a2713aSLionel Sambuc       return true;
2856f4a2713aSLionel Sambuc     }
2857f4a2713aSLionel Sambuc     // We always deduce U = void in this case.
2858f4a2713aSLionel Sambuc     Deduced = SubstAutoType(OrigResultType.getType(), Context.VoidTy);
2859f4a2713aSLionel Sambuc     if (Deduced.isNull())
2860f4a2713aSLionel Sambuc       return true;
2861f4a2713aSLionel Sambuc   }
2862f4a2713aSLionel Sambuc 
2863f4a2713aSLionel Sambuc   //  If a function with a declared return type that contains a placeholder type
2864f4a2713aSLionel Sambuc   //  has multiple return statements, the return type is deduced for each return
2865f4a2713aSLionel Sambuc   //  statement. [...] if the type deduced is not the same in each deduction,
2866f4a2713aSLionel Sambuc   //  the program is ill-formed.
2867f4a2713aSLionel Sambuc   if (AT->isDeduced() && !FD->isInvalidDecl()) {
2868f4a2713aSLionel Sambuc     AutoType *NewAT = Deduced->getContainedAutoType();
2869f4a2713aSLionel Sambuc     if (!FD->isDependentContext() &&
2870f4a2713aSLionel Sambuc         !Context.hasSameType(AT->getDeducedType(), NewAT->getDeducedType())) {
2871f4a2713aSLionel Sambuc       const LambdaScopeInfo *LambdaSI = getCurLambda();
2872f4a2713aSLionel Sambuc       if (LambdaSI && LambdaSI->HasImplicitReturnType) {
2873f4a2713aSLionel Sambuc         Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
2874f4a2713aSLionel Sambuc           << NewAT->getDeducedType() << AT->getDeducedType()
2875f4a2713aSLionel Sambuc           << true /*IsLambda*/;
2876f4a2713aSLionel Sambuc       } else {
2877f4a2713aSLionel Sambuc         Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
2878f4a2713aSLionel Sambuc           << (AT->isDecltypeAuto() ? 1 : 0)
2879f4a2713aSLionel Sambuc           << NewAT->getDeducedType() << AT->getDeducedType();
2880f4a2713aSLionel Sambuc       }
2881f4a2713aSLionel Sambuc       return true;
2882f4a2713aSLionel Sambuc     }
2883f4a2713aSLionel Sambuc   } else if (!FD->isInvalidDecl()) {
2884f4a2713aSLionel Sambuc     // Update all declarations of the function to have the deduced return type.
2885f4a2713aSLionel Sambuc     Context.adjustDeducedFunctionResultType(FD, Deduced);
2886f4a2713aSLionel Sambuc   }
2887f4a2713aSLionel Sambuc 
2888f4a2713aSLionel Sambuc   return false;
2889f4a2713aSLionel Sambuc }
2890f4a2713aSLionel Sambuc 
2891f4a2713aSLionel Sambuc StmtResult
ActOnReturnStmt(SourceLocation ReturnLoc,Expr * RetValExp,Scope * CurScope)2892*0a6a1f1dSLionel Sambuc Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
2893*0a6a1f1dSLionel Sambuc                       Scope *CurScope) {
2894*0a6a1f1dSLionel Sambuc   StmtResult R = BuildReturnStmt(ReturnLoc, RetValExp);
2895*0a6a1f1dSLionel Sambuc   if (R.isInvalid()) {
2896*0a6a1f1dSLionel Sambuc     return R;
2897*0a6a1f1dSLionel Sambuc   }
2898*0a6a1f1dSLionel Sambuc 
2899*0a6a1f1dSLionel Sambuc   if (VarDecl *VD =
2900*0a6a1f1dSLionel Sambuc       const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate())) {
2901*0a6a1f1dSLionel Sambuc     CurScope->addNRVOCandidate(VD);
2902*0a6a1f1dSLionel Sambuc   } else {
2903*0a6a1f1dSLionel Sambuc     CurScope->setNoNRVO();
2904*0a6a1f1dSLionel Sambuc   }
2905*0a6a1f1dSLionel Sambuc 
2906*0a6a1f1dSLionel Sambuc   return R;
2907*0a6a1f1dSLionel Sambuc }
2908*0a6a1f1dSLionel Sambuc 
BuildReturnStmt(SourceLocation ReturnLoc,Expr * RetValExp)2909*0a6a1f1dSLionel Sambuc StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
2910f4a2713aSLionel Sambuc   // Check for unexpanded parameter packs.
2911f4a2713aSLionel Sambuc   if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
2912f4a2713aSLionel Sambuc     return StmtError();
2913f4a2713aSLionel Sambuc 
2914f4a2713aSLionel Sambuc   if (isa<CapturingScopeInfo>(getCurFunction()))
2915f4a2713aSLionel Sambuc     return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
2916f4a2713aSLionel Sambuc 
2917f4a2713aSLionel Sambuc   QualType FnRetType;
2918f4a2713aSLionel Sambuc   QualType RelatedRetType;
2919*0a6a1f1dSLionel Sambuc   const AttrVec *Attrs = nullptr;
2920*0a6a1f1dSLionel Sambuc   bool isObjCMethod = false;
2921*0a6a1f1dSLionel Sambuc 
2922f4a2713aSLionel Sambuc   if (const FunctionDecl *FD = getCurFunctionDecl()) {
2923*0a6a1f1dSLionel Sambuc     FnRetType = FD->getReturnType();
2924*0a6a1f1dSLionel Sambuc     if (FD->hasAttrs())
2925*0a6a1f1dSLionel Sambuc       Attrs = &FD->getAttrs();
2926f4a2713aSLionel Sambuc     if (FD->isNoReturn())
2927f4a2713aSLionel Sambuc       Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
2928f4a2713aSLionel Sambuc         << FD->getDeclName();
2929f4a2713aSLionel Sambuc   } else if (ObjCMethodDecl *MD = getCurMethodDecl()) {
2930*0a6a1f1dSLionel Sambuc     FnRetType = MD->getReturnType();
2931*0a6a1f1dSLionel Sambuc     isObjCMethod = true;
2932*0a6a1f1dSLionel Sambuc     if (MD->hasAttrs())
2933*0a6a1f1dSLionel Sambuc       Attrs = &MD->getAttrs();
2934f4a2713aSLionel Sambuc     if (MD->hasRelatedResultType() && MD->getClassInterface()) {
2935f4a2713aSLionel Sambuc       // In the implementation of a method with a related return type, the
2936f4a2713aSLionel Sambuc       // type used to type-check the validity of return statements within the
2937f4a2713aSLionel Sambuc       // method body is a pointer to the type of the class being implemented.
2938f4a2713aSLionel Sambuc       RelatedRetType = Context.getObjCInterfaceType(MD->getClassInterface());
2939f4a2713aSLionel Sambuc       RelatedRetType = Context.getObjCObjectPointerType(RelatedRetType);
2940f4a2713aSLionel Sambuc     }
2941f4a2713aSLionel Sambuc   } else // If we don't have a function/method context, bail.
2942f4a2713aSLionel Sambuc     return StmtError();
2943f4a2713aSLionel Sambuc 
2944f4a2713aSLionel Sambuc   // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing
2945f4a2713aSLionel Sambuc   // deduction.
2946*0a6a1f1dSLionel Sambuc   if (getLangOpts().CPlusPlus14) {
2947f4a2713aSLionel Sambuc     if (AutoType *AT = FnRetType->getContainedAutoType()) {
2948f4a2713aSLionel Sambuc       FunctionDecl *FD = cast<FunctionDecl>(CurContext);
2949f4a2713aSLionel Sambuc       if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
2950f4a2713aSLionel Sambuc         FD->setInvalidDecl();
2951f4a2713aSLionel Sambuc         return StmtError();
2952f4a2713aSLionel Sambuc       } else {
2953*0a6a1f1dSLionel Sambuc         FnRetType = FD->getReturnType();
2954f4a2713aSLionel Sambuc       }
2955f4a2713aSLionel Sambuc     }
2956f4a2713aSLionel Sambuc   }
2957f4a2713aSLionel Sambuc 
2958f4a2713aSLionel Sambuc   bool HasDependentReturnType = FnRetType->isDependentType();
2959f4a2713aSLionel Sambuc 
2960*0a6a1f1dSLionel Sambuc   ReturnStmt *Result = nullptr;
2961f4a2713aSLionel Sambuc   if (FnRetType->isVoidType()) {
2962f4a2713aSLionel Sambuc     if (RetValExp) {
2963f4a2713aSLionel Sambuc       if (isa<InitListExpr>(RetValExp)) {
2964f4a2713aSLionel Sambuc         // We simply never allow init lists as the return value of void
2965f4a2713aSLionel Sambuc         // functions. This is compatible because this was never allowed before,
2966f4a2713aSLionel Sambuc         // so there's no legacy code to deal with.
2967f4a2713aSLionel Sambuc         NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
2968f4a2713aSLionel Sambuc         int FunctionKind = 0;
2969f4a2713aSLionel Sambuc         if (isa<ObjCMethodDecl>(CurDecl))
2970f4a2713aSLionel Sambuc           FunctionKind = 1;
2971f4a2713aSLionel Sambuc         else if (isa<CXXConstructorDecl>(CurDecl))
2972f4a2713aSLionel Sambuc           FunctionKind = 2;
2973f4a2713aSLionel Sambuc         else if (isa<CXXDestructorDecl>(CurDecl))
2974f4a2713aSLionel Sambuc           FunctionKind = 3;
2975f4a2713aSLionel Sambuc 
2976f4a2713aSLionel Sambuc         Diag(ReturnLoc, diag::err_return_init_list)
2977f4a2713aSLionel Sambuc           << CurDecl->getDeclName() << FunctionKind
2978f4a2713aSLionel Sambuc           << RetValExp->getSourceRange();
2979f4a2713aSLionel Sambuc 
2980f4a2713aSLionel Sambuc         // Drop the expression.
2981*0a6a1f1dSLionel Sambuc         RetValExp = nullptr;
2982f4a2713aSLionel Sambuc       } else if (!RetValExp->isTypeDependent()) {
2983f4a2713aSLionel Sambuc         // C99 6.8.6.4p1 (ext_ since GCC warns)
2984f4a2713aSLionel Sambuc         unsigned D = diag::ext_return_has_expr;
2985*0a6a1f1dSLionel Sambuc         if (RetValExp->getType()->isVoidType()) {
2986*0a6a1f1dSLionel Sambuc           NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
2987*0a6a1f1dSLionel Sambuc           if (isa<CXXConstructorDecl>(CurDecl) ||
2988*0a6a1f1dSLionel Sambuc               isa<CXXDestructorDecl>(CurDecl))
2989*0a6a1f1dSLionel Sambuc             D = diag::err_ctor_dtor_returns_void;
2990*0a6a1f1dSLionel Sambuc           else
2991f4a2713aSLionel Sambuc             D = diag::ext_return_has_void_expr;
2992*0a6a1f1dSLionel Sambuc         }
2993f4a2713aSLionel Sambuc         else {
2994*0a6a1f1dSLionel Sambuc           ExprResult Result = RetValExp;
2995*0a6a1f1dSLionel Sambuc           Result = IgnoredValueConversions(Result.get());
2996f4a2713aSLionel Sambuc           if (Result.isInvalid())
2997f4a2713aSLionel Sambuc             return StmtError();
2998*0a6a1f1dSLionel Sambuc           RetValExp = Result.get();
2999f4a2713aSLionel Sambuc           RetValExp = ImpCastExprToType(RetValExp,
3000*0a6a1f1dSLionel Sambuc                                         Context.VoidTy, CK_ToVoid).get();
3001f4a2713aSLionel Sambuc         }
3002*0a6a1f1dSLionel Sambuc         // return of void in constructor/destructor is illegal in C++.
3003*0a6a1f1dSLionel Sambuc         if (D == diag::err_ctor_dtor_returns_void) {
3004*0a6a1f1dSLionel Sambuc           NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
3005*0a6a1f1dSLionel Sambuc           Diag(ReturnLoc, D)
3006*0a6a1f1dSLionel Sambuc             << CurDecl->getDeclName() << isa<CXXDestructorDecl>(CurDecl)
3007*0a6a1f1dSLionel Sambuc             << RetValExp->getSourceRange();
3008*0a6a1f1dSLionel Sambuc         }
3009f4a2713aSLionel Sambuc         // return (some void expression); is legal in C++.
3010*0a6a1f1dSLionel Sambuc         else if (D != diag::ext_return_has_void_expr ||
3011f4a2713aSLionel Sambuc             !getLangOpts().CPlusPlus) {
3012f4a2713aSLionel Sambuc           NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
3013f4a2713aSLionel Sambuc 
3014f4a2713aSLionel Sambuc           int FunctionKind = 0;
3015f4a2713aSLionel Sambuc           if (isa<ObjCMethodDecl>(CurDecl))
3016f4a2713aSLionel Sambuc             FunctionKind = 1;
3017f4a2713aSLionel Sambuc           else if (isa<CXXConstructorDecl>(CurDecl))
3018f4a2713aSLionel Sambuc             FunctionKind = 2;
3019f4a2713aSLionel Sambuc           else if (isa<CXXDestructorDecl>(CurDecl))
3020f4a2713aSLionel Sambuc             FunctionKind = 3;
3021f4a2713aSLionel Sambuc 
3022f4a2713aSLionel Sambuc           Diag(ReturnLoc, D)
3023f4a2713aSLionel Sambuc             << CurDecl->getDeclName() << FunctionKind
3024f4a2713aSLionel Sambuc             << RetValExp->getSourceRange();
3025f4a2713aSLionel Sambuc         }
3026f4a2713aSLionel Sambuc       }
3027f4a2713aSLionel Sambuc 
3028f4a2713aSLionel Sambuc       if (RetValExp) {
3029f4a2713aSLionel Sambuc         ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
3030f4a2713aSLionel Sambuc         if (ER.isInvalid())
3031f4a2713aSLionel Sambuc           return StmtError();
3032*0a6a1f1dSLionel Sambuc         RetValExp = ER.get();
3033f4a2713aSLionel Sambuc       }
3034f4a2713aSLionel Sambuc     }
3035f4a2713aSLionel Sambuc 
3036*0a6a1f1dSLionel Sambuc     Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);
3037f4a2713aSLionel Sambuc   } else if (!RetValExp && !HasDependentReturnType) {
3038*0a6a1f1dSLionel Sambuc     FunctionDecl *FD = getCurFunctionDecl();
3039f4a2713aSLionel Sambuc 
3040*0a6a1f1dSLionel Sambuc     unsigned DiagID;
3041*0a6a1f1dSLionel Sambuc     if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) {
3042*0a6a1f1dSLionel Sambuc       // C++11 [stmt.return]p2
3043*0a6a1f1dSLionel Sambuc       DiagID = diag::err_constexpr_return_missing_expr;
3044*0a6a1f1dSLionel Sambuc       FD->setInvalidDecl();
3045*0a6a1f1dSLionel Sambuc     } else if (getLangOpts().C99) {
3046*0a6a1f1dSLionel Sambuc       // C99 6.8.6.4p1 (ext_ since GCC warns)
3047*0a6a1f1dSLionel Sambuc       DiagID = diag::ext_return_missing_expr;
3048*0a6a1f1dSLionel Sambuc     } else {
3049*0a6a1f1dSLionel Sambuc       // C90 6.6.6.4p4
3050*0a6a1f1dSLionel Sambuc       DiagID = diag::warn_return_missing_expr;
3051*0a6a1f1dSLionel Sambuc     }
3052*0a6a1f1dSLionel Sambuc 
3053*0a6a1f1dSLionel Sambuc     if (FD)
3054f4a2713aSLionel Sambuc       Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/;
3055f4a2713aSLionel Sambuc     else
3056f4a2713aSLionel Sambuc       Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/;
3057*0a6a1f1dSLionel Sambuc 
3058f4a2713aSLionel Sambuc     Result = new (Context) ReturnStmt(ReturnLoc);
3059f4a2713aSLionel Sambuc   } else {
3060f4a2713aSLionel Sambuc     assert(RetValExp || HasDependentReturnType);
3061*0a6a1f1dSLionel Sambuc     const VarDecl *NRVOCandidate = nullptr;
3062f4a2713aSLionel Sambuc 
3063*0a6a1f1dSLionel Sambuc     QualType RetType = RelatedRetType.isNull() ? FnRetType : RelatedRetType;
3064f4a2713aSLionel Sambuc 
3065f4a2713aSLionel Sambuc     // C99 6.8.6.4p3(136): The return statement is not an assignment. The
3066f4a2713aSLionel Sambuc     // overlap restriction of subclause 6.5.16.1 does not apply to the case of
3067f4a2713aSLionel Sambuc     // function return.
3068f4a2713aSLionel Sambuc 
3069f4a2713aSLionel Sambuc     // In C++ the return statement is handled via a copy initialization,
3070f4a2713aSLionel Sambuc     // the C version of which boils down to CheckSingleAssignmentConstraints.
3071*0a6a1f1dSLionel Sambuc     if (RetValExp)
3072f4a2713aSLionel Sambuc       NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
3073*0a6a1f1dSLionel Sambuc     if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {
3074*0a6a1f1dSLionel Sambuc       // we have a non-void function with an expression, continue checking
3075f4a2713aSLionel Sambuc       InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
3076f4a2713aSLionel Sambuc                                                                      RetType,
3077*0a6a1f1dSLionel Sambuc                                                       NRVOCandidate != nullptr);
3078f4a2713aSLionel Sambuc       ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
3079f4a2713aSLionel Sambuc                                                        RetType, RetValExp);
3080f4a2713aSLionel Sambuc       if (Res.isInvalid()) {
3081f4a2713aSLionel Sambuc         // FIXME: Clean up temporaries here anyway?
3082f4a2713aSLionel Sambuc         return StmtError();
3083f4a2713aSLionel Sambuc       }
3084*0a6a1f1dSLionel Sambuc       RetValExp = Res.getAs<Expr>();
3085f4a2713aSLionel Sambuc 
3086f4a2713aSLionel Sambuc       // If we have a related result type, we need to implicitly
3087f4a2713aSLionel Sambuc       // convert back to the formal result type.  We can't pretend to
3088f4a2713aSLionel Sambuc       // initialize the result again --- we might end double-retaining
3089f4a2713aSLionel Sambuc       // --- so instead we initialize a notional temporary.
3090f4a2713aSLionel Sambuc       if (!RelatedRetType.isNull()) {
3091f4a2713aSLionel Sambuc         Entity = InitializedEntity::InitializeRelatedResult(getCurMethodDecl(),
3092f4a2713aSLionel Sambuc                                                             FnRetType);
3093f4a2713aSLionel Sambuc         Res = PerformCopyInitialization(Entity, ReturnLoc, RetValExp);
3094f4a2713aSLionel Sambuc         if (Res.isInvalid()) {
3095f4a2713aSLionel Sambuc           // FIXME: Clean up temporaries here anyway?
3096f4a2713aSLionel Sambuc           return StmtError();
3097f4a2713aSLionel Sambuc         }
3098*0a6a1f1dSLionel Sambuc         RetValExp = Res.getAs<Expr>();
3099f4a2713aSLionel Sambuc       }
3100f4a2713aSLionel Sambuc 
3101*0a6a1f1dSLionel Sambuc       CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
3102*0a6a1f1dSLionel Sambuc                          getCurFunctionDecl());
3103f4a2713aSLionel Sambuc     }
3104f4a2713aSLionel Sambuc 
3105f4a2713aSLionel Sambuc     if (RetValExp) {
3106f4a2713aSLionel Sambuc       ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
3107f4a2713aSLionel Sambuc       if (ER.isInvalid())
3108f4a2713aSLionel Sambuc         return StmtError();
3109*0a6a1f1dSLionel Sambuc       RetValExp = ER.get();
3110f4a2713aSLionel Sambuc     }
3111f4a2713aSLionel Sambuc     Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
3112f4a2713aSLionel Sambuc   }
3113f4a2713aSLionel Sambuc 
3114f4a2713aSLionel Sambuc   // If we need to check for the named return value optimization, save the
3115f4a2713aSLionel Sambuc   // return statement in our scope for later processing.
3116*0a6a1f1dSLionel Sambuc   if (Result->getNRVOCandidate())
3117f4a2713aSLionel Sambuc     FunctionScopes.back()->Returns.push_back(Result);
3118f4a2713aSLionel Sambuc 
3119*0a6a1f1dSLionel Sambuc   return Result;
3120f4a2713aSLionel Sambuc }
3121f4a2713aSLionel Sambuc 
3122f4a2713aSLionel Sambuc StmtResult
ActOnObjCAtCatchStmt(SourceLocation AtLoc,SourceLocation RParen,Decl * Parm,Stmt * Body)3123f4a2713aSLionel Sambuc Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
3124f4a2713aSLionel Sambuc                            SourceLocation RParen, Decl *Parm,
3125f4a2713aSLionel Sambuc                            Stmt *Body) {
3126f4a2713aSLionel Sambuc   VarDecl *Var = cast_or_null<VarDecl>(Parm);
3127f4a2713aSLionel Sambuc   if (Var && Var->isInvalidDecl())
3128f4a2713aSLionel Sambuc     return StmtError();
3129f4a2713aSLionel Sambuc 
3130*0a6a1f1dSLionel Sambuc   return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body);
3131f4a2713aSLionel Sambuc }
3132f4a2713aSLionel Sambuc 
3133f4a2713aSLionel Sambuc StmtResult
ActOnObjCAtFinallyStmt(SourceLocation AtLoc,Stmt * Body)3134f4a2713aSLionel Sambuc Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
3135*0a6a1f1dSLionel Sambuc   return new (Context) ObjCAtFinallyStmt(AtLoc, Body);
3136f4a2713aSLionel Sambuc }
3137f4a2713aSLionel Sambuc 
3138f4a2713aSLionel Sambuc StmtResult
ActOnObjCAtTryStmt(SourceLocation AtLoc,Stmt * Try,MultiStmtArg CatchStmts,Stmt * Finally)3139f4a2713aSLionel Sambuc Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
3140f4a2713aSLionel Sambuc                          MultiStmtArg CatchStmts, Stmt *Finally) {
3141f4a2713aSLionel Sambuc   if (!getLangOpts().ObjCExceptions)
3142f4a2713aSLionel Sambuc     Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@try";
3143f4a2713aSLionel Sambuc 
3144f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchProtectedScope();
3145f4a2713aSLionel Sambuc   unsigned NumCatchStmts = CatchStmts.size();
3146*0a6a1f1dSLionel Sambuc   return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(),
3147*0a6a1f1dSLionel Sambuc                                NumCatchStmts, Finally);
3148f4a2713aSLionel Sambuc }
3149f4a2713aSLionel Sambuc 
BuildObjCAtThrowStmt(SourceLocation AtLoc,Expr * Throw)3150f4a2713aSLionel Sambuc StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
3151f4a2713aSLionel Sambuc   if (Throw) {
3152f4a2713aSLionel Sambuc     ExprResult Result = DefaultLvalueConversion(Throw);
3153f4a2713aSLionel Sambuc     if (Result.isInvalid())
3154f4a2713aSLionel Sambuc       return StmtError();
3155f4a2713aSLionel Sambuc 
3156*0a6a1f1dSLionel Sambuc     Result = ActOnFinishFullExpr(Result.get());
3157f4a2713aSLionel Sambuc     if (Result.isInvalid())
3158f4a2713aSLionel Sambuc       return StmtError();
3159*0a6a1f1dSLionel Sambuc     Throw = Result.get();
3160f4a2713aSLionel Sambuc 
3161f4a2713aSLionel Sambuc     QualType ThrowType = Throw->getType();
3162f4a2713aSLionel Sambuc     // Make sure the expression type is an ObjC pointer or "void *".
3163f4a2713aSLionel Sambuc     if (!ThrowType->isDependentType() &&
3164f4a2713aSLionel Sambuc         !ThrowType->isObjCObjectPointerType()) {
3165f4a2713aSLionel Sambuc       const PointerType *PT = ThrowType->getAs<PointerType>();
3166f4a2713aSLionel Sambuc       if (!PT || !PT->getPointeeType()->isVoidType())
3167f4a2713aSLionel Sambuc         return StmtError(Diag(AtLoc, diag::error_objc_throw_expects_object)
3168f4a2713aSLionel Sambuc                          << Throw->getType() << Throw->getSourceRange());
3169f4a2713aSLionel Sambuc     }
3170f4a2713aSLionel Sambuc   }
3171f4a2713aSLionel Sambuc 
3172*0a6a1f1dSLionel Sambuc   return new (Context) ObjCAtThrowStmt(AtLoc, Throw);
3173f4a2713aSLionel Sambuc }
3174f4a2713aSLionel Sambuc 
3175f4a2713aSLionel Sambuc StmtResult
ActOnObjCAtThrowStmt(SourceLocation AtLoc,Expr * Throw,Scope * CurScope)3176f4a2713aSLionel Sambuc Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw,
3177f4a2713aSLionel Sambuc                            Scope *CurScope) {
3178f4a2713aSLionel Sambuc   if (!getLangOpts().ObjCExceptions)
3179f4a2713aSLionel Sambuc     Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@throw";
3180f4a2713aSLionel Sambuc 
3181f4a2713aSLionel Sambuc   if (!Throw) {
3182f4a2713aSLionel Sambuc     // @throw without an expression designates a rethrow (which much occur
3183f4a2713aSLionel Sambuc     // in the context of an @catch clause).
3184f4a2713aSLionel Sambuc     Scope *AtCatchParent = CurScope;
3185f4a2713aSLionel Sambuc     while (AtCatchParent && !AtCatchParent->isAtCatchScope())
3186f4a2713aSLionel Sambuc       AtCatchParent = AtCatchParent->getParent();
3187f4a2713aSLionel Sambuc     if (!AtCatchParent)
3188f4a2713aSLionel Sambuc       return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
3189f4a2713aSLionel Sambuc   }
3190f4a2713aSLionel Sambuc   return BuildObjCAtThrowStmt(AtLoc, Throw);
3191f4a2713aSLionel Sambuc }
3192f4a2713aSLionel Sambuc 
3193f4a2713aSLionel Sambuc ExprResult
ActOnObjCAtSynchronizedOperand(SourceLocation atLoc,Expr * operand)3194f4a2713aSLionel Sambuc Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) {
3195f4a2713aSLionel Sambuc   ExprResult result = DefaultLvalueConversion(operand);
3196f4a2713aSLionel Sambuc   if (result.isInvalid())
3197f4a2713aSLionel Sambuc     return ExprError();
3198*0a6a1f1dSLionel Sambuc   operand = result.get();
3199f4a2713aSLionel Sambuc 
3200f4a2713aSLionel Sambuc   // Make sure the expression type is an ObjC pointer or "void *".
3201f4a2713aSLionel Sambuc   QualType type = operand->getType();
3202f4a2713aSLionel Sambuc   if (!type->isDependentType() &&
3203f4a2713aSLionel Sambuc       !type->isObjCObjectPointerType()) {
3204f4a2713aSLionel Sambuc     const PointerType *pointerType = type->getAs<PointerType>();
3205*0a6a1f1dSLionel Sambuc     if (!pointerType || !pointerType->getPointeeType()->isVoidType()) {
3206*0a6a1f1dSLionel Sambuc       if (getLangOpts().CPlusPlus) {
3207*0a6a1f1dSLionel Sambuc         if (RequireCompleteType(atLoc, type,
3208*0a6a1f1dSLionel Sambuc                                 diag::err_incomplete_receiver_type))
3209f4a2713aSLionel Sambuc           return Diag(atLoc, diag::error_objc_synchronized_expects_object)
3210f4a2713aSLionel Sambuc                    << type << operand->getSourceRange();
3211*0a6a1f1dSLionel Sambuc 
3212*0a6a1f1dSLionel Sambuc         ExprResult result = PerformContextuallyConvertToObjCPointer(operand);
3213*0a6a1f1dSLionel Sambuc         if (!result.isUsable())
3214*0a6a1f1dSLionel Sambuc           return Diag(atLoc, diag::error_objc_synchronized_expects_object)
3215*0a6a1f1dSLionel Sambuc                    << type << operand->getSourceRange();
3216*0a6a1f1dSLionel Sambuc 
3217*0a6a1f1dSLionel Sambuc         operand = result.get();
3218*0a6a1f1dSLionel Sambuc       } else {
3219*0a6a1f1dSLionel Sambuc           return Diag(atLoc, diag::error_objc_synchronized_expects_object)
3220*0a6a1f1dSLionel Sambuc                    << type << operand->getSourceRange();
3221*0a6a1f1dSLionel Sambuc       }
3222*0a6a1f1dSLionel Sambuc     }
3223f4a2713aSLionel Sambuc   }
3224f4a2713aSLionel Sambuc 
3225f4a2713aSLionel Sambuc   // The operand to @synchronized is a full-expression.
3226f4a2713aSLionel Sambuc   return ActOnFinishFullExpr(operand);
3227f4a2713aSLionel Sambuc }
3228f4a2713aSLionel Sambuc 
3229f4a2713aSLionel Sambuc StmtResult
ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,Expr * SyncExpr,Stmt * SyncBody)3230f4a2713aSLionel Sambuc Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr,
3231f4a2713aSLionel Sambuc                                   Stmt *SyncBody) {
3232f4a2713aSLionel Sambuc   // We can't jump into or indirect-jump out of a @synchronized block.
3233f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchProtectedScope();
3234*0a6a1f1dSLionel Sambuc   return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody);
3235f4a2713aSLionel Sambuc }
3236f4a2713aSLionel Sambuc 
3237f4a2713aSLionel Sambuc /// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
3238f4a2713aSLionel Sambuc /// and creates a proper catch handler from them.
3239f4a2713aSLionel Sambuc StmtResult
ActOnCXXCatchBlock(SourceLocation CatchLoc,Decl * ExDecl,Stmt * HandlerBlock)3240f4a2713aSLionel Sambuc Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
3241f4a2713aSLionel Sambuc                          Stmt *HandlerBlock) {
3242f4a2713aSLionel Sambuc   // There's nothing to test that ActOnExceptionDecl didn't already test.
3243*0a6a1f1dSLionel Sambuc   return new (Context)
3244*0a6a1f1dSLionel Sambuc       CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
3245f4a2713aSLionel Sambuc }
3246f4a2713aSLionel Sambuc 
3247f4a2713aSLionel Sambuc StmtResult
ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc,Stmt * Body)3248f4a2713aSLionel Sambuc Sema::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) {
3249f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchProtectedScope();
3250*0a6a1f1dSLionel Sambuc   return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body);
3251f4a2713aSLionel Sambuc }
3252f4a2713aSLionel Sambuc 
3253f4a2713aSLionel Sambuc namespace {
3254f4a2713aSLionel Sambuc 
3255f4a2713aSLionel Sambuc class TypeWithHandler {
3256f4a2713aSLionel Sambuc   QualType t;
3257f4a2713aSLionel Sambuc   CXXCatchStmt *stmt;
3258f4a2713aSLionel Sambuc public:
TypeWithHandler(const QualType & type,CXXCatchStmt * statement)3259f4a2713aSLionel Sambuc   TypeWithHandler(const QualType &type, CXXCatchStmt *statement)
3260f4a2713aSLionel Sambuc   : t(type), stmt(statement) {}
3261f4a2713aSLionel Sambuc 
3262f4a2713aSLionel Sambuc   // An arbitrary order is fine as long as it places identical
3263f4a2713aSLionel Sambuc   // types next to each other.
operator <(const TypeWithHandler & y) const3264f4a2713aSLionel Sambuc   bool operator<(const TypeWithHandler &y) const {
3265f4a2713aSLionel Sambuc     if (t.getAsOpaquePtr() < y.t.getAsOpaquePtr())
3266f4a2713aSLionel Sambuc       return true;
3267f4a2713aSLionel Sambuc     if (t.getAsOpaquePtr() > y.t.getAsOpaquePtr())
3268f4a2713aSLionel Sambuc       return false;
3269f4a2713aSLionel Sambuc     else
3270f4a2713aSLionel Sambuc       return getTypeSpecStartLoc() < y.getTypeSpecStartLoc();
3271f4a2713aSLionel Sambuc   }
3272f4a2713aSLionel Sambuc 
operator ==(const TypeWithHandler & other) const3273f4a2713aSLionel Sambuc   bool operator==(const TypeWithHandler& other) const {
3274f4a2713aSLionel Sambuc     return t == other.t;
3275f4a2713aSLionel Sambuc   }
3276f4a2713aSLionel Sambuc 
getCatchStmt() const3277f4a2713aSLionel Sambuc   CXXCatchStmt *getCatchStmt() const { return stmt; }
getTypeSpecStartLoc() const3278f4a2713aSLionel Sambuc   SourceLocation getTypeSpecStartLoc() const {
3279f4a2713aSLionel Sambuc     return stmt->getExceptionDecl()->getTypeSpecStartLoc();
3280f4a2713aSLionel Sambuc   }
3281f4a2713aSLionel Sambuc };
3282f4a2713aSLionel Sambuc 
3283f4a2713aSLionel Sambuc }
3284f4a2713aSLionel Sambuc 
3285f4a2713aSLionel Sambuc /// ActOnCXXTryBlock - Takes a try compound-statement and a number of
3286f4a2713aSLionel Sambuc /// handlers and creates a try statement from them.
ActOnCXXTryBlock(SourceLocation TryLoc,Stmt * TryBlock,ArrayRef<Stmt * > Handlers)3287f4a2713aSLionel Sambuc StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
3288f4a2713aSLionel Sambuc                                   ArrayRef<Stmt *> Handlers) {
3289f4a2713aSLionel Sambuc   // Don't report an error if 'try' is used in system headers.
3290f4a2713aSLionel Sambuc   if (!getLangOpts().CXXExceptions &&
3291f4a2713aSLionel Sambuc       !getSourceManager().isInSystemHeader(TryLoc))
3292f4a2713aSLionel Sambuc       Diag(TryLoc, diag::err_exceptions_disabled) << "try";
3293f4a2713aSLionel Sambuc 
3294*0a6a1f1dSLionel Sambuc   if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
3295*0a6a1f1dSLionel Sambuc     Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
3296*0a6a1f1dSLionel Sambuc 
3297f4a2713aSLionel Sambuc   const unsigned NumHandlers = Handlers.size();
3298f4a2713aSLionel Sambuc   assert(NumHandlers > 0 &&
3299f4a2713aSLionel Sambuc          "The parser shouldn't call this if there are no handlers.");
3300f4a2713aSLionel Sambuc 
3301f4a2713aSLionel Sambuc   SmallVector<TypeWithHandler, 8> TypesWithHandlers;
3302f4a2713aSLionel Sambuc 
3303f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumHandlers; ++i) {
3304f4a2713aSLionel Sambuc     CXXCatchStmt *Handler = cast<CXXCatchStmt>(Handlers[i]);
3305f4a2713aSLionel Sambuc     if (!Handler->getExceptionDecl()) {
3306f4a2713aSLionel Sambuc       if (i < NumHandlers - 1)
3307f4a2713aSLionel Sambuc         return StmtError(Diag(Handler->getLocStart(),
3308f4a2713aSLionel Sambuc                               diag::err_early_catch_all));
3309f4a2713aSLionel Sambuc 
3310f4a2713aSLionel Sambuc       continue;
3311f4a2713aSLionel Sambuc     }
3312f4a2713aSLionel Sambuc 
3313f4a2713aSLionel Sambuc     const QualType CaughtType = Handler->getCaughtType();
3314f4a2713aSLionel Sambuc     const QualType CanonicalCaughtType = Context.getCanonicalType(CaughtType);
3315f4a2713aSLionel Sambuc     TypesWithHandlers.push_back(TypeWithHandler(CanonicalCaughtType, Handler));
3316f4a2713aSLionel Sambuc   }
3317f4a2713aSLionel Sambuc 
3318f4a2713aSLionel Sambuc   // Detect handlers for the same type as an earlier one.
3319f4a2713aSLionel Sambuc   if (NumHandlers > 1) {
3320f4a2713aSLionel Sambuc     llvm::array_pod_sort(TypesWithHandlers.begin(), TypesWithHandlers.end());
3321f4a2713aSLionel Sambuc 
3322f4a2713aSLionel Sambuc     TypeWithHandler prev = TypesWithHandlers[0];
3323f4a2713aSLionel Sambuc     for (unsigned i = 1; i < TypesWithHandlers.size(); ++i) {
3324f4a2713aSLionel Sambuc       TypeWithHandler curr = TypesWithHandlers[i];
3325f4a2713aSLionel Sambuc 
3326f4a2713aSLionel Sambuc       if (curr == prev) {
3327f4a2713aSLionel Sambuc         Diag(curr.getTypeSpecStartLoc(),
3328f4a2713aSLionel Sambuc              diag::warn_exception_caught_by_earlier_handler)
3329f4a2713aSLionel Sambuc           << curr.getCatchStmt()->getCaughtType().getAsString();
3330f4a2713aSLionel Sambuc         Diag(prev.getTypeSpecStartLoc(),
3331f4a2713aSLionel Sambuc              diag::note_previous_exception_handler)
3332f4a2713aSLionel Sambuc           << prev.getCatchStmt()->getCaughtType().getAsString();
3333f4a2713aSLionel Sambuc       }
3334f4a2713aSLionel Sambuc 
3335f4a2713aSLionel Sambuc       prev = curr;
3336f4a2713aSLionel Sambuc     }
3337f4a2713aSLionel Sambuc   }
3338f4a2713aSLionel Sambuc 
3339f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchProtectedScope();
3340f4a2713aSLionel Sambuc 
3341f4a2713aSLionel Sambuc   // FIXME: We should detect handlers that cannot catch anything because an
3342f4a2713aSLionel Sambuc   // earlier handler catches a superclass. Need to find a method that is not
3343f4a2713aSLionel Sambuc   // quadratic for this.
3344f4a2713aSLionel Sambuc   // Neither of these are explicitly forbidden, but every compiler detects them
3345f4a2713aSLionel Sambuc   // and warns.
3346f4a2713aSLionel Sambuc 
3347*0a6a1f1dSLionel Sambuc   return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers);
3348f4a2713aSLionel Sambuc }
3349f4a2713aSLionel Sambuc 
3350f4a2713aSLionel Sambuc StmtResult
ActOnSEHTryBlock(bool IsCXXTry,SourceLocation TryLoc,Stmt * TryBlock,Stmt * Handler)3351f4a2713aSLionel Sambuc Sema::ActOnSEHTryBlock(bool IsCXXTry,
3352f4a2713aSLionel Sambuc                        SourceLocation TryLoc,
3353f4a2713aSLionel Sambuc                        Stmt *TryBlock,
3354f4a2713aSLionel Sambuc                        Stmt *Handler) {
3355f4a2713aSLionel Sambuc   assert(TryBlock && Handler);
3356f4a2713aSLionel Sambuc 
3357f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchProtectedScope();
3358f4a2713aSLionel Sambuc 
3359*0a6a1f1dSLionel Sambuc   return SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler);
3360f4a2713aSLionel Sambuc }
3361f4a2713aSLionel Sambuc 
3362f4a2713aSLionel Sambuc StmtResult
ActOnSEHExceptBlock(SourceLocation Loc,Expr * FilterExpr,Stmt * Block)3363f4a2713aSLionel Sambuc Sema::ActOnSEHExceptBlock(SourceLocation Loc,
3364f4a2713aSLionel Sambuc                           Expr *FilterExpr,
3365f4a2713aSLionel Sambuc                           Stmt *Block) {
3366f4a2713aSLionel Sambuc   assert(FilterExpr && Block);
3367f4a2713aSLionel Sambuc 
3368f4a2713aSLionel Sambuc   if(!FilterExpr->getType()->isIntegerType()) {
3369f4a2713aSLionel Sambuc     return StmtError(Diag(FilterExpr->getExprLoc(),
3370f4a2713aSLionel Sambuc                      diag::err_filter_expression_integral)
3371f4a2713aSLionel Sambuc                      << FilterExpr->getType());
3372f4a2713aSLionel Sambuc   }
3373f4a2713aSLionel Sambuc 
3374*0a6a1f1dSLionel Sambuc   return SEHExceptStmt::Create(Context,Loc,FilterExpr,Block);
3375f4a2713aSLionel Sambuc }
3376f4a2713aSLionel Sambuc 
3377f4a2713aSLionel Sambuc StmtResult
ActOnSEHFinallyBlock(SourceLocation Loc,Stmt * Block)3378f4a2713aSLionel Sambuc Sema::ActOnSEHFinallyBlock(SourceLocation Loc,
3379f4a2713aSLionel Sambuc                            Stmt *Block) {
3380f4a2713aSLionel Sambuc   assert(Block);
3381*0a6a1f1dSLionel Sambuc   return SEHFinallyStmt::Create(Context,Loc,Block);
3382*0a6a1f1dSLionel Sambuc }
3383*0a6a1f1dSLionel Sambuc 
3384*0a6a1f1dSLionel Sambuc StmtResult
ActOnSEHLeaveStmt(SourceLocation Loc,Scope * CurScope)3385*0a6a1f1dSLionel Sambuc Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {
3386*0a6a1f1dSLionel Sambuc   Scope *SEHTryParent = CurScope;
3387*0a6a1f1dSLionel Sambuc   while (SEHTryParent && !SEHTryParent->isSEHTryScope())
3388*0a6a1f1dSLionel Sambuc     SEHTryParent = SEHTryParent->getParent();
3389*0a6a1f1dSLionel Sambuc   if (!SEHTryParent)
3390*0a6a1f1dSLionel Sambuc     return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));
3391*0a6a1f1dSLionel Sambuc 
3392*0a6a1f1dSLionel Sambuc   return new (Context) SEHLeaveStmt(Loc);
3393f4a2713aSLionel Sambuc }
3394f4a2713aSLionel Sambuc 
BuildMSDependentExistsStmt(SourceLocation KeywordLoc,bool IsIfExists,NestedNameSpecifierLoc QualifierLoc,DeclarationNameInfo NameInfo,Stmt * Nested)3395f4a2713aSLionel Sambuc StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
3396f4a2713aSLionel Sambuc                                             bool IsIfExists,
3397f4a2713aSLionel Sambuc                                             NestedNameSpecifierLoc QualifierLoc,
3398f4a2713aSLionel Sambuc                                             DeclarationNameInfo NameInfo,
3399f4a2713aSLionel Sambuc                                             Stmt *Nested)
3400f4a2713aSLionel Sambuc {
3401f4a2713aSLionel Sambuc   return new (Context) MSDependentExistsStmt(KeywordLoc, IsIfExists,
3402f4a2713aSLionel Sambuc                                              QualifierLoc, NameInfo,
3403f4a2713aSLionel Sambuc                                              cast<CompoundStmt>(Nested));
3404f4a2713aSLionel Sambuc }
3405f4a2713aSLionel Sambuc 
3406f4a2713aSLionel Sambuc 
ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,bool IsIfExists,CXXScopeSpec & SS,UnqualifiedId & Name,Stmt * Nested)3407f4a2713aSLionel Sambuc StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,
3408f4a2713aSLionel Sambuc                                             bool IsIfExists,
3409f4a2713aSLionel Sambuc                                             CXXScopeSpec &SS,
3410f4a2713aSLionel Sambuc                                             UnqualifiedId &Name,
3411f4a2713aSLionel Sambuc                                             Stmt *Nested) {
3412f4a2713aSLionel Sambuc   return BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
3413f4a2713aSLionel Sambuc                                     SS.getWithLocInContext(Context),
3414f4a2713aSLionel Sambuc                                     GetNameFromUnqualifiedId(Name),
3415f4a2713aSLionel Sambuc                                     Nested);
3416f4a2713aSLionel Sambuc }
3417f4a2713aSLionel Sambuc 
3418f4a2713aSLionel Sambuc RecordDecl*
CreateCapturedStmtRecordDecl(CapturedDecl * & CD,SourceLocation Loc,unsigned NumParams)3419f4a2713aSLionel Sambuc Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc,
3420f4a2713aSLionel Sambuc                                    unsigned NumParams) {
3421f4a2713aSLionel Sambuc   DeclContext *DC = CurContext;
3422f4a2713aSLionel Sambuc   while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
3423f4a2713aSLionel Sambuc     DC = DC->getParent();
3424f4a2713aSLionel Sambuc 
3425*0a6a1f1dSLionel Sambuc   RecordDecl *RD = nullptr;
3426f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus)
3427*0a6a1f1dSLionel Sambuc     RD = CXXRecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc,
3428*0a6a1f1dSLionel Sambuc                                /*Id=*/nullptr);
3429f4a2713aSLionel Sambuc   else
3430*0a6a1f1dSLionel Sambuc     RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/nullptr);
3431f4a2713aSLionel Sambuc 
3432*0a6a1f1dSLionel Sambuc   RD->setCapturedRecord();
3433f4a2713aSLionel Sambuc   DC->addDecl(RD);
3434f4a2713aSLionel Sambuc   RD->setImplicit();
3435f4a2713aSLionel Sambuc   RD->startDefinition();
3436f4a2713aSLionel Sambuc 
3437*0a6a1f1dSLionel Sambuc   assert(NumParams > 0 && "CapturedStmt requires context parameter");
3438f4a2713aSLionel Sambuc   CD = CapturedDecl::Create(Context, CurContext, NumParams);
3439f4a2713aSLionel Sambuc   DC->addDecl(CD);
3440f4a2713aSLionel Sambuc   return RD;
3441f4a2713aSLionel Sambuc }
3442f4a2713aSLionel Sambuc 
buildCapturedStmtCaptureList(SmallVectorImpl<CapturedStmt::Capture> & Captures,SmallVectorImpl<Expr * > & CaptureInits,ArrayRef<CapturingScopeInfo::Capture> Candidates)3443f4a2713aSLionel Sambuc static void buildCapturedStmtCaptureList(
3444f4a2713aSLionel Sambuc     SmallVectorImpl<CapturedStmt::Capture> &Captures,
3445f4a2713aSLionel Sambuc     SmallVectorImpl<Expr *> &CaptureInits,
3446f4a2713aSLionel Sambuc     ArrayRef<CapturingScopeInfo::Capture> Candidates) {
3447f4a2713aSLionel Sambuc 
3448f4a2713aSLionel Sambuc   typedef ArrayRef<CapturingScopeInfo::Capture>::const_iterator CaptureIter;
3449f4a2713aSLionel Sambuc   for (CaptureIter Cap = Candidates.begin(); Cap != Candidates.end(); ++Cap) {
3450f4a2713aSLionel Sambuc 
3451f4a2713aSLionel Sambuc     if (Cap->isThisCapture()) {
3452f4a2713aSLionel Sambuc       Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
3453f4a2713aSLionel Sambuc                                                CapturedStmt::VCK_This));
3454f4a2713aSLionel Sambuc       CaptureInits.push_back(Cap->getInitExpr());
3455f4a2713aSLionel Sambuc       continue;
3456*0a6a1f1dSLionel Sambuc     } else if (Cap->isVLATypeCapture()) {
3457*0a6a1f1dSLionel Sambuc       Captures.push_back(
3458*0a6a1f1dSLionel Sambuc           CapturedStmt::Capture(Cap->getLocation(), CapturedStmt::VCK_VLAType));
3459*0a6a1f1dSLionel Sambuc       CaptureInits.push_back(nullptr);
3460*0a6a1f1dSLionel Sambuc       continue;
3461f4a2713aSLionel Sambuc     }
3462f4a2713aSLionel Sambuc 
3463f4a2713aSLionel Sambuc     assert(Cap->isReferenceCapture() &&
3464f4a2713aSLionel Sambuc            "non-reference capture not yet implemented");
3465f4a2713aSLionel Sambuc 
3466f4a2713aSLionel Sambuc     Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
3467f4a2713aSLionel Sambuc                                              CapturedStmt::VCK_ByRef,
3468f4a2713aSLionel Sambuc                                              Cap->getVariable()));
3469f4a2713aSLionel Sambuc     CaptureInits.push_back(Cap->getInitExpr());
3470f4a2713aSLionel Sambuc   }
3471f4a2713aSLionel Sambuc }
3472f4a2713aSLionel Sambuc 
ActOnCapturedRegionStart(SourceLocation Loc,Scope * CurScope,CapturedRegionKind Kind,unsigned NumParams)3473f4a2713aSLionel Sambuc void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
3474f4a2713aSLionel Sambuc                                     CapturedRegionKind Kind,
3475f4a2713aSLionel Sambuc                                     unsigned NumParams) {
3476*0a6a1f1dSLionel Sambuc   CapturedDecl *CD = nullptr;
3477f4a2713aSLionel Sambuc   RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams);
3478f4a2713aSLionel Sambuc 
3479*0a6a1f1dSLionel Sambuc   // Build the context parameter
3480*0a6a1f1dSLionel Sambuc   DeclContext *DC = CapturedDecl::castToDeclContext(CD);
3481*0a6a1f1dSLionel Sambuc   IdentifierInfo *ParamName = &Context.Idents.get("__context");
3482*0a6a1f1dSLionel Sambuc   QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
3483*0a6a1f1dSLionel Sambuc   ImplicitParamDecl *Param
3484*0a6a1f1dSLionel Sambuc     = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
3485*0a6a1f1dSLionel Sambuc   DC->addDecl(Param);
3486*0a6a1f1dSLionel Sambuc 
3487*0a6a1f1dSLionel Sambuc   CD->setContextParam(0, Param);
3488*0a6a1f1dSLionel Sambuc 
3489*0a6a1f1dSLionel Sambuc   // Enter the capturing scope for this captured region.
3490*0a6a1f1dSLionel Sambuc   PushCapturedRegionScope(CurScope, CD, RD, Kind);
3491*0a6a1f1dSLionel Sambuc 
3492*0a6a1f1dSLionel Sambuc   if (CurScope)
3493*0a6a1f1dSLionel Sambuc     PushDeclContext(CurScope, CD);
3494*0a6a1f1dSLionel Sambuc   else
3495*0a6a1f1dSLionel Sambuc     CurContext = CD;
3496*0a6a1f1dSLionel Sambuc 
3497*0a6a1f1dSLionel Sambuc   PushExpressionEvaluationContext(PotentiallyEvaluated);
3498*0a6a1f1dSLionel Sambuc }
3499*0a6a1f1dSLionel Sambuc 
ActOnCapturedRegionStart(SourceLocation Loc,Scope * CurScope,CapturedRegionKind Kind,ArrayRef<CapturedParamNameType> Params)3500*0a6a1f1dSLionel Sambuc void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
3501*0a6a1f1dSLionel Sambuc                                     CapturedRegionKind Kind,
3502*0a6a1f1dSLionel Sambuc                                     ArrayRef<CapturedParamNameType> Params) {
3503*0a6a1f1dSLionel Sambuc   CapturedDecl *CD = nullptr;
3504*0a6a1f1dSLionel Sambuc   RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, Params.size());
3505*0a6a1f1dSLionel Sambuc 
3506*0a6a1f1dSLionel Sambuc   // Build the context parameter
3507*0a6a1f1dSLionel Sambuc   DeclContext *DC = CapturedDecl::castToDeclContext(CD);
3508*0a6a1f1dSLionel Sambuc   bool ContextIsFound = false;
3509*0a6a1f1dSLionel Sambuc   unsigned ParamNum = 0;
3510*0a6a1f1dSLionel Sambuc   for (ArrayRef<CapturedParamNameType>::iterator I = Params.begin(),
3511*0a6a1f1dSLionel Sambuc                                                  E = Params.end();
3512*0a6a1f1dSLionel Sambuc        I != E; ++I, ++ParamNum) {
3513*0a6a1f1dSLionel Sambuc     if (I->second.isNull()) {
3514*0a6a1f1dSLionel Sambuc       assert(!ContextIsFound &&
3515*0a6a1f1dSLionel Sambuc              "null type has been found already for '__context' parameter");
3516*0a6a1f1dSLionel Sambuc       IdentifierInfo *ParamName = &Context.Idents.get("__context");
3517*0a6a1f1dSLionel Sambuc       QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
3518*0a6a1f1dSLionel Sambuc       ImplicitParamDecl *Param
3519*0a6a1f1dSLionel Sambuc         = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
3520*0a6a1f1dSLionel Sambuc       DC->addDecl(Param);
3521*0a6a1f1dSLionel Sambuc       CD->setContextParam(ParamNum, Param);
3522*0a6a1f1dSLionel Sambuc       ContextIsFound = true;
3523*0a6a1f1dSLionel Sambuc     } else {
3524*0a6a1f1dSLionel Sambuc       IdentifierInfo *ParamName = &Context.Idents.get(I->first);
3525*0a6a1f1dSLionel Sambuc       ImplicitParamDecl *Param
3526*0a6a1f1dSLionel Sambuc         = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, I->second);
3527*0a6a1f1dSLionel Sambuc       DC->addDecl(Param);
3528*0a6a1f1dSLionel Sambuc       CD->setParam(ParamNum, Param);
3529*0a6a1f1dSLionel Sambuc     }
3530*0a6a1f1dSLionel Sambuc   }
3531*0a6a1f1dSLionel Sambuc   assert(ContextIsFound && "no null type for '__context' parameter");
3532*0a6a1f1dSLionel Sambuc   if (!ContextIsFound) {
3533*0a6a1f1dSLionel Sambuc     // Add __context implicitly if it is not specified.
3534*0a6a1f1dSLionel Sambuc     IdentifierInfo *ParamName = &Context.Idents.get("__context");
3535*0a6a1f1dSLionel Sambuc     QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
3536*0a6a1f1dSLionel Sambuc     ImplicitParamDecl *Param =
3537*0a6a1f1dSLionel Sambuc         ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
3538*0a6a1f1dSLionel Sambuc     DC->addDecl(Param);
3539*0a6a1f1dSLionel Sambuc     CD->setContextParam(ParamNum, Param);
3540*0a6a1f1dSLionel Sambuc   }
3541f4a2713aSLionel Sambuc   // Enter the capturing scope for this captured region.
3542f4a2713aSLionel Sambuc   PushCapturedRegionScope(CurScope, CD, RD, Kind);
3543f4a2713aSLionel Sambuc 
3544f4a2713aSLionel Sambuc   if (CurScope)
3545f4a2713aSLionel Sambuc     PushDeclContext(CurScope, CD);
3546f4a2713aSLionel Sambuc   else
3547f4a2713aSLionel Sambuc     CurContext = CD;
3548f4a2713aSLionel Sambuc 
3549f4a2713aSLionel Sambuc   PushExpressionEvaluationContext(PotentiallyEvaluated);
3550f4a2713aSLionel Sambuc }
3551f4a2713aSLionel Sambuc 
ActOnCapturedRegionError()3552f4a2713aSLionel Sambuc void Sema::ActOnCapturedRegionError() {
3553f4a2713aSLionel Sambuc   DiscardCleanupsInEvaluationContext();
3554f4a2713aSLionel Sambuc   PopExpressionEvaluationContext();
3555f4a2713aSLionel Sambuc 
3556f4a2713aSLionel Sambuc   CapturedRegionScopeInfo *RSI = getCurCapturedRegion();
3557f4a2713aSLionel Sambuc   RecordDecl *Record = RSI->TheRecordDecl;
3558f4a2713aSLionel Sambuc   Record->setInvalidDecl();
3559f4a2713aSLionel Sambuc 
3560*0a6a1f1dSLionel Sambuc   SmallVector<Decl*, 4> Fields(Record->fields());
3561*0a6a1f1dSLionel Sambuc   ActOnFields(/*Scope=*/nullptr, Record->getLocation(), Record, Fields,
3562*0a6a1f1dSLionel Sambuc               SourceLocation(), SourceLocation(), /*AttributeList=*/nullptr);
3563f4a2713aSLionel Sambuc 
3564f4a2713aSLionel Sambuc   PopDeclContext();
3565f4a2713aSLionel Sambuc   PopFunctionScopeInfo();
3566f4a2713aSLionel Sambuc }
3567f4a2713aSLionel Sambuc 
ActOnCapturedRegionEnd(Stmt * S)3568f4a2713aSLionel Sambuc StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) {
3569f4a2713aSLionel Sambuc   CapturedRegionScopeInfo *RSI = getCurCapturedRegion();
3570f4a2713aSLionel Sambuc 
3571f4a2713aSLionel Sambuc   SmallVector<CapturedStmt::Capture, 4> Captures;
3572f4a2713aSLionel Sambuc   SmallVector<Expr *, 4> CaptureInits;
3573f4a2713aSLionel Sambuc   buildCapturedStmtCaptureList(Captures, CaptureInits, RSI->Captures);
3574f4a2713aSLionel Sambuc 
3575f4a2713aSLionel Sambuc   CapturedDecl *CD = RSI->TheCapturedDecl;
3576f4a2713aSLionel Sambuc   RecordDecl *RD = RSI->TheRecordDecl;
3577f4a2713aSLionel Sambuc 
3578f4a2713aSLionel Sambuc   CapturedStmt *Res = CapturedStmt::Create(getASTContext(), S,
3579f4a2713aSLionel Sambuc                                            RSI->CapRegionKind, Captures,
3580f4a2713aSLionel Sambuc                                            CaptureInits, CD, RD);
3581f4a2713aSLionel Sambuc 
3582f4a2713aSLionel Sambuc   CD->setBody(Res->getCapturedStmt());
3583f4a2713aSLionel Sambuc   RD->completeDefinition();
3584f4a2713aSLionel Sambuc 
3585f4a2713aSLionel Sambuc   DiscardCleanupsInEvaluationContext();
3586f4a2713aSLionel Sambuc   PopExpressionEvaluationContext();
3587f4a2713aSLionel Sambuc 
3588f4a2713aSLionel Sambuc   PopDeclContext();
3589f4a2713aSLionel Sambuc   PopFunctionScopeInfo();
3590f4a2713aSLionel Sambuc 
3591*0a6a1f1dSLionel Sambuc   return Res;
3592f4a2713aSLionel Sambuc }
3593