21#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
22#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
33#include "llvm/ADT/DenseMap.h"
34#include "llvm/ADT/PointerIntPair.h"
35#include "llvm/ADT/PointerUnion.h"
36#include "llvm/ADT/SmallVector.h"
37#include "llvm/Support/Casting.h"
45class AbstractConditionalOperator;
46class ArraySubscriptExpr;
50class CXXDestructorDecl;
51class CXXMemberCallExpr;
52class CXXOperatorCallExpr;
61namespace threadSafety {
74 if (isa<til::Wildcard>(E1))
75 return isa<til::Wildcard>(E2);
76 if (isa<til::Wildcard>(E2))
77 return isa<til::Wildcard>(E1);
83 const auto *PE1 = dyn_cast_or_null<til::Project>(E1);
86 const auto *PE2 = dyn_cast_or_null<til::Project>(E2);
89 return PE1->clangDecl() == PE2->clangDecl();
108 void enterCFGBlock(
const CFGBlock *B) {}
111 bool visitPredecessors() {
return true; }
114 void handlePredecessor(
const CFGBlock *Pred) {}
117 void handlePredecessorBackEdge(
const CFGBlock *Pred) {}
120 void enterCFGBlockBody(
const CFGBlock *B) {}
123 void handleStatement(
const Stmt *S) {}
129 void exitCFGBlockBody(
const CFGBlock *B) {}
132 bool visitSuccessors() {
return true; }
135 void handleSuccessor(
const CFGBlock *Succ) {}
138 void handleSuccessorBackEdge(
const CFGBlock *Succ) {}
141 void exitCFGBlock(
const CFGBlock *B) {}
156 CFGraph = AC.getCFG();
161 if (!isa_and_nonnull<NamedDecl>(AC.getDecl()))
172 template <
class Visitor>
178 for (
const auto *CurrBlock : *SortedGraph) {
179 VisitedBlocks.
insert(CurrBlock);
181 V.enterCFGBlock(CurrBlock);
184 if (
V.visitPredecessors()) {
188 SE = CurrBlock->pred_end();
194 BackEdges.push_back(*SI);
197 V.handlePredecessor(*SI);
200 for (
auto *Blk : BackEdges)
201 V.handlePredecessorBackEdge(Blk);
204 V.enterCFGBlockBody(CurrBlock);
207 for (
const auto &BI : *CurrBlock) {
208 switch (BI.getKind()) {
218 V.handleDestructorCall(VD, DD);
226 V.exitCFGBlockBody(CurrBlock);
229 if (
V.visitSuccessors()) {
234 SE = CurrBlock->succ_end();
240 ForwardEdges.push_back(*SI);
243 V.handleSuccessorBackEdge(*SI);
246 for (
auto *Blk : ForwardEdges)
247 V.handleSuccessor(Blk);
250 V.exitCFGBlock(CurrBlock);
259 return dyn_cast<NamedDecl>(ACtx->
getDecl());
265 CFG *CFGraph =
nullptr;
275 static constexpr unsigned FlagNegative = 1u << 0;
276 static constexpr unsigned FlagReentrant = 1u << 1;
279 llvm::PointerIntPair<const til::SExpr *, 2, unsigned> CapExpr;
287 : CapExpr(
E, (Neg ? FlagNegative : 0) | (Reentrant ? FlagReentrant : 0)),
293 template <
typename T>
298 bool negative()
const {
return CapExpr.getInt() & FlagNegative; }
299 bool reentrant()
const {
return CapExpr.getInt() & FlagReentrant; }
328 if (
const auto *
P = dyn_cast<til::Project>(
sexpr()))
329 return P->clangDecl();
330 if (
const auto *
P = dyn_cast<til::LiteralPtr>(
sexpr()))
331 return P->clangDecl();
368 llvm::PointerUnion<const Expr *, til::SExpr *>
SelfArg =
nullptr;
374 llvm::PointerUnion<const Expr *const *, til::SExpr *>
FunArgs =
nullptr;
426 const Expr *SelfE =
nullptr);
444 til::SExpr *translateAbstractConditionalOperator(
450 using StatementMap = llvm::DenseMap<const Stmt *, til::SExpr *>;
453 using LVarIndexMap = llvm::DenseMap<const ValueDecl *, unsigned>;
456 using NameVarPair = std::pair<const ValueDecl *, til::SExpr *>;
461 bool HasBackEdges =
false;
464 unsigned UnprocessedSuccessors = 0;
467 unsigned ProcessedPredecessors = 0;
469 BlockInfo() =
default;
470 BlockInfo(BlockInfo &&) =
default;
471 BlockInfo &operator=(BlockInfo &&) =
default;
475 void enterCFGBlock(
const CFGBlock *B);
476 bool visitPredecessors() {
return true; }
477 void handlePredecessor(
const CFGBlock *Pred);
478 void handlePredecessorBackEdge(
const CFGBlock *Pred);
479 void enterCFGBlockBody(
const CFGBlock *B);
480 void handleStatement(
const Stmt *S);
482 void exitCFGBlockBody(
const CFGBlock *B);
483 bool visitSuccessors() {
return true; }
484 void handleSuccessor(
const CFGBlock *Succ);
485 void handleSuccessorBackEdge(
const CFGBlock *Succ);
486 void exitCFGBlock(
const CFGBlock *B);
487 void exitCFG(
const CFGBlock *
Last);
489 void insertStmt(
const Stmt *S, til::SExpr *
E) {
490 SMap.insert(std::make_pair(S,
E));
493 til::SExpr *addStatement(til::SExpr *
E,
const Stmt *S,
494 const ValueDecl *VD =
nullptr);
495 til::SExpr *lookupVarDecl(
const ValueDecl *VD);
496 til::SExpr *addVarDecl(
const ValueDecl *VD, til::SExpr *
E);
497 til::SExpr *updateVarDecl(
const ValueDecl *VD, til::SExpr *
E);
499 void makePhiNodeVar(
unsigned i,
unsigned NPreds, til::SExpr *
E);
500 void mergeEntryMap(LVarDefinitionMap Map);
501 void mergeEntryMapBackEdge();
502 void mergePhiNodesBackEdge(
const CFGBlock *Blk);
507 static const bool CapabilityExprMode =
true;
509 til::MemRegionRef Arena;
512 til::Variable *SelfVar =
nullptr;
514 til::SCFG *Scfg =
nullptr;
520 LVarIndexMap LVarIdxMap;
523 std::vector<til::BasicBlock *> BlockMap;
526 std::vector<BlockInfo> BBInfo;
528 LVarDefinitionMap CurrentLVarMap;
529 std::vector<til::Phi *> CurrentArguments;
530 std::vector<til::SExpr *> CurrentInstructions;
531 std::vector<til::Phi *> IncompleteArgs;
532 til::BasicBlock *CurrentBB =
nullptr;
533 BlockInfo *CurrentBlockInfo =
nullptr;
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
SExprBuilder::CallingContext CallingContext
C Language Family Type Representation.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
const Decl * getDecl() const
ASTContext & getASTContext() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
const VarDecl * getVarDecl() const
Represents a single basic block in a source-level CFG.
AdjacentBlocks::const_iterator const_pred_iterator
unsigned getBlockID() const
AdjacentBlocks::const_iterator const_succ_iterator
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
const Stmt * getStmt() const
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Represents a C++ destructor within a class.
Represents a call to a member function that may be written either with member call syntax (e....
A call to an overloaded operator written using operator syntax.
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
This represents one expression.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
This represents a decl that may have a name.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Implements a set of CFGBlocks using a BitVector.
std::pair< std::nullopt_t, bool > insert(const CFGBlock *Block)
Set the bit associated with a particular CFGBlock.
bool alreadySet(const CFGBlock *Block)
Check if the bit for a CFGBlock has been already set.
A (possibly-)qualified type.
Stmt - This represents one statement.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const PostOrderCFGView * getSortedGraph() const
const NamedDecl * getDecl() const
bool init(AnalysisDeclContext &AC)
const CFG * getGraph() const
CapabilityExpr operator!() const
bool shouldIgnore() const
CapabilityExpr(const til::SExpr *E, StringRef Kind, bool Neg, bool Reentrant)
CapabilityExpr(const til::SExpr *, T, bool, bool)=delete
bool matches(const CapabilityExpr &other) const
bool partiallyMatches(const CapabilityExpr &other) const
bool equals(const CapabilityExpr &other) const
const til::SExpr * sexpr() const
bool matchesUniv(const CapabilityExpr &CapE) const
std::string toString() const
const ValueDecl * valueDecl() const
StringRef getKind() const
const til::SCFG * getCFG() const
CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D, const Expr *DeclExp, til::SExpr *Self=nullptr)
Translate a clang expression in an attribute to a til::SExpr.
til::SExpr * translate(const Stmt *S, CallingContext *Ctx)
SExprBuilder(til::MemRegionRef A)
til::SExpr * lookupStmt(const Stmt *S)
til::SCFG * buildCFG(CFGWalker &Walker)
til::LiteralPtr * createVariable(const VarDecl *VD)
til::BasicBlock * lookupBlock(const CFGBlock *B)
A basic block is part of an SCFG.
static bool compareExprs(const SExpr *E1, const SExpr *E2)
A Literal pointer to an object allocated in memory.
static bool compareExprs(const SExpr *E1, const SExpr *E2)
static void print(const SExpr *E, std::ostream &SS)
An SCFG is a control-flow graph.
Base class for AST nodes in the typed intermediate language.
@ VK_SFun
SFunction (self) parameter.
void setKind(VariableKind K)
bool matches(const til::SExpr *E1, const til::SExpr *E2)
bool equals(const til::SExpr *E1, const til::SExpr *E2)
std::string toString(const til::SExpr *E)
bool partiallyMatches(const til::SExpr *E1, const til::SExpr *E2)
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
void printSCFG(CFGWalker &Walker)
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
const FunctionProtoType * T
Encapsulates the lexical context of a function call.
llvm::PointerUnion< const Expr *const *, til::SExpr * > FunArgs
const NamedDecl * AttrDecl
CallingContext(CallingContext *P, const NamedDecl *D=nullptr)
llvm::PointerUnion< const Expr *, til::SExpr * > SelfArg