Skip to content

Commit 0805d5b

Browse files
committed
C++: fix "export" declaration wrongly marked as file-local (file: and extras:fileScope)
Close #4003. Signed-off-by: Masatake YAMATO <[email protected]>
1 parent 300a488 commit 0805d5b

File tree

11 files changed

+77
-33
lines changed

11 files changed

+77
-33
lines changed
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
A input.cpp /^export module A; \/\/ declares the primary module interface unit for named module 'A'$/;" M properties:export
22
hello input.cpp /^export char const* hello() { return "hello"; }$/;" f typeref:typename:char const * properties:export
33
world input.cpp /^char const* world() { return "world"; }$/;" f typeref:typename:char const *
4-
hi input.cpp /^export namespace hi$/;" n file: properties:export
4+
hi input.cpp /^export namespace hi$/;" n properties:export
55
english input.cpp /^ char const* english() { return "Hi!"; }$/;" f namespace:hi typeref:typename:char const *
66
french input.cpp /^ char const* french() { return "Salut!"; }$/;" f namespace:hi typeref:typename:char const *
7-
x input.cpp /^export enum x { a = 1 };$/;" g file: properties:export
8-
a input.cpp /^export enum x { a = 1 };$/;" e enum:x file:
9-
td input.cpp /^export typedef int td;$/;" t typeref:typename:int file: properties:export
7+
x input.cpp /^export enum x { a = 1 };$/;" g properties:export
8+
a input.cpp /^export enum x { a = 1 };$/;" e enum:x
9+
td input.cpp /^export typedef int td;$/;" t typeref:typename:int properties:export
1010
s_ input.cpp /^struct s_ {$/;" s file:
1111
mbr input.cpp /^ int mbr;$/;" m struct:s_ typeref:typename:int file:
12-
s input.cpp /^export struct s {$/;" s file: properties:export
13-
mbr input.cpp /^ int mbr;$/;" m struct:s typeref:typename:int file:
12+
s input.cpp /^export struct s {$/;" s properties:export
13+
mbr input.cpp /^ int mbr;$/;" m struct:s typeref:typename:int
1414
s__ input.cpp /^struct s__ {$/;" s file:
1515
mbr input.cpp /^ int mbr;$/;" m struct:s__ typeref:typename:int file:
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
Y input.cpp /^export module Y;$/;" M properties:export
2-
Z0 input.cpp /^ namespace Z0 {$/;" n file: properties:export
2+
Z0 input.cpp /^ namespace Z0 {$/;" n properties:export
33
z0 input.cpp /^ int z0;$/;" v namespace:Z0 typeref:typename:int
44
X input.cpp /^namespace X {$/;" n file:
55
a input.cpp /^ int a;$/;" v namespace:X typeref:typename:int
66
x input.cpp /^ int x;$/;" v namespace:X typeref:typename:int properties:export
7-
f input.cpp /^ int f(int i);$/;" p namespace:X typeref:typename:int file: properties:export
8-
u input.cpp /^ union u {$/;" u namespace:X file: properties:export
9-
mbr input.cpp /^ int mbr;$/;" m union:X::u typeref:typename:int file:
7+
f input.cpp /^ int f(int i);$/;" p namespace:X typeref:typename:int properties:export
8+
u input.cpp /^ union u {$/;" u namespace:X properties:export
9+
mbr input.cpp /^ int mbr;$/;" m union:X::u typeref:typename:int
1010
b input.cpp /^ int b;$/;" v namespace:X typeref:typename:int
1111
m input.cpp /^int m;$/;" v typeref:typename:int
1212
z input.cpp /^ int z;$/;" v typeref:typename:int properties:export
13-
E input.cpp /^ enum E { a = 1 };$/;" g file: properties:export
14-
a input.cpp /^ enum E { a = 1 };$/;" e enum:E file:
15-
td input.cpp /^ typedef int td;$/;" t typeref:typename:int file: properties:export
16-
c input.cpp /^ class c {$/;" c file: properties:export
17-
mbr input.cpp /^ int mbr;$/;" m class:c typeref:typename:int file:
13+
E input.cpp /^ enum E { a = 1 };$/;" g properties:export
14+
a input.cpp /^ enum E { a = 1 };$/;" e enum:E
15+
td input.cpp /^ typedef int td;$/;" t typeref:typename:int properties:export
16+
c input.cpp /^ class c {$/;" c properties:export
17+
mbr input.cpp /^ int mbr;$/;" m class:c typeref:typename:int
1818
n input.cpp /^int n;$/;" v typeref:typename:int
19+
o input.cpp /^static int o;$/;" v typeref:typename:int file: properties:static

Units/parser-cxx.r/export-3.d/input.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ export {
3030
};
3131
}
3232
int n;
33+
static int o;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
mylib input.cpp /^export module mylib;$/;" module properties:export
2-
X input.cpp /^export namespace X {$/;" namespace file: properties:export
2+
X input.cpp /^export namespace X {$/;" namespace properties:export
33
i input.cpp /^ int i;$/;" variable namespace:X typeref:typename:int
4-
Z input.cpp /^export namespace Z = X;$/;" alias file: properties:export name:X
4+
Z input.cpp /^export namespace Z = X;$/;" alias properties:export name:X
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Delta input.cpp /^export module Delta;$/;" module roles:def properties:export
2-
Param input.cpp /^export using Param = int;$/;" typedef typeref:typename:int file: roles:def properties:export
3-
Param input.cpp /^export using ::Param;$/;" name file: roles:def properties:export
4-
Param input.cpp /^export using ::Param; \/\/ We can declare an object more than twice.$/;" name file: roles:def properties:export
5-
fn input.cpp /^export void fn();$/;" prototype typeref:typename:void file: roles:def properties:export
2+
Param input.cpp /^export using Param = int;$/;" typedef typeref:typename:int roles:def properties:export
3+
Param input.cpp /^export using ::Param;$/;" name roles:def properties:export
4+
Param input.cpp /^export using ::Param; \/\/ We can declare an object more than twice.$/;" name roles:def properties:export
5+
fn input.cpp /^export void fn();$/;" prototype typeref:typename:void roles:def properties:export

parsers/cxx/cxx_parser.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,7 @@ bool cxxParserParseEnum(void)
899899
int iCorkQueueIndex = CORK_NIL;
900900
int iCorkQueueIndexFQ = CORK_NIL;
901901

902+
bool bEnumExported = false;
902903
if(tag)
903904
{
904905
// FIXME: this is debatable
@@ -921,7 +922,13 @@ bool cxxParserParseEnum(void)
921922
if(bIsScopedEnum)
922923
uProperties |= CXXTagPropertyScopedEnum;
923924
if(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)
925+
{
924926
uProperties |= CXXTagPropertyExport;
927+
bEnumExported = true;
928+
}
929+
tag->isFileScope = (bEnumExported || cxxScopeIsExported())
930+
? 0
931+
: tag->isFileScope;
925932

926933
if(uProperties)
927934
pszProperties = cxxTagSetProperties(uProperties);
@@ -936,7 +943,7 @@ bool cxxParserParseEnum(void)
936943
cxxTokenDestroy(pTypeName);
937944
}
938945

939-
cxxScopePush(pEnumName,CXXScopeTypeEnum,CXXScopeAccessPublic);
946+
cxxScopePushExported(pEnumName,CXXScopeTypeEnum,CXXScopeAccessPublic, bEnumExported);
940947
iPushedScopes++;
941948

942949
vString * pScopeName = cxxScopeGetFullNameAsString();
@@ -968,7 +975,10 @@ bool cxxParserParseEnum(void)
968975
tag = cxxTagBegin(CXXTagKindENUMERATOR,pFirst);
969976
if(tag)
970977
{
971-
tag->isFileScope = !isInputHeaderFile();
978+
// If the enum is export'ed, we consider that its
979+
// enumerators are not limited in a file scope.
980+
tag->isFileScope = !isInputHeaderFile() && !cxxScopeIsExported();
981+
972982
cxxTagCommit(NULL);
973983
}
974984
}
@@ -1349,6 +1359,7 @@ static bool cxxParserParseClassStructOrUnionInternal(
13491359
bool bGotTemplate = g_cxx.pTemplateTokenChain &&
13501360
(g_cxx.pTemplateTokenChain->iCount > 0) &&
13511361
cxxParserCurrentLanguageIsCPP();
1362+
bool bExported = uInitialKeywordState & CXXParserKeywordStateSeenExport;
13521363

13531364
if(tag)
13541365
{
@@ -1400,8 +1411,14 @@ static bool cxxParserParseClassStructOrUnionInternal(
14001411
tag->isFileScope = !isInputHeaderFile();
14011412

14021413
unsigned int uProperties = 0;
1403-
if(uInitialKeywordState & CXXParserKeywordStateSeenExport)
1414+
if(bExported)
14041415
uProperties |= CXXTagPropertyExport;
1416+
// Overwrite the assigned value if the language object is export'ed
1417+
// directly or indirectly.
1418+
tag->isFileScope = (bExported || cxxScopeIsExported())
1419+
? 0
1420+
: tag->isFileScope;
1421+
14051422
vString * pszProperties = NULL;
14061423

14071424
if(uProperties)
@@ -1413,11 +1430,12 @@ static bool cxxParserParseClassStructOrUnionInternal(
14131430
vStringDelete (pszProperties); /* NULL is acceptable. */
14141431
}
14151432

1416-
cxxScopePush(
1433+
cxxScopePushExported(
14171434
pClassName,
14181435
uScopeType,
14191436
(uTagKind == CXXTagCPPKindCLASS) ?
1420-
CXXScopeAccessPrivate : CXXScopeAccessPublic
1437+
CXXScopeAccessPrivate : CXXScopeAccessPublic,
1438+
bExported
14211439
);
14221440

14231441
if(

parsers/cxx/cxx_parser_function.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ int cxxParserMaybeParseKnRStyleFunctionDefinition(void)
294294
pParenthesis->pChain->pTail->bFollowedBySpace = false;
295295
}
296296

297+
// We don't have to consider export'ed status here; the input is written in C!
297298
tag->isFileScope = (g_cxx.uKeywordState & CXXParserKeywordStateSeenStatic) &&
298299
!isInputHeaderFile();
299300

@@ -319,6 +320,7 @@ int cxxParserMaybeParseKnRStyleFunctionDefinition(void)
319320
vStringValue(pIdentifier->pszWord)
320321
);
321322

323+
// We don't have to propagate export'ed status; the input is written in C!
322324
cxxScopePush(pIdentifier,CXXScopeTypeFunction,CXXScopeAccessUnknown);
323325

324326
// emit parameters
@@ -1626,6 +1628,11 @@ int cxxParserEmitFunctionTags(
16261628
tag->isFileScope = !isInputHeaderFile();
16271629
}
16281630
}
1631+
// Overwrite the assigned value if the language object is export'ed.
1632+
tag->isFileScope = ((g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)
1633+
|| cxxScopeIsExported())
1634+
? 0
1635+
: tag->isFileScope;
16291636

16301637
vString * pszSignature = cxxTokenChainJoin(pInfo->pParenthesis->pChain,NULL,0);
16311638
if(pInfo->pSignatureConst)

parsers/cxx/cxx_parser_namespace.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ bool cxxParserParseNamespace(void)
5151
// namespace;
5252

5353
unsigned int uProperties = 0;
54+
bool bExported = g_cxx.uKeywordState & CXXParserKeywordStateSeenExport;
5455

5556
if(cxxTagFieldEnabled(CXXTagFieldProperties))
5657
{
5758
if(g_cxx.uKeywordState & CXXParserKeywordStateSeenInline)
5859
uProperties |= CXXTagPropertyInline;
59-
if(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)
60+
if(bExported)
6061
uProperties |= CXXTagPropertyExport;
6162
}
6263

@@ -136,7 +137,7 @@ bool cxxParserParseNamespace(void)
136137
if(tag)
137138
{
138139
// This is highly questionable but well.. it's how old ctags did, so we do.
139-
tag->isFileScope = !isInputHeaderFile();
140+
tag->isFileScope = !isInputHeaderFile() && !bExported && !cxxScopeIsExported();
140141

141142
vString * pszProperties = NULL;
142143
if(uProperties)
@@ -249,7 +250,7 @@ bool cxxParserParseNamespace(void)
249250
if(tag)
250251
{
251252
// This is highly questionable but well.. it's how old ctags did, so we do.
252-
tag->isFileScope = !isInputHeaderFile();
253+
tag->isFileScope = !isInputHeaderFile() && !bExported && !cxxScopeIsExported();
253254

254255
vString * pszProperties = uProperties ? cxxTagSetProperties(uProperties) : NULL;
255256

@@ -269,10 +270,11 @@ bool cxxParserParseNamespace(void)
269270

270271
cxxTokenChainTake(g_cxx.pTokenChain,t);
271272

272-
cxxScopePush(
273+
cxxScopePushExported(
273274
t,
274275
CXXScopeTypeNamespace,
275-
CXXScopeAccessUnknown
276+
CXXScopeAccessUnknown,
277+
bExported
276278
);
277279

278280
iScopeCount++;
@@ -290,6 +292,8 @@ bool cxxParserParseNamespace(void)
290292
if(tag)
291293
{
292294
tag->isFileScope = !isInputHeaderFile();
295+
// We don't have to consider "export" keyword here because an object having
296+
// no name is not exportable.
293297

294298
markTagExtraBit (tag, XTAG_ANONYMOUS);
295299

parsers/cxx/cxx_parser_typedef.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,9 @@ void cxxParserExtractTypedef(
441441
);
442442
}
443443

444-
tag->isFileScope = !isInputHeaderFile();
444+
tag->isFileScope = !isInputHeaderFile()
445+
&& !(uProperties & CXXTagPropertyExport)
446+
&& !cxxScopeIsExported();
445447

446448
if(bGotTemplate)
447449
cxxTagHandleTemplateFields();

parsers/cxx/cxx_parser_using.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,13 @@ bool cxxParserParseUsingClause(void)
173173
tag->isFileScope = (cxxScopeGetType() == CXXScopeTypeNamespace) &&
174174
(!isInputHeaderFile());
175175

176+
bool bExported = uInitialKeywordState & CXXParserKeywordStateSeenExport;
176177
unsigned int uProperties = 0;
177-
if(uInitialKeywordState & CXXParserKeywordStateSeenExport)
178+
if(bExported)
178179
uProperties |= CXXTagPropertyExport;
180+
tag->isFileScope = bExported || cxxScopeIsExported()
181+
? 0
182+
: tag->isFileScope;
179183
vString * pszProperties = NULL;
180184

181185
if(uProperties)

0 commit comments

Comments
 (0)