summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp188
-rw-r--r--clang/lib/Sema/SemaChecking.cpp449
2 files changed, 383 insertions, 254 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 6cda82b2b0c..d3157680222 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 <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+
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 <class E, class T>
- SourceLocation getExprLocImpl(const Expr *expr,
- SourceLocation (T::*v)() const) {
- return static_cast<const E*>(expr)->getExprLoc();
- }
- /// This implementation is used when a class doesn't provide
- /// a custom implementation of getExprLoc. Overload resolution
- /// should pick it over the implementation above because it's
- /// more specialized according to function template partial ordering.
- template <class E>
- SourceLocation getExprLocImpl(const Expr *expr,
- SourceLocation (Expr::*v)() const) {
- return static_cast<const E*>(expr)->getLocStart();
- }
+/// This implementation is used when a class provides a custom
+/// implementation of getExprLoc.
+template <class E, class T>
+static SourceLocation getExprLocImpl(const Expr *expr,
+ SourceLocation (T::*v)() const) {
+ return static_cast<const E*>(expr)->getExprLoc();
+}
+
+/// This implementation is used when a class doesn't provide
+/// a custom implementation of getExprLoc. Overload resolution
+/// should pick it over the implementation above because it's
+/// more specialized according to function template partial ordering.
+template <class E>
+static SourceLocation getExprLocImpl(const Expr *expr,
+ SourceLocation (Expr::*v)() const) {
+ return static_cast<const E*>(expr)->getLocStart();
}
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<const ClassTemplateSpecializationDecl *, 8> SpecsTy;
+ using SpecsTy = SmallVector<const ClassTemplateSpecializationDecl *, 8>;
SpecsTy Specs;
+
const DeclContext *Ctx = FD->getDeclContext();
while (Ctx && isa<NamedDecl>(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<Expr *> args,
QualType t, ExprValueKind VK, SourceLocation rparenloc)
- : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {
-}
+ : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK,
+ rparenloc) {}
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
: CallExpr(C, SC, /*NumPreArgs=*/0, Empty) {}
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
EmptyShell Empty)
- : Expr(SC, Empty), 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<CXXOperatorCallExpr>(this))
return cast<CXXOperatorCallExpr>(this)->getLocEnd();
@@ -1393,7 +1424,7 @@ IdentifierInfo *OffsetOfNode::getFieldName() const {
if (getKind() == Field)
return getField()->getIdentifier();
- return reinterpret_cast<IdentifierInfo *> (Data & ~(uintptr_t)Mask);
+ return reinterpret_cast<IdentifierInfo *>(Data & ~(uintptr_t)Mask);
}
UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr(
@@ -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<MaterializeTemporaryExpr>(expr))
- expr = Materialize->GetTemporaryExpr();
+static Expr *skipImplicitTemporary(Expr *expr) {
+ // Skip through reference binding to temporary.
+ if (MaterializeTemporaryExpr *Materialize
+ = dyn_cast<MaterializeTemporaryExpr>(expr))
+ expr = Materialize->GetTemporaryExpr();
- // Skip any temporary bindings; they're implicit.
- if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(expr))
- expr = Binder->getSubExpr();
+ // Skip any temporary bindings; they're implicit.
+ if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(expr))
+ expr = Binder->getSubExpr();
- return expr;
- }
+ return expr;
}
Expr *CastExpr::getSubExprAsWritten() {
@@ -1861,13 +1890,13 @@ bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx,
return true;
}
+
InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
ArrayRef<Expr*> initExprs, SourceLocation rbraceloc)
- : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
- false, false),
- InitExprs(C, initExprs.size()),
- LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true)
-{
+ : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ InitExprs(C, initExprs.size()),
+ LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true) {
sawArrayRangeDesignator(false);
for (unsigned I = 0; I != initExprs.size(); ++I) {
if (initExprs[I]->isTypeDependent())
@@ -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<BlockPointerType>(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<WarnUnusedAttr>()) {
WarnE = this;
@@ -2221,7 +2250,6 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
}
}
return false;
- }
case ObjCMessageExprClass: {
const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(this);
@@ -2894,7 +2922,6 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
case MaterializeTemporaryExprClass:
return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
->isConstantInitializer(Ctx, false, Culprit);
-
case SubstNonTypeTemplateParmExprClass:
return cast<SubstNonTypeTemplateParmExpr>(this)->getReplacement()
->isConstantInitializer(Ctx, false, Culprit);
@@ -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<SideEffectFinder> {
- typedef ConstEvaluatedExprVisitor<SideEffectFinder> Inherited;
+ using Inherited = ConstEvaluatedExprVisitor<SideEffectFinder>;
+
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<NonTrivialCallFinder>
- {
- typedef ConstEvaluatedExprVisitor<NonTrivialCallFinder> Inherited;
+ class NonTrivialCallFinder
+ : public ConstEvaluatedExprVisitor<NonTrivialCallFinder> {
+ using Inherited = ConstEvaluatedExprVisitor<NonTrivialCallFinder>;
- 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<Expr*> args,
QualType Type, SourceLocation BLoc,
SourceLocation RP)
- : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
- Type->isDependentType(), Type->isDependentType(),
- Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
- BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size())
-{
+ : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
+ Type->isDependentType(), Type->isDependentType(),
+ Type->isInstantiationDependentType(),
+ Type->containsUnexpandedParameterPack()),
+ BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size()) {
SubExprs = new (C) Stmt*[args.size()];
for (unsigned i = 0; i != args.size(); i++) {
if (args[i]->isTypeDependent())
@@ -3906,7 +3935,7 @@ PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &C, Expr *syntax,
ArrayRef<Expr*> 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<Expr*> args,
QualType t, AtomicOp op, SourceLocation RP)
- : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
- false, false, false, false),
- NumSubExprs(args.size()), BuiltinLoc(BLoc), RParenLoc(RP), Op(op)
-{
+ : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
+ false, false, false, false),
+ NumSubExprs(args.size()), BuiltinLoc(BLoc), RParenLoc(RP), Op(op) {
assert(args.size() == getNumSubExprs(op) && "wrong number of subexpressions");
for (unsigned i = 0; i != args.size(); i++) {
if (args[i]->isTypeDependent())
@@ -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 ca07f7429e8..6b209cdef7c 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 <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <string>
+#include <tuple>
+#include <utility>
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<FunctionType>()->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<int32_t>::max())
return Diag(TheCall->getLocStart(), diag::err_alignment_too_big)
- << INT32_MAX
+ << std::numeric_limits<int32_t>::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<const Expr *, 4> 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<unsigned>::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<const Expr *> Args,
return (CheckLeft && Left < Right) ? Left : Right;
}
- case Stmt::ImplicitCastExprClass: {
+ case Stmt::ImplicitCastExprClass:
E = cast<ImplicitCastExpr>(E)->getSubExpr();
goto tryAgain;
- }
case Stmt::OpaqueValueExprClass:
if (const Expr *src = cast<OpaqueValueExpr>(E)->getSourceExpr()) {
@@ -5043,7 +5111,7 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,
case Stmt::UnaryOperatorClass: {
const UnaryOperator *UnaOp = cast<UnaryOperator>(E);
auto ASE = dyn_cast<ArraySubscriptExpr>(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<const Expr *> Args,
}
namespace {
+
class CheckFormatHandler : public analyze_format_string::FormatStringHandler {
protected:
Sema &S;
@@ -5189,8 +5258,8 @@ protected:
ArrayRef<const Expr *> 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<FixItHint> 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<FixItHint> 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<CXXMethodDecl*, 1> MethodSet;
+ using MethodSet = llvm::SmallPtrSet<CXXMethodDecl *, 1>;
+
MethodSet Results =
CXXRecordMembersNamed<CXXMethodDecl>("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<CXXMethodDecl*, 1> MethodSet;
+ using MethodSet = llvm::SmallPtrSet<CXXMethodDecl *, 1>;
MethodSet Results =
CXXRecordMembersNamed<CXXMethodDecl>("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<UnaryExprOrTypeTraitExpr>(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<UnaryExprOrTypeTraitExpr>(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<BinaryOperator>(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<const DeclRefExpr *, 8> 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<AtomicType>())
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<DeclRefExpr>(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<LimitType> IsTypeLimit(Sema &S, Expr *Constant, Expr *Other,
- const llvm::APSInt &Value) {
+static llvm::Optional<LimitType> IsTypeLimit(Sema &S, Expr *Constant,
+ Expr *Other,
+ const llvm::APSInt &Value) {
if (IsEnumConstOrFromMacro(S, Constant))
return llvm::Optional<LimitType>();
@@ -8636,7 +8713,7 @@ llvm::Optional<LimitType> 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<ImplicitCastExpr>(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<ImplicitCastExpr>(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<ImplicitCastExpr>(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<ConditionalOperator>(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<SequenceChecker> {
- typedef EvaluatedExprVisitor<SequenceChecker> Base;
+ using Base = EvaluatedExprVisitor<SequenceChecker>;
/// \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<SequenceChecker> {
/// \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<SequenceChecker> {
};
/// 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<SequenceChecker> {
};
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<Object, UsageInfo, 16> UsageInfoMap;
+ using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
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<std::pair<Object, Usage> > *ModAsSideEffect;
+ SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect = nullptr;
+
/// Expressions to check later. We defer checking these to reduce
/// stack usage.
SmallVectorImpl<Expr *> &WorkList;
@@ -10351,6 +10451,7 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
: 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> {
SequenceChecker &Self;
SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
- SmallVectorImpl<std::pair<Object, Usage> > *OldModAsSideEffect;
+ SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
};
/// RAII object wrapping the visitation of a subexpression which we might
@@ -10373,9 +10474,10 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
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<SequenceChecker> {
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<SequenceChecker> {
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<SequenceChecker> {
// 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<SequenceChecker> {
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<SequenceChecker> {
public:
SequenceChecker(Sema &S, Expr *E, SmallVectorImpl<Expr *> &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<Expr *, 8> 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> {
- FindCaptureVisitor(ASTContext &Context, VarDecl *variable)
- : EvaluatedExprVisitor<FindCaptureVisitor>(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<FindCaptureVisitor>(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<CXXRecordDecl>(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<FieldDecl *, 8> 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::DenseMap<Sema::TypeTagMagicValue,
@@ -12186,7 +12290,6 @@ bool GetMatchingCType(
TypeInfo = I->second;
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<BuiltinType>();
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));
}
-
OpenPOWER on IntegriCloud