Skip to content

Commit 1664610

Browse files
authored
[clang] Introduce SemaPseudoObject (#92646)
This patch moves `Sema` functions that handle pseudo-objects into the new `SemaPseudoObject` class. This continues previous efforts to split `Sema` up. Additional context can be found in #84184. As usual, in order to help reviewing this, formatting changes are split into a separate commit.
1 parent 46d8bb0 commit 1664610

File tree

6 files changed

+112
-80
lines changed

6 files changed

+112
-80
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class SemaHLSL;
174174
class SemaObjC;
175175
class SemaOpenACC;
176176
class SemaOpenMP;
177+
class SemaPseudoObject;
177178
class SemaSYCL;
178179
class StandardConversionSequence;
179180
class Stmt;
@@ -471,20 +472,19 @@ class Sema final : public SemaBase {
471472
// 18. Name Lookup (SemaLookup.cpp)
472473
// 19. Modules (SemaModule.cpp)
473474
// 20. C++ Overloading (SemaOverload.cpp)
474-
// 21. Pseudo-Object (SemaPseudoObject.cpp)
475-
// 22. Statements (SemaStmt.cpp)
476-
// 23. `inline asm` Statement (SemaStmtAsm.cpp)
477-
// 24. Statement Attribute Handling (SemaStmtAttr.cpp)
478-
// 25. C++ Templates (SemaTemplate.cpp)
479-
// 26. C++ Template Argument Deduction (SemaTemplateDeduction.cpp)
480-
// 27. C++ Template Instantiation (SemaTemplateInstantiate.cpp)
481-
// 28. C++ Template Declaration Instantiation
475+
// 21. Statements (SemaStmt.cpp)
476+
// 22. `inline asm` Statement (SemaStmtAsm.cpp)
477+
// 23. Statement Attribute Handling (SemaStmtAttr.cpp)
478+
// 24. C++ Templates (SemaTemplate.cpp)
479+
// 25. C++ Template Argument Deduction (SemaTemplateDeduction.cpp)
480+
// 26. C++ Template Instantiation (SemaTemplateInstantiate.cpp)
481+
// 27. C++ Template Declaration Instantiation
482482
// (SemaTemplateInstantiateDecl.cpp)
483-
// 29. C++ Variadic Templates (SemaTemplateVariadic.cpp)
484-
// 30. Constraints and Concepts (SemaConcept.cpp)
485-
// 31. Types (SemaType.cpp)
486-
// 32. FixIt Helpers (SemaFixItUtils.cpp)
487-
// 33. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp)
483+
// 28. C++ Variadic Templates (SemaTemplateVariadic.cpp)
484+
// 29. Constraints and Concepts (SemaConcept.cpp)
485+
// 30. Types (SemaType.cpp)
486+
// 31. FixIt Helpers (SemaFixItUtils.cpp)
487+
// 32. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp)
488488

489489
/// \name Semantic Analysis
490490
/// Implementations are in Sema.cpp
@@ -1015,6 +1015,11 @@ class Sema final : public SemaBase {
10151015
return *OpenMPPtr;
10161016
}
10171017

1018+
SemaPseudoObject &PseudoObject() {
1019+
assert(PseudoObjectPtr);
1020+
return *PseudoObjectPtr;
1021+
}
1022+
10181023
SemaSYCL &SYCL() {
10191024
assert(SYCLPtr);
10201025
return *SYCLPtr;
@@ -1056,6 +1061,7 @@ class Sema final : public SemaBase {
10561061
std::unique_ptr<SemaObjC> ObjCPtr;
10571062
std::unique_ptr<SemaOpenACC> OpenACCPtr;
10581063
std::unique_ptr<SemaOpenMP> OpenMPPtr;
1064+
std::unique_ptr<SemaPseudoObject> PseudoObjectPtr;
10591065
std::unique_ptr<SemaSYCL> SYCLPtr;
10601066

10611067
///@}
@@ -6369,6 +6375,8 @@ class Sema final : public SemaBase {
63696375
llvm::SmallVector<std::pair<SourceLocation, const BlockDecl *>, 1>
63706376
ImplicitlyRetainedSelfLocs;
63716377

6378+
void maybeExtendBlockObject(ExprResult &E);
6379+
63726380
private:
63736381
static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind);
63746382

@@ -8367,29 +8375,6 @@ class Sema final : public SemaBase {
83678375
//
83688376
//
83698377

8370-
/// \name Pseudo-Object
8371-
/// Implementations are in SemaPseudoObject.cpp
8372-
///@{
8373-
8374-
public:
8375-
void maybeExtendBlockObject(ExprResult &E);
8376-
8377-
ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc,
8378-
UnaryOperatorKind Opcode, Expr *Op);
8379-
ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc,
8380-
BinaryOperatorKind Opcode, Expr *LHS,
8381-
Expr *RHS);
8382-
ExprResult checkPseudoObjectRValue(Expr *E);
8383-
Expr *recreateSyntacticForm(PseudoObjectExpr *E);
8384-
8385-
///@}
8386-
8387-
//
8388-
//
8389-
// -------------------------------------------------------------------------
8390-
//
8391-
//
8392-
83938378
/// \name Statements
83948379
/// Implementations are in SemaStmt.cpp
83958380
///@{
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===----- SemaPseudoObject.h --- Semantic Analysis for Pseudo-Objects ----===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
/// This file declares semantic analysis for expressions involving
10+
// pseudo-object references.
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H
15+
#define LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H
16+
17+
#include "clang/AST/Expr.h"
18+
#include "clang/AST/OperationKinds.h"
19+
#include "clang/Basic/SourceLocation.h"
20+
#include "clang/Sema/Ownership.h"
21+
#include "clang/Sema/Scope.h"
22+
#include "clang/Sema/SemaBase.h"
23+
24+
namespace clang {
25+
26+
class SemaPseudoObject : public SemaBase {
27+
public:
28+
SemaPseudoObject(Sema &S);
29+
30+
ExprResult checkIncDec(Scope *S, SourceLocation OpLoc,
31+
UnaryOperatorKind Opcode, Expr *Op);
32+
ExprResult checkAssignment(Scope *S, SourceLocation OpLoc,
33+
BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS);
34+
ExprResult checkRValue(Expr *E);
35+
Expr *recreateSyntacticForm(PseudoObjectExpr *E);
36+
};
37+
38+
} // namespace clang
39+
40+
#endif // LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H

clang/lib/Sema/Sema.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "clang/Sema/SemaObjC.h"
5050
#include "clang/Sema/SemaOpenACC.h"
5151
#include "clang/Sema/SemaOpenMP.h"
52+
#include "clang/Sema/SemaPseudoObject.h"
5253
#include "clang/Sema/SemaSYCL.h"
5354
#include "clang/Sema/TemplateDeduction.h"
5455
#include "clang/Sema/TemplateInstCallback.h"
@@ -210,6 +211,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
210211
ObjCPtr(std::make_unique<SemaObjC>(*this)),
211212
OpenACCPtr(std::make_unique<SemaOpenACC>(*this)),
212213
OpenMPPtr(std::make_unique<SemaOpenMP>(*this)),
214+
PseudoObjectPtr(std::make_unique<SemaPseudoObject>(*this)),
213215
SYCLPtr(std::make_unique<SemaSYCL>(*this)),
214216
MSPointerToMemberRepresentationMethod(
215217
LangOpts.getMSPointerToMemberRepresentationMethod()),

clang/lib/Sema/SemaExpr.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "clang/Sema/SemaInternal.h"
5555
#include "clang/Sema/SemaObjC.h"
5656
#include "clang/Sema/SemaOpenMP.h"
57+
#include "clang/Sema/SemaPseudoObject.h"
5758
#include "clang/Sema/Template.h"
5859
#include "llvm/ADT/STLExtras.h"
5960
#include "llvm/ADT/STLForwardCompat.h"
@@ -15239,7 +15240,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
1523915240
LHSExpr = LHS.get();
1524015241
RHSExpr = RHS.get();
1524115242

15242-
// We want to end up calling one of checkPseudoObjectAssignment
15243+
// We want to end up calling one of SemaPseudoObject::checkAssignment
1524315244
// (if the LHS is a pseudo-object), BuildOverloadedBinOp (if
1524415245
// both expressions are overloadable or either is type-dependent),
1524515246
// or CreateBuiltinBinOp (in any other case). We also want to get
@@ -15250,7 +15251,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
1525015251
// Assignments with a pseudo-object l-value need special analysis.
1525115252
if (pty->getKind() == BuiltinType::PseudoObject &&
1525215253
BinaryOperator::isAssignmentOp(Opc))
15253-
return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr);
15254+
return PseudoObject().checkAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr);
1525415255

1525515256
// Don't resolve overloads if the other type is overloadable.
1525615257
if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload) {
@@ -15673,7 +15674,7 @@ ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
1567315674
// Increment and decrement of pseudo-object references.
1567415675
if (pty->getKind() == BuiltinType::PseudoObject &&
1567515676
UnaryOperator::isIncrementDecrementOp(Opc))
15676-
return checkPseudoObjectIncDec(S, OpLoc, Opc, Input);
15677+
return PseudoObject().checkIncDec(S, OpLoc, Opc, Input);
1567715678

1567815679
// extension is always a builtin operator.
1567915680
if (Opc == UO_Extension)
@@ -20890,7 +20891,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
2089020891

2089120892
// Pseudo-objects.
2089220893
case BuiltinType::PseudoObject:
20893-
return checkPseudoObjectRValue(E);
20894+
return PseudoObject().checkRValue(E);
2089420895

2089520896
case BuiltinType::BuiltinFn: {
2089620897
// Accept __noop without parens by implicitly converting it to a call expr.

clang/lib/Sema/SemaPseudoObject.cpp

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
//
3030
//===----------------------------------------------------------------------===//
3131

32+
#include "clang/Sema/SemaPseudoObject.h"
3233
#include "clang/AST/ExprCXX.h"
3334
#include "clang/AST/ExprObjC.h"
3435
#include "clang/Basic/CharInfo.h"
@@ -1446,73 +1447,73 @@ ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
14461447
// General Sema routines.
14471448
//===----------------------------------------------------------------------===//
14481449

1449-
ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
1450+
ExprResult SemaPseudoObject::checkRValue(Expr *E) {
14501451
Expr *opaqueRef = E->IgnoreParens();
14511452
if (ObjCPropertyRefExpr *refExpr
14521453
= dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1453-
ObjCPropertyOpBuilder builder(*this, refExpr, true);
1454+
ObjCPropertyOpBuilder builder(SemaRef, refExpr, true);
14541455
return builder.buildRValueOperation(E);
14551456
}
14561457
else if (ObjCSubscriptRefExpr *refExpr
14571458
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1458-
ObjCSubscriptOpBuilder builder(*this, refExpr, true);
1459+
ObjCSubscriptOpBuilder builder(SemaRef, refExpr, true);
14591460
return builder.buildRValueOperation(E);
14601461
} else if (MSPropertyRefExpr *refExpr
14611462
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1462-
MSPropertyOpBuilder builder(*this, refExpr, true);
1463+
MSPropertyOpBuilder builder(SemaRef, refExpr, true);
14631464
return builder.buildRValueOperation(E);
14641465
} else if (MSPropertySubscriptExpr *RefExpr =
14651466
dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1466-
MSPropertyOpBuilder Builder(*this, RefExpr, true);
1467+
MSPropertyOpBuilder Builder(SemaRef, RefExpr, true);
14671468
return Builder.buildRValueOperation(E);
14681469
} else {
14691470
llvm_unreachable("unknown pseudo-object kind!");
14701471
}
14711472
}
14721473

14731474
/// Check an increment or decrement of a pseudo-object expression.
1474-
ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
1475+
ExprResult SemaPseudoObject::checkIncDec(Scope *Sc, SourceLocation opcLoc,
14751476
UnaryOperatorKind opcode, Expr *op) {
14761477
// Do nothing if the operand is dependent.
14771478
if (op->isTypeDependent())
1478-
return UnaryOperator::Create(Context, op, opcode, Context.DependentTy,
1479-
VK_PRValue, OK_Ordinary, opcLoc, false,
1480-
CurFPFeatureOverrides());
1479+
return UnaryOperator::Create(
1480+
SemaRef.Context, op, opcode, SemaRef.Context.DependentTy, VK_PRValue,
1481+
OK_Ordinary, opcLoc, false, SemaRef.CurFPFeatureOverrides());
14811482

14821483
assert(UnaryOperator::isIncrementDecrementOp(opcode));
14831484
Expr *opaqueRef = op->IgnoreParens();
14841485
if (ObjCPropertyRefExpr *refExpr
14851486
= dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1486-
ObjCPropertyOpBuilder builder(*this, refExpr, false);
1487+
ObjCPropertyOpBuilder builder(SemaRef, refExpr, false);
14871488
return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
14881489
} else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
14891490
Diag(opcLoc, diag::err_illegal_container_subscripting_op);
14901491
return ExprError();
14911492
} else if (MSPropertyRefExpr *refExpr
14921493
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1493-
MSPropertyOpBuilder builder(*this, refExpr, false);
1494+
MSPropertyOpBuilder builder(SemaRef, refExpr, false);
14941495
return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
14951496
} else if (MSPropertySubscriptExpr *RefExpr
14961497
= dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1497-
MSPropertyOpBuilder Builder(*this, RefExpr, false);
1498+
MSPropertyOpBuilder Builder(SemaRef, RefExpr, false);
14981499
return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
14991500
} else {
15001501
llvm_unreachable("unknown pseudo-object kind!");
15011502
}
15021503
}
15031504

1504-
ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
1505+
ExprResult SemaPseudoObject::checkAssignment(Scope *S, SourceLocation opcLoc,
15051506
BinaryOperatorKind opcode,
15061507
Expr *LHS, Expr *RHS) {
15071508
// Do nothing if either argument is dependent.
15081509
if (LHS->isTypeDependent() || RHS->isTypeDependent())
1509-
return BinaryOperator::Create(Context, LHS, RHS, opcode,
1510-
Context.DependentTy, VK_PRValue, OK_Ordinary,
1511-
opcLoc, CurFPFeatureOverrides());
1510+
return BinaryOperator::Create(
1511+
SemaRef.Context, LHS, RHS, opcode, SemaRef.Context.DependentTy,
1512+
VK_PRValue, OK_Ordinary, opcLoc, SemaRef.CurFPFeatureOverrides());
15121513

15131514
// Filter out non-overload placeholder types in the RHS.
15141515
if (RHS->getType()->isNonOverloadPlaceholderType()) {
1515-
ExprResult result = CheckPlaceholderExpr(RHS);
1516+
ExprResult result = SemaRef.CheckPlaceholderExpr(RHS);
15161517
if (result.isInvalid()) return ExprError();
15171518
RHS = result.get();
15181519
}
@@ -1521,20 +1522,20 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
15211522
Expr *opaqueRef = LHS->IgnoreParens();
15221523
if (ObjCPropertyRefExpr *refExpr
15231524
= dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1524-
ObjCPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign);
1525+
ObjCPropertyOpBuilder builder(SemaRef, refExpr, IsSimpleAssign);
15251526
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
15261527
} else if (ObjCSubscriptRefExpr *refExpr
15271528
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1528-
ObjCSubscriptOpBuilder builder(*this, refExpr, IsSimpleAssign);
1529+
ObjCSubscriptOpBuilder builder(SemaRef, refExpr, IsSimpleAssign);
15291530
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
15301531
} else if (MSPropertyRefExpr *refExpr
15311532
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1532-
MSPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign);
1533-
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1533+
MSPropertyOpBuilder builder(SemaRef, refExpr, IsSimpleAssign);
1534+
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
15341535
} else if (MSPropertySubscriptExpr *RefExpr
15351536
= dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1536-
MSPropertyOpBuilder Builder(*this, RefExpr, IsSimpleAssign);
1537-
return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1537+
MSPropertyOpBuilder Builder(SemaRef, RefExpr, IsSimpleAssign);
1538+
return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
15381539
} else {
15391540
llvm_unreachable("unknown pseudo-object kind!");
15401541
}
@@ -1557,36 +1558,38 @@ static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
15571558
/// This is a hack which should be removed when TreeTransform is
15581559
/// capable of rebuilding a tree without stripping implicit
15591560
/// operations.
1560-
Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
1561+
Expr *SemaPseudoObject::recreateSyntacticForm(PseudoObjectExpr *E) {
15611562
Expr *syntax = E->getSyntacticForm();
15621563
if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
1563-
Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
1564-
return UnaryOperator::Create(Context, op, uop->getOpcode(), uop->getType(),
1565-
uop->getValueKind(), uop->getObjectKind(),
1566-
uop->getOperatorLoc(), uop->canOverflow(),
1567-
CurFPFeatureOverrides());
1564+
Expr *op = stripOpaqueValuesFromPseudoObjectRef(SemaRef, uop->getSubExpr());
1565+
return UnaryOperator::Create(
1566+
SemaRef.Context, op, uop->getOpcode(), uop->getType(),
1567+
uop->getValueKind(), uop->getObjectKind(), uop->getOperatorLoc(),
1568+
uop->canOverflow(), SemaRef.CurFPFeatureOverrides());
15681569
} else if (CompoundAssignOperator *cop
15691570
= dyn_cast<CompoundAssignOperator>(syntax)) {
1570-
Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
1571+
Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(SemaRef, cop->getLHS());
15711572
Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
15721573
return CompoundAssignOperator::Create(
1573-
Context, lhs, rhs, cop->getOpcode(), cop->getType(),
1574+
SemaRef.Context, lhs, rhs, cop->getOpcode(), cop->getType(),
15741575
cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(),
1575-
CurFPFeatureOverrides(), cop->getComputationLHSType(),
1576+
SemaRef.CurFPFeatureOverrides(), cop->getComputationLHSType(),
15761577
cop->getComputationResultType());
15771578

15781579
} else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1579-
Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
1580+
Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(SemaRef, bop->getLHS());
15801581
Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1581-
return BinaryOperator::Create(Context, lhs, rhs, bop->getOpcode(),
1582+
return BinaryOperator::Create(SemaRef.Context, lhs, rhs, bop->getOpcode(),
15821583
bop->getType(), bop->getValueKind(),
15831584
bop->getObjectKind(), bop->getOperatorLoc(),
1584-
CurFPFeatureOverrides());
1585+
SemaRef.CurFPFeatureOverrides());
15851586

15861587
} else if (isa<CallExpr>(syntax)) {
15871588
return syntax;
15881589
} else {
15891590
assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
1590-
return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
1591+
return stripOpaqueValuesFromPseudoObjectRef(SemaRef, syntax);
15911592
}
15921593
}
1594+
1595+
SemaPseudoObject::SemaPseudoObject(Sema &S) : SemaBase(S) {}

0 commit comments

Comments
 (0)