1 /*
2  * Copyright 2017, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef VISITOR_H
18 #define VISITOR_H
19 
20 #include <functional>
21 
22 namespace android {
23 namespace spirit {
24 
25 class Entity;
26 class Module;
27 class EntryPointDefinition;
28 class DebugInfoSection;
29 class AnnotationSection;
30 class GlobalSection;
31 class FunctionDeclaration;
32 class Block;
33 class FunctionDefinition;
34 class Instruction;
35 #define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) class INST_CLASS;
36 #include "instruction_dispatches_generated.h"
37 #undef HANDLE_INSTRUCTION
38 
39 class IVisitor {
40 public:
~IVisitor()41   virtual ~IVisitor() {}
42 
43   virtual void visit(Entity *) = 0;
44   virtual void visit(Module *) = 0;
45   virtual void visit(EntryPointDefinition *) = 0;
46   virtual void visit(DebugInfoSection *) = 0;
47   virtual void visit(AnnotationSection *) = 0;
48   virtual void visit(GlobalSection *) = 0;
49   virtual void visit(FunctionDeclaration *) = 0;
50   virtual void visit(Block *) = 0;
51   virtual void visit(FunctionDefinition *) = 0;
52   virtual void visit(Instruction *) = 0;
53 #define HANDLE_INSTRUCTION(OPCODE, INST_CLASS)                                 \
54   virtual void visit(INST_CLASS *) = 0;
55 #include "instruction_dispatches_generated.h"
56 #undef HANDLE_INSTRUCTION
57 };
58 
59 class DoNothingVisitor : public IVisitor {
60 public:
~DoNothingVisitor()61   virtual ~DoNothingVisitor() {}
62 
63   virtual void visit(Entity *e);
64   virtual void visit(Module *m);
65   virtual void visit(EntryPointDefinition *);
66   virtual void visit(DebugInfoSection *dinfo);
67   virtual void visit(AnnotationSection *a);
68   virtual void visit(GlobalSection *g);
69   virtual void visit(FunctionDeclaration *fdecl);
70   virtual void visit(Block *b);
71   virtual void visit(FunctionDefinition *fdef);
72   // This visit(Instruction *) necessary?
73   virtual void visit(Instruction *inst);
74 #define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) virtual void visit(INST_CLASS *);
75 #include "instruction_dispatches_generated.h"
76 #undef HANDLE_INSTRUCTION
77 };
78 
79 template <typename T> class InstructionVisitor : public DoNothingVisitor {
80 public:
InstructionVisitor(T action)81   InstructionVisitor(T action) : mAction(action) {}
82 
~InstructionVisitor()83   virtual ~InstructionVisitor() {}
84 
85 #define HANDLE_INSTRUCTION(OPCODE, INST_CLASS)                                 \
86   void visit(INST_CLASS *inst) override { mAction((Instruction *)inst); }
87 #include "instruction_dispatches_generated.h"
88 #undef HANDLE_INSTRUCTION
89 
90 private:
91   T mAction;
92 };
93 
CreateInstructionVisitor(T action)94 template <typename T> static IVisitor *CreateInstructionVisitor(T action) {
95   return new InstructionVisitor<decltype(action)>(action);
96 }
97 
98 } // namespace spirit
99 } // namespace android
100 
101 #endif // VISITOR_H
102