mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
cpp: auto/for handling improved for standard containers
git-svn-id: svn://ultimatepp.org/upp/trunk@8710 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
0b8e4336a2
commit
8d08a282bf
4 changed files with 113 additions and 26 deletions
|
|
@ -1,7 +1,22 @@
|
|||
#include "CppBase.h"
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Parser::Locals(const String& type)
|
||||
{
|
||||
Line();
|
||||
Array<Parser::Decl> d = Declaration(true, true, Null, Null);
|
||||
for(int i = 0; i < d.GetCount(); i++) {
|
||||
Local& l = local.Add(d[i].name);
|
||||
l.type = *type == '*' ? d[i].type : type;
|
||||
l.isptr = d[i].isptr;
|
||||
l.line = line + 1;
|
||||
LLOG("== Local variable " << d[i].name << ": " << l.type);
|
||||
}
|
||||
}
|
||||
|
||||
bool Parser::TryDecl()
|
||||
{ // attempt to interpret code as local variable declaration
|
||||
for(;;) {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ String ResolveTParam(const CppBase& codebase, const String& type, const Vector<S
|
|||
LLOG("Resolved " << type << " -> " << r);
|
||||
const Array<CppItem>& x = GetTypeItems(codebase, r);
|
||||
if(x.GetCount() && x[0].kind == TYPEDEF) {
|
||||
LLOG("Is typedef " << x[0].qtype << ';' << x[0].type << ';' << x[0].natural);
|
||||
LLOG("Is typedef " << x[0].qtype << ", unqualified " << x[0].type << ", natural " << x[0].natural);
|
||||
String h = x[0].qtype;
|
||||
if(h != type && h != r)
|
||||
return ResolveTParam(codebase, h, tparam);
|
||||
|
|
@ -113,6 +113,8 @@ struct ExpressionTyper {
|
|||
void ExpressionType(const String& ttype, int ii, bool variable, int lvl);
|
||||
|
||||
Index<String> ExpressionType();
|
||||
|
||||
enum { MAX_COUNT = 1000 };
|
||||
|
||||
ExpressionTyper(const CppBase& codebase, const Parser& parser, const Vector<String>& xp);
|
||||
};
|
||||
|
|
@ -219,16 +221,10 @@ void ExpressionTyper::ExpressionType(const String& ttype, int ii,
|
|||
bool variable, bool can_shortcut_operator,
|
||||
Index<String>& visited_bases, int lvl)
|
||||
{
|
||||
LLOG("--- ExpressionType " << scan_counter << ", lvl " << lvl << ", ttype " << ttype);
|
||||
if(++scan_counter > 1000 || lvl > 100) // sort of ugly limitation of parsing permutations
|
||||
LLOG("--- ExpressionType " << scan_counter << ", lvl " << lvl << ", ttype " << ttype
|
||||
<< ", ii " << ii << ": " << ii << (ii < xp.GetCount() ? xp[ii] : "<end>"));
|
||||
if(++scan_counter >= MAX_COUNT || lvl > 100) // sort of ugly limitation of parsing permutations
|
||||
return;
|
||||
if(ii >= xp.GetCount()) {
|
||||
LLOG("--- Final type: " << ttype);
|
||||
typeset.FindAdd(ttype);
|
||||
return;
|
||||
}
|
||||
LDUMP(ii);
|
||||
LDUMP(xp[ii]);
|
||||
LDUMP(can_shortcut_operator);
|
||||
Vector<String> tparam;
|
||||
String type = ParseTemplatedType(ttype, tparam);
|
||||
|
|
@ -236,6 +232,65 @@ void ExpressionTyper::ExpressionType(const String& ttype, int ii,
|
|||
const Array<CppItem>& n = GetTypeItems(codebase, type);
|
||||
LDUMP(type);
|
||||
LDUMP(tparam);
|
||||
|
||||
// STL/NTL is too much to parse for now, so until we have better expression resolver, let us play dirty
|
||||
static Index<String> std_container;
|
||||
static Index<String> std_pair_container;
|
||||
static Index<String> std_container_iterator;
|
||||
static Index<String> std_pair_container_iterator;
|
||||
static Index<String> upp_map_container;
|
||||
static Index<String> upp_map_container_iterator;
|
||||
static Index<String> upp_map_container_key_iterator;
|
||||
ONCELOCK {
|
||||
Vector<String> a = Split("array;vector;deque;forward_list;list;stack;queue;priority_queue;"
|
||||
"set;multiset;unordered_set;unordered_multiset", ';');
|
||||
for(int i = 0; i < a.GetCount(); i++) {
|
||||
std_container.Add("std::" + a[i]);
|
||||
std_container_iterator.Add("std::" + a[i] + "::iterator");
|
||||
}
|
||||
a = Split("map;multimap;unordered_map;unordered_multimap", ';');
|
||||
for(int i = 0; i < a.GetCount(); i++) {
|
||||
std_container.Add("std::" + a[i]);
|
||||
std_pair_container_iterator.Add("std::" + a[i] + "::iterator");
|
||||
}
|
||||
a = Split("VectorMap;ArrayMap", ';');
|
||||
for(int i = 0; i < a.GetCount(); i++) {
|
||||
upp_map_container.Add("Upp::" + a[i]);
|
||||
upp_map_container_iterator.Add("Upp::" + a[i] + "::iterator");
|
||||
upp_map_container_iterator.Add("Upp::" + a[i] + "::Iterator");
|
||||
upp_map_container_key_iterator.Add("Upp::" + a[i] + "::KeyIterator");
|
||||
}
|
||||
}
|
||||
if(tparam.GetCount() > 0 && std_container_iterator.Find(type) >= 0) {
|
||||
LLOG("# nasty iterator");
|
||||
typeset.Clear();
|
||||
ExpressionType(tparam[0], ii, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
scan_counter = MAX_COUNT;
|
||||
return;
|
||||
}
|
||||
if(tparam.GetCount() > 1 && std_pair_container_iterator.Find(type) >= 0) {
|
||||
LLOG("# nasty pair iterator");
|
||||
typeset.Clear();
|
||||
ExpressionType("std::pair<" + tparam[0] + "," + tparam[1] + ">",
|
||||
ii, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
scan_counter = MAX_COUNT;
|
||||
return;
|
||||
}
|
||||
if(tparam.GetCount() > 1 && upp_map_container_iterator.Find(type) >= 0) {
|
||||
LLOG("# Upp map nasty iterator");
|
||||
typeset.Clear();
|
||||
ExpressionType(tparam[1], ii, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
scan_counter = MAX_COUNT;
|
||||
return;
|
||||
}
|
||||
if(tparam.GetCount() > 1 && upp_map_container_key_iterator.Find(type) >= 0) {
|
||||
LLOG("# Upp map nasty key iterator");
|
||||
typeset.Clear();
|
||||
ExpressionType(tparam[0], ii, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
scan_counter = MAX_COUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
if(codebase.namespaces.Find(ttype) < 0 && ttype.GetCount()) // do not search for namespace typedefs
|
||||
for(int i = 0; i < n.GetCount(); i++)
|
||||
if(n[i].kind == TYPEDEF) {
|
||||
|
|
@ -243,7 +298,36 @@ void ExpressionTyper::ExpressionType(const String& ttype, int ii,
|
|||
ExpressionType(AddTParams(ResolveTParam(codebase, n[i].qtype, tparam), ttype), ii, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
return;
|
||||
}
|
||||
if(ii >= xp.GetCount()) {
|
||||
LLOG("==== Final type: " << ttype);
|
||||
typeset.FindAdd(ttype);
|
||||
return;
|
||||
}
|
||||
String id = xp[ii];
|
||||
|
||||
// More nasty tricks to make things work with containers (hopefully temporary)
|
||||
if((id == "begin" || id == "end") && std_container.Find(type) >= 0) {
|
||||
LLOG("# nasty begin/end");
|
||||
typeset.Clear();
|
||||
ExpressionType(ttype + "::iterator", ii + 1, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
scan_counter = MAX_COUNT;
|
||||
return;
|
||||
}
|
||||
if(findarg(id, "begin", "end", "Begin", "End") >= 0 && upp_map_container.Find(type) >= 0) {
|
||||
LLOG("# nasty Upp begin/end");
|
||||
typeset.Clear();
|
||||
ExpressionType(ttype + "::Iterator", ii + 1, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
scan_counter = MAX_COUNT;
|
||||
return;
|
||||
}
|
||||
if(findarg(id, "begin", "end", "KeyBegin", "KeyEnd") >= 0 && upp_map_container.Find(type) >= 0) {
|
||||
LLOG("# nasty Upp begin/end");
|
||||
typeset.Clear();
|
||||
ExpressionType(ttype + "::KeyIterator", ii + 1, variable, can_shortcut_operator, visited_bases, lvl + 1);
|
||||
scan_counter = MAX_COUNT;
|
||||
return;
|
||||
}
|
||||
|
||||
int q = id.ReverseFind(':');
|
||||
if(q > 0 && id[q - 1] == ':') {
|
||||
type = ResolveTParam(codebase, Qualify(codebase, ttype, id.Mid(0, q - 1), usings), tparam);
|
||||
|
|
@ -271,7 +355,6 @@ void ExpressionTyper::ExpressionType(const String& ttype, int ii,
|
|||
for(int i = 0; i < n.GetCount(); i++) {
|
||||
const CppItem& m = n[i];
|
||||
if(m.name == id) {
|
||||
LLOG("Member " << m.qtype << " " << m.name);
|
||||
String t = AddTParams(ResolveReturnType(m, tparam), ttype);
|
||||
bool skipfnpars = m.IsCode() && ii + 1 < xp.GetCount() && xp[ii + 1] == "()";
|
||||
ExpressionType(ResolveTParam(codebase, t, tparam), ii + skipfnpars + 1,
|
||||
|
|
@ -307,6 +390,7 @@ void ExpressionTyper::ExpressionType(const String& ttype, int ii, bool variable,
|
|||
|
||||
Index<String> ExpressionTyper::ExpressionType()
|
||||
{
|
||||
LLOG("------------------------------------------------------");
|
||||
LLOG("**** ExpressionType " << xp);
|
||||
String type;
|
||||
if(xp.GetCount() == 0)
|
||||
|
|
|
|||
|
|
@ -1043,18 +1043,6 @@ Array<Parser::Decl> Parser::Declaration(bool l0, bool more, const String& tname,
|
|||
return Declaration0(l0, more, tname, tparam);
|
||||
}
|
||||
|
||||
void Parser::Locals(const String& type)
|
||||
{
|
||||
Line();
|
||||
Array<Parser::Decl> d = Declaration(true, true, Null, Null);
|
||||
for(int i = 0; i < d.GetCount(); i++) {
|
||||
Local& l = local.Add(d[i].name);
|
||||
l.type = *type == '*' ? d[i].type : type;
|
||||
l.isptr = d[i].isptr;
|
||||
l.line = line + 1;
|
||||
}
|
||||
}
|
||||
|
||||
String Parser::Tparam(int& q)
|
||||
{
|
||||
if(lex[q] != '<')
|
||||
|
|
|
|||
|
|
@ -135,13 +135,13 @@ String QualifyIds(ScopeInfo& nf, const String& k, const String& usings, bool all
|
|||
if(c == ':') {
|
||||
const char *b = s++;
|
||||
while(*s == ':' || iscid(*s)) s++;
|
||||
if(all) {
|
||||
/* if(all) {
|
||||
if(iscid(*r.Last()))
|
||||
r << ' ';
|
||||
ScopeInfo nnf(nf.GetScope(), nf.base);
|
||||
Qualify(r, nnf, b, s, usings);
|
||||
}
|
||||
else
|
||||
else*/
|
||||
r.Cat(b, s);
|
||||
}
|
||||
else
|
||||
|
|
@ -242,7 +242,7 @@ void QualifyPass2(CppBase& base)
|
|||
}
|
||||
}
|
||||
|
||||
void Qualify(CppBase& base)
|
||||
void Qualify(CppBase& base)
|
||||
{
|
||||
Md5Stream md5;
|
||||
Vector<int> no = GetSortOrder(base.GetKeys());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue