clang API Documentation

ThreadSafetyCommon.cpp
Go to the documentation of this file.
00001 //===- ThreadSafetyCommon.cpp ----------------------------------*- 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 //
00010 // Implementation of the interfaces declared in ThreadSafetyCommon.h
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Analysis/Analyses/ThreadSafetyCommon.h"
00015 #include "clang/AST/Attr.h"
00016 #include "clang/AST/DeclCXX.h"
00017 #include "clang/AST/DeclObjC.h"
00018 #include "clang/AST/ExprCXX.h"
00019 #include "clang/AST/StmtCXX.h"
00020 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
00021 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
00022 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
00023 #include "clang/Analysis/AnalysisContext.h"
00024 #include "clang/Analysis/CFG.h"
00025 #include "clang/Basic/OperatorKinds.h"
00026 #include "clang/Basic/SourceLocation.h"
00027 #include "clang/Basic/SourceManager.h"
00028 #include "llvm/ADT/DenseMap.h"
00029 #include "llvm/ADT/SmallVector.h"
00030 #include "llvm/ADT/StringRef.h"
00031 
00032 #include <algorithm>
00033 #include <climits>
00034 #include <vector>
00035 
00036 
00037 namespace clang {
00038 namespace threadSafety {
00039 
00040 // From ThreadSafetyUtil.h
00041 std::string getSourceLiteralString(const clang::Expr *CE) {
00042   switch (CE->getStmtClass()) {
00043     case Stmt::IntegerLiteralClass:
00044       return cast<IntegerLiteral>(CE)->getValue().toString(10, true);
00045     case Stmt::StringLiteralClass: {
00046       std::string ret("\"");
00047       ret += cast<StringLiteral>(CE)->getString();
00048       ret += "\"";
00049       return ret;
00050     }
00051     case Stmt::CharacterLiteralClass:
00052     case Stmt::CXXNullPtrLiteralExprClass:
00053     case Stmt::GNUNullExprClass:
00054     case Stmt::CXXBoolLiteralExprClass:
00055     case Stmt::FloatingLiteralClass:
00056     case Stmt::ImaginaryLiteralClass:
00057     case Stmt::ObjCStringLiteralClass:
00058     default:
00059       return "#lit";
00060   }
00061 }
00062 
00063 namespace til {
00064 
00065 // Return true if E is a variable that points to an incomplete Phi node.
00066 static bool isIncompletePhi(const SExpr *E) {
00067   if (const auto *Ph = dyn_cast<Phi>(E))
00068     return Ph->status() == Phi::PH_Incomplete;
00069   return false;
00070 }
00071 
00072 }  // end namespace til
00073 
00074 
00075 typedef SExprBuilder::CallingContext CallingContext;
00076 
00077 
00078 til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) {
00079   auto It = SMap.find(S);
00080   if (It != SMap.end())
00081     return It->second;
00082   return nullptr;
00083 }
00084 
00085 
00086 til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) {
00087   Walker.walk(*this);
00088   return Scfg;
00089 }
00090 
00091 
00092 
00093 inline bool isCalleeArrow(const Expr *E) {
00094   const MemberExpr *ME = dyn_cast<MemberExpr>(E->IgnoreParenCasts());
00095   return ME ? ME->isArrow() : false;
00096 }
00097 
00098 
00099 /// \brief Translate a clang expression in an attribute to a til::SExpr.
00100 /// Constructs the context from D, DeclExp, and SelfDecl.
00101 ///
00102 /// \param AttrExp The expression to translate.
00103 /// \param D       The declaration to which the attribute is attached.
00104 /// \param DeclExp An expression involving the Decl to which the attribute
00105 ///                is attached.  E.g. the call to a function.
00106 CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp,
00107                                                const NamedDecl *D,
00108                                                const Expr *DeclExp,
00109                                                VarDecl *SelfDecl) {
00110   // If we are processing a raw attribute expression, with no substitutions.
00111   if (!DeclExp)
00112     return translateAttrExpr(AttrExp, nullptr);
00113 
00114   CallingContext Ctx(nullptr, D);
00115 
00116   // Examine DeclExp to find SelfArg and FunArgs, which are used to substitute
00117   // for formal parameters when we call buildMutexID later.
00118   if (const MemberExpr *ME = dyn_cast<MemberExpr>(DeclExp)) {
00119     Ctx.SelfArg   = ME->getBase();
00120     Ctx.SelfArrow = ME->isArrow();
00121   } else if (const CXXMemberCallExpr *CE =
00122              dyn_cast<CXXMemberCallExpr>(DeclExp)) {
00123     Ctx.SelfArg   = CE->getImplicitObjectArgument();
00124     Ctx.SelfArrow = isCalleeArrow(CE->getCallee());
00125     Ctx.NumArgs   = CE->getNumArgs();
00126     Ctx.FunArgs   = CE->getArgs();
00127   } else if (const CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
00128     Ctx.NumArgs = CE->getNumArgs();
00129     Ctx.FunArgs = CE->getArgs();
00130   } else if (const CXXConstructExpr *CE =
00131              dyn_cast<CXXConstructExpr>(DeclExp)) {
00132     Ctx.SelfArg = nullptr;  // Will be set below
00133     Ctx.NumArgs = CE->getNumArgs();
00134     Ctx.FunArgs = CE->getArgs();
00135   } else if (D && isa<CXXDestructorDecl>(D)) {
00136     // There's no such thing as a "destructor call" in the AST.
00137     Ctx.SelfArg = DeclExp;
00138   }
00139 
00140   // Hack to handle constructors, where self cannot be recovered from
00141   // the expression.
00142   if (SelfDecl && !Ctx.SelfArg) {
00143     DeclRefExpr SelfDRE(SelfDecl, false, SelfDecl->getType(), VK_LValue,
00144                         SelfDecl->getLocation());
00145     Ctx.SelfArg = &SelfDRE;
00146 
00147     // If the attribute has no arguments, then assume the argument is "this".
00148     if (!AttrExp)
00149       return translateAttrExpr(Ctx.SelfArg, nullptr);
00150     else  // For most attributes.
00151       return translateAttrExpr(AttrExp, &Ctx);
00152   }
00153 
00154   // If the attribute has no arguments, then assume the argument is "this".
00155   if (!AttrExp)
00156     return translateAttrExpr(Ctx.SelfArg, nullptr);
00157   else  // For most attributes.
00158     return translateAttrExpr(AttrExp, &Ctx);
00159 }
00160 
00161 
00162 /// \brief Translate a clang expression in an attribute to a til::SExpr.
00163 // This assumes a CallingContext has already been created.
00164 CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp,
00165                                                CallingContext *Ctx) {
00166   if (!AttrExp)
00167     return CapabilityExpr(nullptr, false);
00168 
00169   if (auto* SLit = dyn_cast<StringLiteral>(AttrExp)) {
00170     if (SLit->getString() == StringRef("*"))
00171       // The "*" expr is a universal lock, which essentially turns off
00172       // checks until it is removed from the lockset.
00173       return CapabilityExpr(new (Arena) til::Wildcard(), false);
00174     else
00175       // Ignore other string literals for now.
00176       return CapabilityExpr(nullptr, false);
00177   }
00178 
00179   bool Neg = false;
00180   if (auto *OE = dyn_cast<CXXOperatorCallExpr>(AttrExp)) {
00181     if (OE->getOperator() == OO_Exclaim) {
00182       Neg = true;
00183       AttrExp = OE->getArg(0);
00184     }
00185   }
00186   else if (auto *UO = dyn_cast<UnaryOperator>(AttrExp)) {
00187     if (UO->getOpcode() == UO_LNot) {
00188       Neg = true;
00189       AttrExp = UO->getSubExpr();
00190     }
00191   }
00192 
00193   til::SExpr *E = translate(AttrExp, Ctx);
00194 
00195   // Trap mutex expressions like nullptr, or 0.
00196   // Any literal value is nonsense.
00197   if (!E || isa<til::Literal>(E))
00198     return CapabilityExpr(nullptr, false);
00199 
00200   // Hack to deal with smart pointers -- strip off top-level pointer casts.
00201   if (auto *CE = dyn_cast_or_null<til::Cast>(E)) {
00202     if (CE->castOpcode() == til::CAST_objToPtr)
00203       return CapabilityExpr(CE->expr(), Neg);
00204   }
00205   return CapabilityExpr(E, Neg);
00206 }
00207 
00208 
00209 
00210 // Translate a clang statement or expression to a TIL expression.
00211 // Also performs substitution of variables; Ctx provides the context.
00212 // Dispatches on the type of S.
00213 til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) {
00214   if (!S)
00215     return nullptr;
00216 
00217   // Check if S has already been translated and cached.
00218   // This handles the lookup of SSA names for DeclRefExprs here.
00219   if (til::SExpr *E = lookupStmt(S))
00220     return E;
00221 
00222   switch (S->getStmtClass()) {
00223   case Stmt::DeclRefExprClass:
00224     return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx);
00225   case Stmt::CXXThisExprClass:
00226     return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx);
00227   case Stmt::MemberExprClass:
00228     return translateMemberExpr(cast<MemberExpr>(S), Ctx);
00229   case Stmt::CallExprClass:
00230     return translateCallExpr(cast<CallExpr>(S), Ctx);
00231   case Stmt::CXXMemberCallExprClass:
00232     return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
00233   case Stmt::CXXOperatorCallExprClass:
00234     return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
00235   case Stmt::UnaryOperatorClass:
00236     return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
00237   case Stmt::BinaryOperatorClass:
00238   case Stmt::CompoundAssignOperatorClass:
00239     return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
00240 
00241   case Stmt::ArraySubscriptExprClass:
00242     return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
00243   case Stmt::ConditionalOperatorClass:
00244     return translateAbstractConditionalOperator(
00245              cast<ConditionalOperator>(S), Ctx);
00246   case Stmt::BinaryConditionalOperatorClass:
00247     return translateAbstractConditionalOperator(
00248              cast<BinaryConditionalOperator>(S), Ctx);
00249 
00250   // We treat these as no-ops
00251   case Stmt::ParenExprClass:
00252     return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx);
00253   case Stmt::ExprWithCleanupsClass:
00254     return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
00255   case Stmt::CXXBindTemporaryExprClass:
00256     return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
00257 
00258   // Collect all literals
00259   case Stmt::CharacterLiteralClass:
00260   case Stmt::CXXNullPtrLiteralExprClass:
00261   case Stmt::GNUNullExprClass:
00262   case Stmt::CXXBoolLiteralExprClass:
00263   case Stmt::FloatingLiteralClass:
00264   case Stmt::ImaginaryLiteralClass:
00265   case Stmt::IntegerLiteralClass:
00266   case Stmt::StringLiteralClass:
00267   case Stmt::ObjCStringLiteralClass:
00268     return new (Arena) til::Literal(cast<Expr>(S));
00269 
00270   case Stmt::DeclStmtClass:
00271     return translateDeclStmt(cast<DeclStmt>(S), Ctx);
00272   default:
00273     break;
00274   }
00275   if (const CastExpr *CE = dyn_cast<CastExpr>(S))
00276     return translateCastExpr(CE, Ctx);
00277 
00278   return new (Arena) til::Undefined(S);
00279 }
00280 
00281 
00282 
00283 til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
00284                                                CallingContext *Ctx) {
00285   const ValueDecl *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
00286 
00287   // Function parameters require substitution and/or renaming.
00288   if (const ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
00289     const FunctionDecl *FD =
00290         cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
00291     unsigned I = PV->getFunctionScopeIndex();
00292 
00293     if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
00294       // Substitute call arguments for references to function parameters
00295       assert(I < Ctx->NumArgs);
00296       return translate(Ctx->FunArgs[I], Ctx->Prev);
00297     }
00298     // Map the param back to the param of the original function declaration
00299     // for consistent comparisons.
00300     VD = FD->getParamDecl(I);
00301   }
00302 
00303   // For non-local variables, treat it as a referenced to a named object.
00304   return new (Arena) til::LiteralPtr(VD);
00305 }
00306 
00307 
00308 til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE,
00309                                                CallingContext *Ctx) {
00310   // Substitute for 'this'
00311   if (Ctx && Ctx->SelfArg)
00312     return translate(Ctx->SelfArg, Ctx->Prev);
00313   assert(SelfVar && "We have no variable for 'this'!");
00314   return SelfVar;
00315 }
00316 
00317 
00318 const ValueDecl *getValueDeclFromSExpr(const til::SExpr *E) {
00319   if (auto *V = dyn_cast<til::Variable>(E))
00320     return V->clangDecl();
00321   if (auto *Ph = dyn_cast<til::Phi>(E))
00322     return Ph->clangDecl();
00323   if (auto *P = dyn_cast<til::Project>(E))
00324     return P->clangDecl();
00325   if (auto *L = dyn_cast<til::LiteralPtr>(E))
00326     return L->clangDecl();
00327   return 0;
00328 }
00329 
00330 bool hasCppPointerType(const til::SExpr *E) {
00331   auto *VD = getValueDeclFromSExpr(E);
00332   if (VD && VD->getType()->isPointerType())
00333     return true;
00334   if (auto *C = dyn_cast<til::Cast>(E))
00335     return C->castOpcode() == til::CAST_objToPtr;
00336 
00337   return false;
00338 }
00339 
00340 
00341 // Grab the very first declaration of virtual method D
00342 const CXXMethodDecl* getFirstVirtualDecl(const CXXMethodDecl *D) {
00343   while (true) {
00344     D = D->getCanonicalDecl();
00345     CXXMethodDecl::method_iterator I = D->begin_overridden_methods(),
00346                                    E = D->end_overridden_methods();
00347     if (I == E)
00348       return D;  // Method does not override anything
00349     D = *I;      // FIXME: this does not work with multiple inheritance.
00350   }
00351   return nullptr;
00352 }
00353 
00354 til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME,
00355                                               CallingContext *Ctx) {
00356   til::SExpr *BE = translate(ME->getBase(), Ctx);
00357   til::SExpr *E  = new (Arena) til::SApply(BE);
00358 
00359   const ValueDecl *D = ME->getMemberDecl();
00360   if (auto *VD = dyn_cast<CXXMethodDecl>(D))
00361     D = getFirstVirtualDecl(VD);
00362 
00363   til::Project *P = new (Arena) til::Project(E, D);
00364   if (hasCppPointerType(BE))
00365     P->setArrow(true);
00366   return P;
00367 }
00368 
00369 
00370 til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE,
00371                                             CallingContext *Ctx,
00372                                             const Expr *SelfE) {
00373   if (CapabilityExprMode) {
00374     // Handle LOCK_RETURNED
00375     const FunctionDecl *FD = CE->getDirectCallee()->getMostRecentDecl();
00376     if (LockReturnedAttr* At = FD->getAttr<LockReturnedAttr>()) {
00377       CallingContext LRCallCtx(Ctx);
00378       LRCallCtx.AttrDecl = CE->getDirectCallee();
00379       LRCallCtx.SelfArg  = SelfE;
00380       LRCallCtx.NumArgs  = CE->getNumArgs();
00381       LRCallCtx.FunArgs  = CE->getArgs();
00382       return const_cast<til::SExpr*>(
00383           translateAttrExpr(At->getArg(), &LRCallCtx).sexpr());
00384     }
00385   }
00386 
00387   til::SExpr *E = translate(CE->getCallee(), Ctx);
00388   for (const auto *Arg : CE->arguments()) {
00389     til::SExpr *A = translate(Arg, Ctx);
00390     E = new (Arena) til::Apply(E, A);
00391   }
00392   return new (Arena) til::Call(E, CE);
00393 }
00394 
00395 
00396 til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
00397     const CXXMemberCallExpr *ME, CallingContext *Ctx) {
00398   if (CapabilityExprMode) {
00399     // Ignore calls to get() on smart pointers.
00400     if (ME->getMethodDecl()->getNameAsString() == "get" &&
00401         ME->getNumArgs() == 0) {
00402       auto *E = translate(ME->getImplicitObjectArgument(), Ctx);
00403       return new (Arena) til::Cast(til::CAST_objToPtr, E);
00404       // return E;
00405     }
00406   }
00407   return translateCallExpr(cast<CallExpr>(ME), Ctx,
00408                            ME->getImplicitObjectArgument());
00409 }
00410 
00411 
00412 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
00413     const CXXOperatorCallExpr *OCE, CallingContext *Ctx) {
00414   if (CapabilityExprMode) {
00415     // Ignore operator * and operator -> on smart pointers.
00416     OverloadedOperatorKind k = OCE->getOperator();
00417     if (k == OO_Star || k == OO_Arrow) {
00418       auto *E = translate(OCE->getArg(0), Ctx);
00419       return new (Arena) til::Cast(til::CAST_objToPtr, E);
00420       // return E;
00421     }
00422   }
00423   return translateCallExpr(cast<CallExpr>(OCE), Ctx);
00424 }
00425 
00426 
00427 til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO,
00428                                                  CallingContext *Ctx) {
00429   switch (UO->getOpcode()) {
00430   case UO_PostInc:
00431   case UO_PostDec:
00432   case UO_PreInc:
00433   case UO_PreDec:
00434     return new (Arena) til::Undefined(UO);
00435 
00436   case UO_AddrOf: {
00437     if (CapabilityExprMode) {
00438       // interpret &Graph::mu_ as an existential.
00439       if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr())) {
00440         if (DRE->getDecl()->isCXXInstanceMember()) {
00441           // This is a pointer-to-member expression, e.g. &MyClass::mu_.
00442           // We interpret this syntax specially, as a wildcard.
00443           auto *W = new (Arena) til::Wildcard();
00444           return new (Arena) til::Project(W, DRE->getDecl());
00445         }
00446       }
00447     }
00448     // otherwise, & is a no-op
00449     return translate(UO->getSubExpr(), Ctx);
00450   }
00451 
00452   // We treat these as no-ops
00453   case UO_Deref:
00454   case UO_Plus:
00455     return translate(UO->getSubExpr(), Ctx);
00456 
00457   case UO_Minus:
00458     return new (Arena)
00459       til::UnaryOp(til::UOP_Minus, translate(UO->getSubExpr(), Ctx));
00460   case UO_Not:
00461     return new (Arena)
00462       til::UnaryOp(til::UOP_BitNot, translate(UO->getSubExpr(), Ctx));
00463   case UO_LNot:
00464     return new (Arena)
00465       til::UnaryOp(til::UOP_LogicNot, translate(UO->getSubExpr(), Ctx));
00466 
00467   // Currently unsupported
00468   case UO_Real:
00469   case UO_Imag:
00470   case UO_Extension:
00471     return new (Arena) til::Undefined(UO);
00472   }
00473   return new (Arena) til::Undefined(UO);
00474 }
00475 
00476 
00477 til::SExpr *SExprBuilder::translateBinOp(til::TIL_BinaryOpcode Op,
00478                                          const BinaryOperator *BO,
00479                                          CallingContext *Ctx, bool Reverse) {
00480    til::SExpr *E0 = translate(BO->getLHS(), Ctx);
00481    til::SExpr *E1 = translate(BO->getRHS(), Ctx);
00482    if (Reverse)
00483      return new (Arena) til::BinaryOp(Op, E1, E0);
00484    else
00485      return new (Arena) til::BinaryOp(Op, E0, E1);
00486 }
00487 
00488 
00489 til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op,
00490                                              const BinaryOperator *BO,
00491                                              CallingContext *Ctx,
00492                                              bool Assign) {
00493   const Expr *LHS = BO->getLHS();
00494   const Expr *RHS = BO->getRHS();
00495   til::SExpr *E0 = translate(LHS, Ctx);
00496   til::SExpr *E1 = translate(RHS, Ctx);
00497 
00498   const ValueDecl *VD = nullptr;
00499   til::SExpr *CV = nullptr;
00500   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHS)) {
00501     VD = DRE->getDecl();
00502     CV = lookupVarDecl(VD);
00503   }
00504 
00505   if (!Assign) {
00506     til::SExpr *Arg = CV ? CV : new (Arena) til::Load(E0);
00507     E1 = new (Arena) til::BinaryOp(Op, Arg, E1);
00508     E1 = addStatement(E1, nullptr, VD);
00509   }
00510   if (VD && CV)
00511     return updateVarDecl(VD, E1);
00512   return new (Arena) til::Store(E0, E1);
00513 }
00514 
00515 
00516 til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO,
00517                                                   CallingContext *Ctx) {
00518   switch (BO->getOpcode()) {
00519   case BO_PtrMemD:
00520   case BO_PtrMemI:
00521     return new (Arena) til::Undefined(BO);
00522 
00523   case BO_Mul:  return translateBinOp(til::BOP_Mul, BO, Ctx);
00524   case BO_Div:  return translateBinOp(til::BOP_Div, BO, Ctx);
00525   case BO_Rem:  return translateBinOp(til::BOP_Rem, BO, Ctx);
00526   case BO_Add:  return translateBinOp(til::BOP_Add, BO, Ctx);
00527   case BO_Sub:  return translateBinOp(til::BOP_Sub, BO, Ctx);
00528   case BO_Shl:  return translateBinOp(til::BOP_Shl, BO, Ctx);
00529   case BO_Shr:  return translateBinOp(til::BOP_Shr, BO, Ctx);
00530   case BO_LT:   return translateBinOp(til::BOP_Lt,  BO, Ctx);
00531   case BO_GT:   return translateBinOp(til::BOP_Lt,  BO, Ctx, true);
00532   case BO_LE:   return translateBinOp(til::BOP_Leq, BO, Ctx);
00533   case BO_GE:   return translateBinOp(til::BOP_Leq, BO, Ctx, true);
00534   case BO_EQ:   return translateBinOp(til::BOP_Eq,  BO, Ctx);
00535   case BO_NE:   return translateBinOp(til::BOP_Neq, BO, Ctx);
00536   case BO_And:  return translateBinOp(til::BOP_BitAnd,   BO, Ctx);
00537   case BO_Xor:  return translateBinOp(til::BOP_BitXor,   BO, Ctx);
00538   case BO_Or:   return translateBinOp(til::BOP_BitOr,    BO, Ctx);
00539   case BO_LAnd: return translateBinOp(til::BOP_LogicAnd, BO, Ctx);
00540   case BO_LOr:  return translateBinOp(til::BOP_LogicOr,  BO, Ctx);
00541 
00542   case BO_Assign:    return translateBinAssign(til::BOP_Eq,  BO, Ctx, true);
00543   case BO_MulAssign: return translateBinAssign(til::BOP_Mul, BO, Ctx);
00544   case BO_DivAssign: return translateBinAssign(til::BOP_Div, BO, Ctx);
00545   case BO_RemAssign: return translateBinAssign(til::BOP_Rem, BO, Ctx);
00546   case BO_AddAssign: return translateBinAssign(til::BOP_Add, BO, Ctx);
00547   case BO_SubAssign: return translateBinAssign(til::BOP_Sub, BO, Ctx);
00548   case BO_ShlAssign: return translateBinAssign(til::BOP_Shl, BO, Ctx);
00549   case BO_ShrAssign: return translateBinAssign(til::BOP_Shr, BO, Ctx);
00550   case BO_AndAssign: return translateBinAssign(til::BOP_BitAnd, BO, Ctx);
00551   case BO_XorAssign: return translateBinAssign(til::BOP_BitXor, BO, Ctx);
00552   case BO_OrAssign:  return translateBinAssign(til::BOP_BitOr,  BO, Ctx);
00553 
00554   case BO_Comma:
00555     // The clang CFG should have already processed both sides.
00556     return translate(BO->getRHS(), Ctx);
00557   }
00558   return new (Arena) til::Undefined(BO);
00559 }
00560 
00561 
00562 til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE,
00563                                             CallingContext *Ctx) {
00564   clang::CastKind K = CE->getCastKind();
00565   switch (K) {
00566   case CK_LValueToRValue: {
00567     if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
00568       til::SExpr *E0 = lookupVarDecl(DRE->getDecl());
00569       if (E0)
00570         return E0;
00571     }
00572     til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
00573     return E0;
00574     // FIXME!! -- get Load working properly
00575     // return new (Arena) til::Load(E0);
00576   }
00577   case CK_NoOp:
00578   case CK_DerivedToBase:
00579   case CK_UncheckedDerivedToBase:
00580   case CK_ArrayToPointerDecay:
00581   case CK_FunctionToPointerDecay: {
00582     til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
00583     return E0;
00584   }
00585   default: {
00586     // FIXME: handle different kinds of casts.
00587     til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
00588     if (CapabilityExprMode)
00589       return E0;
00590     return new (Arena) til::Cast(til::CAST_none, E0);
00591   }
00592   }
00593 }
00594 
00595 
00596 til::SExpr *
00597 SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E,
00598                                           CallingContext *Ctx) {
00599   til::SExpr *E0 = translate(E->getBase(), Ctx);
00600   til::SExpr *E1 = translate(E->getIdx(), Ctx);
00601   return new (Arena) til::ArrayIndex(E0, E1);
00602 }
00603 
00604 
00605 til::SExpr *
00606 SExprBuilder::translateAbstractConditionalOperator(
00607     const AbstractConditionalOperator *CO, CallingContext *Ctx) {
00608   auto *C = translate(CO->getCond(), Ctx);
00609   auto *T = translate(CO->getTrueExpr(), Ctx);
00610   auto *E = translate(CO->getFalseExpr(), Ctx);
00611   return new (Arena) til::IfThenElse(C, T, E);
00612 }
00613 
00614 
00615 til::SExpr *
00616 SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) {
00617   DeclGroupRef DGrp = S->getDeclGroup();
00618   for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
00619     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
00620       Expr *E = VD->getInit();
00621       til::SExpr* SE = translate(E, Ctx);
00622 
00623       // Add local variables with trivial type to the variable map
00624       QualType T = VD->getType();
00625       if (T.isTrivialType(VD->getASTContext())) {
00626         return addVarDecl(VD, SE);
00627       }
00628       else {
00629         // TODO: add alloca
00630       }
00631     }
00632   }
00633   return nullptr;
00634 }
00635 
00636 
00637 
00638 // If (E) is non-trivial, then add it to the current basic block, and
00639 // update the statement map so that S refers to E.  Returns a new variable
00640 // that refers to E.
00641 // If E is trivial returns E.
00642 til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S,
00643                                        const ValueDecl *VD) {
00644   if (!E || !CurrentBB || E->block() || til::ThreadSafetyTIL::isTrivial(E))
00645     return E;
00646   if (VD)
00647     E = new (Arena) til::Variable(E, VD);
00648   CurrentInstructions.push_back(E);
00649   if (S)
00650     insertStmt(S, E);
00651   return E;
00652 }
00653 
00654 
00655 // Returns the current value of VD, if known, and nullptr otherwise.
00656 til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) {
00657   auto It = LVarIdxMap.find(VD);
00658   if (It != LVarIdxMap.end()) {
00659     assert(CurrentLVarMap[It->second].first == VD);
00660     return CurrentLVarMap[It->second].second;
00661   }
00662   return nullptr;
00663 }
00664 
00665 
00666 // if E is a til::Variable, update its clangDecl.
00667 inline void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {
00668   if (!E)
00669     return;
00670   if (til::Variable *V = dyn_cast<til::Variable>(E)) {
00671     if (!V->clangDecl())
00672       V->setClangDecl(VD);
00673   }
00674 }
00675 
00676 // Adds a new variable declaration.
00677 til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) {
00678   maybeUpdateVD(E, VD);
00679   LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size()));
00680   CurrentLVarMap.makeWritable();
00681   CurrentLVarMap.push_back(std::make_pair(VD, E));
00682   return E;
00683 }
00684 
00685 
00686 // Updates a current variable declaration.  (E.g. by assignment)
00687 til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) {
00688   maybeUpdateVD(E, VD);
00689   auto It = LVarIdxMap.find(VD);
00690   if (It == LVarIdxMap.end()) {
00691     til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD);
00692     til::SExpr *St  = new (Arena) til::Store(Ptr, E);
00693     return St;
00694   }
00695   CurrentLVarMap.makeWritable();
00696   CurrentLVarMap.elem(It->second).second = E;
00697   return E;
00698 }
00699 
00700 
00701 // Make a Phi node in the current block for the i^th variable in CurrentVarMap.
00702 // If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E.
00703 // If E == null, this is a backedge and will be set later.
00704 void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) {
00705   unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
00706   assert(ArgIndex > 0 && ArgIndex < NPreds);
00707 
00708   til::SExpr *CurrE = CurrentLVarMap[i].second;
00709   if (CurrE->block() == CurrentBB) {
00710     // We already have a Phi node in the current block,
00711     // so just add the new variable to the Phi node.
00712     til::Phi *Ph = dyn_cast<til::Phi>(CurrE);
00713     assert(Ph && "Expecting Phi node.");
00714     if (E)
00715       Ph->values()[ArgIndex] = E;
00716     return;
00717   }
00718 
00719   // Make a new phi node: phi(..., E)
00720   // All phi args up to the current index are set to the current value.
00721   til::Phi *Ph = new (Arena) til::Phi(Arena, NPreds);
00722   Ph->values().setValues(NPreds, nullptr);
00723   for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
00724     Ph->values()[PIdx] = CurrE;
00725   if (E)
00726     Ph->values()[ArgIndex] = E;
00727   Ph->setClangDecl(CurrentLVarMap[i].first);
00728   // If E is from a back-edge, or either E or CurrE are incomplete, then
00729   // mark this node as incomplete; we may need to remove it later.
00730   if (!E || isIncompletePhi(E) || isIncompletePhi(CurrE)) {
00731     Ph->setStatus(til::Phi::PH_Incomplete);
00732   }
00733 
00734   // Add Phi node to current block, and update CurrentLVarMap[i]
00735   CurrentArguments.push_back(Ph);
00736   if (Ph->status() == til::Phi::PH_Incomplete)
00737     IncompleteArgs.push_back(Ph);
00738 
00739   CurrentLVarMap.makeWritable();
00740   CurrentLVarMap.elem(i).second = Ph;
00741 }
00742 
00743 
00744 // Merge values from Map into the current variable map.
00745 // This will construct Phi nodes in the current basic block as necessary.
00746 void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
00747   assert(CurrentBlockInfo && "Not processing a block!");
00748 
00749   if (!CurrentLVarMap.valid()) {
00750     // Steal Map, using copy-on-write.
00751     CurrentLVarMap = std::move(Map);
00752     return;
00753   }
00754   if (CurrentLVarMap.sameAs(Map))
00755     return;  // Easy merge: maps from different predecessors are unchanged.
00756 
00757   unsigned NPreds = CurrentBB->numPredecessors();
00758   unsigned ESz = CurrentLVarMap.size();
00759   unsigned MSz = Map.size();
00760   unsigned Sz  = std::min(ESz, MSz);
00761 
00762   for (unsigned i=0; i<Sz; ++i) {
00763     if (CurrentLVarMap[i].first != Map[i].first) {
00764       // We've reached the end of variables in common.
00765       CurrentLVarMap.makeWritable();
00766       CurrentLVarMap.downsize(i);
00767       break;
00768     }
00769     if (CurrentLVarMap[i].second != Map[i].second)
00770       makePhiNodeVar(i, NPreds, Map[i].second);
00771   }
00772   if (ESz > MSz) {
00773     CurrentLVarMap.makeWritable();
00774     CurrentLVarMap.downsize(Map.size());
00775   }
00776 }
00777 
00778 
00779 // Merge a back edge into the current variable map.
00780 // This will create phi nodes for all variables in the variable map.
00781 void SExprBuilder::mergeEntryMapBackEdge() {
00782   // We don't have definitions for variables on the backedge, because we
00783   // haven't gotten that far in the CFG.  Thus, when encountering a back edge,
00784   // we conservatively create Phi nodes for all variables.  Unnecessary Phi
00785   // nodes will be marked as incomplete, and stripped out at the end.
00786   //
00787   // An Phi node is unnecessary if it only refers to itself and one other
00788   // variable, e.g. x = Phi(y, y, x)  can be reduced to x = y.
00789 
00790   assert(CurrentBlockInfo && "Not processing a block!");
00791 
00792   if (CurrentBlockInfo->HasBackEdges)
00793     return;
00794   CurrentBlockInfo->HasBackEdges = true;
00795 
00796   CurrentLVarMap.makeWritable();
00797   unsigned Sz = CurrentLVarMap.size();
00798   unsigned NPreds = CurrentBB->numPredecessors();
00799 
00800   for (unsigned i=0; i < Sz; ++i) {
00801     makePhiNodeVar(i, NPreds, nullptr);
00802   }
00803 }
00804 
00805 
00806 // Update the phi nodes that were initially created for a back edge
00807 // once the variable definitions have been computed.
00808 // I.e., merge the current variable map into the phi nodes for Blk.
00809 void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {
00810   til::BasicBlock *BB = lookupBlock(Blk);
00811   unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors;
00812   assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
00813 
00814   for (til::SExpr *PE : BB->arguments()) {
00815     til::Phi *Ph = dyn_cast_or_null<til::Phi>(PE);
00816     assert(Ph && "Expecting Phi Node.");
00817     assert(Ph->values()[ArgIndex] == nullptr && "Wrong index for back edge.");
00818 
00819     til::SExpr *E = lookupVarDecl(Ph->clangDecl());
00820     assert(E && "Couldn't find local variable for Phi node.");
00821     Ph->values()[ArgIndex] = E;
00822   }
00823 }
00824 
00825 void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D,
00826                             const CFGBlock *First) {
00827   // Perform initial setup operations.
00828   unsigned NBlocks = Cfg->getNumBlockIDs();
00829   Scfg = new (Arena) til::SCFG(Arena, NBlocks);
00830 
00831   // allocate all basic blocks immediately, to handle forward references.
00832   BBInfo.resize(NBlocks);
00833   BlockMap.resize(NBlocks, nullptr);
00834   // create map from clang blockID to til::BasicBlocks
00835   for (auto *B : *Cfg) {
00836     auto *BB = new (Arena) til::BasicBlock(Arena);
00837     BB->reserveInstructions(B->size());
00838     BlockMap[B->getBlockID()] = BB;
00839   }
00840 
00841   CurrentBB = lookupBlock(&Cfg->getEntry());
00842   auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
00843                                       : cast<FunctionDecl>(D)->parameters();
00844   for (auto *Pm : Parms) {
00845     QualType T = Pm->getType();
00846     if (!T.isTrivialType(Pm->getASTContext()))
00847       continue;
00848 
00849     // Add parameters to local variable map.
00850     // FIXME: right now we emulate params with loads; that should be fixed.
00851     til::SExpr *Lp = new (Arena) til::LiteralPtr(Pm);
00852     til::SExpr *Ld = new (Arena) til::Load(Lp);
00853     til::SExpr *V  = addStatement(Ld, nullptr, Pm);
00854     addVarDecl(Pm, V);
00855   }
00856 }
00857 
00858 
00859 void SExprBuilder::enterCFGBlock(const CFGBlock *B) {
00860   // Intialize TIL basic block and add it to the CFG.
00861   CurrentBB = lookupBlock(B);
00862   CurrentBB->reservePredecessors(B->pred_size());
00863   Scfg->add(CurrentBB);
00864 
00865   CurrentBlockInfo = &BBInfo[B->getBlockID()];
00866 
00867   // CurrentLVarMap is moved to ExitMap on block exit.
00868   // FIXME: the entry block will hold function parameters.
00869   // assert(!CurrentLVarMap.valid() && "CurrentLVarMap already initialized.");
00870 }
00871 
00872 
00873 void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {
00874   // Compute CurrentLVarMap on entry from ExitMaps of predecessors
00875 
00876   CurrentBB->addPredecessor(BlockMap[Pred->getBlockID()]);
00877   BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()];
00878   assert(PredInfo->UnprocessedSuccessors > 0);
00879 
00880   if (--PredInfo->UnprocessedSuccessors == 0)
00881     mergeEntryMap(std::move(PredInfo->ExitMap));
00882   else
00883     mergeEntryMap(PredInfo->ExitMap.clone());
00884 
00885   ++CurrentBlockInfo->ProcessedPredecessors;
00886 }
00887 
00888 
00889 void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) {
00890   mergeEntryMapBackEdge();
00891 }
00892 
00893 
00894 void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) {
00895   // The merge*() methods have created arguments.
00896   // Push those arguments onto the basic block.
00897   CurrentBB->arguments().reserve(
00898     static_cast<unsigned>(CurrentArguments.size()), Arena);
00899   for (auto *A : CurrentArguments)
00900     CurrentBB->addArgument(A);
00901 }
00902 
00903 
00904 void SExprBuilder::handleStatement(const Stmt *S) {
00905   til::SExpr *E = translate(S, nullptr);
00906   addStatement(E, S);
00907 }
00908 
00909 
00910 void SExprBuilder::handleDestructorCall(const VarDecl *VD,
00911                                         const CXXDestructorDecl *DD) {
00912   til::SExpr *Sf = new (Arena) til::LiteralPtr(VD);
00913   til::SExpr *Dr = new (Arena) til::LiteralPtr(DD);
00914   til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf);
00915   til::SExpr *E = new (Arena) til::Call(Ap);
00916   addStatement(E, nullptr);
00917 }
00918 
00919 
00920 
00921 void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) {
00922   CurrentBB->instructions().reserve(
00923     static_cast<unsigned>(CurrentInstructions.size()), Arena);
00924   for (auto *V : CurrentInstructions)
00925     CurrentBB->addInstruction(V);
00926 
00927   // Create an appropriate terminator
00928   unsigned N = B->succ_size();
00929   auto It = B->succ_begin();
00930   if (N == 1) {
00931     til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr;
00932     // TODO: set index
00933     unsigned Idx = BB ? BB->findPredecessorIndex(CurrentBB) : 0;
00934     auto *Tm = new (Arena) til::Goto(BB, Idx);
00935     CurrentBB->setTerminator(Tm);
00936   }
00937   else if (N == 2) {
00938     til::SExpr *C = translate(B->getTerminatorCondition(true), nullptr);
00939     til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr;
00940     ++It;
00941     til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr;
00942     // FIXME: make sure these arent' critical edges.
00943     auto *Tm = new (Arena) til::Branch(C, BB1, BB2);
00944     CurrentBB->setTerminator(Tm);
00945   }
00946 }
00947 
00948 
00949 void SExprBuilder::handleSuccessor(const CFGBlock *Succ) {
00950   ++CurrentBlockInfo->UnprocessedSuccessors;
00951 }
00952 
00953 
00954 void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) {
00955   mergePhiNodesBackEdge(Succ);
00956   ++BBInfo[Succ->getBlockID()].ProcessedPredecessors;
00957 }
00958 
00959 
00960 void SExprBuilder::exitCFGBlock(const CFGBlock *B) {
00961   CurrentArguments.clear();
00962   CurrentInstructions.clear();
00963   CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
00964   CurrentBB = nullptr;
00965   CurrentBlockInfo = nullptr;
00966 }
00967 
00968 
00969 void SExprBuilder::exitCFG(const CFGBlock *Last) {
00970   for (auto *Ph : IncompleteArgs) {
00971     if (Ph->status() == til::Phi::PH_Incomplete)
00972       simplifyIncompleteArg(Ph);
00973   }
00974 
00975   CurrentArguments.clear();
00976   CurrentInstructions.clear();
00977   IncompleteArgs.clear();
00978 }
00979 
00980 
00981 /*
00982 void printSCFG(CFGWalker &Walker) {
00983   llvm::BumpPtrAllocator Bpa;
00984   til::MemRegionRef Arena(&Bpa);
00985   SExprBuilder SxBuilder(Arena);
00986   til::SCFG *Scfg = SxBuilder.buildCFG(Walker);
00987   TILPrinter::print(Scfg, llvm::errs());
00988 }
00989 */
00990 
00991 
00992 } // end namespace threadSafety
00993 
00994 } // end namespace clang