summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-03-07 22:48:35 +0000
committerReid Kleckner <rnk@google.com>2018-03-07 22:48:35 +0000
commit1f5fca8f18e3417de286e5bdb7ef06ef3ebb4db4 (patch)
treec4312a29ce81cab1f47b2c1267f963c9476b723f
parent9062e07a82f72a8bf3f55701a6b1f26186eb74a0 (diff)
downloadclang-1f5fca8f18e3417de286e5bdb7ef06ef3ebb4db4.tar.gz
Avoid including ScopeInfo.h from Sema.h
Summary: This provides no measurable build speedup, but it reinstates an optimization from r112038 that was lost in r179618. It requires moving CapturedScopeInfo::Capture out to clang::sema, which might be too general since we have plenty of other Capture records in BlockDecl and other AST nodes. Reviewers: rjmccall Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D44221 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326957 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/ScopeInfo.h234
-rw-r--r--include/clang/Sema/Sema.h25
-rw-r--r--include/clang/Sema/SemaLambda.h6
-rw-r--r--lib/Sema/Sema.cpp12
-rw-r--r--lib/Sema/SemaCoroutine.cpp1
-rw-r--r--lib/Sema/SemaDecl.cpp2
-rw-r--r--lib/Sema/SemaDeclAttr.cpp1
-rw-r--r--lib/Sema/SemaExpr.cpp13
-rw-r--r--lib/Sema/SemaExprMember.cpp5
-rw-r--r--lib/Sema/SemaLambda.cpp11
-rw-r--r--lib/Sema/SemaPseudoObject.cpp6
-rw-r--r--lib/Sema/SemaStmt.cpp31
12 files changed, 174 insertions, 173 deletions
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 35fdd74b15..744be7e2c0 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -469,144 +469,144 @@ public:
void Clear();
};
-class CapturingScopeInfo : public FunctionScopeInfo {
-protected:
- CapturingScopeInfo(const CapturingScopeInfo&) = default;
-
-public:
- enum ImplicitCaptureStyle {
- ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
- ImpCap_CapturedRegion
+class Capture {
+ // There are three categories of capture: capturing 'this', capturing
+ // local variables, and C++1y initialized captures (which can have an
+ // arbitrary initializer, and don't really capture in the traditional
+ // sense at all).
+ //
+ // There are three ways to capture a local variable:
+ // - capture by copy in the C++11 sense,
+ // - capture by reference in the C++11 sense, and
+ // - __block capture.
+ // Lambdas explicitly specify capture by copy or capture by reference.
+ // For blocks, __block capture applies to variables with that annotation,
+ // variables of reference type are captured by reference, and other
+ // variables are captured by copy.
+ enum CaptureKind {
+ Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
+ };
+ enum {
+ IsNestedCapture = 0x1,
+ IsThisCaptured = 0x2
};
- ImplicitCaptureStyle ImpCaptureStyle;
+ /// The variable being captured (if we are not capturing 'this') and whether
+ /// this is a nested capture, and whether we are capturing 'this'
+ llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
- class Capture {
- // There are three categories of capture: capturing 'this', capturing
- // local variables, and C++1y initialized captures (which can have an
- // arbitrary initializer, and don't really capture in the traditional
- // sense at all).
- //
- // There are three ways to capture a local variable:
- // - capture by copy in the C++11 sense,
- // - capture by reference in the C++11 sense, and
- // - __block capture.
- // Lambdas explicitly specify capture by copy or capture by reference.
- // For blocks, __block capture applies to variables with that annotation,
- // variables of reference type are captured by reference, and other
- // variables are captured by copy.
- enum CaptureKind {
- Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
- };
- enum {
- IsNestedCapture = 0x1,
- IsThisCaptured = 0x2
- };
+ /// Expression to initialize a field of the given type, and the kind of
+ /// capture (if this is a capture and not an init-capture). The expression
+ /// is only required if we are capturing ByVal and the variable's type has
+ /// a non-trivial copy constructor.
+ llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
- /// The variable being captured (if we are not capturing 'this') and whether
- /// this is a nested capture, and whether we are capturing 'this'
- llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
+ /// \brief The source location at which the first capture occurred.
+ SourceLocation Loc;
- /// Expression to initialize a field of the given type, and the kind of
- /// capture (if this is a capture and not an init-capture). The expression
- /// is only required if we are capturing ByVal and the variable's type has
- /// a non-trivial copy constructor.
- llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
-
- /// \brief The source location at which the first capture occurred.
- SourceLocation Loc;
+ /// \brief The location of the ellipsis that expands a parameter pack.
+ SourceLocation EllipsisLoc;
- /// \brief The location of the ellipsis that expands a parameter pack.
- SourceLocation EllipsisLoc;
+ /// \brief The type as it was captured, which is in effect the type of the
+ /// non-static data member that would hold the capture.
+ QualType CaptureType;
- /// \brief The type as it was captured, which is in effect the type of the
- /// non-static data member that would hold the capture.
- QualType CaptureType;
+ /// \brief Whether an explicit capture has been odr-used in the body of the
+ /// lambda.
+ bool ODRUsed = false;
- /// \brief Whether an explicit capture has been odr-used in the body of the
- /// lambda.
- bool ODRUsed = false;
+ /// \brief Whether an explicit capture has been non-odr-used in the body of
+ /// the lambda.
+ bool NonODRUsed = false;
- /// \brief Whether an explicit capture has been non-odr-used in the body of
- /// the lambda.
- bool NonODRUsed = false;
+public:
+ Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
+ SourceLocation Loc, SourceLocation EllipsisLoc,
+ QualType CaptureType, Expr *Cpy)
+ : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
+ InitExprAndCaptureKind(
+ Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
+ : Cap_ByCopy),
+ Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
- public:
- Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
- SourceLocation Loc, SourceLocation EllipsisLoc,
- QualType CaptureType, Expr *Cpy)
- : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
- InitExprAndCaptureKind(
- Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
- : Cap_ByCopy),
- Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
-
- enum IsThisCapture { ThisCapture };
- Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
- QualType CaptureType, Expr *Cpy, const bool ByCopy)
- : VarAndNestedAndThis(
- nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
- InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
- Loc(Loc), CaptureType(CaptureType) {}
-
- bool isThisCapture() const {
- return VarAndNestedAndThis.getInt() & IsThisCaptured;
- }
+ enum IsThisCapture { ThisCapture };
+ Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
+ QualType CaptureType, Expr *Cpy, const bool ByCopy)
+ : VarAndNestedAndThis(
+ nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
+ InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
+ Loc(Loc), CaptureType(CaptureType) {}
- bool isVariableCapture() const {
- return !isThisCapture() && !isVLATypeCapture();
- }
+ bool isThisCapture() const {
+ return VarAndNestedAndThis.getInt() & IsThisCaptured;
+ }
- bool isCopyCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
- }
+ bool isVariableCapture() const {
+ return !isThisCapture() && !isVLATypeCapture();
+ }
- bool isReferenceCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByRef;
- }
+ bool isCopyCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
+ }
- bool isBlockCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_Block;
- }
+ bool isReferenceCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_ByRef;
+ }
- bool isVLATypeCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_VLA;
- }
+ bool isBlockCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_Block;
+ }
- bool isNested() const {
- return VarAndNestedAndThis.getInt() & IsNestedCapture;
- }
+ bool isVLATypeCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_VLA;
+ }
- bool isODRUsed() const { return ODRUsed; }
- bool isNonODRUsed() const { return NonODRUsed; }
- void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
+ bool isNested() const {
+ return VarAndNestedAndThis.getInt() & IsNestedCapture;
+ }
- VarDecl *getVariable() const {
- assert(isVariableCapture());
- return VarAndNestedAndThis.getPointer();
- }
-
- /// \brief Retrieve the location at which this variable was captured.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Retrieve the source location of the ellipsis, whose presence
- /// indicates that the capture is a pack expansion.
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
-
- /// \brief Retrieve the capture type for this capture, which is effectively
- /// the type of the non-static data member in the lambda/block structure
- /// that would store this capture.
- QualType getCaptureType() const {
- assert(!isThisCapture());
- return CaptureType;
- }
+ bool isODRUsed() const { return ODRUsed; }
+ bool isNonODRUsed() const { return NonODRUsed; }
+ void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
- Expr *getInitExpr() const {
- assert(!isVLATypeCapture() && "no init expression for type capture");
- return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
- }
+ VarDecl *getVariable() const {
+ assert(isVariableCapture());
+ return VarAndNestedAndThis.getPointer();
+ }
+
+ /// \brief Retrieve the location at which this variable was captured.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Retrieve the source location of the ellipsis, whose presence
+ /// indicates that the capture is a pack expansion.
+ SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+
+ /// \brief Retrieve the capture type for this capture, which is effectively
+ /// the type of the non-static data member in the lambda/block structure
+ /// that would store this capture.
+ QualType getCaptureType() const {
+ assert(!isThisCapture());
+ return CaptureType;
+ }
+
+ Expr *getInitExpr() const {
+ assert(!isVLATypeCapture() && "no init expression for type capture");
+ return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
+ }
+};
+
+class CapturingScopeInfo : public FunctionScopeInfo {
+protected:
+ CapturingScopeInfo(const CapturingScopeInfo&) = default;
+
+public:
+ enum ImplicitCaptureStyle {
+ ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
+ ImpCap_CapturedRegion
};
+ ImplicitCaptureStyle ImpCaptureStyle;
+
CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
: FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 35599bf6ce..625001d85a 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -30,7 +30,6 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PragmaKinds.h"
@@ -45,7 +44,6 @@
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
-#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/TypoCorrection.h"
#include "clang/Sema/Weak.h"
#include "llvm/ADT/ArrayRef.h"
@@ -201,6 +199,7 @@ namespace clang {
namespace sema {
class AccessedEntity;
class BlockScopeInfo;
+ class Capture;
class CapturedRegionScopeInfo;
class CapturingScopeInfo;
class CompoundScopeInfo;
@@ -1322,23 +1321,7 @@ public:
return FunctionScopes.back();
}
- sema::FunctionScopeInfo *getEnclosingFunction() const {
- if (FunctionScopes.empty())
- return nullptr;
-
- for (int e = FunctionScopes.size()-1; e >= 0; --e) {
- if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
- continue;
- return FunctionScopes[e];
- }
- return nullptr;
- }
-
- template <typename ExprT>
- void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
- if (!isUnevaluatedContext())
- getCurFunction()->recordUseOfWeak(E, IsRead);
- }
+ sema::FunctionScopeInfo *getEnclosingFunction() const;
void PushCompoundScope(bool IsStmtExpr);
void PopCompoundScope();
@@ -5553,10 +5536,10 @@ public:
Scope *CurScope);
/// \brief Does copying/destroying the captured variable have side effects?
- bool CaptureHasSideEffects(const sema::LambdaScopeInfo::Capture &From);
+ bool CaptureHasSideEffects(const sema::Capture &From);
/// \brief Diagnose if an explicit lambda capture is unused.
- void DiagnoseUnusedLambdaCapture(const sema::LambdaScopeInfo::Capture &From);
+ void DiagnoseUnusedLambdaCapture(const sema::Capture &From);
/// \brief Complete a lambda-expression having processed and attached the
/// lambda body.
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
index df40b134f0..ec16dc8e6b 100644
--- a/include/clang/Sema/SemaLambda.h
+++ b/include/clang/Sema/SemaLambda.h
@@ -15,9 +15,13 @@
#ifndef LLVM_CLANG_SEMA_SEMALAMBDA_H
#define LLVM_CLANG_SEMA_SEMALAMBDA_H
+
#include "clang/AST/ASTLambda.h"
-#include "clang/Sema/ScopeInfo.h"
+
namespace clang {
+namespace sema {
+class FunctionScopeInfo;
+}
class Sema;
/// \brief Examines the FunctionScopeInfo stack to determine the nearest
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 1e9e53bb13..d0ed6bf75f 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -1426,6 +1426,18 @@ BlockScopeInfo *Sema::getCurBlock() {
return CurBSI;
}
+FunctionScopeInfo *Sema::getEnclosingFunction() const {
+ if (FunctionScopes.empty())
+ return nullptr;
+
+ for (int e = FunctionScopes.size() - 1; e >= 0; --e) {
+ if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
+ continue;
+ return FunctionScopes[e];
+ }
+ return nullptr;
+}
+
LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
if (FunctionScopes.empty())
return nullptr;
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index 54dcc9784f..e4cb4cf059 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -19,6 +19,7 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Overload.h"
+#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
using namespace clang;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 03dd9292a9..036082c941 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -6930,7 +6930,7 @@ static ShadowedDeclKind computeShadowedDeclKind(const NamedDecl *ShadowedDecl,
/// variable \p VD, or an invalid source location otherwise.
static SourceLocation getCaptureLocation(const LambdaScopeInfo *LSI,
const VarDecl *VD) {
- for (const LambdaScopeInfo::Capture &Capture : LSI->Captures) {
+ for (const Capture &Capture : LSI->Captures) {
if (Capture.isVariableCapture() && Capture.getVariable() == VD)
return Capture.getLocation();
}
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index fb430da801..1453fd273e 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -31,6 +31,7 @@
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 8c22c0e643..95b56a242a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1679,9 +1679,9 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
MarkDeclRefReferenced(E);
if (getLangOpts().ObjCWeak && isa<VarDecl>(D) &&
- Ty.getObjCLifetime() == Qualifiers::OCL_Weak &&
+ Ty.getObjCLifetime() == Qualifiers::OCL_Weak && !isUnevaluatedContext() &&
!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart()))
- recordUseOfEvaluatedWeak(E);
+ getCurFunction()->recordUseOfWeak(E);
FieldDecl *FD = dyn_cast<FieldDecl>(D);
if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(D))
@@ -2431,8 +2431,9 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
IV->getLocation(), SelfExpr.get(), true, true);
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
- if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
- recordUseOfEvaluatedWeak(Result);
+ if (!isUnevaluatedContext() &&
+ !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
+ getCurFunction()->recordUseOfWeak(Result);
}
if (getLangOpts().ObjCAutoRefCount) {
if (CurContext->isClosure())
@@ -13045,7 +13046,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
// Set the captured variables on the block.
// FIXME: Share capture structure between BlockDecl and CapturingScopeInfo!
SmallVector<BlockDecl::Capture, 4> Captures;
- for (CapturingScopeInfo::Capture &Cap : BSI->Captures) {
+ for (Capture &Cap : BSI->Captures) {
if (Cap.isThisCapture())
continue;
BlockDecl::Capture NewCap(Cap.getVariable(), Cap.isBlockCapture(),
@@ -14144,7 +14145,7 @@ static bool isVariableAlreadyCapturedInScopeInfo(CapturingScopeInfo *CSI, VarDec
// Similarly to mutable captures in lambda, all the OpenMP captures by copy
// are mutable in the sense that user can change their value - they are
// private instances of the captured declarations.
- const CapturingScopeInfo::Capture &Cap = CSI->getCapture(Var);
+ const Capture &Cap = CSI->getCapture(Var);
if (Cap.isCopyCapture() &&
!(isa<LambdaScopeInfo>(CSI) && cast<LambdaScopeInfo>(CSI)->Mutable) &&
!(isa<CapturedRegionScopeInfo>(CSI) &&
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 5bb9653db0..d054274289 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -1479,8 +1479,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
IsArrow);
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
- if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
- S.recordUseOfEvaluatedWeak(Result);
+ if (!S.isUnevaluatedContext() &&
+ !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
+ S.getCurFunction()->recordUseOfWeak(Result);
}
return Result;
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 19d2de7197..db8dd1793c 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -1388,8 +1388,9 @@ static void addBlockPointerConversion(Sema &S,
Class->addDecl(Conversion);
}
-static ExprResult performLambdaVarCaptureInitialization(
- Sema &S, const LambdaScopeInfo::Capture &Capture, FieldDecl *Field) {
+static ExprResult performLambdaVarCaptureInitialization(Sema &S,
+ const Capture &Capture,
+ FieldDecl *Field) {
assert(Capture.isVariableCapture() && "not a variable capture");
auto *Var = Capture.getVariable();
@@ -1443,7 +1444,7 @@ mapImplicitCaptureStyle(CapturingScopeInfo::ImplicitCaptureStyle ICS) {
llvm_unreachable("Unknown implicit capture style");
}
-bool Sema::CaptureHasSideEffects(const LambdaScopeInfo::Capture &From) {
+bool Sema::CaptureHasSideEffects(const Capture &From) {
if (!From.isVLATypeCapture()) {
Expr *Init = From.getInitExpr();
if (Init && Init->HasSideEffects(Context))
@@ -1468,7 +1469,7 @@ bool Sema::CaptureHasSideEffects(const LambdaScopeInfo::Capture &From) {
return false;
}
-void Sema::DiagnoseUnusedLambdaCapture(const LambdaScopeInfo::Capture &From) {
+void Sema::DiagnoseUnusedLambdaCapture(const Capture &From) {
if (CaptureHasSideEffects(From))
return;
@@ -1523,7 +1524,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
// Translate captures.
auto CurField = Class->field_begin();
for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I, ++CurField) {
- const LambdaScopeInfo::Capture &From = LSI->Captures[I];
+ const Capture &From = LSI->Captures[I];
assert(!From.isBlockCapture() && "Cannot capture __block variables");
bool IsImplicit = I >= LSI->NumExplicitCaptures;
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index f09a6f7158..8a671b1487 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -965,11 +965,11 @@ ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
}
ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
- if (isWeakProperty() &&
+ if (isWeakProperty() && !S.isUnevaluatedContext() &&
!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
SyntacticForm->getLocStart()))
- S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
- SyntacticRefExpr->isMessagingGetter());
+ S.getCurFunction()->recordUseOfWeak(SyntacticRefExpr,
+ SyntacticRefExpr->isMessagingGetter());
return PseudoOpBuilder::complete(SyntacticForm);
}
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index b77018503a..08af3fa676 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -4040,32 +4040,29 @@ Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc,
return RD;
}
-static void buildCapturedStmtCaptureList(
- SmallVectorImpl<CapturedStmt::Capture> &Captures,
- SmallVectorImpl<Expr *> &CaptureInits,
- ArrayRef<CapturingScopeInfo::Capture> Candidates) {
-
- typedef ArrayRef<CapturingScopeInfo::Capture>::const_iterator CaptureIter;
- for (CaptureIter Cap = Candidates.begin(); Cap != Candidates.end(); ++Cap) {
-
- if (Cap->isThisCapture()) {
- Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
+static void
+buildCapturedStmtCaptureList(SmallVectorImpl<CapturedStmt::Capture> &Captures,
+ SmallVectorImpl<Expr *> &CaptureInits,
+ ArrayRef<sema::Capture> Candidates) {
+ for (const sema::Capture &Cap : Candidates) {
+ if (Cap.isThisCapture()) {
+ Captures.push_back(CapturedStmt::Capture(Cap.getLocation(),
CapturedStmt::VCK_This));
- CaptureInits.push_back(Cap->getInitExpr());
+ CaptureInits.push_back(Cap.getInitExpr());
continue;
- } else if (Cap->isVLATypeCapture()) {
+ } else if (Cap.isVLATypeCapture()) {
Captures.push_back(
- CapturedStmt::Capture(Cap->getLocation(), CapturedStmt::VCK_VLAType));
+ CapturedStmt::Capture(Cap.getLocation(), CapturedStmt::VCK_VLAType));
CaptureInits.push_back(nullptr);
continue;
}
- Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
- Cap->isReferenceCapture()
+ Captures.push_back(CapturedStmt::Capture(Cap.getLocation(),
+ Cap.isReferenceCapture()
? CapturedStmt::VCK_ByRef
: CapturedStmt::VCK_ByCopy,
- Cap->getVariable()));
- CaptureInits.push_back(Cap->getInitExpr());
+ Cap.getVariable()));
+ CaptureInits.push_back(Cap.getInitExpr());
}
}