| 233 | } |
| 234 | |
| 235 | void ArgFlow::mergeDirection(const ArgFlow &CalleeArgFlowResult) { |
| 236 | this->Direction |= CalleeArgFlowResult.Direction; |
| 237 | |
| 238 | // if argument/value is struct, merge each fields result also |
| 239 | if (!CalleeArgFlowResult.STInfo) |
| 240 | return; |
| 241 | |
| 242 | if (!isStruct()) |
| 243 | setStruct(CalleeArgFlowResult.STInfo->StructType); |
| 244 | |
| 245 | for (auto Result : CalleeArgFlowResult.STInfo->FieldResults) { |
| 246 | if (!Result.second) |
| 247 | continue; |
| 248 | unsigned FieldNum = Result.first; |
| 249 | ArgFlow &FieldResult = this->getOrCreateFieldFlow(FieldNum); |
| 250 | ArgFlow &CalleeResult = *Result.second; |
| 251 | FieldResult.mergeDirection(CalleeResult); |
| 252 | STInfo->FieldsDirection |= FieldResult.Direction; |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | void ArgFlow::mergeArray(const ArgFlow &CalleeArgFlowResult, CallBase &C) { |
| 257 | |