summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 18:11:16 +0000
committerdim <dim@FreeBSD.org>2014-11-24 18:11:16 +0000
commit6148c19c738a92f344008aa3f88f4e008bada0ee (patch)
treed4426858455f04d0d8c25a2f9eb9ea5582ffe1b6 /contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
parent2c8643c6396b0a3db33430cf9380e70bbb9efce0 (diff)
parent173a4f43a911175643bda81ee675e8d9269056ea (diff)
downloadFreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.zip
FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.tar.gz
Merge clang 3.5.0 release from ^/vendor/clang/dist, resolve conflicts,
and preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp734
1 files changed, 457 insertions, 277 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
index 9bd8678..278e6d6 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
@@ -49,7 +49,7 @@ StmtResult Sema::ActOnExprStmt(ExprResult FE) {
// operand, even incomplete types.
// Same thing in for stmt first clause (when expr) and third clause.
- return Owned(static_cast<Stmt*>(FE.take()));
+ return StmtResult(FE.getAs<Stmt>());
}
@@ -60,7 +60,7 @@ StmtResult Sema::ActOnExprStmtError() {
StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,
bool HasLeadingEmptyMacro) {
- return Owned(new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro));
+ return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);
}
StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
@@ -70,7 +70,7 @@ StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
// If we have an invalid decl, just return an error.
if (DG.isNull()) return StmtError();
- return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
+ return new (Context) DeclStmt(DG, StartLoc, EndLoc);
}
void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
@@ -95,7 +95,7 @@ void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
// foreach variables are never actually initialized in the way that
// the parser came up with.
- var->setInit(0);
+ var->setInit(nullptr);
// In ARC, we don't need to retain the iteration variable of a fast
// enumeration loop. Rather than actually trying to catch that
@@ -114,25 +114,38 @@ void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
}
}
-/// \brief Diagnose unused '==' and '!=' as likely typos for '=' or '|='.
+/// \brief Diagnose unused comparisons, both builtin and overloaded operators.
+/// For '==' and '!=', suggest fixits for '=' or '|='.
///
/// Adding a cast to void (or other expression wrappers) will prevent the
/// warning from firing.
static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) {
SourceLocation Loc;
- bool IsNotEqual, CanAssign;
+ bool IsNotEqual, CanAssign, IsRelational;
if (const BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {
- if (Op->getOpcode() != BO_EQ && Op->getOpcode() != BO_NE)
+ if (!Op->isComparisonOp())
return false;
+ IsRelational = Op->isRelationalOp();
Loc = Op->getOperatorLoc();
IsNotEqual = Op->getOpcode() == BO_NE;
CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();
} else if (const CXXOperatorCallExpr *Op = dyn_cast<CXXOperatorCallExpr>(E)) {
- if (Op->getOperator() != OO_EqualEqual &&
- Op->getOperator() != OO_ExclaimEqual)
+ switch (Op->getOperator()) {
+ default:
return false;
+ case OO_EqualEqual:
+ case OO_ExclaimEqual:
+ IsRelational = false;
+ break;
+ case OO_Less:
+ case OO_Greater:
+ case OO_GreaterEqual:
+ case OO_LessEqual:
+ IsRelational = true;
+ break;
+ }
Loc = Op->getOperatorLoc();
IsNotEqual = Op->getOperator() == OO_ExclaimEqual;
@@ -148,11 +161,11 @@ static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) {
return false;
S.Diag(Loc, diag::warn_unused_comparison)
- << (unsigned)IsNotEqual << E->getSourceRange();
+ << (unsigned)IsRelational << (unsigned)IsNotEqual << E->getSourceRange();
// If the LHS is a plausible entity to assign to, provide a fixit hint to
// correct common typos.
- if (CanAssign) {
+ if (!IsRelational && CanAssign) {
if (IsNotEqual)
S.Diag(Loc, diag::note_inequality_comparison_to_or_assign)
<< FixItHint::CreateReplacement(Loc, "|=");
@@ -216,17 +229,17 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
// is written in a macro body, only warn if it has the warn_unused_result
// attribute.
if (const Decl *FD = CE->getCalleeDecl()) {
- if (FD->getAttr<WarnUnusedResultAttr>()) {
+ if (FD->hasAttr<WarnUnusedResultAttr>()) {
Diag(Loc, diag::warn_unused_result) << R1 << R2;
return;
}
if (ShouldSuppress)
return;
- if (FD->getAttr<PureAttr>()) {
+ if (FD->hasAttr<PureAttr>()) {
Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
return;
}
- if (FD->getAttr<ConstAttr>()) {
+ if (FD->hasAttr<ConstAttr>()) {
Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
return;
}
@@ -240,9 +253,15 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
return;
}
const ObjCMethodDecl *MD = ME->getMethodDecl();
- if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
- Diag(Loc, diag::warn_unused_result) << R1 << R2;
- return;
+ if (MD) {
+ if (MD->hasAttr<WarnUnusedResultAttr>()) {
+ Diag(Loc, diag::warn_unused_result) << R1 << R2;
+ return;
+ }
+ if (MD->isPropertyAccessor()) {
+ Diag(Loc, diag::warn_unused_property_expr);
+ return;
+ }
}
} else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
const Expr *Source = POE->getSyntacticForm();
@@ -276,7 +295,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
return;
}
- DiagRuntimeBehavior(Loc, 0, PDiag(DiagID) << R1 << R2);
+ DiagRuntimeBehavior(Loc, nullptr, PDiag(DiagID) << R1 << R2);
}
void Sema::ActOnStartOfCompoundStmt() {
@@ -331,14 +350,14 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
}
- return Owned(new (Context) CompoundStmt(Context, Elts, L, R));
+ return new (Context) CompoundStmt(Context, Elts, L, R);
}
StmtResult
Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
SourceLocation DotDotDotLoc, Expr *RHSVal,
SourceLocation ColonLoc) {
- assert((LHSVal != 0) && "missing expression in case statement");
+ assert(LHSVal && "missing expression in case statement");
if (getCurFunction()->SwitchStack.empty()) {
Diag(CaseLoc, diag::err_case_not_in_switch);
@@ -349,7 +368,7 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
// C99 6.8.4.2p3: The expression shall be an integer constant.
// However, GCC allows any evaluatable integer expression.
if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent()) {
- LHSVal = VerifyIntegerConstantExpression(LHSVal).take();
+ LHSVal = VerifyIntegerConstantExpression(LHSVal).get();
if (!LHSVal)
return StmtError();
}
@@ -357,21 +376,21 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
// GCC extension: The expression shall be an integer constant.
if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent()) {
- RHSVal = VerifyIntegerConstantExpression(RHSVal).take();
+ RHSVal = VerifyIntegerConstantExpression(RHSVal).get();
// Recover from an error by just forgetting about it.
}
}
LHSVal = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
- getLangOpts().CPlusPlus11).take();
+ getLangOpts().CPlusPlus11).get();
if (RHSVal)
RHSVal = ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false,
- getLangOpts().CPlusPlus11).take();
+ getLangOpts().CPlusPlus11).get();
CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
ColonLoc);
getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
- return Owned(CS);
+ return CS;
}
/// ActOnCaseStmtBody - This installs a statement as the body of a case.
@@ -389,12 +408,12 @@ Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
if (getCurFunction()->SwitchStack.empty()) {
Diag(DefaultLoc, diag::err_default_not_in_switch);
- return Owned(SubStmt);
+ return SubStmt;
}
DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
- return Owned(DS);
+ return DS;
}
StmtResult
@@ -404,7 +423,7 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
if (TheDecl->getStmt()) {
Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();
Diag(TheDecl->getLocation(), diag::note_previous_definition);
- return Owned(SubStmt);
+ return SubStmt;
}
// Otherwise, things are good. Fill in the declaration and return it.
@@ -414,7 +433,7 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
TheDecl->setLocStart(IdentLoc);
TheDecl->setLocation(IdentLoc);
}
- return Owned(LS);
+ return LS;
}
StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc,
@@ -422,7 +441,7 @@ StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc,
Stmt *SubStmt) {
// Fill in the declaration and return it.
AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt);
- return Owned(LS);
+ return LS;
}
StmtResult
@@ -438,14 +457,14 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
ExprResult CondResult(CondVal.release());
- VarDecl *ConditionVar = 0;
+ VarDecl *ConditionVar = nullptr;
if (CondVar) {
ConditionVar = cast<VarDecl>(CondVar);
CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
if (CondResult.isInvalid())
return StmtError();
}
- Expr *ConditionExpr = CondResult.takeAs<Expr>();
+ Expr *ConditionExpr = CondResult.getAs<Expr>();
if (!ConditionExpr)
return StmtError();
@@ -458,8 +477,8 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
DiagnoseUnusedExprResult(elseStmt);
- return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
- thenStmt, ElseLoc, elseStmt));
+ return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
+ thenStmt, ElseLoc, elseStmt);
}
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
@@ -499,7 +518,6 @@ void Sema::ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &Val,
// We don't diagnose this overflow, because it is implementation-defined
// behavior.
// FIXME: Introduce a second, default-ignored warning for this case?
- llvm::APSInt OldVal(Val);
Val.setIsSigned(NewSign);
}
}
@@ -568,14 +586,14 @@ Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
Decl *CondVar) {
ExprResult CondResult;
- VarDecl *ConditionVar = 0;
+ VarDecl *ConditionVar = nullptr;
if (CondVar) {
ConditionVar = cast<VarDecl>(CondVar);
CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.release();
+ Cond = CondResult.get();
}
if (!Cond)
@@ -589,41 +607,41 @@ Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
: ICEConvertDiagnoser(/*AllowScopedEnumerations*/true, false, true),
Cond(Cond) {}
- virtual SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
- QualType T) {
+ SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+ QualType T) override {
return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T;
}
- virtual SemaDiagnosticBuilder diagnoseIncomplete(
- Sema &S, SourceLocation Loc, QualType T) {
+ SemaDiagnosticBuilder diagnoseIncomplete(
+ Sema &S, SourceLocation Loc, QualType T) override {
return S.Diag(Loc, diag::err_switch_incomplete_class_type)
<< T << Cond->getSourceRange();
}
- virtual SemaDiagnosticBuilder diagnoseExplicitConv(
- Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+ SemaDiagnosticBuilder diagnoseExplicitConv(
+ Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy;
}
- virtual SemaDiagnosticBuilder noteExplicitConv(
- Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+ SemaDiagnosticBuilder noteExplicitConv(
+ Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
}
- virtual SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
- QualType T) {
+ SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+ QualType T) override {
return S.Diag(Loc, diag::err_switch_multiple_conversions) << T;
}
- virtual SemaDiagnosticBuilder noteAmbiguous(
- Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+ SemaDiagnosticBuilder noteAmbiguous(
+ Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
}
- virtual SemaDiagnosticBuilder diagnoseConversion(
- Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+ SemaDiagnosticBuilder diagnoseConversion(
+ Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
llvm_unreachable("conversion functions are permitted");
}
} SwitchDiagnoser(Cond);
@@ -631,25 +649,25 @@ Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
CondResult =
PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);
if (CondResult.isInvalid()) return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
// C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
CondResult = UsualUnaryConversions(Cond);
if (CondResult.isInvalid()) return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
if (!CondVar) {
CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
}
getCurFunction()->setHasBranchIntoScope();
SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
getCurFunction()->SwitchStack.push_back(SS);
- return Owned(SS);
+ return SS;
}
static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
@@ -660,6 +678,29 @@ static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
Val.setIsSigned(IsSigned);
}
+/// Returns true if we should emit a diagnostic about this case expression not
+/// being a part of the enum used in the switch controlling expression.
+static bool ShouldDiagnoseSwitchCaseNotInEnum(const ASTContext &Ctx,
+ const EnumDecl *ED,
+ const Expr *CaseExpr) {
+ // Don't warn if the 'case' expression refers to a static const variable of
+ // the enum type.
+ CaseExpr = CaseExpr->IgnoreParenImpCasts();
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseExpr)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+ if (!VD->hasGlobalStorage())
+ return true;
+ QualType VarType = VD->getType();
+ if (!VarType.isConstQualified())
+ return true;
+ QualType EnumType = Ctx.getTypeDeclType(ED);
+ if (Ctx.hasSameUnqualifiedType(EnumType, VarType))
+ return false;
+ }
+ }
+ return true;
+}
+
StmtResult
Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
Stmt *BodyStmt) {
@@ -667,6 +708,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
assert(SS == getCurFunction()->SwitchStack.back() &&
"switch stack missing push/pop!");
+ if (!BodyStmt) return StmtError();
SS->setBody(BodyStmt, SwitchLoc);
getCurFunction()->SwitchStack.pop_back();
@@ -721,7 +763,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
CaseRangesTy CaseRanges;
- DefaultStmt *TheDefaultStmt = 0;
+ DefaultStmt *TheDefaultStmt = nullptr;
bool CaseListIsErroneous = false;
@@ -762,7 +804,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
CaseListIsErroneous = true;
continue;
}
- Lo = ConvLo.take();
+ Lo = ConvLo.get();
} else {
// We already verified that the expression has a i-c-e value (C99
// 6.8.4.2p3) - get that value now.
@@ -770,8 +812,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// If the LHS is not the same type as the condition, insert an implicit
// cast.
- Lo = DefaultLvalueConversion(Lo).take();
- Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).take();
+ Lo = DefaultLvalueConversion(Lo).get();
+ Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).get();
}
// Convert the value to the same width/sign as the condition had prior to
@@ -883,14 +925,14 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
CaseListIsErroneous = true;
continue;
}
- Hi = ConvHi.take();
+ Hi = ConvHi.get();
} else {
HiVal = Hi->EvaluateKnownConstInt(Context);
// If the RHS is not the same type as the condition, insert an
// implicit cast.
- Hi = DefaultLvalueConversion(Hi).take();
- Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).take();
+ Hi = DefaultLvalueConversion(Hi).get();
+ Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).get();
}
// Convert the value to the same width/sign as the condition.
@@ -928,7 +970,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// Check to see whether the case range overlaps with any
// singleton cases.
- CaseStmt *OverlapStmt = 0;
+ CaseStmt *OverlapStmt = nullptr;
llvm::APSInt OverlapVal(32);
// Find the smallest value >= the lower bound. If I is in the
@@ -993,11 +1035,10 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// Gather all enum values, set their type and sort them,
// allowing easier comparison with CaseVals.
- for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin();
- EDI != ED->enumerator_end(); ++EDI) {
+ for (auto *EDI : ED->enumerators()) {
llvm::APSInt Val = EDI->getInitVal();
AdjustAPSInt(Val, CondWidth, CondIsSigned);
- EnumVals.push_back(std::make_pair(Val, *EDI));
+ EnumVals.push_back(std::make_pair(Val, EDI));
}
std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
EnumValsTy::iterator EIend =
@@ -1009,9 +1050,12 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
CI != CaseVals.end(); CI++) {
while (EI != EIend && EI->first < CI->first)
EI++;
- if (EI == EIend || EI->first > CI->first)
- Diag(CI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum)
- << CondTypeBeforePromotion;
+ if (EI == EIend || EI->first > CI->first) {
+ Expr *CaseExpr = CI->second->getLHS();
+ if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+ Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+ << CondTypeBeforePromotion;
+ }
}
// See which of case ranges aren't in enum
EI = EnumVals.begin();
@@ -1021,8 +1065,10 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
EI++;
if (EI == EIend || EI->first != RI->first) {
- Diag(RI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum)
- << CondTypeBeforePromotion;
+ Expr *CaseExpr = RI->second->getLHS();
+ if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+ Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+ << CondTypeBeforePromotion;
}
llvm::APSInt Hi =
@@ -1030,9 +1076,12 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
AdjustAPSInt(Hi, CondWidth, CondIsSigned);
while (EI != EIend && EI->first < Hi)
EI++;
- if (EI == EIend || EI->first != Hi)
- Diag(RI->second->getRHS()->getExprLoc(), diag::warn_not_in_enum)
- << CondTypeBeforePromotion;
+ if (EI == EIend || EI->first != Hi) {
+ Expr *CaseExpr = RI->second->getRHS();
+ if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+ Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+ << CondTypeBeforePromotion;
+ }
}
// Check which enum vals aren't in switch
@@ -1044,7 +1093,6 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
for (EI = EnumVals.begin(); EI != EIend; EI++){
// Drop unneeded case values
- llvm::APSInt CIVal;
while (CI != CaseVals.end() && CI->first < EI->first)
CI++;
@@ -1100,27 +1148,26 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
}
}
- DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), BodyStmt,
- diag::warn_empty_switch_body);
+ if (BodyStmt)
+ DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), BodyStmt,
+ diag::warn_empty_switch_body);
// FIXME: If the case list was broken is some way, we don't have a good system
// to patch it up. Instead, just return the whole substmt as broken.
if (CaseListIsErroneous)
return StmtError();
- return Owned(SS);
+ return SS;
}
void
Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
Expr *SrcExpr) {
- if (Diags.getDiagnosticLevel(diag::warn_not_in_enum_assignment,
- SrcExpr->getExprLoc()) ==
- DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))
return;
if (const EnumType *ET = DstType->getAs<EnumType>())
- if (!Context.hasSameType(SrcType, DstType) &&
+ if (!Context.hasSameUnqualifiedType(SrcType, DstType) &&
SrcType->isIntegerType()) {
if (!SrcExpr->isTypeDependent() && !SrcExpr->isValueDependent() &&
SrcExpr->isIntegerConstantExpr(Context)) {
@@ -1137,11 +1184,10 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
// Gather all enum values, set their type and sort them,
// allowing easier comparison with rhs constant.
- for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin();
- EDI != ED->enumerator_end(); ++EDI) {
+ for (auto *EDI : ED->enumerators()) {
llvm::APSInt Val = EDI->getInitVal();
AdjustAPSInt(Val, DstWidth, DstIsSigned);
- EnumVals.push_back(std::make_pair(Val, *EDI));
+ EnumVals.push_back(std::make_pair(Val, EDI));
}
if (EnumVals.empty())
return;
@@ -1155,7 +1201,7 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
EI++;
if (EI == EIend || EI->first != RhsVal) {
Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
- << DstType;
+ << DstType.getUnqualifiedType();
}
}
}
@@ -1166,24 +1212,25 @@ Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
Decl *CondVar, Stmt *Body) {
ExprResult CondResult(Cond.release());
- VarDecl *ConditionVar = 0;
+ VarDecl *ConditionVar = nullptr;
if (CondVar) {
ConditionVar = cast<VarDecl>(CondVar);
CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
if (CondResult.isInvalid())
return StmtError();
}
- Expr *ConditionExpr = CondResult.take();
+ Expr *ConditionExpr = CondResult.get();
if (!ConditionExpr)
return StmtError();
+ CheckBreakContinueBinding(ConditionExpr);
DiagnoseUnusedExprResult(Body);
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
- return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
- Body, WhileLoc));
+ return new (Context)
+ WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);
}
StmtResult
@@ -1192,19 +1239,20 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
Expr *Cond, SourceLocation CondRParen) {
assert(Cond && "ActOnDoStmt(): missing expression");
+ CheckBreakContinueBinding(Cond);
ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
CondResult = ActOnFinishFullExpr(Cond, DoLoc);
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
DiagnoseUnusedExprResult(Body);
- return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
+ return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
}
namespace {
@@ -1362,9 +1410,8 @@ namespace {
// Condition is empty
if (!Second) return;
- if (S.Diags.getDiagnosticLevel(diag::warn_variables_not_in_loop_body,
- Second->getLocStart())
- == DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,
+ Second->getLocStart()))
return;
PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body);
@@ -1454,25 +1501,33 @@ namespace {
return false;
}
- // A visitor to determine if a continue statement is a subexpression.
- class ContinueFinder : public EvaluatedExprVisitor<ContinueFinder> {
- bool Found;
+ // A visitor to determine if a continue or break statement is a
+ // subexpression.
+ class BreakContinueFinder : public EvaluatedExprVisitor<BreakContinueFinder> {
+ SourceLocation BreakLoc;
+ SourceLocation ContinueLoc;
public:
- ContinueFinder(Sema &S, Stmt* Body) :
- Inherited(S.Context),
- Found(false) {
+ BreakContinueFinder(Sema &S, Stmt* Body) :
+ Inherited(S.Context) {
Visit(Body);
}
- typedef EvaluatedExprVisitor<ContinueFinder> Inherited;
+ typedef EvaluatedExprVisitor<BreakContinueFinder> Inherited;
void VisitContinueStmt(ContinueStmt* E) {
- Found = true;
+ ContinueLoc = E->getContinueLoc();
+ }
+
+ void VisitBreakStmt(BreakStmt* E) {
+ BreakLoc = E->getBreakLoc();
}
- bool ContinueFound() { return Found; }
+ bool ContinueFound() { return ContinueLoc.isValid(); }
+ bool BreakFound() { return BreakLoc.isValid(); }
+ SourceLocation GetContinueLoc() { return ContinueLoc; }
+ SourceLocation GetBreakLoc() { return BreakLoc; }
- }; // end class ContinueFinder
+ }; // end class BreakContinueFinder
// Emit a warning when a loop increment/decrement appears twice per loop
// iteration. The conditions which trigger this warning are:
@@ -1483,9 +1538,8 @@ namespace {
// Return when there is nothing to check.
if (!Body || !Third) return;
- if (S.Diags.getDiagnosticLevel(diag::warn_redundant_loop_iteration,
- Third->getLocStart())
- == DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,
+ Third->getLocStart()))
return;
// Get the last statement from the loop body.
@@ -1501,11 +1555,11 @@ namespace {
if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE)) return;
// Check that the two statements are both increments or both decrements
- // on the same varaible.
+ // on the same variable.
if (LoopIncrement != LastIncrement ||
LoopDRE->getDecl() != LastDRE->getDecl()) return;
- if (ContinueFinder(S, Body).ContinueFound()) return;
+ if (BreakContinueFinder(S, Body).ContinueFound()) return;
S.Diag(LastDRE->getLocation(), diag::warn_redundant_loop_iteration)
<< LastDRE->getDecl() << LastIncrement;
@@ -1515,6 +1569,25 @@ namespace {
} // end namespace
+
+void Sema::CheckBreakContinueBinding(Expr *E) {
+ if (!E || getLangOpts().CPlusPlus)
+ return;
+ BreakContinueFinder BCFinder(*this, E);
+ Scope *BreakParent = CurScope->getBreakParent();
+ if (BCFinder.BreakFound() && BreakParent) {
+ if (BreakParent->getFlags() & Scope::SwitchScope) {
+ Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);
+ } else {
+ Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)
+ << "break";
+ }
+ } else if (BCFinder.ContinueFound() && CurScope->getContinueParent()) {
+ Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)
+ << "continue";
+ }
+}
+
StmtResult
Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
Stmt *First, FullExprArg second, Decl *secondVar,
@@ -1525,24 +1598,26 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
// C99 6.8.5p3: The declaration part of a 'for' statement shall only
// declare identifiers for objects having storage class 'auto' or
// 'register'.
- for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
- DI!=DE; ++DI) {
- VarDecl *VD = dyn_cast<VarDecl>(*DI);
+ for (auto *DI : DS->decls()) {
+ VarDecl *VD = dyn_cast<VarDecl>(DI);
if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage())
- VD = 0;
- if (VD == 0) {
- Diag((*DI)->getLocation(), diag::err_non_local_variable_decl_in_for);
- (*DI)->setInvalidDecl();
+ VD = nullptr;
+ if (!VD) {
+ Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
+ DI->setInvalidDecl();
}
}
}
}
+ CheckBreakContinueBinding(second.get());
+ CheckBreakContinueBinding(third.get());
+
CheckForLoopConditionalStatement(*this, second.get(), third.get(), Body);
CheckForRedundantIteration(*this, third.get(), Body);
ExprResult SecondResult(second.release());
- VarDecl *ConditionVar = 0;
+ VarDecl *ConditionVar = nullptr;
if (secondVar) {
ConditionVar = cast<VarDecl>(secondVar);
SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
@@ -1550,7 +1625,7 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
return StmtError();
}
- Expr *Third = third.release().takeAs<Expr>();
+ Expr *Third = third.release().getAs<Expr>();
DiagnoseUnusedExprResult(First);
DiagnoseUnusedExprResult(Third);
@@ -1559,10 +1634,8 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
- return Owned(new (Context) ForStmt(Context, First,
- SecondResult.take(), ConditionVar,
- Third, Body, ForLoc, LParenLoc,
- RParenLoc));
+ return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,
+ Third, Body, ForLoc, LParenLoc, RParenLoc);
}
/// In an Objective C collection iteration statement:
@@ -1574,12 +1647,12 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
// use of pseudo-object l-values in this position.
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return StmtError();
- E = result.take();
+ E = result.get();
ExprResult FullExpr = ActOnFinishFullExpr(E);
if (FullExpr.isInvalid())
return StmtError();
- return StmtResult(static_cast<Stmt*>(FullExpr.take()));
+ return StmtResult(static_cast<Stmt*>(FullExpr.get()));
}
ExprResult
@@ -1588,13 +1661,13 @@ Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {
return ExprError();
// Bail out early if we've got a type-dependent expression.
- if (collection->isTypeDependent()) return Owned(collection);
+ if (collection->isTypeDependent()) return collection;
// Perform normal l-value conversion.
ExprResult result = DefaultFunctionArrayLvalueConversion(collection);
if (result.isInvalid())
return ExprError();
- collection = result.take();
+ collection = result.get();
// The operand needs to have object-pointer type.
// TODO: should we do a contextual conversion?
@@ -1627,7 +1700,7 @@ Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {
};
Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]);
- ObjCMethodDecl *method = 0;
+ ObjCMethodDecl *method = nullptr;
// If there's an interface, look in both the public and private APIs.
if (iface) {
@@ -1650,7 +1723,7 @@ Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {
}
// Wrap up any cleanups in the expression.
- return Owned(collection);
+ return collection;
}
StmtResult
@@ -1725,13 +1798,12 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
if (CollectionExprResult.isInvalid())
return StmtError();
- CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.take());
+ CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
if (CollectionExprResult.isInvalid())
return StmtError();
- return Owned(new (Context) ObjCForCollectionStmt(First,
- CollectionExprResult.take(), 0,
- ForLoc, RParenLoc));
+ return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(),
+ nullptr, ForLoc, RParenLoc);
}
/// Finish building a variable declaration for a for-range statement.
@@ -1809,7 +1881,7 @@ VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc,
static bool ObjCEnumerationCollection(Expr *Collection) {
return !Collection->isTypeDependent()
- && Collection->getType()->getAs<ObjCObjectPointerType>() != 0;
+ && Collection->getType()->getAs<ObjCObjectPointerType>() != nullptr;
}
/// ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
@@ -1868,7 +1940,7 @@ Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc,
// Claim the type doesn't contain auto: we've already done the checking.
DeclGroupPtrTy RangeGroup =
- BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
+ BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
/*TypeMayContainAuto=*/ false);
StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);
if (RangeDecl.isInvalid()) {
@@ -1877,8 +1949,8 @@ Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc,
}
return BuildCXXForRangeStmt(ForLoc, ColonLoc, RangeDecl.get(),
- /*BeginEndDecl=*/0, /*Cond=*/0, /*Inc=*/0, DS,
- RParenLoc, Kind);
+ /*BeginEndDecl=*/nullptr, /*Cond=*/nullptr,
+ /*Inc=*/nullptr, DS, RParenLoc, Kind);
}
/// \brief Create the initialization, compare, and increment steps for
@@ -2100,9 +2172,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
// Find the array bound.
ExprResult BoundExpr;
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(UnqAT))
- BoundExpr = Owned(IntegerLiteral::Create(Context, CAT->getSize(),
- Context.getPointerDiffType(),
- RangeLoc));
+ BoundExpr = IntegerLiteral::Create(
+ Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);
else if (const VariableArrayType *VAT =
dyn_cast<VariableArrayType>(UnqAT))
BoundExpr = VAT->getSizeExpr();
@@ -2123,7 +2194,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
return StmtError();
}
} else {
- OverloadCandidateSet CandidateSet(RangeLoc);
+ OverloadCandidateSet CandidateSet(RangeLoc,
+ OverloadCandidateSet::CSK_Normal);
Sema::BeginEndFunction BEFFailure;
ForRangeStatus RangeStatus =
BuildNonArrayForRange(*this, S, BeginRangeRef.get(),
@@ -2185,7 +2257,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
Decl *BeginEndDecls[] = { BeginVar, EndVar };
// Claim the type doesn't contain auto: we've already done the checking.
DeclGroupPtrTy BeginEndGroup =
- BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>(BeginEndDecls, 2),
+ BuildDeclaratorGroup(MutableArrayRef<Decl *>(BeginEndDecls, 2),
/*TypeMayContainAuto=*/ false);
BeginEndDecl = ActOnDeclStmt(BeginEndGroup, ColonLoc, ColonLoc);
@@ -2258,11 +2330,9 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
if (Kind == BFRK_Check)
return StmtResult();
- return Owned(new (Context) CXXForRangeStmt(RangeDS,
- cast_or_null<DeclStmt>(BeginEndDecl.get()),
- NotEqExpr.take(), IncrExpr.take(),
- LoopVarDS, /*Body=*/0, ForLoc,
- ColonLoc, RParenLoc));
+ return new (Context) CXXForRangeStmt(
+ RangeDS, cast_or_null<DeclStmt>(BeginEndDecl.get()), NotEqExpr.get(),
+ IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, ColonLoc, RParenLoc);
}
/// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach
@@ -2301,7 +2371,7 @@ StmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc,
LabelDecl *TheDecl) {
getCurFunction()->setHasBranchIntoScope();
TheDecl->markUsed(Context);
- return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc));
+ return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
}
StmtResult
@@ -2311,12 +2381,12 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
if (!E->isTypeDependent()) {
QualType ETy = E->getType();
QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
- ExprResult ExprRes = Owned(E);
+ ExprResult ExprRes = E;
AssignConvertType ConvTy =
CheckSingleAssignmentConstraints(DestTy, ExprRes);
if (ExprRes.isInvalid())
return StmtError();
- E = ExprRes.take();
+ E = ExprRes.get();
if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
return StmtError();
}
@@ -2324,11 +2394,11 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
ExprResult ExprRes = ActOnFinishFullExpr(E);
if (ExprRes.isInvalid())
return StmtError();
- E = ExprRes.take();
+ E = ExprRes.get();
getCurFunction()->setHasIndirectGoto();
- return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
+ return new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E);
}
StmtResult
@@ -2339,7 +2409,7 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
}
- return Owned(new (Context) ContinueStmt(ContinueLoc));
+ return new (Context) ContinueStmt(ContinueLoc);
}
StmtResult
@@ -2349,8 +2419,11 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
// C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
}
+ if (S->isOpenMPLoopScope())
+ return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
+ << "break");
- return Owned(new (Context) BreakStmt(BreakLoc));
+ return new (Context) BreakStmt(BreakLoc);
}
/// \brief Determine whether the given expression is a candidate for
@@ -2371,52 +2444,62 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
///
/// \returns The NRVO candidate variable, if the return statement may use the
/// NRVO, or NULL if there is no such candidate.
-const VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,
- Expr *E,
- bool AllowFunctionParameter) {
- QualType ExprType = E->getType();
+VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,
+ Expr *E,
+ bool AllowFunctionParameter) {
+ if (!getLangOpts().CPlusPlus)
+ return nullptr;
+
+ // - in a return statement in a function [where] ...
+ // ... the expression is the name of a non-volatile automatic object ...
+ DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
+ if (!DR || DR->refersToEnclosingLocal())
+ return nullptr;
+ VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
+ if (!VD)
+ return nullptr;
+
+ if (isCopyElisionCandidate(ReturnType, VD, AllowFunctionParameter))
+ return VD;
+ return nullptr;
+}
+
+bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
+ bool AllowFunctionParameter) {
+ QualType VDType = VD->getType();
// - in a return statement in a function with ...
// ... a class return type ...
- if (!ReturnType.isNull()) {
+ if (!ReturnType.isNull() && !ReturnType->isDependentType()) {
if (!ReturnType->isRecordType())
- return 0;
+ return false;
// ... the same cv-unqualified type as the function return type ...
- if (!Context.hasSameUnqualifiedType(ReturnType, ExprType))
- return 0;
+ if (!VDType->isDependentType() &&
+ !Context.hasSameUnqualifiedType(ReturnType, VDType))
+ return false;
}
- // ... the expression is the name of a non-volatile automatic object
- // (other than a function or catch-clause parameter)) ...
- const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
- if (!DR || DR->refersToEnclosingLocal())
- return 0;
- const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
- if (!VD)
- return 0;
-
// ...object (other than a function or catch-clause parameter)...
if (VD->getKind() != Decl::Var &&
!(AllowFunctionParameter && VD->getKind() == Decl::ParmVar))
- return 0;
- if (VD->isExceptionVariable()) return 0;
+ return false;
+ if (VD->isExceptionVariable()) return false;
// ...automatic...
- if (!VD->hasLocalStorage()) return 0;
+ if (!VD->hasLocalStorage()) return false;
// ...non-volatile...
- if (VD->getType().isVolatileQualified()) return 0;
- if (VD->getType()->isReferenceType()) return 0;
+ if (VD->getType().isVolatileQualified()) return false;
// __block variables can't be allocated in a way that permits NRVO.
- if (VD->hasAttr<BlocksAttr>()) return 0;
+ if (VD->hasAttr<BlocksAttr>()) return false;
// Variables with higher required alignment than their type's ABI
// alignment cannot use NRVO.
- if (VD->hasAttr<AlignedAttr>() &&
+ if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType()))
- return 0;
+ return false;
- return VD;
+ return true;
}
/// \brief Perform the initialization of a potentially-movable value, which
@@ -2476,7 +2559,7 @@ Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
// Promote "AsRvalue" to the heap, since we now need this
// expression node to persist.
Value = ImplicitCastExpr::Create(Context, Value->getType(),
- CK_NoOp, Value, 0, VK_XValue);
+ CK_NoOp, Value, nullptr, VK_XValue);
// Complete type-checking the initialization of the return type
// using the constructor we found.
@@ -2499,7 +2582,7 @@ Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
static bool hasDeducedReturnType(FunctionDecl *FD) {
const FunctionProtoType *FPT =
FD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>();
- return FPT->getResultType()->isUndeducedType();
+ return FPT->getReturnType()->isUndeducedType();
}
/// ActOnCapScopeReturnStmt - Utility routine to type-check return statements
@@ -2518,7 +2601,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// FIXME: Blocks might have a return type of 'auto' explicitly specified.
FunctionDecl *FD = CurLambda->CallOperator;
if (CurCap->ReturnType.isNull())
- CurCap->ReturnType = FD->getResultType();
+ CurCap->ReturnType = FD->getReturnType();
AutoType *AT = CurCap->ReturnType->getContainedAutoType();
assert(AT && "lost auto type from lambda return type");
@@ -2526,7 +2609,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
FD->setInvalidDecl();
return StmtError();
}
- CurCap->ReturnType = FnRetType = FD->getResultType();
+ CurCap->ReturnType = FnRetType = FD->getReturnType();
} else if (CurCap->HasImplicitReturnType) {
// For blocks/lambdas with implicit return types, we check each return
// statement individually, and deduce the common return type when the block
@@ -2536,7 +2619,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
if (Result.isInvalid())
return StmtError();
- RetValExp = Result.take();
+ RetValExp = Result.get();
if (!CurContext->isDependentContext())
FnRetType = RetValExp->getType();
@@ -2582,7 +2665,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// Otherwise, verify that this result type matches the previous one. We are
// pickier with blocks than for normal functions because we don't have GCC
// compatibility to worry about here.
- const VarDecl *NRVOCandidate = 0;
+ const VarDecl *NRVOCandidate = nullptr;
if (FnRetType->isDependentType()) {
// Delay processing for now. TODO: there are lots of dependent
// types we can conclusively prove aren't void.
@@ -2596,7 +2679,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
Diag(ReturnLoc, diag::ext_return_has_void_expr) << "literal" << 2;
else {
Diag(ReturnLoc, diag::err_return_block_has_expr);
- RetValExp = 0;
+ RetValExp = nullptr;
}
}
} else if (!RetValExp) {
@@ -2613,22 +2696,24 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
FnRetType,
- NRVOCandidate != 0);
+ NRVOCandidate != nullptr);
ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
FnRetType, RetValExp);
if (Res.isInvalid()) {
// FIXME: Cleanup temporaries here, anyway?
return StmtError();
}
- RetValExp = Res.take();
- CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+ RetValExp = Res.get();
+ CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
+ } else {
+ NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
}
if (RetValExp) {
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
- RetValExp = ER.take();
+ RetValExp = ER.get();
}
ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp,
NRVOCandidate);
@@ -2636,12 +2721,10 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// If we need to check for the named return value optimization,
// or if we need to infer the return type,
// save the return statement in our scope for later processing.
- if (CurCap->HasImplicitReturnType ||
- (getLangOpts().CPlusPlus && FnRetType->isRecordType() &&
- !CurContext->isDependentContext()))
+ if (CurCap->HasImplicitReturnType || NRVOCandidate)
FunctionScopes.back()->Returns.push_back(Result);
- return Owned(Result);
+ return Result;
}
/// Deduce the return type for a function from a returned expression, per
@@ -2651,7 +2734,7 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
Expr *&RetExpr,
AutoType *AT) {
TypeLoc OrigResultType = FD->getTypeSourceInfo()->getTypeLoc().
- IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc();
+ IgnoreParens().castAs<FunctionProtoTypeLoc>().getReturnLoc();
QualType Deduced;
if (RetExpr && isa<InitListExpr>(RetExpr)) {
@@ -2735,7 +2818,24 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
}
StmtResult
-Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
+Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
+ Scope *CurScope) {
+ StmtResult R = BuildReturnStmt(ReturnLoc, RetValExp);
+ if (R.isInvalid()) {
+ return R;
+ }
+
+ if (VarDecl *VD =
+ const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate())) {
+ CurScope->addNRVOCandidate(VD);
+ } else {
+ CurScope->setNoNRVO();
+ }
+
+ return R;
+}
+
+StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// Check for unexpanded parameter packs.
if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
return StmtError();
@@ -2745,13 +2845,21 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
QualType FnRetType;
QualType RelatedRetType;
+ const AttrVec *Attrs = nullptr;
+ bool isObjCMethod = false;
+
if (const FunctionDecl *FD = getCurFunctionDecl()) {
- FnRetType = FD->getResultType();
+ FnRetType = FD->getReturnType();
+ if (FD->hasAttrs())
+ Attrs = &FD->getAttrs();
if (FD->isNoReturn())
Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
<< FD->getDeclName();
} else if (ObjCMethodDecl *MD = getCurMethodDecl()) {
- FnRetType = MD->getResultType();
+ FnRetType = MD->getReturnType();
+ isObjCMethod = true;
+ if (MD->hasAttrs())
+ Attrs = &MD->getAttrs();
if (MD->hasRelatedResultType() && MD->getClassInterface()) {
// In the implementation of a method with a related return type, the
// type used to type-check the validity of return statements within the
@@ -2771,14 +2879,14 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
FD->setInvalidDecl();
return StmtError();
} else {
- FnRetType = FD->getResultType();
+ FnRetType = FD->getReturnType();
}
}
}
bool HasDependentReturnType = FnRetType->isDependentType();
- ReturnStmt *Result = 0;
+ ReturnStmt *Result = nullptr;
if (FnRetType->isVoidType()) {
if (RetValExp) {
if (isa<InitListExpr>(RetValExp)) {
@@ -2799,24 +2907,36 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
<< RetValExp->getSourceRange();
// Drop the expression.
- RetValExp = 0;
+ RetValExp = nullptr;
} else if (!RetValExp->isTypeDependent()) {
// C99 6.8.6.4p1 (ext_ since GCC warns)
unsigned D = diag::ext_return_has_expr;
- if (RetValExp->getType()->isVoidType())
- D = diag::ext_return_has_void_expr;
+ if (RetValExp->getType()->isVoidType()) {
+ NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
+ if (isa<CXXConstructorDecl>(CurDecl) ||
+ isa<CXXDestructorDecl>(CurDecl))
+ D = diag::err_ctor_dtor_returns_void;
+ else
+ D = diag::ext_return_has_void_expr;
+ }
else {
- ExprResult Result = Owned(RetValExp);
- Result = IgnoredValueConversions(Result.take());
+ ExprResult Result = RetValExp;
+ Result = IgnoredValueConversions(Result.get());
if (Result.isInvalid())
return StmtError();
- RetValExp = Result.take();
+ RetValExp = Result.get();
RetValExp = ImpCastExprToType(RetValExp,
- Context.VoidTy, CK_ToVoid).take();
+ Context.VoidTy, CK_ToVoid).get();
+ }
+ // return of void in constructor/destructor is illegal in C++.
+ if (D == diag::err_ctor_dtor_returns_void) {
+ NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
+ Diag(ReturnLoc, D)
+ << CurDecl->getDeclName() << isa<CXXDestructorDecl>(CurDecl)
+ << RetValExp->getSourceRange();
}
-
// return (some void expression); is legal in C++.
- if (D != diag::ext_return_has_void_expr ||
+ else if (D != diag::ext_return_has_void_expr ||
!getLangOpts().CPlusPlus) {
NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
@@ -2838,11 +2958,11 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
- RetValExp = ER.take();
+ RetValExp = ER.get();
}
}
- Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
+ Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);
} else if (!RetValExp && !HasDependentReturnType) {
unsigned DiagID = diag::warn_return_missing_expr; // C90 6.6.6.4p4
// C99 6.8.6.4p1 (ext_ since GCC warns)
@@ -2855,29 +2975,30 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
Result = new (Context) ReturnStmt(ReturnLoc);
} else {
assert(RetValExp || HasDependentReturnType);
- const VarDecl *NRVOCandidate = 0;
- if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {
- // we have a non-void function with an expression, continue checking
+ const VarDecl *NRVOCandidate = nullptr;
- QualType RetType = (RelatedRetType.isNull() ? FnRetType : RelatedRetType);
+ QualType RetType = RelatedRetType.isNull() ? FnRetType : RelatedRetType;
- // C99 6.8.6.4p3(136): The return statement is not an assignment. The
- // overlap restriction of subclause 6.5.16.1 does not apply to the case of
- // function return.
+ // C99 6.8.6.4p3(136): The return statement is not an assignment. The
+ // overlap restriction of subclause 6.5.16.1 does not apply to the case of
+ // function return.
- // In C++ the return statement is handled via a copy initialization,
- // the C version of which boils down to CheckSingleAssignmentConstraints.
+ // In C++ the return statement is handled via a copy initialization,
+ // the C version of which boils down to CheckSingleAssignmentConstraints.
+ if (RetValExp)
NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
+ if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {
+ // we have a non-void function with an expression, continue checking
InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
RetType,
- NRVOCandidate != 0);
+ NRVOCandidate != nullptr);
ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
RetType, RetValExp);
if (Res.isInvalid()) {
// FIXME: Clean up temporaries here anyway?
return StmtError();
}
- RetValExp = Res.takeAs<Expr>();
+ RetValExp = Res.getAs<Expr>();
// If we have a related result type, we need to implicitly
// convert back to the formal result type. We can't pretend to
@@ -2891,28 +3012,28 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// FIXME: Clean up temporaries here anyway?
return StmtError();
}
- RetValExp = Res.takeAs<Expr>();
+ RetValExp = Res.getAs<Expr>();
}
- CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+ CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
+ getCurFunctionDecl());
}
if (RetValExp) {
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
- RetValExp = ER.take();
+ RetValExp = ER.get();
}
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
}
// If we need to check for the named return value optimization, save the
// return statement in our scope for later processing.
- if (getLangOpts().CPlusPlus && FnRetType->isRecordType() &&
- !CurContext->isDependentContext())
+ if (Result->getNRVOCandidate())
FunctionScopes.back()->Returns.push_back(Result);
- return Owned(Result);
+ return Result;
}
StmtResult
@@ -2923,12 +3044,12 @@ Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
if (Var && Var->isInvalidDecl())
return StmtError();
- return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
+ return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body);
}
StmtResult
Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
- return Owned(new (Context) ObjCAtFinallyStmt(AtLoc, Body));
+ return new (Context) ObjCAtFinallyStmt(AtLoc, Body);
}
StmtResult
@@ -2939,10 +3060,8 @@ Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
getCurFunction()->setHasBranchProtectedScope();
unsigned NumCatchStmts = CatchStmts.size();
- return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
- CatchStmts.data(),
- NumCatchStmts,
- Finally));
+ return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(),
+ NumCatchStmts, Finally);
}
StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
@@ -2951,10 +3070,10 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
if (Result.isInvalid())
return StmtError();
- Result = ActOnFinishFullExpr(Result.take());
+ Result = ActOnFinishFullExpr(Result.get());
if (Result.isInvalid())
return StmtError();
- Throw = Result.take();
+ Throw = Result.get();
QualType ThrowType = Throw->getType();
// Make sure the expression type is an ObjC pointer or "void *".
@@ -2967,7 +3086,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
}
}
- return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
+ return new (Context) ObjCAtThrowStmt(AtLoc, Throw);
}
StmtResult
@@ -2993,7 +3112,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) {
ExprResult result = DefaultLvalueConversion(operand);
if (result.isInvalid())
return ExprError();
- operand = result.take();
+ operand = result.get();
// Make sure the expression type is an ObjC pointer or "void *".
QualType type = operand->getType();
@@ -3014,7 +3133,7 @@ Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr,
Stmt *SyncBody) {
// We can't jump into or indirect-jump out of a @synchronized block.
getCurFunction()->setHasBranchProtectedScope();
- return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody));
+ return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody);
}
/// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
@@ -3023,15 +3142,14 @@ StmtResult
Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
Stmt *HandlerBlock) {
// There's nothing to test that ActOnExceptionDecl didn't already test.
- return Owned(new (Context) CXXCatchStmt(CatchLoc,
- cast_or_null<VarDecl>(ExDecl),
- HandlerBlock));
+ return new (Context)
+ CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
}
StmtResult
Sema::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) {
getCurFunction()->setHasBranchProtectedScope();
- return Owned(new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body));
+ return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body);
}
namespace {
@@ -3075,6 +3193,9 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
!getSourceManager().isInSystemHeader(TryLoc))
Diag(TryLoc, diag::err_exceptions_disabled) << "try";
+ if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
+ Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
+
const unsigned NumHandlers = Handlers.size();
assert(NumHandlers > 0 &&
"The parser shouldn't call this if there are no handlers.");
@@ -3125,19 +3246,18 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
// Neither of these are explicitly forbidden, but every compiler detects them
// and warns.
- return Owned(CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers));
+ return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers);
}
-StmtResult
-Sema::ActOnSEHTryBlock(bool IsCXXTry,
- SourceLocation TryLoc,
- Stmt *TryBlock,
- Stmt *Handler) {
+StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
+ Stmt *TryBlock, Stmt *Handler,
+ int HandlerIndex, int HandlerParentIndex) {
assert(TryBlock && Handler);
getCurFunction()->setHasBranchProtectedScope();
- return Owned(SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler));
+ return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler,
+ HandlerIndex, HandlerParentIndex);
}
StmtResult
@@ -3152,14 +3272,25 @@ Sema::ActOnSEHExceptBlock(SourceLocation Loc,
<< FilterExpr->getType());
}
- return Owned(SEHExceptStmt::Create(Context,Loc,FilterExpr,Block));
+ return SEHExceptStmt::Create(Context,Loc,FilterExpr,Block);
}
StmtResult
Sema::ActOnSEHFinallyBlock(SourceLocation Loc,
Stmt *Block) {
assert(Block);
- return Owned(SEHFinallyStmt::Create(Context,Loc,Block));
+ return SEHFinallyStmt::Create(Context,Loc,Block);
+}
+
+StmtResult
+Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {
+ Scope *SEHTryParent = CurScope;
+ while (SEHTryParent && !SEHTryParent->isSEHTryScope())
+ SEHTryParent = SEHTryParent->getParent();
+ if (!SEHTryParent)
+ return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));
+
+ return new (Context) SEHLeaveStmt(Loc);
}
StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
@@ -3192,30 +3323,20 @@ Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc,
while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
DC = DC->getParent();
- RecordDecl *RD = 0;
+ RecordDecl *RD = nullptr;
if (getLangOpts().CPlusPlus)
- RD = CXXRecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0);
+ RD = CXXRecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc,
+ /*Id=*/nullptr);
else
- RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0);
+ RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/nullptr);
DC->addDecl(RD);
RD->setImplicit();
RD->startDefinition();
+ assert(NumParams > 0 && "CapturedStmt requires context parameter");
CD = CapturedDecl::Create(Context, CurContext, NumParams);
DC->addDecl(CD);
-
- // Build the context parameter
- assert(NumParams > 0 && "CapturedStmt requires context parameter");
- DC = CapturedDecl::castToDeclContext(CD);
- IdentifierInfo *VarName = &Context.Idents.get("__context");
- QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
- ImplicitParamDecl *Param
- = ImplicitParamDecl::Create(Context, DC, Loc, VarName, ParamType);
- DC->addDecl(Param);
-
- CD->setContextParam(Param);
-
return RD;
}
@@ -3247,9 +3368,71 @@ static void buildCapturedStmtCaptureList(
void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
CapturedRegionKind Kind,
unsigned NumParams) {
- CapturedDecl *CD = 0;
+ CapturedDecl *CD = nullptr;
RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams);
+ // Build the context parameter
+ DeclContext *DC = CapturedDecl::castToDeclContext(CD);
+ IdentifierInfo *ParamName = &Context.Idents.get("__context");
+ QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+ ImplicitParamDecl *Param
+ = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
+ DC->addDecl(Param);
+
+ CD->setContextParam(0, Param);
+
+ // Enter the capturing scope for this captured region.
+ PushCapturedRegionScope(CurScope, CD, RD, Kind);
+
+ if (CurScope)
+ PushDeclContext(CurScope, CD);
+ else
+ CurContext = CD;
+
+ PushExpressionEvaluationContext(PotentiallyEvaluated);
+}
+
+void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
+ CapturedRegionKind Kind,
+ ArrayRef<CapturedParamNameType> Params) {
+ CapturedDecl *CD = nullptr;
+ RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, Params.size());
+
+ // Build the context parameter
+ DeclContext *DC = CapturedDecl::castToDeclContext(CD);
+ bool ContextIsFound = false;
+ unsigned ParamNum = 0;
+ for (ArrayRef<CapturedParamNameType>::iterator I = Params.begin(),
+ E = Params.end();
+ I != E; ++I, ++ParamNum) {
+ if (I->second.isNull()) {
+ assert(!ContextIsFound &&
+ "null type has been found already for '__context' parameter");
+ IdentifierInfo *ParamName = &Context.Idents.get("__context");
+ QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+ ImplicitParamDecl *Param
+ = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
+ DC->addDecl(Param);
+ CD->setContextParam(ParamNum, Param);
+ ContextIsFound = true;
+ } else {
+ IdentifierInfo *ParamName = &Context.Idents.get(I->first);
+ ImplicitParamDecl *Param
+ = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, I->second);
+ DC->addDecl(Param);
+ CD->setParam(ParamNum, Param);
+ }
+ }
+ assert(ContextIsFound && "no null type for '__context' parameter");
+ if (!ContextIsFound) {
+ // Add __context implicitly if it is not specified.
+ IdentifierInfo *ParamName = &Context.Idents.get("__context");
+ QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+ ImplicitParamDecl *Param =
+ ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
+ DC->addDecl(Param);
+ CD->setContextParam(ParamNum, Param);
+ }
// Enter the capturing scope for this captured region.
PushCapturedRegionScope(CurScope, CD, RD, Kind);
@@ -3269,12 +3452,9 @@ void Sema::ActOnCapturedRegionError() {
RecordDecl *Record = RSI->TheRecordDecl;
Record->setInvalidDecl();
- SmallVector<Decl*, 4> Fields;
- for (RecordDecl::field_iterator I = Record->field_begin(),
- E = Record->field_end(); I != E; ++I)
- Fields.push_back(*I);
- ActOnFields(/*Scope=*/0, Record->getLocation(), Record, Fields,
- SourceLocation(), SourceLocation(), /*AttributeList=*/0);
+ SmallVector<Decl*, 4> Fields(Record->fields());
+ ActOnFields(/*Scope=*/nullptr, Record->getLocation(), Record, Fields,
+ SourceLocation(), SourceLocation(), /*AttributeList=*/nullptr);
PopDeclContext();
PopFunctionScopeInfo();
@@ -3303,5 +3483,5 @@ StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) {
PopDeclContext();
PopFunctionScopeInfo();
- return Owned(Res);
+ return Res;
}
OpenPOWER on IntegriCloud