]> granicus.if.org Git - clang/blobdiff - include/clang/Analysis/Analyses/ThreadSafetyTIL.h
Header guard canonicalization, clang part.
[clang] / include / clang / Analysis / Analyses / ThreadSafetyTIL.h
index 34e70552a601a21e2d3da706198cb4ea6d8d3240..4b7b092708e1653ed819670f4b7d467fe56d10bf 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_THREAD_SAFETY_TIL_H
-#define LLVM_CLANG_THREAD_SAFETY_TIL_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
 
 // All clang include dependencies for this file must be put in
 // ThreadSafetyUtil.h.
 #include "ThreadSafetyUtil.h"
 
 #include <stdint.h>
+#include <algorithm>
 #include <cassert>
 #include <cstddef>
 #include <utility>
@@ -99,6 +100,7 @@ enum TIL_CastOpcode : unsigned char {
   CAST_truncNum,    // truncate precision of numeric type
   CAST_toFloat,     // convert to floating point type
   CAST_toInt,       // convert to integer type
+  CAST_objToPtr     // convert smart pointer to pointer  (C++ only)
 };
 
 const TIL_Opcode       COP_Min  = COP_Future;
@@ -236,7 +238,7 @@ inline ValueType ValueType::getValueType<long double>() {
 
 template<>
 inline ValueType ValueType::getValueType<StringRef>() {
-  return ValueType(BT_Pointer, getSizeType(sizeof(StringRef)), false, 0);
+  return ValueType(BT_String, getSizeType(sizeof(StringRef)), false, 0);
 }
 
 template<>
@@ -404,7 +406,8 @@ public:
     return Vs.reduceVariableRef(this);
   }
 
-  template <class C> typename C::CType compare(Variable* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Variable* E, C& Cmp) const {
     return Cmp.compareVariableRefs(this, E);
   }
 
@@ -454,7 +457,7 @@ public:
   virtual SExpr *create() { return nullptr; }
 
   // Return the result of this future if it exists, otherwise return null.
-  SExpr *maybeGetResult() {
+  SExpr *maybeGetResult() const {
     return Result;
   }
 
@@ -477,7 +480,8 @@ public:
     return Vs.traverse(Result, Ctx);
   }
 
-  template <class C> typename C::CType compare(Future* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Future* E, C& Cmp) const {
     if (!Result || !E->Result)
       return Cmp.comparePointers(this, E);
     return Cmp.compare(Result, E->Result);
@@ -571,8 +575,9 @@ public:
     return Vs.reduceUndefined(*this);
   }
 
-  template <class C> typename C::CType compare(Undefined* E, C& Cmp) {
-    return Cmp.comparePointers(Cstmt, E->Cstmt);
+  template <class C>
+  typename C::CType compare(const Undefined* E, C& Cmp) const {
+    return Cmp.trueResult();
   }
 
 private:
@@ -592,21 +597,24 @@ public:
     return Vs.reduceWildcard(*this);
   }
 
-  template <class C> typename C::CType compare(Wildcard* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Wildcard* E, C& Cmp) const {
     return Cmp.trueResult();
   }
 };
 
 
+template <class T> class LiteralT;
+
 // Base class for literal values.
 class Literal : public SExpr {
 public:
   static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
 
   Literal(const clang::Expr *C)
-     : SExpr(COP_Literal), ValType(ValueType::getValueType<void>())
+     : SExpr(COP_Literal), ValType(ValueType::getValueType<void>()), Cexpr(C)
   { }
-  Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT) {}
+  Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT), Cexpr(nullptr) {}
   Literal(const Literal &L) : SExpr(L), ValType(L.ValType), Cexpr(L.Cexpr) {}
 
   // The clang expression for this literal.
@@ -614,14 +622,22 @@ public:
 
   ValueType valueType() const { return ValType; }
 
+  template<class T> const LiteralT<T>& as() const {
+    return *static_cast<const LiteralT<T>*>(this);
+  }
+  template<class T> LiteralT<T>& as() {
+    return *static_cast<LiteralT<T>*>(this);
+  }
+
   template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx);
 
-  template <class C> typename C::CType compare(Literal* E, C& Cmp) {
-    // TODO -- use value, not pointer equality
-    return Cmp.comparePointers(Cexpr, E->Cexpr);
+  template <class C>
+  typename C::CType compare(const Literal* E, C& Cmp) const {
+    // TODO: defer actual comparison to LiteralT
+    return Cmp.trueResult();
   }
 
-protected:
+private:
   const ValueType ValType;
   const clang::Expr *Cexpr;
 };
@@ -642,6 +658,7 @@ private:
 };
 
 
+
 template <class V>
 typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
   if (Cexpr)
@@ -651,29 +668,29 @@ typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
   case ValueType::BT_Void:
     break;
   case ValueType::BT_Bool:
-    return Vs.reduceLiteralT(*static_cast<LiteralT<bool>*>(this));
+    return Vs.reduceLiteralT(as<bool>());
   case ValueType::BT_Int: {
     switch (ValType.Size) {
     case ValueType::ST_8:
       if (ValType.Signed)
-        return Vs.reduceLiteralT(*static_cast<LiteralT<int8_t>*>(this));
+        return Vs.reduceLiteralT(as<int8_t>());
       else
-        return Vs.reduceLiteralT(*static_cast<LiteralT<uint8_t>*>(this));
+        return Vs.reduceLiteralT(as<uint8_t>());
     case ValueType::ST_16:
       if (ValType.Signed)
-        return Vs.reduceLiteralT(*static_cast<LiteralT<int16_t>*>(this));
+        return Vs.reduceLiteralT(as<int16_t>());
       else
-        return Vs.reduceLiteralT(*static_cast<LiteralT<uint16_t>*>(this));
+        return Vs.reduceLiteralT(as<uint16_t>());
     case ValueType::ST_32:
       if (ValType.Signed)
-        return Vs.reduceLiteralT(*static_cast<LiteralT<int32_t>*>(this));
+        return Vs.reduceLiteralT(as<int32_t>());
       else
-        return Vs.reduceLiteralT(*static_cast<LiteralT<uint32_t>*>(this));
+        return Vs.reduceLiteralT(as<uint32_t>());
     case ValueType::ST_64:
       if (ValType.Signed)
-        return Vs.reduceLiteralT(*static_cast<LiteralT<int64_t>*>(this));
+        return Vs.reduceLiteralT(as<int64_t>());
       else
-        return Vs.reduceLiteralT(*static_cast<LiteralT<uint64_t>*>(this));
+        return Vs.reduceLiteralT(as<uint64_t>());
     default:
       break;
     }
@@ -681,17 +698,17 @@ typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
   case ValueType::BT_Float: {
     switch (ValType.Size) {
     case ValueType::ST_32:
-      return Vs.reduceLiteralT(*static_cast<LiteralT<float>*>(this));
+      return Vs.reduceLiteralT(as<float>());
     case ValueType::ST_64:
-      return Vs.reduceLiteralT(*static_cast<LiteralT<double>*>(this));
+      return Vs.reduceLiteralT(as<double>());
     default:
       break;
     }
   }
   case ValueType::BT_String:
-    return Vs.reduceLiteralT(*static_cast<LiteralT<StringRef>*>(this));
+    return Vs.reduceLiteralT(as<StringRef>());
   case ValueType::BT_Pointer:
-    return Vs.reduceLiteralT(*static_cast<LiteralT<void*>*>(this));
+    return Vs.reduceLiteralT(as<void*>());
   case ValueType::BT_ValueRef:
     break;
   }
@@ -716,7 +733,8 @@ public:
     return Vs.reduceLiteralPtr(*this);
   }
 
-  template <class C> typename C::CType compare(LiteralPtr* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const LiteralPtr* E, C& Cmp) const {
     return Cmp.comparePointers(Cvdecl, E->Cvdecl);
   }
 
@@ -758,7 +776,8 @@ public:
     return Vs.reduceFunction(*this, Nvd, E1);
   }
 
-  template <class C> typename C::CType compare(Function* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Function* E, C& Cmp) const {
     typename C::CType Ct =
       Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
     if (Cmp.notTrue(Ct))
@@ -813,7 +832,8 @@ public:
     return Vs.reduceSFunction(*this, Nvd, E1);
   }
 
-  template <class C> typename C::CType compare(SFunction* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const SFunction* E, C& Cmp) const {
     Cmp.enterScope(variableDecl(), E->variableDecl());
     typename C::CType Ct = Cmp.compare(body(), E->body());
     Cmp.leaveScope();
@@ -848,7 +868,8 @@ public:
     return Vs.reduceCode(*this, Nt, Nb);
   }
 
-  template <class C> typename C::CType compare(Code* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Code* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -883,7 +904,8 @@ public:
     return Vs.reduceField(*this, Nr, Nb);
   }
 
-  template <class C> typename C::CType compare(Field* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Field* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(range(), E->range());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -919,7 +941,8 @@ public:
     return Vs.reduceApply(*this, Nf, Na);
   }
 
-  template <class C> typename C::CType compare(Apply* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Apply* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(fun(), E->fun());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -947,7 +970,7 @@ public:
   SExpr *arg() { return Arg.get() ? Arg.get() : Sfun.get(); }
   const SExpr *arg() const { return Arg.get() ? Arg.get() : Sfun.get(); }
 
-  bool isDelegation() const { return Arg == nullptr; }
+  bool isDelegation() const { return Arg != nullptr; }
 
   template <class V>
   typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -957,7 +980,8 @@ public:
     return Vs.reduceSApply(*this, Nf, Na);
   }
 
-  template <class C> typename C::CType compare(SApply* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const SApply* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
     if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
       return Ct;
@@ -978,7 +1002,7 @@ public:
   Project(SExpr *R, StringRef SName)
       : SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
   { }
-  Project(SExpr *R, clang::ValueDecl *Cvd)
+  Project(SExpr *R, const clang::ValueDecl *Cvd)
       : SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
   { }
   Project(const Project &P, SExpr *R)
@@ -988,7 +1012,13 @@ public:
   SExpr *record() { return Rec.get(); }
   const SExpr *record() const { return Rec.get(); }
 
-  const clang::ValueDecl *clangValueDecl() const { return Cvdecl; }
+  const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+  bool isArrow() const { return (Flags & 0x01) != 0; }
+  void setArrow(bool b) {
+    if (b) Flags |= 0x01;
+    else Flags &= 0xFFFE;
+  }
 
   StringRef slotName() const {
     if (Cvdecl)
@@ -1003,7 +1033,8 @@ public:
     return Vs.reduceProject(*this, Nr);
   }
 
-  template <class C> typename C::CType compare(Project* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Project* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(record(), E->record());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -1013,7 +1044,7 @@ public:
 private:
   SExprRef Rec;
   StringRef SlotName;
-  clang::ValueDecl *Cvdecl;
+  const clang::ValueDecl *Cvdecl;
 };
 
 
@@ -1037,7 +1068,8 @@ public:
     return Vs.reduceCall(*this, Nt);
   }
 
-  template <class C> typename C::CType compare(Call* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Call* E, C& Cmp) const {
     return Cmp.compare(target(), E->target());
   }
 
@@ -1071,7 +1103,8 @@ public:
     return Vs.reduceAlloc(*this, Nd);
   }
 
-  template <class C> typename C::CType compare(Alloc* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Alloc* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -1100,7 +1133,8 @@ public:
     return Vs.reduceLoad(*this, Np);
   }
 
-  template <class C> typename C::CType compare(Load* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Load* E, C& Cmp) const {
     return Cmp.compare(pointer(), E->pointer());
   }
 
@@ -1131,7 +1165,8 @@ public:
     return Vs.reduceStore(*this, Np, Nv);
   }
 
-  template <class C> typename C::CType compare(Store* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Store* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(destination(), E->destination());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -1167,7 +1202,8 @@ public:
     return Vs.reduceArrayIndex(*this, Na, Ni);
   }
 
-  template <class C> typename C::CType compare(ArrayIndex* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const ArrayIndex* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(array(), E->array());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -1204,7 +1240,8 @@ public:
     return Vs.reduceArrayAdd(*this, Na, Ni);
   }
 
-  template <class C> typename C::CType compare(ArrayAdd* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const ArrayAdd* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(array(), E->array());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -1240,7 +1277,8 @@ public:
     return Vs.reduceUnaryOp(*this, Ne);
   }
 
-  template <class C> typename C::CType compare(UnaryOp* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const UnaryOp* E, C& Cmp) const {
     typename C::CType Ct =
       Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
     if (Cmp.notTrue(Ct))
@@ -1284,7 +1322,8 @@ public:
     return Vs.reduceBinaryOp(*this, Ne0, Ne1);
   }
 
-  template <class C> typename C::CType compare(BinaryOp* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const BinaryOp* E, C& Cmp) const {
     typename C::CType Ct =
       Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
     if (Cmp.notTrue(Ct))
@@ -1322,7 +1361,8 @@ public:
     return Vs.reduceCast(*this, Ne);
   }
 
-  template <class C> typename C::CType compare(Cast* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Cast* E, C& Cmp) const {
     typename C::CType Ct =
       Cmp.compareIntegers(castOpcode(), E->castOpcode());
     if (Cmp.notTrue(Ct))
@@ -1375,7 +1415,8 @@ public:
     return Vs.reducePhi(*this, Nvs);
   }
 
-  template <class C> typename C::CType compare(Phi *E, C &Cmp) {
+  template <class C>
+  typename C::CType compare(const Phi *E, C &Cmp) const {
     // TODO: implement CFG comparisons
     return Cmp.comparePointers(this, E);
   }
@@ -1458,13 +1499,9 @@ public:
   void reservePredecessors(unsigned NumPreds);
 
   // Return the index of BB, or Predecessors.size if BB is not a predecessor.
-  unsigned findPredecessorIndex(BasicBlock *BB) {
-    unsigned I = 0;
-    for (BasicBlock *B : Predecessors) {
-      if (B == BB) return I;
-      ++I;
-    }
-    return Predecessors.size();
+  unsigned findPredecessorIndex(const BasicBlock *BB) const {
+    auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB);
+    return std::distance(Predecessors.cbegin(), I);
   }
 
   // Set id numbers for variables.
@@ -1496,7 +1533,8 @@ public:
     return Vs.reduceBasicBlock(*this, Nas, Nis, Nt);
   }
 
-  template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
+  template <class C>
+  typename C::CType compare(const BasicBlock *E, C &Cmp) const {
     // TODO: implement CFG comparisons
     return Cmp.comparePointers(this, E);
   }
@@ -1583,7 +1621,8 @@ public:
     return Vs.reduceSCFG(*this, Bbs);
   }
 
-  template <class C> typename C::CType compare(SCFG *E, C &Cmp) {
+  template <class C>
+  typename C::CType compare(const SCFG *E, C &Cmp) const {
     // TODO -- implement CFG comparisons
     return Cmp.comparePointers(this, E);
   }
@@ -1616,7 +1655,8 @@ public:
     return Vs.reduceGoto(*this, Ntb);
   }
 
-  template <class C> typename C::CType compare(Goto *E, C &Cmp) {
+  template <class C>
+  typename C::CType compare(const Goto *E, C &Cmp) const {
     // TODO -- implement CFG comparisons
     return Cmp.comparePointers(this, E);
   }
@@ -1661,7 +1701,8 @@ public:
     return Vs.reduceBranch(*this, Nc, Ntb, Nte);
   }
 
-  template <class C> typename C::CType compare(Branch *E, C &Cmp) {
+  template <class C>
+  typename C::CType compare(const Branch *E, C &Cmp) const {
     // TODO -- implement CFG comparisons
     return Cmp.comparePointers(this, E);
   }
@@ -1691,7 +1732,8 @@ public:
     return Vs.reduceIdentifier(*this);
   }
 
-  template <class C> typename C::CType compare(Identifier* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Identifier* E, C& Cmp) const {
     return Cmp.compareStrings(name(), E->name());
   }
 
@@ -1730,7 +1772,8 @@ public:
     return Vs.reduceIfThenElse(*this, Nc, Nt, Ne);
   }
 
-  template <class C> typename C::CType compare(IfThenElse* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const IfThenElse* E, C& Cmp) const {
     typename C::CType Ct = Cmp.compare(condition(), E->condition());
     if (Cmp.notTrue(Ct))
       return Ct;
@@ -1777,7 +1820,8 @@ public:
     return Vs.reduceLet(*this, Nvd, E1);
   }
 
-  template <class C> typename C::CType compare(Let* E, C& Cmp) {
+  template <class C>
+  typename C::CType compare(const Let* E, C& Cmp) const {
     typename C::CType Ct =
       Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
     if (Cmp.notTrue(Ct))
@@ -1795,7 +1839,8 @@ private:
 
 
 
-SExpr *getCanonicalVal(SExpr *E);
+const SExpr *getCanonicalVal(const SExpr *E);
+SExpr* simplifyToCanonicalVal(SExpr *E);
 void simplifyIncompleteArg(Variable *V, til::Phi *Ph);
 
 
@@ -1803,4 +1848,4 @@ void simplifyIncompleteArg(Variable *V, til::Phi *Ph);
 } // end namespace threadSafety
 } // end namespace clang
 
-#endif // LLVM_CLANG_THREAD_SAFETY_TIL_H
+#endif