//
//===----------------------------------------------------------------------===//
-#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.
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;
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);
}
virtual SExpr *create() { return nullptr; }
// Return the result of this future if it exists, otherwise return null.
- SExpr *maybeGetResult() {
+ SExpr *maybeGetResult() const {
return Result;
}
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);
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:
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 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();
}
private:
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);
}
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))
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();
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;
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;
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;
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) {
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;
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)
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)
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;
private:
SExprRef Rec;
StringRef SlotName;
- clang::ValueDecl *Cvdecl;
+ const clang::ValueDecl *Cvdecl;
};
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());
}
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;
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());
}
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;
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;
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;
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))
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))
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))
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);
}
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);
}
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);
}
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);
}
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);
}
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());
}
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;
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))
-SExpr *getCanonicalVal(SExpr *E);
+const SExpr *getCanonicalVal(const SExpr *E);
+SExpr* simplifyToCanonicalVal(SExpr *E);
void simplifyIncompleteArg(Variable *V, til::Phi *Ph);
} // end namespace threadSafety
} // end namespace clang
-#endif // LLVM_CLANG_THREAD_SAFETY_TIL_H
+#endif