CE Parser.cpp 104 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. namespace Edit{
  5. /******************************************************************************/
  6. static void SetTokenSymbol(Token &token, Str &temp)
  7. {
  8. if(!token.symbol)
  9. {
  10. if(token.line->source->cpp && token=="char")token.symbol.find("char8");else // treat 'char' as 'char8' on C++ files
  11. if(token.line->source->cpp && token=="long")token.symbol.find("int" );else // treat 'long' as 'int ' on C++ files
  12. token.symbol.find(temp=token);
  13. }
  14. }
  15. /******************************************************************************/
  16. // NAMES
  17. /******************************************************************************/
  18. static void MakeUnique(Str &name)
  19. {
  20. name=S+"Unique "+name+' '+RandomName();
  21. }
  22. static Str UniqueName(C SymbolPtr &parent, Token &token, UInt &modifiers, Bool allow_namespace=false) // modifiers may have enabled MODIF_NAMELESS, MODIF_TRANSPARENT and MODIF_SKIP_SUGGESTIONS
  23. {
  24. Str name; if(parent)name=parent->full_name+SEP; if(token=='{'){modifiers|=Symbol::MODIF_NAMELESS|Symbol::MODIF_TRANSPARENT|Symbol::MODIF_SKIP_SUGGESTIONS; name+=NamelessName(parent());}else name+=token;
  25. SymbolPtr symbol; if(symbol.find(name))if(symbol->valid)if(allow_namespace ? symbol->type!=Symbol::NAMESPACE : true){modifiers|=Symbol::MODIF_SKIP_SUGGESTIONS; MakeUnique(name);} // is 'duplicate' name
  26. return name;
  27. }
  28. static Str UniqueVarFuncName(C SymbolPtr &parent, C Str &name)
  29. {
  30. Str full; if(parent)full=parent->full_name+SEP; full+=name;
  31. SymbolPtr symbol; if(symbol.find(full))
  32. {
  33. if((symbol->valid && symbol->type==Symbol::TYPEDEF) || symbol->valid_decl)MakeUnique(full); // create a unique name only for "valid typedefs" or "valid class forward declarations" (typedefs in order to allow multiple same typedefs, like "ASSERT" macro uses "typedef xx" making one typedef declared multiple times, also for classes because if we have a class declared, we can't override it with some var/func)
  34. }
  35. return full;
  36. }
  37. /******************************************************************************/
  38. // PARSING
  39. /******************************************************************************/
  40. void ParseFuncTemplate(Memc<Token*> &tokens, Int i)
  41. {
  42. if(InRange(i , tokens)
  43. && InRange(i+1, tokens)
  44. && *tokens[i]=='>' && *tokens[i+1]=='(') // "<..>(" mark function templates
  45. {
  46. for(Int level=0, j=i-1; j>=0; j--)
  47. {
  48. Token &token=*tokens[j];
  49. switch(token[0])
  50. {
  51. case '}': case '{': case ';': return;
  52. case ')': case ']': case '>': level--; break;
  53. case '(': case '[': case '<': level++; if(level>0)
  54. {
  55. if(token[0]=='<')
  56. {
  57. for(; j<=i; j++)
  58. {
  59. Token &token=*tokens[j];
  60. if(token=='<')token.BStr::setBorrowed(TMPL_B);else
  61. if(token=='>')token.BStr::setBorrowed(TMPL_E);
  62. }
  63. }
  64. }return;
  65. }
  66. }
  67. }
  68. }
  69. /******************************************************************************/
  70. static void ParseTemplates(Memc<Token*> &tokens, Int &i, Str &temp, Symbol *set_parent, Bool inside_template) // 'inside_template'=if we're already inside templates <..|..>
  71. {
  72. Memc<Symbol::Modif> templates;
  73. for(Int level=0, template_level=0, original=i; i<tokens.elms(); )
  74. {
  75. Int start=i;
  76. Token &token=*tokens[i];
  77. if(inside_template && !level)
  78. {
  79. if(token=='<' || token==TMPL_B) template_level++;
  80. if(token=='>' || token==TMPL_E)if(!template_level--)return;
  81. }
  82. switch(token[0])
  83. {
  84. case '>': ParseFuncTemplate(tokens, i); break;
  85. case '{': case '(': case '[': level++; break;
  86. case '}': case ')': case ']': if(!level-- )return; break;
  87. case ';': case ',': if(!level && !template_level)return; break;
  88. default :
  89. {
  90. Token *prev=(InRange(i-1, tokens) ? tokens[i-1] : null);
  91. if(!(prev && (*prev=='.' || *prev=="->" || *prev=="::"))) // if not preceeded by separator
  92. GetFullSymbol(tokens, i, temp, set_parent, templates);
  93. }break;
  94. }
  95. token.parent=set_parent;
  96. MAX(i, start+1);
  97. }
  98. }
  99. /******************************************************************************/
  100. static void ReadTemplates(Memc<SymbolDef> &symbols, Memc<Token*> &tokens, Int i, Str &temp, Symbol &symbol, Bool as_template) // "template<typename TYPE>", "<TYPE>", "<const int x>", "<const int* *x>"
  101. {
  102. Symbol *set_parent=&symbol;
  103. if(InRange(i, tokens))for(; i<tokens.elms(); )
  104. {
  105. Token &token=*tokens[i], *next=(InRange(i+1, tokens) ? tokens[i+1] : null);
  106. if(token=="typename" || token=="class" || token=="struct"){token.parent=set_parent; i++; continue;} // skip 'typename'
  107. if(token=="const_mem_addr"){token.parent=set_parent; i++; continue;} // skip modifiers
  108. if(token.type==TOKEN_CODE && next && (*next=='=' || *next==',' || *next=='>' || *next==TMPL_E)) // if there's only one TOKEN_CODE then treat it as 'typename'
  109. {
  110. token.symbol=symbols.New().require(symbol.full_name+SEP+token).set(&symbol, Symbol::TYPENAME, i, token.line->source); if(as_template)symbol.templates.add(token.symbol);
  111. token.parent=set_parent; i++; // skip name
  112. UInt const_level=0; Memc<Int> new_templates; ReadModifiers(tokens, i-2, const_level, token.symbol->modifiers, new_templates, temp);
  113. }else
  114. {
  115. // TODO:
  116. // for this block use new function GetFuncParam (which extract from GetFuncParams), watch out for small differences between here and GetFuncParams such as ParseTemplates has true/false parameters
  117. // as currently array_dims are ignored
  118. Int bracket_level=0, ptr_level=0, ptr_level_in_bracket=0, type_start=i;
  119. UInt modifiers=0, const_level=0, const_level_in_bracket=0;
  120. Token *par=tokens[i++]; par->parent=set_parent;
  121. if(*par=="const" ){par=(InRange(i, tokens) ? tokens[i++] : null); par->parent=set_parent; const_level=1;}else
  122. if(*par=="constexpr"){par=(InRange(i, tokens) ? tokens[i++] : null); par->parent=set_parent;}
  123. if( par)
  124. {
  125. if(*par==')' || *par=='>' || *par==TMPL_E)break;
  126. if(*par==',')continue;
  127. i--; Int start=i ; Memc<Symbol::Modif> templates; Symbol *type=GetFullSymbol(tokens, i, temp, set_parent, templates); MAX(i, start+1);
  128. Int type_end=i-1;
  129. for(; i<tokens.elms(); )
  130. {
  131. Int param_token_index=i;
  132. Token &name=*tokens[i++]; name.parent=set_parent;
  133. switch(name.type)
  134. {
  135. case TOKEN_OPERATOR:
  136. {
  137. switch(name[0])
  138. {
  139. case '*': if(bracket_level)ptr_level_in_bracket++;else ptr_level++; break;
  140. case '&': modifiers|=Symbol::MODIF_REF; break;
  141. case '(': bracket_level++; break;
  142. case ',':
  143. case ')':
  144. case '>':
  145. default : // TMPL_E
  146. {
  147. // TODO: create empty param
  148. if(name[0]==',')goto finished_param;
  149. return; // error
  150. }break;
  151. }
  152. }break;
  153. case TOKEN_KEYWORD:
  154. {
  155. if(name=="const")
  156. {
  157. if(bracket_level)const_level_in_bracket|=(1<<ptr_level_in_bracket);
  158. else const_level |=(1<<ptr_level );
  159. }else
  160. if(name=="long"){}else // long long
  161. return; // error
  162. }break;
  163. case TOKEN_CODE:
  164. {
  165. for(; bracket_level>0 && i<tokens.elms() && *tokens[i]==')'; ){bracket_level--; tokens[i++]->parent=set_parent;} // force closing brackets started earlier "int ((x))|"
  166. if( !bracket_level)
  167. {
  168. name.def_decl=true;
  169. name.symbol =symbols.New().require(symbol.full_name+SEP+name).set(&symbol, Symbol::VAR, param_token_index, name.line->source); if(as_template)symbol.templates.add(name.symbol);
  170. // TODO: when name.symbol will be as FUNC, then calculate differently
  171. name.symbol-> modifiers|=(modifiers & ~Symbol::MODIF_REF); // set all except MODIF_REF
  172. name.symbol->value. modifiers|=(modifiers & Symbol::MODIF_REF); // set only MODIF_REF
  173. name.symbol->value =type; Swap(name.symbol->value.templates, templates);
  174. name.symbol->value. ptr_level= ptr_level+ ptr_level_in_bracket;
  175. name.symbol->value.const_level=const_level|(const_level_in_bracket<<ptr_level);
  176. name.symbol->type_range.set(type_start, type_end);
  177. name.symbol-> def_range.set(type_end+1);
  178. for(; i<tokens.elms(); )
  179. {
  180. Token &op=*tokens[i++]; op.parent=set_parent;
  181. switch(op[0])
  182. {
  183. case '(': // parameter list or default value declaration
  184. {
  185. // TODO:
  186. GetFuncParams(symbols, tokens, i, temp, null, param_token_index, true, set_parent);
  187. }break;
  188. case '[': // array
  189. {
  190. for(Str dim; i<tokens.elms(); )
  191. {
  192. Token &token=*tokens[i++]; token.parent=set_parent;
  193. if(token==']')
  194. {
  195. // TODO: watch out for error in calculation of 'CalculateI' or <=0 value
  196. // TODO: this is wrong, ignores ptr_level_in_bracket
  197. if(name.symbol)name.symbol->value.array_dims.NewAt(0)=CalculateI(dim);
  198. goto finished_dim;
  199. }
  200. dim+=token;
  201. }
  202. return; // error
  203. finished_dim:;
  204. }break;
  205. case '=': // default value
  206. {
  207. // for example: 5, x, 1*(x+2), Map<Image,Int>::static_var+Mems<X>::stat_var
  208. Int start=i; ParseTemplates(tokens, i, temp, set_parent, true);
  209. if(name.symbol){name.symbol->modifiers|=Symbol::MODIF_DEF_VALUE; name.symbol->def_range.y=i-1; name.symbol->def_val_range.set(start, i-1);}
  210. }break;
  211. case ',':
  212. {
  213. if(name.symbol)name.symbol->def_range.y=i-2;
  214. }goto finished_param; // proceed to next param
  215. default:
  216. {
  217. if(name.symbol)name.symbol->def_range.y=i-2;
  218. }return; // end of param declaration
  219. }
  220. }
  221. }
  222. }break;
  223. default: return; // error
  224. }
  225. }
  226. }
  227. }
  228. finished_param:;
  229. }
  230. }
  231. /******************************************************************************/
  232. static void ReadModifier(Token &token, UInt &const_level, UInt &modifiers)
  233. {
  234. if(token=="const" )const_level=1;else
  235. if(token=="static" )modifiers|=Symbol::MODIF_STATIC ;else
  236. if(token=="inline" )modifiers|=Symbol::MODIF_INLINE ;else
  237. if(token=="virtual" )modifiers|=Symbol::MODIF_VIRTUAL ;else
  238. if(token=="friend" )modifiers|=Symbol::MODIF_FRIEND ;else
  239. if(token=="mutable" )modifiers|=Symbol::MODIF_MUTABLE ;else
  240. if(token=="explicit" )modifiers|=Symbol::MODIF_EXPLICIT ;else
  241. if(token=="extern" )modifiers|=Symbol::MODIF_EXTERN ;else
  242. if(token=="const_mem_addr")modifiers|=Symbol::MODIF_CONST_MEM_ADDR;else
  243. if(token=="public" )Symbol::SetPublic (modifiers) ;else
  244. if(token=="protected" )Symbol::SetProtected(modifiers) ;else
  245. if(token=="private" )Symbol::SetPrivate (modifiers) ;
  246. }
  247. Int ReadModifiers(Memc<Token*> &tokens, Int i, UInt &const_level, UInt &modifiers, Memc<Int> &new_templates, Str &temp)
  248. {
  249. new_templates.clear();
  250. for(; i>=0; i--)
  251. {
  252. Token &mod=*tokens[i];
  253. if(mod.type==TOKEN_KEYWORD)SetTokenSymbol(mod, temp);
  254. if(mod.symbol && (mod.symbol->modifiers&Symbol::MODIF_CPP_MODIFIER))ReadModifier(mod, const_level, modifiers);else
  255. {
  256. // check if there are templates
  257. for(; InRange(i, tokens); )
  258. {
  259. Token &t=*tokens[i];
  260. if(t=='>' || t==TMPL_E)
  261. {
  262. for(Int level=0, j=i; j>=0; )
  263. {
  264. Token &token=*tokens[j--];
  265. if(token=='{' || token=='}' || token==';')goto finished;
  266. if(token=='>' || token==TMPL_E) --level;else
  267. if(token=='<' || token==TMPL_B)if(!++level) // we've reached the start
  268. {
  269. token.BStr::setBorrowed(TMPL_B);
  270. new_templates.NewAt(0)=j+2; // set 'new_templates' to first token after '<'
  271. if(InRange(j, tokens) && *tokens[j]=="template")j--;
  272. i=j; // this template section was successfully read, so we can adjust the 'i' index
  273. break;
  274. }
  275. }
  276. }else break;
  277. }
  278. break;
  279. }
  280. }
  281. finished:
  282. return i+1;
  283. }
  284. /******************************************************************************/
  285. static void SkipUnknownSymbol(Memc<Token*> &tokens, Int &i, Symbol *set_parent) // "X", "EE::X", "StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)>"
  286. {
  287. if(InRange(i, tokens))
  288. {
  289. Token &token_start =*tokens[i];
  290. Bool precise_parent=false;
  291. if(token_start=='.' || token_start=="::" || token_start=="->"){precise_parent=true; token_start.parent=set_parent; i++;}
  292. for(; i<tokens.elms(); )
  293. {
  294. Token &token=*tokens[i];
  295. switch(token.type)
  296. {
  297. default: return;
  298. case TOKEN_KEYWORD:
  299. case TOKEN_CODE : token.parent=set_parent; i++; break;
  300. }
  301. if(InRange(i, tokens)) // check operator following symbol, can be . :: -> < TMPL_B
  302. {
  303. Token *op=tokens[i];
  304. if(*op=='<' || *op==TMPL_B)
  305. {
  306. for(Int template_level=0, bracket_level=0; i<tokens.elms(); )
  307. {
  308. Token &token=*tokens[i];
  309. if(token==';' || token=='{' || token=='}')break;
  310. token.parent=set_parent; i++;
  311. if(token=='(')bracket_level++;else
  312. if(token==')')bracket_level--;
  313. if(!bracket_level)
  314. {
  315. if(token=='<' || token==TMPL_B) ++template_level;else
  316. if(token=='>' || token==TMPL_E)if(--template_level<=0)break;
  317. }
  318. }
  319. op=(InRange(i, tokens) ? tokens[i] : null);
  320. }
  321. if(op)
  322. if(*op=='.' || *op=="::" || *op=="->"){i++; op->parent=set_parent; continue;} // wishes to use sub-symbol
  323. }
  324. break;
  325. }
  326. }
  327. }
  328. /******************************************************************************/
  329. Symbol* GetFullSymbol(Memc<Token*> &tokens, Int &i, Str &temp, Symbol *set_parent, Memc<Symbol::Modif> &templates, Symbol* *symbol_parent, Int *symbol_index, Bool adjust_super) // 'i' will update only on tokens that were processed
  330. {
  331. Symbol *symbol=null;
  332. templates.clear();
  333. if(symbol_parent)*symbol_parent=null;
  334. if(symbol_index )*symbol_index =0;
  335. if(InRange(i, tokens))
  336. {
  337. Symbol *parent;
  338. Bool precise_parent=false, allow_self=true;
  339. Token &token_start =*tokens[i], *prev=(InRange(i-1, tokens) ? tokens[i-1] : null);
  340. if(token_start=='.' || token_start=="::" || token_start=="->") // start with global namespace, for example ::EE::Image
  341. {
  342. if(prev)
  343. {
  344. if(prev->type==TOKEN_CODE )return null; // can't process symbols followed by code
  345. if(prev->type==TOKEN_KEYWORD)if(!(prev->symbol && (prev->symbol->modifiers&Symbol::MODIF_CPP_MODIFIER)))return null; // can't process symbols followed by keywords that aren't modifiers
  346. }
  347. parent=null; precise_parent=true; token_start.parent=set_parent; i++;
  348. }else
  349. {
  350. if(prev && (*prev=='.' || *prev=="::" || *prev=="->"))return null; // can't process symbols followed by separators
  351. parent=set_parent;
  352. }
  353. for(; i<tokens.elms(); )
  354. {
  355. if(symbol_parent)*symbol_parent=symbol;
  356. Token &token=*tokens[i]; // read symbol name
  357. Int token_index=i;
  358. switch(token.type)
  359. {
  360. default: symbol=null; break;
  361. case TOKEN_OPERATOR:
  362. {
  363. symbol=null;
  364. if(token=='~' && InRange(i+1, tokens)) // possible destructor declaration "class X{~X()} X::~X(){}"
  365. {
  366. Token &name=*tokens[i+1]; // get class name
  367. Int name_index=i+1;
  368. if(name.type==TOKEN_CODE)
  369. {
  370. if(!name.symbol && parent && name==*parent)name.symbol=parent;
  371. if( name.symbol)
  372. {
  373. token.parent=name.parent=set_parent; i+=2;
  374. allow_self=true;
  375. precise_parent=true;
  376. parent=symbol=name.symbol(); if(symbol_index)*symbol_index=name_index;
  377. }
  378. }
  379. }
  380. }break;
  381. case TOKEN_KEYWORD:
  382. {
  383. token.parent=set_parent; SetTokenSymbol(token, temp);
  384. symbol=token.symbol(); if(symbol_index)*symbol_index=token_index;
  385. if(adjust_super && (token=="__super" || token=="super"))
  386. {
  387. allow_self=false;
  388. symbol =(parent ? parent : set_parent ? set_parent->Class() : null); // if "parent.super" is available then use that parent, if not then use class of current space
  389. }else allow_self=true;
  390. if(symbol && (symbol->modifiers&Symbol::MODIF_DATA_TYPE)) // check for "signed/unsigned/short/long" combination
  391. {
  392. Int j=i;
  393. for(; InRange(j+1, tokens) && tokens[j+1]->type==TOKEN_KEYWORD; j++)SetTokenSymbol(*tokens[j+1], temp); // iterate all continuous keywords, i..j range
  394. for(; j>i && !(tokens[j]->symbol && (tokens[j]->symbol->modifiers&Symbol::MODIF_DATA_TYPE)); j--); // ignore last keywords which are not data type
  395. if(j>i)
  396. {
  397. Bool signed_=false, unsigned_=false, short_=false, long_=false, char_=false, int_=false, int8_=false, int16_=false, int32_=false, int64_=false;
  398. for(Int k=i; k<=j; k++)
  399. {
  400. Token &t=*tokens[k]; t.parent=set_parent;
  401. if(t== "signed") signed_=true;else
  402. if(t=="unsigned")unsigned_=true;else
  403. if(t== "int") int_=true;else
  404. if(t== "short") short_=true;else
  405. if(t== "long" && t.line->source->cpp)long_=true;else
  406. if(t== "char" && t.line->source->cpp)char_=true;else
  407. if(t== "__int8")int8_ =true;else
  408. if(t== "__int16")int16_=true;else
  409. if(t== "__int32")int32_=true;else
  410. if(t== "__int64")int64_=true;
  411. }
  412. i=j;
  413. if(char_ )symbol=TypeSymbol(unsigned_ ? VAR_BYTE : signed_ ? VAR_SBYTE : VAR_CHAR8);else
  414. if(long_ )symbol=TypeSymbol(unsigned_ ? VAR_UINT : VAR_INT );else
  415. if(int8_ )symbol=TypeSymbol(unsigned_ ? VAR_BYTE : VAR_SBYTE);else
  416. if(int16_)symbol=TypeSymbol(unsigned_ ? VAR_USHORT : VAR_SHORT);else
  417. if(int32_)symbol=TypeSymbol(unsigned_ ? VAR_UINT : VAR_INT );else
  418. if(int64_)symbol=TypeSymbol(unsigned_ ? VAR_ULONG : VAR_LONG );else
  419. {
  420. // TODO: compile error
  421. }
  422. }
  423. }
  424. i++;
  425. precise_parent=true;
  426. parent=symbol;
  427. }break;
  428. case TOKEN_CODE:
  429. {
  430. i++; token.parent=set_parent;
  431. if( !token.symbol)
  432. {
  433. if(parent && token==*parent)token.symbol=parent ;else // constructor "class X{X();} X::X(){}"
  434. if(precise_parent && parent)token.symbol=FindChild (temp=token, parent, null, true, allow_self);else // if there's no parent then allow usings too (go to next line)
  435. token.symbol=FindSymbol(temp=token, parent, ProjectUsings );
  436. }
  437. allow_self=true;
  438. precise_parent=true;
  439. parent=symbol=token.symbol(); if(symbol_index)*symbol_index=token_index;
  440. }break;
  441. }
  442. if(!symbol){templates.clear(); break;}
  443. if(symbol->type==Symbol::KEYWORD)break; // 'operator', in this case 'symbol_parent' can point to parent class or null if it's inside class declaration
  444. if(symbol->type==Symbol::TYPEDEF)
  445. if(InRange(i+1, tokens)) // check operator following symbol, can be . :: -> < TMPL_B
  446. {
  447. Token &op=*tokens[i];
  448. if(op=='<' || op==TMPL_B || op=='.' || op=="::" || op=="->") // proceed with typedef to target
  449. {
  450. // TODO: this typedef can be not yet resolved (if we're inside 'LinkDataTypes' and proceeding to another typedef that was not yet processed)
  451. Symbol::Modif modif; modif=symbol; Swap(modif.templates, templates);
  452. modif.proceedToFinal(&modif.templates);
  453. parent=symbol=modif(); Swap(modif.templates, templates);
  454. }
  455. }
  456. if(symbol->type==Symbol::NAMESPACE || symbol->type==Symbol::CLASS)
  457. if(InRange(i+1, tokens)) // check operator following symbol, can be . :: -> < TMPL_B
  458. {
  459. Token *op=tokens[i];
  460. if(*op=='<' || *op==TMPL_B) // template declaration, for example "Map<Image, Int>", "Map< Mems<Image>::ImageSub, Int >"
  461. {
  462. // TODO: template param can be also a function
  463. op->BStr::setBorrowed(TMPL_B); i++; op->parent=set_parent; // replace '<' with TMPL_B to specify template brackets explicitly
  464. for(Int template_index=0; i<tokens.elms(); template_index++)
  465. {
  466. Memc<Symbol::Modif> ts;
  467. UInt const_level=0, modifiers=0;
  468. for(; i<tokens.elms(); i++) // read modifiers
  469. {
  470. Token &token=*tokens[i];
  471. if(token=="constexpr" ){token.parent=set_parent;}else
  472. if(token=="const" ){token.parent=set_parent; const_level=1;}else
  473. if(token=="const_mem_addr"){token.parent=set_parent; modifiers|=Symbol::MODIF_CONST_MEM_ADDR;}else
  474. if(token=="volatile" ){token.parent=set_parent;}else
  475. break;
  476. }
  477. Int start=i;
  478. if(Symbol *templat=GetFullSymbol(tokens, i, temp, set_parent, ts))
  479. {
  480. Symbol::Modif &t=templates.New(); t=templat; // add new template
  481. if(InRange(template_index, symbol->templates))t.src_template=symbol->templates[template_index]; // if specified template actually fits in templates available
  482. t.const_level=const_level; t.modifiers|=modifiers; Swap(t.templates, ts);
  483. for(; i<tokens.elms(); i++) // process remaining modifiers
  484. {
  485. Token &token=*tokens[i];
  486. if(token=='*' ){token.parent=set_parent; t.ptr_level++; }else
  487. if(token=='&' ){token.parent=set_parent; t.modifiers|=Symbol::MODIF_REF; }else
  488. if(token=="const"){token.parent=set_parent; t.const_level|=(1<<t.ptr_level);}else
  489. {
  490. ParseTemplates(tokens, i, temp, set_parent, true);
  491. break;
  492. }
  493. }
  494. }else
  495. {
  496. i=start;
  497. ParseTemplates(tokens, i, temp, set_parent, true); // skip unknown template
  498. }
  499. if(InRange(i, tokens))
  500. {
  501. op=tokens[i];
  502. if(*op==',' ){ i++; op->parent=set_parent; continue;}
  503. if(*op=='>' || *op==TMPL_E){op->BStr::setBorrowed(TMPL_E); i++; op->parent=set_parent; break ;} // replace '>' with TMPL_E to specify template brackets explicitly
  504. }
  505. return null;
  506. }
  507. op=(InRange(i, tokens) ? tokens[i] : null);
  508. }
  509. if(op)
  510. if(*op=='.' || *op=="::" || *op=="->"){i++; op->parent=set_parent; continue;} // wishes to use sub-symbol
  511. }
  512. break;
  513. }
  514. }
  515. return symbol;
  516. }
  517. /******************************************************************************/
  518. enum CLASS_TYPE
  519. {
  520. CLASS_CLASS ,
  521. CLASS_STRUCT,
  522. CLASS_UNION ,
  523. };
  524. static void CreateClass(Memc<SymbolDef> &symbols, Memc<SymbolDecl> &decls, Memc<Token*> &tokens, Symbol *set_parent, SymbolPtr &clazz, Int &i, CLASS_TYPE class_type, Symbol::ACCESS_LEVEL access_level, Str &temp, Memc<Symbol::Modif> &templates, Memc<Int> &new_templates)
  525. {
  526. Int start=i;
  527. if(InRange(i-1, tokens))
  528. {
  529. Token &prev=*tokens[i-1];
  530. if(prev=="friend" || prev=="<" || prev==TMPL_B || prev==",")return; // skip "friend class X;", "template<class X, class Y>"
  531. }
  532. if(InRange(i+1, tokens))
  533. {
  534. Token &token=*tokens[i+1];
  535. if(token=="__declspec")
  536. {
  537. token.parent=set_parent; i+=2;
  538. for(Int level=0; i<tokens.elms(); i++)
  539. {
  540. Token &token=*tokens[i]; token.parent=set_parent;
  541. if(token=='{' || token=='}' || token==';'){i--; return;}
  542. if(token=='(') ++level;
  543. if(token==')')if(--level<=0)break;
  544. }
  545. }
  546. }
  547. if(InRange(i+1, tokens))
  548. {
  549. Token &name=*tokens[i+1]; name.def_decl=true; // set 'def_decl' without checking for "InRange(i+2, tokens)" because when typing new class at the end of file there is no next token, while we still want to set the 'def_decl' so suggestions are disabled
  550. if(InRange(i+2, tokens))
  551. {
  552. Token &next=*tokens[i+2];
  553. UInt const_level=0, modifiers=Symbol::AccessLevelToModif(access_level);
  554. FlagSet(modifiers, Symbol::MODIF_UNION , class_type==CLASS_UNION);
  555. FlagSet(modifiers, Symbol::MODIF_TYPEDEF, InRange(start-1, tokens) && *tokens[start-1]=="typedef");
  556. if(name.line->source->cpp && name.type==TOKEN_CODE && (next=='<' || next==TMPL_B || next=='.' || next=="->" || next=="::")) // class A<B>::C {}, class A::C {} (this can happen if C was forward declared in A)
  557. {
  558. i++; // now points to 'name'
  559. Int symbol_index, local_start=i;
  560. Symbol *symbol_parent, *symbol=GetFullSymbol(tokens, i, temp, set_parent, templates, &symbol_parent, &symbol_index, false);
  561. DEBUG_ASSERT(symbol || !name.line->source->cpp, S+"Invalid Class definition\nLine ("+name.lineIndex()+"): \""+*name.line+"\"\nSource: \""+name.line->source->loc.asText()+"\"");
  562. if(symbol)
  563. {
  564. i--;
  565. Token &name=*tokens[symbol_index];
  566. clazz=symbols.New().require(UniqueName(set_parent, name, modifiers)).set(set_parent, Symbol::CLASS, symbol_index, name.line->source);
  567. name.symbol=clazz;
  568. clazz->type_range.set(ReadModifiers(tokens, start-1, const_level, modifiers, new_templates, temp), start);
  569. clazz-> def_range.set(local_start, i);
  570. clazz->modifiers |=modifiers;
  571. clazz->access_level=((class_type==CLASS_CLASS && name.line->source->cpp) ? Symbol::ACCESS_PRIVATE : Symbol::ACCESS_PUBLIC); // C++ has classes with default private access, .es has classes with default public access
  572. if(new_templates.elms())ReadTemplates(symbols, tokens, new_templates[0], temp, *clazz, true);
  573. }
  574. }else
  575. if(name.type==TOKEN_CODE && next==';') // forward declaration "class X;"
  576. {
  577. name.symbol=decls.New().require((set_parent ? set_parent->full_name+SEP : S)+name).set(set_parent, Symbol::CLASS, i+1, name.line->source);
  578. }else
  579. if(name.type==TOKEN_CODE || name=='{')
  580. {
  581. clazz=symbols.New().require(UniqueName(set_parent, name, modifiers)).set(set_parent, Symbol::CLASS, (name=='{') ? start : i+1, name.line->source);
  582. if(name.type==TOKEN_CODE)name.symbol=clazz; // not '{'
  583. clazz->type_range.set(ReadModifiers(tokens, start-1, const_level, modifiers, new_templates, temp), start);
  584. clazz-> def_range.set((name=='{') ? start : i+1);
  585. clazz->modifiers |=modifiers;
  586. clazz->access_level=((class_type==CLASS_CLASS && name.line->source->cpp) ? Symbol::ACCESS_PRIVATE : Symbol::ACCESS_PUBLIC); // C++ has classes with default private access, .es has classes with default public access
  587. if(new_templates.elms())ReadTemplates(symbols, tokens, new_templates[0], temp, *clazz, true);
  588. }
  589. }
  590. }
  591. }
  592. /******************************************************************************/
  593. void DetectDataTypes(Memc<SymbolDef> &symbols, Memc<SymbolDecl> &decls, Memc<Token*> &tokens, SymbolPtr parent)
  594. {
  595. Str temp;
  596. Bool extern_c =false;
  597. Int level =(parent ? parent->level+1 : 0);
  598. SymbolPtr next_parent= parent;
  599. Memc<Symbol::Modif > templates;
  600. Memc<Int > new_templates;
  601. Memc<Symbol::ACCESS_LEVEL> access_levels; access_levels.add(parent ? parent->accessLevel() : Symbol::ACCESS_PUBLIC);
  602. FREPA(tokens)
  603. {
  604. Token &token=*tokens[i];
  605. token.parent=parent();
  606. switch(token.type)
  607. {
  608. case TOKEN_OPERATOR:
  609. {
  610. Char c=token[0];
  611. if(c=='{')
  612. {
  613. if(!next_parent && !level && InRange(i-2, tokens) && (*tokens[i-2])=="extern")extern_c=true;else level++; // check for "extern "C" {"
  614. parent=next_parent; token.parent=parent(); access_levels.add(parent ? parent->accessLevel() : Symbol::ACCESS_PUBLIC);
  615. }else
  616. if(c=='}')
  617. {
  618. if(parent && parent->type==Symbol::CLASS && (parent->modifiers&Symbol::MODIF_TYPEDEF) && level==parent->level+1) // check for typedefs after "typedef struct {}|"
  619. {
  620. if(InRange(i+1, tokens) && *tokens[i+1]!=';')FlagDisable(parent->modifiers, Symbol::MODIF_TRANSPARENT); // if the class has a typedef defined, then it can be accessed through it, and will not be a transparent class
  621. i++; ReadVarFunc(parent(), symbols, tokens, i, parent->token_index, SPACE_NORMAL, temp, templates, new_templates);
  622. i--;
  623. }
  624. if(extern_c && !level)extern_c=false;else level--;
  625. if(parent && level<=parent->level)next_parent=parent=parent->parent;
  626. if(access_levels.elms()>1)access_levels.removeLast(); // keep at least one because codes operate on 'access_levels.last()'
  627. DEBUG_ASSERT(level>=0 || !token.line->source->cpp, S+"level<0\nLine ("+token.lineIndex()+"): \""+*token.line+"\"\nSource: \""+token.line->source->loc.asText()+"\"");
  628. }
  629. }break;
  630. case TOKEN_KEYWORD:
  631. {
  632. if(parent ? (level==parent->level+1) : (level==0)) // skip everything inside functions
  633. if(InRange(i+1, tokens))
  634. switch(token[0])
  635. {
  636. case 'p': if(*tokens[i+1]==':') // only for "private:" and not "private int"
  637. {
  638. if(token=="private" )access_levels.last()=Symbol::ACCESS_PRIVATE ;else
  639. if(token=="protected")access_levels.last()=Symbol::ACCESS_PROTECTED;else
  640. if(token=="public" )access_levels.last()=Symbol::ACCESS_PUBLIC ;
  641. }break;
  642. case 'n': if(token=="namespace")if(!(InRange(i-1, tokens) && *tokens[i-1]=="using")) // skip "using namespace X;"
  643. {
  644. Token &name=*tokens[i+1]; name.def_decl=true;
  645. if(name.type==TOKEN_CODE)
  646. {
  647. UInt modifiers=0;
  648. next_parent=name.symbol=symbols.New().require(UniqueName(parent, name, modifiers, true)).set(parent, Symbol::NAMESPACE, i+1, name.line->source);
  649. next_parent->type_range.set(i); next_parent->def_range.set(i+1); next_parent->modifiers|=modifiers;
  650. }
  651. }break;
  652. case 's': if(token=="struct")CreateClass(symbols, decls, tokens, parent(), next_parent, i, CLASS_STRUCT, access_levels.last(), temp, templates, new_templates); break;
  653. case 'c': if(token=="class" )CreateClass(symbols, decls, tokens, parent(), next_parent, i, CLASS_CLASS , access_levels.last(), temp, templates, new_templates); break;
  654. case 'u': if(token=="union" )CreateClass(symbols, decls, tokens, parent(), next_parent, i, CLASS_UNION , access_levels.last(), temp, templates, new_templates); break;
  655. case 'e': if(token=="enum")
  656. {
  657. Token &name=*tokens[i+1]; name.def_decl=true; name.parent=parent();
  658. if(InRange(i+2, tokens))
  659. {
  660. Token &next=*tokens[i+2];
  661. if(next!=';') // skip forward declarations
  662. if(name.type==TOKEN_CODE && (next=='{' || (next==':' && InRange(i+4, tokens) && *tokens[i+4]=='{')) // valid name for enum "enum A {" or "enum A : B {"
  663. || name=='{') // nameless enum
  664. {
  665. UInt modifiers=0;
  666. Int start=i;
  667. SymbolPtr enm=symbols.New().require(UniqueName(parent, name, modifiers)).set(parent, Symbol::ENUM, (name=='{') ? i : i+1, name.line->source); if(name.type==TOKEN_CODE)name.symbol=enm();
  668. enm->type_range.set(i); enm->def_range.set(enm->token_index); enm->modifiers|=modifiers;
  669. for(; i<tokens.elms(); )
  670. {
  671. Token &token=*tokens[i++]; if(token=='{')
  672. {
  673. token.parent=enm();
  674. break;
  675. }
  676. }
  677. for(; i<tokens.elms(); )
  678. {
  679. Token &enum_elm=*tokens[i++]; enum_elm.def_decl=true; enum_elm.parent=enm();
  680. if(enum_elm.type==TOKEN_CODE)
  681. {
  682. modifiers=0;
  683. enum_elm.symbol=symbols.New().require(UniqueName(parent, enum_elm, modifiers)).set(parent, Symbol::ENUM_ELM, i-1, enum_elm.line->source); // ENUM_ELM's are assigned to the parent of ENUM
  684. enum_elm.symbol->value=enm; enum_elm.symbol->type_range=enm->def_range; enum_elm.symbol->def_range.set(i-1); enum_elm.symbol->modifiers|=modifiers;
  685. if(InRange(i, tokens) && *tokens[i]=='=') // custom value
  686. {
  687. tokens[i++]->parent=enm();
  688. for(; i<tokens.elms(); i++)
  689. {
  690. Token &token=*tokens[i];
  691. if(token=='{' || token=='}' || token==',' || token==';')break;
  692. token.parent=enm();
  693. }
  694. }
  695. }else
  696. if(enum_elm=='}') // enum declaration end
  697. {
  698. FlagSet(enm->modifiers, Symbol::MODIF_TYPEDEF, InRange(start-1, tokens) && *tokens[start-1]=="typedef");
  699. if(enm->modifiers&Symbol::MODIF_TYPEDEF)ReadVarFunc(enm(), symbols, tokens, i, enm->token_index, SPACE_NORMAL, temp, templates, new_templates);
  700. i--; break;
  701. }else
  702. if(enum_elm!=',') // ',' means next enum element so just skip it
  703. {
  704. // not TOKEN_CODE, not '}', not ',' means error
  705. DEBUG_ASSERT(token.line->source->cpp==false, S+"invalid enum declaration\nLine ("+token.lineIndex()+"): \""+*token.line+"\"\nSource: \""+token.line->source->loc.asText()+"\""); // report error only on C++ files
  706. }
  707. }
  708. }
  709. }
  710. }break;
  711. case 't': if(token=="typedef")
  712. {
  713. i++;
  714. Int type_start=i;
  715. Bool data_type =false;
  716. for(; i<tokens.elms(); i++) // skip modifiers ("typedef const int volatile x", "typedef int const x")
  717. {
  718. Token &token=*tokens[i];
  719. if(token.type==TOKEN_KEYWORD)
  720. {
  721. token.parent=parent(); SetTokenSymbol(token, temp);
  722. if(token.symbol && (token.symbol->modifiers&Symbol::MODIF_DATA_TYPE)){if(!data_type)type_start=i; data_type=true;}
  723. }else break;
  724. }
  725. if(InRange(i+1, tokens)) // check if it's a possible struct/class/union/enum definition
  726. {
  727. Token &token=*tokens[i-1];
  728. if(token.type==TOKEN_KEYWORD)
  729. if(token=="struct" || token=="class" || token=="union" || token=="enum")
  730. {
  731. Token &name=*tokens[i], &next=*tokens[i+1];
  732. if(name=='{' // nameless "typedef struct {} X;"
  733. ||(name.type==TOKEN_CODE && (next=='{' || next==':'))) // named "typedef struct A {} X;" or "typedef struct A:B {} X;"
  734. {
  735. i-=2; break; // if it's a definition then don't process it here (move cursor back to 'struct' and additional step back because it will be increased in main loop)
  736. }
  737. }
  738. }
  739. if(!data_type){type_start=i; SkipUnknownSymbol(tokens, i, parent());} // if there wasn't any keyword data type then we must skip unknown data type
  740. ReadVarFunc(null, symbols, tokens, i, type_start, SPACE_NORMAL, temp, templates, new_templates);
  741. i--;
  742. }break;
  743. }
  744. }break;
  745. }
  746. }
  747. }
  748. /******************************************************************************/
  749. // TODO: LinkDataTypes will fail for "typedef CLASS<TEMPLATE_FROM_VAR_FUNC> TYPEDEF;" because var funcs were not yet processed during LinkDataTypes stage
  750. void LinkDataTypes(Memc<SymbolDef> &symbols, Memc<Token*> &tokens)
  751. {
  752. Str temp;
  753. REPA(symbols) // iterate through all symbol definitions in this source
  754. {
  755. Symbol &symbol=*symbols[i];
  756. if( symbol.valid)
  757. {
  758. if(symbol.valid>1) // if symbol was defined more than one time then check if we're processing the one which source fits the source of the tokens (this is needed in case symbol is from different source, in which case we would be operating on tokens of different source)
  759. {
  760. Bool same_source=false;
  761. if(InRange(symbol.token_index, tokens))
  762. if(Line *line=tokens[symbol.token_index]->line)same_source=(line->source==symbol.source);
  763. if(!same_source)continue; // skip this symbol
  764. }
  765. switch(symbol.type)
  766. {
  767. case Symbol::TYPEDEF: // if it's a typedef
  768. {
  769. if(!(symbol.modifiers&Symbol::MODIF_TYPEDEF)) // not direct typedef's must be linked
  770. {
  771. symbol.value=null; // clear only value symbol pointer (and keep modifiers, const_level, ptr_level, array_dims, etc.)
  772. for(Int i=GetSymbolStart(tokens, symbol.token_index)+1; InRange(i, tokens); ) // +1 to skip the 'typedef' token
  773. {
  774. Int start=i;
  775. Symbol *ts =GetFullSymbol(tokens, i, temp, tokens[i]->parent, symbol.value.templates);
  776. if(ts && (ts->modifiers&Symbol::MODIF_CPP_MODIFIER))
  777. {
  778. // ignore modifiers
  779. }else
  780. {
  781. symbol.value=ts;
  782. symbol.type_range.y=i-1;
  783. break;
  784. }
  785. MAX(i, start+1);
  786. }
  787. }
  788. }break;
  789. case Symbol::CLASS: // if it's a class, then detect its base classes
  790. {
  791. symbol.base.clear();
  792. Int i=symbol.token_index+1; // skip class name, and check next operator
  793. if(InRange(i, tokens) && *tokens[i]==':')for(i++; ; )
  794. {
  795. Symbol::ACCESS_LEVEL access_level=symbol.access_level; // get default access
  796. Memc<Symbol::Modif> templates;
  797. for(; i<tokens.elms(); i++) // read modifiers
  798. {
  799. Token &token=*tokens[i];
  800. if(token=="private" )access_level=Symbol::ACCESS_PRIVATE ;else
  801. if(token=="protected")access_level=Symbol::ACCESS_PROTECTED;else
  802. if(token=="public" )access_level=Symbol::ACCESS_PUBLIC ;else break;
  803. }
  804. if(Symbol *base=GetFullSymbol(tokens, i, temp, &symbol, templates))
  805. {
  806. Symbol::Modif &symbol_base=symbol.base.New(); symbol_base=base; Swap(symbol_base.templates, templates); symbol_base.modifiers=Symbol::AccessLevelToModif(access_level);
  807. symbol.def_range.y=i-1;
  808. if(InRange(i, tokens) && *tokens[i++]==',')continue;
  809. }
  810. break;
  811. }
  812. }break;
  813. }
  814. }
  815. }
  816. }
  817. /******************************************************************************/
  818. static Symbol* ConvertToFunc(Memc<SymbolDef> &symbols, SymbolPtr *var_func, Int token_index, Source *source, Bool func_ptr_or_ref)
  819. {
  820. if(var_func)if(SymbolPtr &symbol=*var_func)
  821. {
  822. if(symbol->type==Symbol::VAR && symbol->valid==1)symbol->type=(func_ptr_or_ref ? Symbol::FUNC : Symbol::FUNC_LIST);
  823. if(symbol->type==Symbol::FUNC_LIST )
  824. {
  825. symbol->modifiers|=Symbol::MODIF_TRANSPARENT; // FUNC_LIST need to be transparent
  826. SymbolPtr &s=symbols.New().require(symbol->full_name+SEP+RandomName()).set(symbol, Symbol::FUNC, token_index, source); // function instance
  827. symbol->funcs.add(s); // add function instance to the function list
  828. symbol=s; // set token symbol to function instance instead of list
  829. }
  830. }
  831. return var_func ? (*var_func)() : null;
  832. }
  833. /******************************************************************************/
  834. Bool IsDeclaration(Memc<Token*> &tokens, Symbol *symbol, Int i)
  835. {
  836. // if(const A<X,B<Y,Z>>.C *x)
  837. for(Int level=0, start=i; i>0; i--)
  838. {
  839. Token &token=*tokens[i];
  840. if(token=='.' || token=="->" || token=="::" || token==',')continue; // skip operators
  841. if(token==TMPL_B){level++; if(level<=0)continue;} // don't continue if level>0
  842. if(token==TMPL_E){level--; continue;}
  843. if(!token.symbol)break; // if no symbol then break
  844. if(!(token.symbol->modifiers&Symbol::MODIF_DATA_TYPE) && !(token.symbol->modifiers&Symbol::MODIF_CPP_MODIFIER) && token.symbol->type!=Symbol::NAMESPACE)break; // if symbol is not data type or modifier or namespace then break
  845. if(!level && start!=i && token.symbol==symbol)return false; // if we have constructor declaration (X::X) then return false
  846. }
  847. if(!i)return true;
  848. Token &token=*tokens[i];
  849. if(token==';'
  850. || token=='{'
  851. || token=='}'
  852. || token=="do"
  853. || token=="else")return true;
  854. if(token=='(')
  855. {
  856. // if(TYPE ..)TYPE ..
  857. // for(TYPE ..; TYPE ..; )TYPE ..
  858. // while(TYPE ..)TYPE ..
  859. // switch(TYPE ..)
  860. if(InRange(i-1, tokens))
  861. {
  862. Token &token=*tokens[i-1];
  863. if(token=="if"
  864. || token=="for"
  865. || token=="while"
  866. || token=="switch")return true;
  867. }
  868. }else
  869. if(token==')')
  870. {
  871. // if(TYPE ..)TYPE ..
  872. // for(TYPE ..; TYPE ..; )TYPE ..
  873. // while(TYPE ..)TYPE ..
  874. // switch(TYPE ..)TYPE ..
  875. for(Int level=0; --i>=0; )
  876. {
  877. Token &token=*tokens[i];
  878. switch(token[0])
  879. {
  880. case '{':
  881. case '}':
  882. case ';': return false;
  883. case ')': --level; break;
  884. case '(': if(++level>0)
  885. {
  886. if(InRange(i-1, tokens)){Token &token=*tokens[i-1]; return token=="if" || token=="for" || token=="while" || token=="switch";}
  887. return false;
  888. }break;
  889. }
  890. }
  891. }else
  892. if(token==':') // label, access mode, case
  893. {
  894. if(InRange(i-2, tokens))
  895. {
  896. if(tokens[i-1]->type==TOKEN_CODE) // label name
  897. {
  898. Token &token=*tokens[i-2]; // allowed tokens before label name
  899. if(token==';'
  900. || token=='{'
  901. || token=='}')return true;
  902. }
  903. if(tokens[i-1]->type==TOKEN_KEYWORD) // access
  904. {
  905. Token &token=*tokens[i-1];
  906. if(token=="public"
  907. || token=="protected"
  908. || token=="private")return true;
  909. }
  910. for(Int level=0; i>0; ) // try "case:"
  911. {
  912. Token &token=*tokens[--i];
  913. switch(token[0])
  914. {
  915. case '{':
  916. case '}':
  917. case ';': return false;
  918. case '(': case '[': level++; break;
  919. case ')': case ']': level--; break;
  920. default : if(!level && token=="case")return true; break;
  921. }
  922. }
  923. }
  924. }else
  925. if(token=="typedef")return true; // typedef TYPE
  926. return false;
  927. }
  928. /******************************************************************************
  929. struct X
  930. {
  931. int x (); // forward declaration of function, FUNC
  932. int ( y)(); // forward declaration of function, FUNC
  933. int (*z)(); // pointer to function , FUNC
  934. int w ; // var , VAR
  935. int (u) ; // var , VAR
  936. int *v ; // pointer to var , VAR
  937. int*(*a) ; // pointer to pointer , VAR
  938. };
  939. int x () ; x(); // forward declaration of function, FUNC
  940. int ( y)() ; y(); // forward declaration of function, FUNC
  941. int (*z)()=null ; z(); // pointer to function , FUNC
  942. int w ; w ; // var , VAR
  943. int u (0) ; u ; // var , VAR
  944. int v= 0 ; v ; // var , VAR
  945. int *a= null ; a ; // pointer to var , VAR
  946. int *b( null) ; b ; // pointer to var , VAR
  947. int c[2][2]={}; c ; // array of int's , VAR
  948. Vec2 v(1,2) ;
  949. Vec2 v(Class::stat_var);
  950. Vec2 v(obj.var);
  951. struct X
  952. {
  953. X x ( ); // forward declaration of function, FUNC
  954. X ( y)( ); // forward declaration of function, FUNC
  955. X (*z)( ); // pointer to function , FUNC
  956. X w ; // var , VAR
  957. X (u) ; // var , VAR
  958. X *v ; // pointer to var , VAR
  959. X (*a) ; // pointer to var , VAR
  960. X*(*b) ; // pointer to pointer , VAR
  961. X ( ); // constructor , FUNC
  962. X (int x); // constructor , FUNC
  963. };
  964. void * (*GetFunc(..params1..)) (..params2..); function which returns pointer to function
  965. /******************************************************************************/
  966. Bool IsVarFuncDefinition(Memc<Token*> &tokens, Int &i, Str &temp, Symbol* &symbol, Memc<Symbol::Modif> &templates, Symbol *set_parent, Symbol* *symbol_parent, Int *symbol_index)
  967. {
  968. /**
  969. int a();
  970. int b(5);
  971. int c(int);
  972. int d(int z);
  973. int e(int(5));
  974. int f(int(z));
  975. int g(int( ));
  976. int h(Vec);
  977. int i(Vec z);
  978. Vec j(Vec(5));
  979. int k(Vec(z));
  980. int l(Vec( ));
  981. a();
  982. b=0;
  983. c(0);
  984. d(0);
  985. e=0;
  986. f(0);
  987. g(0);
  988. h(0);
  989. i(0);
  990. j=0;
  991. k(0);
  992. l(0);
  993. void func(const ..) OK modifier at start
  994. void func(Vec2 ) OK data type followed by *&,) (unnamed parameter)
  995. void func(Vec2 v) OK data type followed by *&TOKEN_CODE ( named parameter)
  996. void func(Vec2( )) OK data type followed by ()
  997. void func(Vec2(*& )) OK data type followed by (*&)
  998. void func(Vec2( 0 )) BAD data type followed by (TOKEN_NUMBER
  999. void func(Vec2('a')) BAD data type followed by (CHR
  1000. void func(Vec2( v)) OK token.type==TOKEN_CODE
  1001. void func(Vec2(*&v)) OK token.type==TOKEN_CODE
  1002. void func(Vec2(v.a)) BAD name not followed by )
  1003. /**/
  1004. if(symbol=GetFullSymbol(tokens, i, temp, set_parent, templates, symbol_parent, symbol_index))
  1005. {
  1006. if(symbol->modifiers&Symbol::MODIF_CPP_MODIFIER)return true;
  1007. if(symbol->modifiers&Symbol::MODIF_DATA_TYPE )
  1008. {
  1009. if(InRange(i, tokens) && *tokens[i]=='(') // if has brackets then we need to perform additional checks
  1010. {
  1011. for(Int j=i+1; j<tokens.elms(); j++)
  1012. {
  1013. Token &token=*tokens[j];
  1014. if(token=='*' || token=='&')continue;
  1015. if(token==')')return true;
  1016. if(token.type==TOKEN_CODE && InRange(j+1, tokens) && *tokens[j+1]==')')return true; // allow only if name is TOKEN_CODE and is followed by ')'
  1017. break;
  1018. }
  1019. return false;
  1020. }
  1021. return true;
  1022. }
  1023. }
  1024. return false;
  1025. }
  1026. /******************************************************************************/
  1027. static void SkipParams(Memc<Token*> &tokens, Int &i, Symbol *set_parent)
  1028. {
  1029. for(Int level=0; i<tokens.elms(); )
  1030. {
  1031. Token &token=*tokens[i];
  1032. if(token=='{' || token=='}' || token==';')return;
  1033. if(token==')')if(!level--)return;
  1034. if(token=='(') level++;
  1035. i++; token.parent=set_parent;
  1036. }
  1037. }
  1038. static void SkipThrow(Memc<Token*> &tokens, Int &i, Symbol *set_parent)
  1039. {
  1040. if(InRange(i, tokens) && *tokens[i]=='(')
  1041. {
  1042. tokens[i++]->parent=set_parent;
  1043. SkipParams(tokens, i, set_parent);
  1044. if(InRange(i, tokens) && *tokens[i]==')')tokens[i++]->parent=set_parent;
  1045. }
  1046. }
  1047. /******************************************************************************/
  1048. // TODO: add support for template based auto-casts like "T1(BASE) operator Memc<BASE>& (); // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  1049. static void ReadAutoCast(Symbol *symbol, Memc<SymbolDef> &symbols, Memc<Token*> &tokens, Int &i, Int start, Str &temp, Memc<Symbol::Modif> &templates) // operator const char * () {}
  1050. {
  1051. Token &token_start =*tokens[start];
  1052. Symbol *start_parent= token_start.parent;
  1053. if(symbol ? (!start_parent || start_parent->type==Symbol::NAMESPACE) // we can define auto-cast operator only in namespace (if Class was specified)
  1054. : ( start_parent && start_parent->type==Symbol::CLASS )) // or inside class (if Class was not specified)
  1055. {
  1056. if(!symbol)symbol=start_parent;
  1057. if( symbol && symbol->type==Symbol::CLASS)
  1058. {
  1059. UInt const_level=0;
  1060. Int ptr_level=0;
  1061. UInt modifiers=0;
  1062. if(InRange(i, tokens) && *tokens[i]=="const"){const_level=1; tokens[i++]->parent=start_parent;}
  1063. Memc<Symbol::Modif> type_templates;
  1064. if(Symbol *type=GetFullSymbol(tokens, i, temp, start_parent, type_templates))
  1065. {
  1066. for(; i<tokens.elms(); )
  1067. {
  1068. Token &mod=*tokens[i];
  1069. if(mod=='*' )ptr_level++;else
  1070. if(mod=='&' )modifiers |=Symbol::MODIF_REF;else
  1071. if(mod=="const")const_level|=(1<<ptr_level);else break;
  1072. i++; mod.parent=start_parent;
  1073. }
  1074. if(InRange(i+1, tokens) && *tokens[i]=='(' && *tokens[i+1]==')')
  1075. {
  1076. tokens[i++]->parent=start_parent; // '('
  1077. tokens[i++]->parent=start_parent; // ')'
  1078. if(InRange(i, tokens) && *tokens[i]=="const"){tokens[i++]->parent=start_parent; modifiers|=Symbol::MODIF_FUNC_CONST;} // ()const
  1079. if(InRange(i, tokens) && *tokens[i]=="throw"){tokens[i++]->parent=start_parent; SkipThrow(tokens, i, start_parent); } // throw(..)
  1080. SymbolPtr op=symbols.New().require(symbol->full_name+SEP+"operator cast").set(symbol, Symbol::FUNC_LIST, start, token_start.line->source);
  1081. op->modifiers|=Symbol::MODIF_SKIP_SUGGESTIONS; // operate on FUNC_LIST before converting to FUNC
  1082. ConvertToFunc(symbols, &op, start, token_start.line->source, false); // 'func_ptr_or_ref'=false because auto cast operators are never a pointer to function
  1083. op->def_range.set(start, i-1);
  1084. op-> modifiers|=(modifiers & ~Symbol::MODIF_REF); // set all except MODIF_REF
  1085. op->value.modifiers|=(modifiers & Symbol::MODIF_REF); // set only MODIF_REF
  1086. op->value=type;
  1087. op->value. ptr_level= ptr_level;
  1088. op->value.const_level=const_level;
  1089. Swap(op->value.templates, type_templates);
  1090. if(InRange(i, tokens) && *tokens[i]=='{')
  1091. {
  1092. op->modifiers|=Symbol::MODIF_FUNC_BODY;
  1093. for(Int level=0; i<tokens.elms(); )
  1094. {
  1095. Token &token=*tokens[i++]; token.parent=op();
  1096. if(token=='{') ++level;else
  1097. if(token=='}')if(--level<=0)break;
  1098. }
  1099. }
  1100. }
  1101. }
  1102. }
  1103. }
  1104. }
  1105. /******************************************************************************/
  1106. // TODO: remove this
  1107. void GetFuncParams(Memc<SymbolDef> &symbols, Memc<Token*> &tokens, Int &i, Str &temp, SymbolPtr *var_func, Int var_func_name_token_index, Bool func_ptr_or_ref, Symbol *set_parent)
  1108. {
  1109. Int params_as_values=0;
  1110. for(; i<tokens.elms(); )
  1111. {
  1112. UInt const_level=0, const_level_in_bracket=0;
  1113. Int ptr_level=0, ptr_level_in_bracket=0, bracket_level=0, type_start=i;
  1114. UInt modifiers=0, modifiers_in_bracket=Symbol::MODIF_FUNC_PARAM;
  1115. Token *par=tokens[i++]; par->parent=set_parent;
  1116. if(*par=="const"){par=(InRange(i, tokens) ? tokens[i++] : null); par->parent=set_parent; const_level=1;}
  1117. if( par)
  1118. {
  1119. if(*par==')')break;
  1120. if(*par==',')continue;
  1121. Bool definition=false; i--; Int start=i; Memc<Symbol::Modif> templates; Symbol *type; if(IsVarFuncDefinition(tokens, i, temp, type, templates, set_parent))if(type->modifiers&Symbol::MODIF_DATA_TYPE)definition=true;
  1122. if( definition)
  1123. {
  1124. ConvertToFunc(symbols, var_func, var_func_name_token_index, tokens[var_func_name_token_index]->line->source, func_ptr_or_ref);
  1125. Int type_end=i-1;
  1126. for(; i<tokens.elms(); )
  1127. {
  1128. Int param_token_index=i;
  1129. Token &name=*tokens[i++]; name.parent=set_parent;
  1130. switch(name.type)
  1131. {
  1132. case TOKEN_OPERATOR:
  1133. {
  1134. switch(name[0])
  1135. {
  1136. case '*': if(bracket_level)ptr_level_in_bracket++;else ptr_level++; break;
  1137. case '&': if(bracket_level)modifiers_in_bracket|=Symbol::MODIF_REF;else modifiers|=Symbol::MODIF_REF;break;
  1138. case '(': bracket_level++; break;
  1139. case ',':
  1140. case ')':
  1141. case '=':
  1142. {
  1143. // TODO: create empty param
  1144. if(name[0]=='=') // default value
  1145. {
  1146. // for example: 5, x, 1*(x+2), Map<Image,Int>::static_var+Mems<X>::stat_var
  1147. Int start=i; ParseTemplates(tokens, i, temp, set_parent, false);
  1148. //if(name.symbol){name.symbol->modifiers|=Symbol::MODIF_DEF_VALUE; name.symbol->def_range.y=i-1; name.symbol->def_val_range.set(start, i-1);}
  1149. break;
  1150. }
  1151. if(name[0]==',')goto finished_param;
  1152. else goto finished_params;
  1153. }break;
  1154. default: goto finished_params; // error
  1155. }
  1156. }break;
  1157. case TOKEN_KEYWORD:
  1158. {
  1159. if(name=="const")
  1160. {
  1161. if(bracket_level)const_level_in_bracket|=(1<<ptr_level_in_bracket);
  1162. else const_level |=(1<<ptr_level );
  1163. }else
  1164. if(name=="long"){}else // long long
  1165. goto finished_params; // error
  1166. }break;
  1167. case TOKEN_CODE:
  1168. {
  1169. for(; bracket_level>0 && i<tokens.elms() && *tokens[i]==')'; ){bracket_level--; tokens[i++]->parent=set_parent;} // force closing brackets started earlier "int ((x))|"
  1170. if( !bracket_level)
  1171. {
  1172. name.def_decl=true;
  1173. if(var_func)if(SymbolPtr &func=*var_func)
  1174. {
  1175. name.symbol=symbols.New().require(func->full_name+SEP+name).set(func, Symbol::VAR, param_token_index, name.line->source);
  1176. name.symbol->value =type; Swap(name.symbol->value.templates, templates);
  1177. // TODO: when name.symbol will be as FUNC, then calculate differently
  1178. name.symbol-> modifiers|=((modifiers| modifiers_in_bracket) & ~Symbol::MODIF_REF); // set all except MODIF_REF
  1179. name.symbol->value. modifiers|=((modifiers| modifiers_in_bracket) & Symbol::MODIF_REF); // set only MODIF_REF
  1180. name.symbol->value. ptr_level= ptr_level+ ptr_level_in_bracket;
  1181. name.symbol->value.const_level=const_level|(const_level_in_bracket<<ptr_level);
  1182. name.symbol->type_range.set(type_start, type_end);
  1183. name.symbol-> def_range.set(type_end+1);
  1184. func->params.add(name.symbol);
  1185. }
  1186. for(; i<tokens.elms(); )
  1187. {
  1188. Token &op=*tokens[i++]; op.parent=set_parent;
  1189. switch(op[0])
  1190. {
  1191. case '(': // parameter list or default value declaration
  1192. {
  1193. // TODO:
  1194. GetFuncParams(symbols, tokens, i, temp, null, param_token_index, true, set_parent); // 'func_ptr_or_ref'=true because we're processing function parameters and in such we can pass only pointer to function (never define new function)
  1195. }break;
  1196. case '[': // array
  1197. {
  1198. for(Str dim; i<tokens.elms(); )
  1199. {
  1200. Token &token=*tokens[i++]; token.parent=set_parent;
  1201. if(token==']')
  1202. {
  1203. // TODO: watch out for error in calculation of 'CalculateI' or <=0 value
  1204. // TODO: this is wrong, ignores ptr_level_in_bracket
  1205. if(name.symbol)name.symbol->value.array_dims.NewAt(0)=CalculateI(dim);
  1206. goto finished_dim;
  1207. }
  1208. dim+=token;
  1209. }
  1210. goto finished_params; // error
  1211. finished_dim:;
  1212. }break;
  1213. case '=': // default value
  1214. {
  1215. // for example: 5, x, 1*(x+2), Map<Image,Int>::static_var+Mems<X>::stat_var
  1216. Int start=i; ParseTemplates(tokens, i, temp, set_parent, false);
  1217. if(name.symbol){name.symbol->modifiers|=Symbol::MODIF_DEF_VALUE; name.symbol->def_range.y=i-1; name.symbol->def_val_range.set(start, i-1);}
  1218. }break;
  1219. case ',':
  1220. {
  1221. if(name.symbol)name.symbol->def_range.y=i-2;
  1222. }goto finished_param; // proceed to next param
  1223. default:
  1224. {
  1225. if(name.symbol)name.symbol->def_range.y=i-2;
  1226. }goto finished_params; // end of param declaration
  1227. }
  1228. }
  1229. }
  1230. }break;
  1231. default: goto finished_params; // error
  1232. }
  1233. }
  1234. }else
  1235. {
  1236. // for example: 5, x, 1*(x+2), Map<Image,Int>::static_var+Mems<X>::stat_var
  1237. i= start; ParseTemplates(tokens, i, temp, set_parent, false);
  1238. if(i==start)goto finished_params;
  1239. params_as_values++;
  1240. }
  1241. }
  1242. finished_param:;
  1243. }
  1244. finished_params:;
  1245. if(!params_as_values)ConvertToFunc(symbols, var_func, var_func_name_token_index, tokens[var_func_name_token_index]->line->source, func_ptr_or_ref);
  1246. }
  1247. void ReadVarFuncs(Memc<SymbolDef> &symbols, Memc<Token*> &tokens, Int &i, SPACE_MODE space_mode, Str &temp, Symbol *set_parent) // don't re-use 'templates' and 'new_templates' from other functions because they might be still used
  1248. {
  1249. Memc<Symbol::Modif> templates;
  1250. Memc<Int> new_templates;
  1251. // process var funcs
  1252. for(; i<tokens.elms(); )
  1253. {
  1254. Int start=i;
  1255. Token &token=*tokens[i];
  1256. if(token.type==TOKEN_OPERATOR)
  1257. {
  1258. if(token==','){i++; token.parent=set_parent; continue;} // proceed to next element
  1259. if(token==')' || token=='{' || token=='}')return;
  1260. }
  1261. Symbol *symbol_parent;
  1262. if(Symbol *type=GetFullSymbol(tokens, i, temp, set_parent, templates, &symbol_parent))
  1263. {
  1264. if(type->modifiers&Symbol::MODIF_DATA_TYPE) // if current element is of data type, then probably it's member/var/method/function definition/declaration
  1265. {
  1266. ReadVarFunc(type, symbols, tokens, i, start, space_mode, temp, templates, new_templates, symbol_parent);
  1267. continue;
  1268. }else
  1269. if(type->modifiers&Symbol::MODIF_CPP_MODIFIER)
  1270. {
  1271. continue;
  1272. }
  1273. }
  1274. ParseTemplates(tokens, i, temp, set_parent, space_mode==SPACE_TEMPLATE);
  1275. MAX(i, start+1);
  1276. }
  1277. }
  1278. void ReadVarFunc(Symbol *type, Memc<SymbolDef> &symbols, Memc<Token*> &tokens, Int &i, Int type_start, SPACE_MODE space_mode, Str &temp, Memc<Symbol::Modif> &templates, Memc<Int> &new_templates, Symbol *symbol_parent)
  1279. {
  1280. Int type_start_backup=type_start;
  1281. if(InRange(type_start-1, tokens)) // 'type_start' may be different between named/nameless struct/class/union/enum, so adjust 'type_start' if needed (case of "struct {}obj;" ?)
  1282. {
  1283. Token &token=*tokens[type_start-1];
  1284. if(token.type==TOKEN_KEYWORD && (token=="struct" || token=="class" || token=="union" || token=="enum"))type_start--;
  1285. }
  1286. Token &token_start =*tokens[type_start];
  1287. Symbol *start_parent= token_start.parent;
  1288. Bool skip_suggestions=false,
  1289. inside_class=(start_parent && start_parent->type==Symbol::CLASS),
  1290. ctor_dtor=false, dtor=(InRange(i-2, tokens) && *tokens[i-2]=='~'); // ~X X::~X
  1291. UInt modifiers=0, modifiers_in_bracket=0, group_modifiers=0, // "group_modifiers TYPE modifiers (modifiers_in_bracket VAR)", "const int& (*var)()"
  1292. const_level=0, const_level_in_bracket=0, group_const_level=0;
  1293. Int ptr_level=0, ptr_level_in_bracket=0,
  1294. bracket_level=0;
  1295. Str name;
  1296. Mems<Int> array_dims;
  1297. Int type_modif_start=ReadModifiers(tokens, type_start-1, group_const_level, group_modifiers, new_templates, temp); // start of type modifiers (including templates) "|<TYPE> const Int"
  1298. // check if it's typedef (check tokens before 'type_modif_start')
  1299. Bool is_typedef=false;
  1300. if(InRange(type_modif_start-1, tokens))
  1301. {
  1302. Token &token=*tokens[type_modif_start-1];
  1303. if(token.type==TOKEN_KEYWORD)
  1304. if(token=="typedef" // "typedef"
  1305. ||(token=="typename" && InRange(type_modif_start-2, tokens) && *tokens[type_modif_start-2]=="typedef")) // "typedef typename"
  1306. {
  1307. is_typedef=true;
  1308. type_modif_start-=((token=="typedef") ? 1 : 2); // 1 for "typedef", 2 for "typedef typename"
  1309. if(type && (type->type==Symbol::CLASS || type->type==Symbol::ENUM) && (type->modifiers&Symbol::MODIF_TYPEDEF)) // if type is class/enum with direct typedef
  1310. if(type->source==token.line->source && type->token_index==type_start_backup)group_modifiers|=Symbol::MODIF_TYPEDEF; // if typedef being declared in the same source as type, and the type definition token index is equal to start it means we're declaring direct B typedef "typedef class A {} B"
  1311. }
  1312. }
  1313. // process modifiers at name position (at 'i')
  1314. for(; i<tokens.elms(); )
  1315. {
  1316. Token &token=*tokens[i];
  1317. if(token.type==TOKEN_KEYWORD)
  1318. {
  1319. SetTokenSymbol(token, temp);
  1320. if(token.symbol && (token.symbol->modifiers&Symbol::MODIF_CPP_MODIFIER))
  1321. {
  1322. i++; token.parent=start_parent;
  1323. ReadModifier(token, group_const_level, group_modifiers);
  1324. continue;
  1325. }
  1326. }
  1327. break; // break on any non-modifier token
  1328. }
  1329. // detect 'type_end' (check tokens between 'type_start' and 'i')
  1330. Int type_end=type_start;
  1331. for(; ; type_end++)
  1332. {
  1333. if(type_end>=i-1)break; // max limit
  1334. Token &token=*tokens[type_end+1];
  1335. if(token==':' || token=='{')break; // struct X : Y { } x;
  1336. }
  1337. // process modifiers in type range (between 'type_start' and 'type_end', sample: "int const unsigned")
  1338. for(Int i=type_start; i<=type_end; i++)
  1339. {
  1340. Token &token=*tokens[i];
  1341. if(token.type==TOKEN_KEYWORD)
  1342. {
  1343. if(token.symbol && (token.symbol->modifiers&Symbol::MODIF_CPP_MODIFIER))ReadModifier(token, group_const_level, group_modifiers);
  1344. continue;
  1345. }
  1346. break; // break on any non-keyword token
  1347. }
  1348. // process var/func
  1349. Int var_func_def_start=i; // var func definition start, this includes pointers "int |**x"
  1350. Bool is_friend=FlagTest(group_modifiers, Symbol::MODIF_FRIEND);
  1351. if(space_mode==SPACE_NORMAL ){if(inside_class && !is_friend)group_modifiers|=Symbol::AccessLevelToModif(start_parent->access_level);}else
  1352. if(space_mode==SPACE_FUNC_PARAM){ group_modifiers|=Symbol::MODIF_FUNC_PARAM;}
  1353. for(; i<tokens.elms(); )
  1354. {
  1355. Int var_func_name_token_index=i; // this must be precisely set to the token which contains the name of the var_func
  1356. Token &token=*tokens[i];
  1357. switch(token.type)
  1358. {
  1359. case TOKEN_OPERATOR:
  1360. {
  1361. switch(token[0])
  1362. {
  1363. case ';': i++; token.parent=start_parent; return;
  1364. case '=':
  1365. case '[':
  1366. case ',':
  1367. case ')':
  1368. {
  1369. if(space_mode==SPACE_NORMAL)return; // "{int,}", "{int=}" is not supported
  1370. if(!name.is()){name="unused"; MakeUnique(name); skip_suggestions=true;} goto create; // "void func(int=", "void func(int,", "void func(int)", "void func(int[])" is supported
  1371. }break;
  1372. case '{':
  1373. case '}': return; // don't process {} symbols
  1374. default : i++; token.parent=start_parent; break;
  1375. case '*': i++; token.parent=start_parent; if(bracket_level)ptr_level_in_bracket++;else ptr_level++; break;
  1376. case '&': i++; token.parent=start_parent; if(bracket_level)modifiers_in_bracket|=Symbol::MODIF_REF;else modifiers|=Symbol::MODIF_REF; break;
  1377. case '(':
  1378. {
  1379. i++; token.parent=start_parent;
  1380. bracket_level++;
  1381. if(bracket_level==1) // check if we're declaring constructor/destructor X(|..)
  1382. {
  1383. if(type && type->type==Symbol::CLASS)
  1384. if( start_parent==type // class X{X();} class A{class B{A::B();}}
  1385. || symbol_parent==type && (!start_parent || start_parent->type==Symbol::NAMESPACE)) // X::X();
  1386. {
  1387. /*Int j=i; Symbol *symbol; Memc<Symbol::Modif> param_templates;
  1388. if(InRange(i, tokens) && *tokens[i]==')' // if nothing X(|)
  1389. || IsVarFuncDefinition(tokens, j, temp, symbol, param_templates, start_parent)) // or parameter definition*/ // can't use 'IsVarFuncDefinition' because it may use unknown yet templates
  1390. for(Int j=i, level=0; j<tokens.elms(); j++)
  1391. {
  1392. Token &token=*tokens[j];
  1393. if(token=='{' || token=='}' || token==';')break;
  1394. if(token=='(') level++;
  1395. if(token==')')if(!level--)
  1396. {
  1397. if(InRange(j+1, tokens) && *tokens[j+1]!='(')
  1398. {
  1399. name=(dtor ? S+'~'+*type : *type); ctor_dtor=true; var_func_name_token_index=type_start; bracket_level=0; i--;
  1400. goto create;
  1401. }
  1402. break;
  1403. }
  1404. }
  1405. }
  1406. }
  1407. }break;
  1408. }
  1409. }break;
  1410. case TOKEN_CODE :
  1411. case TOKEN_KEYWORD:
  1412. {
  1413. create:;
  1414. Memc<Symbol::Modif> name_templates;
  1415. Symbol *parent, *symbol=GetFullSymbol(tokens, i, temp, start_parent, name_templates, &parent, null, false); // 'parent'=to which symbol 'symbol' should belong to as a child
  1416. SymbolPtr symbol_ptr_temp, *symbol_ptr=&symbol_ptr_temp; // 'symbol_ptr'=pointer to Token::symbol which will be set to the created element
  1417. if(!parent )parent=start_parent ; // if parent hasn't been specified then use current space
  1418. if( is_friend && parent)parent=parent->Namespace() ; // friends are in nearest namespace
  1419. if( ctor_dtor )parent=type ; // constructors/destructors are always in their same class space
  1420. if( dtor )type =TypeSymbol(VAR_VOID); // destructors are of void type
  1421. if(!ctor_dtor )
  1422. {
  1423. if(symbol && (symbol->modifiers&Symbol::MODIF_CPP_MODIFIER))
  1424. {
  1425. if(*symbol=="const")
  1426. {
  1427. if(bracket_level)const_level_in_bracket|=(1<<ptr_level_in_bracket);else
  1428. const_level |=(1<<ptr_level );
  1429. }
  1430. // TODO: else compile error
  1431. break;
  1432. }
  1433. if(!InRange(i-1, tokens))return;
  1434. // check for pointer to member (function/variable) "func: void (Class::*func)();", "var: int Class::*var;"
  1435. if(!symbol && InRange(i+1, tokens)) // check for "i+1" because we're adding +2 and later accessing -1
  1436. {
  1437. Token &sep=*tokens[i-1];
  1438. if((sep=='.' || sep=="->" || sep=="::") && *tokens[i]=='*')i+=2;
  1439. }
  1440. Token &token=*tokens[i-1]; symbol_ptr=&token.symbol; token.def_decl=true;
  1441. if(!symbol)
  1442. {
  1443. if(!name.is())if(token.type==TOKEN_CODE)name=token;else return; // can only accept names as TOKEN_CODE (not keywords)
  1444. }else
  1445. if(symbol->type!=Symbol::KEYWORD)name=*symbol;else
  1446. {
  1447. if(*symbol!="operator")return; // can't use any other keyword except 'operator'
  1448. skip_suggestions=true;
  1449. if(is_friend || !parent || parent->type!=Symbol::CLASS)parent=null; // in C++ global operators work from all namespaces, which means we must store them in global namespace
  1450. if(InRange(i+1, tokens))
  1451. {
  1452. Token &p=*tokens[i], &n=*tokens[i+1];
  1453. if(p=='(' && n==')'){name= "operator()" ; p.parent=start_parent; n.parent=start_parent; i+=2;}else
  1454. if(p=='[' && n==']'){name= "operator[]" ; p.parent=start_parent; n.parent=start_parent; i+=2;}else
  1455. if(p=='<' && n=='<'){name= "operator<<" ; p.parent=start_parent; n.parent=start_parent; i+=2;}else
  1456. if(p=='>' && n=='>'){name= "operator>>" ; p.parent=start_parent; n.parent=start_parent; i+=2;}else
  1457. if(p=='+' ){name= "operator+" ; p.parent=start_parent; i+=1;}else
  1458. if(p=='-' ){name= "operator-" ; p.parent=start_parent; i+=1;}else
  1459. if(p=='*' ){name= "operator*" ; p.parent=start_parent; i+=1;}else
  1460. if(p=='/' ){name=S+"operator"+DIV ; p.parent=start_parent; i+=1;}else
  1461. if(p=='%' ){name= "operator%" ; p.parent=start_parent; i+=1;}else
  1462. if(p=='!' ){name= "operator!" ; p.parent=start_parent; i+=1;}else
  1463. if(p=='~' ){name= "operator~" ; p.parent=start_parent; i+=1;}else
  1464. if(p=='=' ){name= "operator=" ; p.parent=start_parent; i+=1;}else
  1465. if(p=='<' ){name= "operator<" ; p.parent=start_parent; i+=1;}else
  1466. if(p=='>' ){name= "operator>" ; p.parent=start_parent; i+=1;}else
  1467. if(p=='&' ){name= "operator&" ; p.parent=start_parent; i+=1;}else
  1468. if(p=='^' ){name= "operator^" ; p.parent=start_parent; i+=1;}else
  1469. if(p=='|' ){name= "operator|" ; p.parent=start_parent; i+=1;}else
  1470. if(p=="->" ){name= "operator->" ; p.parent=start_parent; i+=1;}else
  1471. if(p=="++" ){name= "operator++" ; p.parent=start_parent; i+=1;}else
  1472. if(p=="--" ){name= "operator--" ; p.parent=start_parent; i+=1;}else
  1473. if(p=="+=" ){name= "operator+=" ; p.parent=start_parent; i+=1;}else
  1474. if(p=="-=" ){name= "operator-=" ; p.parent=start_parent; i+=1;}else
  1475. if(p=="*=" ){name= "operator*=" ; p.parent=start_parent; i+=1;}else
  1476. if(p=="/=" ){name=S+"operator"+DIV+'='; p.parent=start_parent; i+=1;}else
  1477. if(p=="%=" ){name= "operator%=" ; p.parent=start_parent; i+=1;}else
  1478. if(p=="&=" ){name= "operator&=" ; p.parent=start_parent; i+=1;}else
  1479. if(p=="^=" ){name= "operator^=" ; p.parent=start_parent; i+=1;}else
  1480. if(p=="|=" ){name= "operator|=" ; p.parent=start_parent; i+=1;}else
  1481. if(p=="==" ){name= "operator==" ; p.parent=start_parent; i+=1;}else
  1482. if(p=="!=" ){name= "operator!=" ; p.parent=start_parent; i+=1;}else
  1483. if(p==">=" ){name= "operator>=" ; p.parent=start_parent; i+=1;}else
  1484. if(p=="<=" ){name= "operator<=" ; p.parent=start_parent; i+=1;}else
  1485. if(p=="===" ){name= "operator===" ; p.parent=start_parent; i+=1;}else
  1486. if(p=="!!=" ){name= "operator!!=" ; p.parent=start_parent; i+=1;}else
  1487. if(p=="<<=" ){name= "operator<<=" ; p.parent=start_parent; i+=1;}else
  1488. if(p==">>=" ){name= "operator>>=" ; p.parent=start_parent; i+=1;}else
  1489. if(p=="new" ){name= "operator new" ; p.parent=start_parent; i+=1;}else
  1490. if(p=="delete" ){name= "operator delete" ; p.parent=start_parent; i+=1;}else return;
  1491. }else return;
  1492. }
  1493. }
  1494. // set FUNC_LIST modifiers (those specified here will be the only ones set for FUNC_LIST, all others will be set to FUNC)
  1495. UInt func_list_modifiers=0; // modifiers set to the FUNC_LIST before converting it to FUNC
  1496. if(ctor_dtor)func_list_modifiers|=(dtor ? Symbol::MODIF_DTOR : Symbol::MODIF_CTOR);
  1497. FlagSet(func_list_modifiers, Symbol::MODIF_SKIP_SUGGESTIONS, skip_suggestions);
  1498. modifiers_in_bracket|=func_list_modifiers;
  1499. // create the var func
  1500. SymbolPtr &var_func=*symbol_ptr; var_func=symbols.New().require(UniqueVarFuncName(parent ? parent->firstNonTransparent() : null, name)).set(parent, is_typedef ? Symbol::TYPEDEF : Symbol::VAR, var_func_name_token_index, tokens[var_func_name_token_index]->line->source); // use first non-transparent parent for the symbol name (read more at MODIF_TRANSPARENT)
  1501. if(var_func->valid==1)var_func->modifiers|=func_list_modifiers;
  1502. // check if the var func has defined templates "<TYPE> void func()"
  1503. Symbol *set_parent_var_func=start_parent; // set_parent which may be possibly set to function itself
  1504. if(new_templates.elms()) // if templates are specified then it must be a function
  1505. {
  1506. set_parent_var_func=ConvertToFunc(symbols, &var_func, var_func_name_token_index, tokens[var_func_name_token_index]->line->source, ptr_level_in_bracket!=0 || (modifiers_in_bracket&Symbol::MODIF_REF)); // set the adjusted set_parent to the func, to allow template types detection (which belong to the func) inside the func params list
  1507. Int template_classes=0; if(!var_func->insideClass())template_classes=var_func->templateClasses(); // how many parent classes are with templates
  1508. FREPA(new_templates)ReadTemplates(symbols, tokens, new_templates[i], temp, *var_func, i>=template_classes);
  1509. if(!type) // try detecting function type again after reading templates if it was unknown
  1510. {
  1511. Int j=type_start; if(type=GetFullSymbol(tokens, j, temp, var_func(), templates))if(!(type->modifiers&Symbol::MODIF_DATA_TYPE))type=null;
  1512. }
  1513. }
  1514. Bool func_params_setup=false;
  1515. for(; i<tokens.elms(); )
  1516. {
  1517. Token &op=*tokens[i++]; op.parent=start_parent; // set parent of 'func' '(' ')' in "func(..)" to the class, so when evaluating the symbol of the func and checking from ')' backwards, we start from the same parent as the func parent
  1518. switch(op[0])
  1519. {
  1520. case '(': // parameter list or default value declaration
  1521. {
  1522. if(!func_params_setup)
  1523. {
  1524. func_params_setup=true;
  1525. SymbolPtr temp_parent=var_func->parent; // if we're processing functions which have parent set different than which defined then temporarily swap parents to detect the symbols: "class Parent { class Child { friend void func(Child &c); } }" - normally 'Child &c' would not be detected because 'func' parent is global namespace
  1526. if(!var_func->contains(start_parent))var_func->parent=start_parent; // adjusting parent needs to be done before calling 'IsVarFuncDefinition' because there the symbol may already get detected using the parent, perform this only if the new parent isn't actually a child of this symbol (which could cause never ending Symbol.parent->.. loops)
  1527. // check if these are default values
  1528. Int start=i; Symbol *type; Memc<Symbol::Modif> templates; // must use temporary 'templates' container
  1529. if(!(InRange(i, tokens) && *tokens[i]==')') // if not "Vec v(|)"
  1530. && !IsVarFuncDefinition(tokens, i, temp, type, templates, set_parent_var_func)) // if not "Vec v(|int v)"
  1531. { // default value
  1532. i=start;
  1533. SkipParams(tokens, i, set_parent_var_func);
  1534. if(var_func->valid==1){var_func->modifiers|=Symbol::MODIF_DEF_VALUE; var_func->def_val_range.set(start, i-1);}
  1535. }else
  1536. { // function with params
  1537. i=start;
  1538. var_func->parent=temp_parent; // restore parent before converting to func
  1539. set_parent_var_func=ConvertToFunc(symbols, &var_func, var_func_name_token_index, tokens[var_func_name_token_index]->line->source, ptr_level_in_bracket!=0 || (modifiers_in_bracket&Symbol::MODIF_REF));
  1540. temp_parent=var_func->parent; // keep backup
  1541. if(!var_func->contains(start_parent))var_func->parent=start_parent; // adjust parent after converting to func, perform this only if the new parent isn't actually a child of this symbol (which could cause never ending Symbol.parent->.. loops)
  1542. ReadVarFuncs(symbols, tokens, i, SPACE_FUNC_PARAM, temp, set_parent_var_func);
  1543. }
  1544. var_func->parent=temp_parent; // restore parent
  1545. if(InRange(i, tokens) && *tokens[i]==')' ) tokens[i++]->parent=start_parent; // adjust ')' parent
  1546. for(; InRange(i, tokens); i++)
  1547. {
  1548. Token &token=*tokens[i];
  1549. if(token=="const" ){token.symbol="const" ; token.parent=start_parent; modifiers_in_bracket|=Symbol::MODIF_FUNC_CONST ;}else // ()const
  1550. if(token=="final" ){token.symbol="final" ; token.parent=start_parent; /*modifiers_in_bracket|=Symbol::MODIF_FUNC_FINAL ;*/}else // ()final
  1551. if(token=="override"){token.symbol="override"; token.parent=start_parent; /*modifiers_in_bracket|=Symbol::MODIF_FUNC_OVERRIDE;*/}else // ()override
  1552. if(token=="throw" ){token.symbol="throw" ; token.parent=start_parent; SkipThrow(tokens, i, set_parent_var_func); }else // throw(..)
  1553. break;
  1554. }
  1555. }else // Flt (*Func(Byte type)) (Flt s) {} - function which returns function, "Func(Byte type)" -> "Flt f(Flt s)"
  1556. {
  1557. SkipThrow(tokens, --i, set_parent_var_func);
  1558. }
  1559. }break;
  1560. case '[': // array
  1561. {
  1562. for(Str dim; i<tokens.elms(); )
  1563. {
  1564. Token &token=*tokens[i++]; token.parent=set_parent_var_func;
  1565. if(token==']')
  1566. {
  1567. // TODO: watch out for error in calculation of "CalculateI(dim)"
  1568. Int d=CalculateI(dim); array_dims.NewAt(0)=((d>=1) ? d : Symbol::DIM_UNKNOWN);
  1569. goto finished_dim;
  1570. }
  1571. dim+=token;
  1572. }
  1573. DEBUG_ASSERT(op.line->source->cpp==false, "Invalid array definition");
  1574. return; // error
  1575. finished_dim:;
  1576. }break;
  1577. case '=': // default value
  1578. {
  1579. // for example: 5, x, 1*(x+2), Map<Image,Int>::static_var+Mems<X>::stat_var
  1580. Int start=i; ParseTemplates(tokens, i, temp, set_parent_var_func, space_mode==SPACE_TEMPLATE);
  1581. if(var_func->valid==1){modifiers_in_bracket|=Symbol::MODIF_DEF_VALUE; var_func->def_val_range.set(start, i-1);}
  1582. }break;
  1583. case ':': // constructor initializers "struct B : A {B() : A() {}}" or bit count "int x:1;"
  1584. {
  1585. if(InRange(i, tokens) && tokens[i]->type==TOKEN_CODE) // ctor initializer
  1586. {
  1587. op.ctor_initializer=true;
  1588. ConvertToFunc(symbols, &var_func, var_func_name_token_index, tokens[var_func_name_token_index]->line->source, false); // 'func_ptr_or_ref'=false because constructors are never a pointer to function
  1589. for(; i<tokens.elms(); )
  1590. {
  1591. Token &token=*tokens[i];
  1592. if(token.type==TOKEN_CODE)
  1593. {
  1594. Int start=i; SkipUnknownSymbol(tokens, i, set_parent_var_func);
  1595. for(; start<i; )tokens[start++]->ctor_initializer=true;
  1596. if(InRange(i, tokens) && *tokens[i]=='(')
  1597. {
  1598. Token &token=*tokens[i++];
  1599. token.ctor_initializer=true;
  1600. token.parent =set_parent_var_func;
  1601. for(Int level=0; i<tokens.elms(); )
  1602. {
  1603. Token &token=*tokens[i++]; token.parent=set_parent_var_func;
  1604. if(token=='(') level++;else
  1605. if(token==')')if(!level--)break;
  1606. }
  1607. if(InRange(i, tokens) && *tokens[i]==',')
  1608. {
  1609. Token &token=*tokens[i++];
  1610. token.ctor_initializer=true;
  1611. token.parent =set_parent_var_func;
  1612. continue; // continue to next constructor call
  1613. }
  1614. }
  1615. }
  1616. if(InRange(i, tokens))
  1617. {
  1618. Token &token=*tokens[i];
  1619. if(token==',' || token==';' || token=='{' || token=='}')break;
  1620. DEBUG_ASSERT(token.line->source->cpp==false, S+"Invalid constructor initializer.\nLine ("+token.lineIndex()+"): \""+*token.line+"\"\nSource: \""+token.line->source->loc.asText()+"\"");
  1621. token.parent=set_parent_var_func; i++;
  1622. }
  1623. }
  1624. }else // possibly bit count "int x:1;"
  1625. {
  1626. for(; i<tokens.elms(); )
  1627. {
  1628. Token &token=*tokens[i];
  1629. if(token==',' || token==';' || token=='{' || token=='}')break;
  1630. token.parent=set_parent_var_func; i++;
  1631. }
  1632. }
  1633. }break;
  1634. case ')':
  1635. case ',': // end of var/func declaration
  1636. case ';':
  1637. case '{':
  1638. default : // if we haven't finished declaring yet, and there's garbage after cursor "struct X{void name|};"
  1639. {
  1640. if(op[0]==')') // int (x), if(int x=..)
  1641. {
  1642. bracket_level--;
  1643. if(bracket_level>=0)break; // we still have possible tokens to process
  1644. }
  1645. DEBUG_ASSERT((op[0]==',' || op[0]==';' || op[0]==')' || op[0]=='{') || !op.line->source->cpp, S+"Unexpected Symbol.\nLine ("+op.lineIndex()+"): \""+*op.line+"\"\nSource: \""+op.line->source->loc.asText()+"\"");
  1646. if(op[0]=='{')
  1647. {
  1648. ConvertToFunc(symbols, &var_func, var_func_name_token_index, tokens[var_func_name_token_index]->line->source, false); // if we haven't finished declaring yet, but there's '{' "void x {" then force func, since we've encountered function body we know what this is not a pointer to function so 'func_ptr_or_ref'=false
  1649. modifiers_in_bracket|=Symbol::MODIF_FUNC_BODY;
  1650. }
  1651. if(!inside_class && var_func->Parent() && var_func->Parent()->type==Symbol::CLASS)modifiers_in_bracket|=Symbol::MODIF_OUTSIDE_METHOD;
  1652. if(var_func->valid==1)
  1653. {
  1654. var_func->type_range .set(type_modif_start , type_end);
  1655. var_func-> def_range .set(var_func_def_start, i-2);
  1656. var_func->value =type;
  1657. var_func->value.templates=templates; // don't use 'Swap' because 'templates' may be used by multiple variables "Memc<Int> a, b;" (by both 'a' and 'b')
  1658. if(var_func->type==Symbol::FUNC) // "int& func()", "int& (&func)()" or "int& (*func)()"
  1659. {
  1660. // TODO:
  1661. DEBUG_ASSERT(array_dims.elms()==0, "Array of pointer to functions is not currently supported"); // change to compile error
  1662. var_func-> modifiers |= modifiers_in_bracket|group_modifiers;
  1663. var_func->value.modifiers |= modifiers;
  1664. var_func-> func_ptr_level= ptr_level_in_bracket;
  1665. var_func->value. ptr_level= ptr_level;
  1666. var_func->value.const_level=const_level|group_const_level;
  1667. }else // "int x", "int* x", "int *x[2]" - 2 pointers to 1 int, "int (*)x[2]" - 1 pointer to 2 int's, "int* (*)x[2]" - 1 pointer to 2 int*
  1668. {
  1669. var_func-> modifiers|=((modifiers|modifiers_in_bracket|group_modifiers) & ~Symbol::MODIF_REF); // set all except MODIF_REF
  1670. var_func->value.modifiers|=((modifiers|modifiers_in_bracket|group_modifiers) & Symbol::MODIF_REF); // set only MODIF_REF
  1671. if(array_dims.elms())
  1672. {
  1673. // order: 'ptr_level', 'array_dims', 'ptr_level_in_bracket' (stored in 'array_dims' as DIM_PTR)
  1674. var_func->value. ptr_level= ptr_level; // set only base pointers
  1675. var_func->value.const_level=const_level|(const_level_in_bracket<<(ptr_level+array_dims.elms()))|group_const_level;
  1676. FREPA(array_dims )var_func->value.const_level|=(1<<(ptr_level+1+i)); // +1 is because for "int x[2];" 'ptr_level' is 0 so '0+i' would make "const int x[2];"
  1677. FREP (ptr_level_in_bracket)array_dims.add(Symbol::DIM_PTR); // append 'array_dims' with DIM_PTR from 'ptr_level_in_bracket'
  1678. Swap(var_func->value.array_dims, array_dims);
  1679. }else
  1680. {
  1681. var_func->value. ptr_level= ptr_level+ ptr_level_in_bracket;
  1682. var_func->value.const_level=const_level|(const_level_in_bracket<<ptr_level)|group_const_level;
  1683. }
  1684. }
  1685. }
  1686. // assign newly created var func to 'children' container of the parent FUNC "<TYPE> void func(int p) {int x=0;}" (this does not process func params like 'p' or templates like 'TYPE'), this is needed for compilation
  1687. if(var_func && var_func->parent)
  1688. if(Symbol *var_func_parent_func=var_func->parent->func())
  1689. {
  1690. if(space_mode==SPACE_NORMAL )var_func_parent_func->children.add(var_func());else
  1691. if(space_mode==SPACE_FUNC_PARAM)var_func_parent_func->params .add(var_func());
  1692. }
  1693. if(op[0]=='{') // fill all until '}' with parent as newly created symbol
  1694. {
  1695. op.parent=var_func();
  1696. for(Int level=0; i<tokens.elms(); )
  1697. {
  1698. Token &token=*tokens[i++]; token.parent=var_func();
  1699. if(token=='{')level++;else
  1700. if(token=='}')level--;
  1701. if(level<0)break;
  1702. }
  1703. }else
  1704. if(op[0]==',') // reset individual modifiers, and proceed to next var/member def/decl
  1705. {
  1706. if(space_mode==SPACE_NORMAL)
  1707. {
  1708. name.clear();
  1709. const_level=0; const_level_in_bracket=0;
  1710. ptr_level=0; ptr_level_in_bracket=0;
  1711. modifiers=0; modifiers_in_bracket=0;
  1712. var_func_def_start=i;
  1713. goto next_var_func;
  1714. }else
  1715. {
  1716. return;
  1717. }
  1718. }else
  1719. if(op[0]==')')
  1720. {
  1721. i--;
  1722. }
  1723. }return;
  1724. }
  1725. }
  1726. }return;
  1727. default: return;
  1728. }
  1729. next_var_func:;
  1730. }
  1731. }
  1732. /******************************************************************************/
  1733. void DetectVarFuncs(Memc<SymbolDef> &symbols, Memc<Token*> &tokens) // get list of 2nd main symbols (variables, functions)
  1734. {
  1735. Symbol *symbol_parent;
  1736. Str temp;
  1737. Memc<Symbol::Modif> templates;
  1738. Memc<Int > new_templates;
  1739. for(Int i=0; i<tokens.elms(); )
  1740. {
  1741. Int start=i;
  1742. Token &token=*tokens[i];
  1743. if(!token.symbol) // if not yet processed by DataTypes/Typedefs
  1744. if(!token.parent || token.parent->type==Symbol::NAMESPACE || token.parent->type==Symbol::CLASS) // detect only in namespaces and class bodies
  1745. {
  1746. if(Symbol *symbol=GetFullSymbol(tokens, i, temp, token.parent, templates, &symbol_parent))
  1747. {
  1748. if(symbol->modifiers&Symbol::MODIF_DATA_TYPE) // if current element is of data type, then probably it's member/var/method/function definition/declaration
  1749. ReadVarFunc(symbol, symbols, tokens, i, start, SPACE_NORMAL, temp, templates, new_templates, symbol_parent);
  1750. else
  1751. if(symbol->type==Symbol::KEYWORD)
  1752. {
  1753. if(*symbol=="operator") // or auto-cast "operator CChar*()"
  1754. ReadAutoCast(symbol_parent, symbols, tokens, i, start, temp, templates);
  1755. else
  1756. if(token.parent && token.parent->type==Symbol::CLASS) // or access-level specification
  1757. if(InRange(i, tokens) && *tokens[i]==':') // only for "private:" and not "private int"
  1758. {
  1759. if(*symbol=="private" )token.parent->access_level=Symbol::ACCESS_PRIVATE ;else
  1760. if(*symbol=="protected")token.parent->access_level=Symbol::ACCESS_PROTECTED;else
  1761. if(*symbol=="public" )token.parent->access_level=Symbol::ACCESS_PUBLIC ;
  1762. }
  1763. }
  1764. }else
  1765. if(token=='<' || token==TMPL_B) // parse "template<..>"
  1766. {
  1767. for(Int level=0; i<tokens.elms(); ) // skip all templates inside
  1768. {
  1769. Token &token=*tokens[i];
  1770. if(token=='{' || token=='}' || token==';')break;
  1771. i++; token.def_decl=true;
  1772. if(token=='<' || token==TMPL_B) ++level;else
  1773. if(token=='>' || token==TMPL_E)if(--level<=0) // when last '>' encountered
  1774. {
  1775. if(InRange(i, tokens)) // check what follows "template<..>"
  1776. {
  1777. Token &token=*tokens[i];
  1778. if(token!="struct" && token!="class" && token!="union" && token!="namespace" // check if it's not "template<..> struct"
  1779. && token!="friend" // check if it's not "template<..> friend struct"
  1780. && token!="template" && token!="<" && token!=TMPL_B) // check if it's not "template<..> template"
  1781. {
  1782. for(; InRange(i, tokens); ) // skip modifiers
  1783. {
  1784. Token &token=*tokens[i];
  1785. if(token=="inline"
  1786. || token=="const"
  1787. || token=="constexpr"
  1788. || token=="typename"
  1789. || token=="static"
  1790. || token=="mutable")i++;else break;
  1791. }
  1792. if(InRange(i, tokens)) // now we should encounter data type (this can be template typename)
  1793. {
  1794. Int type_start=i;
  1795. Symbol *type =GetFullSymbol(tokens, i, temp, token.parent, templates, &symbol_parent); if(type && type->type==Symbol::TYPENAME){type=null; templates.clear();} // skip typenames, in case they're detected from parent "T1(TYPE) class X {T1(TYPE) void x();}"
  1796. if(!type){i=type_start; SkipUnknownSymbol(tokens, i, token.parent);} // if type was not detected, then skip it fully
  1797. if(type && *type=="operator") // auto-cast "operator TYPE()"
  1798. ReadAutoCast(symbol_parent, symbols, tokens, i, type_start, temp, templates);
  1799. else
  1800. if(InRange(i, tokens))
  1801. {
  1802. Token &token=*tokens[i];
  1803. if(token!='{' && token!='}' && token!=';' && token!=',') // skip "class Ext : Base<TYPE>, Base<TYPE2> {}"
  1804. ReadVarFunc(type, symbols, tokens, i, type_start, SPACE_NORMAL, temp, templates, new_templates, symbol_parent);
  1805. }
  1806. }
  1807. }
  1808. }
  1809. break;
  1810. }
  1811. }
  1812. }else
  1813. if(token.line->source->cpp) // allow variable definition after struct/class/union/enum definition "class X{}x;" (remember it can also be "typedef class X{}x;" in which case 'x' is typedef for 'X' class)
  1814. {
  1815. if(token=='}' && token.parent)if(token.parent->type==Symbol::CLASS || token.parent->type==Symbol::ENUM)
  1816. {
  1817. i=start+1;
  1818. if(InRange(i, tokens))
  1819. {
  1820. if(tokens[i]->parent==token.parent)
  1821. {
  1822. DEBUG_ASSERT(false, S+"Trying to read Var/Func after class/enum definition while still in class.\nLine ("+token.lineIndex()+"): \""+*token.line+"\"\nSource: \""+token.line->source->loc.asText()+"\"");
  1823. }else
  1824. if(!tokens[i]->symbol) // if not yet processed by DataTypes/Typedefs
  1825. {
  1826. if(*tokens[i]!=';')FlagDisable(token.parent->modifiers, Symbol::MODIF_TRANSPARENT); // if the class has a variable defined, then it can be accessed through it, and will not be a transparent class
  1827. ReadVarFunc(token.parent, symbols, tokens, i, token.parent->token_index, SPACE_NORMAL, temp, templates, new_templates);
  1828. }
  1829. }
  1830. }
  1831. }
  1832. }
  1833. MAX(i, start+1);
  1834. }
  1835. }
  1836. /******************************************************************************/
  1837. Int GetSymbolStart(Memc<Token*> &tokens, Int i)
  1838. {
  1839. if(!InRange(i, tokens))return -1;
  1840. for(Int level=0; i>=0; i--)
  1841. {
  1842. Token &c=*tokens[i];
  1843. if(level)
  1844. {
  1845. if(c=='}')level++;else
  1846. if(c=='{')level--;
  1847. }else
  1848. {
  1849. if(c=='{')break;
  1850. if(c=='}')if(InRange(i+1, tokens) && *tokens[i+1]==',')level++;else break; // allow going through "{}" if followed by ',', like this: "int a, b[]={1,2}, c;" when starting from the end
  1851. }
  1852. if(c==';')break;
  1853. if(c==':') // this can be: label "found:", "case 5:", "public/private/protected:", "x ? y : z"
  1854. { // we need to stop on all except "?:"
  1855. // watch out for mixed "case (1 ? 2 : 3): (4 ? 5: 6);"
  1856. for(Int level=0, j=i; --j>=0; )
  1857. {
  1858. Token &c=*tokens[j];
  1859. if(c.symbol)
  1860. if(c.symbol->type==Symbol::LABEL
  1861. || c.symbol->type==Symbol::KEYWORD && (c=="public" || c=="private" || c=="protected" || c=="case" || c=="default"))goto end;
  1862. if(c==':')level++;else
  1863. if(c=='?')if(!level--){i=j; break;}
  1864. }
  1865. }
  1866. }
  1867. end:
  1868. return i+1;
  1869. }
  1870. /******************************************************************************/
  1871. }}
  1872. /******************************************************************************/