/*
 * Copyright 2015, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _FRAMEWORKS_COMPILE_SLANG_RS_FOREACH_LOWERING_H
#define _FRAMEWORKS_COMPILE_SLANG_RS_FOREACH_LOWERING_H

#include "clang/AST/StmtVisitor.h"

namespace clang {
  class ASTContext;
  class CallExpr;
  class Expr;
  class FunctionDecl;
}

namespace slang {

class RSContext;

class RSForEachLowering : public clang::StmtVisitor<RSForEachLowering> {
 public:
  RSForEachLowering(RSContext* ctxt);

  void VisitCallExpr(clang::CallExpr *CE);
  void VisitStmt(clang::Stmt *S);

 private:
  RSContext* mCtxt;
  clang::ASTContext& mASTCtxt;

  const clang::FunctionDecl* matchFunctionDesignator(clang::Expr* expr);
  const clang::FunctionDecl* matchKernelLaunchCall(clang::CallExpr* CE,
                                                   int* slot,
                                                   bool* hasOptions);
  clang::FunctionDecl* CreateForEachInternalFunctionDecl();
  clang::Expr* CreateCalleeExprForInternalForEach();
};  // RSForEachLowering

}  // namespace slang

#endif  // _FRAMEWORKS_COMPILE_SLANG_RS_FOREACH_LOWERING_H
