From 11a7ef8559fce524bf3946cd80d436976df9c8d1 Mon Sep 17 00:00:00 2001 From: Eugene Zelenko Date: Wed, 15 Nov 2017 22:00:04 +0000 Subject: [PATCH] [AST, Sema] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC). llvm-svn: 318341 --- clang/include/clang/AST/Expr.h | 583 +++++++++++++++++++++++++--------------- clang/lib/AST/Expr.cpp | 188 +++++++------ clang/lib/Sema/SemaChecking.cpp | 449 +++++++++++++++++++------------ 3 files changed, 753 insertions(+), 467 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index bef2339..509837d 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1,4 +1,4 @@ -//===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===// +//===- Expr.h - Classes for representing expressions ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,42 +18,56 @@ #include "clang/AST/ASTVector.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclAccessPair.h" +#include "clang/AST/DeclarationName.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/SyncScope.h" #include "clang/Basic/TypeTraits.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/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/AtomicOrdering.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TrailingObjects.h" +#include +#include +#include +#include +#include namespace clang { - class APValue; - class ASTContext; - class BlockDecl; - class CXXBaseSpecifier; - class CXXMemberCallExpr; - class CXXOperatorCallExpr; - class CastExpr; - class Decl; - class IdentifierInfo; - class MaterializeTemporaryExpr; - class NamedDecl; - class ObjCPropertyRefExpr; - class OpaqueValueExpr; - class ParmVarDecl; - class StringLiteral; - class TargetInfo; - class ValueDecl; + +class ASTContext; +class CastExpr; +class CXXBaseSpecifier; +class CXXRecordDecl; +class Decl; +class Expr; +class IdentifierInfo; +class ObjCPropertyRefExpr; +class SourceManager; +class StringLiteral; +class TargetInfo; /// \brief A simple array of base specifiers. -typedef SmallVector CXXCastPath; +using CXXCastPath = SmallVector; /// \brief An adjustment to be made to the temporary created when emitting a /// reference binding, which accesses a particular subobject of that temporary. @@ -82,18 +96,17 @@ struct SubobjectAdjustment { SubobjectAdjustment(const CastExpr *BasePath, const CXXRecordDecl *DerivedClass) - : Kind(DerivedToBaseAdjustment) { + : Kind(DerivedToBaseAdjustment) { DerivedToBase.BasePath = BasePath; DerivedToBase.DerivedClass = DerivedClass; } - SubobjectAdjustment(FieldDecl *Field) - : Kind(FieldAdjustment) { + SubobjectAdjustment(FieldDecl *Field) : Kind(FieldAdjustment) { this->Field = Field; } SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS) - : Kind(MemberPointerAdjustment) { + : Kind(MemberPointerAdjustment) { this->Ptr.MPT = MPT; this->Ptr.RHS = RHS; } @@ -109,8 +122,7 @@ class Expr : public Stmt { protected: Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) - : Stmt(SC) - { + : Stmt(SC) { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; ExprBits.InstantiationDependent = ID; @@ -122,10 +134,11 @@ protected: } /// \brief Construct an empty expression. - explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { } + explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) {} public: QualType getType() const { return TR; } + void setType(QualType t) { // In C++, the type of an expression is always adjusted so that it // will not have reference type (C++ [expr]p6). Use @@ -187,7 +200,6 @@ public: /// sizeof(sizeof(T() + T()); /// } /// \endcode - /// bool isInstantiationDependent() const { return ExprBits.InstantiationDependent; } @@ -263,6 +275,7 @@ public: LV_ClassTemporary, LV_ArrayTemporary }; + /// Reasons why an expression might not be an l-value. LValueClassification ClassifyLValue(ASTContext &Ctx) const; @@ -285,6 +298,7 @@ public: MLV_ClassTemporary, MLV_ArrayTemporary }; + /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, /// does not have an incomplete type, does not have a const-qualified type, /// and if it is a structure or union, does not have any member (including, @@ -316,6 +330,7 @@ public: CL_ObjCMessageRValue, // ObjC message is an rvalue CL_PRValue // A prvalue for any other reason, of any other type }; + /// \brief The results of modification testing. enum ModifiableType { CM_Untested, // testModifiable was false. @@ -338,17 +353,18 @@ public: unsigned short Modifiable; explicit Classification(Kinds k, ModifiableType m) - : Kind(k), Modifiable(m) - {} + : Kind(k), Modifiable(m) {} public: - Classification() {} + Classification() = default; Kinds getKind() const { return static_cast(Kind); } + ModifiableType getModifiable() const { assert(Modifiable != CM_Untested && "Did not test for modifiability."); return static_cast(Modifiable); } + bool isLValue() const { return Kind == CL_LValue; } bool isXValue() const { return Kind == CL_XValue; } bool isGLValue() const { return Kind <= CL_XValue; } @@ -362,6 +378,7 @@ public: } }; + /// \brief Classify - Classify this expression according to the C++11 /// expression taxonomy. /// @@ -428,7 +445,6 @@ private: Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const; public: - /// \brief Returns true if this expression is a gl-value that /// potentially refers to a bit-field. /// @@ -541,12 +557,12 @@ public: struct EvalStatus { /// \brief Whether the evaluated expression has side effects. /// For example, (f() && 0) can be folded, but it still has side effects. - bool HasSideEffects; + bool HasSideEffects = false; /// \brief Whether the evaluation hit undefined behavior. /// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior. /// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB. - bool HasUndefinedBehavior; + bool HasUndefinedBehavior = false; /// Diag - If this is non-null, it will be filled in with a stack of notes /// indicating why evaluation failed (or why it failed to produce a constant @@ -555,10 +571,9 @@ public: /// foldable. If the expression is foldable, but not a constant expression, /// the notes will describes why it isn't a constant expression. If the /// expression *is* a constant expression, no notes will be produced. - SmallVectorImpl *Diag; + SmallVectorImpl *Diag = nullptr; - EvalStatus() - : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {} + EvalStatus() = default; // hasSideEffects - Return true if the evaluated expression has // side effects. @@ -592,10 +607,15 @@ public: bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const; enum SideEffectsKind { - SE_NoSideEffects, ///< Strictly evaluate the expression. - SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not - ///< arbitrary unmodeled side effects. - SE_AllowSideEffects ///< Allow any unmodeled side effect. + /// Strictly evaluate the expression. + SE_NoSideEffects, + + /// Allow UB that we can give a value, but not arbitrary unmodeled side + /// effects. + SE_AllowUndefinedBehavior, + + /// Allow any unmodeled side effect. + SE_AllowSideEffects }; /// EvaluateAsInt - Return true if this is a constant which we can fold and @@ -807,12 +827,15 @@ public: const Expr *IgnoreImpCasts() const LLVM_READONLY { return const_cast(this)->IgnoreImpCasts(); } + const Expr *IgnoreParens() const LLVM_READONLY { return const_cast(this)->IgnoreParens(); } + const Expr *IgnoreParenCasts() const LLVM_READONLY { return const_cast(this)->IgnoreParenCasts(); } + /// Strip off casts, but keep parentheses. const Expr *IgnoreCasts() const LLVM_READONLY { return const_cast(this)->IgnoreCasts(); @@ -867,6 +890,7 @@ public: /// context. class OpaqueValueExpr : public Expr { friend class ASTStmtReader; + Expr *SourceExpr; SourceLocation Loc; @@ -891,7 +915,7 @@ public: static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr); explicit OpaqueValueExpr(EmptyShell Empty) - : Expr(OpaqueValueExprClass, Empty) { } + : Expr(OpaqueValueExprClass, Empty) {} /// \brief Retrieve the location of this expression. SourceLocation getLocation() const { return Loc; } @@ -899,9 +923,11 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return SourceExpr ? SourceExpr->getLocStart() : Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return SourceExpr ? SourceExpr->getLocEnd() : Loc; } + SourceLocation getExprLoc() const LLVM_READONLY { if (SourceExpr) return SourceExpr->getExprLoc(); return Loc; @@ -968,6 +994,18 @@ class DeclRefExpr final /// embedded in D. DeclarationNameLoc DNLoc; + DeclRefExpr(const ASTContext &Ctx, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, + ValueDecl *D, bool RefersToEnlosingVariableOrCapture, + const DeclarationNameInfo &NameInfo, + NamedDecl *FoundD, + const TemplateArgumentListInfo *TemplateArgs, + QualType T, ExprValueKind VK); + + /// \brief Construct an empty declaration reference expression. + explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} + size_t numTrailingObjects(OverloadToken) const { return hasQualifier() ? 1 : 0; } @@ -984,24 +1022,15 @@ class DeclRefExpr final /// this DRE. bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } - DeclRefExpr(const ASTContext &Ctx, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - ValueDecl *D, bool RefersToEnlosingVariableOrCapture, - const DeclarationNameInfo &NameInfo, - NamedDecl *FoundD, - const TemplateArgumentListInfo *TemplateArgs, - QualType T, ExprValueKind VK); - - /// \brief Construct an empty declaration reference expression. - explicit DeclRefExpr(EmptyShell Empty) - : Expr(DeclRefExprClass, Empty) { } - /// \brief Computes the type- and value-dependence flags for this /// declaration reference expression. void computeDependence(const ASTContext &C); public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, ExprValueKind VK, SourceLocation L, const DeclarationNameLoc &LocInfo = DeclarationNameLoc()) @@ -1074,7 +1103,6 @@ public: /// This Decl may be different from the ValueDecl actually referred to in the /// presence of using declarations, etc. It always returns non-NULL, and may /// simple return the ValueDecl when appropriate. - NamedDecl *getFoundDecl() { return hasFoundDecl() ? *getTrailingObjects() : D; } @@ -1153,6 +1181,7 @@ public: bool hadMultipleCandidates() const { return DeclRefExprBits.HadMultipleCandidates; } + /// \brief Sets the flag telling whether this expression refers to /// a function that was resolved from an overloaded set having size /// greater than 1. @@ -1178,10 +1207,6 @@ public: const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } - - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief [C99 6.4.2.2] - A predefined identifier such as __func__. @@ -1190,10 +1215,13 @@ public: enum IdentType { Func, Function, - LFunction, // Same as Function, but as wide string. + + // Same as Function, but as wide string. + LFunction, FuncDName, FuncSig, PrettyFunction, + /// \brief The same as PrettyFunction, except that the /// 'virtual' keyword is omitted for virtual member functions. PrettyFunctionNoVirtual @@ -1202,15 +1230,17 @@ public: private: SourceLocation Loc; IdentType Type; - Stmt *FnName; + Stmt *FnName = nullptr; public: + friend class ASTStmtReader; + PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT, StringLiteral *SL); /// \brief Construct an empty predefined expression. explicit PredefinedExpr(EmptyShell Empty) - : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {} + : Expr(PredefinedExprClass, Empty), Type(Func) {} IdentType getIdentType() const { return Type; } @@ -1234,11 +1264,10 @@ public: // Iterators child_range children() { return child_range(&FnName, &FnName + 1); } + const_child_range children() const { return const_child_range(&FnName, &FnName + 1); } - - friend class ASTStmtReader; }; /// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without @@ -1254,15 +1283,12 @@ class APNumericStorage { uint64_t VAL; ///< Used to store the <= 64 bits integer value. uint64_t *pVal; ///< Used to store the >64 bits integer value. }; - unsigned BitWidth; + unsigned BitWidth = 0; bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } - APNumericStorage(const APNumericStorage &) = delete; - void operator=(const APNumericStorage &) = delete; - protected: - APNumericStorage() : VAL(0), BitWidth(0) { } + APNumericStorage() : VAL(0) {} llvm::APInt getIntValue() const { unsigned NumWords = llvm::APInt::getNumWords(BitWidth); @@ -1271,12 +1297,18 @@ protected: else return llvm::APInt(BitWidth, VAL); } + void setIntValue(const ASTContext &C, const llvm::APInt &Val); + +public: + APNumericStorage(const APNumericStorage &) = delete; + APNumericStorage &operator=(const APNumericStorage &) = delete; }; class APIntStorage : private APNumericStorage { public: llvm::APInt getValue() const { return getIntValue(); } + void setValue(const ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); } @@ -1287,6 +1319,7 @@ public: llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const { return llvm::APFloat(Semantics, getIntValue()); } + void setValue(const ASTContext &C, const llvm::APFloat &Val) { setIntValue(C, Val.bitcastToAPInt()); } @@ -1297,7 +1330,7 @@ class IntegerLiteral : public Expr, public APIntStorage { /// \brief Construct an empty integer literal. explicit IntegerLiteral(EmptyShell Empty) - : Expr(IntegerLiteralClass, Empty) { } + : Expr(IntegerLiteralClass, Empty) {} public: // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, @@ -1311,6 +1344,7 @@ public: /// \param V - the value that the returned integer literal contains. static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l); + /// \brief Returns a new empty integer literal. static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty); @@ -1330,6 +1364,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -1348,6 +1383,7 @@ public: private: unsigned Value; SourceLocation Loc; + public: // type should be IntTy CharacterLiteral(unsigned value, CharacterKind kind, QualType type, @@ -1359,9 +1395,10 @@ public: } /// \brief Construct an empty character literal. - CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { } + CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) {} SourceLocation getLocation() const { return Loc; } + CharacterKind getKind() const { return static_cast(CharacterLiteralBits.Kind); } @@ -1383,6 +1420,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -1405,6 +1443,7 @@ public: llvm::APFloat getValue() const { return APFloatStorage::getValue(getSemantics()); } + void setValue(const ASTContext &C, const llvm::APFloat &Val) { assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics"); APFloatStorage::setValue(C, Val); @@ -1450,6 +1489,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -1459,9 +1499,9 @@ public: /// like "1.0i". We represent these as a wrapper around FloatingLiteral and /// IntegerLiteral classes. Instances of this class always have a Complex type /// whose element type matches the subexpression. -/// class ImaginaryLiteral : public Expr { Stmt *Val; + public: ImaginaryLiteral(Expr *val, QualType Ty) : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, @@ -1470,7 +1510,7 @@ public: /// \brief Build an empty imaginary literal. explicit ImaginaryLiteral(EmptyShell Empty) - : Expr(ImaginaryLiteralClass, Empty) { } + : Expr(ImaginaryLiteralClass, Empty) {} const Expr *getSubExpr() const { return cast(Val); } Expr *getSubExpr() { return cast(Val); } @@ -1485,6 +1525,7 @@ public: // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { return const_child_range(&Val, &Val + 1); } @@ -1531,11 +1572,11 @@ private: unsigned NumConcatenated; SourceLocation TokLocs[1]; - StringLiteral(QualType Ty) : - Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false, - false) {} + StringLiteral(QualType Ty) + : Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, + false, false) {} - static int mapCharByteWidth(TargetInfo const &target,StringKind k); + static int mapCharByteWidth(TargetInfo const &target, StringKind k); public: /// This is the "fully general" constructor that allows representation of @@ -1596,7 +1637,6 @@ public: StringKind getKind() const { return static_cast(Kind); } - bool isAscii() const { return Kind == Ascii; } bool isWide() const { return Kind == Wide; } bool isUTF8() const { return Kind == UTF8; } @@ -1638,11 +1678,13 @@ public: unsigned *StartToken = nullptr, unsigned *StartTokenByteOffset = nullptr) const; - typedef const SourceLocation *tokloc_iterator; + using tokloc_iterator = const SourceLocation *; + tokloc_iterator tokloc_begin() const { return TokLocs; } tokloc_iterator tokloc_end() const { return TokLocs + NumConcatenated; } SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; } + SourceLocation getLocEnd() const LLVM_READONLY { return TokLocs[NumConcatenated - 1]; } @@ -1655,6 +1697,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -1665,6 +1708,7 @@ public: class ParenExpr : public Expr { SourceLocation L, R; Stmt *Val; + public: ParenExpr(SourceLocation l, SourceLocation r, Expr *val) : Expr(ParenExprClass, val->getType(), @@ -1675,8 +1719,7 @@ public: L(l), R(r), Val(val) {} /// \brief Construct an empty parenthesized expression. - explicit ParenExpr(EmptyShell Empty) - : Expr(ParenExprClass, Empty) { } + explicit ParenExpr(EmptyShell Empty) : Expr(ParenExprClass, Empty) {} const Expr *getSubExpr() const { return cast(Val); } Expr *getSubExpr() { return cast(Val); } @@ -1699,6 +1742,7 @@ public: // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { return const_child_range(&Val, &Val + 1); } @@ -1713,17 +1757,16 @@ public: /// Real/Imag - These return the real/imag part of a complex operand. If /// applied to a non-complex value, the former returns its operand and the /// later returns zero in the type of the operand. -/// class UnaryOperator : public Expr { public: - typedef UnaryOperatorKind Opcode; + using Opcode = UnaryOperatorKind; private: unsigned Opc : 5; SourceLocation Loc; Stmt *Val; -public: +public: UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l) : Expr(UnaryOperatorClass, type, VK, OK, @@ -1736,7 +1779,7 @@ public: /// \brief Build an empty unary operator. explicit UnaryOperator(EmptyShell Empty) - : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { } + : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) {} Opcode getOpcode() const { return static_cast(Opc); } void setOpcode(Opcode O) { Opc = O; } @@ -1800,9 +1843,11 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return isPostfix() ? Val->getLocStart() : Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return isPostfix() ? Loc : Val->getLocEnd(); } + SourceLocation getExprLoc() const LLVM_READONLY { return Loc; } static bool classof(const Stmt *T) { @@ -1811,6 +1856,7 @@ public: // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { return const_child_range(&Val, &Val + 1); } @@ -1825,10 +1871,13 @@ public: enum Kind { /// \brief An index into an array. Array = 0x00, + /// \brief A field. Field = 0x01, + /// \brief A field in a dependent type, known only by its name. Identifier = 0x02, + /// \brief An implicit indirection through a C++ base class, when the /// field found is in a base class. Base = 0x03 @@ -1870,7 +1919,7 @@ public: /// \brief Create an offsetof node that refers into a C++ base class. explicit OffsetOfNode(const CXXBaseSpecifier *Base) - : Range(), Data(reinterpret_cast(Base) | OffsetOfNode::Base) {} + : Data(reinterpret_cast(Base) | OffsetOfNode::Base) {} /// \brief Determine what kind of offsetof node this is. Kind getKind() const { return static_cast(Data & Mask); } @@ -1922,15 +1971,17 @@ public: /// }; /// @endcode /// we can represent and evaluate the expression @c offsetof(struct T, s[2].d). - class OffsetOfExpr final : public Expr, private llvm::TrailingObjects { SourceLocation OperatorLoc, RParenLoc; + // Base type; - TypeSourceInfo *TSInfo; + TypeSourceInfo *TSInfo = nullptr; + // Number of sub-components (i.e. instances of OffsetOfNode). unsigned NumComps; + // Number of sub-expressions (i.e. array subscript expressions). unsigned NumExprs; @@ -1944,10 +1995,11 @@ class OffsetOfExpr final SourceLocation RParenLoc); explicit OffsetOfExpr(unsigned numComps, unsigned numExprs) - : Expr(OffsetOfExprClass, EmptyShell()), - TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {} + : Expr(OffsetOfExprClass, EmptyShell()), NumComps(numComps), + NumExprs(numExprs) {} public: + friend TrailingObjects; static OffsetOfExpr *Create(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, @@ -1968,6 +2020,7 @@ public: TypeSourceInfo *getTypeSourceInfo() const { return TSInfo; } + void setTypeSourceInfo(TypeSourceInfo *tsi) { TSInfo = tsi; } @@ -2017,12 +2070,12 @@ public: Stmt **begin = reinterpret_cast(getTrailingObjects()); return child_range(begin, begin + NumExprs); } + const_child_range children() const { Stmt *const *begin = reinterpret_cast(getTrailingObjects()); return const_child_range(begin, begin + NumExprs); } - friend TrailingObjects; }; /// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) @@ -2057,21 +2110,25 @@ public: /// \brief Construct an empty sizeof/alignof expression. explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty) - : Expr(UnaryExprOrTypeTraitExprClass, Empty) { } + : Expr(UnaryExprOrTypeTraitExprClass, Empty) {} UnaryExprOrTypeTrait getKind() const { return static_cast(UnaryExprOrTypeTraitExprBits.Kind); } + void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;} bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; } + QualType getArgumentType() const { return getArgumentTypeInfo()->getType(); } + TypeSourceInfo *getArgumentTypeInfo() const { assert(isArgumentType() && "calling getArgumentType() when arg is expr"); return Argument.Ty; } + Expr *getArgumentExpr() { assert(!isArgumentType() && "calling getArgumentExpr() when arg is type"); return static_cast(Argument.Ex); @@ -2120,8 +2177,10 @@ public: /// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting. class ArraySubscriptExpr : public Expr { enum { LHS, RHS, END_EXPR=2 }; + Stmt* SubExprs[END_EXPR]; SourceLocation RBracketLoc; + public: ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK, @@ -2140,7 +2199,7 @@ public: /// \brief Create an empty array subscript expression. explicit ArraySubscriptExpr(EmptyShell Shell) - : Expr(ArraySubscriptExprClass, Shell) { } + : Expr(ArraySubscriptExprClass, Shell) {} /// An array access can be written A[4] or 4[A] (both are equivalent). /// - getBase() and getIdx() always present the normalized view: A[4]. @@ -2178,6 +2237,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getLHS()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; } SourceLocation getRBracketLoc() const { return RBracketLoc; } @@ -2195,6 +2255,7 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } @@ -2208,8 +2269,9 @@ public: /// "str1 + str2" to resolve to a function call. class CallExpr : public Expr { enum { FN=0, PREARGS_START=1 }; - Stmt **SubExprs; - unsigned NumArgs; + + Stmt **SubExprs = nullptr; + unsigned NumArgs = 0; SourceLocation RParenLoc; void updateDependenciesFromArg(Expr *Arg); @@ -2262,7 +2324,6 @@ public: } /// getNumArgs - Return the number of actual arguments to this call. - /// unsigned getNumArgs() const { return NumArgs; } /// \brief Retrieve the call arguments. @@ -2295,10 +2356,10 @@ public: /// to null. void setNumArgs(const ASTContext& C, unsigned NumArgs); - typedef ExprIterator arg_iterator; - typedef ConstExprIterator const_arg_iterator; - typedef llvm::iterator_range arg_range; - typedef llvm::iterator_range arg_const_range; + using arg_iterator = ExprIterator; + using const_arg_iterator = ConstExprIterator; + using arg_range = llvm::iterator_range; + using arg_const_range = llvm::iterator_range; arg_range arguments() { return arg_range(arg_begin(), arg_end()); } arg_const_range arguments() const { @@ -2306,12 +2367,15 @@ public: } arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); } + arg_iterator arg_end() { return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs(); } + const_arg_iterator arg_begin() const { return SubExprs+PREARGS_START+getNumPreArgs(); } + const_arg_iterator arg_end() const { return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs(); } @@ -2436,6 +2500,10 @@ class MemberExpr final } public: + friend class ASTReader; + friend class ASTStmtWriter; + friend TrailingObjects; + MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, ValueDecl *memberdecl, const DeclarationNameInfo &NameInfo, QualType ty, ExprValueKind VK, ExprObjectKind OK) @@ -2459,7 +2527,7 @@ public: : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), base->isValueDependent(), base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l), + Base(base), MemberDecl(memberdecl), MemberLoc(l), OperatorLoc(operatorloc), IsArrow(isarrow), HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {} @@ -2602,6 +2670,7 @@ public: bool hadMultipleCandidates() const { return HadMultipleCandidates; } + /// \brief Sets the flag telling whether this expression refers to /// a method that was resolved from an overloaded set having size /// greater than 1. @@ -2623,17 +2692,13 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { return const_child_range(&Base, &Base + 1); } - - friend TrailingObjects; - friend class ASTReader; - friend class ASTStmtWriter; }; /// CompoundLiteralExpr - [C99 6.5.2.5] -/// class CompoundLiteralExpr : public Expr { /// LParenLoc - If non-null, this is the location of the left paren in a /// compound literal like "(int){4}". This can be null if this is a @@ -2645,6 +2710,7 @@ class CompoundLiteralExpr : public Expr { /// The int part of the pair stores whether this expr is file scope. llvm::PointerIntPair TInfoAndScope; Stmt *Init; + public: CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, QualType T, ExprValueKind VK, Expr *init, bool fileScope) @@ -2658,7 +2724,7 @@ public: /// \brief Construct an empty compound literal. explicit CompoundLiteralExpr(EmptyShell Empty) - : Expr(CompoundLiteralExprClass, Empty) { } + : Expr(CompoundLiteralExprClass, Empty) {} const Expr *getInitializer() const { return cast(Init); } Expr *getInitializer() { return cast(Init); } @@ -2673,6 +2739,7 @@ public: TypeSourceInfo *getTypeSourceInfo() const { return TInfoAndScope.getPointer(); } + void setTypeSourceInfo(TypeSourceInfo *tinfo) { TInfoAndScope.setPointer(tinfo); } @@ -2685,6 +2752,7 @@ public: return Init->getLocStart(); return LParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { // FIXME: Init should never be null. if (!Init) @@ -2698,6 +2766,7 @@ public: // Iterators child_range children() { return child_range(&Init, &Init+1); } + const_child_range children() const { return const_child_range(&Init, &Init + 1); } @@ -2716,6 +2785,7 @@ private: const CXXBaseSpecifier * const *path_buffer() const { return const_cast(this)->path_buffer(); } + CXXBaseSpecifier **path_buffer(); void setBasePathSize(unsigned basePathSize) { @@ -2750,7 +2820,7 @@ protected: /// \brief Construct an empty cast. CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize) - : Expr(SC, Empty) { + : Expr(SC, Empty) { setBasePathSize(BasePathSize); } @@ -2771,8 +2841,9 @@ public: return const_cast(this)->getSubExprAsWritten(); } - typedef CXXBaseSpecifier **path_iterator; - typedef const CXXBaseSpecifier * const *path_const_iterator; + using path_iterator = CXXBaseSpecifier **; + using path_const_iterator = const CXXBaseSpecifier * const *; + bool path_empty() const { return CastExprBits.BasePathSize == 0; } unsigned path_size() const { return CastExprBits.BasePathSize; } path_iterator path_begin() { return path_buffer(); } @@ -2826,19 +2897,21 @@ class ImplicitCastExpr final private: ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, unsigned BasePathLength, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { - } + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) {} /// \brief Construct an empty implicit cast. explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize) - : CastExpr(ImplicitCastExprClass, Shell, PathSize) { } + : CastExpr(ImplicitCastExprClass, Shell, PathSize) {} public: + friend class CastExpr; + friend TrailingObjects; + enum OnStack_t { OnStack }; + ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { - } + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {} static ImplicitCastExpr *Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, @@ -2851,6 +2924,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getSubExpr()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getSubExpr()->getLocEnd(); } @@ -2858,9 +2932,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitCastExprClass; } - - friend TrailingObjects; - friend class CastExpr; }; inline Expr *Expr::IgnoreImpCasts() { @@ -2895,11 +2966,11 @@ protected: ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK, CastKind kind, Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy) - : CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {} + : CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {} /// \brief Construct an empty explicit cast. ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) - : CastExpr(SC, Shell, PathSize) { } + : CastExpr(SC, Shell, PathSize) {} public: /// getTypeInfoAsWritten - Returns the type source info for the type @@ -2923,8 +2994,11 @@ public: class CStyleCastExpr final : public ExplicitCastExpr, private llvm::TrailingObjects { - SourceLocation LPLoc; // the location of the left paren - SourceLocation RPLoc; // the location of the right paren + // the location of the left paren + SourceLocation LPLoc; + + // the location of the right paren + SourceLocation RPLoc; CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy, @@ -2934,9 +3008,12 @@ class CStyleCastExpr final /// \brief Construct an empty C-style explicit cast. explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize) - : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { } + : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) {} public: + friend class CastExpr; + friend TrailingObjects; + static CStyleCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, @@ -2953,6 +3030,7 @@ public: void setRParenLoc(SourceLocation L) { RPLoc = L; } SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return getSubExpr()->getLocEnd(); } @@ -2960,9 +3038,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CStyleCastExprClass; } - - friend TrailingObjects; - friend class CastExpr; }; /// \brief A builtin binary operation expression such as "x + y" or "x <= y". @@ -2985,7 +3060,7 @@ public: /// be used to express the computation. class BinaryOperator : public Expr { public: - typedef BinaryOperatorKind Opcode; + using Opcode = BinaryOperatorKind; private: unsigned Opc : 6; @@ -2993,12 +3068,13 @@ private: // This is only meaningful for operations on floating point types and 0 // otherwise. unsigned FPFeatures : 2; + SourceLocation OpLoc; enum { LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; -public: +public: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptions FPFeatures) @@ -3018,7 +3094,7 @@ public: /// \brief Construct an empty binary operator. explicit BinaryOperator(EmptyShell Empty) - : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { } + : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) {} SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; } SourceLocation getOperatorLoc() const { return OpLoc; } @@ -3035,6 +3111,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getLHS()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getRHS()->getLocEnd(); } @@ -3117,6 +3194,7 @@ public: bool isCompoundAssignmentOp() const { return isCompoundAssignmentOp(getOpcode()); } + static Opcode getOpForCompoundAssignment(Opcode Opc) { assert(isCompoundAssignmentOp(Opc)); if (Opc >= BO_AndAssign) @@ -3147,6 +3225,7 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } @@ -3180,7 +3259,7 @@ protected: } BinaryOperator(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty), Opc(BO_MulAssign) { } + : Expr(SC, Empty), Opc(BO_MulAssign) {} }; /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep @@ -3192,6 +3271,7 @@ protected: class CompoundAssignOperator : public BinaryOperator { QualType ComputationLHSType; QualType ComputationResultType; + public: CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, ExprValueKind VK, ExprObjectKind OK, @@ -3207,7 +3287,7 @@ public: /// \brief Build an empty compound assignment operator expression. explicit CompoundAssignOperator(EmptyShell Empty) - : BinaryOperator(CompoundAssignOperatorClass, Empty) { } + : BinaryOperator(CompoundAssignOperatorClass, Empty) {} // The two computation types are the type the LHS is converted // to for the computation and the type of the result; the two are @@ -3226,9 +3306,10 @@ public: /// AbstractConditionalOperator - An abstract base class for /// ConditionalOperator and BinaryConditionalOperator. class AbstractConditionalOperator : public Expr { - SourceLocation QuestionLoc, ColonLoc; friend class ASTStmtReader; + SourceLocation QuestionLoc, ColonLoc; + protected: AbstractConditionalOperator(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, @@ -3240,7 +3321,7 @@ protected: QuestionLoc(qloc), ColonLoc(cloc) {} AbstractConditionalOperator(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty) { } + : Expr(SC, Empty) {} public: // getCond - Return the expression representing the condition for @@ -3268,10 +3349,13 @@ public: /// ConditionalOperator - The ?: ternary operator. The GNU "missing /// middle" extension is a BinaryConditionalOperator. class ConditionalOperator : public AbstractConditionalOperator { + friend class ASTStmtReader; + enum { COND, LHS, RHS, END_EXPR }; - Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. - friend class ASTStmtReader; + // Left/Middle/Right hand sides. + Stmt* SubExprs[END_EXPR]; + public: ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, SourceLocation CLoc, Expr *rhs, @@ -3297,7 +3381,7 @@ public: /// \brief Build an empty conditional operator. explicit ConditionalOperator(EmptyShell Empty) - : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { } + : AbstractConditionalOperator(ConditionalOperatorClass, Empty) {} // getCond - Return the expression representing the condition for // the ?: operator. @@ -3318,6 +3402,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getCond()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getRHS()->getLocEnd(); } @@ -3330,6 +3415,7 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } @@ -3341,6 +3427,8 @@ public: /// This is a different expression kind on the assumption that almost /// every client ends up needing to know that these are different. class BinaryConditionalOperator : public AbstractConditionalOperator { + friend class ASTStmtReader; + enum { COMMON, COND, LHS, RHS, NUM_SUBEXPRS }; /// - the common condition/left-hand-side expression, which will be @@ -3351,7 +3439,6 @@ class BinaryConditionalOperator : public AbstractConditionalOperator { Stmt *SubExprs[NUM_SUBEXPRS]; OpaqueValueExpr *OpaqueValue; - friend class ASTStmtReader; public: BinaryConditionalOperator(Expr *common, OpaqueValueExpr *opaqueValue, Expr *cond, Expr *lhs, Expr *rhs, @@ -3375,7 +3462,7 @@ public: /// \brief Build an empty conditional operator. explicit BinaryConditionalOperator(EmptyShell Empty) - : AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) { } + : AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) {} /// \brief getCommon - Return the common expression, written to the /// left of the condition. The opaque value will be bound to the @@ -3406,6 +3493,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getCommon()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getFalseExpr()->getLocEnd(); } @@ -3418,6 +3506,7 @@ public: child_range children() { return child_range(SubExprs, SubExprs + NUM_SUBEXPRS); } + const_child_range children() const { return const_child_range(SubExprs, SubExprs + NUM_SUBEXPRS); } @@ -3445,6 +3534,7 @@ inline Expr *AbstractConditionalOperator::getFalseExpr() const { class AddrLabelExpr : public Expr { SourceLocation AmpAmpLoc, LabelLoc; LabelDecl *Label; + public: AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L, QualType t) @@ -3453,8 +3543,7 @@ public: AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} /// \brief Build an empty address of a label expression. - explicit AddrLabelExpr(EmptyShell Empty) - : Expr(AddrLabelExprClass, Empty) { } + explicit AddrLabelExpr(EmptyShell Empty) : Expr(AddrLabelExprClass, Empty) {} SourceLocation getAmpAmpLoc() const { return AmpAmpLoc; } void setAmpAmpLoc(SourceLocation L) { AmpAmpLoc = L; } @@ -3475,6 +3564,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -3489,18 +3579,19 @@ public: class StmtExpr : public Expr { Stmt *SubStmt; SourceLocation LParenLoc, RParenLoc; + public: // FIXME: Does type-dependence need to be computed differently? // FIXME: Do we need to compute instantiation instantiation-dependence for // statements? (ugh!) StmtExpr(CompoundStmt *substmt, QualType T, - SourceLocation lp, SourceLocation rp) : - Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, - T->isDependentType(), false, false, false), - SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } + SourceLocation lp, SourceLocation rp) + : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, + T->isDependentType(), false, false, false), + SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) {} /// \brief Build an empty statement expression. - explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { } + explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) {} CompoundStmt *getSubStmt() { return cast(SubStmt); } const CompoundStmt *getSubStmt() const { return cast(SubStmt); } @@ -3520,6 +3611,7 @@ public: // Iterators child_range children() { return child_range(&SubStmt, &SubStmt+1); } + const_child_range children() const { return const_child_range(&SubStmt, &SubStmt + 1); } @@ -3538,7 +3630,7 @@ class ShuffleVectorExpr : public Expr { // function. The first two are vectors, and the rest are constant // indices. The number of values in this list is always // 2+the number of indices in the vector type. - Stmt **SubExprs; + Stmt **SubExprs = nullptr; unsigned NumExprs; public: @@ -3547,7 +3639,7 @@ public: /// \brief Build an empty vector-shuffle expression. explicit ShuffleVectorExpr(EmptyShell Empty) - : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { } + : Expr(ShuffleVectorExprClass, Empty) {} SourceLocation getBuiltinLoc() const { return BuiltinLoc; } void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; } @@ -3591,6 +3683,7 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+NumExprs); } + const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs); } @@ -3601,12 +3694,13 @@ public: /// vector type of the same arity. class ConvertVectorExpr : public Expr { private: + friend class ASTReader; + friend class ASTStmtReader; + Stmt *SrcExpr; TypeSourceInfo *TInfo; SourceLocation BuiltinLoc, RParenLoc; - friend class ASTReader; - friend class ASTStmtReader; explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {} public: @@ -3648,6 +3742,7 @@ public: // Iterators child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } + const_child_range children() const { return const_child_range(&SrcExpr, &SrcExpr + 1); } @@ -3664,9 +3759,11 @@ public: /// sub-expression. class ChooseExpr : public Expr { enum { COND, LHS, RHS, END_EXPR }; + Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. SourceLocation BuiltinLoc, RParenLoc; bool CondIsTrue; + public: ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK, @@ -3686,7 +3783,7 @@ public: } /// \brief Build an empty __builtin_choose_expr. - explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { } + explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) {} /// isConditionTrue - Return whether the condition is true (i.e. not /// equal to zero). @@ -3731,6 +3828,7 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } @@ -3748,12 +3846,12 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false, - false), - TokenLoc(Loc) { } + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false, + false), + TokenLoc(Loc) {} /// \brief Build an empty GNU __null expression. - explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { } + explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) {} /// getTokenLocation - The location of the __null token. SourceLocation getTokenLocation() const { return TokenLoc; } @@ -3770,6 +3868,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -3777,9 +3876,10 @@ public: /// Represents a call to the builtin function \c __builtin_va_arg. class VAArgExpr : public Expr { - Stmt *Val; + Stmt *Val = nullptr; llvm::PointerIntPair TInfo; SourceLocation BuiltinLoc, RParenLoc; + public: VAArgExpr(SourceLocation BLoc, Expr *e, TypeSourceInfo *TInfo, SourceLocation RPLoc, QualType t, bool IsMS) @@ -3792,7 +3892,7 @@ public: /// Create an empty __builtin_va_arg expression. explicit VAArgExpr(EmptyShell Empty) - : Expr(VAArgExprClass, Empty), Val(nullptr), TInfo(nullptr, false) {} + : Expr(VAArgExprClass, Empty), TInfo(nullptr, false) {} const Expr *getSubExpr() const { return cast(Val); } Expr *getSubExpr() { return cast(Val); } @@ -3820,6 +3920,7 @@ public: // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { return const_child_range(&Val, &Val + 1); } @@ -3872,7 +3973,8 @@ public: /// semantic initializer list also serves as its syntactic form. class InitListExpr : public Expr { // FIXME: Eliminate this vector in favor of ASTContext allocation - typedef ASTVector InitExprsTy; + using InitExprsTy = ASTVector; + InitExprsTy InitExprs; SourceLocation LBraceLoc, RBraceLoc; @@ -3893,12 +3995,15 @@ class InitListExpr : public Expr { llvm::PointerUnion ArrayFillerOrUnionFieldInit; public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef initExprs, SourceLocation rbraceloc); /// \brief Build an empty initializer list. explicit InitListExpr(EmptyShell Empty) - : Expr(InitListExprClass, Empty), AltForm(nullptr, true) { } + : Expr(InitListExprClass, Empty), AltForm(nullptr, true) {} unsigned getNumInits() const { return InitExprs.size(); } @@ -4021,12 +4126,15 @@ public: void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; } bool isSemanticForm() const { return AltForm.getInt(); } + InitListExpr *getSemanticForm() const { return isSemanticForm() ? nullptr : AltForm.getPointer(); } + bool isSyntacticForm() const { return !AltForm.getInt() || !AltForm.getPointer(); } + InitListExpr *getSyntacticForm() const { return isSemanticForm() ? AltForm.getPointer() : nullptr; } @@ -4041,6 +4149,7 @@ public: bool hadArrayRangeDesignator() const { return InitListExprBits.HadArrayRangeDesignator != 0; } + void sawArrayRangeDesignator(bool ARD = true) { InitListExprBits.HadArrayRangeDesignator = ARD; } @@ -4066,10 +4175,10 @@ public: return const_child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size()); } - typedef InitExprsTy::iterator iterator; - typedef InitExprsTy::const_iterator const_iterator; - typedef InitExprsTy::reverse_iterator reverse_iterator; - typedef InitExprsTy::const_reverse_iterator const_reverse_iterator; + using iterator = InitExprsTy::iterator; + using const_iterator = InitExprsTy::const_iterator; + using reverse_iterator = InitExprsTy::reverse_iterator; + using const_reverse_iterator = InitExprsTy::const_reverse_iterator; iterator begin() { return InitExprs.begin(); } const_iterator begin() const { return InitExprs.begin(); } @@ -4079,9 +4188,6 @@ public: const_reverse_iterator rbegin() const { return InitExprs.rbegin(); } reverse_iterator rend() { return InitExprs.rend(); } const_reverse_iterator rend() const { return InitExprs.rend(); } - - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// @brief Represents a C99 designated initializer expression. @@ -4130,7 +4236,7 @@ private: /// \brief The designators in this designated initialization /// expression. - Designator *Designators; + Designator *Designators = nullptr; DesignatedInitExpr(const ASTContext &C, QualType Ty, llvm::ArrayRef Designators, @@ -4138,10 +4244,12 @@ private: ArrayRef IndexExprs, Expr *Init); explicit DesignatedInitExpr(unsigned NumSubExprs) - : Expr(DesignatedInitExprClass, EmptyShell()), - NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { } + : Expr(DesignatedInitExprClass, EmptyShell()), + NumDesignators(0), NumSubExprs(NumSubExprs) {} public: + friend TrailingObjects; + /// A field designator, e.g., ".x". struct FieldDesignator { /// Refers to the field that is being initialized. The low bit @@ -4164,11 +4272,14 @@ public: /// Location of the first index expression within the designated /// initializer expression's list of subexpressions. unsigned Index; + /// The location of the '[' starting the array range designator. unsigned LBracketLoc; + /// The location of the ellipsis separating the start and end /// indices. Only valid for GNU array-range designators. unsigned EllipsisLoc; + /// The location of the ']' terminating the array range designator. unsigned RBracketLoc; }; @@ -4180,6 +4291,8 @@ public: /// keep us from reusing it. Try harder, later, to rectify these /// differences. class Designator { + friend class DesignatedInitExpr; + /// @brief The kind of designator this describes. enum { FieldDesignator, @@ -4190,13 +4303,13 @@ public: union { /// A field designator, e.g., ".x". struct FieldDesignator Field; + /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]". struct ArrayOrRangeDesignator ArrayOrRange; }; - friend class DesignatedInitExpr; public: - Designator() {} + Designator() = default; /// @brief Initializes a field designator. Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc, @@ -4286,9 +4399,11 @@ public: else return getLBracketLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc(); } + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocStart(), getLocEnd()); } @@ -4381,12 +4496,11 @@ public: Stmt **begin = getTrailingObjects(); return child_range(begin, begin + NumSubExprs); } + const_child_range children() const { Stmt * const *begin = getTrailingObjects(); return const_child_range(begin, begin + NumSubExprs); } - - friend TrailingObjects; }; /// \brief Represents a place-holder for an object not to be initialized by @@ -4401,11 +4515,10 @@ public: class NoInitExpr : public Expr { public: explicit NoInitExpr(QualType ty) - : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, ty->isInstantiationDependentType(), false) { } + : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary, + false, false, ty->isInstantiationDependentType(), false) {} - explicit NoInitExpr(EmptyShell Empty) - : Expr(NoInitExprClass, Empty) { } + explicit NoInitExpr(EmptyShell Empty) : Expr(NoInitExprClass, Empty) {} static bool classof(const Stmt *T) { return T->getStmtClass() == NoInitExprClass; @@ -4418,6 +4531,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -4444,7 +4558,7 @@ public: Expr *baseExprs, SourceLocation rBraceLoc); explicit DesignatedInitUpdateExpr(EmptyShell Empty) - : Expr(DesignatedInitUpdateExprClass, Empty) { } + : Expr(DesignatedInitUpdateExprClass, Empty) {} SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; @@ -4459,6 +4573,7 @@ public: InitListExpr *getUpdater() const { return cast(BaseAndUpdaterExprs[1]); } + void setUpdater(Expr *Updater) { BaseAndUpdaterExprs[1] = Updater; } // Iterators @@ -4466,6 +4581,7 @@ public: child_range children() { return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2); } + const_child_range children() const { return const_child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2); @@ -4495,6 +4611,10 @@ class ArrayInitLoopExpr : public Expr { : Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {} public: + friend class ASTReader; + friend class ASTStmtReader; + friend class ASTStmtWriter; + explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit) : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false, CommonInit->isValueDependent() || ElementInit->isValueDependent(), @@ -4524,6 +4644,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getCommonExpr()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getCommonExpr()->getLocEnd(); } @@ -4531,13 +4652,10 @@ public: child_range children() { return child_range(SubExprs, SubExprs + 2); } + const_child_range children() const { return const_child_range(SubExprs, SubExprs + 2); } - - friend class ASTReader; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief Represents the index of the current element of an array being @@ -4548,6 +4666,9 @@ class ArrayInitIndexExpr : public Expr { : Expr(ArrayInitIndexExprClass, Empty) {} public: + friend class ASTReader; + friend class ASTStmtReader; + explicit ArrayInitIndexExpr(QualType T) : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary, false, false, false, false) {} @@ -4562,12 +4683,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } - - friend class ASTReader; - friend class ASTStmtReader; }; /// \brief Represents an implicitly-generated value initialization of @@ -4581,12 +4700,12 @@ public: class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) - : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, ty->isInstantiationDependentType(), false) { } + : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, + false, false, ty->isInstantiationDependentType(), false) {} /// \brief Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) - : Expr(ImplicitValueInitExprClass, Empty) { } + : Expr(ImplicitValueInitExprClass, Empty) {} static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitValueInitExprClass; @@ -4599,6 +4718,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -4610,11 +4730,14 @@ class ParenListExpr : public Expr { SourceLocation LParenLoc, RParenLoc; public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + ParenListExpr(const ASTContext& C, SourceLocation lparenloc, ArrayRef exprs, SourceLocation rparenloc); /// \brief Build an empty paren list. - explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } + explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) {} unsigned getNumExprs() const { return NumExprs; } @@ -4648,12 +4771,10 @@ public: child_range children() { return child_range(&Exprs[0], &Exprs[0]+NumExprs); } + const_child_range children() const { return const_child_range(&Exprs[0], &Exprs[0] + NumExprs); } - - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief Represents a C11 generic selection. @@ -4684,12 +4805,15 @@ public: /// Result-dependent generic associations are both type- and value-dependent. class GenericSelectionExpr : public Expr { enum { CONTROLLING, END_EXPR }; + TypeSourceInfo **AssocTypes; Stmt **SubExprs; unsigned NumAssocs, ResultIndex; SourceLocation GenericLoc, DefaultLoc, RParenLoc; public: + friend class ASTStmtReader; + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef AssocTypes, @@ -4707,7 +4831,7 @@ public: bool ContainsUnexpandedParameterPack); explicit GenericSelectionExpr(EmptyShell Empty) - : Expr(GenericSelectionExprClass, Empty) { } + : Expr(GenericSelectionExprClass, Empty) {} unsigned getNumAssocs() const { return NumAssocs; } @@ -4718,17 +4842,22 @@ public: const Expr *getAssocExpr(unsigned i) const { return cast(SubExprs[END_EXPR+i]); } + Expr *getAssocExpr(unsigned i) { return cast(SubExprs[END_EXPR+i]); } + ArrayRef getAssocExprs() const { return NumAssocs ? llvm::makeArrayRef( &reinterpret_cast(SubExprs)[END_EXPR], NumAssocs) : None; } + const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const { return AssocTypes[i]; } + TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; } + ArrayRef getAssocTypeSourceInfos() const { return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None; } @@ -4743,6 +4872,7 @@ public: const Expr *getControllingExpr() const { return cast(SubExprs[CONTROLLING]); } + Expr *getControllingExpr() { return cast(SubExprs[CONTROLLING]); } /// Whether this generic selection is result-dependent. @@ -4771,10 +4901,10 @@ public: child_range children() { return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs); } + const_child_range children() const { return const_child_range(SubExprs, SubExprs + END_EXPR + NumAssocs); } - friend class ASTStmtReader; }; //===----------------------------------------------------------------------===// @@ -4787,11 +4917,11 @@ public: /// /// Note that the base may have either vector or pointer to vector type, just /// like a struct field reference. -/// class ExtVectorElementExpr : public Expr { Stmt *Base; IdentifierInfo *Accessor; SourceLocation AccessorLoc; + public: ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base, IdentifierInfo &accessor, SourceLocation loc) @@ -4804,7 +4934,7 @@ public: /// \brief Build an empty vector element expression. explicit ExtVectorElementExpr(EmptyShell Empty) - : Expr(ExtVectorElementExprClass, Empty) { } + : Expr(ExtVectorElementExprClass, Empty) {} const Expr *getBase() const { return cast(Base); } Expr *getBase() { return cast(Base); } @@ -4830,6 +4960,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getBase()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; } /// isArrow - Return true if the base expression is a pointer to vector, @@ -4842,6 +4973,7 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { return const_child_range(&Base, &Base + 1); } @@ -4852,6 +4984,7 @@ public: class BlockExpr : public Expr { protected: BlockDecl *TheBlock; + public: BlockExpr(BlockDecl *BD, QualType ty) : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, @@ -4861,7 +4994,7 @@ public: TheBlock(BD) {} /// \brief Build an empty block expression. - explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { } + explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) {} const BlockDecl *getBlockDecl() const { return TheBlock; } BlockDecl *getBlockDecl() { return TheBlock; } @@ -4886,6 +5019,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -4896,11 +5030,12 @@ public: /// type of the same size. class AsTypeExpr : public Expr { private: + friend class ASTReader; + friend class ASTStmtReader; + Stmt *SrcExpr; SourceLocation BuiltinLoc, RParenLoc; - friend class ASTReader; - friend class ASTStmtReader; explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {} public: @@ -4934,6 +5069,7 @@ public: // Iterators child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } + const_child_range children() const { return const_child_range(&SrcExpr, &SrcExpr + 1); } @@ -4981,22 +5117,26 @@ class PseudoObjectExpr final // in to Create, which is an index within the semantic forms. // Note also that ASTStmtWriter assumes this encoding. - Expr **getSubExprsBuffer() { return getTrailingObjects(); } - const Expr * const *getSubExprsBuffer() const { - return getTrailingObjects(); - } - PseudoObjectExpr(QualType type, ExprValueKind VK, Expr *syntactic, ArrayRef semantic, unsigned resultIndex); PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs); + Expr **getSubExprsBuffer() { return getTrailingObjects(); } + + const Expr * const *getSubExprsBuffer() const { + return getTrailingObjects(); + } + unsigned getNumSubExprs() const { return PseudoObjectExprBits.NumSubExprs; } public: + friend class ASTStmtReader; + friend TrailingObjects; + /// NoResult - A value for the result index indicating that there is /// no semantic result. enum : unsigned { NoResult = ~0U }; @@ -5033,17 +5173,21 @@ public: unsigned getNumSemanticExprs() const { return getNumSubExprs() - 1; } - typedef Expr * const *semantics_iterator; - typedef const Expr * const *const_semantics_iterator; + using semantics_iterator = Expr * const *; + using const_semantics_iterator = const Expr * const *; + semantics_iterator semantics_begin() { return getSubExprsBuffer() + 1; } + const_semantics_iterator semantics_begin() const { return getSubExprsBuffer() + 1; } + semantics_iterator semantics_end() { return getSubExprsBuffer() + getNumSubExprs(); } + const_semantics_iterator semantics_end() const { return getSubExprsBuffer() + getNumSubExprs(); } @@ -5051,6 +5195,7 @@ public: llvm::iterator_range semantics() { return llvm::make_range(semantics_begin(), semantics_end()); } + llvm::iterator_range semantics() const { return llvm::make_range(semantics_begin(), semantics_end()); } @@ -5059,6 +5204,7 @@ public: assert(index + 1 < getNumSubExprs()); return getSubExprsBuffer()[index + 1]; } + const Expr *getSemanticExpr(unsigned index) const { return const_cast(this)->getSemanticExpr(index); } @@ -5070,6 +5216,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getSyntacticForm()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getSyntacticForm()->getLocEnd(); } @@ -5080,6 +5227,7 @@ public: return child_range(cast_away_const(CCR.begin()), cast_away_const(CCR.end())); } + const_child_range children() const { Stmt *const *cs = const_cast( reinterpret_cast(getSubExprsBuffer())); @@ -5089,9 +5237,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == PseudoObjectExprClass; } - - friend TrailingObjects; - friend class ASTStmtReader; }; /// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, @@ -5112,16 +5257,18 @@ public: }; private: + friend class ASTStmtReader; + /// \brief Location of sub-expressions. /// The location of Scope sub-expression is NumSubExprs - 1, which is /// not fixed, therefore is not defined in enum. enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR }; + Stmt *SubExprs[END_EXPR + 1]; unsigned NumSubExprs; SourceLocation BuiltinLoc, RParenLoc; AtomicOp Op; - friend class ASTStmtReader; public: AtomicExpr(SourceLocation BLoc, ArrayRef args, QualType t, AtomicOp op, SourceLocation RP); @@ -5131,44 +5278,52 @@ public: static unsigned getNumSubExprs(AtomicOp Op); /// \brief Build an empty AtomicExpr. - explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { } + explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) {} Expr *getPtr() const { return cast(SubExprs[PTR]); } + Expr *getOrder() const { return cast(SubExprs[ORDER]); } + Expr *getScope() const { assert(getScopeModel() && "No scope"); return cast(SubExprs[NumSubExprs - 1]); } + Expr *getVal1() const { if (Op == AO__c11_atomic_init || Op == AO__opencl_atomic_init) return cast(SubExprs[ORDER]); assert(NumSubExprs > VAL1); return cast(SubExprs[VAL1]); } + Expr *getOrderFail() const { assert(NumSubExprs > ORDER_FAIL); return cast(SubExprs[ORDER_FAIL]); } + Expr *getVal2() const { if (Op == AO__atomic_exchange) return cast(SubExprs[ORDER_FAIL]); assert(NumSubExprs > VAL2); return cast(SubExprs[VAL2]); } + Expr *getWeak() const { assert(NumSubExprs > WEAK); return cast(SubExprs[WEAK]); } + QualType getValueType() const; AtomicOp getOp() const { return Op; } unsigned getNumSubExprs() const { return NumSubExprs; } Expr **getSubExprs() { return reinterpret_cast(SubExprs); } + const Expr * const *getSubExprs() const { return reinterpret_cast(SubExprs); } @@ -5205,6 +5360,7 @@ public: child_range children() { return child_range(SubExprs, SubExprs+NumSubExprs); } + const_child_range children() const { return const_child_range(SubExprs, SubExprs + NumSubExprs); } @@ -5244,6 +5400,7 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } @@ -5254,8 +5411,8 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == TypoExprClass; } - }; -} // end namespace clang + +} // namespace clang #endif // LLVM_CLANG_AST_EXPR_H diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6cda82b..d315768 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,28 +11,62 @@ // //===----------------------------------------------------------------------===// +#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/RecordLayout.h" -#include "clang/AST/StmtVisitor.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/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/Sema/SemaDiagnostic.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 "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include +#include +#include +#include #include +#include +#include +#include + using namespace clang; const Expr *Expr::getBestDynamicClassTypeExpr() const { @@ -193,24 +227,23 @@ 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 - SourceLocation getExprLocImpl(const Expr *expr, - SourceLocation (T::*v)() const) { - return static_cast(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 - SourceLocation getExprLocImpl(const Expr *expr, - SourceLocation (Expr::*v)() const) { - return static_cast(expr)->getLocStart(); - } +/// This implementation is used when a class provides a custom +/// implementation of getExprLoc. +template +static SourceLocation getExprLocImpl(const Expr *expr, + SourceLocation (T::*v)() const) { + return static_cast(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 +static SourceLocation getExprLocImpl(const Expr *expr, + SourceLocation (Expr::*v)() const) { + return static_cast(expr)->getLocStart(); } SourceLocation Expr::getExprLoc() const { @@ -452,6 +485,7 @@ SourceLocation DeclRefExpr::getLocStart() const { return getQualifierLoc().getBeginLoc(); return getNameInfo().getLocStart(); } + SourceLocation DeclRefExpr::getLocEnd() const { if (hasExplicitTemplateArgs()) return getRAngleLoc(); @@ -606,8 +640,9 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { POut << " &&"; } - typedef SmallVector SpecsTy; + using SpecsTy = SmallVector; SpecsTy Specs; + const DeclContext *Ctx = FD->getDeclContext(); while (Ctx && isa(Ctx)) { const ClassTemplateSpecializationDecl *Spec @@ -765,7 +800,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; } @@ -1035,7 +1070,6 @@ 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, @@ -1054,7 +1088,7 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM, StringOffset = *StartTokenByteOffset; ByteNo -= StringOffset; } - while (1) { + while (true) { assert(TokNo < getNumConcatenated() && "Invalid byte number!"); SourceLocation StrTokLoc = getStrTokenLoc(TokNo); @@ -1109,8 +1143,6 @@ 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) { @@ -1152,7 +1184,6 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) { } } - //===----------------------------------------------------------------------===// // Postfix Operators. //===----------------------------------------------------------------------===// @@ -1164,7 +1195,6 @@ 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; @@ -1188,15 +1218,15 @@ CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef args, QualType t, ExprValueKind VK, SourceLocation rparenloc) - : CallExpr(C, CallExprClass, fn, ArrayRef(), args, t, VK, rparenloc) { -} + : CallExpr(C, CallExprClass, fn, ArrayRef(), 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), SubExprs(nullptr), NumArgs(0) { + : Expr(SC, Empty) { // FIXME: Why do we allocate this? SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs](); CallExprBits.NumPreArgs = NumPreArgs; @@ -1332,6 +1362,7 @@ SourceLocation CallExpr::getLocStart() const { begin = getArg(0)->getLocStart(); return begin; } + SourceLocation CallExpr::getLocEnd() const { if (isa(this)) return cast(this)->getLocEnd(); @@ -1393,7 +1424,7 @@ IdentifierInfo *OffsetOfNode::getFieldName() const { if (getKind() == Field) return getField()->getIdentifier(); - return reinterpret_cast (Data & ~(uintptr_t)Mask); + return reinterpret_cast(Data & ~(uintptr_t)Mask); } UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr( @@ -1440,7 +1471,6 @@ 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()); @@ -1508,6 +1538,7 @@ SourceLocation MemberExpr::getLocStart() const { return BaseStartLoc; return MemberLoc; } + SourceLocation MemberExpr::getLocEnd() const { SourceLocation EndLoc = getMemberNameInfo().getEndLoc(); if (hasExplicitTemplateArgs()) @@ -1641,19 +1672,17 @@ const char *CastExpr::getCastKindName() const { llvm_unreachable("Unhandled cast kind!"); } -namespace { - Expr *skipImplicitTemporary(Expr *expr) { - // Skip through reference binding to temporary. - if (MaterializeTemporaryExpr *Materialize - = dyn_cast(expr)) - expr = Materialize->GetTemporaryExpr(); +static Expr *skipImplicitTemporary(Expr *expr) { + // Skip through reference binding to temporary. + if (MaterializeTemporaryExpr *Materialize + = dyn_cast(expr)) + expr = Materialize->GetTemporaryExpr(); - // Skip any temporary bindings; they're implicit. - if (CXXBindTemporaryExpr *Binder = dyn_cast(expr)) - expr = Binder->getSubExpr(); + // Skip any temporary bindings; they're implicit. + if (CXXBindTemporaryExpr *Binder = dyn_cast(expr)) + expr = Binder->getSubExpr(); - return expr; - } + return expr; } Expr *CastExpr::getSubExprAsWritten() { @@ -1861,13 +1890,13 @@ bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx, return true; } + InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef 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()) @@ -1999,7 +2028,6 @@ 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(getType()) @@ -2009,14 +2037,15 @@ 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 //===----------------------------------------------------------------------===// @@ -2211,7 +2240,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()) { WarnE = this; @@ -2221,7 +2250,6 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, } } return false; - } case ObjCMessageExprClass: { const ObjCMessageExpr *ME = cast(this); @@ -2894,7 +2922,6 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, case MaterializeTemporaryExprClass: return cast(this)->GetTemporaryExpr() ->isConstantInitializer(Ctx, false, Culprit); - case SubstNonTypeTemplateParmExprClass: return cast(this)->getReplacement() ->isConstantInitializer(Ctx, false, Culprit); @@ -2916,16 +2943,17 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, } namespace { + /// \brief Look for any side effects within a Stmt. class SideEffectFinder : public ConstEvaluatedExprVisitor { - typedef ConstEvaluatedExprVisitor Inherited; + using Inherited = ConstEvaluatedExprVisitor; + const bool IncludePossibleEffects; - bool HasSideEffects; + bool HasSideEffects = false; public: explicit SideEffectFinder(const ASTContext &Context, bool IncludePossible) - : Inherited(Context), - IncludePossibleEffects(IncludePossible), HasSideEffects(false) { } + : Inherited(Context), IncludePossibleEffects(IncludePossible) {} bool hasSideEffects() const { return HasSideEffects; } @@ -2935,7 +2963,8 @@ namespace { HasSideEffects = true; } }; -} + +} // namespace bool Expr::HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects) const { @@ -3211,16 +3240,17 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, } namespace { + /// \brief Look for a call to a non-trivial function within an expression. - class NonTrivialCallFinder : public ConstEvaluatedExprVisitor - { - typedef ConstEvaluatedExprVisitor Inherited; + class NonTrivialCallFinder + : public ConstEvaluatedExprVisitor { + using Inherited = ConstEvaluatedExprVisitor; - bool NonTrivial; + bool NonTrivial = false; public: explicit NonTrivialCallFinder(const ASTContext &Context) - : Inherited(Context), NonTrivial(false) { } + : Inherited(Context) {} bool hasNonTrivialCall() const { return NonTrivial; } @@ -3256,7 +3286,8 @@ namespace { NonTrivial = true; } }; -} + +} // namespace bool Expr::hasNonTrivialCall(const ASTContext &Ctx) const { NonTrivialCallFinder Finder(Ctx); @@ -3282,7 +3313,6 @@ Expr::isNullPointerConstant(ASTContext &Ctx, return NPCK_ZeroExpression; else return NPCK_NotNull; - case NPC_ValueDependentIsNotNull: return NPCK_NotNull; } @@ -3580,12 +3610,11 @@ void ExtVectorElementExpr::getEncodedElementAccess( ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef 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()) @@ -3906,7 +3935,7 @@ PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &C, Expr *syntax, ArrayRef semantics, unsigned resultIndex) { assert(syntax && "no syntactic expression!"); - assert(semantics.size() && "no semantic expressions!"); + assert(!semantics.empty() && "no semantic expressions!"); QualType type; ExprValueKind VK; @@ -3980,10 +4009,9 @@ Stmt::const_child_range UnaryExprOrTypeTraitExpr::children() const { AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef 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()) @@ -4086,7 +4114,7 @@ QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) { if (OriginalTy->isAnyPointerType()) OriginalTy = OriginalTy->getPointeeType(); else { - assert (OriginalTy->isArrayType()); + assert(OriginalTy->isArrayType()); OriginalTy = OriginalTy->castAsArrayTypeUnsafe()->getElementType(); } } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ca07f74..6b209cd 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1,4 +1,4 @@ -//===--- SemaChecking.cpp - Extra Semantic Checking -----------------------===// +//===- SemaChecking.cpp - Extra Semantic Checking -------------------------===// // // The LLVM Compiler Infrastructure // @@ -12,35 +12,88 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" +#include "clang/AST/AttrIterator.h" #include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.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/StmtCXX.h" -#include "clang/AST/StmtObjC.h" +#include "clang/AST/NSAPI.h" +#include "clang/AST/OperationKinds.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" +#include "clang/AST/UnresolvedSet.h" #include "clang/Analysis/Analyses/FormatString.h" +#include "clang/Basic/AddressSpaces.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/OpenCLOptions.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/SyncScope.h" #include "clang/Basic/TargetBuiltins.h" +#include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TypeTraits.h" #include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering. #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/Ownership.h" +#include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/AtomicOrdering.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/Locale.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace clang; using namespace sema; @@ -638,7 +691,7 @@ static bool SemaBuiltinRWPipe(Sema &S, CallExpr *Call) { // OpenCL v2.0 s6.13.16.2 - The built-in read/write // functions have two forms. switch (Call->getNumArgs()) { - case 2: { + case 2: if (checkOpenCLPipeArg(S, Call)) return true; // The call with 2 arguments should be @@ -646,7 +699,7 @@ static bool SemaBuiltinRWPipe(Sema &S, CallExpr *Call) { // Check packet type T. if (checkOpenCLPipePacketType(S, Call, 1)) return true; - } break; + break; case 4: { if (checkOpenCLPipeArg(S, Call)) @@ -753,6 +806,7 @@ static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) { return false; } + // \brief OpenCL v2.0 s6.13.9 - Address space qualifier functions. // \brief Performs semantic analysis for the to_global/local/private call. // \param S Reference to the semantic analyzer. @@ -905,7 +959,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (checkArgCount(*this, TheCall, 1)) return true; break; - case Builtin::BI__builtin_classify_type: if (checkArgCount(*this, TheCall, 1)) return true; TheCall->setType(Context.IntTy); @@ -1170,9 +1223,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, break; case Builtin::BI__builtin_os_log_format: case Builtin::BI__builtin_os_log_format_buffer_size: - if (SemaBuiltinOSLogFormat(TheCall)) { + if (SemaBuiltinOSLogFormat(TheCall)) return ExprError(); - } break; } @@ -2508,6 +2560,7 @@ bool Sema::GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx) { } return false; } + /// \brief Diagnose use of %s directive in an NSString which is being passed /// as formatting string to formatting method. static void @@ -2874,23 +2927,32 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, enum { // C __c11_atomic_init(A *, C) Init, + // C __c11_atomic_load(A *, int) Load, + // void __atomic_load(A *, CP, int) LoadCopy, + // void __atomic_store(A *, CP, int) Copy, + // C __c11_atomic_add(A *, M, int) Arithmetic, + // C __atomic_exchange_n(A *, CP, int) Xchg, + // void __atomic_exchange(A *, C *, CP, int) GNUXchg, + // bool __c11_atomic_compare_exchange_strong(A *, C *, CP, int, int) C11CmpXchg, + // bool __atomic_compare_exchange(A *, C *, CP, bool, int, int) GNUCmpXchg } Form = Init; + const unsigned NumForm = GNUCmpXchg + 1; const unsigned NumArgs[] = { 2, 2, 3, 3, 3, 3, 4, 5, 6 }; const unsigned NumVals[] = { 1, 0, 1, 1, 1, 1, 2, 2, 3 }; @@ -3783,7 +3845,7 @@ static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) { bool IsWindows = TT.isOSWindows(); bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start; if (IsX64 || IsAArch64) { - clang::CallingConv CC = CC_C; + CallingConv CC = CC_C; if (const FunctionDecl *FD = S.getCurFunctionDecl()) CC = FD->getType()->getAs()->getCallConv(); if (IsMSVAStart) { @@ -4305,9 +4367,9 @@ bool Sema::SemaBuiltinAllocaWithAlign(CallExpr *TheCall) { << (unsigned)Context.getCharWidth() << Arg->getSourceRange(); - if (Result > INT32_MAX) + if (Result > std::numeric_limits::max()) return Diag(TheCall->getLocStart(), diag::err_alignment_too_big) - << INT32_MAX + << std::numeric_limits::max() << Arg->getSourceRange(); } @@ -4572,7 +4634,6 @@ bool Sema::SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, if (!ValidString) return Diag(TheCall->getLocStart(), diag::err_arm_invalid_specialreg) << Arg->getSourceRange(); - } else if (IsAArch64Builtin && Fields.size() == 1) { // If the register name is one of those that appear in the condition below // and the special register builtin being used is one of the write builtins, @@ -4626,13 +4687,15 @@ bool Sema::SemaBuiltinSetjmp(CallExpr *TheCall) { } namespace { + class UncoveredArgHandler { enum { Unknown = -1, AllCovered = -2 }; - signed FirstUncoveredArg; + + signed FirstUncoveredArg = Unknown; SmallVector DiagnosticExprs; public: - UncoveredArgHandler() : FirstUncoveredArg(Unknown) { } + UncoveredArgHandler() = default; bool hasUncoveredArg() const { return (FirstUncoveredArg >= 0); @@ -4676,7 +4739,8 @@ enum StringLiteralCheckType { SLCT_UncheckedLiteral, SLCT_CheckedLiteral }; -} // end anonymous namespace + +} // namespace static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, @@ -4709,7 +4773,8 @@ static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, // We add an offset to a pointer here so we should support an offset as big as // possible. if (Ov) { - assert(BitWidth <= UINT_MAX / 2 && "index (intermediate) result too big"); + assert(BitWidth <= std::numeric_limits::max() / 2 && + "index (intermediate) result too big"); Offset = Offset.sext(2 * BitWidth); sumOffsets(Offset, Addend, BinOpKind, AddendIsRight); return; @@ -4719,6 +4784,7 @@ static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, } namespace { + // This is a wrapper class around StringLiteral to support offsetted string // literals as format strings. It takes the offset into account when returning // the string and its length or the source locations to display notes correctly. @@ -4737,6 +4803,7 @@ class FormatStringLiteral { unsigned getByteLength() const { return FExpr->getByteLength() - getCharByteWidth() * Offset; } + unsigned getLength() const { return FExpr->getLength() - Offset; } unsigned getCharByteWidth() const { return FExpr->getCharByteWidth(); } @@ -4762,9 +4829,11 @@ class FormatStringLiteral { SourceLocation getLocStart() const LLVM_READONLY { return FExpr->getLocStart().getLocWithOffset(Offset); } + SourceLocation getLocEnd() const LLVM_READONLY { return FExpr->getLocEnd(); } }; -} // end anonymous namespace + +} // namespace static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr, @@ -4851,10 +4920,9 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef Args, return (CheckLeft && Left < Right) ? Left : Right; } - case Stmt::ImplicitCastExprClass: { + case Stmt::ImplicitCastExprClass: E = cast(E)->getSubExpr(); goto tryAgain; - } case Stmt::OpaqueValueExprClass: if (const Expr *src = cast(E)->getSourceExpr()) { @@ -5043,7 +5111,7 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef Args, case Stmt::UnaryOperatorClass: { const UnaryOperator *UnaOp = cast(E); auto ASE = dyn_cast(UnaOp->getSubExpr()); - if (UnaOp->getOpcode() == clang::UO_AddrOf && ASE) { + if (UnaOp->getOpcode() == UO_AddrOf && ASE) { llvm::APSInt IndexResult; if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.Context)) { sumOffsets(Offset, IndexResult, BO_Add, /*RHS is int*/ true); @@ -5176,6 +5244,7 @@ bool Sema::CheckFormatArguments(ArrayRef Args, } namespace { + class CheckFormatHandler : public analyze_format_string::FormatStringHandler { protected: Sema &S; @@ -5189,8 +5258,8 @@ protected: ArrayRef Args; unsigned FormatIdx; llvm::SmallBitVector CoveredArgs; - bool usesPositionalArgs; - bool atFirstArg; + bool usesPositionalArgs = false; + bool atFirstArg = true; bool inFunctionCall; Sema::VariadicCallType CallType; llvm::SmallBitVector &CheckedVarArgs; @@ -5208,7 +5277,6 @@ public: : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(type), FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg), HasVAListArg(hasVAListArg), Args(Args), FormatIdx(formatIdx), - usesPositionalArgs(false), atFirstArg(true), inFunctionCall(inFunctionCall), CallType(callType), CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) { CoveredArgs.resize(numDataArgs); @@ -5278,7 +5346,8 @@ protected: bool IsStringLocation, Range StringRange, ArrayRef Fixit = None); }; -} // end anonymous namespace + +} // namespace SourceRange CheckFormatHandler::getFormatStringRange() { return OrigFormatExpr->getSourceRange(); @@ -5632,6 +5701,7 @@ void CheckFormatHandler::EmitFormatDiagnostic( //===--- CHECK: Printf format string checking ------------------------------===// namespace { + class CheckPrintfHandler : public CheckFormatHandler { public: CheckPrintfHandler(Sema &s, const FormatStringLiteral *fexpr, @@ -5696,7 +5766,8 @@ public: const char *conversionPosition) override; }; -} // end anonymous namespace + +} // namespace bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier( const analyze_printf::PrintfSpecifier &FS, @@ -5814,10 +5885,6 @@ void CheckPrintfHandler::HandleIgnoredFlag( getSpecifierRange(ignoredFlag.getPosition(), 1))); } -// void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc, -// bool IsStringLocation, Range StringRange, -// ArrayRef Fixit = None); - void CheckPrintfHandler::HandleEmptyObjCModifierFlag(const char *startFlag, unsigned flagLen) { // Warn about an empty flag. @@ -5884,7 +5951,8 @@ CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty) { /// FIXME: This returns the wrong results in some cases (if cv-qualifiers don't /// allow the call, or if it would be ambiguous). bool Sema::hasCStrMethod(const Expr *E) { - typedef llvm::SmallPtrSet MethodSet; + using MethodSet = llvm::SmallPtrSet; + MethodSet Results = CXXRecordMembersNamed("c_str", *this, E->getType()); for (MethodSet::iterator MI = Results.begin(), ME = Results.end(); @@ -5899,7 +5967,7 @@ bool Sema::hasCStrMethod(const Expr *E) { // Returns true when a c_str() conversion method is found. bool CheckPrintfHandler::checkForCStrMembers( const analyze_printf::ArgType &AT, const Expr *E) { - typedef llvm::SmallPtrSet MethodSet; + using MethodSet = llvm::SmallPtrSet; MethodSet Results = CXXRecordMembersNamed("c_str", S, E->getType()); @@ -5927,7 +5995,8 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier const char *startSpecifier, unsigned specifierLen) { using namespace analyze_format_string; - using namespace analyze_printf; + using namespace analyze_printf; + const PrintfConversionSpecifier &CS = FS.getConversionSpecifier(); if (FS.consumesDataArgument()) { @@ -6225,6 +6294,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, const Expr *E) { using namespace analyze_format_string; using namespace analyze_printf; + // Now type check the data expression that matches the // format specifier. const analyze_printf::ArgType &AT = FS.getArgType(S.Context, isObjCContext()); @@ -6477,6 +6547,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, //===--- CHECK: Scanf format string checking ------------------------------===// namespace { + class CheckScanfHandler : public CheckFormatHandler { public: CheckScanfHandler(Sema &s, const FormatStringLiteral *fexpr, @@ -6503,7 +6574,8 @@ public: void HandleIncompleteScanList(const char *start, const char *end) override; }; -} // end anonymous namespace + +} // namespace void CheckScanfHandler::HandleIncompleteScanList(const char *start, const char *end) { @@ -6516,7 +6588,6 @@ bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier( const analyze_scanf::ScanfSpecifier &FS, const char *startSpecifier, unsigned specifierLen) { - const analyze_scanf::ScanfConversionSpecifier &CS = FS.getConversionSpecifier(); @@ -7258,7 +7329,7 @@ static const CXXRecordDecl *getContainedDynamicClass(QualType T, static const Expr *getSizeOfExprArg(const Expr *E) { if (const UnaryExprOrTypeTraitExpr *SizeOf = dyn_cast(E)) - if (SizeOf->getKind() == clang::UETT_SizeOf && !SizeOf->isArgumentType()) + if (SizeOf->getKind() == UETT_SizeOf && !SizeOf->isArgumentType()) return SizeOf->getArgumentExpr()->IgnoreParenImpCasts(); return nullptr; @@ -7268,7 +7339,7 @@ static const Expr *getSizeOfExprArg(const Expr *E) { static QualType getSizeOfArgType(const Expr *E) { if (const UnaryExprOrTypeTraitExpr *SizeOf = dyn_cast(E)) - if (SizeOf->getKind() == clang::UETT_SizeOf) + if (SizeOf->getKind() == UETT_SizeOf) return SizeOf->getTypeOfArgument(); return QualType(); @@ -7456,7 +7527,7 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call, static const Expr *ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx) { Ex = Ex->IgnoreParenCasts(); - for (;;) { + while (true) { const BinaryOperator * BO = dyn_cast(Ex); if (!BO || !BO->isAdditiveOp()) break; @@ -7674,7 +7745,6 @@ static const Expr *EvalAddr(const Expr *E, static void CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc) { - const Expr *stackE = nullptr; SmallVector refVars; @@ -8159,8 +8229,7 @@ struct IntRange { bool NonNegative; IntRange(unsigned Width, bool NonNegative) - : Width(Width), NonNegative(NonNegative) - {} + : Width(Width), NonNegative(NonNegative) {} /// Returns the range of the bool type. static IntRange forBoolType() { @@ -8249,7 +8318,10 @@ struct IntRange { } }; -IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth) { +} // namespace + +static IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, + unsigned MaxWidth) { if (value.isSigned() && value.isNegative()) return IntRange(value.getMinSignedBits(), false); @@ -8261,8 +8333,8 @@ IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth) { return IntRange(value.getActiveBits(), true); } -IntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty, - unsigned MaxWidth) { +static IntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty, + unsigned MaxWidth) { if (result.isInt()) return GetValueRange(C, result.getInt(), MaxWidth); @@ -8290,7 +8362,7 @@ IntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty, return IntRange(MaxWidth, Ty->isUnsignedIntegerOrEnumerationType()); } -QualType GetExprType(const Expr *E) { +static QualType GetExprType(const Expr *E) { QualType Ty = E->getType(); if (const AtomicType *AtomicRHS = Ty->getAs()) Ty = AtomicRHS->getValueType(); @@ -8301,7 +8373,7 @@ QualType GetExprType(const Expr *E) { /// range of values it might take. /// /// \param MaxWidth - the width to which the value will be truncated -IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth) { +static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth) { E = E->IgnoreParens(); // Try a full evaluation first. @@ -8519,16 +8591,16 @@ IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth) { return IntRange::forValueOfType(C, GetExprType(E)); } -IntRange GetExprRange(ASTContext &C, const Expr *E) { +static IntRange GetExprRange(ASTContext &C, const Expr *E) { return GetExprRange(C, E, C.getIntWidth(GetExprType(E))); } /// Checks whether the given value, which currently has the given /// source semantics, has the same value when coerced through the /// target semantics. -bool IsSameFloatAfterCast(const llvm::APFloat &value, - const llvm::fltSemantics &Src, - const llvm::fltSemantics &Tgt) { +static bool IsSameFloatAfterCast(const llvm::APFloat &value, + const llvm::fltSemantics &Src, + const llvm::fltSemantics &Tgt) { llvm::APFloat truncated = value; bool ignored; @@ -8543,9 +8615,9 @@ bool IsSameFloatAfterCast(const llvm::APFloat &value, /// target semantics. /// /// The value might be a vector of floats (or a complex number). -bool IsSameFloatAfterCast(const APValue &value, - const llvm::fltSemantics &Src, - const llvm::fltSemantics &Tgt) { +static bool IsSameFloatAfterCast(const APValue &value, + const llvm::fltSemantics &Src, + const llvm::fltSemantics &Tgt) { if (value.isFloat()) return IsSameFloatAfterCast(value.getFloat(), Src, Tgt); @@ -8561,9 +8633,9 @@ bool IsSameFloatAfterCast(const APValue &value, IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt)); } -void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC); +static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC); -bool IsEnumConstOrFromMacro(Sema &S, Expr *E) { +static bool IsEnumConstOrFromMacro(Sema &S, Expr *E) { // Suppress cases where we are comparing against an enum constant. if (const DeclRefExpr *DR = dyn_cast(E->IgnoreParenImpCasts())) @@ -8577,11 +8649,11 @@ bool IsEnumConstOrFromMacro(Sema &S, Expr *E) { return false; } -bool isNonBooleanIntegerValue(Expr *E) { +static bool isNonBooleanIntegerValue(Expr *E) { return !E->isKnownToHaveBooleanValue() && E->getType()->isIntegerType(); } -bool isNonBooleanUnsignedValue(Expr *E) { +static bool isNonBooleanUnsignedValue(Expr *E) { // We are checking that the expression is not known to have boolean value, // is an integer type; and is either unsigned after implicit casts, // or was unsigned before implicit casts. @@ -8590,6 +8662,8 @@ bool isNonBooleanUnsignedValue(Expr *E) { !E->IgnoreParenImpCasts()->getType()->isSignedIntegerType()); } +namespace { + enum class LimitType { Max = 1U << 0U, // e.g. 32767 for short Min = 1U << 1U, // e.g. -32768 for short @@ -8597,12 +8671,15 @@ enum class LimitType { // same time; e.g. in C++, A::a in enum A { a = 0 }; }; +} // namespace + /// Checks whether Expr 'Constant' may be the /// std::numeric_limits<>::max() or std::numeric_limits<>::min() /// of the Expr 'Other'. If true, then returns the limit type (min or max). /// The Value is the evaluation of Constant -llvm::Optional IsTypeLimit(Sema &S, Expr *Constant, Expr *Other, - const llvm::APSInt &Value) { +static llvm::Optional IsTypeLimit(Sema &S, Expr *Constant, + Expr *Other, + const llvm::APSInt &Value) { if (IsEnumConstOrFromMacro(S, Constant)) return llvm::Optional(); @@ -8636,7 +8713,7 @@ llvm::Optional IsTypeLimit(Sema &S, Expr *Constant, Expr *Other, return llvm::None; } -bool HasEnumType(Expr *E) { +static bool HasEnumType(Expr *E) { // Strip off implicit integral promotions. while (ImplicitCastExpr *ICE = dyn_cast(E)) { if (ICE->getCastKind() != CK_IntegralCast && @@ -8648,9 +8725,10 @@ bool HasEnumType(Expr *E) { return E->getType()->isEnumeralType(); } -bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, - Expr *Other, const llvm::APSInt &Value, - bool RhsConstant) { +static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, + Expr *Constant, Expr *Other, + const llvm::APSInt &Value, + bool RhsConstant) { // Disable warning in template instantiations // and only analyze <, >, <= and >= operations. if (S.inTemplateInstantiation() || !E->isRelationalOp()) @@ -8696,9 +8774,10 @@ bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, return true; } -bool DiagnoseOutOfRangeComparison(Sema &S, BinaryOperator *E, Expr *Constant, - Expr *Other, const llvm::APSInt &Value, - bool RhsConstant) { +static bool DiagnoseOutOfRangeComparison(Sema &S, BinaryOperator *E, + Expr *Constant, Expr *Other, + const llvm::APSInt &Value, + bool RhsConstant) { // Disable warning in template instantiations. if (S.inTemplateInstantiation()) return false; @@ -8907,7 +8986,7 @@ bool DiagnoseOutOfRangeComparison(Sema &S, BinaryOperator *E, Expr *Constant, /// Analyze the operands of the given comparison. Implements the /// fallback case from AnalyzeComparison. -void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) { +static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) { AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); } @@ -8915,7 +8994,7 @@ void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) { /// \brief Implements -Wsign-compare. /// /// \param E the binary operator to check for warnings -void AnalyzeComparison(Sema &S, BinaryOperator *E) { +static void AnalyzeComparison(Sema &S, BinaryOperator *E) { // The type the comparison is being performed in. QualType T = E->getLHS()->getType(); @@ -9023,8 +9102,8 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) { /// Analyzes an attempt to assign the given value to a bitfield. /// /// Returns true if there was something fishy about the attempt. -bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, - SourceLocation InitLoc) { +static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, + SourceLocation InitLoc) { assert(Bitfield->isBitField()); if (Bitfield->isInvalidDecl()) return false; @@ -9154,7 +9233,7 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, /// Analyze the given simple or compound assignment for warning-worthy /// operations. -void AnalyzeAssignment(Sema &S, BinaryOperator *E) { +static void AnalyzeAssignment(Sema &S, BinaryOperator *E) { // Just recurse on the LHS. AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); @@ -9173,9 +9252,9 @@ void AnalyzeAssignment(Sema &S, BinaryOperator *E) { } /// Diagnose an implicit cast; purely a helper for CheckImplicitConversion. -void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, - SourceLocation CContext, unsigned diag, - bool pruneControlFlow = false) { +static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, + SourceLocation CContext, unsigned diag, + bool pruneControlFlow = false) { if (pruneControlFlow) { S.DiagRuntimeBehavior(E->getExprLoc(), E, S.PDiag(diag) @@ -9188,16 +9267,16 @@ void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, } /// Diagnose an implicit cast; purely a helper for CheckImplicitConversion. -void DiagnoseImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext, - unsigned diag, bool pruneControlFlow = false) { +static void DiagnoseImpCast(Sema &S, Expr *E, QualType T, + SourceLocation CContext, + unsigned diag, bool pruneControlFlow = false) { DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow); } /// Diagnose an implicit cast from a floating point value to an integer value. -void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, - - SourceLocation CContext) { +static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, + SourceLocation CContext) { const bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool); const bool PruneWarnings = S.inTemplateInstantiation(); @@ -9287,7 +9366,8 @@ void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, } } -std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) { +static std::string PrettyPrintInRange(const llvm::APSInt &Value, + IntRange Range) { if (!Range.Width) return "0"; llvm::APSInt ValueInRange = Value; @@ -9296,7 +9376,7 @@ std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) { return ValueInRange.toString(10); } -bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool) { +static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool) { if (!isa(Ex)) return false; @@ -9315,8 +9395,8 @@ bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool) { FloatCandidateBT && (FloatCandidateBT->isFloatingPoint())); } -void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, - SourceLocation CC) { +static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, + SourceLocation CC) { unsigned NumArgs = TheCall->getNumArgs(); for (unsigned i = 0; i < NumArgs; ++i) { Expr *CurrA = TheCall->getArg(i); @@ -9336,7 +9416,8 @@ void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, } } -void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC) { +static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, + SourceLocation CC) { if (S.Diags.isIgnored(diag::warn_impcast_null_pointer_to_integer, E->getExprLoc())) return; @@ -9380,20 +9461,24 @@ void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC) { return; S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) - << (NullKind == Expr::NPCK_CXX11_nullptr) << T << clang::SourceRange(CC) + << (NullKind == Expr::NPCK_CXX11_nullptr) << T << SourceRange(CC) << FixItHint::CreateReplacement(Loc, S.getFixItZeroLiteralForType(T, Loc)); } -void checkObjCArrayLiteral(Sema &S, QualType TargetType, - ObjCArrayLiteral *ArrayLiteral); -void checkObjCDictionaryLiteral(Sema &S, QualType TargetType, - ObjCDictionaryLiteral *DictionaryLiteral); +static void checkObjCArrayLiteral(Sema &S, QualType TargetType, + ObjCArrayLiteral *ArrayLiteral); + +static void +checkObjCDictionaryLiteral(Sema &S, QualType TargetType, + ObjCDictionaryLiteral *DictionaryLiteral); /// Check a single element within a collection literal against the /// target element type. -void checkObjCCollectionLiteralElement(Sema &S, QualType TargetElementType, - Expr *Element, unsigned ElementKind) { +static void checkObjCCollectionLiteralElement(Sema &S, + QualType TargetElementType, + Expr *Element, + unsigned ElementKind) { // Skip a bitcast to 'id' or qualified 'id'. if (auto ICE = dyn_cast(Element)) { if (ICE->getCastKind() == CK_BitCast && @@ -9422,8 +9507,8 @@ void checkObjCCollectionLiteralElement(Sema &S, QualType TargetElementType, /// Check an Objective-C array literal being converted to the given /// target type. -void checkObjCArrayLiteral(Sema &S, QualType TargetType, - ObjCArrayLiteral *ArrayLiteral) { +static void checkObjCArrayLiteral(Sema &S, QualType TargetType, + ObjCArrayLiteral *ArrayLiteral) { if (!S.NSArrayDecl) return; @@ -9450,8 +9535,9 @@ void checkObjCArrayLiteral(Sema &S, QualType TargetType, /// Check an Objective-C dictionary literal being converted to the given /// target type. -void checkObjCDictionaryLiteral(Sema &S, QualType TargetType, - ObjCDictionaryLiteral *DictionaryLiteral) { +static void +checkObjCDictionaryLiteral(Sema &S, QualType TargetType, + ObjCDictionaryLiteral *DictionaryLiteral) { if (!S.NSDictionaryDecl) return; @@ -9479,8 +9565,8 @@ void checkObjCDictionaryLiteral(Sema &S, QualType TargetType, // Helper function to filter out cases for constant width constant conversion. // Don't warn on char array initialization or for non-decimal values. -bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, - SourceLocation CC) { +static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, + SourceLocation CC) { // If initializing from a constant, and the constant starts with '0', // then it is a binary, octal, or hexadecimal. Allow these constants // to fill all the bits, even if there is a sign change. @@ -9503,8 +9589,9 @@ bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, return true; } -void CheckImplicitConversion(Sema &S, Expr *E, QualType T, - SourceLocation CC, bool *ICContext = nullptr) { +static void +CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, + bool *ICContext = nullptr) { if (E->isTypeDependent() || E->isValueDependent()) return; const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr(); @@ -9772,11 +9859,11 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, } } -void CheckConditionalOperator(Sema &S, ConditionalOperator *E, - SourceLocation CC, QualType T); +static void CheckConditionalOperator(Sema &S, ConditionalOperator *E, + SourceLocation CC, QualType T); -void CheckConditionalOperand(Sema &S, Expr *E, QualType T, - SourceLocation CC, bool &ICContext) { +static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, + SourceLocation CC, bool &ICContext) { E = E->IgnoreParenImpCasts(); if (isa(E)) @@ -9787,8 +9874,8 @@ void CheckConditionalOperand(Sema &S, Expr *E, QualType T, return CheckImplicitConversion(S, E, T, CC, &ICContext); } -void CheckConditionalOperator(Sema &S, ConditionalOperator *E, - SourceLocation CC, QualType T) { +static void CheckConditionalOperator(Sema &S, ConditionalOperator *E, + SourceLocation CC, QualType T) { AnalyzeImplicitConversions(S, E->getCond(), E->getQuestionLoc()); bool Suspicious = false; @@ -9817,7 +9904,7 @@ void CheckConditionalOperator(Sema &S, ConditionalOperator *E, /// CheckBoolLikeConversion - Check conversion of given expression to boolean. /// Input argument E is a logical expression. -void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) { +static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) { if (S.getLangOpts().Bool) return; CheckImplicitConversion(S, E->IgnoreParenImpCasts(), S.Context.BoolTy, CC); @@ -9826,7 +9913,8 @@ void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) { /// AnalyzeImplicitConversions - Find and report any interesting /// implicit conversions in the given expression. There are a couple /// of competing diagnostics here, -Wconversion and -Wsign-compare. -void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) { +static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, + SourceLocation CC) { QualType T = OrigE->getType(); Expr *E = OrigE->IgnoreParenImpCasts(); @@ -9919,8 +10007,6 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) { ::CheckBoolLikeConversion(S, U->getSubExpr(), CC); } -} // end anonymous namespace - /// Diagnose integer type and any valid implicit convertion to it. static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, const QualType &IntT) { // Taking into account implicit conversions, @@ -10226,10 +10312,11 @@ void Sema::CheckForIntOverflow (Expr *E) { } namespace { + /// \brief Visitor for expressions which looks for unsequenced operations on the /// same object. class SequenceChecker : public EvaluatedExprVisitor { - typedef EvaluatedExprVisitor Base; + using Base = EvaluatedExprVisitor; /// \brief A tree of sequenced regions within an expression. Two regions are /// unsequenced if one is an ancestor or a descendent of the other. When we @@ -10248,11 +10335,14 @@ class SequenceChecker : public EvaluatedExprVisitor { /// \brief A region within an expression which may be sequenced with respect /// to some other region. class Seq { - explicit Seq(unsigned N) : Index(N) {} - unsigned Index; friend class SequenceTree; + + unsigned Index = 0; + + explicit Seq(unsigned N) : Index(N) {} + public: - Seq() : Index(0) {} + Seq() = default; }; SequenceTree() { Values.push_back(Value(0)); } @@ -10296,16 +10386,18 @@ class SequenceChecker : public EvaluatedExprVisitor { }; /// An object for which we can track unsequenced uses. - typedef NamedDecl *Object; + using Object = NamedDecl *; /// Different flavors of object usage which we track. We only track the /// least-sequenced usage of each kind. enum UsageKind { /// A read of an object. Multiple unsequenced reads are OK. UK_Use, + /// A modification of an object which is sequenced before the value /// computation of the expression, such as ++n in C++. UK_ModAsValue, + /// A modification of an object which is not sequenced before the value /// computation of the expression, such as n++. UK_ModAsSideEffect, @@ -10314,29 +10406,37 @@ class SequenceChecker : public EvaluatedExprVisitor { }; struct Usage { - Usage() : Use(nullptr), Seq() {} - Expr *Use; + Expr *Use = nullptr; SequenceTree::Seq Seq; + + Usage() = default; }; struct UsageInfo { - UsageInfo() : Diagnosed(false) {} Usage Uses[UK_Count]; + /// Have we issued a diagnostic for this variable already? - bool Diagnosed; + bool Diagnosed = false; + + UsageInfo() = default; }; - typedef llvm::SmallDenseMap UsageInfoMap; + using UsageInfoMap = llvm::SmallDenseMap; Sema &SemaRef; + /// Sequenced regions within the expression. SequenceTree Tree; + /// Declaration modifications and references which we have seen. UsageInfoMap UsageMap; + /// The region we are currently within. SequenceTree::Seq Region; + /// Filled in with declarations which were modified as a side-effect /// (that is, post-increment operations). - SmallVectorImpl > *ModAsSideEffect; + SmallVectorImpl> *ModAsSideEffect = nullptr; + /// Expressions to check later. We defer checking these to reduce /// stack usage. SmallVectorImpl &WorkList; @@ -10351,6 +10451,7 @@ class SequenceChecker : public EvaluatedExprVisitor { : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) { Self.ModAsSideEffect = &ModAsSideEffect; } + ~SequencedSubexpression() { for (auto &M : llvm::reverse(ModAsSideEffect)) { UsageInfo &U = Self.UsageMap[M.first]; @@ -10363,7 +10464,7 @@ class SequenceChecker : public EvaluatedExprVisitor { SequenceChecker &Self; SmallVector, 4> ModAsSideEffect; - SmallVectorImpl > *OldModAsSideEffect; + SmallVectorImpl> *OldModAsSideEffect; }; /// RAII object wrapping the visitation of a subexpression which we might @@ -10373,9 +10474,10 @@ class SequenceChecker : public EvaluatedExprVisitor { class EvaluationTracker { public: EvaluationTracker(SequenceChecker &Self) - : Self(Self), Prev(Self.EvalTracker), EvalOK(true) { + : Self(Self), Prev(Self.EvalTracker) { Self.EvalTracker = this; } + ~EvaluationTracker() { Self.EvalTracker = Prev; if (Prev) @@ -10392,8 +10494,8 @@ class SequenceChecker : public EvaluatedExprVisitor { private: SequenceChecker &Self; EvaluationTracker *Prev; - bool EvalOK; - } *EvalTracker; + bool EvalOK = true; + } *EvalTracker = nullptr; /// \brief Find the object which is produced by the specified expression, /// if any. @@ -10427,6 +10529,7 @@ class SequenceChecker : public EvaluatedExprVisitor { U.Seq = Region; } } + /// \brief Check whether a modification or use conflicts with a prior usage. void checkUsage(Object O, UsageInfo &UI, Expr *Ref, UsageKind OtherKind, bool IsModMod) { @@ -10454,6 +10557,7 @@ class SequenceChecker : public EvaluatedExprVisitor { // Uses conflict with other modifications. checkUsage(O, U, Use, UK_ModAsValue, false); } + void notePostUse(Object O, Expr *Use) { UsageInfo &U = UsageMap[O]; checkUsage(O, U, Use, UK_ModAsSideEffect, false); @@ -10466,6 +10570,7 @@ class SequenceChecker : public EvaluatedExprVisitor { checkUsage(O, U, Mod, UK_ModAsValue, true); checkUsage(O, U, Mod, UK_Use, false); } + void notePostMod(Object O, Expr *Use, UsageKind UK) { UsageInfo &U = UsageMap[O]; checkUsage(O, U, Use, UK_ModAsSideEffect, true); @@ -10474,8 +10579,7 @@ class SequenceChecker : public EvaluatedExprVisitor { public: SequenceChecker(Sema &S, Expr *E, SmallVectorImpl &WorkList) - : Base(S.Context), SemaRef(S), Region(Tree.root()), - ModAsSideEffect(nullptr), WorkList(WorkList), EvalTracker(nullptr) { + : Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) { Visit(E); } @@ -10709,7 +10813,8 @@ public: Tree.merge(Elts[I]); } }; -} // end anonymous namespace + +} // namespace void Sema::CheckUnsequencedOperations(Expr *E) { SmallVector WorkList; @@ -11126,19 +11231,22 @@ void Sema::CheckArrayAccess(const Expr *expr) { //===--- CHECK: Objective-C retain cycles ----------------------------------// namespace { - struct RetainCycleOwner { - RetainCycleOwner() : Variable(nullptr), Indirect(false) {} - VarDecl *Variable; - SourceRange Range; - SourceLocation Loc; - bool Indirect; - void setLocsFrom(Expr *e) { - Loc = e->getExprLoc(); - Range = e->getSourceRange(); - } - }; -} // end anonymous namespace +struct RetainCycleOwner { + VarDecl *Variable = nullptr; + SourceRange Range; + SourceLocation Loc; + bool Indirect = false; + + RetainCycleOwner() = default; + + void setLocsFrom(Expr *e) { + Loc = e->getExprLoc(); + Range = e->getSourceRange(); + } +}; + +} // namespace /// Consider whether capturing the given variable can possibly lead to /// a retain cycle. @@ -11235,15 +11343,16 @@ static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { } namespace { + struct FindCaptureVisitor : EvaluatedExprVisitor { - FindCaptureVisitor(ASTContext &Context, VarDecl *variable) - : EvaluatedExprVisitor(Context), - Context(Context), Variable(variable), Capturer(nullptr), - VarWillBeReased(false) {} ASTContext &Context; VarDecl *Variable; - Expr *Capturer; - bool VarWillBeReased; + Expr *Capturer = nullptr; + bool VarWillBeReased = false; + + FindCaptureVisitor(ASTContext &Context, VarDecl *variable) + : EvaluatedExprVisitor(Context), + Context(Context), Variable(variable) {} void VisitDeclRefExpr(DeclRefExpr *ref) { if (ref->getDecl() == Variable && !Capturer) @@ -11268,6 +11377,7 @@ namespace { if (OVE->getSourceExpr()) Visit(OVE->getSourceExpr()); } + void VisitBinaryOperator(BinaryOperator *BinOp) { if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign) return; @@ -11284,7 +11394,8 @@ namespace { } } }; -} // end anonymous namespace + +} // namespace /// Check whether the given argument is a block which captures a /// variable. @@ -11691,16 +11802,14 @@ void Sema::checkUnsafeExprAssigns(SourceLocation Loc, //===--- CHECK: Empty statement body (-Wempty-body) ---------------------===// -namespace { -bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, - SourceLocation StmtLoc, - const NullStmt *Body) { +static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, + SourceLocation StmtLoc, + const NullStmt *Body) { // Do not warn if the body is a macro that expands to nothing, e.g: // // #define CALL(x) // if (condition) // CALL(0); - // if (Body->hasLeadingEmptyMacro()) return false; @@ -11723,7 +11832,6 @@ bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, return true; } -} // end anonymous namespace void Sema::DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, @@ -11903,12 +12011,10 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, //===--- Layout compatibility ----------------------------------------------// -namespace { - -bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2); +static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2); /// \brief Check if two enumeration types are layout-compatible. -bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { +static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { // C++11 [dcl.enum] p8: // Two enumeration types are layout-compatible if they have the same // underlying type. @@ -11917,7 +12023,8 @@ bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { } /// \brief Check if two fields are layout-compatible. -bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, FieldDecl *Field2) { +static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, + FieldDecl *Field2) { if (!isLayoutCompatible(C, Field1->getType(), Field2->getType())) return false; @@ -11938,9 +12045,8 @@ bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, FieldDecl *Field2) { /// \brief Check if two standard-layout structs are layout-compatible. /// (C++11 [class.mem] p17) -bool isLayoutCompatibleStruct(ASTContext &C, - RecordDecl *RD1, - RecordDecl *RD2) { +static bool isLayoutCompatibleStruct(ASTContext &C, RecordDecl *RD1, + RecordDecl *RD2) { // If both records are C++ classes, check that base classes match. if (const CXXRecordDecl *D1CXX = dyn_cast(RD1)) { // If one of records is a CXXRecordDecl we are in C++ mode, @@ -11983,9 +12089,8 @@ bool isLayoutCompatibleStruct(ASTContext &C, /// \brief Check if two standard-layout unions are layout-compatible. /// (C++11 [class.mem] p18) -bool isLayoutCompatibleUnion(ASTContext &C, - RecordDecl *RD1, - RecordDecl *RD2) { +static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1, + RecordDecl *RD2) { llvm::SmallPtrSet UnmatchedFields; for (auto *Field2 : RD2->fields()) UnmatchedFields.insert(Field2); @@ -12010,7 +12115,8 @@ bool isLayoutCompatibleUnion(ASTContext &C, return UnmatchedFields.empty(); } -bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, RecordDecl *RD2) { +static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, + RecordDecl *RD2) { if (RD1->isUnion() != RD2->isUnion()) return false; @@ -12021,7 +12127,7 @@ bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, RecordDecl *RD2) { } /// \brief Check if two types are layout-compatible in C++11 sense. -bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) { +static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) { if (T1.isNull() || T2.isNull()) return false; @@ -12055,11 +12161,9 @@ bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) { return false; } -} // end anonymous namespace //===--- CHECK: pointer_with_type_tag attribute: datatypes should match ----// -namespace { /// \brief Given a type tag expression find the type tag itself. /// /// \param TypeExpr Type tag expression, as it appears in user's code. @@ -12067,8 +12171,8 @@ namespace { /// \param VD Declaration of an identifier that appears in a type tag. /// /// \param MagicValue Type tag magic value. -bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, - const ValueDecl **VD, uint64_t *MagicValue) { +static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, + const ValueDecl **VD, uint64_t *MagicValue) { while(true) { if (!TypeExpr) return false; @@ -12143,7 +12247,7 @@ bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, /// \param TypeInfo Information about the corresponding C type. /// /// \returns true if the corresponding C type was found. -bool GetMatchingCType( +static bool GetMatchingCType( const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMapsecond; return true; } -} // end anonymous namespace void Sema::RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, @@ -12201,8 +12304,7 @@ void Sema::RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, TypeTagData(Type, LayoutCompatible, MustBeNull); } -namespace { -bool IsSameCharType(QualType T1, QualType T2) { +static bool IsSameCharType(QualType T1, QualType T2) { const BuiltinType *BT1 = T1->getAs(); if (!BT1) return false; @@ -12219,7 +12321,6 @@ bool IsSameCharType(QualType T1, QualType T2) { (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) || (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar); } -} // end anonymous namespace void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, const Expr * const *ExprArgs) { @@ -12448,8 +12549,8 @@ void Sema::RefersToMemberWithReducedAlignment( void Sema::CheckAddressOfPackedMember(Expr *rhs) { using namespace std::placeholders; + RefersToMemberWithReducedAlignment( rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*this), _1, _2, _3, _4)); } - -- 2.7.4