Skip to content

Commit 66033e6

Browse files
committed
C++: fill scope file of name kind tags
using A::B::C; For the input, this change makes a tag for C like: TODO:: * the way to handle the first "::" in 'using ::std::cout;' * the way to handle 'namespace X { using A::B; }' How can we represent the relationship between X and B. Signed-off-by: Masatake YAMATO <yamato@redhat.com>
1 parent 016957e commit 66033e6

6 files changed

Lines changed: 69 additions & 5 deletions

File tree

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
A input.cpp /^class A$/;" class file: roles:def
22
B input.cpp /^class B : public A$/;" class file: roles:def
3+
C input.cpp /^ class C : A$/;" class namespace:X file: roles:def
4+
D input.cpp /^class D : X::C$/;" class file: roles:def
5+
X input.cpp /^namespace X$/;" namespace file: roles:def
36
std input.cpp /^using namespace std;$/;" namespace file: roles:used
47
string input.cpp /^#include <string>/;" header roles:system
5-
string input.cpp /^using std::string;$/;" name file: roles:used
6-
test input.cpp /^ using A::test;$/;" name class:B roles:used
8+
string input.cpp /^using std::string;$/;" name name:std roles:used
9+
test input.cpp /^ using A::test;$/;" name name:A roles:used
710
test input.cpp /^ void test();$/;" prototype class:A typeref:typename:void file: signature:() roles:def
811
test input.cpp /^ void test(x t);$/;" prototype class:B typeref:typename:void file: signature:(x t) roles:def
12+
test2 input.cpp /^ void test2();$/;" prototype class:X::C typeref:typename:void file: signature:() roles:def
13+
test2 input.cpp /^ using X::C::test2;$/;" name name:X::C roles:used
914
x input.cpp /^using x = std::string;$/;" typedef typeref:typename:std::string file: roles:def

Units/parser-cxx.r/using.cpp.d/input.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,19 @@ class B : public A
1515
public:
1616
void test(x t);
1717
using A::test;
18-
};
18+
};
19+
20+
namespace X
21+
{
22+
class C : A
23+
{
24+
public:
25+
void test2();
26+
};
27+
}
28+
29+
class D : X::C
30+
{
31+
public:
32+
using X::C::test2;
33+
};

parsers/cxx/cxx_debug.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ const char* cxxDebugScopeDecode(enum CXXScopeType scope)
172172
[CXXScopeTypeVariable] = "variable",
173173
[CXXScopeTypePrototype] = "prototype",
174174
[CXXScopeTypeTypedef] = "typedef",
175+
[CXXScopeTypeName] = "name",
175176
};
176177
if (CXXScopeTypeLAST > scope)
177178
return table[scope];

parsers/cxx/cxx_parser_using.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ bool cxxParserParseUsingClause(void)
118118
if(g_cxx.pTokenChain->iCount > 0)
119119
{
120120
tagEntryInfo * tag;
121+
int iScopeCount = 0;
122+
CXXTokenChain *pOriginalScope = NULL;
121123

122124
if(bUsingNamespace)
123125
{
@@ -145,10 +147,34 @@ bool cxxParserParseUsingClause(void)
145147
"Found using clause '%s' which imports a name",
146148
vStringValue(t->pszWord)
147149
);
150+
151+
// Backup the original scope stack
152+
int iSize = cxxScopeGetSize();
153+
if(iSize > 0)
154+
{
155+
pOriginalScope = cxxTokenChainCreate();
156+
while(iSize--)
157+
{
158+
CXXToken *t0 = cxxScopeTakeTop();
159+
cxxTokenChainPrepend(pOriginalScope, t0);
160+
}
161+
}
162+
163+
// Push temporary scopes for the name
164+
while(cxxTokenChainFirst(g_cxx.pTokenChain) != t)
165+
{
166+
CXXToken *pTokenScope = cxxTokenChainTakeFirst(g_cxx.pTokenChain);
167+
if(cxxTokenTypeIs(pTokenScope,CXXTokenTypeIdentifier))
168+
{
169+
cxxScopePush(pTokenScope,CXXScopeTypeName,CXXScopeAccessUnknown);
170+
iScopeCount++;
171+
}
172+
else
173+
cxxTokenDestroy(pTokenScope);
174+
}
175+
148176
tag = cxxRefTagBegin(CXXTagCPPKindNAME,
149177
CXXTagCPPNameRoleUSED, t);
150-
151-
// FIXME: We need something like "nameref:<condensed>" here!
152178
}
153179

154180
if(tag)
@@ -157,6 +183,19 @@ bool cxxParserParseUsingClause(void)
157183
(!isInputHeaderFile());
158184
cxxTagCommit();
159185
}
186+
187+
// Destory the temporary scopes for the name
188+
while(iScopeCount--)
189+
cxxScopePop();
190+
191+
// Recover the original scope stack
192+
if(pOriginalScope)
193+
{
194+
CXXToken *t0;
195+
while((t0 = cxxTokenChainTakeFirst(pOriginalScope)))
196+
cxxScopePushTop(t0);
197+
cxxTokenChainDestroy(pOriginalScope);
198+
}
160199
}
161200
}
162201

parsers/cxx/cxx_scope.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ unsigned int cxxScopeGetKind(void)
112112
return CXXTagKindVARIABLE;
113113
case CXXScopeTypeTypedef:
114114
return CXXTagKindTYPEDEF;
115+
case CXXScopeTypeName:
116+
return CXXTagCPPKindNAME;
115117
default:
116118
CXX_DEBUG_ASSERT(false,"Unhandled scope type!");
117119
break;

parsers/cxx/cxx_scope.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ enum CXXScopeType
3232
CXXScopeTypeVariable, // template variables, mainly
3333
CXXScopeTypePrototype,
3434
CXXScopeTypeTypedef, // template variables used in "using A = B<T>"
35+
CXXScopeTypeName, /* for representing scope information of
36+
foo in "using some::thing::foo" */
3537
CXXScopeTypeLAST
3638
};
3739

0 commit comments

Comments
 (0)