summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/Expr.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Expr.cpp140
1 files changed, 81 insertions, 59 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/Expr.cpp b/contrib/llvm/tools/clang/lib/AST/Expr.cpp
index 712de50..76a4da2 100644
--- a/contrib/llvm/tools/clang/lib/AST/Expr.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Expr.cpp
@@ -1141,40 +1141,13 @@ CallExpr::CallExpr(const ASTContext& C, StmtClass SC, Expr *fn,
RParenLoc = rparenloc;
}
-CallExpr::CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args,
+CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args,
QualType t, ExprValueKind VK, SourceLocation rparenloc)
- : Expr(CallExprClass, t, VK, OK_Ordinary,
- fn->isTypeDependent(),
- fn->isValueDependent(),
- fn->isInstantiationDependent(),
- fn->containsUnexpandedParameterPack()),
- NumArgs(args.size()) {
-
- SubExprs = new (C) Stmt*[args.size()+PREARGS_START];
- SubExprs[FN] = fn;
- for (unsigned i = 0; i != args.size(); ++i) {
- if (args[i]->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (args[i]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (args[i]->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (args[i]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
- SubExprs[i+PREARGS_START] = args[i];
- }
-
- CallExprBits.NumPreArgs = 0;
- RParenLoc = rparenloc;
+ : CallExpr(C, CallExprClass, fn, /*NumPreArgs=*/0, args, t, VK, rparenloc) {
}
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
- // FIXME: Why do we allocate this?
- SubExprs = new (C) Stmt*[PREARGS_START];
- CallExprBits.NumPreArgs = 0;
-}
+ : CallExpr(C, SC, /*NumPreArgs=*/0, Empty) {}
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
EmptyShell Empty)
@@ -1271,16 +1244,21 @@ bool CallExpr::isUnevaluatedBuiltinCall(ASTContext &Ctx) const {
return false;
}
-QualType CallExpr::getCallReturnType() const {
- QualType CalleeType = getCallee()->getType();
- if (const PointerType *FnTypePtr = CalleeType->getAs<PointerType>())
+QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const {
+ const Expr *Callee = getCallee();
+ QualType CalleeType = Callee->getType();
+ if (const auto *FnTypePtr = CalleeType->getAs<PointerType>()) {
CalleeType = FnTypePtr->getPointeeType();
- else if (const BlockPointerType *BPT = CalleeType->getAs<BlockPointerType>())
+ } else if (const auto *BPT = CalleeType->getAs<BlockPointerType>()) {
CalleeType = BPT->getPointeeType();
- else if (CalleeType->isSpecificPlaceholderType(BuiltinType::BoundMember))
+ } else if (CalleeType->isSpecificPlaceholderType(BuiltinType::BoundMember)) {
+ if (isa<CXXPseudoDestructorExpr>(Callee->IgnoreParens()))
+ return Ctx.VoidTy;
+
// This should never be overloaded and so should never return null.
- CalleeType = Expr::findBoundMemberType(getCallee());
-
+ CalleeType = Expr::findBoundMemberType(Callee);
+ }
+
const FunctionType *FnType = CalleeType->castAs<FunctionType>();
return FnType->getReturnType();
}
@@ -1360,16 +1338,50 @@ IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const {
return reinterpret_cast<IdentifierInfo *> (Data & ~(uintptr_t)Mask);
}
-MemberExpr *MemberExpr::Create(const ASTContext &C, Expr *base, bool isarrow,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *memberdecl,
- DeclAccessPair founddecl,
- DeclarationNameInfo nameinfo,
- const TemplateArgumentListInfo *targs,
- QualType ty,
- ExprValueKind vk,
- ExprObjectKind ok) {
+UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr(
+ UnaryExprOrTypeTrait ExprKind, Expr *E, QualType resultType,
+ SourceLocation op, SourceLocation rp)
+ : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
+ false, // Never type-dependent (C++ [temp.dep.expr]p3).
+ // Value-dependent if the argument is type-dependent.
+ E->isTypeDependent(), E->isInstantiationDependent(),
+ E->containsUnexpandedParameterPack()),
+ OpLoc(op), RParenLoc(rp) {
+ UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
+ UnaryExprOrTypeTraitExprBits.IsType = false;
+ Argument.Ex = E;
+
+ // Check to see if we are in the situation where alignof(decl) should be
+ // dependent because decl's alignment is dependent.
+ if (ExprKind == UETT_AlignOf) {
+ if (!isValueDependent() || !isInstantiationDependent()) {
+ E = E->IgnoreParens();
+
+ const ValueDecl *D = nullptr;
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
+ D = DRE->getDecl();
+ else if (const auto *ME = dyn_cast<MemberExpr>(E))
+ D = ME->getMemberDecl();
+
+ if (D) {
+ for (const auto *I : D->specific_attrs<AlignedAttr>()) {
+ if (I->isAlignmentDependent()) {
+ setValueDependent(true);
+ setInstantiationDependent(true);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+MemberExpr *MemberExpr::Create(
+ const ASTContext &C, Expr *base, bool isarrow, SourceLocation OperatorLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+ ValueDecl *memberdecl, DeclAccessPair founddecl,
+ DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs,
+ QualType ty, ExprValueKind vk, ExprObjectKind ok) {
std::size_t Size = sizeof(MemberExpr);
bool hasQualOrFound = (QualifierLoc ||
@@ -1384,8 +1396,8 @@ MemberExpr *MemberExpr::Create(const ASTContext &C, Expr *base, bool isarrow,
Size += ASTTemplateKWAndArgsInfo::sizeFor(0);
void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>());
- MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo,
- ty, vk, ok);
+ MemberExpr *E = new (Mem)
+ MemberExpr(base, isarrow, OperatorLoc, memberdecl, nameinfo, ty, vk, ok);
if (hasQualOrFound) {
// FIXME: Wrong. We should be looking at the member declaration we found.
@@ -2132,8 +2144,8 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
case OO_Greater:
case OO_GreaterEqual:
case OO_LessEqual:
- if (Op->getCallReturnType()->isReferenceType() ||
- Op->getCallReturnType()->isVoidType())
+ if (Op->getCallReturnType(Ctx)->isReferenceType() ||
+ Op->getCallReturnType(Ctx)->isVoidType())
break;
WarnE = this;
Loc = Op->getOperatorLoc();
@@ -2149,12 +2161,16 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
// If this is a direct call, get the callee.
const CallExpr *CE = cast<CallExpr>(this);
if (const Decl *FD = CE->getCalleeDecl()) {
+ const FunctionDecl *Func = dyn_cast<FunctionDecl>(FD);
+ bool HasWarnUnusedResultAttr = Func ? Func->hasUnusedResultAttr()
+ : FD->hasAttr<WarnUnusedResultAttr>();
+
// If the callee has attribute pure, const, or warn_unused_result, warn
// about it. void foo() { strlen("bar"); } should warn.
//
// Note: If new cases are added here, DiagnoseUnusedExprResult should be
// updated to match for QoI.
- if (FD->hasAttr<WarnUnusedResultAttr>() ||
+ if (HasWarnUnusedResultAttr ||
FD->hasAttr<PureAttr>() || FD->hasAttr<ConstAttr>()) {
WarnE = this;
Loc = CE->getCallee()->getLocStart();
@@ -2200,9 +2216,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
}
if (const ObjCMethodDecl *MD = ME->getMethodDecl())
- if (MD->hasAttr<WarnUnusedResultAttr>() ||
- (MD->isPropertyAccessor() && !MD->getReturnType()->isVoidType() &&
- !ME->getReceiverType()->isObjCIdType())) {
+ if (MD->hasAttr<WarnUnusedResultAttr>()) {
WarnE = this;
Loc = getExprLoc();
return true;
@@ -2387,7 +2401,7 @@ QualType Expr::findBoundMemberType(const Expr *expr) {
return type;
}
- assert(isa<UnresolvedMemberExpr>(expr));
+ assert(isa<UnresolvedMemberExpr>(expr) || isa<CXXPseudoDestructorExpr>(expr));
return QualType();
}
@@ -2932,11 +2946,19 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case CXXOperatorCallExprClass:
case CXXMemberCallExprClass:
case CUDAKernelCallExprClass:
+ case UserDefinedLiteralClass: {
+ // We don't know a call definitely has side effects, except for calls
+ // to pure/const functions that definitely don't.
+ // If the call itself is considered side-effect free, check the operands.
+ const Decl *FD = cast<CallExpr>(this)->getCalleeDecl();
+ bool IsPure = FD && (FD->hasAttr<ConstAttr>() || FD->hasAttr<PureAttr>());
+ if (IsPure || !IncludePossibleEffects)
+ break;
+ return true;
+ }
+
case BlockExprClass:
case CXXBindTemporaryExprClass:
- case UserDefinedLiteralClass:
- // We don't know a call definitely has side effects, but we can check the
- // call's operands.
if (!IncludePossibleEffects)
break;
return true;
OpenPOWER on IntegriCloud