bool AppArgs::Parse( int argc, const char *argv[] ) { int opt, opt_index; char* end; const char *optstring; mLongOptions[ mNumLongOptions ].name = NULL; mLongOptions[ mNumLongOptions ].has_arg = 0; mLongOptions[ mNumLongOptions ].flag = NULL; mLongOptions[ mNumLongOptions ].val = 0; optstring = ""; optind = 0; do { opt = getopt_long_only( argc, const_cast<char * const*>( argv ), optstring, mLongOptions, &opt_index ); switch (opt) { case 0: if ( opt_index < mNumLongOptions && mOptionData[ opt_index ].numeric ) { int val = strtol( optarg, &end, 0 ); if ( *end != 0 ) { usage( argv[ 0 ] ); return false; } if ( handleParam( mKey, val ) == false ) { usage( argv[ 0 ] ); return false; } } else { if ( handleParam( mKey, optarg ) == false ) { usage( argv[ 0 ] ); return false; } } break; case -1: mParamIndex = optind; break; case ':': case '?': default: usage( argv[ 0 ] ); return false; } } while( opt >= 0 ); return true; }
static bool handleParams(LLVMNode *callNode, unsigned vararg, LLVMDGParameters *params, DefMap *df, DefMap *subgraph_df) { bool changed = false; // operand[0] is the called func for (int i = 1, e = callNode->getOperandsNum(); i < e; ++i) { LLVMNode *op = callNode->getOperand(i); if (!op) continue; if (!op->isPointerTy()) continue; LLVMDGParameter *p = params->find(op->getKey()); if (!p) { #ifdef DEBUG_ENABLED if (i - 1 < (int) vararg) DBG("ERR: no actual param for " << *op->getKey()); #endif continue; } changed |= handleParam(op, p->out, df, subgraph_df); } return changed; }
static bool handleParam(LLVMNode *node, LLVMNode *to, DefMap *df, DefMap *subgraph_df) { bool changed = false; for (const Pointer& ptr : node->getPointsTo()) { changed |= handleParam(ptr, to, df, subgraph_df); // handle also the memory pointers, if we define some memory // in subprocedure, we'd like to propagate it to the callee if (!ptr.isKnown()) continue; for (auto memit : ptr.obj->pointsTo) for (const Pointer& memptr : memit.second) changed |= handleParam(memptr, to, df, subgraph_df); } return changed; }
static bool handleVarArgParams(LLVMDependenceGraph *subgraph, DefMap *df, DefMap *subgraph_df) { LLVMDGParameters *formal = subgraph->getParameters(); if (!formal) return false; LLVMDGParameter *vaparam = formal->getVarArg(); assert(vaparam && "No va param in vararg function"); return handleParam(vaparam->in, vaparam->out, df, subgraph_df); }
static bool handleParamsGlobals(LLVMDependenceGraph *dg, LLVMDGParameters *params, DefMap *df, DefMap *subgraph_df) { bool changed = false; for (auto I = params->global_begin(), E = params->global_end(); I != E; ++I) { LLVMDGParameter& p = I->second; // get the global node, it contains the points-to set LLVMNode *glob = dg->getNode(I->first); if (!glob) { errs() << "ERR: no global node for param\n"; continue; } changed |= handleParam(glob, p.out, df, subgraph_df); } return changed; }
static bool handleDynMemoryParams(LLVMDependenceGraph *subgraph, LLVMDGParameters *params, DefMap *df, DefMap *subgraph_df) { bool changed = false; LLVMDGParameters *formal = subgraph->getParameters(); if (!formal) return false; // operand[0] is the called func for (auto it : *formal) { // FIXME Probably will be best add to DGParameters another // container for mem. allocation params, to keep it // separate so that we don't need to do this if (isa<CallInst>(it.first)) { // the formal in param contains the points-to set LLVMDGParameter *actprm = params->find(it.first); assert(actprm && "No actual param for dyn. mem."); changed |= handleParam(it.second.in, actprm->out, df, subgraph_df); } } return changed; }