17 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
18 #define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
24 namespace threadSafety {
52 template <
class Self,
class R>
55 Self *
self() {
return static_cast<Self *
>(
this); }
63 typename R::R_SExpr
traverse(T* &
E,
typename R::R_Ctx Ctx) {
76 #define TIL_OPCODE_DEF(X) \
78 return self()->traverse##X(cast<X>(E), Ctx);
79 #include "ThreadSafetyOps.def"
82 return self()->reduceNull();
87 #define TIL_OPCODE_DEF(X) \
88 typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) { \
89 return e->traverse(*self(), Ctx); \
91 #include "ThreadSafetyOps.def"
175 template <
class Self>
283 template <
typename Self>
286 Self *
self() {
return reinterpret_cast<Self *
>(
this); }
291 #define TIL_OPCODE_DEF(X) \
293 return cast<X>(E1)->compare(cast<X>(E2), *self());
294 #include "ThreadSafetyOps.def"
295 #undef TIL_OPCODE_DEF
354 if (E1->
opcode() == COP_Wildcard || E2->
opcode() == COP_Wildcard)
372 return Matcher.
compare(E1, E2);
383 template <
typename Self,
typename StreamType>
392 : Verbose(V), Cleanup(C), CStyle(CS)
397 printer.printSExpr(E, SS,
Prec_MAX);
401 Self *
self() {
return reinterpret_cast<Self *
>(
this); }
447 case COP_BasicBlock:
return Prec_MAX;
479 if (Sub && E->
block() && E->
opcode() != COP_Variable) {
480 SS <<
"_x" << E->
id();
492 #define TIL_OPCODE_DEF(X) \
494 self()->print##X(cast<X>(E), SS); \
496 #include "ThreadSafetyOps.def"
497 #undef TIL_OPCODE_DEF
523 SS <<
"'" << E->
value() <<
"'";
539 if (E->
as<
bool>().value())
616 SS << V->
name() << V->
id();
636 if (B && B->
opcode() == COP_Function)
637 self()->printFunction(cast<Function>(B), SS, 2);
667 if (F->
opcode() == COP_Apply) {
691 if (
const SApply *SAP = dyn_cast<SApply>(E->
record())) {
692 if (
const Variable *V = dyn_cast<Variable>(SAP->sfun())) {
699 if (isa<Wildcard>(E->
record())) {
718 if (T->
opcode() == COP_Apply) {
783 for (
auto BBI : *E) {
793 if (E->
opcode() == COP_Variable) {
794 auto *V = cast<Variable>(
E);
795 SS <<
"let " << V->name() << V->id() <<
" = ";
799 else if (E->
opcode() != COP_Store) {
800 SS <<
"let _x" << E->
id() <<
" = ";
808 SS <<
"BB_" << E->
blockID() <<
":";
834 for (
auto V : E->
values()) {
902 #endif // LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1)
Simple arithmetic unary operations, e.g.
Apply a self-argument to a self-applicable function.
Pointer arithmetic, restricted to arrays only.
StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op)
Return the name of a binary opcode.
R_SExpr reduceCall(Call &Orig, R_SExpr E0)
R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1)
void printSExpr(const SExpr *E, StreamType &SS, unsigned P, bool Sub=true)
void printVariable(const Variable *V, StreamType &SS, bool IsVarDecl=false)
R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0)
A typed, writable location in memory.
A conditional branch to two other blocks.
bool compareVariableRefs(const Variable *V1, const Variable *V2)
ValueTypes are data types that can actually be held in registers.
CopyReducerBase(MemRegionRef A)
void printStore(const Store *E, StreamType &SS)
R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1)
static const unsigned Prec_Unary
const ValArray & values() const
static const unsigned Prec_MAX
const BasicBlock * parent() const
BasicBlock * R_BasicBlock
void printCall(const Call *E, StreamType &SS)
R::R_SExpr traverse(T *&E, typename R::R_Ctx Ctx)
R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1)
bool compareIntegers(unsigned i, unsigned j)
const DynTypedMatcher *const Matcher
static const unsigned Prec_Atom
BasicBlock * reduceBasicBlockRef(BasicBlock *Obb)
R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E)
void printWildcard(const Wildcard *E, StreamType &SS)
Variable * variableDecl()
static const unsigned Prec_Decl
R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1)
If p is a reference to an array, then p[i] is a reference to the i'th element of the array...
R_SExpr reduceUndefined(Undefined &Orig)
InstrArray & instructions()
Project a named slot from a C++ struct or class.
R::R_SExpr traverseSExpr(SExpr *E, typename R::R_Ctx Ctx)
void printUndefined(const Undefined *E, StreamType &SS)
Container(VisitReducerBase &S, unsigned N)
R_Ctx subExprCtx(R_Ctx Ctx)
R_SExpr reduceProject(Project &Orig, R_SExpr E0)
const SExpr * condition() const
R_SExpr reducePhi(Phi &Orig, Container< R_SExpr > &As)
R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx)
void printReturn(const Return *E, StreamType &SS)
void printLiteralT(const LiteralT< uint8_t > *E, StreamType &SS)
static const unsigned Prec_Other
void printBinaryOp(const BinaryOp *E, StreamType &SS)
Variable * reduceVariableRef(Variable *Ovd)
R_SExpr reduceReturn(Return &O, R_SExpr E)
void printSFunction(const SFunction *E, StreamType &SS)
static void print(const SExpr *E, StreamType &SS)
void printFunction(const Function *E, StreamType &SS, unsigned sugared=0)
bool compareVariableRefs(const Variable *V1, const Variable *V2)
R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B)
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
A basic block is part of an SCFG.
void printArrayAdd(const ArrayAdd *E, StreamType &SS)
detail::InMemoryDirectory::const_iterator I
void printArrayIndex(const ArrayIndex *E, StreamType &SS)
Placeholder for expressions that cannot be represented in the TIL.
bool traverse(SExpr *E, TraversalKind K=TRV_Normal)
R_SExpr reduceCast(Cast &Orig, R_SExpr E0)
A self-applicable function.
unsigned precedence(const SExpr *E)
An SCFG is a control-flow graph.
R_SExpr reduceLoad(Load &Orig, R_SExpr E0)
TIL_Opcode opcode() const
void printNull(StreamType &SS)
R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1)
void printLiteral(const Literal *E, StreamType &SS)
PrettyPrinter(bool V=false, bool C=true, bool CS=true)
void enterBasicBlock(BasicBlock &BB)
Container(CopyReducerBase &S, unsigned N)
void printField(const Field *E, StreamType &SS)
Apply an argument to a function.
void printBranch(const Branch *E, StreamType &SS)
StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op)
Return the name of a unary opcode.
unsigned id() const
Returns the instruction ID for this expression.
const InstrArray & arguments() const
const clang::Expr * clangExpr() const
void enterScope(const Variable *V1, const Variable *V2)
bool compare(const SExpr *E1, const SExpr *E2)
ValueType valueType() const
bool compareByCase(const SExpr *E1, const SExpr *E2)
R_SExpr reduceLiteralT(LiteralT< T > &Orig)
Jump to another basic block.
R_SExpr reduceIdentifier(Identifier &Orig)
void printCast(const Cast *E, StreamType &SS)
Return from the enclosing function, passing the return value to the caller.
StringRef name() const
Return the name of the variable, if any.
R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0)
static bool compareExprs(const SExpr *E1, const SExpr *E2)
bool compareIntegers(unsigned i, unsigned j)
void enterScope(const Variable *V1, const Variable *V2)
void printGoto(const Goto *E, StreamType &SS)
void printBasicBlock(const BasicBlock *E, StreamType &SS)
R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1)
BasicBlock * block() const
Returns the block, if this is an instruction in a basic block, otherwise returns null.
void printFuture(const Future *E, StreamType &SS)
const Terminator * terminator() const
void printLet(const Let *E, StreamType &SS)
void exitBasicBlock(BasicBlock &BB)
TIL_BinaryOpcode binaryOpcode() const
bool compareStrings(StringRef s, StringRef r)
const clang::ValueDecl * clangDecl() const
bool isDelegation() const
void printBBInstr(const SExpr *E, StreamType &SS)
void newline(StreamType &SS)
bool comparePointers(const void *P, const void *Q)
static const unsigned Prec_Binary
const LiteralT< T > & as() const
R_SExpr reduceWildcard(Wildcard &Orig)
const clang::ValueDecl * clangDecl() const
R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0)
std::string getSourceLiteralString(const clang::Expr *CE)
Placeholder for a wildcard that matches any other expression.
void printApply(const Apply *E, StreamType &SS, bool sugared=false)
unsigned index() const
Returns the index into the.
TIL_UnaryOpcode unaryOpcode() const
const BasicBlock * targetBlock() const
StringRef slotName() const
Load a value from memory.
Allocate memory for a new value on the heap or stack.
void printSApply(const SApply *E, StreamType &SS)
int blockID() const
Returns the block ID. Every block has a unique ID in the CFG.
void printSCFG(const SCFG *E, StreamType &SS)
void printUnaryOp(const UnaryOp *E, StreamType &SS)
An if-then-else expression.
R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0)
Variable * variableDecl()
detail::InMemoryDirectory::const_iterator E
SExpr * maybeGetResult() const
R_SExpr reduceLiteralPtr(Literal &Orig)
Variable * enterScope(Variable &Orig, R_SExpr E0)
R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container< R_SExpr > &As, Container< R_SExpr > &Is, R_SExpr T)
R_SExpr reduceLiteral(Literal &Orig)
Phi Node, for code in SSA form.
const BasicBlock * thenBlock() const
R_SExpr reduceGoto(Goto &Orig, BasicBlock *B)
Simple arithmetic binary operations, e.g.
static const unsigned Prec_Postfix
A block of code – e.g. the body of a function.
void printBlockLabel(StreamType &SS, const BasicBlock *BB, int index)
R_SExpr reduceArrayIndex(Store &Orig, R_SExpr E0, R_SExpr E1)
void printLiteralPtr(const LiteralPtr *E, StreamType &SS)
void printLiteralT(const LiteralT< T > *E, StreamType &SS)
const BasicBlock * elseBlock() const
void printIdentifier(const Identifier *E, StreamType &SS)
std::string getQualifiedNameAsString() const
R_SExpr reduceSCFG(SCFG &Orig, Container< BasicBlock * > Bbs)
R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1)
SExpr * definition()
Return the definition of the variable.
VariableKind kind() const
Return the kind of variable (let, function param, or self)
TIL_CastOpcode castOpcode() const
void printProject(const Project *E, StreamType &SS)
void printAlloc(const Alloc *E, StreamType &SS)
bool compare(const SExpr *E1, const SExpr *E2)
void printIfThenElse(const IfThenElse *E, StreamType &SS)
Placeholder for an expression that has not yet been created.
Base class for AST nodes in the typed intermediate language.
A Literal pointer to an object allocated in memory.
void printPhi(const Phi *E, StreamType &SS)
static bool compareExprs(const SExpr *E1, const SExpr *E2)
static bool visit(SExpr *E)
Call a function (after all arguments have been applied).
Variable * variableDecl()
void printLoad(const Load *E, StreamType &SS)
SFunction (self) parameter.
void exitScope(const Variable &Orig)
bool compareStrings(StringRef s, StringRef r)
bool comparePointers(const void *P, const void *Q)
void printCode(const Code *E, StreamType &SS)