summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r--clang/lib/AST/Expr.cpp188
1 files changed, 80 insertions, 108 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index d3157680222..6cda82b2b0c 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1,4 +1,4 @@
-//===- Expr.cpp - Expression AST Node Implementation ----------------------===//
+//===--- Expr.cpp - Expression AST Node Implementation --------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,62 +11,28 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/Expr.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/EvaluatedExprVisitor.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/Mangle.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/OperationKinds.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/AddressSpaces.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Lambda.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/TypeTraits.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/LiteralSupport.h"
-#include "clang/Lex/Token.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
+#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
#include <cstring>
-#include <memory>
-#include <string>
-#include <utility>
-
using namespace clang;
const Expr *Expr::getBestDynamicClassTypeExpr() const {
@@ -227,23 +193,24 @@ bool Expr::isKnownToHaveBooleanValue() const {
// a more specific implementation of getExprLoc().
//
// See also Stmt.cpp:{getLocStart(),getLocEnd()}.
+namespace {
+ /// This implementation is used when a class provides a custom
+ /// implementation of getExprLoc.
+ template <class E, class T>
+ SourceLocation getExprLocImpl(const Expr *expr,
+ SourceLocation (T::*v)() const) {
+ return static_cast<const E*>(expr)->getExprLoc();
+ }
-/// This implementation is used when a class provides a custom
-/// implementation of getExprLoc.
-template <class E, class T>
-static SourceLocation getExprLocImpl(const Expr *expr,
- SourceLocation (T::*v)() const) {
- return static_cast<const E*>(expr)->getExprLoc();
-}
-
-/// This implementation is used when a class doesn't provide
-/// a custom implementation of getExprLoc. Overload resolution
-/// should pick it over the implementation above because it's
-/// more specialized according to function template partial ordering.
-template <class E>
-static SourceLocation getExprLocImpl(const Expr *expr,
- SourceLocation (Expr::*v)() const) {
- return static_cast<const E*>(expr)->getLocStart();
+ /// This implementation is used when a class doesn't provide
+ /// a custom implementation of getExprLoc. Overload resolution
+ /// should pick it over the implementation above because it's
+ /// more specialized according to function template partial ordering.
+ template <class E>
+ SourceLocation getExprLocImpl(const Expr *expr,
+ SourceLocation (Expr::*v)() const) {
+ return static_cast<const E*>(expr)->getLocStart();
+ }
}
SourceLocation Expr::getExprLoc() const {
@@ -485,7 +452,6 @@ SourceLocation DeclRefExpr::getLocStart() const {
return getQualifierLoc().getBeginLoc();
return getNameInfo().getLocStart();
}
-
SourceLocation DeclRefExpr::getLocEnd() const {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
@@ -640,9 +606,8 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
POut << " &&";
}
- using SpecsTy = SmallVector<const ClassTemplateSpecializationDecl *, 8>;
+ typedef SmallVector<const ClassTemplateSpecializationDecl *, 8> SpecsTy;
SpecsTy Specs;
-
const DeclContext *Ctx = FD->getDeclContext();
while (Ctx && isa<NamedDecl>(Ctx)) {
const ClassTemplateSpecializationDecl *Spec
@@ -800,7 +765,7 @@ FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V,
}
FloatingLiteral::FloatingLiteral(const ASTContext &C, EmptyShell Empty)
- : Expr(FloatingLiteralClass, Empty) {
+ : Expr(FloatingLiteralClass, Empty) {
setRawSemantics(IEEEhalf);
FloatingLiteralBits.IsExact = false;
}
@@ -1070,6 +1035,7 @@ void StringLiteral::setString(const ASTContext &C, StringRef Str,
/// Using these two parameters can reduce the time complexity from O(n^2) to
/// O(n) if one wants to get the location of byte for all the tokens in a
/// string.
+///
SourceLocation
StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
const LangOptions &Features,
@@ -1088,7 +1054,7 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
StringOffset = *StartTokenByteOffset;
ByteNo -= StringOffset;
}
- while (true) {
+ while (1) {
assert(TokNo < getNumConcatenated() && "Invalid byte number!");
SourceLocation StrTokLoc = getStrTokenLoc(TokNo);
@@ -1143,6 +1109,8 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
}
}
+
+
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "sizeof" or "[pre]++".
StringRef UnaryOperator::getOpcodeStr(Opcode Op) {
@@ -1184,6 +1152,7 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) {
}
}
+
//===----------------------------------------------------------------------===//
// Postfix Operators.
//===----------------------------------------------------------------------===//
@@ -1195,6 +1164,7 @@ CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
fn->isValueDependent(), fn->isInstantiationDependent(),
fn->containsUnexpandedParameterPack()),
NumArgs(args.size()) {
+
unsigned NumPreArgs = preargs.size();
SubExprs = new (C) Stmt *[args.size()+PREARGS_START+NumPreArgs];
SubExprs[FN] = fn;
@@ -1218,15 +1188,15 @@ CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args,
QualType t, ExprValueKind VK, SourceLocation rparenloc)
- : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK,
- rparenloc) {}
+ : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {
+}
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
: CallExpr(C, SC, /*NumPreArgs=*/0, Empty) {}
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
EmptyShell Empty)
- : Expr(SC, Empty) {
+ : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
// FIXME: Why do we allocate this?
SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs]();
CallExprBits.NumPreArgs = NumPreArgs;
@@ -1362,7 +1332,6 @@ SourceLocation CallExpr::getLocStart() const {
begin = getArg(0)->getLocStart();
return begin;
}
-
SourceLocation CallExpr::getLocEnd() const {
if (isa<CXXOperatorCallExpr>(this))
return cast<CXXOperatorCallExpr>(this)->getLocEnd();
@@ -1424,7 +1393,7 @@ IdentifierInfo *OffsetOfNode::getFieldName() const {
if (getKind() == Field)
return getField()->getIdentifier();
- return reinterpret_cast<IdentifierInfo *>(Data & ~(uintptr_t)Mask);
+ return reinterpret_cast<IdentifierInfo *> (Data & ~(uintptr_t)Mask);
}
UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr(
@@ -1471,6 +1440,7 @@ MemberExpr *MemberExpr::Create(
ValueDecl *memberdecl, DeclAccessPair founddecl,
DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs,
QualType ty, ExprValueKind vk, ExprObjectKind ok) {
+
bool hasQualOrFound = (QualifierLoc ||
founddecl.getDecl() != memberdecl ||
founddecl.getAccess() != memberdecl->getAccess());
@@ -1538,7 +1508,6 @@ SourceLocation MemberExpr::getLocStart() const {
return BaseStartLoc;
return MemberLoc;
}
-
SourceLocation MemberExpr::getLocEnd() const {
SourceLocation EndLoc = getMemberNameInfo().getEndLoc();
if (hasExplicitTemplateArgs())
@@ -1672,17 +1641,19 @@ const char *CastExpr::getCastKindName() const {
llvm_unreachable("Unhandled cast kind!");
}
-static Expr *skipImplicitTemporary(Expr *expr) {
- // Skip through reference binding to temporary.
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(expr))
- expr = Materialize->GetTemporaryExpr();
+namespace {
+ Expr *skipImplicitTemporary(Expr *expr) {
+ // Skip through reference binding to temporary.
+ if (MaterializeTemporaryExpr *Materialize
+ = dyn_cast<MaterializeTemporaryExpr>(expr))
+ expr = Materialize->GetTemporaryExpr();
- // Skip any temporary bindings; they're implicit.
- if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(expr))
- expr = Binder->getSubExpr();
+ // Skip any temporary bindings; they're implicit.
+ if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(expr))
+ expr = Binder->getSubExpr();
- return expr;
+ return expr;
+ }
}
Expr *CastExpr::getSubExprAsWritten() {
@@ -1890,13 +1861,13 @@ bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx,
return true;
}
-
InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
ArrayRef<Expr*> initExprs, SourceLocation rbraceloc)
- : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
- false, false),
- InitExprs(C, initExprs.size()),
- LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true) {
+ : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ InitExprs(C, initExprs.size()),
+ LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true)
+{
sawArrayRangeDesignator(false);
for (unsigned I = 0; I != initExprs.size(); ++I) {
if (initExprs[I]->isTypeDependent())
@@ -2028,6 +1999,7 @@ SourceLocation InitListExpr::getLocEnd() const {
}
/// getFunctionType - Return the underlying function type for this block.
+///
const FunctionProtoType *BlockExpr::getFunctionType() const {
// The block pointer is never sugared, but the function type might be.
return cast<BlockPointerType>(getType())
@@ -2037,15 +2009,14 @@ const FunctionProtoType *BlockExpr::getFunctionType() const {
SourceLocation BlockExpr::getCaretLocation() const {
return TheBlock->getCaretLocation();
}
-
const Stmt *BlockExpr::getBody() const {
return TheBlock->getBody();
}
-
Stmt *BlockExpr::getBody() {
return TheBlock->getBody();
}
+
//===----------------------------------------------------------------------===//
// Generic Expression Routines
//===----------------------------------------------------------------------===//
@@ -2240,7 +2211,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
return false;
case CXXTemporaryObjectExprClass:
- case CXXConstructExprClass:
+ case CXXConstructExprClass: {
if (const CXXRecordDecl *Type = getType()->getAsCXXRecordDecl()) {
if (Type->hasAttr<WarnUnusedAttr>()) {
WarnE = this;
@@ -2250,6 +2221,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
}
}
return false;
+ }
case ObjCMessageExprClass: {
const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(this);
@@ -2922,6 +2894,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
case MaterializeTemporaryExprClass:
return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
->isConstantInitializer(Ctx, false, Culprit);
+
case SubstNonTypeTemplateParmExprClass:
return cast<SubstNonTypeTemplateParmExpr>(this)->getReplacement()
->isConstantInitializer(Ctx, false, Culprit);
@@ -2943,17 +2916,16 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
}
namespace {
-
/// \brief Look for any side effects within a Stmt.
class SideEffectFinder : public ConstEvaluatedExprVisitor<SideEffectFinder> {
- using Inherited = ConstEvaluatedExprVisitor<SideEffectFinder>;
-
+ typedef ConstEvaluatedExprVisitor<SideEffectFinder> Inherited;
const bool IncludePossibleEffects;
- bool HasSideEffects = false;
+ bool HasSideEffects;
public:
explicit SideEffectFinder(const ASTContext &Context, bool IncludePossible)
- : Inherited(Context), IncludePossibleEffects(IncludePossible) {}
+ : Inherited(Context),
+ IncludePossibleEffects(IncludePossible), HasSideEffects(false) { }
bool hasSideEffects() const { return HasSideEffects; }
@@ -2963,8 +2935,7 @@ namespace {
HasSideEffects = true;
}
};
-
-} // namespace
+}
bool Expr::HasSideEffects(const ASTContext &Ctx,
bool IncludePossibleEffects) const {
@@ -3240,17 +3211,16 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
}
namespace {
-
/// \brief Look for a call to a non-trivial function within an expression.
- class NonTrivialCallFinder
- : public ConstEvaluatedExprVisitor<NonTrivialCallFinder> {
- using Inherited = ConstEvaluatedExprVisitor<NonTrivialCallFinder>;
+ class NonTrivialCallFinder : public ConstEvaluatedExprVisitor<NonTrivialCallFinder>
+ {
+ typedef ConstEvaluatedExprVisitor<NonTrivialCallFinder> Inherited;
- bool NonTrivial = false;
+ bool NonTrivial;
public:
explicit NonTrivialCallFinder(const ASTContext &Context)
- : Inherited(Context) {}
+ : Inherited(Context), NonTrivial(false) { }
bool hasNonTrivialCall() const { return NonTrivial; }
@@ -3286,8 +3256,7 @@ namespace {
NonTrivial = true;
}
};
-
-} // namespace
+}
bool Expr::hasNonTrivialCall(const ASTContext &Ctx) const {
NonTrivialCallFinder Finder(Ctx);
@@ -3313,6 +3282,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
return NPCK_ZeroExpression;
else
return NPCK_NotNull;
+
case NPC_ValueDependentIsNotNull:
return NPCK_NotNull;
}
@@ -3610,11 +3580,12 @@ void ExtVectorElementExpr::getEncodedElementAccess(
ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args,
QualType Type, SourceLocation BLoc,
SourceLocation RP)
- : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
- Type->isDependentType(), Type->isDependentType(),
- Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
- BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size()) {
+ : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
+ Type->isDependentType(), Type->isDependentType(),
+ Type->isInstantiationDependentType(),
+ Type->containsUnexpandedParameterPack()),
+ BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size())
+{
SubExprs = new (C) Stmt*[args.size()];
for (unsigned i = 0; i != args.size(); i++) {
if (args[i]->isTypeDependent())
@@ -3935,7 +3906,7 @@ PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &C, Expr *syntax,
ArrayRef<Expr*> semantics,
unsigned resultIndex) {
assert(syntax && "no syntactic expression!");
- assert(!semantics.empty() && "no semantic expressions!");
+ assert(semantics.size() && "no semantic expressions!");
QualType type;
ExprValueKind VK;
@@ -4009,9 +3980,10 @@ Stmt::const_child_range UnaryExprOrTypeTraitExpr::children() const {
AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args,
QualType t, AtomicOp op, SourceLocation RP)
- : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
- false, false, false, false),
- NumSubExprs(args.size()), BuiltinLoc(BLoc), RParenLoc(RP), Op(op) {
+ : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
+ false, false, false, false),
+ NumSubExprs(args.size()), BuiltinLoc(BLoc), RParenLoc(RP), Op(op)
+{
assert(args.size() == getNumSubExprs(op) && "wrong number of subexpressions");
for (unsigned i = 0; i != args.size(); i++) {
if (args[i]->isTypeDependent())
@@ -4114,7 +4086,7 @@ QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) {
if (OriginalTy->isAnyPointerType())
OriginalTy = OriginalTy->getPointeeType();
else {
- assert(OriginalTy->isArrayType());
+ assert (OriginalTy->isArrayType());
OriginalTy = OriginalTy->castAsArrayTypeUnsafe()->getElementType();
}
}
OpenPOWER on IntegriCloud