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:
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