32 #ifndef _QORE_VARREFNODE_H
33 #define _QORE_VARREFNODE_H
35 #include "qore/intern/FunctionCallNode.h"
37 class VarRefNewObjectNode;
41 hashdecl ClosureVarValue;
43 class VarRefNode :
public ParseNode {
48 bool explicit_scope : 1;
50 DLLLOCAL ~VarRefNode() {
52 assert(type != VT_IMMEDIATE || !
ref.cvv);
53 assert(type != VT_IMMEDIATE || !
ref.cvv);
57 if (type == VT_IMMEDIATE) {
59 ref.cvv->deref(xsink);
69 DLLLOCAL
void resolve(
const QoreTypeInfo* typeInfo);
70 DLLLOCAL
void parseInitIntern(LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo* typeInfo,
bool is_new =
false);
71 DLLLOCAL VarRefNewObjectNode* globalMakeNewCall(
QoreValue args);
74 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar *oflag,
int pflag,
int &lvids,
const QoreTypeInfo *&typeInfo);
76 DLLLOCAL
virtual const QoreTypeInfo* parseGetTypeInfo()
const {
77 if (type == VT_LOCAL || type == VT_CLOSURE || type == VT_LOCAL_TS)
78 return ref.id->parseGetTypeInfo();
79 if (type == VT_GLOBAL)
80 return ref.var->parseGetTypeInfo();
84 DLLLOCAL
virtual const QoreTypeInfo* parseGetTypeInfoForInitialAssignment()
const {
85 const QoreTypeInfo* rv;
86 if (type == VT_LOCAL || type == VT_CLOSURE || type == VT_LOCAL_TS) {
87 rv =
ref.id->parseGetTypeInfoForInitialAssignment();
88 }
else if (type == VT_GLOBAL) {
89 rv =
ref.var->parseGetTypeInfoForInitialAssignment();
93 if (rv && QoreTypeInfo::isReference(rv)) {
94 return QoreTypeInfo::getHardReference(rv);
99 DLLLOCAL
void setThreadSafeIntern() {
100 ref.id->setClosureUse();
104 DLLLOCAL
void setClosureIntern() {
105 ref.id->setClosureUse();
109 DLLLOCAL VarRefNode(
const QoreProgramLocation* loc,
char* n, ClosureVarValue* cvv) : ParseNode(loc,
NT_VARREF, true, false), name(n), type(VT_IMMEDIATE), new_decl(false), explicit_scope(false) {
114 DLLLOCAL VarRefNode(
const QoreProgramLocation* loc,
char* n, Var* n_var,
bool n_has_effect =
false,
bool n_new_decl =
true) : ParseNode(loc,
NT_VARREF, true, n_has_effect), name(n), type(VT_GLOBAL), new_decl(n_new_decl), explicit_scope(false) {
122 ClosureVarValue* cvv;
126 DLLLOCAL VarRefNode(
const QoreProgramLocation* loc,
char* n, qore_var_t t,
bool n_has_effect =
false) : ParseNode(loc,
NT_VARREF, true, n_has_effect), name(n), type(t), new_decl(t == VT_LOCAL), explicit_scope(false) {
127 if (type == VT_LOCAL)
129 assert(type != VT_GLOBAL);
132 DLLLOCAL VarRefNode(
const QoreProgramLocation* loc,
char* n, LocalVar* n_id,
bool in_closure) : ParseNode(loc,
NT_VARREF, true, false), name(n), new_decl(false), explicit_scope(false) {
144 DLLLOCAL
bool parseEqualTo(
const VarRefNode& other)
const;
149 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
150 if (type == VT_LOCAL || type == VT_CLOSURE || type == VT_LOCAL_TS)
151 return ref.id->getTypeInfo();
152 if (type == VT_GLOBAL)
153 return ref.var->getTypeInfo();
158 DLLLOCAL
virtual const char* getTypeName()
const;
160 DLLLOCAL
virtual bool stayInTree()
const {
161 return !(type == VT_GLOBAL);
164 DLLLOCAL
virtual bool parseIsDecl()
const {
return type != VT_UNRESOLVED; }
165 DLLLOCAL
virtual bool isDecl()
const {
return false; }
166 DLLLOCAL
bool explicitScope()
const {
return explicit_scope; }
167 DLLLOCAL
void setExplicitScope() { explicit_scope =
true; }
170 DLLLOCAL
virtual const char* parseGetTypeName()
const {
178 DLLLOCAL
bool isGlobalDecl()
const {
return new_decl; }
180 DLLLOCAL
bool isGlobalVar()
const {
return type == VT_GLOBAL; }
183 DLLLOCAL
int getLValue(LValueHelper& lvh,
bool for_remove)
const;
185 DLLLOCAL
bool isRef()
const {
186 if (type == VT_LOCAL)
187 return ref.id->isRef();
188 if (type == VT_IMMEDIATE)
190 assert(type == VT_GLOBAL);
191 return ref.var->isRef();
194 DLLLOCAL
void remove(LValueRemoveHelper& lvrh);
196 DLLLOCAL qore_var_t getType()
const {
return type; }
197 DLLLOCAL
const char* getName()
const {
return name.ostr; }
199 DLLLOCAL
void makeLocal() {
200 assert(type != VT_GLOBAL);
206 DLLLOCAL
virtual void makeGlobal();
209 DLLLOCAL
char* takeName() {
211 return name.takeName();
214 DLLLOCAL
void setThreadSafe() {
215 if (type == VT_LOCAL)
216 setThreadSafeIntern();
219 DLLLOCAL
void setClosure() {
220 if (type == VT_LOCAL || type == VT_LOCAL_TS)
224 DLLLOCAL
void setPublic() {
225 assert(type == VT_GLOBAL);
226 ref.var->setPublic();
229 DLLLOCAL
void parseAssigned() {
230 assert(type != VT_IMMEDIATE);
231 if (type == VT_LOCAL || type == VT_CLOSURE || type == VT_LOCAL_TS)
232 ref.id->parseAssigned();
235 DLLLOCAL
bool scanMembers(RSetHelper& rsh);
238 class GlobalVarRefNode :
public VarRefNode {
241 DLLLOCAL GlobalVarRefNode(
const QoreProgramLocation* loc,
char* n, Var* v) : VarRefNode(loc, n, v, false, false) {
242 explicit_scope =
true;
245 DLLLOCAL GlobalVarRefNode(
const QoreProgramLocation* loc,
char* n,
const QoreTypeInfo* typeInfo = 0);
246 DLLLOCAL GlobalVarRefNode(
const QoreProgramLocation* loc,
char* n, QoreParseTypeInfo* parseTypeInfo);
253 class VarRefDeclNode :
public VarRefNode {
255 QoreParseTypeInfo* parseTypeInfo;
256 const QoreTypeInfo* typeInfo;
258 DLLLOCAL VarRefDeclNode(
const QoreProgramLocation* loc,
char* n, qore_var_t t,
const QoreTypeInfo* n_typeInfo, QoreParseTypeInfo* n_parseTypeInfo,
bool n_has_effect) :
259 VarRefNode(loc, n, t, n_has_effect), parseTypeInfo(n_parseTypeInfo), typeInfo(n_typeInfo) {
263 DLLLOCAL VarRefDeclNode(
const QoreProgramLocation* loc,
char* n, Var* var,
const QoreTypeInfo* n_typeInfo, QoreParseTypeInfo* n_parseTypeInfo) :
264 VarRefNode(loc, n, var, true), parseTypeInfo(n_parseTypeInfo), typeInfo(n_typeInfo) {
268 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar *oflag,
int pflag,
int &lvids,
const QoreTypeInfo *&typeInfo);
270 DLLLOCAL VarRefDeclNode(
const QoreProgramLocation* loc,
char* n, ClosureVarValue* cvv,
const QoreTypeInfo* n_typeInfo) : VarRefNode(loc, n, cvv), parseTypeInfo(0), typeInfo(n_typeInfo) {
274 DLLLOCAL VarRefDeclNode(
const QoreProgramLocation* loc,
char* n, qore_var_t t,
const QoreTypeInfo* n_typeInfo) :
275 VarRefNode(loc, n, t), parseTypeInfo(nullptr), typeInfo(n_typeInfo) {
280 DLLLOCAL VarRefDeclNode(
const QoreProgramLocation* loc,
char* n, qore_var_t t,
char* class_name) :
281 VarRefNode(loc, n, t), parseTypeInfo(new QoreParseTypeInfo(class_name)), typeInfo(0) {
286 DLLLOCAL VarRefDeclNode(
const QoreProgramLocation* loc,
char* n, qore_var_t t, QoreParseTypeInfo* n_parseTypeInfo) :
287 VarRefNode(loc, n, t), parseTypeInfo(n_parseTypeInfo), typeInfo(0) {
292 DLLLOCAL VarRefDeclNode(
const QoreProgramLocation* loc,
char* n, qore_var_t t,
const QoreTypeInfo* n_typeInfo, QoreParseTypeInfo* n_parseTypeInfo) :
293 VarRefNode(loc, n, t), parseTypeInfo(n_parseTypeInfo), typeInfo(n_typeInfo) {
297 DLLLOCAL ~VarRefDeclNode() {
298 delete parseTypeInfo;
300 DLLLOCAL
virtual bool parseIsDecl()
const {
303 DLLLOCAL
virtual bool isDecl()
const {
310 DLLLOCAL QoreParseTypeInfo* takeParseTypeInfo() {
311 QoreParseTypeInfo* ti = parseTypeInfo;
312 parseTypeInfo =
nullptr;
315 DLLLOCAL QoreParseTypeInfo* getParseTypeInfo() {
316 return parseTypeInfo;
318 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
319 assert(!parseTypeInfo);
322 DLLLOCAL
virtual void makeGlobal();
324 DLLLOCAL
void parseInitCommon(LocalVar* oflag,
int pflag,
int& lvids,
bool is_new =
false);
327 class VarRefImmediateNode :
public VarRefDeclNode {
329 DLLLOCAL
void deref() {
338 ref.cvv->deref(xsink);
346 DLLLOCAL VarRefImmediateNode(
const QoreProgramLocation* loc,
char* n, ClosureVarValue* cvv,
const QoreTypeInfo* n_typeInfo) : VarRefDeclNode(loc, n, cvv, n_typeInfo) {
350 DLLLOCAL
virtual ~VarRefImmediateNode() {
357 class VarRefTryModuleErrorNode :
public VarRefDeclNode {
359 DLLLOCAL VarRefTryModuleErrorNode(
const QoreProgramLocation* loc,
char* n) : VarRefDeclNode(loc, n, VT_LOCAL, hashTypeInfo) {
362 DLLLOCAL
virtual ~VarRefTryModuleErrorNode() {
366 class VarRefNewObjectNode :
public VarRefDeclNode,
public FunctionCallBase {
368 DLLLOCAL VarRefNewObjectNode(
const QoreProgramLocation* loc,
char* n,
const QoreTypeInfo* n_typeInfo, QoreParseTypeInfo* n_parseTypeInfo, QoreParseListNode* n_args, qore_var_t t) :
369 VarRefDeclNode(loc, n, t, n_typeInfo, n_parseTypeInfo, true), FunctionCallBase(n_args) {
372 DLLLOCAL VarRefNewObjectNode(
const QoreProgramLocation* loc,
char* n, Var* var, QoreParseListNode* n_args,
const QoreTypeInfo* n_typeInfo, QoreParseTypeInfo* n_parseTypeInfo) :
373 VarRefDeclNode(loc, n, var, n_typeInfo, n_parseTypeInfo), FunctionCallBase(n_args) {
376 DLLLOCAL
virtual ~VarRefNewObjectNode() {
378 new_args.discard(
nullptr);
381 DLLLOCAL
virtual bool stayInTree()
const {
385 DLLLOCAL
const char* parseGetTypeName()
const {
386 return typeInfo ? QoreTypeInfo::getName(typeInfo) : parseTypeInfo->cscope->getIdentifier();
389 DLLLOCAL QoreParseListNode* takeParseArgs() {
390 QoreParseListNode* rv = parse_args;
391 parse_args =
nullptr;
396 enum vrn_type_e :
unsigned char {
402 } vrn_type = VRN_NONE;
404 bool runtime_check =
false;
409 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar *oflag,
int pflag,
int &lvids,
const QoreTypeInfo *&typeInfo);
411 DLLLOCAL
void parseInitConstructorCall(
const QoreProgramLocation* loc, LocalVar* oflag,
int pflag,
int& lvids,
const QoreClass* qc);
413 DLLLOCAL
void parseInitHashDeclInitialization(
const QoreProgramLocation* loc, LocalVar* oflag,
int pflag,
int& lvids,
const TypedHashDecl* hd);
415 DLLLOCAL
void parseInitComplexHashInitialization(
const QoreProgramLocation* loc, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo* ti);
417 DLLLOCAL
void parseInitComplexListInitialization(
const QoreProgramLocation* loc, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo* ti);