void FixKernelParameterCallback::run(
    const ast_matchers::MatchFinder::MatchResult& result)
{
  auto funcDecl = result.Nodes.getDeclAs<FunctionDecl>("decl");
  if (funcDecl) {
    // Check if function is an OpenCL kernel
    if (!funcDecl->hasAttr<OpenCLKernelAttr>()) { return; }
    // search all parameters ...
    for ( auto param  = funcDecl->param_begin(),
               last   = funcDecl->param_end();
               param != last;
             ++param ) {
      // ... and look for a type ending in _matrix_t
      auto fullType = (*param)->getOriginalType().getAsString();
      auto pos = fullType.rfind("_matrix_t");
      if ( pos != std::string::npos) {
        // if found transform this parameter into two and adopt the body
        // accordingly
        auto dataType = fullType.substr(0, pos);
        auto paramName = (*param)->getName().str();
        rewriteParameter(*param, dataType, paramName, *result.SourceManager);
        adoptBody(funcDecl, fullType, paramName, *result.SourceManager);
      }
    }
  }
}
Example #2
0
bool ParseFunctionExit(FunctionEvent *Event, CallExpr *Call,
                       vector<ValueDecl*>& References,
                       ASTContext& Ctx) {
  assert(Call->getDirectCallee() != NULL);
  assert(Call->getDirectCallee()->getName() == "__tesla_leaving");

  // TODO: better distinguishing between callee and/or caller
  Event->set_context(FunctionEvent::Callee);
  Event->set_direction(FunctionEvent::Exit);

  if ((Call->getNumArgs() != 1) || (Call->getArg(0) == NULL)) {
    Report("__tesla_leaving predicate should have one argument: the function",
        Call->getLocStart(), Ctx)
      << Call->getSourceRange();
    return false;
  }

  auto FnRef = dyn_cast<DeclRefExpr>(Call->getArg(0)->IgnoreImplicit());
  if (!FnRef) {
    Report("Expected a function call", Call->getLocStart(), Ctx)
      << Call->getSourceRange();
    return false;
  }

  auto Fn = dyn_cast<FunctionDecl>(FnRef->getDecl());
  assert(Fn != NULL);

  for (auto I = Fn->param_begin(); I != Fn->param_end(); ++I) {
    if (!ParseArgument(Event->add_argument(), *I, References, Ctx))
      return false;
  }

  return ParseFunctionRef(Event->mutable_function(), Fn, Ctx);
}
void GetParameterTypeNamesCallback::run(
    const ast_matchers::MatchFinder::MatchResult& result)
{
  auto funcDecl = result.Nodes.getDeclAs<FunctionDecl>("decl");
  if (funcDecl) {
    for (auto i  = funcDecl->param_begin(),
              e  = funcDecl->param_end();
              i != e;
            ++i) {
      _parameterTypeNames.push_back(
          // get unqualified, i.e. without const, etc. type
          (*i)->getType().getUnqualifiedType().getAsString()
          );
    }
  }
}