21 #include "llvm/Support/ErrorHandling.h"
22 using namespace clang;
33 const Expr *falseExpr);
38 assert(!TR->
isReferenceType() &&
"Expressions can't have reference type.");
73 return Classification(kind, modifiable);
99 llvm_unreachable(
"Invalid value category of implicit cast.");
106 switch (E->getStmtClass()) {
107 case Stmt::NoStmtClass:
108 #define ABSTRACT_STMT(Kind)
109 #define STMT(Kind, Base) case Expr::Kind##Class:
110 #define EXPR(Kind, Base)
111 #include "clang/AST/StmtNodes.inc"
112 llvm_unreachable(
"cannot classify a statement");
115 case Expr::ObjCIsaExprClass:
117 case Expr::StringLiteralClass:
119 case Expr::ObjCEncodeExprClass:
121 case Expr::PredefinedExprClass:
123 case Expr::ObjCSubscriptRefExprClass:
124 case Expr::ObjCPropertyRefExprClass:
126 case Expr::CXXTypeidExprClass:
129 case Expr::UnresolvedLookupExprClass:
130 case Expr::UnresolvedMemberExprClass:
131 case Expr::TypoExprClass:
132 case Expr::CXXDependentScopeMemberExprClass:
133 case Expr::DependentScopeDeclRefExprClass:
136 case Expr::ObjCIvarRefExprClass:
137 case Expr::FunctionParmPackExprClass:
138 case Expr::MSPropertyRefExprClass:
143 case Expr::CompoundLiteralExprClass:
148 case Expr::CXXBoolLiteralExprClass:
149 case Expr::CXXPseudoDestructorExprClass:
150 case Expr::UnaryExprOrTypeTraitExprClass:
151 case Expr::CXXNewExprClass:
152 case Expr::CXXThisExprClass:
153 case Expr::CXXNullPtrLiteralExprClass:
154 case Expr::ImaginaryLiteralClass:
155 case Expr::GNUNullExprClass:
156 case Expr::OffsetOfExprClass:
157 case Expr::CXXThrowExprClass:
158 case Expr::ShuffleVectorExprClass:
159 case Expr::ConvertVectorExprClass:
160 case Expr::IntegerLiteralClass:
161 case Expr::CharacterLiteralClass:
162 case Expr::AddrLabelExprClass:
163 case Expr::CXXDeleteExprClass:
164 case Expr::ImplicitValueInitExprClass:
165 case Expr::BlockExprClass:
166 case Expr::FloatingLiteralClass:
167 case Expr::CXXNoexceptExprClass:
168 case Expr::CXXScalarValueInitExprClass:
169 case Expr::TypeTraitExprClass:
170 case Expr::ArrayTypeTraitExprClass:
171 case Expr::ExpressionTraitExprClass:
172 case Expr::ObjCSelectorExprClass:
173 case Expr::ObjCProtocolExprClass:
174 case Expr::ObjCStringLiteralClass:
175 case Expr::ObjCBoxedExprClass:
176 case Expr::ObjCArrayLiteralClass:
177 case Expr::ObjCDictionaryLiteralClass:
178 case Expr::ObjCBoolLiteralExprClass:
179 case Expr::ParenListExprClass:
180 case Expr::SizeOfPackExprClass:
181 case Expr::SubstNonTypeTemplateParmPackExprClass:
182 case Expr::AsTypeExprClass:
183 case Expr::ObjCIndirectCopyRestoreExprClass:
184 case Expr::AtomicExprClass:
185 case Expr::CXXFoldExprClass:
186 case Expr::NoInitExprClass:
187 case Expr::DesignatedInitUpdateExprClass:
191 case Expr::SubstNonTypeTemplateParmExprClass:
193 cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
197 case Expr::ArraySubscriptExprClass:
198 if (cast<ArraySubscriptExpr>(E)->getBase()->getType()->isVectorType())
204 case Expr::DeclRefExprClass:
206 return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl())
208 return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());
211 case Expr::MemberExprClass:
214 case Expr::UnaryOperatorClass:
215 switch (cast<UnaryOperator>(E)->getOpcode()) {
234 if (isa<ObjCPropertyRefExpr>(Op))
250 case Expr::OpaqueValueExprClass:
254 case Expr::PseudoObjectExprClass:
256 cast<PseudoObjectExpr>(E)->getValueKind());
260 case Expr::ImplicitCastExprClass:
265 case Expr::ParenExprClass:
271 case Expr::GenericSelectionExprClass:
272 if (cast<GenericSelectionExpr>(E)->isResultDependent())
274 return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr());
276 case Expr::BinaryOperatorClass:
277 case Expr::CompoundAssignOperatorClass:
283 case Expr::CallExprClass:
284 case Expr::CXXOperatorCallExprClass:
285 case Expr::CXXMemberCallExprClass:
286 case Expr::UserDefinedLiteralClass:
287 case Expr::CUDAKernelCallExprClass:
288 return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType(Ctx));
291 case Expr::ChooseExprClass:
296 case Expr::ExtVectorElementExprClass:
297 if (cast<ExtVectorElementExpr>(E)->containsDuplicateElements())
299 if (cast<ExtVectorElementExpr>(E)->isArrow())
304 case Expr::CXXDefaultArgExprClass:
308 case Expr::CXXDefaultInitExprClass:
312 case Expr::CXXBindTemporaryExprClass:
316 case Expr::ExprWithCleanupsClass:
320 case Expr::CStyleCastExprClass:
321 case Expr::CXXFunctionalCastExprClass:
322 case Expr::CXXStaticCastExprClass:
323 case Expr::CXXDynamicCastExprClass:
324 case Expr::CXXReinterpretCastExprClass:
325 case Expr::CXXConstCastExprClass:
326 case Expr::ObjCBridgedCastExprClass:
329 return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
331 case Expr::CXXUnresolvedConstructExprClass:
333 cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
335 case Expr::BinaryConditionalOperatorClass: {
341 case Expr::ConditionalOperatorClass: {
350 case Expr::ObjCMessageExprClass:
352 cast<ObjCMessageExpr>(E)->getMethodDecl()) {
359 case Expr::CXXConstructExprClass:
360 case Expr::CXXTemporaryObjectExprClass:
361 case Expr::LambdaExprClass:
362 case Expr::CXXStdInitializerListExprClass:
365 case Expr::VAArgExprClass:
368 case Expr::DesignatedInitExprClass:
371 case Expr::StmtExprClass: {
373 if (
const Expr *LastExpr = dyn_cast_or_null<Expr>(S->
body_back()))
378 case Expr::CXXUuidofExprClass:
381 case Expr::PackExpansionExprClass:
384 case Expr::MaterializeTemporaryExprClass:
385 return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference()
389 case Expr::InitListExprClass:
396 assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
397 "Only 1-element init lists can be glvalues.");
401 llvm_unreachable(
"unhandled expression kind in classification");
414 if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
419 dyn_cast<NonTypeTemplateParmDecl>(D))
420 islvalue = NTTParm->getType()->isReferenceType();
422 islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) ||
423 isa<IndirectFieldDecl>(D) ||
425 (isa<FunctionDecl>(D) || isa<MSPropertyDecl>(D) ||
426 isa<FunctionTemplateDecl>(D)));
462 return Cl::CL_LValue;
465 if (isa<ObjCPropertyRefExpr>(Base))
475 if (
Value->getType()->isReferenceType())
476 return Cl::CL_LValue;
481 return Cl::CL_LValue;
486 if (isa<FieldDecl>(Member)) {
489 return Cl::CL_LValue;
491 if (isa<ObjCPropertyRefExpr>(Base))
510 "This is only relevant for C++.");
546 "This is only relevant for C++.");
557 if (
const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ?
nullptr : False)
558 : (FalseIsThrow ? True :
nullptr))
584 if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
585 Loc = CE->getExprLoc();
601 if (
Expr->isImplicitProperty() &&
602 Expr->getImplicitPropertySetter() ==
nullptr)
614 if (CT->isArrayType())
617 if (CT->isIncompleteType())
622 if (R->hasConstFields())
644 llvm_unreachable(
"Unhandled kind");
671 case Cl::CM_RValue: llvm_unreachable(
"CM_RValue and CL_LValue don't match");
674 llvm_unreachable(
"CM_LValueCast and CL_LValue don't match");
681 llvm_unreachable(
"Unhandled modifiable type");
LValueClassification ClassifyLValue(ASTContext &Ctx) const
Reasons why an expression might not be an l-value.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Defines the clang::ASTContext interface.
ExprObjectKind getObjectKind() const
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool isRecordType() const
Defines the C++ template declaration subclasses.
bool isConstQualified() const
static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang, const Expr *E, ExprValueKind Kind)
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.
static bool isAssignmentOp(Opcode Opc)
Defines the clang::Expr interface and subclasses for C++ expressions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isReferenceType() const
static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, Cl::Kinds Kind, SourceLocation &Loc)
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.
const LangOptions & getLangOpts() const
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed...
An x-value expression is a reference to an object with independent storage but which can be "moved"...
A builtin binary operation expression such as "x + y" or "x <= y".
Expr * getFalseExpr() const
The return type of classify(). Represents the C++11 expression taxonomy.
Kinds
The various classification results. Most of these mean prvalue.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
DeclContext * getDeclContext()
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc=nullptr) const
ModifiableType
The results of modification testing.
Expr * getTrueExpr() const
static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T)
static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
Represents a static or instance method of a struct/union/class.
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)
static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D)
ModifiableType getModifiable() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool isLValueReferenceType() const
static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *trueExpr, const Expr *falseExpr)
Expr * IgnoreParenImpCasts() LLVM_READONLY
bool isFunctionType() const
unsigned getAddressSpace() const
QualType getPointeeType() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condnition evaluates to false;...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E)
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool hasQualifiers() const
Determine whether this type has any qualifiers.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression which will be evaluated if the condition evaluates to true; th...
An l-value expression is a reference to an object with independent storage.
Expr * IgnoreParens() LLVM_READONLY