Skip to content

Commit 4bf209a

Browse files
committed
Remove the block scope
1 parent 323469c commit 4bf209a

File tree

2 files changed

+124
-141
lines changed

2 files changed

+124
-141
lines changed

clang/lib/Sema/Sema.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,8 +2464,6 @@ Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
24642464

24652465
void Sema::PoppedFunctionScopeDeleter::
24662466
operator()(sema::FunctionScopeInfo *Scope) const {
2467-
if (!Scope)
2468-
return;
24692467
if (!Scope->isPlainFunction())
24702468
Self->CapturingFunctionScopes--;
24712469
// Stash the function scope for later reuse if it's for a normal function.

clang/lib/Sema/SemaLambda.cpp

Lines changed: 124 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,155 +2142,140 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc,
21422142
SourceLocation CaptureDefaultLoc = LSI->CaptureDefaultLoc;
21432143
LambdaCaptureDefault CaptureDefault =
21442144
mapImplicitCaptureStyle(LSI->ImpCaptureStyle);
2145-
CXXRecordDecl *Class;
2146-
CXXMethodDecl *CallOperator;
2147-
SourceRange IntroducerRange;
2148-
bool ExplicitParams;
2149-
bool ExplicitResultType;
2150-
CleanupInfo LambdaCleanup;
2151-
bool ContainsUnexpandedParameterPack;
2152-
bool IsGenericLambda;
2153-
PoppedFunctionScopePtr KeepLSI(nullptr, PoppedFunctionScopeDeleter(this));
2154-
{
2155-
CallOperator = LSI->CallOperator;
2156-
Class = LSI->Lambda;
2157-
IntroducerRange = LSI->IntroducerRange;
2158-
ExplicitParams = LSI->ExplicitParams;
2159-
ExplicitResultType = !LSI->HasImplicitReturnType;
2160-
LambdaCleanup = LSI->Cleanup;
2161-
ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
2162-
IsGenericLambda = Class->isGenericLambda();
2163-
2164-
CallOperator->setLexicalDeclContext(Class);
2165-
Decl *TemplateOrNonTemplateCallOperatorDecl =
2166-
CallOperator->getDescribedFunctionTemplate()
2167-
? CallOperator->getDescribedFunctionTemplate()
2168-
: cast<Decl>(CallOperator);
2169-
2170-
// FIXME: Is this really the best choice? Keeping the lexical decl context
2171-
// set as CurContext seems more faithful to the source.
2172-
TemplateOrNonTemplateCallOperatorDecl->setLexicalDeclContext(Class);
2173-
2174-
PopExpressionEvaluationContext();
2175-
2176-
sema::AnalysisBasedWarnings::Policy WP =
2177-
AnalysisWarnings.getPolicyInEffectAt(EndLoc);
2178-
// We cannot release LSI until we finish computing captures, which
2179-
// requires the scope to be popped.
2180-
KeepLSI = PopFunctionScopeInfo(&WP, LSI->CallOperator);
2181-
2182-
// True if the current capture has a used capture or default before it.
2183-
bool CurHasPreviousCapture = CaptureDefault != LCD_None;
2184-
SourceLocation PrevCaptureLoc = CurHasPreviousCapture ?
2185-
CaptureDefaultLoc : IntroducerRange.getBegin();
2186-
2187-
for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
2188-
const Capture &From = LSI->Captures[I];
2189-
2190-
if (From.isInvalid())
2191-
return ExprError();
2192-
2193-
assert(!From.isBlockCapture() && "Cannot capture __block variables");
2194-
bool IsImplicit = I >= LSI->NumExplicitCaptures;
2195-
SourceLocation ImplicitCaptureLoc =
2196-
IsImplicit ? CaptureDefaultLoc : SourceLocation();
2197-
2198-
// Use source ranges of explicit captures for fixits where available.
2199-
SourceRange CaptureRange = LSI->ExplicitCaptureRanges[I];
2200-
2201-
// Warn about unused explicit captures.
2202-
bool IsCaptureUsed = true;
2203-
if (!CurContext->isDependentContext() && !IsImplicit &&
2204-
!From.isODRUsed()) {
2205-
// Initialized captures that are non-ODR used may not be eliminated.
2206-
// FIXME: Where did the IsGenericLambda here come from?
2207-
bool NonODRUsedInitCapture =
2208-
IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
2209-
if (!NonODRUsedInitCapture) {
2210-
bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
2211-
SourceRange FixItRange = ConstructFixItRangeForUnusedCapture(
2212-
*this, CaptureRange, PrevCaptureLoc, CurHasPreviousCapture,
2213-
IsLast);
2214-
IsCaptureUsed =
2215-
!DiagnoseUnusedLambdaCapture(CaptureRange, FixItRange, From);
2216-
}
2217-
}
2145+
CXXRecordDecl *Class = LSI->Lambda;
2146+
CXXMethodDecl *CallOperator = LSI->CallOperator;
2147+
SourceRange IntroducerRange = LSI->IntroducerRange;
2148+
bool ExplicitParams = LSI->ExplicitParams;
2149+
bool ExplicitResultType = !LSI->HasImplicitReturnType;
2150+
CleanupInfo LambdaCleanup = LSI->Cleanup;
2151+
bool ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
2152+
bool IsGenericLambda = Class->isGenericLambda();
2153+
2154+
CallOperator->setLexicalDeclContext(Class);
2155+
Decl *TemplateOrNonTemplateCallOperatorDecl =
2156+
CallOperator->getDescribedFunctionTemplate()
2157+
? CallOperator->getDescribedFunctionTemplate()
2158+
: cast<Decl>(CallOperator);
2159+
2160+
// FIXME: Is this really the best choice? Keeping the lexical decl context
2161+
// set as CurContext seems more faithful to the source.
2162+
TemplateOrNonTemplateCallOperatorDecl->setLexicalDeclContext(Class);
2163+
2164+
PopExpressionEvaluationContext();
2165+
2166+
sema::AnalysisBasedWarnings::Policy WP =
2167+
AnalysisWarnings.getPolicyInEffectAt(EndLoc);
2168+
// We cannot release LSI until we finish computing captures, which
2169+
// requires the scope to be popped.
2170+
Sema::PoppedFunctionScopePtr _ = PopFunctionScopeInfo(&WP, LSI->CallOperator);
22182171

2219-
if (CaptureRange.isValid()) {
2220-
CurHasPreviousCapture |= IsCaptureUsed;
2221-
PrevCaptureLoc = CaptureRange.getEnd();
2172+
// True if the current capture has a used capture or default before it.
2173+
bool CurHasPreviousCapture = CaptureDefault != LCD_None;
2174+
SourceLocation PrevCaptureLoc =
2175+
CurHasPreviousCapture ? CaptureDefaultLoc : IntroducerRange.getBegin();
2176+
2177+
for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
2178+
const Capture &From = LSI->Captures[I];
2179+
2180+
if (From.isInvalid())
2181+
return ExprError();
2182+
2183+
assert(!From.isBlockCapture() && "Cannot capture __block variables");
2184+
bool IsImplicit = I >= LSI->NumExplicitCaptures;
2185+
SourceLocation ImplicitCaptureLoc =
2186+
IsImplicit ? CaptureDefaultLoc : SourceLocation();
2187+
2188+
// Use source ranges of explicit captures for fixits where available.
2189+
SourceRange CaptureRange = LSI->ExplicitCaptureRanges[I];
2190+
2191+
// Warn about unused explicit captures.
2192+
bool IsCaptureUsed = true;
2193+
if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
2194+
// Initialized captures that are non-ODR used may not be eliminated.
2195+
// FIXME: Where did the IsGenericLambda here come from?
2196+
bool NonODRUsedInitCapture =
2197+
IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
2198+
if (!NonODRUsedInitCapture) {
2199+
bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
2200+
SourceRange FixItRange = ConstructFixItRangeForUnusedCapture(
2201+
*this, CaptureRange, PrevCaptureLoc, CurHasPreviousCapture, IsLast);
2202+
IsCaptureUsed =
2203+
!DiagnoseUnusedLambdaCapture(CaptureRange, FixItRange, From);
22222204
}
2205+
}
22232206

2224-
// Map the capture to our AST representation.
2225-
LambdaCapture Capture = [&] {
2226-
if (From.isThisCapture()) {
2227-
// Capturing 'this' implicitly with a default of '[=]' is deprecated,
2228-
// because it results in a reference capture. Don't warn prior to
2229-
// C++2a; there's nothing that can be done about it before then.
2230-
if (getLangOpts().CPlusPlus20 && IsImplicit &&
2231-
CaptureDefault == LCD_ByCopy) {
2232-
Diag(From.getLocation(), diag::warn_deprecated_this_capture);
2233-
Diag(CaptureDefaultLoc, diag::note_deprecated_this_capture)
2234-
<< FixItHint::CreateInsertion(
2235-
getLocForEndOfToken(CaptureDefaultLoc), ", this");
2236-
}
2237-
return LambdaCapture(From.getLocation(), IsImplicit,
2238-
From.isCopyCapture() ? LCK_StarThis : LCK_This);
2239-
} else if (From.isVLATypeCapture()) {
2240-
return LambdaCapture(From.getLocation(), IsImplicit, LCK_VLAType);
2241-
} else {
2242-
assert(From.isVariableCapture() && "unknown kind of capture");
2243-
ValueDecl *Var = From.getVariable();
2244-
LambdaCaptureKind Kind =
2245-
From.isCopyCapture() ? LCK_ByCopy : LCK_ByRef;
2246-
return LambdaCapture(From.getLocation(), IsImplicit, Kind, Var,
2247-
From.getEllipsisLoc());
2248-
}
2249-
}();
2207+
if (CaptureRange.isValid()) {
2208+
CurHasPreviousCapture |= IsCaptureUsed;
2209+
PrevCaptureLoc = CaptureRange.getEnd();
2210+
}
22502211

2251-
// Form the initializer for the capture field.
2252-
ExprResult Init = BuildCaptureInit(From, ImplicitCaptureLoc);
2212+
// Map the capture to our AST representation.
2213+
LambdaCapture Capture = [&] {
2214+
if (From.isThisCapture()) {
2215+
// Capturing 'this' implicitly with a default of '[=]' is deprecated,
2216+
// because it results in a reference capture. Don't warn prior to
2217+
// C++2a; there's nothing that can be done about it before then.
2218+
if (getLangOpts().CPlusPlus20 && IsImplicit &&
2219+
CaptureDefault == LCD_ByCopy) {
2220+
Diag(From.getLocation(), diag::warn_deprecated_this_capture);
2221+
Diag(CaptureDefaultLoc, diag::note_deprecated_this_capture)
2222+
<< FixItHint::CreateInsertion(
2223+
getLocForEndOfToken(CaptureDefaultLoc), ", this");
2224+
}
2225+
return LambdaCapture(From.getLocation(), IsImplicit,
2226+
From.isCopyCapture() ? LCK_StarThis : LCK_This);
2227+
} else if (From.isVLATypeCapture()) {
2228+
return LambdaCapture(From.getLocation(), IsImplicit, LCK_VLAType);
2229+
} else {
2230+
assert(From.isVariableCapture() && "unknown kind of capture");
2231+
ValueDecl *Var = From.getVariable();
2232+
LambdaCaptureKind Kind = From.isCopyCapture() ? LCK_ByCopy : LCK_ByRef;
2233+
return LambdaCapture(From.getLocation(), IsImplicit, Kind, Var,
2234+
From.getEllipsisLoc());
2235+
}
2236+
}();
22532237

2254-
// FIXME: Skip this capture if the capture is not used, the initializer
2255-
// has no side-effects, the type of the capture is trivial, and the
2256-
// lambda is not externally visible.
2238+
// Form the initializer for the capture field.
2239+
ExprResult Init = BuildCaptureInit(From, ImplicitCaptureLoc);
22572240

2258-
// Add a FieldDecl for the capture and form its initializer.
2259-
BuildCaptureField(Class, From);
2260-
Captures.push_back(Capture);
2261-
CaptureInits.push_back(Init.get());
2241+
// FIXME: Skip this capture if the capture is not used, the initializer
2242+
// has no side-effects, the type of the capture is trivial, and the
2243+
// lambda is not externally visible.
22622244

2263-
if (LangOpts.CUDA)
2264-
CUDA().CheckLambdaCapture(CallOperator, From);
2265-
}
2245+
// Add a FieldDecl for the capture and form its initializer.
2246+
BuildCaptureField(Class, From);
2247+
Captures.push_back(Capture);
2248+
CaptureInits.push_back(Init.get());
22662249

2267-
Class->setCaptures(Context, Captures);
2268-
2269-
// C++11 [expr.prim.lambda]p6:
2270-
// The closure type for a lambda-expression with no lambda-capture
2271-
// has a public non-virtual non-explicit const conversion function
2272-
// to pointer to function having the same parameter and return
2273-
// types as the closure type's function call operator.
2274-
if (Captures.empty() && CaptureDefault == LCD_None)
2275-
addFunctionPointerConversions(*this, IntroducerRange, Class,
2276-
CallOperator);
2277-
2278-
// Objective-C++:
2279-
// The closure type for a lambda-expression has a public non-virtual
2280-
// non-explicit const conversion function to a block pointer having the
2281-
// same parameter and return types as the closure type's function call
2282-
// operator.
2283-
// FIXME: Fix generic lambda to block conversions.
2284-
if (getLangOpts().Blocks && getLangOpts().ObjC && !IsGenericLambda)
2285-
addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
2286-
2287-
// Finalize the lambda class.
2288-
SmallVector<Decl*, 4> Fields(Class->fields());
2289-
ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
2290-
SourceLocation(), ParsedAttributesView());
2291-
CheckCompletedCXXClass(nullptr, Class);
2250+
if (LangOpts.CUDA)
2251+
CUDA().CheckLambdaCapture(CallOperator, From);
22922252
}
22932253

2254+
Class->setCaptures(Context, Captures);
2255+
2256+
// C++11 [expr.prim.lambda]p6:
2257+
// The closure type for a lambda-expression with no lambda-capture
2258+
// has a public non-virtual non-explicit const conversion function
2259+
// to pointer to function having the same parameter and return
2260+
// types as the closure type's function call operator.
2261+
if (Captures.empty() && CaptureDefault == LCD_None)
2262+
addFunctionPointerConversions(*this, IntroducerRange, Class, CallOperator);
2263+
2264+
// Objective-C++:
2265+
// The closure type for a lambda-expression has a public non-virtual
2266+
// non-explicit const conversion function to a block pointer having the
2267+
// same parameter and return types as the closure type's function call
2268+
// operator.
2269+
// FIXME: Fix generic lambda to block conversions.
2270+
if (getLangOpts().Blocks && getLangOpts().ObjC && !IsGenericLambda)
2271+
addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
2272+
2273+
// Finalize the lambda class.
2274+
SmallVector<Decl *, 4> Fields(Class->fields());
2275+
ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
2276+
SourceLocation(), ParsedAttributesView());
2277+
CheckCompletedCXXClass(nullptr, Class);
2278+
22942279
Cleanup.mergeFrom(LambdaCleanup);
22952280

22962281
LambdaExpr *Lambda =

0 commit comments

Comments
 (0)