20#include "llvm/Support/ErrorHandling.h"
33 const Expr *falseExpr);
38 assert(!TR->
isReferenceType() &&
"Expressions can't have reference type.");
79 return Classification(kind, modifiable);
105 llvm_unreachable(
"Invalid value category of implicit cast.");
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");
121 case Expr::ObjCIsaExprClass:
123 case Expr::ObjCSubscriptRefExprClass:
124 case Expr::ObjCPropertyRefExprClass:
126 case Expr::CXXTypeidExprClass:
127 case Expr::CXXUuidofExprClass:
130 case Expr::UnresolvedLookupExprClass:
131 case Expr::UnresolvedMemberExprClass:
132 case Expr::TypoExprClass:
133 case Expr::DependentCoawaitExprClass:
134 case Expr::CXXDependentScopeMemberExprClass:
135 case Expr::DependentScopeDeclRefExprClass:
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:
149 case Expr::StringLiteralClass:
151 case Expr::ObjCEncodeExprClass:
159 case Expr::PredefinedExprClass: {
160 auto *PE = cast<PredefinedExpr>(
E);
162 if (PE->isTransparent())
170 case Expr::CompoundLiteralExprClass:
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:
222 case Expr::EmbedExprClass:
228 case Expr::CXXThisExprClass:
231 case Expr::ConstantExprClass:
235 case Expr::SubstNonTypeTemplateParmExprClass:
237 cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement());
239 case Expr::PackIndexingExprClass: {
242 if (cast<PackIndexingExpr>(
E)->isInstantiationDependent())
251 case Expr::ArraySubscriptExprClass:
252 if (cast<ArraySubscriptExpr>(
E)->getBase()->getType()->isVectorType())
254 if (Lang.CPlusPlus11) {
257 auto *
Base = cast<ArraySubscriptExpr>(
E)->getBase()->IgnoreImpCasts();
258 if (
Base->getType()->isArrayType())
264 case Expr::MatrixSubscriptExprClass:
269 case Expr::DeclRefExprClass:
271 return isa<FunctionDecl>(cast<DeclRefExpr>(
E)->getDecl())
276 case Expr::MemberExprClass:
279 case Expr::UnaryOperatorClass:
280 switch (cast<UnaryOperator>(
E)->getOpcode()) {
299 if (isa<ObjCPropertyRefExpr>(Op))
315 case Expr::RecoveryExprClass:
316 case Expr::OpaqueValueExprClass:
320 case Expr::PseudoObjectExprClass:
322 cast<PseudoObjectExpr>(
E)->getValueKind());
326 case Expr::ImplicitCastExprClass:
331 case Expr::ParenExprClass:
337 case Expr::GenericSelectionExprClass:
338 if (cast<GenericSelectionExpr>(
E)->isResultDependent())
342 case Expr::BinaryOperatorClass:
343 case Expr::CompoundAssignOperatorClass:
349 case Expr::CallExprClass:
350 case Expr::CXXOperatorCallExprClass:
351 case Expr::CXXMemberCallExprClass:
352 case Expr::UserDefinedLiteralClass:
353 case Expr::CUDAKernelCallExprClass:
356 case Expr::CXXRewrittenBinaryOperatorClass:
358 Ctx, cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm());
361 case Expr::ChooseExprClass:
366 case Expr::ExtVectorElementExprClass:
367 if (cast<ExtVectorElementExpr>(
E)->containsDuplicateElements())
369 if (cast<ExtVectorElementExpr>(
E)->isArrow())
374 case Expr::CXXDefaultArgExprClass:
378 case Expr::CXXDefaultInitExprClass:
382 case Expr::CXXBindTemporaryExprClass:
386 case Expr::ExprWithCleanupsClass:
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:
403 case Expr::CXXUnresolvedConstructExprClass:
405 cast<CXXUnresolvedConstructExpr>(
E)->getTypeAsWritten());
407 case Expr::BinaryConditionalOperatorClass: {
409 const auto *co = cast<BinaryConditionalOperator>(
E);
413 case Expr::ConditionalOperatorClass: {
416 const auto *co = cast<ConditionalOperator>(
E);
422 case Expr::ObjCMessageExprClass:
424 cast<ObjCMessageExpr>(
E)->getMethodDecl()) {
431 case Expr::CXXConstructExprClass:
432 case Expr::CXXInheritedCtorInitExprClass:
433 case Expr::CXXTemporaryObjectExprClass:
434 case Expr::LambdaExprClass:
435 case Expr::CXXStdInitializerListExprClass:
438 case Expr::VAArgExprClass:
441 case Expr::DesignatedInitExprClass:
444 case Expr::StmtExprClass: {
446 if (
const auto *LastExpr = dyn_cast_or_null<Expr>(S->body_back()))
451 case Expr::PackExpansionExprClass:
454 case Expr::MaterializeTemporaryExprClass:
455 return cast<MaterializeTemporaryExpr>(
E)->isBoundToLvalueReference()
459 case Expr::InitListExprClass:
466 assert(cast<InitListExpr>(
E)->getNumInits() == 1 &&
467 "Only 1-element init lists can be glvalues.");
470 case Expr::CoawaitExprClass:
471 case Expr::CoyieldExprClass:
473 case Expr::SYCLUniqueStableNameExprClass:
474 case Expr::OpenACCAsteriskSizeExprClass:
478 case Expr::CXXParenListInitExprClass:
484 llvm_unreachable(
"unhandled expression kind in classification");
498 if (
const auto *M = dyn_cast<CXXMethodDecl>(
D)) {
499 if (M->isImplicitObjectMemberFunction())
507 if (
const auto *NTTParm = dyn_cast<NonTypeTemplateParmDecl>(
D))
508 islvalue = NTTParm->getType()->isReferenceType() ||
509 NTTParm->getType()->isRecordType();
515 (isa<FunctionDecl, MSPropertyDecl, FunctionTemplateDecl>(
D)));
542 return (isa<FunctionDecl>(
E->getMemberDecl())
554 if (isa<ObjCPropertyRefExpr>(
Base))
563 if (
const auto *
Value = dyn_cast<ValueDecl>(
Member))
569 if (isa<VarDecl>(
Member) &&
Member->getDeclContext()->isRecord())
575 if (isa<FieldDecl>(
Member)) {
580 if (isa<ObjCPropertyRefExpr>(
Base))
589 if (
const auto *Method = dyn_cast<CXXMethodDecl>(
Member)) {
590 if (Method->isStatic())
592 if (Method->isImplicitObjectMemberFunction())
604 "This is only relevant for C++.");
607 if (
E->isAssignmentOp())
613 if (
E->getOpcode() == BO_Comma)
619 if (
E->getOpcode() == BO_PtrMemD)
627 if (
E->getOpcode() == BO_PtrMemI)
640 "This is only relevant for C++.");
645 if (
True->getType()->isVoidType() ||
False->getType()->isVoidType()) {
649 bool TrueIsThrow = isa<CXXThrowExpr>(
True->IgnoreParenImpCasts());
650 bool FalseIsThrow = isa<CXXThrowExpr>(
False->IgnoreParenImpCasts());
651 if (
const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ?
nullptr :
False)
652 : (FalseIsThrow ?
True :
nullptr))
676 if (
const auto *CE = dyn_cast<ExplicitCastExpr>(
E->
IgnoreParens())) {
677 if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
678 Loc = CE->getExprLoc();
693 if (
const auto *
Expr = dyn_cast<ObjCPropertyRefExpr>(
E)) {
694 if (
Expr->isImplicitProperty() &&
695 Expr->getImplicitPropertySetter() ==
nullptr)
708 if (CT->isArrayType() &&
709 !(Ctx.
getLangOpts().HLSL && CT->isConstantArrayType()))
712 if (CT->isIncompleteType())
717 if (R->hasConstFields())
739 llvm_unreachable(
"Unhandled kind");
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");
777 llvm_unreachable(
"Unhandled modifiable type");
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<specific type>'.
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