21 #include "llvm/Support/ErrorHandling.h" 23 using namespace clang;
34 const Expr *falseExpr);
39 assert(!TR->
isReferenceType() &&
"Expressions can't have reference type.");
74 return Classification(kind, modifiable);
100 llvm_unreachable(
"Invalid value category of implicit cast.");
109 #define ABSTRACT_STMT(Kind) 110 #define STMT(Kind, Base) case Expr::Kind##Class: 111 #define EXPR(Kind, Base) 112 #include "clang/AST/StmtNodes.inc" 113 llvm_unreachable(
"cannot classify a statement");
116 case Expr::ObjCIsaExprClass:
118 case Expr::StringLiteralClass:
120 case Expr::ObjCEncodeExprClass:
122 case Expr::PredefinedExprClass:
124 case Expr::ObjCSubscriptRefExprClass:
125 case Expr::ObjCPropertyRefExprClass:
127 case Expr::CXXTypeidExprClass:
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::OMPArraySectionExprClass:
147 case Expr::CompoundLiteralExprClass:
151 case Expr::CXXBoolLiteralExprClass:
152 case Expr::CXXPseudoDestructorExprClass:
153 case Expr::UnaryExprOrTypeTraitExprClass:
154 case Expr::CXXNewExprClass:
155 case Expr::CXXThisExprClass:
156 case Expr::CXXNullPtrLiteralExprClass:
157 case Expr::ImaginaryLiteralClass:
158 case Expr::GNUNullExprClass:
159 case Expr::OffsetOfExprClass:
160 case Expr::CXXThrowExprClass:
161 case Expr::ShuffleVectorExprClass:
162 case Expr::ConvertVectorExprClass:
163 case Expr::IntegerLiteralClass:
164 case Expr::FixedPointLiteralClass:
165 case Expr::CharacterLiteralClass:
166 case Expr::AddrLabelExprClass:
167 case Expr::CXXDeleteExprClass:
168 case Expr::ImplicitValueInitExprClass:
169 case Expr::BlockExprClass:
170 case Expr::FloatingLiteralClass:
171 case Expr::CXXNoexceptExprClass:
172 case Expr::CXXScalarValueInitExprClass:
173 case Expr::TypeTraitExprClass:
174 case Expr::ArrayTypeTraitExprClass:
175 case Expr::ExpressionTraitExprClass:
176 case Expr::ObjCSelectorExprClass:
177 case Expr::ObjCProtocolExprClass:
178 case Expr::ObjCStringLiteralClass:
179 case Expr::ObjCBoxedExprClass:
180 case Expr::ObjCArrayLiteralClass:
181 case Expr::ObjCDictionaryLiteralClass:
182 case Expr::ObjCBoolLiteralExprClass:
183 case Expr::ObjCAvailabilityCheckExprClass:
184 case Expr::ParenListExprClass:
185 case Expr::SizeOfPackExprClass:
186 case Expr::SubstNonTypeTemplateParmPackExprClass:
187 case Expr::AsTypeExprClass:
188 case Expr::ObjCIndirectCopyRestoreExprClass:
189 case Expr::AtomicExprClass:
190 case Expr::CXXFoldExprClass:
191 case Expr::ArrayInitLoopExprClass:
192 case Expr::ArrayInitIndexExprClass:
193 case Expr::NoInitExprClass:
194 case Expr::DesignatedInitUpdateExprClass:
197 case Expr::ConstantExprClass:
201 case Expr::SubstNonTypeTemplateParmExprClass:
203 cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
209 case Expr::ArraySubscriptExprClass:
210 if (cast<ArraySubscriptExpr>(E)->getBase()->
getType()->isVectorType())
212 if (Lang.CPlusPlus11) {
215 auto *
Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreImpCasts();
216 if (
Base->getType()->isArrayType())
223 case Expr::DeclRefExprClass:
225 return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl())
227 return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());
230 case Expr::MemberExprClass:
233 case Expr::UnaryOperatorClass:
234 switch (cast<UnaryOperator>(E)->
getOpcode()) {
253 if (isa<ObjCPropertyRefExpr>(Op))
269 case Expr::OpaqueValueExprClass:
273 case Expr::PseudoObjectExprClass:
279 case Expr::ImplicitCastExprClass:
284 case Expr::ParenExprClass:
290 case Expr::GenericSelectionExprClass:
291 if (cast<GenericSelectionExpr>(E)->isResultDependent())
293 return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr());
295 case Expr::BinaryOperatorClass:
296 case Expr::CompoundAssignOperatorClass:
302 case Expr::CallExprClass:
303 case Expr::CXXOperatorCallExprClass:
304 case Expr::CXXMemberCallExprClass:
305 case Expr::UserDefinedLiteralClass:
306 case Expr::CUDAKernelCallExprClass:
307 return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType(Ctx));
310 case Expr::ChooseExprClass:
315 case Expr::ExtVectorElementExprClass:
316 if (cast<ExtVectorElementExpr>(E)->containsDuplicateElements())
318 if (cast<ExtVectorElementExpr>(E)->isArrow())
323 case Expr::CXXDefaultArgExprClass:
327 case Expr::CXXDefaultInitExprClass:
331 case Expr::CXXBindTemporaryExprClass:
335 case Expr::ExprWithCleanupsClass:
339 case Expr::CStyleCastExprClass:
340 case Expr::CXXFunctionalCastExprClass:
341 case Expr::CXXStaticCastExprClass:
342 case Expr::CXXDynamicCastExprClass:
343 case Expr::CXXReinterpretCastExprClass:
344 case Expr::CXXConstCastExprClass:
345 case Expr::ObjCBridgedCastExprClass:
348 return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
350 case Expr::CXXUnresolvedConstructExprClass:
352 cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
354 case Expr::BinaryConditionalOperatorClass: {
356 const auto *co = cast<BinaryConditionalOperator>(E);
360 case Expr::ConditionalOperatorClass: {
363 const auto *co = cast<ConditionalOperator>(E);
369 case Expr::ObjCMessageExprClass:
371 cast<ObjCMessageExpr>(E)->getMethodDecl()) {
378 case Expr::CXXConstructExprClass:
379 case Expr::CXXInheritedCtorInitExprClass:
380 case Expr::CXXTemporaryObjectExprClass:
381 case Expr::LambdaExprClass:
382 case Expr::CXXStdInitializerListExprClass:
385 case Expr::VAArgExprClass:
388 case Expr::DesignatedInitExprClass:
391 case Expr::StmtExprClass: {
392 const CompoundStmt *S = cast<StmtExpr>(E)->getSubStmt();
393 if (
const auto *LastExpr = dyn_cast_or_null<Expr>(S->
body_back()))
398 case Expr::CXXUuidofExprClass:
401 case Expr::PackExpansionExprClass:
404 case Expr::MaterializeTemporaryExprClass:
405 return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference()
409 case Expr::InitListExprClass:
416 assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
417 "Only 1-element init lists can be glvalues.");
420 case Expr::CoawaitExprClass:
421 case Expr::CoyieldExprClass:
422 return ClassifyInternal(Ctx, cast<CoroutineSuspendExpr>(E)->getResumeExpr());
425 llvm_unreachable(
"unhandled expression kind in classification");
438 if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
442 if (
const auto *NTTParm = dyn_cast<NonTypeTemplateParmDecl>(D))
443 islvalue = NTTParm->getType()->isReferenceType();
445 islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) ||
446 isa<IndirectFieldDecl>(D) ||
447 isa<BindingDecl>(D) ||
449 (isa<FunctionDecl>(D) || isa<MSPropertyDecl>(D) ||
450 isa<FunctionTemplateDecl>(D)));
486 return Cl::CL_LValue;
489 if (isa<ObjCPropertyRefExpr>(Base))
498 if (
const auto *
Value = dyn_cast<ValueDecl>(Member))
499 if (
Value->getType()->isReferenceType())
500 return Cl::CL_LValue;
505 return Cl::CL_LValue;
510 if (isa<FieldDecl>(Member)) {
513 return Cl::CL_LValue;
515 if (isa<ObjCPropertyRefExpr>(Base))
524 if (
const auto *Method = dyn_cast<CXXMethodDecl>(Member))
534 "This is only relevant for C++.");
570 "This is only relevant for C++.");
581 if (
const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ?
nullptr : False)
582 : (FalseIsThrow ? True :
nullptr))
606 if (
const auto *CE = dyn_cast<ExplicitCastExpr>(E->
IgnoreParens())) {
607 if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
608 Loc = CE->getExprLoc();
623 if (
const auto *
Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
624 if (
Expr->isImplicitProperty() &&
625 Expr->getImplicitPropertySetter() ==
nullptr)
638 if (CT->isArrayType())
641 if (CT->isIncompleteType())
646 if (R->hasConstFields())
668 llvm_unreachable(
"Unhandled kind");
695 case Cl::CM_RValue: llvm_unreachable(
"CM_RValue and CL_LValue don't match");
698 llvm_unreachable(
"CM_LValueCast and CL_LValue don't match");
706 llvm_unreachable(
"Unhandled modifiable type");
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
bool isConstQualified() const
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
Defines the C++ template declaration subclasses.
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang, const Expr *E, ExprValueKind Kind)
const T * getAs() const
Member-template getAs<specific type>'.
ObjCMethodDecl - Represents an instance or class method declaration.
static bool isAssignmentOp(Opcode Opc)
Defines the clang::Expr interface and subclasses for C++ expressions.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
LValueClassification ClassifyLValue(ASTContext &Ctx) const
Reasons why an expression might not be an l-value.
static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, Cl::Kinds Kind, SourceLocation &Loc)
bool isReferenceType() const
Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const
ClassifyModifiable - Classify this expression according to the C++11 expression taxonomy, and see if it is valid on the left side of an assignment.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
An rvalue reference type, per C++11 [dcl.ref].
An x-value expression is a reference to an object with independent storage but which can be "moved"...
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
A builtin binary operation expression such as "x + y" or "x <= y".
LangAS getAddressSpace() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
The return type of classify().
bool hasQualifiers() const
Determine whether this type has any qualifiers.
Kinds
The various classification results. Most of these mean prvalue.
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
This represents one expression.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
DeclContext * getDeclContext()
ModifiableType
The results of modification testing.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
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 ClassifyInternal(ASTContext &Ctx, const Expr *E)
Encodes a location in the source.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
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...
static Cl::Kinds ClassifyTemporary(QualType T)
Classify an expression which creates a temporary, based on its type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed...
static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E)
Dataflow Directional Tag Classes.
ModifiableType getModifiable() const
BinaryOperator::Opcode getOpcode(const SymExpr *SE)
static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D)
ClassifyDecl - Return the classification of an expression referencing the given declaration.
StmtClass getStmtClass() const
static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *trueExpr, const Expr *falseExpr)
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
bool isFunctionType() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool isLValueReferenceType() const
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E)
An l-value expression is a reference to an object with independent storage.
This represents a decl that may have a name.
const LangOptions & getLangOpts() const
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.