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:
148 case Expr::StringLiteralClass:
150 case Expr::ObjCEncodeExprClass:
158 case Expr::PredefinedExprClass: {
159 auto *PE = cast<PredefinedExpr>(
E);
161 if (PE->isTransparent())
169 case Expr::CompoundLiteralExprClass:
173 case Expr::CXXBoolLiteralExprClass:
174 case Expr::CXXPseudoDestructorExprClass:
175 case Expr::UnaryExprOrTypeTraitExprClass:
176 case Expr::CXXNewExprClass:
177 case Expr::CXXNullPtrLiteralExprClass:
178 case Expr::ImaginaryLiteralClass:
179 case Expr::GNUNullExprClass:
180 case Expr::OffsetOfExprClass:
181 case Expr::CXXThrowExprClass:
182 case Expr::ShuffleVectorExprClass:
183 case Expr::ConvertVectorExprClass:
184 case Expr::IntegerLiteralClass:
185 case Expr::FixedPointLiteralClass:
186 case Expr::CharacterLiteralClass:
187 case Expr::AddrLabelExprClass:
188 case Expr::CXXDeleteExprClass:
189 case Expr::ImplicitValueInitExprClass:
190 case Expr::BlockExprClass:
191 case Expr::FloatingLiteralClass:
192 case Expr::CXXNoexceptExprClass:
193 case Expr::CXXScalarValueInitExprClass:
194 case Expr::TypeTraitExprClass:
195 case Expr::ArrayTypeTraitExprClass:
196 case Expr::ExpressionTraitExprClass:
197 case Expr::ObjCSelectorExprClass:
198 case Expr::ObjCProtocolExprClass:
199 case Expr::ObjCStringLiteralClass:
200 case Expr::ObjCBoxedExprClass:
201 case Expr::ObjCArrayLiteralClass:
202 case Expr::ObjCDictionaryLiteralClass:
203 case Expr::ObjCBoolLiteralExprClass:
204 case Expr::ObjCAvailabilityCheckExprClass:
205 case Expr::ParenListExprClass:
206 case Expr::SizeOfPackExprClass:
207 case Expr::SubstNonTypeTemplateParmPackExprClass:
208 case Expr::AsTypeExprClass:
209 case Expr::ObjCIndirectCopyRestoreExprClass:
210 case Expr::AtomicExprClass:
211 case Expr::CXXFoldExprClass:
212 case Expr::ArrayInitLoopExprClass:
213 case Expr::ArrayInitIndexExprClass:
214 case Expr::NoInitExprClass:
215 case Expr::DesignatedInitUpdateExprClass:
216 case Expr::SourceLocExprClass:
217 case Expr::ConceptSpecializationExprClass:
218 case Expr::RequiresExprClass:
221 case Expr::EmbedExprClass:
227 case Expr::CXXThisExprClass:
230 case Expr::ConstantExprClass:
234 case Expr::SubstNonTypeTemplateParmExprClass:
236 cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement());
238 case Expr::PackIndexingExprClass: {
241 if (cast<PackIndexingExpr>(
E)->isInstantiationDependent())
250 case Expr::ArraySubscriptExprClass:
251 if (cast<ArraySubscriptExpr>(
E)->getBase()->getType()->isVectorType())
253 if (Lang.CPlusPlus11) {
256 auto *
Base = cast<ArraySubscriptExpr>(
E)->getBase()->IgnoreImpCasts();
257 if (
Base->getType()->isArrayType())
263 case Expr::MatrixSubscriptExprClass:
268 case Expr::DeclRefExprClass:
270 return isa<FunctionDecl>(cast<DeclRefExpr>(
E)->getDecl())
275 case Expr::MemberExprClass:
278 case Expr::UnaryOperatorClass:
279 switch (cast<UnaryOperator>(
E)->getOpcode()) {
298 if (isa<ObjCPropertyRefExpr>(Op))
314 case Expr::RecoveryExprClass:
315 case Expr::OpaqueValueExprClass:
319 case Expr::PseudoObjectExprClass:
321 cast<PseudoObjectExpr>(
E)->getValueKind());
325 case Expr::ImplicitCastExprClass:
330 case Expr::ParenExprClass:
336 case Expr::GenericSelectionExprClass:
337 if (cast<GenericSelectionExpr>(
E)->isResultDependent())
341 case Expr::BinaryOperatorClass:
342 case Expr::CompoundAssignOperatorClass:
348 case Expr::CallExprClass:
349 case Expr::CXXOperatorCallExprClass:
350 case Expr::CXXMemberCallExprClass:
351 case Expr::UserDefinedLiteralClass:
352 case Expr::CUDAKernelCallExprClass:
355 case Expr::CXXRewrittenBinaryOperatorClass:
357 Ctx, cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm());
360 case Expr::ChooseExprClass:
365 case Expr::ExtVectorElementExprClass:
366 if (cast<ExtVectorElementExpr>(
E)->containsDuplicateElements())
368 if (cast<ExtVectorElementExpr>(
E)->isArrow())
373 case Expr::CXXDefaultArgExprClass:
377 case Expr::CXXDefaultInitExprClass:
381 case Expr::CXXBindTemporaryExprClass:
385 case Expr::ExprWithCleanupsClass:
389 case Expr::CStyleCastExprClass:
390 case Expr::CXXFunctionalCastExprClass:
391 case Expr::CXXStaticCastExprClass:
392 case Expr::CXXDynamicCastExprClass:
393 case Expr::CXXReinterpretCastExprClass:
394 case Expr::CXXConstCastExprClass:
395 case Expr::CXXAddrspaceCastExprClass:
396 case Expr::ObjCBridgedCastExprClass:
397 case Expr::BuiltinBitCastExprClass:
402 case Expr::CXXUnresolvedConstructExprClass:
404 cast<CXXUnresolvedConstructExpr>(
E)->getTypeAsWritten());
406 case Expr::BinaryConditionalOperatorClass: {
408 const auto *co = cast<BinaryConditionalOperator>(
E);
412 case Expr::ConditionalOperatorClass: {
415 const auto *co = cast<ConditionalOperator>(
E);
421 case Expr::ObjCMessageExprClass:
423 cast<ObjCMessageExpr>(
E)->getMethodDecl()) {
430 case Expr::CXXConstructExprClass:
431 case Expr::CXXInheritedCtorInitExprClass:
432 case Expr::CXXTemporaryObjectExprClass:
433 case Expr::LambdaExprClass:
434 case Expr::CXXStdInitializerListExprClass:
437 case Expr::VAArgExprClass:
440 case Expr::DesignatedInitExprClass:
443 case Expr::StmtExprClass: {
445 if (
const auto *LastExpr = dyn_cast_or_null<Expr>(S->body_back()))
450 case Expr::PackExpansionExprClass:
453 case Expr::MaterializeTemporaryExprClass:
454 return cast<MaterializeTemporaryExpr>(
E)->isBoundToLvalueReference()
458 case Expr::InitListExprClass:
465 assert(cast<InitListExpr>(
E)->getNumInits() == 1 &&
466 "Only 1-element init lists can be glvalues.");
469 case Expr::CoawaitExprClass:
470 case Expr::CoyieldExprClass:
472 case Expr::SYCLUniqueStableNameExprClass:
476 case Expr::CXXParenListInitExprClass:
482 llvm_unreachable(
"unhandled expression kind in classification");
496 if (
const auto *M = dyn_cast<CXXMethodDecl>(
D)) {
497 if (M->isImplicitObjectMemberFunction())
505 if (
const auto *NTTParm = dyn_cast<NonTypeTemplateParmDecl>(
D))
506 islvalue = NTTParm->getType()->isReferenceType() ||
507 NTTParm->getType()->isRecordType();
513 (isa<FunctionDecl, MSPropertyDecl, FunctionTemplateDecl>(
D)));
540 return (isa<FunctionDecl>(
E->getMemberDecl())
552 if (isa<ObjCPropertyRefExpr>(
Base))
561 if (
const auto *
Value = dyn_cast<ValueDecl>(
Member))
567 if (isa<VarDecl>(
Member) &&
Member->getDeclContext()->isRecord())
573 if (isa<FieldDecl>(
Member)) {
578 if (isa<ObjCPropertyRefExpr>(
Base))
587 if (
const auto *Method = dyn_cast<CXXMethodDecl>(
Member)) {
588 if (Method->isStatic())
590 if (Method->isImplicitObjectMemberFunction())
602 "This is only relevant for C++.");
605 if (
E->isAssignmentOp())
611 if (
E->getOpcode() == BO_Comma)
617 if (
E->getOpcode() == BO_PtrMemD)
625 if (
E->getOpcode() == BO_PtrMemI)
638 "This is only relevant for C++.");
643 if (
True->getType()->isVoidType() ||
False->getType()->isVoidType()) {
647 bool TrueIsThrow = isa<CXXThrowExpr>(
True->IgnoreParenImpCasts());
648 bool FalseIsThrow = isa<CXXThrowExpr>(
False->IgnoreParenImpCasts());
649 if (
const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ?
nullptr :
False)
650 : (FalseIsThrow ?
True :
nullptr))
674 if (
const auto *CE = dyn_cast<ExplicitCastExpr>(
E->
IgnoreParens())) {
675 if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
676 Loc = CE->getExprLoc();
691 if (
const auto *
Expr = dyn_cast<ObjCPropertyRefExpr>(
E)) {
692 if (
Expr->isImplicitProperty() &&
693 Expr->getImplicitPropertySetter() ==
nullptr)
706 if (CT->isArrayType())
709 if (CT->isIncompleteType())
714 if (R->hasConstFields())
736 llvm_unreachable(
"Unhandled kind");
763 case Cl::CM_RValue: llvm_unreachable(
"CM_RValue and CL_LValue don't match");
766 llvm_unreachable(
"CM_LValueCast and CL_LValue don't match");
774 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