Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Tmain/list-kinds-full.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ z parameter no no 0 C function parameters inside function or prototype definitio
A alias no no 0 NONE namespace aliases
D macroparam no no 0 C parameters inside macro definitions
L label no no 0 C goto labels
N name no no 0 NONE names imported via using scope::symbol
U using no yes 0 NONE using namespace statements
N name yes yes 1 NONE names imported via using scope::symbol
Z tparam no no 0 NONE template parameters
c class yes no 0 NONE classes
d macro yes no 1 C macro definitions
Expand All @@ -30,7 +29,7 @@ g enum yes no 0 C enumeration names
h header yes yes 2 C included header files
l local no no 0 C local variables
m member yes no 0 C class, struct, and union members
n namespace yes no 0 NONE namespaces
n namespace yes no 1 NONE namespaces
p prototype no no 0 C function prototypes
s struct yes no 0 C structure names
t typedef yes no 0 C typedefs
Expand Down
4 changes: 4 additions & 0 deletions Tmain/list-roles.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ Automake d/directory script on directory for SCRIPT
C d/macro undef on undefined
C h/header local on local header
C h/header system on system header
C++ N/name used on specified with "using foo::bar"
C++ d/macro undef on undefined
C++ h/header local on local header
C++ h/header system on system header
C++ n/namespace used on specified with "using namespace"
CPreProcessor d/macro undef on undefined
CPreProcessor h/header local on local header
CPreProcessor h/header system on system header
Expand Down Expand Up @@ -109,9 +111,11 @@ Automake d/directory script on directory for SCRIPT
C d/macro undef on undefined
C h/header local on local header
C h/header system on system header
C++ N/name used on specified with "using foo::bar"
C++ d/macro undef on undefined
C++ h/header local on local header
C++ h/header system on system header
C++ n/namespace used on specified with "using namespace"
CPreProcessor d/macro undef on undefined
CPreProcessor h/header local on local header
CPreProcessor h/header system on system header
Expand Down
1 change: 0 additions & 1 deletion Units/parser-cxx.r/bug1093123.cpp.d/expected.tags
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
main input.cpp /^int main() {$/;" f typeref:typename:int
std input.cpp /^using namespace std;$/;" U function:main
m input.cpp /^int m;$/;" l function:main typeref:typename:int file:
1 change: 0 additions & 1 deletion Units/parser-cxx.r/bug834.cpp.d/expected.tags
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
std input.cpp /^using namespace std;$/;" U file:
C input.cpp /^vector<vector<int>> C;$/;" v typeref:typename:vector<vector<int>>
A input.cpp /^struct A {$/;" s file:
a input.cpp /^ int a;$/;" m struct:A typeref:typename:int file:
Expand Down
11 changes: 8 additions & 3 deletions Units/parser-cxx.r/using.cpp.d/expected.tags
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
A input.cpp /^class A$/;" class file: roles:def
B input.cpp /^class B : public A$/;" class file: roles:def
std input.cpp /^using namespace std;$/;" using file: roles:def
C input.cpp /^ class C : A$/;" class namespace:X file: roles:def
D input.cpp /^class D : X::C$/;" class file: roles:def
X input.cpp /^namespace X$/;" namespace file: roles:def
std input.cpp /^using namespace std;$/;" namespace file: roles:used
string input.cpp /^#include <string>/;" header roles:system
string input.cpp /^using std::string;$/;" name file: roles:def
test input.cpp /^ using A::test;$/;" name class:B roles:def
string input.cpp /^using std::string;$/;" name name:std roles:used
test input.cpp /^ using A::test;$/;" name name:A roles:used
test input.cpp /^ void test();$/;" prototype class:A typeref:typename:void file: signature:() roles:def
test input.cpp /^ void test(x t);$/;" prototype class:B typeref:typename:void file: signature:(x t) roles:def
test2 input.cpp /^ void test2();$/;" prototype class:X::C typeref:typename:void file: signature:() roles:def
test2 input.cpp /^ using X::C::test2;$/;" name name:X::C roles:used
x input.cpp /^using x = std::string;$/;" typedef typeref:typename:std::string file: roles:def
17 changes: 16 additions & 1 deletion Units/parser-cxx.r/using.cpp.d/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,19 @@ class B : public A
public:
void test(x t);
using A::test;
};
};

namespace X
{
class C : A
{
public:
void test2();
};
}

class D : X::C
{
public:
using X::C::test2;
};
1 change: 1 addition & 0 deletions parsers/cxx/cxx_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ const char* cxxDebugScopeDecode(enum CXXScopeType scope)
[CXXScopeTypeVariable] = "variable",
[CXXScopeTypePrototype] = "prototype",
[CXXScopeTypeTypedef] = "typedef",
[CXXScopeTypeName] = "name",
};
if (CXXScopeTypeLAST > scope)
return table[scope];
Expand Down
48 changes: 45 additions & 3 deletions parsers/cxx/cxx_parser_using.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ bool cxxParserParseUsingClause(void)
if(g_cxx.pTokenChain->iCount > 0)
{
tagEntryInfo * tag;
int iScopeCount = 0;
CXXTokenChain *pOriginalScope = NULL;

if(bUsingNamespace)
{
Expand All @@ -134,7 +136,9 @@ bool cxxParserParseUsingClause(void)
"Found using clause '%s' which extends scope",
vStringValue(t->pszWord)
);
tag = cxxTagBegin(CXXTagCPPKindUSING,t);
tag = cxxRefTagBegin(CXXTagCPPKindNAMESPACE,
CXXTagCPPNamespaceRoleUSED,t);

} else {

t = cxxTokenChainLast(g_cxx.pTokenChain);
Expand All @@ -143,9 +147,34 @@ bool cxxParserParseUsingClause(void)
"Found using clause '%s' which imports a name",
vStringValue(t->pszWord)
);
tag = cxxTagBegin(CXXTagCPPKindNAME,t);

// FIXME: We need something like "nameref:<condensed>" here!
// Backup the original scope stack
int iSize = cxxScopeGetSize();
if(iSize > 0)
{
pOriginalScope = cxxTokenChainCreate();
while(iSize--)
{
CXXToken *t0 = cxxScopeTakeTop();
cxxTokenChainPrepend(pOriginalScope, t0);
}
}

// Push temporary scopes for the name
while(cxxTokenChainFirst(g_cxx.pTokenChain) != t)
{
CXXToken *pTokenScope = cxxTokenChainTakeFirst(g_cxx.pTokenChain);
if(cxxTokenTypeIs(pTokenScope,CXXTokenTypeIdentifier))
{
cxxScopePush(pTokenScope,CXXScopeTypeName,CXXScopeAccessUnknown);
iScopeCount++;
}
else
cxxTokenDestroy(pTokenScope);
}

tag = cxxRefTagBegin(CXXTagCPPKindNAME,
CXXTagCPPNameRoleUSED, t);
}

if(tag)
Expand All @@ -154,6 +183,19 @@ bool cxxParserParseUsingClause(void)
(!isInputHeaderFile());
cxxTagCommit();
}

// Destory the temporary scopes for the name
while(iScopeCount--)
cxxScopePop();

// Recover the original scope stack
if(pOriginalScope)
{
CXXToken *t0;
while((t0 = cxxTokenChainTakeFirst(pOriginalScope)))
cxxScopePushTop(t0);
cxxTokenChainDestroy(pOriginalScope);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions parsers/cxx/cxx_scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ unsigned int cxxScopeGetKind(void)
return CXXTagKindVARIABLE;
case CXXScopeTypeTypedef:
return CXXTagKindTYPEDEF;
case CXXScopeTypeName:
return CXXTagCPPKindNAME;
default:
CXX_DEBUG_ASSERT(false,"Unhandled scope type!");
break;
Expand Down
2 changes: 2 additions & 0 deletions parsers/cxx/cxx_scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ enum CXXScopeType
CXXScopeTypeVariable, // template variables, mainly
CXXScopeTypePrototype,
CXXScopeTypeTypedef, // template variables used in "using A = B<T>"
CXXScopeTypeName, /* for representing scope information of
foo in "using some::thing::foo" */
CXXScopeTypeLAST
};

Expand Down
33 changes: 26 additions & 7 deletions parsers/cxx/cxx_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,22 @@ static kindDefinition g_aCXXCKinds [] = {
CXX_COMMON_KINDS(C,"struct, and union members", LANG_IGNORE)
};

static roleDefinition g_aCXXCPPNamespaceRoles [] = {
{ true, "used", "specified with \"using namespace\"" },
};

static roleDefinition g_aCXXCPPNameRoles [] = {
{ true, "used", "specified with \"using foo::bar\"" },
};

static kindDefinition g_aCXXCPPKinds [] = {
CXX_COMMON_KINDS(CXX,"class, struct, and union members", LANG_AUTO),
{ true, 'c', "class", "classes" },
{ true, 'n', "namespace", "namespaces" },
{ true, 'n', "namespace", "namespaces",
.referenceOnly = false, ATTACH_ROLES(g_aCXXCPPNamespaceRoles) },
{ false, 'A', "alias", "namespace aliases" },
{ false, 'N', "name", "names imported via using scope::symbol" },
{ false, 'U', "using", "using namespace statements",
.referenceOnly = true },
{ true, 'N', "name", "names imported via using scope::symbol",
.referenceOnly = true, ATTACH_ROLES(g_aCXXCPPNameRoles) },
{ false, 'Z', "tparam", "template parameters" },
};

Expand Down Expand Up @@ -245,7 +253,7 @@ bool cxxTagFieldEnabled(unsigned int uField)
static tagEntryInfo g_oCXXTag;


tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)
static tagEntryInfo * cxxTagBeginCommon(unsigned int uKind,unsigned int uRole,CXXToken * pToken)
{
kindDefinition * pKindDefinitions = g_cxx.pKindDefinitions;

Expand All @@ -255,10 +263,11 @@ tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)
return NULL;
}

initTagEntry(
initRefTagEntry(
&g_oCXXTag,
vStringValue(pToken->pszWord),
uKind
uKind,
uRole
);

g_oCXXTag.lineNumber = pToken->iLineNumber;
Expand All @@ -277,6 +286,16 @@ tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)
return &g_oCXXTag;
}

tagEntryInfo * cxxRefTagBegin(unsigned int uKind, unsigned int uRole, CXXToken * pToken)
{
return cxxTagBeginCommon(uKind, uRole, pToken);
}

tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)
{
return cxxTagBeginCommon(uKind, ROLE_DEFINITION_INDEX, pToken);
}

vString * cxxTagSetProperties(unsigned int uProperties)
{
if(uProperties == 0)
Expand Down
15 changes: 14 additions & 1 deletion parsers/cxx/cxx_tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,19 @@ enum CXXTagCPPKind
CXXTagCPPKindNAMESPACE,
CXXTagCPPKindALIAS,
CXXTagCPPKindNAME,
CXXTagCPPKindUSING,
CXXTagCPPKindTEMPLATEPARAM
};

enum CXXTagCPPNamespaceRole
{
CXXTagCPPNamespaceRoleUSED,
};

enum CXXTagCPPNameRole
{
CXXTagCPPNameRoleUSED,
};

// The fields common to all (sub)languages this parser supports.
enum CXXTagCommonField
{
Expand Down Expand Up @@ -99,6 +108,10 @@ bool cxxTagKindEnabled(unsigned int uTagKind);
// The pToken ownership is NOT transferred.
tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken);

// Do the same as cxxTagBegin but attaching a role for making a
// reference tag.
tagEntryInfo * cxxRefTagBegin(unsigned int uKind,unsigned int uRole,CXXToken * pToken);

// Set the type of the current tag from the specified token sequence
// (which must belong to the same chain!).
// Before setting the type this function will check that the specified
Expand Down