Skip to content

Commit

Permalink
Merge pull request #1965 from pragmaware/fix-c++-public-protected-pri…
Browse files Browse the repository at this point in the history
…vate-parsing

CXX: Improve parsing of private/public/protected
  • Loading branch information
pragmaware authored Jan 4, 2019
2 parents 199d20d + 23b5ebd commit 0b04c12
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 54 deletions.
1 change: 1 addition & 0 deletions Units/parser-c.r/cxx-scope-keywords.d/expected.tags
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ bar input.h /^void bar(void) {$/;" function typeref:typename:void
private input.h /^private :$/;" label function:bar file:
baz input.h /^void baz(void) {$/;" function typeref:typename:void
private input.h /^ private\/* coment *\/:$/;" label function:baz file:
private input.h /^int private;$/;" variable typeref:typename:int
2 changes: 2 additions & 0 deletions Units/parser-c.r/cxx-scope-keywords.d/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ void baz(void) {
private/* coment */:
return;
}

int private;
68 changes: 52 additions & 16 deletions parsers/cxx/cxx_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,16 @@ bool cxxParserParseAccessSpecifier(void)
{
CXX_DEBUG_ENTER();

CXX_DEBUG_ASSERT(
cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeKeyword) &&
(
(g_cxx.pToken->eKeyword == CXXKeywordPUBLIC) ||
(g_cxx.pToken->eKeyword == CXXKeywordPROTECTED) ||
(g_cxx.pToken->eKeyword == CXXKeywordPRIVATE)
),
"This must be called just after parinsg public/protected/private"
);

unsigned int uExtraType = 0;

enum CXXScopeType eScopeType = cxxScopeGetType();
Expand All @@ -1569,33 +1579,34 @@ bool cxxParserParseAccessSpecifier(void)

if(!g_cxx.bConfirmedCPPLanguage)
{
CXX_DEBUG_LEAVE_TEXT("C++ language is not confirmed: we try to be flexible and not bail out");
CXX_DEBUG_LEAVE_TEXT("C++ is not confirmed and the scope is not right: likely not access specifier");
g_cxx.pToken->eType = CXXTokenTypeIdentifier;
return true;
}

// this is a syntax error: we're in the wrong scope.
CXX_DEBUG_LEAVE_TEXT("C++ language is confirmed: bailing out to avoid reporting broken structure");
return false;
}

if(!g_cxx.bConfirmedCPPLanguage)
{
if(g_cxx.pToken->pPrev)
{
// ugly, there is something before the public/private/protected keyword.
// This is likely a type or something else.
CXX_DEBUG_LEAVE_TEXT(
"C++ is not confirmed and there is something before: likely not access specifier"
);
g_cxx.pToken->eType = CXXTokenTypeIdentifier;
return true;
}
}

if (cxxSubparserNotifyParseAccessSpecifier (pSubparsers))
uExtraType = CXXTokenTypeIdentifier;

switch(g_cxx.pToken->eKeyword)
{
case CXXKeywordPUBLIC:
cxxScopeSetAccess(CXXScopeAccessPublic);
break;
case CXXKeywordPRIVATE:
cxxScopeSetAccess(CXXScopeAccessPrivate);
break;
case CXXKeywordPROTECTED:
cxxScopeSetAccess(CXXScopeAccessProtected);
break;
default:
CXX_DEBUG_ASSERT(false,"Bad keyword in cxxParserParseAccessSpecifier!");
break;
}
CXXToken * pInitialToken = g_cxx.pToken;

// skip to the next :, without leaving scope.
findColon:
Expand All @@ -1618,6 +1629,31 @@ bool cxxParserParseAccessSpecifier(void)
goto findColon;
}

if(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSingleColon))
{
if(!pInitialToken->pPrev)
{
CXX_DEBUG_PRINT("The access specifier was the first token and I have found a colon: this is C++");
g_cxx.bConfirmedCPPLanguage = true;
}
}

switch(pInitialToken->eKeyword)
{
case CXXKeywordPUBLIC:
cxxScopeSetAccess(CXXScopeAccessPublic);
break;
case CXXKeywordPRIVATE:
cxxScopeSetAccess(CXXScopeAccessPrivate);
break;
case CXXKeywordPROTECTED:
cxxScopeSetAccess(CXXScopeAccessProtected);
break;
default:
CXX_DEBUG_ASSERT(false,"Bad keyword in cxxParserParseAccessSpecifier!");
break;
}

cxxTokenChainClear(g_cxx.pTokenChain);
ptrArrayClear (pSubparsers);
CXX_DEBUG_LEAVE();
Expand Down
39 changes: 1 addition & 38 deletions parsers/cxx/cxx_parser_tokenizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1231,45 +1231,8 @@ bool cxxParserParseNextToken(void)
if(cxxKeywordIsDisabled((CXXKeyword)iCXXKeyword))
{
t->eType = CXXTokenTypeIdentifier;
} else if (isInputHeaderFile ()
&& (iCXXKeyword == CXXKeywordPUBLIC
|| iCXXKeyword == CXXKeywordPROTECTED
|| iCXXKeyword == CXXKeywordPRIVATE))
{
int c0 = g_cxx.iChar;

if (c0 == ':')
{
/* Specifying the scope of struct/union/class member */
goto assign_keyword;
}

if (cppIsspace (c0))
{
int c1;

cxxParserSkipToNonWhiteSpace ();
c1 = g_cxx.iChar;
cppUngetc (c1);
g_cxx.iChar = c0;

if (c1 == ':')
{
/* Specifying the scope of struct/union/class member */
goto assign_keyword;
}
else if (cppIsalpha(c1))
{
/* Specifying the scope of class inheritance */
goto assign_keyword;
}
}

t->eType = CXXTokenTypeIdentifier;
g_cxx.bConfirmedCPPLanguage = false;
cxxKeywordEnablePublicProtectedPrivate(false);
} else {
assign_keyword:

t->eType = CXXTokenTypeKeyword;
t->eKeyword = (CXXKeyword)iCXXKeyword;

Expand Down
2 changes: 2 additions & 0 deletions parsers/cxx/cxx_qtmoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,14 @@ static bool unknownIdentifierInClassNotify (struct sCxxSubparser *pSubparser,
{
case KEYWORD_SIGNALS:
CXX_DEBUG_PRINT("Found \"signals\" QtMoc Keyword");
pToken->eType = CXXTokenTypeKeyword;
pToken->eKeyword = CXXKeywordPUBLIC;
cxxParserParseAccessSpecifier();
pQtMoc->eMemberMarker = QtMocMemberMarkerSignal;
return true;
case KEYWORD_SLOTS:
CXX_DEBUG_PRINT("Found \"slots\" QtMoc Keyword");
pToken->eType = CXXTokenTypeKeyword;
g_cxx.pToken->eKeyword = CXXKeywordPUBLIC; /* ??? */
cxxParserParseAccessSpecifier();
pQtMoc->eMemberMarker = QtMocMemberMarkerSlot;
Expand Down

0 comments on commit 0b04c12

Please sign in to comment.