diff options
Diffstat (limited to 'src/util.cpp')
-rw-r--r-- | src/util.cpp | 101 |
1 files changed, 68 insertions, 33 deletions
diff --git a/src/util.cpp b/src/util.cpp index 1cef237..dac8532 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * - * + * $Id$ * * Copyright (C) 1997-2006 by Dimitri van Heesch. * @@ -626,13 +626,16 @@ ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, bool isCached = md->isTypedefValCached(); // value already cached if (isCached) { - //printf("Already cached %s->%s\n", + //printf("Already cached %s->%s [%s]\n", // md->name().data(), - // md->getCachedTypedefVal()?md->getCachedTypedefVal()->name().data():"<none>"); + // md->getCachedTypedefVal()?md->getCachedTypedefVal()->name().data():"<none>", + // md->getCachedResolvedTypedef()?md->getCachedResolvedTypedef().data():"<none>"); + if (pTemplSpec) *pTemplSpec = md->getCachedTypedefTemplSpec(); if (pResolvedType) *pResolvedType = md->getCachedResolvedTypedef(); return md->getCachedTypedefVal(); } + //printf("new typedef\n"); QCString qname = md->qualifiedName(); if (g_resolvedTypedefs.find(qname)) return 0; // typedef already done @@ -648,9 +651,9 @@ ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, } type=type.left(ip+1); int sp=0; - if (type.stripPrefix("const ")) sp+=6; // strip leading "const" + if (type.stripPrefix("const ")) sp+=6; // strip leading "const" if (type.stripPrefix("struct ")) sp+=7; // strip leading "struct" - if (type.stripPrefix("union ")) sp+=6; // strip leading "union" + if (type.stripPrefix("union ")) sp+=6; // strip leading "union" while (sp<tl && type.at(sp)==' ') sp++; MemberDef *memTypeDef = 0; ClassDef *result = getResolvedClassRec(md->getOuterScope(), @@ -677,6 +680,8 @@ ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, if (pTemplSpec) *pTemplSpec = type.mid(i); result = getResolvedClassRec(md->getOuterScope(),fileScope, type.left(i),0,0,pResolvedType); + //printf("result=%p pRresolvedType=%s sp=%d ip=%d tl=%d\n", + // result,pResolvedType?pResolvedType->data():"<none>",sp,ip,tl); } else if (si!=-1) // A::B { @@ -694,7 +699,7 @@ ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, pResolvedType); } - if (result) ip=si+sp+1; + //if (result) ip=si+sp+1; } done: @@ -703,6 +708,7 @@ done: if (result) { *pResolvedType=result->qualifiedName(); + //printf("*pResolvedType=%s\n",pResolvedType->data()); if (sp>0) pResolvedType->prepend(typedefValue.left(sp)); if (ip<tl-1) pResolvedType->append(typedefValue.right(tl-ip-1)); } @@ -719,6 +725,7 @@ done: { //printf("setting cached typedef %p in result %p\n",md,result); //printf("==> %s (%s,%d)\n",result->name().data(),result->getDefFileName().data(),result->getDefLine()); + //printf("*pResolvedType=%s\n",pResolvedType?pResolvedType->data():"<none>"); md->cacheTypedefVal(result, pTemplSpec ? *pTemplSpec : QCString(), pResolvedType ? *pResolvedType : QCString() @@ -840,6 +847,7 @@ static Definition *followPath(Definition *start,FileDef *fileScope,const QCStrin } } Definition *next = current->findInnerCompound(qualScopePart); + //printf("++ Looking for %s inside %s result %p\n",qualScopePart.data(),current->name().data(),next?next->name().data():"<null>"); if (next==0) // failed to follow the path { if (current->definitionType()==Definition::TypeNamespace) @@ -1015,7 +1023,18 @@ done: /* Returns the "distance" (=number of levels up) from item to scope, or -1 * if item in not in this scope. The explicitScopePart limits the search - * to scopes that match \a scope plus the explicit part. + * to scopes that match \a scope (or its parent scope(s)) plus the explicit part. + * Example: + * + * class A { public: class I {}; }; + * class B { public: class J {}; }; + * + * - Looking for item=='J' inside scope=='B' will return 0. + * - Looking for item=='I' inside scope=='B' will return -1 + * (as it is not found in B nor in the global scope). + * - Looking for item=='A::I' inside scope=='B', first the match B::A::I is tried but + * not found and then A::I is searched in the global scope, which matches and + * thus the result is 1. */ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope, Definition *item,const QCString &explicitScopePart) @@ -1039,11 +1058,30 @@ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope, Definition *newScope = followPath(scope,fileScope,explicitScopePart); if (newScope) // explicitScope is inside scope => newScope is the result { + Definition *itemScope = item->getOuterScope(); //printf("scope traversal successful %s<->%s!\n",item->getOuterScope()->name().data(),newScope->name().data()); - if (item->getOuterScope()==newScope) + if (newScope && newScope->definitionType()==Definition::TypeClass) + { + //ClassDef *cd = (ClassDef *)newScope; + //printf("---> Class %s: bases=%p\n",cd->name().data(),cd->baseClasses()); + } + if (itemScope==newScope) // exact match of scopes => distance==0 { //printf("> found it\n"); } + else if (itemScope && newScope && + itemScope->definitionType()==Definition::TypeClass && + newScope->definitionType()==Definition::TypeClass && + ((ClassDef*)newScope)->isBaseClass((ClassDef*)itemScope,TRUE,0) + ) + { + // inheritance is also ok. Example: looking for B::I, where + // class A { public: class I {} }; + // class B : public A {} + + //printf("outerScope(%s) is base class of newScope(%s)\n", + // outerScope->name().data(),newScope->name().data()); + } else { int i=-1; @@ -1134,19 +1172,6 @@ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope, //printf("> result=%d\n",i); result= (i==-1) ? -1 : i+1; } -#if 0 - if (scope!=Doxygen::globalScope) - { - int i=isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope, - item,explicitScopePart); - //printf("> result=%d\n",i); - result= (i==-1) ? -1 : i+1; - } - else - { - result = -1; - } -#endif } done: //printf("> result=%d\n",result); @@ -1175,7 +1200,7 @@ static void getResolvedSymbol(Definition *scope, //printf(" found type %x name=%s d=%p\n", // d->definitionType(),d->name().data(),d); - // only look at classes and members + // only look at classes and members that are enums or typedefs if (d->definitionType()==Definition::TypeClass || (d->definitionType()==Definition::TypeMember && (((MemberDef*)d)->isTypedef() || ((MemberDef*)d)->isEnumerate()) @@ -1418,7 +1443,7 @@ ClassDef *getResolvedClassRec(Definition *scope, QCString bestResolvedType; int minDistance=10000; // init at "infinite" - if (di->definitionType()==DefinitionIntf::TypeSymbolList) + if (di->definitionType()==DefinitionIntf::TypeSymbolList) // not a unique name { DefinitionListIterator dli(*(DefinitionList*)di); Definition *d; @@ -1430,7 +1455,7 @@ ClassDef *getResolvedClassRec(Definition *scope, bestResolvedType); } } - else + else // unique name { Definition *d = (Definition *)di; getResolvedSymbol(scope,fileScope,d,explicitScopePart, @@ -1540,6 +1565,7 @@ static const char virtualScope[] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' }; QCString removeRedundantWhiteSpace(const QCString &s) { + static bool cliSupport = Config_getBool("CPP_CLI_SUPPORT"); if (s.isEmpty()) return s; QCString result; uint i; @@ -1644,6 +1670,7 @@ nextChar: if (rl>0 && (isId(result.at(rl-1)) || result.at(rl-1)=='>')) result+=' '; } result+=c; + if (cliSupport && (c=='^' || c=='%') && i>1 && isId(s.at(i-1))) result+=' '; // C++/CLI: Type^ name and Type% name } } //printf("removeRedundantWhiteSpace(`%s')=`%s'\n",s.data(),result.data()); @@ -2183,7 +2210,7 @@ int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level) if (level==256) { err("Error: Internal inconsistency: found class %s seem to have a recursive " - "inheritance relation! Please send a bug report to dimitri@stack.nl",cd->name().data()); + "inheritance relation! Please send a bug report to dimitri@stack.nl\n",cd->name().data()); return -1; } int m=maxInheritanceDepth; @@ -2948,12 +2975,20 @@ static QCString stripDeclKeywords(const QCString &s) // forward decl for circular dependencies static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type); -QCString getCanonicalTemplateSpec(Definition *d,FileDef *fs,const QCString& spec) +QCString getCanonicalTemplateSpec(Definition *d,FileDef *,const QCString& spec) { - //printf("getCanonicalTemplateSpec(%s)\n",spec.data()); QCString templSpec = spec.stripWhiteSpace(); - if (templSpec.isEmpty() || templSpec.at(0) != '<') return templSpec; - return "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace()); + //if (!templSpec.isEmpty() && templSpec.at(0) == '<') + //{ + // templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace()); + //} + QCString resolvedType = resolveTypeDef(d,spec); + if (!resolvedType.isEmpty()) // not known as a typedef either + { + templSpec = resolvedType; + } + //printf("getCanonicalTemplateSpec(%s)=%s\n",spec.data(),templSpec.data()); + return templSpec; } @@ -3096,14 +3131,14 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type) // foreach identifier in the type { //printf(" i=%d p=%d\n",i,p); - canType += type.mid(pp,i-pp); + if (i>pp) canType += type.mid(pp,i-pp); - //printf(" word=%s templSpec=%s\n",word.data(),templSpec.data()); canType += getCanonicalTypeForIdentifier(d,fs,word,&templSpec); + //printf(" word=%s templSpec=%s canType=%s\n",word.data(),templSpec.data(),canType.data()); if (!templSpec.isEmpty()) // if we didn't use up the templSpec already - // (i.e. type is not a template specialization) - // then resolve any identifiers inside. + // (i.e. type is not a template specialization) + // then resolve any identifiers inside. { static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); int tp=0,tl,ti; |