Skip to content

Commit 0a7e798

Browse files
committed
issue #10797 Spurious links generated for C++ keywords and template parameters
1 parent 588fa6b commit 0a7e798

File tree

7 files changed

+73
-84
lines changed

7 files changed

+73
-84
lines changed

src/pycode.l

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,8 +1545,8 @@ static void findMemberLink(yyscan_t yyscanner,
15451545
bool found = false;
15461546
if (yyextra->currentDefinition)
15471547
{
1548-
auto v = Doxygen::symbolMap->find(symName);
1549-
for (auto p : v)
1548+
const auto &v = Doxygen::symbolMap->find(symName);
1549+
for (const auto &p : v)
15501550
{
15511551
if (findMemberLink(yyscanner,ol,p,symName)) found = true;
15521552
}

src/sqlite3gen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -834,15 +834,15 @@ class TextGeneratorSqlite3Impl : public TextGeneratorIntf
834834
{
835835
public:
836836
TextGeneratorSqlite3Impl(StringVector &l) : m_list(l) { }
837-
void writeString(const QCString & /*s*/,bool /*keepSpaces*/) const override
837+
void writeString(std::string_view /*s*/,bool /*keepSpaces*/) const override
838838
{
839839
}
840840
void writeBreak(int) const override
841841
{
842842
DBG_CTX(("writeBreak\n"));
843843
}
844844
void writeLink(const QCString & /*extRef*/,const QCString &file,
845-
const QCString &anchor,const QCString & /*text*/
845+
const QCString &anchor,std::string_view /*text*/
846846
) const override
847847
{
848848
std::string rs = file.str();

src/symbolmap.h

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <vector>
2222
#include <string>
2323
#include <utility>
24+
#include <cassert>
2425

2526
//! Class implementing a symbol map that maps symbol names to objects.
2627
//! Symbol names do not have to be unique.
@@ -46,37 +47,34 @@ class SymbolMap
4647
}
4748
else
4849
{
49-
m_map.emplace(std::make_pair(name.str(),VectorPtr({def})));
50+
m_map.emplace(name.str(),VectorPtr({def}));
5051
}
5152
}
5253

5354
//! Remove a symbol \a def from the map that was stored under key \a name
5455
void remove(const QCString &name,Ptr def)
5556
{
56-
VectorPtr &v = find(name);
57-
auto it = std::find(v.begin(),v.end(),def);
58-
if (it!=v.end())
57+
auto it1 = m_map.find(name.str());
58+
if (it1!=m_map.end())
5959
{
60-
v.erase(it);
61-
if (v.empty())
60+
VectorPtr &v = it1->second;
61+
auto it2 = std::find(v.begin(),v.end(),def);
62+
if (it2!=v.end())
6263
{
63-
m_map.erase(name.str());
64+
v.erase(it2);
65+
if (v.empty())
66+
{
67+
m_map.erase(it1);
68+
}
6469
}
6570
}
6671
}
6772

6873
//! Find the list of symbols stored under key \a name
6974
//! Returns a pair of iterators pointing to the start and end of the range of matching symbols
70-
const VectorPtr &find(const QCString &name) const
71-
{
72-
auto it = m_map.find(name.str());
73-
return it==m_map.end() ? m_noMatch : it->second;
74-
}
75-
76-
//! Find the list of symbols stored under key \a name
77-
//! Returns a pair of iterators pointing to the start and end of the range of matching symbols
78-
VectorPtr &find(const QCString &name)
75+
const VectorPtr &find(const QCString &name)
7976
{
77+
assert(m_noMatch.empty());
8078
auto it = m_map.find(name.str());
8179
return it==m_map.end() ? m_noMatch : it->second;
8280
}

src/symbolresolver.cpp

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -411,29 +411,15 @@ const Definition *SymbolResolver::Private::getResolvedSymbolRec(
411411
return nullptr; // empty name
412412
}
413413

414-
auto &range = Doxygen::symbolMap->find(name);
414+
int i;
415+
const auto &range1 = Doxygen::symbolMap->find(name);
416+
const auto &range = range1.empty() && (i=name.find('<')!=-1) ? Doxygen::symbolMap->find(name.left(i)) : range1;
415417
if (range.empty())
416418
{
417-
int i;
418-
if (insideCode && (i=name.find('<'))!=-1)
419-
{
420-
range = Doxygen::symbolMap->find(name.left(i));
421-
if (range.empty())
422-
{
423-
AUTO_TRACE_ADD("no symbols (including unspecialized)");
424-
return nullptr;
425-
}
426-
}
427-
else
428-
{
429-
AUTO_TRACE_ADD("no symbols");
430-
return nullptr;
431-
}
432-
}
433-
else
434-
{
435-
AUTO_TRACE_ADD("{} candidates",range.size());
419+
AUTO_TRACE_ADD("no symbols (including unspecialized)");
420+
return nullptr;
436421
}
422+
AUTO_TRACE_ADD("{} -> {} candidates",name,range.size());
437423

438424
bool hasUsingStatements =
439425
(m_fileScope && (!m_fileScope->getUsedNamespaces().empty() ||

src/util.cpp

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -104,28 +104,32 @@ TextGeneratorOLImpl::TextGeneratorOLImpl(OutputList &ol) : m_ol(ol)
104104
{
105105
}
106106

107-
void TextGeneratorOLImpl::writeString(const QCString &s,bool keepSpaces) const
107+
void TextGeneratorOLImpl::writeString(std::string_view s,bool keepSpaces) const
108108
{
109-
if (s.isEmpty()) return;
109+
if (s.empty()) return;
110110
//printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces);
111111
if (keepSpaces)
112112
{
113-
const char *p=s.data();
114-
if (p)
113+
char cs[2];
114+
char c;
115+
cs[1]='\0';
116+
for (size_t i=0;i<s.length();i++)
115117
{
116-
char cs[2];
117-
char c;
118-
cs[1]='\0';
119-
while ((c=*p++))
118+
c = s[i];
119+
if (c==' ')
120+
{
121+
m_ol.writeNonBreakableSpace(1);
122+
}
123+
else
120124
{
121-
if (c==' ') m_ol.writeNonBreakableSpace(1);
122-
else cs[0]=c,m_ol.docify(cs);
125+
cs[0]=c;
126+
m_ol.docify(cs);
123127
}
124128
}
125129
}
126130
else
127131
{
128-
m_ol.docify(s);
132+
m_ol.docify(QCString(s));
129133
}
130134
}
131135

@@ -140,11 +144,11 @@ void TextGeneratorOLImpl::writeBreak(int indent) const
140144
}
141145

142146
void TextGeneratorOLImpl::writeLink(const QCString &extRef,const QCString &file,
143-
const QCString &anchor,const QCString &text
147+
const QCString &anchor,std::string_view text
144148
) const
145149
{
146150
//printf("TextGeneratorOlImpl::writeLink('%s')\n",text);
147-
m_ol.writeObjectLink(extRef,file,anchor,text);
151+
m_ol.writeObjectLink(extRef,file,anchor,QCString(text));
148152
}
149153

150154
//------------------------------------------------------------------------
@@ -892,15 +896,15 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
892896
{
893897
if (text.isEmpty()) return;
894898
//printf("linkify='%s'\n",qPrint(text));
895-
std::string txtStr=text.str();
899+
std::string_view txtStr=text.view();
896900
size_t strLen = txtStr.length();
897901
if (strLen==0) return;
898902

899903
static const reg::Ex regExp(R"((::)?\a[\w~!\\.:$"]*)");
900904
reg::Iterator it(txtStr,regExp);
901905
reg::Iterator end;
902906

903-
//printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%d external=%d\n",
907+
//printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%zu external=%d\n",
904908
// scope ? qPrint(scope->name()):"<none>",
905909
// fileScope ? qPrint(fileScope->name()) : "<none>",
906910
// qPrint(txtStr),strLen,external);
@@ -915,8 +919,8 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
915919
floatingIndex+=newIndex-skipIndex+matchLen;
916920
if (newIndex>0 && txtStr.at(newIndex-1)=='0') // ignore hex numbers (match x00 in 0x00)
917921
{
918-
std::string part = txtStr.substr(skipIndex,newIndex+matchLen-skipIndex);
919-
out.writeString(part.c_str(),keepSpaces);
922+
std::string_view part = txtStr.substr(skipIndex,newIndex+matchLen-skipIndex);
923+
out.writeString(part,keepSpaces);
920924
skipIndex=index=newIndex+matchLen;
921925
continue;
922926
}
@@ -932,7 +936,7 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
932936
//printf("floatingIndex=%d strlen=%d autoBreak=%d\n",floatingIndex,strLen,autoBreak);
933937
if (strLen>35 && floatingIndex>30 && autoBreak) // try to insert a split point
934938
{
935-
std::string splitText = txtStr.substr(skipIndex,newIndex-skipIndex);
939+
std::string_view splitText = txtStr.substr(skipIndex,newIndex-skipIndex);
936940
size_t splitLength = splitText.length();
937941
size_t offset=1;
938942
size_t i = splitText.find(',');
@@ -942,26 +946,26 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
942946
//printf("splitText=[%s] len=%d i=%d offset=%d\n",qPrint(splitText),splitLength,i,offset);
943947
if (i!=std::string::npos) // add a link-break at i in case of Html output
944948
{
945-
std::string part1 = splitText.substr(0,i+offset);
946-
out.writeString(part1.c_str(),keepSpaces);
949+
std::string_view part1 = splitText.substr(0,i+offset);
950+
out.writeString(part1,keepSpaces);
947951
out.writeBreak(indentLevel==0 ? 0 : indentLevel+1);
948-
std::string part2 = splitText.substr(i+offset);
949-
out.writeString(part2.c_str(),keepSpaces);
952+
std::string_view part2 = splitText.substr(i+offset);
953+
out.writeString(part2,keepSpaces);
950954
floatingIndex=splitLength-i-offset+matchLen;
951955
}
952956
else
953957
{
954-
out.writeString(splitText.c_str(),keepSpaces);
958+
out.writeString(splitText,keepSpaces);
955959
}
956960
}
957961
else
958962
{
959963
//ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex));
960-
std::string part = txtStr.substr(skipIndex,newIndex-skipIndex);
961-
out.writeString(part.c_str(),keepSpaces);
964+
std::string_view part = txtStr.substr(skipIndex,newIndex-skipIndex);
965+
out.writeString(part,keepSpaces);
962966
}
963967
// get word from string
964-
std::string word=txtStr.substr(newIndex,matchLen);
968+
std::string_view word=txtStr.substr(newIndex,matchLen);
965969
QCString matchWord = substitute(substitute(QCString(word),"\\","::"),".","::");
966970
//printf("linkifyText word=%s matchWord=%s scope=%s\n",
967971
// qPrint(word),qPrint(matchWord),scope ? qPrint(scope->name()) : "<none>");
@@ -977,15 +981,15 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
977981
const MemberDef *typeDef = resolver.getTypedef();
978982
if (typeDef) // First look at typedef then class, see bug 584184.
979983
{
980-
//printf("Found typedef %s\n",qPrint(typeDef->name()));
981984
if (external ? typeDef->isLinkable() : typeDef->isLinkableInProject())
982985
{
983986
if (typeDef->getOuterScope()!=self)
984987
{
988+
//printf("Found typedef %s word='%s'\n",qPrint(typeDef->name()),qPrint(word));
985989
out.writeLink(typeDef->getReference(),
986990
typeDef->getOutputFileBase(),
987991
typeDef->anchor(),
988-
word.c_str());
992+
word);
989993
found=TRUE;
990994
}
991995
}
@@ -995,14 +999,14 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
995999
{
9961000
if (self==nullptr || cd_->qualifiedName()!=self->qualifiedName())
9971001
{
998-
out.writeLink(cd_->getReference(),cd_->getOutputFileBase(),cd_->anchor(),word.c_str());
1002+
//printf("Found compound %s word='%s'\n",qPrint(cd->name()),qPrint(word));
1003+
out.writeLink(cd_->getReference(),cd_->getOutputFileBase(),cd_->anchor(),word);
9991004
found=TRUE;
10001005
}
10011006
}
10021007
};
10031008
if (!found && (cd || (cd=getClass(matchWord))))
10041009
{
1005-
//printf("Found class %s\n",qPrint(cd->name()));
10061010
writeCompoundName(cd);
10071011
}
10081012
else if ((cd=getClass(matchWord+"-p"))) // search for Obj-C protocols as well
@@ -1035,7 +1039,7 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
10351039
}
10361040

10371041
//printf("ScopeName=%s\n",qPrint(scopeName));
1038-
//if (!found) printf("Trying to link %s in %s\n",qPrint(word),qPrint(scopeName));
1042+
//if (!found) printf("Trying to link '%s' in '%s'\n",qPrint(word),qPrint(scopeName));
10391043
if (!found)
10401044
{
10411045
GetDefInput input(scopeName,matchWord,QCString());
@@ -1060,9 +1064,9 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
10601064
)
10611065
)
10621066
{
1067+
//printf("found symbol %s word='%s'\n",qPrint(result.md->name()),qPrint(word));
10631068
out.writeLink(result.md->getReference(),result.md->getOutputFileBase(),
1064-
result.md->anchor(),word.c_str());
1065-
//printf("found symbol %s\n",qPrint(matchWord));
1069+
result.md->anchor(),word);
10661070
found=TRUE;
10671071
}
10681072
}
@@ -1072,16 +1076,16 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
10721076

10731077
if (!found) // add word to the result
10741078
{
1075-
out.writeString(word.c_str(),keepSpaces);
1079+
out.writeString(word,keepSpaces);
10761080
}
10771081
// set next start point in the string
10781082
//printf("index=%d/%d\n",index,txtStr.length());
10791083
skipIndex=index=newIndex+matchLen;
10801084
}
10811085
// add last part of the string to the result.
10821086
//ol.docify(txtStr.right(txtStr.length()-skipIndex));
1083-
std::string lastPart = txtStr.substr(skipIndex);
1084-
out.writeString(lastPart.c_str(),keepSpaces);
1087+
std::string_view lastPart = txtStr.substr(skipIndex);
1088+
out.writeString(lastPart,keepSpaces);
10851089
}
10861090

10871091
void writeMarkerList(OutputList &ol,const std::string &markerText,size_t numMarkers,

src/util.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <functional>
2727
#include <fstream>
2828
#include <variant>
29+
#include <string_view>
2930

3031
#include <ctype.h>
3132
#include "types.h"
@@ -64,10 +65,10 @@ class TextGeneratorIntf
6465
public:
6566
ABSTRACT_BASE_CLASS(TextGeneratorIntf)
6667

67-
virtual void writeString(const QCString &,bool) const = 0;
68+
virtual void writeString(std::string_view,bool) const = 0;
6869
virtual void writeBreak(int indent) const = 0;
6970
virtual void writeLink(const QCString &extRef,const QCString &file,
70-
const QCString &anchor,const QCString &text
71+
const QCString &anchor,std::string_view text
7172
) const = 0;
7273
};
7374

@@ -76,10 +77,10 @@ class TextGeneratorOLImpl : public TextGeneratorIntf
7677
{
7778
public:
7879
TextGeneratorOLImpl(OutputList &ol);
79-
void writeString(const QCString &s,bool keepSpaces) const override;
80+
void writeString(std::string_view s,bool keepSpaces) const override;
8081
void writeBreak(int indent) const override;
8182
void writeLink(const QCString &extRef,const QCString &file,
82-
const QCString &anchor,const QCString &text
83+
const QCString &anchor,std::string_view text
8384
) const override;
8485
private:
8586
OutputList &m_ol;

src/xmlgen.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,16 +212,16 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf
212212
{
213213
public:
214214
TextGeneratorXMLImpl(TextStream &t): m_t(t) {}
215-
void writeString(const QCString &s,bool /*keepSpaces*/) const override
215+
void writeString(std::string_view s,bool /*keepSpaces*/) const override
216216
{
217-
writeXMLString(m_t,s);
217+
writeXMLString(m_t,QCString(s));
218218
}
219219
void writeBreak(int) const override {}
220220
void writeLink(const QCString &extRef,const QCString &file,
221-
const QCString &anchor,const QCString &text
221+
const QCString &anchor,std::string_view text
222222
) const override
223223
{
224-
writeXMLLink(m_t,extRef,file,anchor,text,QCString());
224+
writeXMLLink(m_t,extRef,file,anchor,QCString(text),QCString());
225225
}
226226
private:
227227
TextStream &m_t;

0 commit comments

Comments
 (0)