@@ -32,10 +32,44 @@ template <class Emitter> class LocalScope;
3232template <class Emitter > class DestructorScope ;
3333template <class Emitter > class VariableScope ;
3434template <class Emitter > class DeclScope ;
35+ template <class Emitter > class InitLinkScope ;
3536template <class Emitter > class OptionScope ;
3637template <class Emitter > class ArrayIndexScope ;
3738template <class Emitter > class SourceLocScope ;
3839
40+ template <class Emitter > class ByteCodeExprGen ;
41+ struct InitLink {
42+ public:
43+ enum {
44+ K_This = 0 ,
45+ K_Field = 1 ,
46+ K_Decl = 2 ,
47+ };
48+
49+ static InitLink This () { return InitLink{K_This}; }
50+ static InitLink Field (unsigned Offset) {
51+ InitLink IL{K_Field};
52+ IL.Offset = Offset;
53+ return IL;
54+ }
55+ static InitLink Decl (const ValueDecl *D) {
56+ InitLink IL{K_Decl};
57+ IL.D = D;
58+ return IL;
59+ }
60+
61+ InitLink (uint8_t Kind) : Kind(Kind) {}
62+ template <class Emitter >
63+ bool emit (ByteCodeExprGen<Emitter> *Ctx, const Expr *E) const ;
64+
65+ private:
66+ uint32_t Kind;
67+ union {
68+ unsigned Offset;
69+ const ValueDecl *D;
70+ };
71+ };
72+
3973// / Compilation context for expressions.
4074template <class Emitter >
4175class ByteCodeExprGen : public ConstStmtVisitor <ByteCodeExprGen<Emitter>, bool >,
@@ -254,9 +288,11 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
254288 friend class LocalScope <Emitter>;
255289 friend class DestructorScope <Emitter>;
256290 friend class DeclScope <Emitter>;
291+ friend class InitLinkScope <Emitter>;
257292 friend class OptionScope <Emitter>;
258293 friend class ArrayIndexScope <Emitter>;
259294 friend class SourceLocScope <Emitter>;
295+ friend struct InitLink ;
260296
261297 // / Emits a zero initializer.
262298 bool visitZeroInitializer (PrimType T, QualType QT, const Expr *E);
@@ -325,6 +361,9 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
325361 bool Initializing = false ;
326362 const ValueDecl *InitializingDecl = nullptr ;
327363
364+ llvm::SmallVector<InitLink> InitStack;
365+ bool InitStackActive = false ;
366+
328367 // / Flag indicating if we're initializing a global variable.
329368 bool GlobalDecl = false ;
330369};
@@ -548,6 +587,18 @@ template <class Emitter> class SourceLocScope final {
548587 bool Enabled = false ;
549588};
550589
590+ template <class Emitter > class InitLinkScope final {
591+ public:
592+ InitLinkScope (ByteCodeExprGen<Emitter> *Ctx, InitLink &&Link) : Ctx(Ctx) {
593+ Ctx->InitStack .push_back (std::move (Link));
594+ }
595+
596+ ~InitLinkScope () { this ->Ctx ->InitStack .pop_back (); }
597+
598+ private:
599+ ByteCodeExprGen<Emitter> *Ctx;
600+ };
601+
551602} // namespace interp
552603} // namespace clang
553604
0 commit comments