Skip to content

[clang][NFC] Move more functions from Sema to SemaObjC #97172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 0 additions & 41 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,6 @@ class Sema final : public SemaBase {
Scope *getScopeForContext(DeclContext *Ctx);

void PushFunctionScope();
void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
sema::LambdaScopeInfo *PushLambdaScope();

/// This is used to inform Sema what the current TemplateParameterDepth
Expand Down Expand Up @@ -736,9 +735,6 @@ class Sema final : public SemaBase {

bool hasAnyUnrecoverableErrorsInThisFunction() const;

/// Retrieve the current block, if any.
sema::BlockScopeInfo *getCurBlock();

/// Get the innermost lambda enclosing the current location, if any. This
/// looks through intervening non-lambda scopes such as local functions and
/// blocks.
Expand Down Expand Up @@ -2182,14 +2178,6 @@ class Sema final : public SemaBase {

void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange);

/// checkUnsafeAssigns - Check whether +1 expr is being assigned
/// to weak/__unsafe_unretained type.
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS);

/// checkUnsafeExprAssigns - Check whether +1 expr is being assigned
/// to weak/__unsafe_unretained expression.
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS);

/// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null
/// statement as a \p Body, and it is located on the same line.
///
Expand Down Expand Up @@ -3853,8 +3841,6 @@ class Sema final : public SemaBase {
void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks);

enum class RetainOwnershipKind { NS, CF, OS };

UuidAttr *mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
StringRef UuidAsWritten, MSGuidDecl *GuidDecl);

Expand Down Expand Up @@ -5833,26 +5819,6 @@ class Sema final : public SemaBase {

bool CheckCaseExpression(Expr *E);

//===------------------------- "Block" Extension ------------------------===//

/// ActOnBlockStart - This callback is invoked when a block literal is
/// started.
void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);

/// ActOnBlockArguments - This callback allows processing of block arguments.
/// If there are no arguments, this is still invoked.
void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
Scope *CurScope);

/// ActOnBlockError - If there is an error parsing a block, this callback
/// is invoked to pop the information about the block from the action impl.
void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);

/// ActOnBlockStmtExpr - This is called when the body of a block statement
/// literal was successfully completed. ^(int x){...}
ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
Scope *CurScope);

//===---------------------------- Clang Extensions ----------------------===//

/// __builtin_convertvector(...)
Expand Down Expand Up @@ -6571,13 +6537,6 @@ class Sema final : public SemaBase {
// Set of failed immediate invocations to avoid double diagnosing.
llvm::SmallPtrSet<ConstantExpr *, 4> FailedImmediateInvocations;

/// List of SourceLocations where 'self' is implicitly retained inside a
/// block.
llvm::SmallVector<std::pair<SourceLocation, const BlockDecl *>, 1>
ImplicitlyRetainedSelfLocs;

void maybeExtendBlockObject(ExprResult &E);

private:
static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind);

Expand Down
49 changes: 45 additions & 4 deletions clang/include/clang/Sema/SemaObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ class SemaObjC : public SemaBase {
/// target type.
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral);

/// Retrieve the current block, if any.
sema::BlockScopeInfo *getCurBlock();

void PushBlockScope(Scope *BlockScope, BlockDecl *Block);

void diagnoseImplicitlyRetainedSelf();

private:
IdentifierInfo *Ident_NSError = nullptr;

Expand Down Expand Up @@ -571,6 +578,21 @@ class SemaObjC : public SemaBase {

ObjCContainerDecl *getObjCDeclContext() const;

/// List of SourceLocations where 'self' is implicitly retained inside a
/// block.
llvm::SmallVector<std::pair<SourceLocation, const BlockDecl *>, 1>
ImplicitlyRetainedSelfLocs;

/// checkUnsafeAssigns - Check whether +1 expr is being assigned
/// to weak/__unsafe_unretained type.
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS);

/// checkUnsafeExprAssigns - Check whether +1 expr is being assigned
/// to weak/__unsafe_unretained expression.
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS);

enum class RetainOwnershipKind { NS, CF, OS };

private:
/// AddMethodToGlobalPool - Add an instance or factory method to the global
/// pool. See descriptoin of AddInstanceMethodToGlobalPool.
Expand Down Expand Up @@ -925,6 +947,27 @@ class SemaObjC : public SemaBase {
};
ObjCLiteralKind CheckLiteralKind(Expr *FromE);

/// Do an explicit extend of the given block pointer if we're in ARC.
void maybeExtendBlockObject(ExprResult &E);

/// ActOnBlockStart - This callback is invoked when a block literal is
/// started.
void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);

/// ActOnBlockArguments - This callback allows processing of block arguments.
/// If there are no arguments, this is still invoked.
void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
Scope *CurScope);

/// ActOnBlockError - If there is an error parsing a block, this callback
/// is invoked to pop the information about the block from the action impl.
void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);

/// ActOnBlockStmtExpr - This is called when the body of a block statement
/// literal was successfully completed. ^(int x){...}
ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
Scope *CurScope);

///@}

//
Expand Down Expand Up @@ -1067,15 +1110,13 @@ class SemaObjC : public SemaBase {
void handleExternallyRetainedAttr(Decl *D, const ParsedAttr &AL);

void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI,
Sema::RetainOwnershipKind K,
bool IsTemplateInstantiation);
RetainOwnershipKind K, bool IsTemplateInstantiation);

/// \return whether the parameter is a pointer to OSObject pointer.
bool isValidOSObjectOutParameter(const Decl *D);
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);

Sema::RetainOwnershipKind
parsedAttrToRetainOwnershipKind(const ParsedAttr &AL);
RetainOwnershipKind parsedAttrToRetainOwnershipKind(const ParsedAttr &AL);

///@}
};
Expand Down
17 changes: 9 additions & 8 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3733,7 +3733,7 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) {
MaybeParseGNUAttributes(DeclaratorInfo);

// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope());
Actions.ObjC().ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope());
}

/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
Expand Down Expand Up @@ -3761,7 +3761,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
Scope::CompoundStmtScope | Scope::DeclScope);

// Inform sema that we are starting a block.
Actions.ActOnBlockStart(CaretLoc, getCurScope());
Actions.ObjC().ActOnBlockStart(CaretLoc, getCurScope());

// Parse the return type if present.
DeclSpec DS(AttrFactory);
Expand All @@ -3786,14 +3786,14 @@ ExprResult Parser::ParseBlockLiteralExpression() {
// If there was an error parsing the arguments, they may have
// tried to use ^(x+y) which requires an argument list. Just
// skip the whole block literal.
Actions.ActOnBlockError(CaretLoc, getCurScope());
Actions.ObjC().ActOnBlockError(CaretLoc, getCurScope());
return ExprError();
}

MaybeParseGNUAttributes(ParamInfo);

// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
Actions.ObjC().ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
} else if (!Tok.is(tok::l_brace)) {
ParseBlockId(CaretLoc);
} else {
Expand Down Expand Up @@ -3823,24 +3823,25 @@ ExprResult Parser::ParseBlockLiteralExpression() {
MaybeParseGNUAttributes(ParamInfo);

// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
Actions.ObjC().ActOnBlockArguments(CaretLoc, ParamInfo, getCurScope());
}


ExprResult Result(true);
if (!Tok.is(tok::l_brace)) {
// Saw something like: ^expr
Diag(Tok, diag::err_expected_expression);
Actions.ActOnBlockError(CaretLoc, getCurScope());
Actions.ObjC().ActOnBlockError(CaretLoc, getCurScope());
return ExprError();
}

StmtResult Stmt(ParseCompoundStatementBody());
BlockScope.Exit();
if (!Stmt.isInvalid())
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
Result =
Actions.ObjC().ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
else
Actions.ActOnBlockError(CaretLoc, getCurScope());
Actions.ObjC().ActOnBlockError(CaretLoc, getCurScope());
return Result;
}

Expand Down
21 changes: 0 additions & 21 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2204,12 +2204,6 @@ void Sema::PushFunctionScope() {
OpenMP().pushOpenMPFunctionRegion();
}

void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics(),
BlockScope, Block));
CapturingFunctionScopes++;
}

LambdaScopeInfo *Sema::PushLambdaScope() {
LambdaScopeInfo *const LSI = new LambdaScopeInfo(getDiagnostics());
FunctionScopes.push_back(LSI);
Expand Down Expand Up @@ -2382,21 +2376,6 @@ void Sema::setFunctionHasMustTail() {
FunctionScopes.back()->setHasMustTail();
}

BlockScopeInfo *Sema::getCurBlock() {
if (FunctionScopes.empty())
return nullptr;

auto CurBSI = dyn_cast<BlockScopeInfo>(FunctionScopes.back());
if (CurBSI && CurBSI->TheDecl &&
!CurBSI->TheDecl->Encloses(CurContext)) {
// We have switched contexts due to template instantiation.
assert(!CodeSynthesisContexts.empty());
return nullptr;
}

return CurBSI;
}

FunctionScopeInfo *Sema::getEnclosingFunction() const {
if (FunctionScopes.empty())
return nullptr;
Expand Down
118 changes: 0 additions & 118 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13457,124 +13457,6 @@ void Sema::CheckArrayAccess(const Expr *expr) {
}
}

static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc,
Expr *RHS, bool isProperty) {
// Check if RHS is an Objective-C object literal, which also can get
// immediately zapped in a weak reference. Note that we explicitly
// allow ObjCStringLiterals, since those are designed to never really die.
RHS = RHS->IgnoreParenImpCasts();

// This enum needs to match with the 'select' in
// warn_objc_arc_literal_assign (off-by-1).
SemaObjC::ObjCLiteralKind Kind = S.ObjC().CheckLiteralKind(RHS);
if (Kind == SemaObjC::LK_String || Kind == SemaObjC::LK_None)
return false;

S.Diag(Loc, diag::warn_arc_literal_assign)
<< (unsigned) Kind
<< (isProperty ? 0 : 1)
<< RHS->getSourceRange();

return true;
}

static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc,
Qualifiers::ObjCLifetime LT,
Expr *RHS, bool isProperty) {
// Strip off any implicit cast added to get to the one ARC-specific.
while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) {
if (cast->getCastKind() == CK_ARCConsumeObject) {
S.Diag(Loc, diag::warn_arc_retained_assign)
<< (LT == Qualifiers::OCL_ExplicitNone)
<< (isProperty ? 0 : 1)
<< RHS->getSourceRange();
return true;
}
RHS = cast->getSubExpr();
}

if (LT == Qualifiers::OCL_Weak &&
checkUnsafeAssignLiteral(S, Loc, RHS, isProperty))
return true;

return false;
}

bool Sema::checkUnsafeAssigns(SourceLocation Loc,
QualType LHS, Expr *RHS) {
Qualifiers::ObjCLifetime LT = LHS.getObjCLifetime();

if (LT != Qualifiers::OCL_Weak && LT != Qualifiers::OCL_ExplicitNone)
return false;

if (checkUnsafeAssignObject(*this, Loc, LT, RHS, false))
return true;

return false;
}

void Sema::checkUnsafeExprAssigns(SourceLocation Loc,
Expr *LHS, Expr *RHS) {
QualType LHSType;
// PropertyRef on LHS type need be directly obtained from
// its declaration as it has a PseudoType.
ObjCPropertyRefExpr *PRE
= dyn_cast<ObjCPropertyRefExpr>(LHS->IgnoreParens());
if (PRE && !PRE->isImplicitProperty()) {
const ObjCPropertyDecl *PD = PRE->getExplicitProperty();
if (PD)
LHSType = PD->getType();
}

if (LHSType.isNull())
LHSType = LHS->getType();

Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime();

if (LT == Qualifiers::OCL_Weak) {
if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
getCurFunction()->markSafeWeakUse(LHS);
}

if (checkUnsafeAssigns(Loc, LHSType, RHS))
return;

// FIXME. Check for other life times.
if (LT != Qualifiers::OCL_None)
return;

if (PRE) {
if (PRE->isImplicitProperty())
return;
const ObjCPropertyDecl *PD = PRE->getExplicitProperty();
if (!PD)
return;

unsigned Attributes = PD->getPropertyAttributes();
if (Attributes & ObjCPropertyAttribute::kind_assign) {
// when 'assign' attribute was not explicitly specified
// by user, ignore it and rely on property type itself
// for lifetime info.
unsigned AsWrittenAttr = PD->getPropertyAttributesAsWritten();
if (!(AsWrittenAttr & ObjCPropertyAttribute::kind_assign) &&
LHSType->isObjCRetainableType())
return;

while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) {
if (cast->getCastKind() == CK_ARCConsumeObject) {
Diag(Loc, diag::warn_arc_retained_property_assign)
<< RHS->getSourceRange();
return;
}
RHS = cast->getSubExpr();
}
} else if (Attributes & ObjCPropertyAttribute::kind_weak) {
if (checkUnsafeAssignObject(*this, Loc, Qualifiers::OCL_Weak, RHS, true))
return;
}
}
}

//===--- CHECK: Empty statement body (-Wempty-body) ---------------------===//

static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr,
Expand Down
Loading
Loading