clang API Documentation

ThreadSafetyLogical.h
Go to the documentation of this file.
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