clang: lib/AST/ExprClassification.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

20#include "llvm/Support/ErrorHandling.h"

21

22using namespace clang;

23

25

32 const Expr *trueExpr,

33 const Expr *falseExpr);

36

38 assert(!TR->isReferenceType() && "Expressions can't have reference type.");

39

41

42

44

47

48

49

52 }

53

54

55 switch (kind) {

58 break;

61 break;

73 break;

74 }

75

79 return Classification(kind, modifiable);

80}

81

82

88

89

90

92}

93

97 switch (Kind) {

104 }

105 llvm_unreachable("Invalid value category of implicit cast.");

106}

107

109

111

114#define ABSTRACT_STMT(Kind)

115#define STMT(Kind, Base) case Expr::Kind##Class:

116#define EXPR(Kind, Base)

117#include "clang/AST/StmtNodes.inc"

118 llvm_unreachable("cannot classify a statement");

119

120

121 case Expr::ObjCIsaExprClass:

122

123 case Expr::ObjCSubscriptRefExprClass:

124 case Expr::ObjCPropertyRefExprClass:

125

126 case Expr::CXXTypeidExprClass:

127 case Expr::CXXUuidofExprClass:

128

129

130 case Expr::UnresolvedLookupExprClass:

131 case Expr::UnresolvedMemberExprClass:

132 case Expr::TypoExprClass:

133 case Expr::DependentCoawaitExprClass:

134 case Expr::CXXDependentScopeMemberExprClass:

135 case Expr::DependentScopeDeclRefExprClass:

136

137

138 case Expr::ObjCIvarRefExprClass:

139 case Expr::FunctionParmPackExprClass:

140 case Expr::MSPropertyRefExprClass:

141 case Expr::MSPropertySubscriptExprClass:

142 case Expr::ArraySectionExprClass:

143 case Expr::OMPArrayShapingExprClass:

144 case Expr::OMPIteratorExprClass:

145 case Expr::HLSLOutArgExprClass:

147

148

149 case Expr::StringLiteralClass:

150

151 case Expr::ObjCEncodeExprClass:

152

153

155

156

157

158

159 case Expr::PredefinedExprClass: {

160 auto *PE = cast(E);

162 if (PE->isTransparent())

164 assert(!SL || SL->isLValue());

166 }

167

168

169

170 case Expr::CompoundLiteralExprClass:

172

173

174 case Expr::CXXBoolLiteralExprClass:

175 case Expr::CXXPseudoDestructorExprClass:

176 case Expr::UnaryExprOrTypeTraitExprClass:

177 case Expr::CXXNewExprClass:

178 case Expr::CXXNullPtrLiteralExprClass:

179 case Expr::ImaginaryLiteralClass:

180 case Expr::GNUNullExprClass:

181 case Expr::OffsetOfExprClass:

182 case Expr::CXXThrowExprClass:

183 case Expr::ShuffleVectorExprClass:

184 case Expr::ConvertVectorExprClass:

185 case Expr::IntegerLiteralClass:

186 case Expr::FixedPointLiteralClass:

187 case Expr::CharacterLiteralClass:

188 case Expr::AddrLabelExprClass:

189 case Expr::CXXDeleteExprClass:

190 case Expr::ImplicitValueInitExprClass:

191 case Expr::BlockExprClass:

192 case Expr::FloatingLiteralClass:

193 case Expr::CXXNoexceptExprClass:

194 case Expr::CXXScalarValueInitExprClass:

195 case Expr::TypeTraitExprClass:

196 case Expr::ArrayTypeTraitExprClass:

197 case Expr::ExpressionTraitExprClass:

198 case Expr::ObjCSelectorExprClass:

199 case Expr::ObjCProtocolExprClass:

200 case Expr::ObjCStringLiteralClass:

201 case Expr::ObjCBoxedExprClass:

202 case Expr::ObjCArrayLiteralClass:

203 case Expr::ObjCDictionaryLiteralClass:

204 case Expr::ObjCBoolLiteralExprClass:

205 case Expr::ObjCAvailabilityCheckExprClass:

206 case Expr::ParenListExprClass:

207 case Expr::SizeOfPackExprClass:

208 case Expr::SubstNonTypeTemplateParmPackExprClass:

209 case Expr::AsTypeExprClass:

210 case Expr::ObjCIndirectCopyRestoreExprClass:

211 case Expr::AtomicExprClass:

212 case Expr::CXXFoldExprClass:

213 case Expr::ArrayInitLoopExprClass:

214 case Expr::ArrayInitIndexExprClass:

215 case Expr::NoInitExprClass:

216 case Expr::DesignatedInitUpdateExprClass:

217 case Expr::SourceLocExprClass:

218 case Expr::ConceptSpecializationExprClass:

219 case Expr::RequiresExprClass:

221

222 case Expr::EmbedExprClass:

223

224

226

227

228 case Expr::CXXThisExprClass:

230

231 case Expr::ConstantExprClass:

232 return ClassifyInternal(Ctx, cast(E)->getSubExpr());

233

234

235 case Expr::SubstNonTypeTemplateParmExprClass:

237 cast(E)->getReplacement());

238

239 case Expr::PackIndexingExprClass: {

240

241

242 if (cast(E)->isInstantiationDependent())

244 return ClassifyInternal(Ctx, cast(E)->getSelectedExpr());

245 }

246

247

248

249

250

251 case Expr::ArraySubscriptExprClass:

252 if (cast(E)->getBase()->getType()->isVectorType())

253 return ClassifyInternal(Ctx, cast(E)->getBase());

254 if (Lang.CPlusPlus11) {

255

256

257 auto *Base = cast(E)->getBase()->IgnoreImpCasts();

258 if (Base->getType()->isArrayType())

260 }

262

263

264 case Expr::MatrixSubscriptExprClass:

265 return ClassifyInternal(Ctx, cast(E)->getBase());

266

267

268

269 case Expr::DeclRefExprClass:

271 return isa(cast(E)->getDecl())

273 return ClassifyDecl(Ctx, cast(E)->getDecl());

274

275

276 case Expr::MemberExprClass:

278

279 case Expr::UnaryOperatorClass:

280 switch (cast(E)->getOpcode()) {

281

282

283

284 case UO_Deref:

286

287

288 case UO_Extension:

289 return ClassifyInternal(Ctx, cast(E)->getSubExpr());

290

291

292

293 case UO_Real:

294 case UO_Imag: {

295 const Expr *Op = cast(E)->getSubExpr()->IgnoreParens();

298

299 if (isa(Op))

302 }

303

304

305

306

307 case UO_PreInc:

308 case UO_PreDec:

310

311 default:

313 }

314

315 case Expr::RecoveryExprClass:

316 case Expr::OpaqueValueExprClass:

318

319

320 case Expr::PseudoObjectExprClass:

322 cast(E)->getValueKind());

323

324

325

326 case Expr::ImplicitCastExprClass:

328

329

330

331 case Expr::ParenExprClass:

333

334

335

336

337 case Expr::GenericSelectionExprClass:

338 if (cast(E)->isResultDependent())

340 return ClassifyInternal(Ctx,cast(E)->getResultExpr());

341

342 case Expr::BinaryOperatorClass:

343 case Expr::CompoundAssignOperatorClass:

344

345 if (Lang.CPlusPlus)

348

349 case Expr::CallExprClass:

350 case Expr::CXXOperatorCallExprClass:

351 case Expr::CXXMemberCallExprClass:

352 case Expr::UserDefinedLiteralClass:

353 case Expr::CUDAKernelCallExprClass:

354 return ClassifyUnnamed(Ctx, cast(E)->getCallReturnType(Ctx));

355

356 case Expr::CXXRewrittenBinaryOperatorClass:

358 Ctx, cast(E)->getSemanticForm());

359

360

361 case Expr::ChooseExprClass:

362 return ClassifyInternal(Ctx, cast(E)->getChosenSubExpr());

363

364

365

366 case Expr::ExtVectorElementExprClass:

367 if (cast(E)->containsDuplicateElements())

369 if (cast(E)->isArrow())

371 return ClassifyInternal(Ctx, cast(E)->getBase());

372

373

374 case Expr::CXXDefaultArgExprClass:

375 return ClassifyInternal(Ctx, cast(E)->getExpr());

376

377

378 case Expr::CXXDefaultInitExprClass:

379 return ClassifyInternal(Ctx, cast(E)->getExpr());

380

381

382 case Expr::CXXBindTemporaryExprClass:

383 return ClassifyInternal(Ctx, cast(E)->getSubExpr());

384

385

386 case Expr::ExprWithCleanupsClass:

387 return ClassifyInternal(Ctx, cast(E)->getSubExpr());

388

389

390 case Expr::CStyleCastExprClass:

391 case Expr::CXXFunctionalCastExprClass:

392 case Expr::CXXStaticCastExprClass:

393 case Expr::CXXDynamicCastExprClass:

394 case Expr::CXXReinterpretCastExprClass:

395 case Expr::CXXConstCastExprClass:

396 case Expr::CXXAddrspaceCastExprClass:

397 case Expr::ObjCBridgedCastExprClass:

398 case Expr::BuiltinBitCastExprClass:

399

401 return ClassifyUnnamed(Ctx, cast(E)->getTypeAsWritten());

402

403 case Expr::CXXUnresolvedConstructExprClass:

405 cast(E)->getTypeAsWritten());

406

407 case Expr::BinaryConditionalOperatorClass: {

409 const auto *co = cast(E);

411 }

412

413 case Expr::ConditionalOperatorClass: {

414

416 const auto *co = cast(E);

418 }

419

420

421

422 case Expr::ObjCMessageExprClass:

424 cast(E)->getMethodDecl()) {

427 }

429

430

431 case Expr::CXXConstructExprClass:

432 case Expr::CXXInheritedCtorInitExprClass:

433 case Expr::CXXTemporaryObjectExprClass:

434 case Expr::LambdaExprClass:

435 case Expr::CXXStdInitializerListExprClass:

437

438 case Expr::VAArgExprClass:

440

441 case Expr::DesignatedInitExprClass:

442 return ClassifyInternal(Ctx, cast(E)->getInit());

443

444 case Expr::StmtExprClass: {

445 const CompoundStmt *S = cast(E)->getSubStmt();

446 if (const auto *LastExpr = dyn_cast_or_null(S->body_back()))

449 }

450

451 case Expr::PackExpansionExprClass:

452 return ClassifyInternal(Ctx, cast(E)->getPattern());

453

454 case Expr::MaterializeTemporaryExprClass:

455 return cast(E)->isBoundToLvalueReference()

458

459 case Expr::InitListExprClass:

460

461

462

463

466 assert(cast(E)->getNumInits() == 1 &&

467 "Only 1-element init lists can be glvalues.");

469

470 case Expr::CoawaitExprClass:

471 case Expr::CoyieldExprClass:

472 return ClassifyInternal(Ctx, cast(E)->getResumeExpr());

473 case Expr::SYCLUniqueStableNameExprClass:

474 case Expr::OpenACCAsteriskSizeExprClass:

476 break;

477

478 case Expr::CXXParenListInitExprClass:

479 if (isa(E->getType()))

482 }

483

484 llvm_unreachable("unhandled expression kind in classification");

485}

486

487

488

490

491

492

493

494

495

496

497

498 if (const auto *M = dyn_cast(D)) {

499 if (M->isImplicitObjectMemberFunction())

501 if (M->isStatic())

504 }

505

506 bool islvalue;

507 if (const auto *NTTParm = dyn_cast(D))

508 islvalue = NTTParm->getType()->isReferenceType() ||

509 NTTParm->getType()->isRecordType();

510 else

511 islvalue =

515 (isa<FunctionDecl, MSPropertyDecl, FunctionTemplateDecl>(D)));

516

518}

519

520

521

522

524

526

527

528

529

530

534 if (!RV)

536

538}

539

542 return (isa(E->getMemberDecl())

544

545

547

548

549

550 if (E->isArrow())

552

554 if (isa(Base))

557 }

558

560

561

562

563 if (const auto *Value = dyn_cast(Member))

566

567

568

569 if (isa(Member) && Member->getDeclContext()->isRecord())

571

572

573

574

575 if (isa(Member)) {

576

577 if (E->isArrow())

580 if (isa(Base))

583 }

584

585

586

587

588

589 if (const auto *Method = dyn_cast(Member)) {

590 if (Method->isStatic())

592 if (Method->isImplicitObjectMemberFunction())

595 }

596

597

598

600}

601

604 "This is only relevant for C++.");

605

606

607 if (E->isAssignmentOp())

610

611

612

613 if (E->getOpcode() == BO_Comma)

615

616

617

618

619 if (E->getOpcode() == BO_PtrMemD)

624

625

626

627 if (E->getOpcode() == BO_PtrMemI)

632

633

635}

636

640 "This is only relevant for C++.");

641

642

643

644

645 if (True->getType()->isVoidType() || False->getType()->isVoidType()) {

646

647

648

649 bool TrueIsThrow = isa(True->IgnoreParenImpCasts());

650 bool FalseIsThrow = isa(False->IgnoreParenImpCasts());

651 if (const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ? nullptr : False)

652 : (FalseIsThrow ? True : nullptr))

654

655

657 }

658

659

660

661

662

663

667}

668

671

672

674

675

676 if (const auto *CE = dyn_cast(E->IgnoreParens())) {

677 if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {

678 Loc = CE->getExprLoc();

680 }

681 }

682 }

685

686

687

690

691

692

693 if (const auto *Expr = dyn_cast(E)) {

694 if (Expr->isImplicitProperty() &&

695 Expr->getImplicitPropertySetter() == nullptr)

697 }

698

700

706

707

708 if (CT->isArrayType() &&

709 !(Ctx.getLangOpts().HLSL && CT->isConstantArrayType()))

711

712 if (CT->isIncompleteType())

714

715

717 if (R->hasConstFields())

719

721}

722

738 }

739 llvm_unreachable("Unhandled kind");

740}

741

761 }

764 case Cl::CM_Untested: llvm_unreachable("Did not test modifiability");

766 case Cl::CM_RValue: llvm_unreachable("CM_RValue and CL_LValue don't match");

769 llvm_unreachable("CM_LValueCast and CL_LValue don't match");

776 }

777 llvm_unreachable("Unhandled modifiable type");

778}

Defines the clang::ASTContext interface.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T)

ClassifyUnnamed - Return the classification of an expression yielding an unnamed value of the given t...

static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *trueExpr, const Expr *falseExpr)

static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D)

ClassifyDecl - Return the classification of an expression referencing the given declaration.

static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E)

static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E)

static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang, const Expr *E, ExprValueKind Kind)

static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, Cl::Kinds Kind, SourceLocation &Loc)

static Cl::Kinds ClassifyTemporary(QualType T)

Classify an expression which creates a temporary, based on its type.

static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E)

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

CanQualType getCanonicalType(QualType T) const

Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...

const LangOptions & getLangOpts() const

A builtin binary operation expression such as "x + y" or "x <= y".

A binding in a decomposition declaration.

bool isConstQualified() const

Qualifiers getQualifiers() const

Retrieve all qualifiers.

CanProxy< U > getAs() const

Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.

CompoundStmt - This represents a group of statements like { stmt stmt }.

Decl - This represents one declaration (or definition), e.g.

The return type of classify().

ModifiableType

The results of modification testing.

ModifiableType getModifiable() const

Kinds

The various classification results. Most of these mean prvalue.

@ CL_SubObjCPropertySetting

@ CL_DuplicateVectorComponents

This represents one expression.

@ LV_DuplicateVectorComponents

@ LV_InvalidMessageExpression

@ LV_SubObjCPropertySetting

Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const

ClassifyModifiable - Classify this expression according to the C++11 expression taxonomy,...

isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc=nullptr) const

isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, does not have an incomplet...

LValueClassification ClassifyLValue(ASTContext &Ctx) const

Reasons why an expression might not be an l-value.

ExprValueKind getValueKind() const

getValueKind - The value kind that this expression produces.

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

bool isLValue() const

isLValue - True if this expression is an "l-value" according to the rules of the current language.

ExprObjectKind getObjectKind() const

getObjectKind - The object kind that this expression produces.

@ MLV_DuplicateVectorComponents

@ MLV_InvalidMessageExpression

@ MLV_ConstQualifiedField

@ MLV_SubObjCPropertySetting

Classification Classify(ASTContext &Ctx) const

Classify - Classify this expression according to the C++11 expression taxonomy.

bool hasPlaceholderType() const

Returns whether this expression has a placeholder type.

Represents a member of a struct/union/class.

Represents a field injected from an anonymous union/struct into the parent scope.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

This represents a decl that may have a name.

ObjCMethodDecl - Represents an instance or class method declaration.

A (possibly-)qualified type.

bool hasQualifiers() const

Determine whether this type has any qualifiers.

LangAS getAddressSpace() const

An rvalue reference type, per C++11 [dcl.ref].

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

Encodes a location in the source.

StmtClass getStmtClass() const

StringLiteral - This represents a string literal expression, e.g.

A template parameter object.

bool isReferenceType() const

bool isLValueReferenceType() const

bool isFunctionType() const

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

An artificial decl, representing a global anonymous constant value which is uniquified by value withi...

Represents a variable declaration or definition.

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

@ OK_ObjCProperty

An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...

ExprValueKind

The categorization of expression values, currently following the C++11 scheme.

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

@ VK_XValue

An x-value expression is a reference to an object with independent storage but which can be "moved",...

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

const FunctionProtoType * T