]> granicus.if.org Git - clang/blob - include/clang/Analysis/Analyses/ThreadSafetyTIL.h
Some minor improvements to the thread safety intermediate language -- mostly const...
[clang] / include / clang / Analysis / Analyses / ThreadSafetyTIL.h
1 //===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a simple intermediate language that is used by the
11 // thread safety analysis (See ThreadSafety.cpp).  The thread safety analysis
12 // works by comparing mutex expressions, e.g.
13 //
14 // class A { Mutex mu; int dat GUARDED_BY(this->mu); }
15 // class B { A a; }
16 //
17 // void foo(B* b) {
18 //   (*b).a.mu.lock();     // locks (*b).a.mu
19 //   b->a.dat = 0;         // substitute &b->a for 'this';
20 //                         // requires lock on (&b->a)->mu
21 //   (b->a.mu).unlock();   // unlocks (b->a.mu)
22 // }
23 //
24 // As illustrated by the above example, clang Exprs are not well-suited to
25 // represent mutex expressions directly, since there is no easy way to compare
26 // Exprs for equivalence.  The thread safety analysis thus lowers clang Exprs
27 // into a simple intermediate language (IL).  The IL supports:
28 //
29 // (1) comparisons for semantic equality of expressions
30 // (2) SSA renaming of variables
31 // (3) wildcards and pattern matching over expressions
32 // (4) hash-based expression lookup
33 //
34 // The IL is currently very experimental, is intended only for use within
35 // the thread safety analysis, and is subject to change without notice.
36 // After the API stabilizes and matures, it may be appropriate to make this
37 // more generally available to other analyses.
38 //
39 // UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
40 //
41 //===----------------------------------------------------------------------===//
42
43 #ifndef LLVM_CLANG_THREAD_SAFETY_TIL_H
44 #define LLVM_CLANG_THREAD_SAFETY_TIL_H
45
46 #include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
47 #include "clang/AST/ExprCXX.h"
48 #include "llvm/ADT/StringRef.h"
49 #include "llvm/Support/Compiler.h"
50
51 #include <cassert>
52 #include <cstddef>
53 #include <utility>
54
55
56 namespace clang {
57 namespace threadSafety {
58 namespace til {
59
60 using llvm::StringRef;
61 using clang::SourceLocation;
62
63
64 enum TIL_Opcode {
65 #define TIL_OPCODE_DEF(X) COP_##X,
66 #include "clang/Analysis/Analyses/ThreadSafetyOps.def"
67 #undef TIL_OPCODE_DEF
68   COP_MAX
69 };
70
71
72 typedef clang::BinaryOperatorKind TIL_BinaryOpcode;
73 typedef clang::UnaryOperatorKind TIL_UnaryOpcode;
74 typedef clang::CastKind TIL_CastOpcode;
75
76
77 enum TraversalKind {
78   TRV_Normal,
79   TRV_Lazy, // subexpression may need to be traversed lazily
80   TRV_Tail  // subexpression occurs in a tail position
81 };
82
83
84 // Base class for AST nodes in the typed intermediate language.
85 class SExpr {
86 public:
87   TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
88
89   // Subclasses of SExpr must define the following:
90   //
91   // This(const This& E, ...) {
92   //   copy constructor: construct copy of E, with some additional arguments.
93   // }
94   //
95   // template <class V> typename V::R_SExpr traverse(V &Visitor) {
96   //   traverse all subexpressions, following the traversal/rewriter interface
97   // }
98   //
99   // template <class C> typename C::CType compare(CType* E, C& Cmp) {
100   //   compare all subexpressions, following the comparator interface
101   // }
102
103   void *operator new(size_t S, clang::threadSafety::til::MemRegionRef &R) {
104     return ::operator new(S, R);
105   }
106
107 protected:
108   SExpr(TIL_Opcode Op) : Opcode(Op), Reserved(0), Flags(0) {}
109   SExpr(const SExpr &E) : Opcode(E.Opcode), Reserved(0), Flags(E.Flags) {}
110
111   const unsigned char Opcode;
112   unsigned char Reserved;
113   unsigned short Flags;
114
115 private:
116   SExpr() LLVM_DELETED_FUNCTION;
117
118   // SExpr objects must be created in an arena and cannot be deleted.
119   void *operator new(size_t) LLVM_DELETED_FUNCTION;
120   void operator delete(void *) LLVM_DELETED_FUNCTION;
121 };
122
123
124 // Class for owning references to SExprs.
125 // Includes attach/detach logic for counting variable references and lazy
126 // rewriting strategies.
127 class SExprRef {
128 public:
129   SExprRef() : Ptr(nullptr) { }
130   SExprRef(std::nullptr_t P) : Ptr(nullptr) { }
131   SExprRef(SExprRef &&R) : Ptr(R.Ptr) { R.Ptr = nullptr; }
132
133   // Defined after Variable and Future, below.
134   inline SExprRef(SExpr *P);
135   inline ~SExprRef();
136
137   SExpr       *get()       { return Ptr; }
138   const SExpr *get() const { return Ptr; }
139
140   SExpr       *operator->()       { return get(); }
141   const SExpr *operator->() const { return get(); }
142
143   SExpr       &operator*()        { return *Ptr; }
144   const SExpr &operator*() const  { return *Ptr; }
145
146   bool operator==(const SExprRef &R) const { return Ptr == R.Ptr; }
147   bool operator!=(const SExprRef &R) const { return !operator==(R); }
148   bool operator==(const SExpr *P) const { return Ptr == P; }
149   bool operator!=(const SExpr *P) const { return !operator==(P); }
150   bool operator==(std::nullptr_t) const { return Ptr == nullptr; }
151   bool operator!=(std::nullptr_t) const { return Ptr != nullptr; }
152
153   inline void reset(SExpr *E);
154
155 private:
156   inline void attach();
157   inline void detach();
158
159   SExpr *Ptr;
160 };
161
162
163 // Contains various helper functions for SExprs.
164 namespace ThreadSafetyTIL {
165   inline bool isTrivial(SExpr *E) {
166     unsigned Op = E->opcode();
167     return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
168   }
169 }
170
171 class Function;
172 class SFunction;
173 class BasicBlock;
174
175
176 // A named variable, e.g. "x".
177 //
178 // There are two distinct places in which a Variable can appear in the AST.
179 // A variable declaration introduces a new variable, and can occur in 3 places:
180 //   Let-expressions:           (Let (x = t) u)
181 //   Functions:                 (Function (x : t) u)
182 //   Self-applicable functions  (SFunction (x) t)
183 //
184 // If a variable occurs in any other location, it is a reference to an existing
185 // variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
186 // allocate a separate AST node for variable references; a reference is just a
187 // pointer to the original declaration.
188 class Variable : public SExpr {
189 public:
190   static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
191
192   // Let-variable, function parameter, or self-variable
193   enum VariableKind {
194     VK_Let,
195     VK_Fun,
196     VK_SFun
197   };
198
199   // These are defined after SExprRef contructor, below
200   inline Variable(VariableKind K, SExpr *D = nullptr,
201                   const clang::ValueDecl *Cvd = nullptr);
202   inline Variable(const clang::ValueDecl *Cvd, SExpr *D = nullptr);
203   inline Variable(const Variable &Vd, SExpr *D);
204
205   VariableKind kind() const { return static_cast<VariableKind>(Flags); }
206
207   const StringRef name() const { return Cvdecl ? Cvdecl->getName() : "_x"; }
208   const clang::ValueDecl *clangDecl() const { return Cvdecl; }
209
210   // Returns the definition (for let vars) or type (for parameter & self vars)
211   SExpr *definition() { return Definition.get(); }
212
213   void attachVar() const { ++NumUses; }
214   void detachVar() const { assert(NumUses > 0); --NumUses; }
215
216   unsigned getID() const { return Id; }
217   unsigned getBlockID() const { return BlockID; }
218
219   void setID(unsigned Bid, unsigned I) {
220     BlockID = static_cast<unsigned short>(Bid);
221     Id = static_cast<unsigned short>(I);
222   }
223
224   template <class V> typename V::R_SExpr traverse(V &Visitor) {
225     // This routine is only called for variable references.
226     return Visitor.reduceVariableRef(this);
227   }
228
229   template <class C> typename C::CType compare(Variable* E, C& Cmp) {
230     return Cmp.compareVariableRefs(this, E);
231   }
232
233 private:
234   friend class Function;
235   friend class SFunction;
236   friend class BasicBlock;
237
238   // Function, SFunction, and BasicBlock will reset the kind.
239   void setKind(VariableKind K) { Flags = K; }
240
241   SExprRef Definition;             // The TIL type or definition
242   const clang::ValueDecl *Cvdecl;  // The clang declaration for this variable.
243
244   unsigned short BlockID;
245   unsigned short Id;
246   mutable unsigned NumUses;
247 };
248
249
250 // Placeholder for an expression that has not yet been created.
251 // Used to implement lazy copy and rewriting strategies.
252 class Future : public SExpr {
253 public:
254   static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
255
256   enum FutureStatus {
257     FS_pending,
258     FS_evaluating,
259     FS_done
260   };
261
262   Future() :
263     SExpr(COP_Future), Status(FS_pending), Result(nullptr), Location(nullptr)
264   {}
265 private:
266   virtual ~Future() LLVM_DELETED_FUNCTION;
267 public:
268
269   // Registers the location in the AST where this future is stored.
270   // Forcing the future will automatically update the AST.
271   static inline void registerLocation(SExprRef *Member) {
272     if (Future *F = dyn_cast_or_null<Future>(Member->get()))
273       F->Location = Member;
274   }
275
276   // A lazy rewriting strategy should subclass Future and override this method.
277   virtual SExpr *create() { return nullptr; }
278
279   // Return the result of this future if it exists, otherwise return null.
280   SExpr *maybeGetResult() {
281     return Result;
282   }
283
284   // Return the result of this future; forcing it if necessary.
285   SExpr *result() {
286     switch (Status) {
287     case FS_pending:
288       force();
289       return Result;
290     case FS_evaluating:
291       return nullptr; // infinite loop; illegal recursion.
292     case FS_done:
293       return Result;
294     }
295   }
296
297   template <class V> typename V::R_SExpr traverse(V &Visitor) {
298     assert(Result && "Cannot traverse Future that has not been forced.");
299     return Visitor.traverse(Result);
300   }
301
302   template <class C> typename C::CType compare(Future* E, C& Cmp) {
303     if (!Result || !E->Result)
304       return Cmp.comparePointers(this, E);
305     return Cmp.compare(Result, E->Result);
306   }
307
308 private:
309   // Force the future.
310   inline void force();
311
312   FutureStatus Status;
313   SExpr *Result;
314   SExprRef *Location;
315 };
316
317 void SExprRef::attach() {
318   if (!Ptr)
319     return;
320
321   TIL_Opcode Op = Ptr->opcode();
322   if (Op == COP_Variable) {
323     cast<Variable>(Ptr)->attachVar();
324   } else if (Op == COP_Future) {
325     cast<Future>(Ptr)->registerLocation(this);
326   }
327 }
328
329 void SExprRef::detach() {
330   if (Ptr && Ptr->opcode() == COP_Variable) {
331     cast<Variable>(Ptr)->detachVar();
332   }
333 }
334
335 SExprRef::SExprRef(SExpr *P) : Ptr(P) {
336   attach();
337 }
338
339 SExprRef::~SExprRef() {
340   detach();
341 }
342
343 void SExprRef::reset(SExpr *P) {
344   detach();
345   Ptr = P;
346   attach();
347 }
348
349
350 Variable::Variable(VariableKind K, SExpr *D, const clang::ValueDecl *Cvd)
351     : SExpr(COP_Variable), Definition(D), Cvdecl(Cvd),
352       BlockID(0), Id(0),  NumUses(0) {
353   Flags = K;
354 }
355
356 Variable::Variable(const clang::ValueDecl *Cvd, SExpr *D)
357     : SExpr(COP_Variable), Definition(D), Cvdecl(Cvd),
358       BlockID(0), Id(0),  NumUses(0) {
359   Flags = VK_Let;
360 }
361
362 Variable::Variable(const Variable &Vd, SExpr *D) // rewrite constructor
363     : SExpr(Vd), Definition(D), Cvdecl(Vd.Cvdecl),
364       BlockID(0), Id(0), NumUses(0) {
365   Flags = Vd.kind();
366 }
367
368 void Future::force() {
369   Status = FS_evaluating;
370   SExpr *R = create();
371   Result = R;
372   if (Location)
373     Location->reset(R);
374   Status = FS_done;
375 }
376
377 // Placeholder for C++ expressions that cannot be represented in the TIL.
378 class Undefined : public SExpr {
379 public:
380   static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
381
382   Undefined(const clang::Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
383   Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
384
385   template <class V> typename V::R_SExpr traverse(V &Visitor) {
386     return Visitor.reduceUndefined(*this);
387   }
388
389   template <class C> typename C::CType compare(Undefined* E, C& Cmp) {
390     return Cmp.comparePointers(Cstmt, E->Cstmt);
391   }
392
393 private:
394   const clang::Stmt *Cstmt;
395 };
396
397
398 // Placeholder for a wildcard that matches any other expression.
399 class Wildcard : public SExpr {
400 public:
401   static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
402
403   Wildcard() : SExpr(COP_Wildcard) {}
404   Wildcard(const Wildcard &W) : SExpr(W) {}
405
406   template <class V> typename V::R_SExpr traverse(V &Visitor) {
407     return Visitor.reduceWildcard(*this);
408   }
409
410   template <class C> typename C::CType compare(Wildcard* E, C& Cmp) {
411     return Cmp.trueResult();
412   }
413 };
414
415
416 // Base class for literal values.
417 class Literal : public SExpr {
418 public:
419   static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
420
421   Literal(const clang::Expr *C) : SExpr(COP_Literal), Cexpr(C) {}
422   Literal(const Literal &L) : SExpr(L), Cexpr(L.Cexpr) {}
423
424   // The clang expression for this literal.
425   const clang::Expr *clangExpr() const { return Cexpr; }
426
427   template <class V> typename V::R_SExpr traverse(V &Visitor) {
428     return Visitor.reduceLiteral(*this);
429   }
430
431   template <class C> typename C::CType compare(Literal* E, C& Cmp) {
432     // TODO -- use value, not pointer equality
433     return Cmp.comparePointers(Cexpr, E->Cexpr);
434   }
435
436 private:
437   const clang::Expr *Cexpr;
438 };
439
440 // Literal pointer to an object allocated in memory.
441 // At compile time, pointer literals are represented by symbolic names.
442 class LiteralPtr : public SExpr {
443 public:
444   static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
445
446   LiteralPtr(const clang::ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
447   LiteralPtr(const LiteralPtr &R) : SExpr(R), Cvdecl(R.Cvdecl) {}
448
449   // The clang declaration for the value that this pointer points to.
450   const clang::ValueDecl *clangDecl() const { return Cvdecl; }
451
452   template <class V> typename V::R_SExpr traverse(V &Visitor) {
453     return Visitor.reduceLiteralPtr(*this);
454   }
455
456   template <class C> typename C::CType compare(LiteralPtr* E, C& Cmp) {
457     return Cmp.comparePointers(Cvdecl, E->Cvdecl);
458   }
459
460 private:
461   const clang::ValueDecl *Cvdecl;
462 };
463
464 // A function -- a.k.a. lambda abstraction.
465 // Functions with multiple arguments are created by currying,
466 // e.g. (function (x: Int) (function (y: Int) (add x y)))
467 class Function : public SExpr {
468 public:
469   static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
470
471   Function(Variable *Vd, SExpr *Bd)
472       : SExpr(COP_Function), VarDecl(Vd), Body(Bd) {
473     Vd->setKind(Variable::VK_Fun);
474   }
475   Function(const Function &F, Variable *Vd, SExpr *Bd) // rewrite constructor
476       : SExpr(F), VarDecl(Vd), Body(Bd) {
477     Vd->setKind(Variable::VK_Fun);
478   }
479
480   Variable *variableDecl()  { return VarDecl; }
481   const Variable *variableDecl() const { return VarDecl; }
482
483   SExpr *body() { return Body.get(); }
484   const SExpr *body() const { return Body.get(); }
485
486   template <class V> typename V::R_SExpr traverse(V &Visitor) {
487     // This is a variable declaration, so traverse the definition.
488     typename V::R_SExpr E0 = Visitor.traverse(VarDecl->Definition, TRV_Lazy);
489     // Tell the rewriter to enter the scope of the function.
490     Variable *Nvd = Visitor.enterScope(*VarDecl, E0);
491     typename V::R_SExpr E1 = Visitor.traverse(Body);
492     Visitor.exitScope(*VarDecl);
493     return Visitor.reduceFunction(*this, Nvd, E1);
494   }
495
496   template <class C> typename C::CType compare(Function* E, C& Cmp) {
497     typename C::CType Ct =
498       Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
499     if (Cmp.notTrue(Ct))
500       return Ct;
501     Cmp.enterScope(variableDecl(), E->variableDecl());
502     Ct = Cmp.compare(body(), E->body());
503     Cmp.leaveScope();
504     return Ct;
505   }
506
507 private:
508   Variable *VarDecl;
509   SExprRef Body;
510 };
511
512
513 // A self-applicable function.
514 // A self-applicable function can be applied to itself.  It's useful for
515 // implementing objects and late binding
516 class SFunction : public SExpr {
517 public:
518   static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
519
520   SFunction(Variable *Vd, SExpr *B)
521       : SExpr(COP_SFunction), VarDecl(Vd), Body(B) {
522     assert(Vd->Definition == nullptr);
523     Vd->setKind(Variable::VK_SFun);
524     Vd->Definition.reset(this);
525   }
526   SFunction(const SFunction &F, Variable *Vd, SExpr *B) // rewrite constructor
527       : SExpr(F), VarDecl(Vd), Body(B) {
528     assert(Vd->Definition == nullptr);
529     Vd->setKind(Variable::VK_SFun);
530     Vd->Definition.reset(this);
531   }
532
533   Variable *variableDecl() { return VarDecl; }
534   const Variable *variableDecl() const { return VarDecl; }
535
536   SExpr *body() { return Body.get(); }
537   const SExpr *body() const { return Body.get(); }
538
539   template <class V> typename V::R_SExpr traverse(V &Visitor) {
540     // A self-variable points to the SFunction itself.
541     // A rewrite must introduce the variable with a null definition, and update
542     // it after 'this' has been rewritten.
543     Variable *Nvd = Visitor.enterScope(*VarDecl, nullptr /* def */);
544     typename V::R_SExpr E1 = Visitor.traverse(Body);
545     Visitor.exitScope(*VarDecl);
546     // A rewrite operation will call SFun constructor to set Vvd->Definition.
547     return Visitor.reduceSFunction(*this, Nvd, E1);
548   }
549
550   template <class C> typename C::CType compare(SFunction* E, C& Cmp) {
551     Cmp.enterScope(variableDecl(), E->variableDecl());
552     typename C::CType Ct = Cmp.compare(body(), E->body());
553     Cmp.leaveScope();
554     return Ct;
555   }
556
557 private:
558   Variable *VarDecl;
559   SExprRef Body;
560 };
561
562
563 // A block of code -- e.g. the body of a function.
564 class Code : public SExpr {
565 public:
566   static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
567
568   Code(SExpr *T, SExpr *B) : SExpr(COP_Code), ReturnType(T), Body(B) {}
569   Code(const Code &C, SExpr *T, SExpr *B) // rewrite constructor
570       : SExpr(C), ReturnType(T), Body(B) {}
571
572   SExpr *returnType() { return ReturnType.get(); }
573   const SExpr *returnType() const { return ReturnType.get(); }
574
575   SExpr *body() { return Body.get(); }
576   const SExpr *body() const { return Body.get(); }
577
578   template <class V> typename V::R_SExpr traverse(V &Visitor) {
579     typename V::R_SExpr Nt = Visitor.traverse(ReturnType, TRV_Lazy);
580     typename V::R_SExpr Nb = Visitor.traverse(Body, TRV_Lazy);
581     return Visitor.reduceCode(*this, Nt, Nb);
582   }
583
584   template <class C> typename C::CType compare(Code* E, C& Cmp) {
585     typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
586     if (Cmp.notTrue(Ct))
587       return Ct;
588     return Cmp.compare(body(), E->body());
589   }
590
591 private:
592   SExprRef ReturnType;
593   SExprRef Body;
594 };
595
596
597 // Apply an argument to a function
598 class Apply : public SExpr {
599 public:
600   static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
601
602   Apply(SExpr *F, SExpr *A) : SExpr(COP_Apply), Fun(F), Arg(A) {}
603   Apply(const Apply &A, SExpr *F, SExpr *Ar)  // rewrite constructor
604       : SExpr(A), Fun(F), Arg(Ar)
605   {}
606
607   SExpr *fun() { return Fun.get(); }
608   const SExpr *fun() const { return Fun.get(); }
609
610   SExpr *arg() { return Arg.get(); }
611   const SExpr *arg() const { return Arg.get(); }
612
613   template <class V> typename V::R_SExpr traverse(V &Visitor) {
614     typename V::R_SExpr Nf = Visitor.traverse(Fun);
615     typename V::R_SExpr Na = Visitor.traverse(Arg);
616     return Visitor.reduceApply(*this, Nf, Na);
617   }
618
619   template <class C> typename C::CType compare(Apply* E, C& Cmp) {
620     typename C::CType Ct = Cmp.compare(fun(), E->fun());
621     if (Cmp.notTrue(Ct))
622       return Ct;
623     return Cmp.compare(arg(), E->arg());
624   }
625
626 private:
627   SExprRef Fun;
628   SExprRef Arg;
629 };
630
631
632 // Apply a self-argument to a self-applicable function
633 class SApply : public SExpr {
634 public:
635   static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
636
637   SApply(SExpr *Sf, SExpr *A = nullptr) : SExpr(COP_SApply), Sfun(Sf), Arg(A) {}
638   SApply(SApply &A, SExpr *Sf, SExpr *Ar = nullptr) // rewrite constructor
639       : SExpr(A), Sfun(Sf), Arg(Ar) {}
640
641   SExpr *sfun() { return Sfun.get(); }
642   const SExpr *sfun() const { return Sfun.get(); }
643
644   SExpr *arg() { return Arg.get() ? Arg.get() : Sfun.get(); }
645   const SExpr *arg() const { return Arg.get() ? Arg.get() : Sfun.get(); }
646
647   bool isDelegation() const { return Arg == nullptr; }
648
649   template <class V> typename V::R_SExpr traverse(V &Visitor) {
650     typename V::R_SExpr Nf = Visitor.traverse(Sfun);
651     typename V::R_SExpr Na = Arg.get() ? Visitor.traverse(Arg) : nullptr;
652     return Visitor.reduceSApply(*this, Nf, Na);
653   }
654
655   template <class C> typename C::CType compare(SApply* E, C& Cmp) {
656     typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
657     if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
658       return Ct;
659     return Cmp.compare(arg(), E->arg());
660   }
661
662 private:
663   SExprRef Sfun;
664   SExprRef Arg;
665 };
666
667
668 // Project a named slot from a C++ struct or class.
669 class Project : public SExpr {
670 public:
671   static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
672
673   Project(SExpr *R, clang::ValueDecl *Cvd)
674       : SExpr(COP_Project), Rec(R), Cvdecl(Cvd) {}
675   Project(const Project &P, SExpr *R) : SExpr(P), Rec(R), Cvdecl(P.Cvdecl) {}
676
677   SExpr *record() { return Rec.get(); }
678   const SExpr *record() const { return Rec.get(); }
679
680   const clang::ValueDecl *clangValueDecl() const { return Cvdecl; }
681
682   StringRef slotName() const { return Cvdecl->getName(); }
683
684   template <class V> typename V::R_SExpr traverse(V &Visitor) {
685     typename V::R_SExpr Nr = Visitor.traverse(Rec);
686     return Visitor.reduceProject(*this, Nr);
687   }
688
689   template <class C> typename C::CType compare(Project* E, C& Cmp) {
690     typename C::CType Ct = Cmp.compare(record(), E->record());
691     if (Cmp.notTrue(Ct))
692       return Ct;
693     return Cmp.comparePointers(Cvdecl, E->Cvdecl);
694   }
695
696 private:
697   SExprRef Rec;
698   clang::ValueDecl *Cvdecl;
699 };
700
701
702 // Call a function (after all arguments have been applied).
703 class Call : public SExpr {
704 public:
705   static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
706
707   Call(SExpr *T, const clang::CallExpr *Ce = nullptr)
708       : SExpr(COP_Call), Target(T), Cexpr(Ce) {}
709   Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
710
711   SExpr *target() { return Target.get(); }
712   const SExpr *target() const { return Target.get(); }
713
714   const clang::CallExpr *clangCallExpr() const { return Cexpr; }
715
716   template <class V> typename V::R_SExpr traverse(V &Visitor) {
717     typename V::R_SExpr Nt = Visitor.traverse(Target);
718     return Visitor.reduceCall(*this, Nt);
719   }
720
721   template <class C> typename C::CType compare(Call* E, C& Cmp) {
722     return Cmp.compare(target(), E->target());
723   }
724
725 private:
726   SExprRef Target;
727   const clang::CallExpr *Cexpr;
728 };
729
730
731 // Allocate memory for a new value on the heap or stack.
732 class Alloc : public SExpr {
733 public:
734   static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
735
736   enum AllocKind {
737     AK_Stack,
738     AK_Heap
739   };
740
741   Alloc(SExpr *D, AllocKind K) : SExpr(COP_Alloc), Dtype(D) { Flags = K; }
742   Alloc(const Alloc &A, SExpr *Dt) : SExpr(A), Dtype(Dt) { Flags = A.kind(); }
743
744   AllocKind kind() const { return static_cast<AllocKind>(Flags); }
745
746   SExpr *dataType() { return Dtype.get(); }
747   const SExpr *dataType() const { return Dtype.get(); }
748
749   template <class V> typename V::R_SExpr traverse(V &Visitor) {
750     typename V::R_SExpr Nd = Visitor.traverse(Dtype);
751     return Visitor.reduceAlloc(*this, Nd);
752   }
753
754   template <class C> typename C::CType compare(Alloc* E, C& Cmp) {
755     typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
756     if (Cmp.notTrue(Ct))
757       return Ct;
758     return Cmp.compare(dataType(), E->dataType());
759   }
760
761 private:
762   SExprRef Dtype;
763 };
764
765
766 // Load a value from memory.
767 class Load : public SExpr {
768 public:
769   static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
770
771   Load(SExpr *P) : SExpr(COP_Load), Ptr(P) {}
772   Load(const Load &L, SExpr *P) : SExpr(L), Ptr(P) {}
773
774   SExpr *pointer() { return Ptr.get(); }
775   const SExpr *pointer() const { return Ptr.get(); }
776
777   template <class V> typename V::R_SExpr traverse(V &Visitor) {
778     typename V::R_SExpr Np = Visitor.traverse(Ptr);
779     return Visitor.reduceLoad(*this, Np);
780   }
781
782   template <class C> typename C::CType compare(Load* E, C& Cmp) {
783     return Cmp.compare(pointer(), E->pointer());
784   }
785
786 private:
787   SExprRef Ptr;
788 };
789
790
791 // Store a value to memory.
792 class Store : public SExpr {
793 public:
794   static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
795
796   Store(SExpr *P, SExpr *V) : SExpr(COP_Store), Dest(P), Source(V) {}
797   Store(const Store &S, SExpr *P, SExpr *V) : SExpr(S), Dest(P), Source(V) {}
798
799   SExpr *destination() { return Dest.get(); }  // Address to store to
800   const SExpr *destination() const { return Dest.get(); }
801
802   SExpr *source() { return Source.get(); }     // Value to store
803   const SExpr *source() const { return Source.get(); }
804
805   template <class V> typename V::R_SExpr traverse(V &Visitor) {
806     typename V::R_SExpr Np = Visitor.traverse(Dest);
807     typename V::R_SExpr Nv = Visitor.traverse(Source);
808     return Visitor.reduceStore(*this, Np, Nv);
809   }
810
811   template <class C> typename C::CType compare(Store* E, C& Cmp) {
812     typename C::CType Ct = Cmp.compare(destination(), E->destination());
813     if (Cmp.notTrue(Ct))
814       return Ct;
815     return Cmp.compare(source(), E->source());
816   }
817
818 private:
819   SExprRef Dest;
820   SExprRef Source;
821 };
822
823
824 // Simple unary operation -- e.g. !, ~, etc.
825 class UnaryOp : public SExpr {
826 public:
827   static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
828
829   UnaryOp(TIL_UnaryOpcode Op, SExpr *E) : SExpr(COP_UnaryOp), Expr0(E) {
830     Flags = Op;
831   }
832   UnaryOp(const UnaryOp &U, SExpr *E) : SExpr(U) { Flags = U.Flags; }
833
834   TIL_UnaryOpcode unaryOpcode() const {
835     return static_cast<TIL_UnaryOpcode>(Flags);
836   }
837
838   SExpr *expr() { return Expr0.get(); }
839   const SExpr *expr() const { return Expr0.get(); }
840
841   template <class V> typename V::R_SExpr traverse(V &Visitor) {
842     typename V::R_SExpr Ne = Visitor.traverse(Expr0);
843     return Visitor.reduceUnaryOp(*this, Ne);
844   }
845
846   template <class C> typename C::CType compare(UnaryOp* E, C& Cmp) {
847     typename C::CType Ct =
848       Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
849     if (Cmp.notTrue(Ct))
850       return Ct;
851     return Cmp.compare(expr(), E->expr());
852   }
853
854 private:
855   SExprRef Expr0;
856 };
857
858
859 // Simple binary operation -- e.g. +, -, etc.
860 class BinaryOp : public SExpr {
861 public:
862   static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
863
864   BinaryOp(TIL_BinaryOpcode Op, SExpr *E0, SExpr *E1)
865       : SExpr(COP_BinaryOp), Expr0(E0), Expr1(E1) {
866     Flags = Op;
867   }
868   BinaryOp(const BinaryOp &B, SExpr *E0, SExpr *E1)
869       : SExpr(B), Expr0(E0), Expr1(E1) {
870     Flags = B.Flags;
871   }
872
873   TIL_BinaryOpcode binaryOpcode() const {
874     return static_cast<TIL_BinaryOpcode>(Flags);
875   }
876
877   SExpr *expr0() { return Expr0.get(); }
878   const SExpr *expr0() const { return Expr0.get(); }
879
880   SExpr *expr1() { return Expr1.get(); }
881   const SExpr *expr1() const { return Expr1.get(); }
882
883   template <class V> typename V::R_SExpr traverse(V &Visitor) {
884     typename V::R_SExpr Ne0 = Visitor.traverse(Expr0);
885     typename V::R_SExpr Ne1 = Visitor.traverse(Expr1);
886     return Visitor.reduceBinaryOp(*this, Ne0, Ne1);
887   }
888
889   template <class C> typename C::CType compare(BinaryOp* E, C& Cmp) {
890     typename C::CType Ct =
891       Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
892     if (Cmp.notTrue(Ct))
893       return Ct;
894     Ct = Cmp.compare(expr0(), E->expr0());
895     if (Cmp.notTrue(Ct))
896       return Ct;
897     return Cmp.compare(expr1(), E->expr1());
898   }
899
900 private:
901   SExprRef Expr0;
902   SExprRef Expr1;
903 };
904
905
906 // Cast expression
907 class Cast : public SExpr {
908 public:
909   static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
910
911   Cast(TIL_CastOpcode Op, SExpr *E) : SExpr(COP_Cast), Expr0(E) { Flags = Op; }
912   Cast(const Cast &C, SExpr *E) : SExpr(C), Expr0(E) { Flags = C.Flags; }
913
914   TIL_CastOpcode castOpcode() const {
915     return static_cast<TIL_CastOpcode>(Flags);
916   }
917
918   SExpr *expr() { return Expr0.get(); }
919   const SExpr *expr() const { return Expr0.get(); }
920
921   template <class V> typename V::R_SExpr traverse(V &Visitor) {
922     typename V::R_SExpr Ne = Visitor.traverse(Expr0);
923     return Visitor.reduceCast(*this, Ne);
924   }
925
926   template <class C> typename C::CType compare(Cast* E, C& Cmp) {
927     typename C::CType Ct =
928       Cmp.compareIntegers(castOpcode(), E->castOpcode());
929     if (Cmp.notTrue(Ct))
930       return Ct;
931     return Cmp.compare(expr(), E->expr());
932   }
933
934 private:
935   SExprRef Expr0;
936 };
937
938 class BasicBlock;
939
940 // An SCFG is a control-flow graph.  It consists of a set of basic blocks, each
941 // of which terminates in a branch to another basic block.  There is one
942 // entry point, and one exit point.
943 class SCFG : public SExpr {
944 public:
945   typedef SimpleArray<BasicBlock *> BlockArray;
946   typedef BlockArray::iterator iterator;
947   typedef BlockArray::const_iterator const_iterator;
948
949   static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
950
951   SCFG(MemRegionRef A, unsigned Nblocks)
952       : SExpr(COP_SCFG), Blocks(A, Nblocks), Entry(nullptr), Exit(nullptr) {}
953   SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
954       : SExpr(COP_SCFG), Blocks(std::move(Ba)), Entry(nullptr), Exit(nullptr) {
955     // TODO: set entry and exit!
956   }
957
958   iterator begin() { return Blocks.begin(); }
959   iterator end() { return Blocks.end(); }
960
961   const_iterator begin() const { return cbegin(); }
962   const_iterator end() const { return cend(); }
963
964   const_iterator cbegin() const { return Blocks.cbegin(); }
965   const_iterator cend() const { return Blocks.cend(); }
966
967   const BasicBlock *entry() const { return Entry; }
968   BasicBlock *entry() { return Entry; }
969   const BasicBlock *exit() const { return Exit; }
970   BasicBlock *exit() { return Exit; }
971
972   void add(BasicBlock *BB) { Blocks.push_back(BB); }
973   void setEntry(BasicBlock *BB) { Entry = BB; }
974   void setExit(BasicBlock *BB) { Exit = BB; }
975
976   template <class V> typename V::R_SExpr traverse(V &Visitor);
977
978   template <class C> typename C::CType compare(SCFG *E, C &Cmp) {
979     // TODO -- implement CFG comparisons
980     return Cmp.comparePointers(this, E);
981   }
982
983 private:
984   BlockArray Blocks;
985   BasicBlock *Entry;
986   BasicBlock *Exit;
987 };
988
989
990 // A basic block is part of an SCFG, and can be treated as a function in
991 // continuation passing style.  It consists of a sequence of phi nodes, which
992 // are "arguments" to the function, followed by a sequence of instructions.
993 // Both arguments and instructions define new variables.  It ends with a
994 // branch or goto to another basic block in the same SCFG.
995 class BasicBlock {
996 public:
997   typedef SimpleArray<Variable*> VarArray;
998
999   BasicBlock(MemRegionRef A, unsigned Nargs, unsigned Nins,
1000              SExpr *Term = nullptr)
1001       : BlockID(0), Parent(nullptr), Args(A, Nargs), Instrs(A, Nins),
1002         Terminator(Term) {}
1003   BasicBlock(const BasicBlock &B, VarArray &&As, VarArray &&Is, SExpr *T)
1004       : BlockID(0), Parent(nullptr), Args(std::move(As)), Instrs(std::move(Is)),
1005         Terminator(T) {}
1006
1007   unsigned blockID() const { return BlockID; }
1008   const BasicBlock *parent() const { return Parent; }
1009   BasicBlock *parent() { return Parent; }
1010
1011   const VarArray &arguments() const { return Args; }
1012   VarArray &arguments() { return Args; }
1013
1014   const VarArray &instructions() const { return Instrs; }
1015   VarArray &instructions() { return Instrs; }
1016
1017   const SExpr *terminator() const { return Terminator.get(); }
1018   SExpr *terminator() { return Terminator.get(); }
1019
1020   void setParent(BasicBlock *P) { Parent = P; }
1021   void setBlockID(unsigned i) { BlockID = i; }
1022   void setTerminator(SExpr *E) { Terminator.reset(E); }
1023   void addArgument(Variable *V) { Args.push_back(V); }
1024   void addInstr(Variable *V) { Args.push_back(V); }
1025
1026   template <class V> BasicBlock *traverse(V &Visitor) {
1027     typename V::template Container<Variable*> Nas(Visitor, Args.size());
1028     typename V::template Container<Variable*> Nis(Visitor, Instrs.size());
1029
1030     for (auto *A : Args) {
1031       typename V::R_SExpr Ne = Visitor.traverse(A->Definition);
1032       Variable *Nvd = Visitor.enterScope(*A, Ne);
1033       Nas.push_back(Nvd);
1034     }
1035     for (auto *I : Instrs) {
1036       typename V::R_SExpr Ne = Visitor.traverse(I->Definition);
1037       Variable *Nvd = Visitor.enterScope(*I, Ne);
1038       Nis.push_back(Nvd);
1039     }
1040     typename V::R_SExpr Nt = Visitor.traverse(Terminator);
1041
1042     // TODO: use reverse iterator
1043     for (unsigned J = 0, JN = Instrs.size(); J < JN; ++J)
1044       Visitor.exitScope(*Instrs[JN-J]);
1045     for (unsigned I = 0, IN = Instrs.size(); I < IN; ++I)
1046       Visitor.exitScope(*Args[IN-I]);
1047
1048     return Visitor.reduceBasicBlock(*this, Nas, Nis, Nt);
1049   }
1050
1051   template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
1052     // TODO: implement CFG comparisons
1053     return Cmp.comparePointers(this, E);
1054   }
1055
1056 private:
1057   friend class SCFG;
1058
1059   unsigned BlockID;
1060   BasicBlock *Parent;   // The parent block is the enclosing lexical scope.
1061                         // The parent dominates this block.
1062   VarArray Args;        // Phi nodes
1063   VarArray Instrs;
1064   SExprRef Terminator;
1065 };
1066
1067 template <class V>
1068 typename V::R_SExpr SCFG::traverse(V &Visitor) {
1069   Visitor.enterCFG(*this);
1070   typename V::template Container<BasicBlock *> Bbs(Visitor, Blocks.size());
1071   for (auto *B : Blocks) {
1072     BasicBlock *Nbb = B->traverse(Visitor);
1073     Bbs.push_back(Nbb);
1074   }
1075   Visitor.exitCFG(*this);
1076   return Visitor.reduceSCFG(*this, Bbs);
1077 }
1078
1079 class Phi : public SExpr {
1080 public:
1081   // TODO: change to SExprRef
1082   typedef SimpleArray<SExpr *> ValArray;
1083
1084   static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
1085
1086   Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
1087   Phi(const Phi &P, ValArray &&Vs) // steals memory of Vs
1088       : SExpr(COP_Phi), Values(std::move(Vs)) {}
1089
1090   const ValArray &values() const { return Values; }
1091   ValArray &values() { return Values; }
1092
1093   template <class V> typename V::R_SExpr traverse(V &Visitor) {
1094     typename V::template Container<typename V::R_SExpr> Nvs(Visitor,
1095                                                             Values.size());
1096     for (auto *Val : Values) {
1097       typename V::R_SExpr Nv = Visitor.traverse(Val);
1098       Nvs.push_back(Nv);
1099     }
1100     return Visitor.reducePhi(*this, Nvs);
1101   }
1102
1103   template <class C> typename C::CType compare(Phi *E, C &Cmp) {
1104     // TODO -- implement CFG comparisons
1105     return Cmp.comparePointers(this, E);
1106   }
1107
1108 private:
1109   ValArray Values;
1110 };
1111
1112
1113 class Goto : public SExpr {
1114 public:
1115   static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
1116
1117   Goto(BasicBlock *B, unsigned Index)
1118       : SExpr(COP_Goto), TargetBlock(B), Index(0) {}
1119   Goto(const Goto &G, BasicBlock *B, unsigned I)
1120       : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
1121
1122   const BasicBlock *targetBlock() const { return TargetBlock; }
1123   BasicBlock *targetBlock() { return TargetBlock; }
1124
1125   unsigned index() const { return Index; }
1126
1127   template <class V> typename V::R_SExpr traverse(V &Visitor) {
1128     // TODO -- rewrite indices properly
1129     BasicBlock *Ntb = Visitor.reduceBasicBlockRef(TargetBlock);
1130     return Visitor.reduceGoto(*this, Ntb, Index);
1131   }
1132
1133   template <class C> typename C::CType compare(Goto *E, C &Cmp) {
1134     // TODO -- implement CFG comparisons
1135     return Cmp.comparePointers(this, E);
1136   }
1137
1138 private:
1139   BasicBlock *TargetBlock;
1140   unsigned Index;   // Index into Phi nodes of target block.
1141 };
1142
1143
1144 class Branch : public SExpr {
1145 public:
1146   static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
1147
1148   Branch(SExpr *C, BasicBlock *T, BasicBlock *E)
1149       : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E) {}
1150   Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E)
1151       : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E) {}
1152
1153   const SExpr *condition() const { return Condition; }
1154   SExpr *condition() { return Condition; }
1155   const BasicBlock *thenBlock() const { return ThenBlock; }
1156   BasicBlock *thenBlock() { return ThenBlock; }
1157   const BasicBlock *elseBlock() const { return ElseBlock; }
1158   BasicBlock *elseBlock() { return ElseBlock; }
1159
1160   template <class V> typename V::R_SExpr traverse(V &Visitor) {
1161     typename V::R_SExpr Nc = Visitor.traverse(Condition);
1162     BasicBlock *Ntb = Visitor.reduceBasicBlockRef(ThenBlock);
1163     BasicBlock *Nte = Visitor.reduceBasicBlockRef(ElseBlock);
1164     return Visitor.reduceBranch(*this, Nc, Ntb, Nte);
1165   }
1166
1167   template <class C> typename C::CType compare(Branch *E, C &Cmp) {
1168     // TODO -- implement CFG comparisons
1169     return Cmp.comparePointers(this, E);
1170   }
1171
1172 private:
1173   SExpr *Condition;
1174   BasicBlock *ThenBlock;
1175   BasicBlock *ElseBlock;
1176 };
1177
1178
1179 } // end namespace til
1180 } // end namespace threadSafety
1181 } // end namespace clang
1182
1183 #endif // LLVM_CLANG_THREAD_SAFETY_TIL_H