diff options
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 130 |
1 files changed, 101 insertions, 29 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 7ddab9356b54a..193efa4e097d9 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -108,7 +108,7 @@ const Expr *Expr::skipRValueSubobjectAdjustments( } } } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { - if (BO->isPtrMemOp()) { + if (BO->getOpcode() == BO_PtrMemD) { assert(BO->getRHS()->isRValue()); E = BO->getLHS(); const MemberPointerType *MPT = @@ -230,7 +230,7 @@ SourceLocation Expr::getExprLoc() const { // Primary Expressions. //===----------------------------------------------------------------------===// -/// \brief Compute the type-, value-, and instantiation-dependence of a +/// Compute the type-, value-, and instantiation-dependence of a /// declaration reference /// based on the declaration being referenced. static void computeDeclRefDependence(const ASTContext &Ctx, NamedDecl *D, @@ -484,6 +484,8 @@ StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) { return "__PRETTY_FUNCTION__"; case FuncSig: return "__FUNCSIG__"; + case LFuncSig: + return "L__FUNCSIG__"; case PrettyFunctionNoVirtual: break; } @@ -536,7 +538,8 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { return Out.str(); } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { - if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && IT != FuncSig) + if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && + IT != FuncSig && IT != LFuncSig) return FD->getNameAsString(); SmallString<256> Name; @@ -561,7 +564,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { if (FD->hasWrittenPrototype()) FT = dyn_cast<FunctionProtoType>(AFT); - if (IT == FuncSig) { + if (IT == FuncSig || IT == LFuncSig) { switch (AFT->getCallConv()) { case CC_C: POut << "__cdecl "; break; case CC_X86StdCall: POut << "__stdcall "; break; @@ -586,7 +589,8 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { if (FT->isVariadic()) { if (FD->getNumParams()) POut << ", "; POut << "..."; - } else if ((IT == FuncSig || !Context.getLangOpts().CPlusPlus) && + } else if ((IT == FuncSig || IT == LFuncSig || + !Context.getLangOpts().CPlusPlus) && !Decl->getNumParams()) { POut << "void"; } @@ -755,6 +759,36 @@ IntegerLiteral::Create(const ASTContext &C, EmptyShell Empty) { return new (C) IntegerLiteral(Empty); } +FixedPointLiteral::FixedPointLiteral(const ASTContext &C, const llvm::APInt &V, + QualType type, SourceLocation l, + unsigned Scale) + : Expr(FixedPointLiteralClass, type, VK_RValue, OK_Ordinary, false, false, + false, false), + Loc(l), Scale(Scale) { + assert(type->isFixedPointType() && "Illegal type in FixedPointLiteral"); + assert(V.getBitWidth() == C.getTypeInfo(type).Width && + "Fixed point type is not the correct size for constant."); + setValue(C, V); +} + +FixedPointLiteral *FixedPointLiteral::CreateFromRawInt(const ASTContext &C, + const llvm::APInt &V, + QualType type, + SourceLocation l, + unsigned Scale) { + return new (C) FixedPointLiteral(C, V, type, l, Scale); +} + +std::string FixedPointLiteral::getValueAsString(unsigned Radix) const { + // Currently the longest decimal number that can be printed is the max for an + // unsigned long _Accum: 4294967295.99999999976716935634613037109375 + // which is 43 characters. + SmallString<64> S; + FixedPointValueToString( + S, llvm::APSInt::getUnsigned(getValue().getZExtValue()), Scale, Radix); + return S.str(); +} + FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, @@ -881,7 +915,8 @@ StringLiteral *StringLiteral::CreateEmpty(const ASTContext &C, void *Mem = C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1), alignof(StringLiteral)); - StringLiteral *SL = new (Mem) StringLiteral(QualType()); + StringLiteral *SL = + new (Mem) StringLiteral(C.adjustStringLiteralBaseType(QualType())); SL->CharByteWidth = 0; SL->Length = 0; SL->NumConcatenated = NumStrs; @@ -1633,8 +1668,8 @@ bool CastExpr::CastConsistency() const { return true; } -const char *CastExpr::getCastKindName() const { - switch (getCastKind()) { +const char *CastExpr::getCastKindName(CastKind CK) { + switch (CK) { #define CAST_OPERATION(Name) case CK_##Name: return #Name; #include "clang/AST/OperationKinds.def" } @@ -1642,23 +1677,22 @@ const char *CastExpr::getCastKindName() const { } namespace { - Expr *skipImplicitTemporary(Expr *expr) { + const Expr *skipImplicitTemporary(const Expr *E) { // Skip through reference binding to temporary. - if (MaterializeTemporaryExpr *Materialize - = dyn_cast<MaterializeTemporaryExpr>(expr)) - expr = Materialize->GetTemporaryExpr(); + if (auto *Materialize = dyn_cast<MaterializeTemporaryExpr>(E)) + E = Materialize->GetTemporaryExpr(); // Skip any temporary bindings; they're implicit. - if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(expr)) - expr = Binder->getSubExpr(); + if (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) + E = Binder->getSubExpr(); - return expr; + return E; } } Expr *CastExpr::getSubExprAsWritten() { - Expr *SubExpr = nullptr; - CastExpr *E = this; + const Expr *SubExpr = nullptr; + const CastExpr *E = this; do { SubExpr = skipImplicitTemporary(E->getSubExpr()); @@ -1671,15 +1705,33 @@ Expr *CastExpr::getSubExprAsWritten() { assert((isa<CXXMemberCallExpr>(SubExpr) || isa<BlockExpr>(SubExpr)) && "Unexpected SubExpr for CK_UserDefinedConversion."); - if (isa<CXXMemberCallExpr>(SubExpr)) - SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument(); + if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SubExpr)) + SubExpr = MCE->getImplicitObjectArgument(); } // If the subexpression we're left with is an implicit cast, look // through that, too. } while ((E = dyn_cast<ImplicitCastExpr>(SubExpr))); - return SubExpr; + return const_cast<Expr*>(SubExpr); +} + +NamedDecl *CastExpr::getConversionFunction() const { + const Expr *SubExpr = nullptr; + + for (const CastExpr *E = this; E; E = dyn_cast<ImplicitCastExpr>(SubExpr)) { + SubExpr = skipImplicitTemporary(E->getSubExpr()); + + if (E->getCastKind() == CK_ConstructorConversion) + return cast<CXXConstructExpr>(SubExpr)->getConstructor(); + + if (E->getCastKind() == CK_UserDefinedConversion) { + if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SubExpr)) + return MCE->getMethodDecl(); + } + } + + return nullptr; } CXXBaseSpecifier **CastExpr::path_buffer() { @@ -2049,6 +2101,10 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, case GenericSelectionExprClass: return cast<GenericSelectionExpr>(this)->getResultExpr()-> isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx); + case CoawaitExprClass: + case CoyieldExprClass: + return cast<CoroutineSuspendExpr>(this)->getResumeExpr()-> + isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx); case ChooseExprClass: return cast<ChooseExpr>(this)->getChosenSubExpr()-> isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx); @@ -2628,7 +2684,7 @@ bool Expr::isDefaultArgument() const { return isa<CXXDefaultArgExpr>(E); } -/// \brief Skip over any no-op casts and any temporary-binding +/// Skip over any no-op casts and any temporary-binding /// expressions. static const Expr *skipTemporaryBindingsNoOpCastsAndParens(const Expr *E) { if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E)) @@ -2917,8 +2973,20 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, return false; } +bool CallExpr::isBuiltinAssumeFalse(const ASTContext &Ctx) const { + const FunctionDecl* FD = getDirectCallee(); + if (!FD || (FD->getBuiltinID() != Builtin::BI__assume && + FD->getBuiltinID() != Builtin::BI__builtin_assume)) + return false; + + const Expr* Arg = getArg(0); + bool ArgVal; + return !Arg->isValueDependent() && + Arg->EvaluateAsBooleanCondition(ArgVal, Ctx) && !ArgVal; +} + namespace { - /// \brief Look for any side effects within a Stmt. + /// Look for any side effects within a Stmt. class SideEffectFinder : public ConstEvaluatedExprVisitor<SideEffectFinder> { typedef ConstEvaluatedExprVisitor<SideEffectFinder> Inherited; const bool IncludePossibleEffects; @@ -2974,6 +3042,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ObjCIvarRefExprClass: case PredefinedExprClass: case IntegerLiteralClass: + case FixedPointLiteralClass: case FloatingLiteralClass: case ImaginaryLiteralClass: case StringLiteralClass: @@ -3214,7 +3283,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, } namespace { - /// \brief Look for a call to a non-trivial function within an expression. + /// Look for a call to a non-trivial function within an expression. class NonTrivialCallFinder : public ConstEvaluatedExprVisitor<NonTrivialCallFinder> { typedef ConstEvaluatedExprVisitor<NonTrivialCallFinder> Inherited; @@ -3390,7 +3459,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx, return NPCK_ZeroExpression; } -/// \brief If this expression is an l-value for an Objective C +/// If this expression is an l-value for an Objective C /// property, find the underlying property reference expression. const ObjCPropertyRefExpr *Expr::getObjCProperty() const { const Expr *E = this; @@ -3446,10 +3515,11 @@ FieldDecl *Expr::getSourceBitField() { if (Field->isBitField()) return Field; - if (ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) - if (FieldDecl *Ivar = dyn_cast<FieldDecl>(IvarRef->getDecl())) - if (Ivar->isBitField()) - return Ivar; + if (ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) { + FieldDecl *Ivar = IvarRef->getDecl(); + if (Ivar->isBitField()) + return Ivar; + } if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E)) { if (FieldDecl *Field = dyn_cast<FieldDecl>(DeclRef->getDecl())) @@ -3813,7 +3883,7 @@ Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator &D) const { return getSubExpr(D.ArrayOrRange.Index + 2); } -/// \brief Replaces the designator at index @p Idx with the series +/// Replaces the designator at index @p Idx with the series /// of designators in [First, Last). void DesignatedInitExpr::ExpandDesignator(const ASTContext &C, unsigned Idx, const Designator *First, @@ -4034,6 +4104,8 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { case AO__atomic_or_fetch: case AO__atomic_xor_fetch: case AO__atomic_nand_fetch: + case AO__atomic_fetch_min: + case AO__atomic_fetch_max: return 3; case AO__opencl_atomic_store: |