clang API Documentation
00001 //===- ThreadSafetyLogical.h -----------------------------------*- C++ --*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // This file defines a representation for logical expressions with SExpr leaves 00010 // that are used as part of fact-checking capability expressions. 00011 //===----------------------------------------------------------------------===// 00012 00013 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYLOGICAL_H 00014 #define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYLOGICAL_H 00015 00016 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h" 00017 00018 namespace clang { 00019 namespace threadSafety { 00020 namespace lexpr { 00021 00022 class LExpr { 00023 public: 00024 enum Opcode { 00025 Terminal, 00026 And, 00027 Or, 00028 Not 00029 }; 00030 Opcode kind() const { return Kind; } 00031 00032 /// \brief Logical implication. Returns true if the LExpr implies RHS, i.e. if 00033 /// the LExpr holds, then RHS must hold. For example, (A & B) implies A. 00034 inline bool implies(const LExpr *RHS) const; 00035 00036 protected: 00037 LExpr(Opcode Kind) : Kind(Kind) {} 00038 00039 private: 00040 Opcode Kind; 00041 }; 00042 00043 class Terminal : public LExpr { 00044 til::SExpr *Expr; 00045 00046 public: 00047 Terminal(til::SExpr *Expr) : LExpr(LExpr::Terminal), Expr(Expr) {} 00048 00049 const til::SExpr *expr() const { return Expr; } 00050 til::SExpr *expr() { return Expr; } 00051 00052 static bool classof(const LExpr *E) { return E->kind() == LExpr::Terminal; } 00053 }; 00054 00055 class BinOp : public LExpr { 00056 LExpr *LHS, *RHS; 00057 00058 protected: 00059 BinOp(LExpr *LHS, LExpr *RHS, Opcode Code) : LExpr(Code), LHS(LHS), RHS(RHS) {} 00060 00061 public: 00062 const LExpr *left() const { return LHS; } 00063 LExpr *left() { return LHS; } 00064 00065 const LExpr *right() const { return RHS; } 00066 LExpr *right() { return RHS; } 00067 }; 00068 00069 class And : public BinOp { 00070 public: 00071 And(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::And) {} 00072 00073 static bool classof(const LExpr *E) { return E->kind() == LExpr::And; } 00074 }; 00075 00076 class Or : public BinOp { 00077 public: 00078 Or(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::Or) {} 00079 00080 static bool classof(const LExpr *E) { return E->kind() == LExpr::Or; } 00081 }; 00082 00083 class Not : public LExpr { 00084 LExpr *Exp; 00085 00086 public: 00087 Not(LExpr *Exp) : LExpr(LExpr::Not), Exp(Exp) {} 00088 00089 const LExpr *exp() const { return Exp; } 00090 LExpr *exp() { return Exp; } 00091 00092 static bool classof(const LExpr *E) { return E->kind() == LExpr::Not; } 00093 }; 00094 00095 /// \brief Logical implication. Returns true if LHS implies RHS, i.e. if LHS 00096 /// holds, then RHS must hold. For example, (A & B) implies A. 00097 bool implies(const LExpr *LHS, const LExpr *RHS); 00098 00099 bool LExpr::implies(const LExpr *RHS) const { 00100 return lexpr::implies(this, RHS); 00101 } 00102 00103 } 00104 } 00105 } 00106 00107 #endif 00108