summaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r--lib/AST/Expr.cpp130
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: