ThreadSafetyHandler &Handler,
BeforeSet **Bset);
+void threadSafetyCleanup(BeforeSet *Cache);
+
/// \brief Helper function that returns a LockKind required for the given level
/// of access.
LockKind getLockKindFromAccessKind(AccessKind AK);
#include <sstream>
#include <utility>
#include <vector>
-
-
-namespace clang {
-namespace threadSafety {
+using namespace clang;
+using namespace threadSafety;
// Key method definition
ThreadSafetyHandler::~ThreadSafetyHandler() {}
+namespace {
class TILPrinter :
public til::PrettyPrinter<TILPrinter, llvm::raw_ostream> {};
Handler.handleInvalidLockExp(Kind, Loc);
}
-
/// \brief A set of CapabilityInfo objects, which are compiled from the
/// requires attributes on a function.
class CapExprSet : public SmallVector<CapabilityExpr, 4> {
}
};
-
class ThreadSafetyAnalyzer;
+} // namespace
-
+namespace clang {
+namespace threadSafety {
class BeforeSet {
private:
typedef SmallVector<const ValueDecl*, 4> BeforeVect;
BeforeMap BMap;
CycleMap CycMap;
};
+} // end namespace threadSafety
+} // end namespace clang
-
-
+namespace {
typedef llvm::ImmutableMap<const NamedDecl*, unsigned> LocalVarContext;
class LocalVariableMap;
/// \brief Class which implements the core thread safety analysis routines.
class ThreadSafetyAnalyzer {
friend class BuildLockset;
- friend class BeforeSet;
+ friend class threadSafety::BeforeSet;
llvm::BumpPtrAllocator Bpa;
threadSafety::til::MemRegionRef Arena;
void runAnalysis(AnalysisDeclContext &AC);
};
-
-
+} // namespace
/// Process acquired_before and acquired_after attributes on Vd.
BeforeSet::BeforeInfo* BeforeSet::insertAttrExprs(const ValueDecl* Vd,
return nullptr;
}
+namespace {
template <typename Ty>
class has_arg_iterator_range {
typedef char yes[1];
public:
static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
};
+} // namespace
static StringRef ClassifyDiagnostic(const CapabilityAttr *A) {
return A->getName();
}
}
-
-bool getStaticBooleanValue(Expr* E, bool& TCond) {
+static bool getStaticBooleanValue(Expr *E, bool &TCond) {
if (isa<CXXNullPtrLiteralExpr>(E) || isa<GNUNullExpr>(E)) {
TCond = false;
return true;
CapDiagKind);
}
+namespace {
/// \brief We use this class to visit different types of expressions in
/// CFGBlocks, and build up the lockset.
/// An expression may cause us to add or remove locks from the lockset, or else
void VisitCXXConstructExpr(CXXConstructExpr *Exp);
void VisitDeclStmt(DeclStmt *S);
};
-
+} // namespace
/// \brief Warn if the LSet does not contain a lock sufficient to protect access
/// of at least the passed in AccessKind.
// Return true if block B never continues to its successors.
-inline bool neverReturns(const CFGBlock* B) {
+static bool neverReturns(const CFGBlock *B) {
if (B->hasNoReturnElement())
return true;
if (B->empty())
/// We traverse the blocks in the CFG, compute the set of mutexes that are held
/// at the end of each block, and issue warnings for thread safety violations.
/// Each block in the CFG is traversed exactly once.
-void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
- ThreadSafetyHandler &Handler,
- BeforeSet **BSet) {
+void threadSafety::runThreadSafetyAnalysis(AnalysisDeclContext &AC,
+ ThreadSafetyHandler &Handler,
+ BeforeSet **BSet) {
if (!*BSet)
*BSet = new BeforeSet;
ThreadSafetyAnalyzer Analyzer(Handler, *BSet);
Analyzer.runAnalysis(AC);
}
-
-void threadSafetyCleanup(BeforeSet* Cache) {
- delete Cache;
-}
-
+void threadSafety::threadSafetyCleanup(BeforeSet *Cache) { delete Cache; }
/// \brief Helper function that returns a LockKind required for the given level
/// of access.
-LockKind getLockKindFromAccessKind(AccessKind AK) {
+LockKind threadSafety::getLockKindFromAccessKind(AccessKind AK) {
switch (AK) {
case AK_Read :
return LK_Shared;
}
llvm_unreachable("Unknown AccessKind");
}
-
-}} // end namespace clang::threadSafety
#include <algorithm>
#include <climits>
#include <vector>
-
-
-namespace clang {
-namespace threadSafety {
+using namespace clang;
+using namespace threadSafety;
// From ThreadSafetyUtil.h
-std::string getSourceLiteralString(const clang::Expr *CE) {
+std::string threadSafety::getSourceLiteralString(const clang::Expr *CE) {
switch (CE->getStmtClass()) {
case Stmt::IntegerLiteralClass:
return cast<IntegerLiteral>(CE)->getValue().toString(10, true);
}
}
-namespace til {
-
// Return true if E is a variable that points to an incomplete Phi node.
-static bool isIncompletePhi(const SExpr *E) {
- if (const auto *Ph = dyn_cast<Phi>(E))
- return Ph->status() == Phi::PH_Incomplete;
+static bool isIncompletePhi(const til::SExpr *E) {
+ if (const auto *Ph = dyn_cast<til::Phi>(E))
+ return Ph->status() == til::Phi::PH_Incomplete;
return false;
}
-} // end namespace til
-
-
typedef SExprBuilder::CallingContext CallingContext;
return Scfg;
}
-
-
-inline bool isCalleeArrow(const Expr *E) {
+static bool isCalleeArrow(const Expr *E) {
const MemberExpr *ME = dyn_cast<MemberExpr>(E->IgnoreParenCasts());
return ME ? ME->isArrow() : false;
}
return SelfVar;
}
-
-const ValueDecl *getValueDeclFromSExpr(const til::SExpr *E) {
+static const ValueDecl *getValueDeclFromSExpr(const til::SExpr *E) {
if (auto *V = dyn_cast<til::Variable>(E))
return V->clangDecl();
if (auto *Ph = dyn_cast<til::Phi>(E))
return 0;
}
-bool hasCppPointerType(const til::SExpr *E) {
+static bool hasCppPointerType(const til::SExpr *E) {
auto *VD = getValueDeclFromSExpr(E);
if (VD && VD->getType()->isPointerType())
return true;
return false;
}
-
// Grab the very first declaration of virtual method D
-const CXXMethodDecl* getFirstVirtualDecl(const CXXMethodDecl *D) {
+static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) {
while (true) {
D = D->getCanonicalDecl();
CXXMethodDecl::method_iterator I = D->begin_overridden_methods(),
// if E is a til::Variable, update its clangDecl.
-inline void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {
+static void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {
if (!E)
return;
if (til::Variable *V = dyn_cast<til::Variable>(E)) {
TILPrinter::print(Scfg, llvm::errs());
}
*/
-
-
-} // end namespace threadSafety
-
-} // end namespace clang
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
+using namespace clang;
+using namespace threadSafety;
+using namespace til;
-namespace clang {
-namespace threadSafety {
-namespace til {
-
-
-StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op) {
+StringRef til::getUnaryOpcodeString(TIL_UnaryOpcode Op) {
switch (Op) {
case UOP_Minus: return "-";
case UOP_BitNot: return "~";
return "";
}
-
-StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op) {
+StringRef til::getBinaryOpcodeString(TIL_BinaryOpcode Op) {
switch (Op) {
case BOP_Mul: return "*";
case BOP_Div: return "/";
// If E is a variable, then trace back through any aliases or redundant
// Phi nodes to find the canonical definition.
-const SExpr *getCanonicalVal(const SExpr *E) {
+const SExpr *til::getCanonicalVal(const SExpr *E) {
while (true) {
if (auto *V = dyn_cast<Variable>(E)) {
if (V->kind() == Variable::VK_Let) {
// If E is a variable, then trace back through any aliases or redundant
// Phi nodes to find the canonical definition.
// The non-const version will simplify incomplete Phi nodes.
-SExpr *simplifyToCanonicalVal(SExpr *E) {
+SExpr *til::simplifyToCanonicalVal(SExpr *E) {
while (true) {
if (auto *V = dyn_cast<Variable>(E)) {
if (V->kind() != Variable::VK_Let)
// Trace the arguments of an incomplete Phi node to see if they have the same
// canonical definition. If so, mark the Phi node as redundant.
// getCanonicalVal() will recursively call simplifyIncompletePhi().
-void simplifyIncompleteArg(til::Phi *Ph) {
+void til::simplifyIncompleteArg(til::Phi *Ph) {
assert(Ph && Ph->status() == Phi::PH_Incomplete);
// eliminate infinite recursion -- assume that this node is not redundant.
computeNodeID(Block, &BasicBlock::PostDominatorNode);
}
}
-
-} // end namespace til
-} // end namespace threadSafety
-} // end namespace clang