Skip to content

Commit

Permalink
Merge pull request #3275 from masatake/cpp-null-arg-macrox
Browse files Browse the repository at this point in the history
Cxx: handle the case passing nothing as a macro argument
  • Loading branch information
masatake committed Feb 13, 2022
2 parents 4c6a120 + 0785b9c commit 38c046d
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Units/parser-c.r/macroexpand-empty-arg.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
--sort=no
--fields=+n{signature}
--param-CPreProcessor._expand=1
--fields-C={macrodef}
69 changes: 69 additions & 0 deletions Units/parser-c.r/macroexpand-empty-arg.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
X input.c /^#define X$/;" d line:1 file: macrodef:
m0 input.c /^#define m0(/;" d line:2 file: signature:(Q,W,E,R) macrodef:int Q
m1 input.c /^#define m1(/;" d line:3 file: signature:(Q,W,E,R) macrodef:int W
m2 input.c /^#define m2(/;" d line:4 file: signature:(Q,W,E,R) macrodef:int E
m3 input.c /^#define m3(/;" d line:5 file: signature:(Q,W,E,R) macrodef:int R
a input.c /^m0(a,b,c,d);$/;" v line:7 typeref:typename:int
a input.c /^m0(a,X,c,d);$/;" v line:8 typeref:typename:int
a input.c /^m0(a,b,X,d);$/;" v line:9 typeref:typename:int
a input.c /^m0(a,b,c,X);$/;" v line:10 typeref:typename:int
a input.c /^m0(a,X,X,d);$/;" v line:11 typeref:typename:int
a input.c /^m0(a,b,X,X);$/;" v line:12 typeref:typename:int
a input.c /^m0(a,X,c,X);$/;" v line:13 typeref:typename:int
a input.c /^m0(a,X,X,X);$/;" v line:14 typeref:typename:int
b input.c /^m1(a,b,c,d);$/;" v line:16 typeref:typename:int
b input.c /^m1(X,b,c,d);$/;" v line:17 typeref:typename:int
b input.c /^m1(a,b,X,d);$/;" v line:18 typeref:typename:int
b input.c /^m1(a,b,c,X);$/;" v line:19 typeref:typename:int
b input.c /^m1(X,b,X,d);$/;" v line:20 typeref:typename:int
b input.c /^m1(a,b,X,X);$/;" v line:21 typeref:typename:int
b input.c /^m1(X,b,c,X);$/;" v line:22 typeref:typename:int
b input.c /^m1(X,b,X,X);$/;" v line:23 typeref:typename:int
c input.c /^m2(a,b,c,d);$/;" v line:25 typeref:typename:int
c input.c /^m2(X,b,c,d);$/;" v line:26 typeref:typename:int
c input.c /^m2(a,X,c,d);$/;" v line:27 typeref:typename:int
c input.c /^m2(a,b,c,X);$/;" v line:28 typeref:typename:int
c input.c /^m2(X,X,c,d);$/;" v line:29 typeref:typename:int
c input.c /^m2(a,X,c,X);$/;" v line:30 typeref:typename:int
c input.c /^m2(X,b,c,X);$/;" v line:31 typeref:typename:int
c input.c /^m2(X,X,c,X);$/;" v line:32 typeref:typename:int
d input.c /^m3(a,b,c,d);$/;" v line:34 typeref:typename:int
d input.c /^m3(X,b,c,d);$/;" v line:35 typeref:typename:int
d input.c /^m3(a,X,c,d);$/;" v line:36 typeref:typename:int
d input.c /^m3(a,b,X,d);$/;" v line:37 typeref:typename:int
d input.c /^m3(X,X,c,d);$/;" v line:38 typeref:typename:int
d input.c /^m3(a,X,X,d);$/;" v line:39 typeref:typename:int
d input.c /^m3(X,b,X,d);$/;" v line:40 typeref:typename:int
d input.c /^m3(X,X,X,d);$/;" v line:41 typeref:typename:int
a input.c /^m0(a,b,c,d);$/;" v line:43 typeref:typename:int
a input.c /^m0(a,,c,d);$/;" v line:44 typeref:typename:int
a input.c /^m0(a,b,,d);$/;" v line:45 typeref:typename:int
a input.c /^m0(a,b,c,);$/;" v line:46 typeref:typename:int
a input.c /^m0(a,,,d);$/;" v line:47 typeref:typename:int
a input.c /^m0(a,b,,);$/;" v line:48 typeref:typename:int
a input.c /^m0(a,,c,);$/;" v line:49 typeref:typename:int
a input.c /^m0(a,,,);$/;" v line:50 typeref:typename:int
b input.c /^m1(a,b,c,d);$/;" v line:52 typeref:typename:int
b input.c /^m1(,b,c,d);$/;" v line:53 typeref:typename:int
b input.c /^m1(a,b,,d);$/;" v line:54 typeref:typename:int
b input.c /^m1(a,b,c,);$/;" v line:55 typeref:typename:int
b input.c /^m1(,b,,d);$/;" v line:56 typeref:typename:int
b input.c /^m1(a,b,,);$/;" v line:57 typeref:typename:int
b input.c /^m1(,b,c,);$/;" v line:58 typeref:typename:int
b input.c /^m1(,b,,);$/;" v line:59 typeref:typename:int
c input.c /^m2(a,b,c,d);$/;" v line:61 typeref:typename:int
c input.c /^m2(,b,c,d);$/;" v line:62 typeref:typename:int
c input.c /^m2(a,,c,d);$/;" v line:63 typeref:typename:int
c input.c /^m2(a,b,c,);$/;" v line:64 typeref:typename:int
c input.c /^m2(,,c,d);$/;" v line:65 typeref:typename:int
c input.c /^m2(a,,c,);$/;" v line:66 typeref:typename:int
c input.c /^m2(,b,c,);$/;" v line:67 typeref:typename:int
c input.c /^m2(,,c,);$/;" v line:68 typeref:typename:int
d input.c /^m3(a,b,c,d);$/;" v line:70 typeref:typename:int
d input.c /^m3(,b,c,d);$/;" v line:71 typeref:typename:int
d input.c /^m3(a,,c,d);$/;" v line:72 typeref:typename:int
d input.c /^m3(a,b,,d);$/;" v line:73 typeref:typename:int
d input.c /^m3(,,c,d);$/;" v line:74 typeref:typename:int
d input.c /^m3(a,,,d);$/;" v line:75 typeref:typename:int
d input.c /^m3(,b,,d);$/;" v line:76 typeref:typename:int
d input.c /^m3(,,,d);$/;" v line:77 typeref:typename:int
77 changes: 77 additions & 0 deletions Units/parser-c.r/macroexpand-empty-arg.d/input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#define X
#define m0(Q,W,E,R) int Q
#define m1(Q,W,E,R) int W
#define m2(Q,W,E,R) int E
#define m3(Q,W,E,R) int R

m0(a,b,c,d);
m0(a,X,c,d);
m0(a,b,X,d);
m0(a,b,c,X);
m0(a,X,X,d);
m0(a,b,X,X);
m0(a,X,c,X);
m0(a,X,X,X);

m1(a,b,c,d);
m1(X,b,c,d);
m1(a,b,X,d);
m1(a,b,c,X);
m1(X,b,X,d);
m1(a,b,X,X);
m1(X,b,c,X);
m1(X,b,X,X);

m2(a,b,c,d);
m2(X,b,c,d);
m2(a,X,c,d);
m2(a,b,c,X);
m2(X,X,c,d);
m2(a,X,c,X);
m2(X,b,c,X);
m2(X,X,c,X);

m3(a,b,c,d);
m3(X,b,c,d);
m3(a,X,c,d);
m3(a,b,X,d);
m3(X,X,c,d);
m3(a,X,X,d);
m3(X,b,X,d);
m3(X,X,X,d);

m0(a,b,c,d);
m0(a,,c,d);
m0(a,b,,d);
m0(a,b,c,);
m0(a,,,d);
m0(a,b,,);
m0(a,,c,);
m0(a,,,);

m1(a,b,c,d);
m1(,b,c,d);
m1(a,b,,d);
m1(a,b,c,);
m1(,b,,d);
m1(a,b,,);
m1(,b,c,);
m1(,b,,);

m2(a,b,c,d);
m2(,b,c,d);
m2(a,,c,d);
m2(a,b,c,);
m2(,,c,d);
m2(a,,c,);
m2(,b,c,);
m2(,,c,);

m3(a,b,c,d);
m3(,b,c,d);
m3(a,,c,d);
m3(a,b,,d);
m3(,,c,d);
m3(a,,,d);
m3(,b,,d);
m3(,,,d);
36 changes: 32 additions & 4 deletions parsers/cxx/cxx_token_chain.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,17 @@ void cxxTokenChainMoveEntryRange(
}
#endif

static CXXToken * cxxTokenCreatePlaceholder(CXXToken * pToken)
{
CXXToken * pPlaceholder = cxxTokenCreate();

pPlaceholder->iLineNumber = pToken->iLineNumber;
pPlaceholder->oFilePosition = pToken->oFilePosition;
pPlaceholder->eType = CXXTokenTypeUnknown;

return pPlaceholder;
}

CXXTokenChain * cxxTokenChainSplitOnComma(CXXTokenChain * tc)
{
if(!tc)
Expand All @@ -457,14 +468,31 @@ CXXTokenChain * cxxTokenChainSplitOnComma(CXXTokenChain * tc)

while(pStart && pToken->pNext)
{
while(pToken->pNext && (!cxxTokenTypeIs(pToken->pNext,CXXTokenTypeComma)))
pToken = pToken->pNext;
CXXToken * pNew = NULL;

CXXToken * pNew = cxxTokenChainExtractRange(pStart,pToken,0);
if (cxxTokenTypeIs(pToken,CXXTokenTypeComma))
{
// If nothing is passed as an argument like
//
// macro(,b),
// macro(a,), or
// macro(,)
//
// , we must inject a dummy token to the chain.
pNew = cxxTokenCreatePlaceholder(pToken);
// we will not update pToken in this case.
}
else
{
while(pToken->pNext && (!cxxTokenTypeIs(pToken->pNext,CXXTokenTypeComma)))
pToken = pToken->pNext;

pNew = cxxTokenChainExtractRange(pStart,pToken,0);
pToken = pToken->pNext; // comma or nothing
}
if(pNew)
cxxTokenChainAppend(pRet,pNew);

pToken = pToken->pNext; // comma or nothing
if(pToken)
pToken = pToken->pNext; // after comma
pStart = pToken;
Expand Down

0 comments on commit 38c046d

Please sign in to comment.