Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- ThreadSafetyTIL.h ----------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines a simple Typed Intermediate Language, or TIL, that is used
10
// by the thread safety analysis (See ThreadSafety.cpp).  The TIL is intended
11
// to be largely independent of clang, in the hope that the analysis can be
12
// reused for other non-C++ languages.  All dependencies on clang/llvm should
13
// go in ThreadSafetyUtil.h.
14
//
15
// Thread safety analysis works by comparing mutex expressions, e.g.
16
//
17
// class A { Mutex mu; int dat GUARDED_BY(this->mu); }
18
// class B { A a; }
19
//
20
// void foo(B* b) {
21
//   (*b).a.mu.lock();     // locks (*b).a.mu
22
//   b->a.dat = 0;         // substitute &b->a for 'this';
23
//                         // requires lock on (&b->a)->mu
24
//   (b->a.mu).unlock();   // unlocks (b->a.mu)
25
// }
26
//
27
// As illustrated by the above example, clang Exprs are not well-suited to
28
// represent mutex expressions directly, since there is no easy way to compare
29
// Exprs for equivalence.  The thread safety analysis thus lowers clang Exprs
30
// into a simple intermediate language (IL).  The IL supports:
31
//
32
// (1) comparisons for semantic equality of expressions
33
// (2) SSA renaming of variables
34
// (3) wildcards and pattern matching over expressions
35
// (4) hash-based expression lookup
36
//
37
// The TIL is currently very experimental, is intended only for use within
38
// the thread safety analysis, and is subject to change without notice.
39
// After the API stabilizes and matures, it may be appropriate to make this
40
// more generally available to other analyses.
41
//
42
// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
43
//
44
//===----------------------------------------------------------------------===//
45
 
46
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
47
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
48
 
49
#include "clang/AST/Decl.h"
50
#include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
51
#include "clang/Basic/LLVM.h"
52
#include "llvm/ADT/ArrayRef.h"
53
#include "llvm/ADT/StringRef.h"
54
#include "llvm/Support/Casting.h"
55
#include "llvm/Support/raw_ostream.h"
56
#include <algorithm>
57
#include <cassert>
58
#include <cstddef>
59
#include <cstdint>
60
#include <iterator>
61
#include <optional>
62
#include <string>
63
#include <utility>
64
 
65
namespace clang {
66
 
67
class CallExpr;
68
class Expr;
69
class Stmt;
70
 
71
namespace threadSafety {
72
namespace til {
73
 
74
class BasicBlock;
75
 
76
/// Enum for the different distinct classes of SExpr
77
enum TIL_Opcode : unsigned char {
78
#define TIL_OPCODE_DEF(X) COP_##X,
79
#include "ThreadSafetyOps.def"
80
#undef TIL_OPCODE_DEF
81
};
82
 
83
/// Opcode for unary arithmetic operations.
84
enum TIL_UnaryOpcode : unsigned char {
85
  UOP_Minus,        //  -
86
  UOP_BitNot,       //  ~
87
  UOP_LogicNot      //  !
88
};
89
 
90
/// Opcode for binary arithmetic operations.
91
enum TIL_BinaryOpcode : unsigned char {
92
  BOP_Add,          //  +
93
  BOP_Sub,          //  -
94
  BOP_Mul,          //  *
95
  BOP_Div,          //  /
96
  BOP_Rem,          //  %
97
  BOP_Shl,          //  <<
98
  BOP_Shr,          //  >>
99
  BOP_BitAnd,       //  &
100
  BOP_BitXor,       //  ^
101
  BOP_BitOr,        //  |
102
  BOP_Eq,           //  ==
103
  BOP_Neq,          //  !=
104
  BOP_Lt,           //  <
105
  BOP_Leq,          //  <=
106
  BOP_Cmp,          //  <=>
107
  BOP_LogicAnd,     //  &&  (no short-circuit)
108
  BOP_LogicOr       //  ||  (no short-circuit)
109
};
110
 
111
/// Opcode for cast operations.
112
enum TIL_CastOpcode : unsigned char {
113
  CAST_none = 0,
114
 
115
  // Extend precision of numeric type
116
  CAST_extendNum,
117
 
118
  // Truncate precision of numeric type
119
  CAST_truncNum,
120
 
121
  // Convert to floating point type
122
  CAST_toFloat,
123
 
124
  // Convert to integer type
125
  CAST_toInt,
126
 
127
  // Convert smart pointer to pointer (C++ only)
128
  CAST_objToPtr
129
};
130
 
131
const TIL_Opcode       COP_Min  = COP_Future;
132
const TIL_Opcode       COP_Max  = COP_Branch;
133
const TIL_UnaryOpcode  UOP_Min  = UOP_Minus;
134
const TIL_UnaryOpcode  UOP_Max  = UOP_LogicNot;
135
const TIL_BinaryOpcode BOP_Min  = BOP_Add;
136
const TIL_BinaryOpcode BOP_Max  = BOP_LogicOr;
137
const TIL_CastOpcode   CAST_Min = CAST_none;
138
const TIL_CastOpcode   CAST_Max = CAST_toInt;
139
 
140
/// Return the name of a unary opcode.
141
StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op);
142
 
143
/// Return the name of a binary opcode.
144
StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op);
145
 
146
/// ValueTypes are data types that can actually be held in registers.
147
/// All variables and expressions must have a value type.
148
/// Pointer types are further subdivided into the various heap-allocated
149
/// types, such as functions, records, etc.
150
/// Structured types that are passed by value (e.g. complex numbers)
151
/// require special handling; they use BT_ValueRef, and size ST_0.
152
struct ValueType {
153
  enum BaseType : unsigned char {
154
    BT_Void = 0,
155
    BT_Bool,
156
    BT_Int,
157
    BT_Float,
158
    BT_String,    // String literals
159
    BT_Pointer,
160
    BT_ValueRef
161
  };
162
 
163
  enum SizeType : unsigned char {
164
    ST_0 = 0,
165
    ST_1,
166
    ST_8,
167
    ST_16,
168
    ST_32,
169
    ST_64,
170
    ST_128
171
  };
172
 
173
  ValueType(BaseType B, SizeType Sz, bool S, unsigned char VS)
174
      : Base(B), Size(Sz), Signed(S), VectSize(VS) {}
175
 
176
  inline static SizeType getSizeType(unsigned nbytes);
177
 
178
  template <class T>
179
  inline static ValueType getValueType();
180
 
181
  BaseType Base;
182
  SizeType Size;
183
  bool Signed;
184
 
185
  // 0 for scalar, otherwise num elements in vector
186
  unsigned char VectSize;
187
};
188
 
189
inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) {
190
  switch (nbytes) {
191
    case 1: return ST_8;
192
    case 2: return ST_16;
193
    case 4: return ST_32;
194
    case 8: return ST_64;
195
    case 16: return ST_128;
196
    default: return ST_0;
197
  }
198
}
199
 
200
template<>
201
inline ValueType ValueType::getValueType<void>() {
202
  return ValueType(BT_Void, ST_0, false, 0);
203
}
204
 
205
template<>
206
inline ValueType ValueType::getValueType<bool>() {
207
  return ValueType(BT_Bool, ST_1, false, 0);
208
}
209
 
210
template<>
211
inline ValueType ValueType::getValueType<int8_t>() {
212
  return ValueType(BT_Int, ST_8, true, 0);
213
}
214
 
215
template<>
216
inline ValueType ValueType::getValueType<uint8_t>() {
217
  return ValueType(BT_Int, ST_8, false, 0);
218
}
219
 
220
template<>
221
inline ValueType ValueType::getValueType<int16_t>() {
222
  return ValueType(BT_Int, ST_16, true, 0);
223
}
224
 
225
template<>
226
inline ValueType ValueType::getValueType<uint16_t>() {
227
  return ValueType(BT_Int, ST_16, false, 0);
228
}
229
 
230
template<>
231
inline ValueType ValueType::getValueType<int32_t>() {
232
  return ValueType(BT_Int, ST_32, true, 0);
233
}
234
 
235
template<>
236
inline ValueType ValueType::getValueType<uint32_t>() {
237
  return ValueType(BT_Int, ST_32, false, 0);
238
}
239
 
240
template<>
241
inline ValueType ValueType::getValueType<int64_t>() {
242
  return ValueType(BT_Int, ST_64, true, 0);
243
}
244
 
245
template<>
246
inline ValueType ValueType::getValueType<uint64_t>() {
247
  return ValueType(BT_Int, ST_64, false, 0);
248
}
249
 
250
template<>
251
inline ValueType ValueType::getValueType<float>() {
252
  return ValueType(BT_Float, ST_32, true, 0);
253
}
254
 
255
template<>
256
inline ValueType ValueType::getValueType<double>() {
257
  return ValueType(BT_Float, ST_64, true, 0);
258
}
259
 
260
template<>
261
inline ValueType ValueType::getValueType<long double>() {
262
  return ValueType(BT_Float, ST_128, true, 0);
263
}
264
 
265
template<>
266
inline ValueType ValueType::getValueType<StringRef>() {
267
  return ValueType(BT_String, getSizeType(sizeof(StringRef)), false, 0);
268
}
269
 
270
template<>
271
inline ValueType ValueType::getValueType<void*>() {
272
  return ValueType(BT_Pointer, getSizeType(sizeof(void*)), false, 0);
273
}
274
 
275
/// Base class for AST nodes in the typed intermediate language.
276
class SExpr {
277
public:
278
  SExpr() = delete;
279
 
280
  TIL_Opcode opcode() const { return Opcode; }
281
 
282
  // Subclasses of SExpr must define the following:
283
  //
284
  // This(const This& E, ...) {
285
  //   copy constructor: construct copy of E, with some additional arguments.
286
  // }
287
  //
288
  // template <class V>
289
  // typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
290
  //   traverse all subexpressions, following the traversal/rewriter interface.
291
  // }
292
  //
293
  // template <class C> typename C::CType compare(CType* E, C& Cmp) {
294
  //   compare all subexpressions, following the comparator interface
295
  // }
296
  void *operator new(size_t S, MemRegionRef &R) {
297
    return ::operator new(S, R);
298
  }
299
 
300
  /// SExpr objects must be created in an arena.
301
  void *operator new(size_t) = delete;
302
 
303
  /// SExpr objects cannot be deleted.
304
  // This declaration is public to workaround a gcc bug that breaks building
305
  // with REQUIRES_EH=1.
306
  void operator delete(void *) = delete;
307
 
308
  /// Returns the instruction ID for this expression.
309
  /// All basic block instructions have a unique ID (i.e. virtual register).
310
  unsigned id() const { return SExprID; }
311
 
312
  /// Returns the block, if this is an instruction in a basic block,
313
  /// otherwise returns null.
314
  BasicBlock *block() const { return Block; }
315
 
316
  /// Set the basic block and instruction ID for this expression.
317
  void setID(BasicBlock *B, unsigned id) { Block = B; SExprID = id; }
318
 
319
protected:
320
  SExpr(TIL_Opcode Op) : Opcode(Op) {}
321
  SExpr(const SExpr &E) : Opcode(E.Opcode), Flags(E.Flags) {}
322
 
323
  const TIL_Opcode Opcode;
324
  unsigned char Reserved = 0;
325
  unsigned short Flags = 0;
326
  unsigned SExprID = 0;
327
  BasicBlock *Block = nullptr;
328
};
329
 
330
// Contains various helper functions for SExprs.
331
namespace ThreadSafetyTIL {
332
 
333
inline bool isTrivial(const SExpr *E) {
334
  TIL_Opcode Op = E->opcode();
335
  return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
336
}
337
 
338
} // namespace ThreadSafetyTIL
339
 
340
// Nodes which declare variables
341
 
342
/// A named variable, e.g. "x".
343
///
344
/// There are two distinct places in which a Variable can appear in the AST.
345
/// A variable declaration introduces a new variable, and can occur in 3 places:
346
///   Let-expressions:           (Let (x = t) u)
347
///   Functions:                 (Function (x : t) u)
348
///   Self-applicable functions  (SFunction (x) t)
349
///
350
/// If a variable occurs in any other location, it is a reference to an existing
351
/// variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
352
/// allocate a separate AST node for variable references; a reference is just a
353
/// pointer to the original declaration.
354
class Variable : public SExpr {
355
public:
356
  enum VariableKind {
357
    /// Let-variable
358
    VK_Let,
359
 
360
    /// Function parameter
361
    VK_Fun,
362
 
363
    /// SFunction (self) parameter
364
    VK_SFun
365
  };
366
 
367
  Variable(StringRef s, SExpr *D = nullptr)
368
      : SExpr(COP_Variable), Name(s), Definition(D) {
369
    Flags = VK_Let;
370
  }
371
 
372
  Variable(SExpr *D, const ValueDecl *Cvd = nullptr)
373
      : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"),
374
        Definition(D), Cvdecl(Cvd) {
375
    Flags = VK_Let;
376
  }
377
 
378
  Variable(const Variable &Vd, SExpr *D)  // rewrite constructor
379
      : SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl) {
380
    Flags = Vd.kind();
381
  }
382
 
383
  static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
384
 
385
  /// Return the kind of variable (let, function param, or self)
386
  VariableKind kind() const { return static_cast<VariableKind>(Flags); }
387
 
388
  /// Return the name of the variable, if any.
389
  StringRef name() const { return Name; }
390
 
391
  /// Return the clang declaration for this variable, if any.
392
  const ValueDecl *clangDecl() const { return Cvdecl; }
393
 
394
  /// Return the definition of the variable.
395
  /// For let-vars, this is the setting expression.
396
  /// For function and self parameters, it is the type of the variable.
397
  SExpr *definition() { return Definition; }
398
  const SExpr *definition() const { return Definition; }
399
 
400
  void setName(StringRef S)    { Name = S;  }
401
  void setKind(VariableKind K) { Flags = K; }
402
  void setDefinition(SExpr *E) { Definition = E; }
403
  void setClangDecl(const ValueDecl *VD) { Cvdecl = VD; }
404
 
405
  template <class V>
406
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
407
    // This routine is only called for variable references.
408
    return Vs.reduceVariableRef(this);
409
  }
410
 
411
  template <class C>
412
  typename C::CType compare(const Variable* E, C& Cmp) const {
413
    return Cmp.compareVariableRefs(this, E);
414
  }
415
 
416
private:
417
  friend class BasicBlock;
418
  friend class Function;
419
  friend class Let;
420
  friend class SFunction;
421
 
422
  // The name of the variable.
423
  StringRef Name;
424
 
425
  // The TIL type or definition.
426
  SExpr *Definition;
427
 
428
  // The clang declaration for this variable.
429
  const ValueDecl *Cvdecl = nullptr;
430
};
431
 
432
/// Placeholder for an expression that has not yet been created.
433
/// Used to implement lazy copy and rewriting strategies.
434
class Future : public SExpr {
435
public:
436
  enum FutureStatus {
437
    FS_pending,
438
    FS_evaluating,
439
    FS_done
440
  };
441
 
442
  Future() : SExpr(COP_Future) {}
443
  virtual ~Future() = delete;
444
 
445
  static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
446
 
447
  // A lazy rewriting strategy should subclass Future and override this method.
448
  virtual SExpr *compute() { return nullptr; }
449
 
450
  // Return the result of this future if it exists, otherwise return null.
451
  SExpr *maybeGetResult() const { return Result; }
452
 
453
  // Return the result of this future; forcing it if necessary.
454
  SExpr *result() {
455
    switch (Status) {
456
    case FS_pending:
457
      return force();
458
    case FS_evaluating:
459
      return nullptr; // infinite loop; illegal recursion.
460
    case FS_done:
461
      return Result;
462
    }
463
  }
464
 
465
  template <class V>
466
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
467
    assert(Result && "Cannot traverse Future that has not been forced.");
468
    return Vs.traverse(Result, Ctx);
469
  }
470
 
471
  template <class C>
472
  typename C::CType compare(const Future* E, C& Cmp) const {
473
    if (!Result || !E->Result)
474
      return Cmp.comparePointers(this, E);
475
    return Cmp.compare(Result, E->Result);
476
  }
477
 
478
private:
479
  SExpr* force();
480
 
481
  FutureStatus Status = FS_pending;
482
  SExpr *Result = nullptr;
483
};
484
 
485
/// Placeholder for expressions that cannot be represented in the TIL.
486
class Undefined : public SExpr {
487
public:
488
  Undefined(const Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
489
  Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
490
 
491
  static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
492
 
493
  template <class V>
494
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
495
    return Vs.reduceUndefined(*this);
496
  }
497
 
498
  template <class C>
499
  typename C::CType compare(const Undefined* E, C& Cmp) const {
500
    return Cmp.trueResult();
501
  }
502
 
503
private:
504
  const Stmt *Cstmt;
505
};
506
 
507
/// Placeholder for a wildcard that matches any other expression.
508
class Wildcard : public SExpr {
509
public:
510
  Wildcard() : SExpr(COP_Wildcard) {}
511
  Wildcard(const Wildcard &) = default;
512
 
513
  static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
514
 
515
  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
516
    return Vs.reduceWildcard(*this);
517
  }
518
 
519
  template <class C>
520
  typename C::CType compare(const Wildcard* E, C& Cmp) const {
521
    return Cmp.trueResult();
522
  }
523
};
524
 
525
template <class T> class LiteralT;
526
 
527
// Base class for literal values.
528
class Literal : public SExpr {
529
public:
530
  Literal(const Expr *C)
531
     : SExpr(COP_Literal), ValType(ValueType::getValueType<void>()), Cexpr(C) {}
532
  Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT) {}
533
  Literal(const Literal &) = default;
534
 
535
  static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
536
 
537
  // The clang expression for this literal.
538
  const Expr *clangExpr() const { return Cexpr; }
539
 
540
  ValueType valueType() const { return ValType; }
541
 
542
  template<class T> const LiteralT<T>& as() const {
543
    return *static_cast<const LiteralT<T>*>(this);
544
  }
545
  template<class T> LiteralT<T>& as() {
546
    return *static_cast<LiteralT<T>*>(this);
547
  }
548
 
549
  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx);
550
 
551
  template <class C>
552
  typename C::CType compare(const Literal* E, C& Cmp) const {
553
    // TODO: defer actual comparison to LiteralT
554
    return Cmp.trueResult();
555
  }
556
 
557
private:
558
  const ValueType ValType;
559
  const Expr *Cexpr = nullptr;
560
};
561
 
562
// Derived class for literal values, which stores the actual value.
563
template<class T>
564
class LiteralT : public Literal {
565
public:
566
  LiteralT(T Dat) : Literal(ValueType::getValueType<T>()), Val(Dat) {}
567
  LiteralT(const LiteralT<T> &L) : Literal(L), Val(L.Val) {}
568
 
569
  T value() const { return Val;}
570
  T& value() { return Val; }
571
 
572
private:
573
  T Val;
574
};
575
 
576
template <class V>
577
typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
578
  if (Cexpr)
579
    return Vs.reduceLiteral(*this);
580
 
581
  switch (ValType.Base) {
582
  case ValueType::BT_Void:
583
    break;
584
  case ValueType::BT_Bool:
585
    return Vs.reduceLiteralT(as<bool>());
586
  case ValueType::BT_Int: {
587
    switch (ValType.Size) {
588
    case ValueType::ST_8:
589
      if (ValType.Signed)
590
        return Vs.reduceLiteralT(as<int8_t>());
591
      else
592
        return Vs.reduceLiteralT(as<uint8_t>());
593
    case ValueType::ST_16:
594
      if (ValType.Signed)
595
        return Vs.reduceLiteralT(as<int16_t>());
596
      else
597
        return Vs.reduceLiteralT(as<uint16_t>());
598
    case ValueType::ST_32:
599
      if (ValType.Signed)
600
        return Vs.reduceLiteralT(as<int32_t>());
601
      else
602
        return Vs.reduceLiteralT(as<uint32_t>());
603
    case ValueType::ST_64:
604
      if (ValType.Signed)
605
        return Vs.reduceLiteralT(as<int64_t>());
606
      else
607
        return Vs.reduceLiteralT(as<uint64_t>());
608
    default:
609
      break;
610
    }
611
  }
612
  case ValueType::BT_Float: {
613
    switch (ValType.Size) {
614
    case ValueType::ST_32:
615
      return Vs.reduceLiteralT(as<float>());
616
    case ValueType::ST_64:
617
      return Vs.reduceLiteralT(as<double>());
618
    default:
619
      break;
620
    }
621
  }
622
  case ValueType::BT_String:
623
    return Vs.reduceLiteralT(as<StringRef>());
624
  case ValueType::BT_Pointer:
625
    return Vs.reduceLiteralT(as<void*>());
626
  case ValueType::BT_ValueRef:
627
    break;
628
  }
629
  return Vs.reduceLiteral(*this);
630
}
631
 
632
/// A Literal pointer to an object allocated in memory.
633
/// At compile time, pointer literals are represented by symbolic names.
634
class LiteralPtr : public SExpr {
635
public:
636
  LiteralPtr(const ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
637
  LiteralPtr(const LiteralPtr &) = default;
638
 
639
  static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
640
 
641
  // The clang declaration for the value that this pointer points to.
642
  const ValueDecl *clangDecl() const { return Cvdecl; }
643
  void setClangDecl(const ValueDecl *VD) { Cvdecl = VD; }
644
 
645
  template <class V>
646
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
647
    return Vs.reduceLiteralPtr(*this);
648
  }
649
 
650
  template <class C>
651
  typename C::CType compare(const LiteralPtr* E, C& Cmp) const {
652
    if (!Cvdecl || !E->Cvdecl)
653
      return Cmp.comparePointers(this, E);
654
    return Cmp.comparePointers(Cvdecl, E->Cvdecl);
655
  }
656
 
657
private:
658
  const ValueDecl *Cvdecl;
659
};
660
 
661
/// A function -- a.k.a. lambda abstraction.
662
/// Functions with multiple arguments are created by currying,
663
/// e.g. (Function (x: Int) (Function (y: Int) (Code { return x + y })))
664
class Function : public SExpr {
665
public:
666
  Function(Variable *Vd, SExpr *Bd)
667
      : SExpr(COP_Function), VarDecl(Vd), Body(Bd) {
668
    Vd->setKind(Variable::VK_Fun);
669
  }
670
 
671
  Function(const Function &F, Variable *Vd, SExpr *Bd) // rewrite constructor
672
      : SExpr(F), VarDecl(Vd), Body(Bd) {
673
    Vd->setKind(Variable::VK_Fun);
674
  }
675
 
676
  static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
677
 
678
  Variable *variableDecl()  { return VarDecl; }
679
  const Variable *variableDecl() const { return VarDecl; }
680
 
681
  SExpr *body() { return Body; }
682
  const SExpr *body() const { return Body; }
683
 
684
  template <class V>
685
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
686
    // This is a variable declaration, so traverse the definition.
687
    auto E0 = Vs.traverse(VarDecl->Definition, Vs.typeCtx(Ctx));
688
    // Tell the rewriter to enter the scope of the function.
689
    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
690
    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
691
    Vs.exitScope(*VarDecl);
692
    return Vs.reduceFunction(*this, Nvd, E1);
693
  }
694
 
695
  template <class C>
696
  typename C::CType compare(const Function* E, C& Cmp) const {
697
    typename C::CType Ct =
698
      Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
699
    if (Cmp.notTrue(Ct))
700
      return Ct;
701
    Cmp.enterScope(variableDecl(), E->variableDecl());
702
    Ct = Cmp.compare(body(), E->body());
703
    Cmp.leaveScope();
704
    return Ct;
705
  }
706
 
707
private:
708
  Variable *VarDecl;
709
  SExpr* Body;
710
};
711
 
712
/// A self-applicable function.
713
/// A self-applicable function can be applied to itself.  It's useful for
714
/// implementing objects and late binding.
715
class SFunction : public SExpr {
716
public:
717
  SFunction(Variable *Vd, SExpr *B)
718
      : SExpr(COP_SFunction), VarDecl(Vd), Body(B) {
719
    assert(Vd->Definition == nullptr);
720
    Vd->setKind(Variable::VK_SFun);
721
    Vd->Definition = this;
722
  }
723
 
724
  SFunction(const SFunction &F, Variable *Vd, SExpr *B) // rewrite constructor
725
      : SExpr(F), VarDecl(Vd), Body(B) {
726
    assert(Vd->Definition == nullptr);
727
    Vd->setKind(Variable::VK_SFun);
728
    Vd->Definition = this;
729
  }
730
 
731
  static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
732
 
733
  Variable *variableDecl() { return VarDecl; }
734
  const Variable *variableDecl() const { return VarDecl; }
735
 
736
  SExpr *body() { return Body; }
737
  const SExpr *body() const { return Body; }
738
 
739
  template <class V>
740
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
741
    // A self-variable points to the SFunction itself.
742
    // A rewrite must introduce the variable with a null definition, and update
743
    // it after 'this' has been rewritten.
744
    Variable *Nvd = Vs.enterScope(*VarDecl, nullptr);
745
    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
746
    Vs.exitScope(*VarDecl);
747
    // A rewrite operation will call SFun constructor to set Vvd->Definition.
748
    return Vs.reduceSFunction(*this, Nvd, E1);
749
  }
750
 
751
  template <class C>
752
  typename C::CType compare(const SFunction* E, C& Cmp) const {
753
    Cmp.enterScope(variableDecl(), E->variableDecl());
754
    typename C::CType Ct = Cmp.compare(body(), E->body());
755
    Cmp.leaveScope();
756
    return Ct;
757
  }
758
 
759
private:
760
  Variable *VarDecl;
761
  SExpr* Body;
762
};
763
 
764
/// A block of code -- e.g. the body of a function.
765
class Code : public SExpr {
766
public:
767
  Code(SExpr *T, SExpr *B) : SExpr(COP_Code), ReturnType(T), Body(B) {}
768
  Code(const Code &C, SExpr *T, SExpr *B) // rewrite constructor
769
      : SExpr(C), ReturnType(T), Body(B) {}
770
 
771
  static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
772
 
773
  SExpr *returnType() { return ReturnType; }
774
  const SExpr *returnType() const { return ReturnType; }
775
 
776
  SExpr *body() { return Body; }
777
  const SExpr *body() const { return Body; }
778
 
779
  template <class V>
780
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
781
    auto Nt = Vs.traverse(ReturnType, Vs.typeCtx(Ctx));
782
    auto Nb = Vs.traverse(Body,       Vs.lazyCtx(Ctx));
783
    return Vs.reduceCode(*this, Nt, Nb);
784
  }
785
 
786
  template <class C>
787
  typename C::CType compare(const Code* E, C& Cmp) const {
788
    typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
789
    if (Cmp.notTrue(Ct))
790
      return Ct;
791
    return Cmp.compare(body(), E->body());
792
  }
793
 
794
private:
795
  SExpr* ReturnType;
796
  SExpr* Body;
797
};
798
 
799
/// A typed, writable location in memory
800
class Field : public SExpr {
801
public:
802
  Field(SExpr *R, SExpr *B) : SExpr(COP_Field), Range(R), Body(B) {}
803
  Field(const Field &C, SExpr *R, SExpr *B) // rewrite constructor
804
      : SExpr(C), Range(R), Body(B) {}
805
 
806
  static bool classof(const SExpr *E) { return E->opcode() == COP_Field; }
807
 
808
  SExpr *range() { return Range; }
809
  const SExpr *range() const { return Range; }
810
 
811
  SExpr *body() { return Body; }
812
  const SExpr *body() const { return Body; }
813
 
814
  template <class V>
815
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
816
    auto Nr = Vs.traverse(Range, Vs.typeCtx(Ctx));
817
    auto Nb = Vs.traverse(Body,  Vs.lazyCtx(Ctx));
818
    return Vs.reduceField(*this, Nr, Nb);
819
  }
820
 
821
  template <class C>
822
  typename C::CType compare(const Field* E, C& Cmp) const {
823
    typename C::CType Ct = Cmp.compare(range(), E->range());
824
    if (Cmp.notTrue(Ct))
825
      return Ct;
826
    return Cmp.compare(body(), E->body());
827
  }
828
 
829
private:
830
  SExpr* Range;
831
  SExpr* Body;
832
};
833
 
834
/// Apply an argument to a function.
835
/// Note that this does not actually call the function.  Functions are curried,
836
/// so this returns a closure in which the first parameter has been applied.
837
/// Once all parameters have been applied, Call can be used to invoke the
838
/// function.
839
class Apply : public SExpr {
840
public:
841
  Apply(SExpr *F, SExpr *A) : SExpr(COP_Apply), Fun(F), Arg(A) {}
842
  Apply(const Apply &A, SExpr *F, SExpr *Ar)  // rewrite constructor
843
      : SExpr(A), Fun(F), Arg(Ar) {}
844
 
845
  static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
846
 
847
  SExpr *fun() { return Fun; }
848
  const SExpr *fun() const { return Fun; }
849
 
850
  SExpr *arg() { return Arg; }
851
  const SExpr *arg() const { return Arg; }
852
 
853
  template <class V>
854
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
855
    auto Nf = Vs.traverse(Fun, Vs.subExprCtx(Ctx));
856
    auto Na = Vs.traverse(Arg, Vs.subExprCtx(Ctx));
857
    return Vs.reduceApply(*this, Nf, Na);
858
  }
859
 
860
  template <class C>
861
  typename C::CType compare(const Apply* E, C& Cmp) const {
862
    typename C::CType Ct = Cmp.compare(fun(), E->fun());
863
    if (Cmp.notTrue(Ct))
864
      return Ct;
865
    return Cmp.compare(arg(), E->arg());
866
  }
867
 
868
private:
869
  SExpr* Fun;
870
  SExpr* Arg;
871
};
872
 
873
/// Apply a self-argument to a self-applicable function.
874
class SApply : public SExpr {
875
public:
876
  SApply(SExpr *Sf, SExpr *A = nullptr) : SExpr(COP_SApply), Sfun(Sf), Arg(A) {}
877
  SApply(SApply &A, SExpr *Sf, SExpr *Ar = nullptr) // rewrite constructor
878
      : SExpr(A), Sfun(Sf), Arg(Ar) {}
879
 
880
  static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
881
 
882
  SExpr *sfun() { return Sfun; }
883
  const SExpr *sfun() const { return Sfun; }
884
 
885
  SExpr *arg() { return Arg ? Arg : Sfun; }
886
  const SExpr *arg() const { return Arg ? Arg : Sfun; }
887
 
888
  bool isDelegation() const { return Arg != nullptr; }
889
 
890
  template <class V>
891
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
892
    auto Nf = Vs.traverse(Sfun, Vs.subExprCtx(Ctx));
893
    typename V::R_SExpr Na = Arg ? Vs.traverse(Arg, Vs.subExprCtx(Ctx))
894
                                       : nullptr;
895
    return Vs.reduceSApply(*this, Nf, Na);
896
  }
897
 
898
  template <class C>
899
  typename C::CType compare(const SApply* E, C& Cmp) const {
900
    typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
901
    if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
902
      return Ct;
903
    return Cmp.compare(arg(), E->arg());
904
  }
905
 
906
private:
907
  SExpr* Sfun;
908
  SExpr* Arg;
909
};
910
 
911
/// Project a named slot from a C++ struct or class.
912
class Project : public SExpr {
913
public:
914
  Project(SExpr *R, const ValueDecl *Cvd)
915
      : SExpr(COP_Project), Rec(R), Cvdecl(Cvd) {
916
    assert(Cvd && "ValueDecl must not be null");
917
  }
918
 
919
  static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
920
 
921
  SExpr *record() { return Rec; }
922
  const SExpr *record() const { return Rec; }
923
 
924
  const ValueDecl *clangDecl() const { return Cvdecl; }
925
 
926
  bool isArrow() const { return (Flags & 0x01) != 0; }
927
 
928
  void setArrow(bool b) {
929
    if (b) Flags |= 0x01;
930
    else Flags &= 0xFFFE;
931
  }
932
 
933
  StringRef slotName() const {
934
    if (Cvdecl->getDeclName().isIdentifier())
935
      return Cvdecl->getName();
936
    if (!SlotName) {
937
      SlotName = "";
938
      llvm::raw_string_ostream OS(*SlotName);
939
      Cvdecl->printName(OS);
940
    }
941
    return *SlotName;
942
  }
943
 
944
  template <class V>
945
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
946
    auto Nr = Vs.traverse(Rec, Vs.subExprCtx(Ctx));
947
    return Vs.reduceProject(*this, Nr);
948
  }
949
 
950
  template <class C>
951
  typename C::CType compare(const Project* E, C& Cmp) const {
952
    typename C::CType Ct = Cmp.compare(record(), E->record());
953
    if (Cmp.notTrue(Ct))
954
      return Ct;
955
    return Cmp.comparePointers(Cvdecl, E->Cvdecl);
956
  }
957
 
958
private:
959
  SExpr* Rec;
960
  mutable std::optional<std::string> SlotName;
961
  const ValueDecl *Cvdecl;
962
};
963
 
964
/// Call a function (after all arguments have been applied).
965
class Call : public SExpr {
966
public:
967
  Call(SExpr *T, const CallExpr *Ce = nullptr)
968
      : SExpr(COP_Call), Target(T), Cexpr(Ce) {}
969
  Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
970
 
971
  static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
972
 
973
  SExpr *target() { return Target; }
974
  const SExpr *target() const { return Target; }
975
 
976
  const CallExpr *clangCallExpr() const { return Cexpr; }
977
 
978
  template <class V>
979
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
980
    auto Nt = Vs.traverse(Target, Vs.subExprCtx(Ctx));
981
    return Vs.reduceCall(*this, Nt);
982
  }
983
 
984
  template <class C>
985
  typename C::CType compare(const Call* E, C& Cmp) const {
986
    return Cmp.compare(target(), E->target());
987
  }
988
 
989
private:
990
  SExpr* Target;
991
  const CallExpr *Cexpr;
992
};
993
 
994
/// Allocate memory for a new value on the heap or stack.
995
class Alloc : public SExpr {
996
public:
997
  enum AllocKind {
998
    AK_Stack,
999
    AK_Heap
1000
  };
1001
 
1002
  Alloc(SExpr *D, AllocKind K) : SExpr(COP_Alloc), Dtype(D) { Flags = K; }
1003
  Alloc(const Alloc &A, SExpr *Dt) : SExpr(A), Dtype(Dt) { Flags = A.kind(); }
1004
 
1005
  static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
1006
 
1007
  AllocKind kind() const { return static_cast<AllocKind>(Flags); }
1008
 
1009
  SExpr *dataType() { return Dtype; }
1010
  const SExpr *dataType() const { return Dtype; }
1011
 
1012
  template <class V>
1013
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1014
    auto Nd = Vs.traverse(Dtype, Vs.declCtx(Ctx));
1015
    return Vs.reduceAlloc(*this, Nd);
1016
  }
1017
 
1018
  template <class C>
1019
  typename C::CType compare(const Alloc* E, C& Cmp) const {
1020
    typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
1021
    if (Cmp.notTrue(Ct))
1022
      return Ct;
1023
    return Cmp.compare(dataType(), E->dataType());
1024
  }
1025
 
1026
private:
1027
  SExpr* Dtype;
1028
};
1029
 
1030
/// Load a value from memory.
1031
class Load : public SExpr {
1032
public:
1033
  Load(SExpr *P) : SExpr(COP_Load), Ptr(P) {}
1034
  Load(const Load &L, SExpr *P) : SExpr(L), Ptr(P) {}
1035
 
1036
  static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
1037
 
1038
  SExpr *pointer() { return Ptr; }
1039
  const SExpr *pointer() const { return Ptr; }
1040
 
1041
  template <class V>
1042
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1043
    auto Np = Vs.traverse(Ptr, Vs.subExprCtx(Ctx));
1044
    return Vs.reduceLoad(*this, Np);
1045
  }
1046
 
1047
  template <class C>
1048
  typename C::CType compare(const Load* E, C& Cmp) const {
1049
    return Cmp.compare(pointer(), E->pointer());
1050
  }
1051
 
1052
private:
1053
  SExpr* Ptr;
1054
};
1055
 
1056
/// Store a value to memory.
1057
/// The destination is a pointer to a field, the source is the value to store.
1058
class Store : public SExpr {
1059
public:
1060
  Store(SExpr *P, SExpr *V) : SExpr(COP_Store), Dest(P), Source(V) {}
1061
  Store(const Store &S, SExpr *P, SExpr *V) : SExpr(S), Dest(P), Source(V) {}
1062
 
1063
  static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
1064
 
1065
  SExpr *destination() { return Dest; }  // Address to store to
1066
  const SExpr *destination() const { return Dest; }
1067
 
1068
  SExpr *source() { return Source; }     // Value to store
1069
  const SExpr *source() const { return Source; }
1070
 
1071
  template <class V>
1072
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1073
    auto Np = Vs.traverse(Dest,   Vs.subExprCtx(Ctx));
1074
    auto Nv = Vs.traverse(Source, Vs.subExprCtx(Ctx));
1075
    return Vs.reduceStore(*this, Np, Nv);
1076
  }
1077
 
1078
  template <class C>
1079
  typename C::CType compare(const Store* E, C& Cmp) const {
1080
    typename C::CType Ct = Cmp.compare(destination(), E->destination());
1081
    if (Cmp.notTrue(Ct))
1082
      return Ct;
1083
    return Cmp.compare(source(), E->source());
1084
  }
1085
 
1086
private:
1087
  SExpr* Dest;
1088
  SExpr* Source;
1089
};
1090
 
1091
/// If p is a reference to an array, then p[i] is a reference to the i'th
1092
/// element of the array.
1093
class ArrayIndex : public SExpr {
1094
public:
1095
  ArrayIndex(SExpr *A, SExpr *N) : SExpr(COP_ArrayIndex), Array(A), Index(N) {}
1096
  ArrayIndex(const ArrayIndex &E, SExpr *A, SExpr *N)
1097
      : SExpr(E), Array(A), Index(N) {}
1098
 
1099
  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayIndex; }
1100
 
1101
  SExpr *array() { return Array; }
1102
  const SExpr *array() const { return Array; }
1103
 
1104
  SExpr *index() { return Index; }
1105
  const SExpr *index() const { return Index; }
1106
 
1107
  template <class V>
1108
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1109
    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
1110
    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
1111
    return Vs.reduceArrayIndex(*this, Na, Ni);
1112
  }
1113
 
1114
  template <class C>
1115
  typename C::CType compare(const ArrayIndex* E, C& Cmp) const {
1116
    typename C::CType Ct = Cmp.compare(array(), E->array());
1117
    if (Cmp.notTrue(Ct))
1118
      return Ct;
1119
    return Cmp.compare(index(), E->index());
1120
  }
1121
 
1122
private:
1123
  SExpr* Array;
1124
  SExpr* Index;
1125
};
1126
 
1127
/// Pointer arithmetic, restricted to arrays only.
1128
/// If p is a reference to an array, then p + n, where n is an integer, is
1129
/// a reference to a subarray.
1130
class ArrayAdd : public SExpr {
1131
public:
1132
  ArrayAdd(SExpr *A, SExpr *N) : SExpr(COP_ArrayAdd), Array(A), Index(N) {}
1133
  ArrayAdd(const ArrayAdd &E, SExpr *A, SExpr *N)
1134
      : SExpr(E), Array(A), Index(N) {}
1135
 
1136
  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayAdd; }
1137
 
1138
  SExpr *array() { return Array; }
1139
  const SExpr *array() const { return Array; }
1140
 
1141
  SExpr *index() { return Index; }
1142
  const SExpr *index() const { return Index; }
1143
 
1144
  template <class V>
1145
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1146
    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
1147
    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
1148
    return Vs.reduceArrayAdd(*this, Na, Ni);
1149
  }
1150
 
1151
  template <class C>
1152
  typename C::CType compare(const ArrayAdd* E, C& Cmp) const {
1153
    typename C::CType Ct = Cmp.compare(array(), E->array());
1154
    if (Cmp.notTrue(Ct))
1155
      return Ct;
1156
    return Cmp.compare(index(), E->index());
1157
  }
1158
 
1159
private:
1160
  SExpr* Array;
1161
  SExpr* Index;
1162
};
1163
 
1164
/// Simple arithmetic unary operations, e.g. negate and not.
1165
/// These operations have no side-effects.
1166
class UnaryOp : public SExpr {
1167
public:
1168
  UnaryOp(TIL_UnaryOpcode Op, SExpr *E) : SExpr(COP_UnaryOp), Expr0(E) {
1169
    Flags = Op;
1170
  }
1171
 
1172
  UnaryOp(const UnaryOp &U, SExpr *E) : SExpr(U), Expr0(E) { Flags = U.Flags; }
1173
 
1174
  static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
1175
 
1176
  TIL_UnaryOpcode unaryOpcode() const {
1177
    return static_cast<TIL_UnaryOpcode>(Flags);
1178
  }
1179
 
1180
  SExpr *expr() { return Expr0; }
1181
  const SExpr *expr() const { return Expr0; }
1182
 
1183
  template <class V>
1184
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1185
    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
1186
    return Vs.reduceUnaryOp(*this, Ne);
1187
  }
1188
 
1189
  template <class C>
1190
  typename C::CType compare(const UnaryOp* E, C& Cmp) const {
1191
    typename C::CType Ct =
1192
      Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
1193
    if (Cmp.notTrue(Ct))
1194
      return Ct;
1195
    return Cmp.compare(expr(), E->expr());
1196
  }
1197
 
1198
private:
1199
  SExpr* Expr0;
1200
};
1201
 
1202
/// Simple arithmetic binary operations, e.g. +, -, etc.
1203
/// These operations have no side effects.
1204
class BinaryOp : public SExpr {
1205
public:
1206
  BinaryOp(TIL_BinaryOpcode Op, SExpr *E0, SExpr *E1)
1207
      : SExpr(COP_BinaryOp), Expr0(E0), Expr1(E1) {
1208
    Flags = Op;
1209
  }
1210
 
1211
  BinaryOp(const BinaryOp &B, SExpr *E0, SExpr *E1)
1212
      : SExpr(B), Expr0(E0), Expr1(E1) {
1213
    Flags = B.Flags;
1214
  }
1215
 
1216
  static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
1217
 
1218
  TIL_BinaryOpcode binaryOpcode() const {
1219
    return static_cast<TIL_BinaryOpcode>(Flags);
1220
  }
1221
 
1222
  SExpr *expr0() { return Expr0; }
1223
  const SExpr *expr0() const { return Expr0; }
1224
 
1225
  SExpr *expr1() { return Expr1; }
1226
  const SExpr *expr1() const { return Expr1; }
1227
 
1228
  template <class V>
1229
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1230
    auto Ne0 = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
1231
    auto Ne1 = Vs.traverse(Expr1, Vs.subExprCtx(Ctx));
1232
    return Vs.reduceBinaryOp(*this, Ne0, Ne1);
1233
  }
1234
 
1235
  template <class C>
1236
  typename C::CType compare(const BinaryOp* E, C& Cmp) const {
1237
    typename C::CType Ct =
1238
      Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
1239
    if (Cmp.notTrue(Ct))
1240
      return Ct;
1241
    Ct = Cmp.compare(expr0(), E->expr0());
1242
    if (Cmp.notTrue(Ct))
1243
      return Ct;
1244
    return Cmp.compare(expr1(), E->expr1());
1245
  }
1246
 
1247
private:
1248
  SExpr* Expr0;
1249
  SExpr* Expr1;
1250
};
1251
 
1252
/// Cast expressions.
1253
/// Cast expressions are essentially unary operations, but we treat them
1254
/// as a distinct AST node because they only change the type of the result.
1255
class Cast : public SExpr {
1256
public:
1257
  Cast(TIL_CastOpcode Op, SExpr *E) : SExpr(COP_Cast), Expr0(E) { Flags = Op; }
1258
  Cast(const Cast &C, SExpr *E) : SExpr(C), Expr0(E) { Flags = C.Flags; }
1259
 
1260
  static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
1261
 
1262
  TIL_CastOpcode castOpcode() const {
1263
    return static_cast<TIL_CastOpcode>(Flags);
1264
  }
1265
 
1266
  SExpr *expr() { return Expr0; }
1267
  const SExpr *expr() const { return Expr0; }
1268
 
1269
  template <class V>
1270
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1271
    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
1272
    return Vs.reduceCast(*this, Ne);
1273
  }
1274
 
1275
  template <class C>
1276
  typename C::CType compare(const Cast* E, C& Cmp) const {
1277
    typename C::CType Ct =
1278
      Cmp.compareIntegers(castOpcode(), E->castOpcode());
1279
    if (Cmp.notTrue(Ct))
1280
      return Ct;
1281
    return Cmp.compare(expr(), E->expr());
1282
  }
1283
 
1284
private:
1285
  SExpr* Expr0;
1286
};
1287
 
1288
class SCFG;
1289
 
1290
/// Phi Node, for code in SSA form.
1291
/// Each Phi node has an array of possible values that it can take,
1292
/// depending on where control flow comes from.
1293
class Phi : public SExpr {
1294
public:
1295
  using ValArray = SimpleArray<SExpr *>;
1296
 
1297
  // In minimal SSA form, all Phi nodes are MultiVal.
1298
  // During conversion to SSA, incomplete Phi nodes may be introduced, which
1299
  // are later determined to be SingleVal, and are thus redundant.
1300
  enum Status {
1301
    PH_MultiVal = 0, // Phi node has multiple distinct values.  (Normal)
1302
    PH_SingleVal,    // Phi node has one distinct value, and can be eliminated
1303
    PH_Incomplete    // Phi node is incomplete
1304
  };
1305
 
1306
  Phi() : SExpr(COP_Phi) {}
1307
  Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals)  {}
1308
  Phi(const Phi &P, ValArray &&Vs) : SExpr(P), Values(std::move(Vs)) {}
1309
 
1310
  static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
1311
 
1312
  const ValArray &values() const { return Values; }
1313
  ValArray &values() { return Values; }
1314
 
1315
  Status status() const { return static_cast<Status>(Flags); }
1316
  void setStatus(Status s) { Flags = s; }
1317
 
1318
  /// Return the clang declaration of the variable for this Phi node, if any.
1319
  const ValueDecl *clangDecl() const { return Cvdecl; }
1320
 
1321
  /// Set the clang variable associated with this Phi node.
1322
  void setClangDecl(const ValueDecl *Cvd) { Cvdecl = Cvd; }
1323
 
1324
  template <class V>
1325
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1326
    typename V::template Container<typename V::R_SExpr>
1327
      Nvs(Vs, Values.size());
1328
 
1329
    for (const auto *Val : Values)
1330
      Nvs.push_back( Vs.traverse(Val, Vs.subExprCtx(Ctx)) );
1331
    return Vs.reducePhi(*this, Nvs);
1332
  }
1333
 
1334
  template <class C>
1335
  typename C::CType compare(const Phi *E, C &Cmp) const {
1336
    // TODO: implement CFG comparisons
1337
    return Cmp.comparePointers(this, E);
1338
  }
1339
 
1340
private:
1341
  ValArray Values;
1342
  const ValueDecl* Cvdecl = nullptr;
1343
};
1344
 
1345
/// Base class for basic block terminators:  Branch, Goto, and Return.
1346
class Terminator : public SExpr {
1347
protected:
1348
  Terminator(TIL_Opcode Op) : SExpr(Op) {}
1349
  Terminator(const SExpr &E) : SExpr(E) {}
1350
 
1351
public:
1352
  static bool classof(const SExpr *E) {
1353
    return E->opcode() >= COP_Goto && E->opcode() <= COP_Return;
1354
  }
1355
 
1356
  /// Return the list of basic blocks that this terminator can branch to.
1357
  ArrayRef<BasicBlock *> successors();
1358
 
1359
  ArrayRef<BasicBlock *> successors() const {
1360
    return const_cast<Terminator*>(this)->successors();
1361
  }
1362
};
1363
 
1364
/// Jump to another basic block.
1365
/// A goto instruction is essentially a tail-recursive call into another
1366
/// block.  In addition to the block pointer, it specifies an index into the
1367
/// phi nodes of that block.  The index can be used to retrieve the "arguments"
1368
/// of the call.
1369
class Goto : public Terminator {
1370
public:
1371
  Goto(BasicBlock *B, unsigned I)
1372
      : Terminator(COP_Goto), TargetBlock(B), Index(I) {}
1373
  Goto(const Goto &G, BasicBlock *B, unsigned I)
1374
      : Terminator(COP_Goto), TargetBlock(B), Index(I) {}
1375
 
1376
  static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
1377
 
1378
  const BasicBlock *targetBlock() const { return TargetBlock; }
1379
  BasicBlock *targetBlock() { return TargetBlock; }
1380
 
1381
  /// Returns the index into the
1382
  unsigned index() const { return Index; }
1383
 
1384
  /// Return the list of basic blocks that this terminator can branch to.
1385
  ArrayRef<BasicBlock *> successors() { return TargetBlock; }
1386
 
1387
  template <class V>
1388
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1389
    BasicBlock *Ntb = Vs.reduceBasicBlockRef(TargetBlock);
1390
    return Vs.reduceGoto(*this, Ntb);
1391
  }
1392
 
1393
  template <class C>
1394
  typename C::CType compare(const Goto *E, C &Cmp) const {
1395
    // TODO: implement CFG comparisons
1396
    return Cmp.comparePointers(this, E);
1397
  }
1398
 
1399
private:
1400
  BasicBlock *TargetBlock;
1401
  unsigned Index;
1402
};
1403
 
1404
/// A conditional branch to two other blocks.
1405
/// Note that unlike Goto, Branch does not have an index.  The target blocks
1406
/// must be child-blocks, and cannot have Phi nodes.
1407
class Branch : public Terminator {
1408
public:
1409
  Branch(SExpr *C, BasicBlock *T, BasicBlock *E)
1410
      : Terminator(COP_Branch), Condition(C) {
1411
    Branches[0] = T;
1412
    Branches[1] = E;
1413
  }
1414
 
1415
  Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E)
1416
      : Terminator(Br), Condition(C) {
1417
    Branches[0] = T;
1418
    Branches[1] = E;
1419
  }
1420
 
1421
  static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
1422
 
1423
  const SExpr *condition() const { return Condition; }
1424
  SExpr *condition() { return Condition; }
1425
 
1426
  const BasicBlock *thenBlock() const { return Branches[0]; }
1427
  BasicBlock *thenBlock() { return Branches[0]; }
1428
 
1429
  const BasicBlock *elseBlock() const { return Branches[1]; }
1430
  BasicBlock *elseBlock() { return Branches[1]; }
1431
 
1432
  /// Return the list of basic blocks that this terminator can branch to.
1433
  ArrayRef<BasicBlock *> successors() { return llvm::ArrayRef(Branches); }
1434
 
1435
  template <class V>
1436
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1437
    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
1438
    BasicBlock *Ntb = Vs.reduceBasicBlockRef(Branches[0]);
1439
    BasicBlock *Nte = Vs.reduceBasicBlockRef(Branches[1]);
1440
    return Vs.reduceBranch(*this, Nc, Ntb, Nte);
1441
  }
1442
 
1443
  template <class C>
1444
  typename C::CType compare(const Branch *E, C &Cmp) const {
1445
    // TODO: implement CFG comparisons
1446
    return Cmp.comparePointers(this, E);
1447
  }
1448
 
1449
private:
1450
  SExpr *Condition;
1451
  BasicBlock *Branches[2];
1452
};
1453
 
1454
/// Return from the enclosing function, passing the return value to the caller.
1455
/// Only the exit block should end with a return statement.
1456
class Return : public Terminator {
1457
public:
1458
  Return(SExpr* Rval) : Terminator(COP_Return), Retval(Rval) {}
1459
  Return(const Return &R, SExpr* Rval) : Terminator(R), Retval(Rval) {}
1460
 
1461
  static bool classof(const SExpr *E) { return E->opcode() == COP_Return; }
1462
 
1463
  /// Return an empty list.
1464
  ArrayRef<BasicBlock *> successors() { return std::nullopt; }
1465
 
1466
  SExpr *returnValue() { return Retval; }
1467
  const SExpr *returnValue() const { return Retval; }
1468
 
1469
  template <class V>
1470
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1471
    auto Ne = Vs.traverse(Retval, Vs.subExprCtx(Ctx));
1472
    return Vs.reduceReturn(*this, Ne);
1473
  }
1474
 
1475
  template <class C>
1476
  typename C::CType compare(const Return *E, C &Cmp) const {
1477
    return Cmp.compare(Retval, E->Retval);
1478
  }
1479
 
1480
private:
1481
  SExpr* Retval;
1482
};
1483
 
1484
inline ArrayRef<BasicBlock*> Terminator::successors() {
1485
  switch (opcode()) {
1486
    case COP_Goto:   return cast<Goto>(this)->successors();
1487
    case COP_Branch: return cast<Branch>(this)->successors();
1488
    case COP_Return: return cast<Return>(this)->successors();
1489
    default:
1490
      return std::nullopt;
1491
  }
1492
}
1493
 
1494
/// A basic block is part of an SCFG.  It can be treated as a function in
1495
/// continuation passing style.  A block consists of a sequence of phi nodes,
1496
/// which are "arguments" to the function, followed by a sequence of
1497
/// instructions.  It ends with a Terminator, which is a Branch or Goto to
1498
/// another basic block in the same SCFG.
1499
class BasicBlock : public SExpr {
1500
public:
1501
  using InstrArray = SimpleArray<SExpr *>;
1502
  using BlockArray = SimpleArray<BasicBlock *>;
1503
 
1504
  // TopologyNodes are used to overlay tree structures on top of the CFG,
1505
  // such as dominator and postdominator trees.  Each block is assigned an
1506
  // ID in the tree according to a depth-first search.  Tree traversals are
1507
  // always up, towards the parents.
1508
  struct TopologyNode {
1509
    int NodeID = 0;
1510
 
1511
    // Includes this node, so must be > 1.
1512
    int SizeOfSubTree = 0;
1513
 
1514
    // Pointer to parent.
1515
    BasicBlock *Parent = nullptr;
1516
 
1517
    TopologyNode() = default;
1518
 
1519
    bool isParentOf(const TopologyNode& OtherNode) {
1520
      return OtherNode.NodeID > NodeID &&
1521
             OtherNode.NodeID < NodeID + SizeOfSubTree;
1522
    }
1523
 
1524
    bool isParentOfOrEqual(const TopologyNode& OtherNode) {
1525
      return OtherNode.NodeID >= NodeID &&
1526
             OtherNode.NodeID < NodeID + SizeOfSubTree;
1527
    }
1528
  };
1529
 
1530
  explicit BasicBlock(MemRegionRef A)
1531
      : SExpr(COP_BasicBlock), Arena(A), BlockID(0), Visited(false) {}
1532
  BasicBlock(BasicBlock &B, MemRegionRef A, InstrArray &&As, InstrArray &&Is,
1533
             Terminator *T)
1534
      : SExpr(COP_BasicBlock), Arena(A), BlockID(0), Visited(false),
1535
        Args(std::move(As)), Instrs(std::move(Is)), TermInstr(T) {}
1536
 
1537
  static bool classof(const SExpr *E) { return E->opcode() == COP_BasicBlock; }
1538
 
1539
  /// Returns the block ID.  Every block has a unique ID in the CFG.
1540
  int blockID() const { return BlockID; }
1541
 
1542
  /// Returns the number of predecessors.
1543
  size_t numPredecessors() const { return Predecessors.size(); }
1544
  size_t numSuccessors() const { return successors().size(); }
1545
 
1546
  const SCFG* cfg() const { return CFGPtr; }
1547
  SCFG* cfg() { return CFGPtr; }
1548
 
1549
  const BasicBlock *parent() const { return DominatorNode.Parent; }
1550
  BasicBlock *parent() { return DominatorNode.Parent; }
1551
 
1552
  const InstrArray &arguments() const { return Args; }
1553
  InstrArray &arguments() { return Args; }
1554
 
1555
  InstrArray &instructions() { return Instrs; }
1556
  const InstrArray &instructions() const { return Instrs; }
1557
 
1558
  /// Returns a list of predecessors.
1559
  /// The order of predecessors in the list is important; each phi node has
1560
  /// exactly one argument for each precessor, in the same order.
1561
  BlockArray &predecessors() { return Predecessors; }
1562
  const BlockArray &predecessors() const { return Predecessors; }
1563
 
1564
  ArrayRef<BasicBlock*> successors() { return TermInstr->successors(); }
1565
  ArrayRef<BasicBlock*> successors() const { return TermInstr->successors(); }
1566
 
1567
  const Terminator *terminator() const { return TermInstr; }
1568
  Terminator *terminator() { return TermInstr; }
1569
 
1570
  void setTerminator(Terminator *E) { TermInstr = E; }
1571
 
1572
  bool Dominates(const BasicBlock &Other) {
1573
    return DominatorNode.isParentOfOrEqual(Other.DominatorNode);
1574
  }
1575
 
1576
  bool PostDominates(const BasicBlock &Other) {
1577
    return PostDominatorNode.isParentOfOrEqual(Other.PostDominatorNode);
1578
  }
1579
 
1580
  /// Add a new argument.
1581
  void addArgument(Phi *V) {
1582
    Args.reserveCheck(1, Arena);
1583
    Args.push_back(V);
1584
  }
1585
 
1586
  /// Add a new instruction.
1587
  void addInstruction(SExpr *V) {
1588
    Instrs.reserveCheck(1, Arena);
1589
    Instrs.push_back(V);
1590
  }
1591
 
1592
  // Add a new predecessor, and return the phi-node index for it.
1593
  // Will add an argument to all phi-nodes, initialized to nullptr.
1594
  unsigned addPredecessor(BasicBlock *Pred);
1595
 
1596
  // Reserve space for Nargs arguments.
1597
  void reserveArguments(unsigned Nargs)   { Args.reserve(Nargs, Arena); }
1598
 
1599
  // Reserve space for Nins instructions.
1600
  void reserveInstructions(unsigned Nins) { Instrs.reserve(Nins, Arena); }
1601
 
1602
  // Reserve space for NumPreds predecessors, including space in phi nodes.
1603
  void reservePredecessors(unsigned NumPreds);
1604
 
1605
  /// Return the index of BB, or Predecessors.size if BB is not a predecessor.
1606
  unsigned findPredecessorIndex(const BasicBlock *BB) const {
1607
    auto I = llvm::find(Predecessors, BB);
1608
    return std::distance(Predecessors.cbegin(), I);
1609
  }
1610
 
1611
  template <class V>
1612
  typename V::R_BasicBlock traverse(V &Vs, typename V::R_Ctx Ctx) {
1613
    typename V::template Container<SExpr*> Nas(Vs, Args.size());
1614
    typename V::template Container<SExpr*> Nis(Vs, Instrs.size());
1615
 
1616
    // Entering the basic block should do any scope initialization.
1617
    Vs.enterBasicBlock(*this);
1618
 
1619
    for (const auto *E : Args) {
1620
      auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
1621
      Nas.push_back(Ne);
1622
    }
1623
    for (const auto *E : Instrs) {
1624
      auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
1625
      Nis.push_back(Ne);
1626
    }
1627
    auto Nt = Vs.traverse(TermInstr, Ctx);
1628
 
1629
    // Exiting the basic block should handle any scope cleanup.
1630
    Vs.exitBasicBlock(*this);
1631
 
1632
    return Vs.reduceBasicBlock(*this, Nas, Nis, Nt);
1633
  }
1634
 
1635
  template <class C>
1636
  typename C::CType compare(const BasicBlock *E, C &Cmp) const {
1637
    // TODO: implement CFG comparisons
1638
    return Cmp.comparePointers(this, E);
1639
  }
1640
 
1641
private:
1642
  friend class SCFG;
1643
 
1644
  // assign unique ids to all instructions
1645
  unsigned renumberInstrs(unsigned id);
1646
 
1647
  unsigned topologicalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID);
1648
  unsigned topologicalFinalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID);
1649
  void computeDominator();
1650
  void computePostDominator();
1651
 
1652
  // The arena used to allocate this block.
1653
  MemRegionRef Arena;
1654
 
1655
  // The CFG that contains this block.
1656
  SCFG *CFGPtr = nullptr;
1657
 
1658
  // Unique ID for this BB in the containing CFG. IDs are in topological order.
1659
  unsigned BlockID : 31;
1660
 
1661
  // Bit to determine if a block has been visited during a traversal.
1662
  bool Visited : 1;
1663
 
1664
  // Predecessor blocks in the CFG.
1665
  BlockArray Predecessors;
1666
 
1667
  // Phi nodes. One argument per predecessor.
1668
  InstrArray Args;
1669
 
1670
  // Instructions.
1671
  InstrArray Instrs;
1672
 
1673
  // Terminating instruction.
1674
  Terminator *TermInstr = nullptr;
1675
 
1676
  // The dominator tree.
1677
  TopologyNode DominatorNode;
1678
 
1679
  // The post-dominator tree.
1680
  TopologyNode PostDominatorNode;
1681
};
1682
 
1683
/// An SCFG is a control-flow graph.  It consists of a set of basic blocks,
1684
/// each of which terminates in a branch to another basic block.  There is one
1685
/// entry point, and one exit point.
1686
class SCFG : public SExpr {
1687
public:
1688
  using BlockArray = SimpleArray<BasicBlock *>;
1689
  using iterator = BlockArray::iterator;
1690
  using const_iterator = BlockArray::const_iterator;
1691
 
1692
  SCFG(MemRegionRef A, unsigned Nblocks)
1693
      : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks) {
1694
    Entry = new (A) BasicBlock(A);
1695
    Exit  = new (A) BasicBlock(A);
1696
    auto *V = new (A) Phi();
1697
    Exit->addArgument(V);
1698
    Exit->setTerminator(new (A) Return(V));
1699
    add(Entry);
1700
    add(Exit);
1701
  }
1702
 
1703
  SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
1704
      : SExpr(COP_SCFG), Arena(Cfg.Arena), Blocks(std::move(Ba)) {
1705
    // TODO: set entry and exit!
1706
  }
1707
 
1708
  static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
1709
 
1710
  /// Return true if this CFG is valid.
1711
  bool valid() const { return Entry && Exit && Blocks.size() > 0; }
1712
 
1713
  /// Return true if this CFG has been normalized.
1714
  /// After normalization, blocks are in topological order, and block and
1715
  /// instruction IDs have been assigned.
1716
  bool normal() const { return Normal; }
1717
 
1718
  iterator begin() { return Blocks.begin(); }
1719
  iterator end() { return Blocks.end(); }
1720
 
1721
  const_iterator begin() const { return cbegin(); }
1722
  const_iterator end() const { return cend(); }
1723
 
1724
  const_iterator cbegin() const { return Blocks.cbegin(); }
1725
  const_iterator cend() const { return Blocks.cend(); }
1726
 
1727
  const BasicBlock *entry() const { return Entry; }
1728
  BasicBlock *entry() { return Entry; }
1729
  const BasicBlock *exit() const { return Exit; }
1730
  BasicBlock *exit() { return Exit; }
1731
 
1732
  /// Return the number of blocks in the CFG.
1733
  /// Block::blockID() will return a number less than numBlocks();
1734
  size_t numBlocks() const { return Blocks.size(); }
1735
 
1736
  /// Return the total number of instructions in the CFG.
1737
  /// This is useful for building instruction side-tables;
1738
  /// A call to SExpr::id() will return a number less than numInstructions().
1739
  unsigned numInstructions() { return NumInstructions; }
1740
 
1741
  inline void add(BasicBlock *BB) {
1742
    assert(BB->CFGPtr == nullptr);
1743
    BB->CFGPtr = this;
1744
    Blocks.reserveCheck(1, Arena);
1745
    Blocks.push_back(BB);
1746
  }
1747
 
1748
  void setEntry(BasicBlock *BB) { Entry = BB; }
1749
  void setExit(BasicBlock *BB)  { Exit = BB;  }
1750
 
1751
  void computeNormalForm();
1752
 
1753
  template <class V>
1754
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1755
    Vs.enterCFG(*this);
1756
    typename V::template Container<BasicBlock *> Bbs(Vs, Blocks.size());
1757
 
1758
    for (const auto *B : Blocks) {
1759
      Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) );
1760
    }
1761
    Vs.exitCFG(*this);
1762
    return Vs.reduceSCFG(*this, Bbs);
1763
  }
1764
 
1765
  template <class C>
1766
  typename C::CType compare(const SCFG *E, C &Cmp) const {
1767
    // TODO: implement CFG comparisons
1768
    return Cmp.comparePointers(this, E);
1769
  }
1770
 
1771
private:
1772
  // assign unique ids to all instructions
1773
  void renumberInstrs();
1774
 
1775
  MemRegionRef Arena;
1776
  BlockArray Blocks;
1777
  BasicBlock *Entry = nullptr;
1778
  BasicBlock *Exit = nullptr;
1779
  unsigned NumInstructions = 0;
1780
  bool Normal = false;
1781
};
1782
 
1783
/// An identifier, e.g. 'foo' or 'x'.
1784
/// This is a pseduo-term; it will be lowered to a variable or projection.
1785
class Identifier : public SExpr {
1786
public:
1787
  Identifier(StringRef Id): SExpr(COP_Identifier), Name(Id) {}
1788
  Identifier(const Identifier &) = default;
1789
 
1790
  static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; }
1791
 
1792
  StringRef name() const { return Name; }
1793
 
1794
  template <class V>
1795
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1796
    return Vs.reduceIdentifier(*this);
1797
  }
1798
 
1799
  template <class C>
1800
  typename C::CType compare(const Identifier* E, C& Cmp) const {
1801
    return Cmp.compareStrings(name(), E->name());
1802
  }
1803
 
1804
private:
1805
  StringRef Name;
1806
};
1807
 
1808
/// An if-then-else expression.
1809
/// This is a pseduo-term; it will be lowered to a branch in a CFG.
1810
class IfThenElse : public SExpr {
1811
public:
1812
  IfThenElse(SExpr *C, SExpr *T, SExpr *E)
1813
      : SExpr(COP_IfThenElse), Condition(C), ThenExpr(T), ElseExpr(E) {}
1814
  IfThenElse(const IfThenElse &I, SExpr *C, SExpr *T, SExpr *E)
1815
      : SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E) {}
1816
 
1817
  static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
1818
 
1819
  SExpr *condition() { return Condition; }   // Address to store to
1820
  const SExpr *condition() const { return Condition; }
1821
 
1822
  SExpr *thenExpr() { return ThenExpr; }     // Value to store
1823
  const SExpr *thenExpr() const { return ThenExpr; }
1824
 
1825
  SExpr *elseExpr() { return ElseExpr; }     // Value to store
1826
  const SExpr *elseExpr() const { return ElseExpr; }
1827
 
1828
  template <class V>
1829
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1830
    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
1831
    auto Nt = Vs.traverse(ThenExpr,  Vs.subExprCtx(Ctx));
1832
    auto Ne = Vs.traverse(ElseExpr,  Vs.subExprCtx(Ctx));
1833
    return Vs.reduceIfThenElse(*this, Nc, Nt, Ne);
1834
  }
1835
 
1836
  template <class C>
1837
  typename C::CType compare(const IfThenElse* E, C& Cmp) const {
1838
    typename C::CType Ct = Cmp.compare(condition(), E->condition());
1839
    if (Cmp.notTrue(Ct))
1840
      return Ct;
1841
    Ct = Cmp.compare(thenExpr(), E->thenExpr());
1842
    if (Cmp.notTrue(Ct))
1843
      return Ct;
1844
    return Cmp.compare(elseExpr(), E->elseExpr());
1845
  }
1846
 
1847
private:
1848
  SExpr* Condition;
1849
  SExpr* ThenExpr;
1850
  SExpr* ElseExpr;
1851
};
1852
 
1853
/// A let-expression,  e.g.  let x=t; u.
1854
/// This is a pseduo-term; it will be lowered to instructions in a CFG.
1855
class Let : public SExpr {
1856
public:
1857
  Let(Variable *Vd, SExpr *Bd) : SExpr(COP_Let), VarDecl(Vd), Body(Bd) {
1858
    Vd->setKind(Variable::VK_Let);
1859
  }
1860
 
1861
  Let(const Let &L, Variable *Vd, SExpr *Bd) : SExpr(L), VarDecl(Vd), Body(Bd) {
1862
    Vd->setKind(Variable::VK_Let);
1863
  }
1864
 
1865
  static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
1866
 
1867
  Variable *variableDecl()  { return VarDecl; }
1868
  const Variable *variableDecl() const { return VarDecl; }
1869
 
1870
  SExpr *body() { return Body; }
1871
  const SExpr *body() const { return Body; }
1872
 
1873
  template <class V>
1874
  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
1875
    // This is a variable declaration, so traverse the definition.
1876
    auto E0 = Vs.traverse(VarDecl->Definition, Vs.subExprCtx(Ctx));
1877
    // Tell the rewriter to enter the scope of the let variable.
1878
    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
1879
    auto E1 = Vs.traverse(Body, Ctx);
1880
    Vs.exitScope(*VarDecl);
1881
    return Vs.reduceLet(*this, Nvd, E1);
1882
  }
1883
 
1884
  template <class C>
1885
  typename C::CType compare(const Let* E, C& Cmp) const {
1886
    typename C::CType Ct =
1887
      Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
1888
    if (Cmp.notTrue(Ct))
1889
      return Ct;
1890
    Cmp.enterScope(variableDecl(), E->variableDecl());
1891
    Ct = Cmp.compare(body(), E->body());
1892
    Cmp.leaveScope();
1893
    return Ct;
1894
  }
1895
 
1896
private:
1897
  Variable *VarDecl;
1898
  SExpr* Body;
1899
};
1900
 
1901
const SExpr *getCanonicalVal(const SExpr *E);
1902
SExpr* simplifyToCanonicalVal(SExpr *E);
1903
void simplifyIncompleteArg(til::Phi *Ph);
1904
 
1905
} // namespace til
1906
} // namespace threadSafety
1907
 
1908
} // namespace clang
1909
 
1910
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H