/*
* Copyright 2017, 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 VISITOR_H
#define VISITOR_H
#include <functional>
namespace android {
namespace spirit {
class Entity;
class Module;
class EntryPointDefinition;
class DebugInfoSection;
class AnnotationSection;
class GlobalSection;
class FunctionDeclaration;
class Block;
class FunctionDefinition;
class Instruction;
#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) class INST_CLASS;
#include "instruction_dispatches_generated.h"
#undef HANDLE_INSTRUCTION
class IVisitor {
public:
virtual ~IVisitor() {}
virtual void visit(Entity *) = 0;
virtual void visit(Module *) = 0;
virtual void visit(EntryPointDefinition *) = 0;
virtual void visit(DebugInfoSection *) = 0;
virtual void visit(AnnotationSection *) = 0;
virtual void visit(GlobalSection *) = 0;
virtual void visit(FunctionDeclaration *) = 0;
virtual void visit(Block *) = 0;
virtual void visit(FunctionDefinition *) = 0;
virtual void visit(Instruction *) = 0;
#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
virtual void visit(INST_CLASS *) = 0;
#include "instruction_dispatches_generated.h"
#undef HANDLE_INSTRUCTION
};
class DoNothingVisitor : public IVisitor {
public:
virtual ~DoNothingVisitor() {}
virtual void visit(Entity *e);
virtual void visit(Module *m);
virtual void visit(EntryPointDefinition *);
virtual void visit(DebugInfoSection *dinfo);
virtual void visit(AnnotationSection *a);
virtual void visit(GlobalSection *g);
virtual void visit(FunctionDeclaration *fdecl);
virtual void visit(Block *b);
virtual void visit(FunctionDefinition *fdef);
// This visit(Instruction *) necessary?
virtual void visit(Instruction *inst);
#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) virtual void visit(INST_CLASS *);
#include "instruction_dispatches_generated.h"
#undef HANDLE_INSTRUCTION
};
template <typename T> class InstructionVisitor : public DoNothingVisitor {
public:
InstructionVisitor(T action) : mAction(action) {}
virtual ~InstructionVisitor() {}
#define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \
void visit(INST_CLASS *inst) override { mAction((Instruction *)inst); }
#include "instruction_dispatches_generated.h"
#undef HANDLE_INSTRUCTION
private:
T mAction;
};
template <typename T> static IVisitor *CreateInstructionVisitor(T action) {
return new InstructionVisitor<decltype(action)>(action);
}
} // namespace spirit
} // namespace android
#endif // VISITOR_H