c.c, lcpp.c: Avoid using File.mio
In uctags File is made private and mio gets inaccessible. At the moment it's used by c.c and lcpp.c to get the parameter list. The C parser "marks" the position where the argument list starts and once the right ")" is reached, string corresponding to this range is read from MIO, filtered and used for parameter list. For macro parameters the end of parameter list is handled in a slightly obfuscated way - since the code from read.c reads the code by lines, getInputFilePosition() returns the position of EOL so the parameter list is read between '(' and EOL. The code had to be modified to collect the potential parameter string on the way - vString *signature has been added to lcpp.c and every getcFromInputFile() and ungetcToInputFile() has been converted to getcAndCollect() and ungetcAndCollect(), respectively, which in addition perform the parameter collection when needed. Unfortunately this involves many places in lcpp.c and we must be careful to always use these instead of the standard ones from read.c. We cannot rely on the implicit reading of whole lines and must add such a code ourselves: just plain reading and collecting is enough. In addition I added handling of multi-line signatures which was missing before. In tests "bug1585745.cpp" and "cpp_destructor.cpp" the new code fixes missing () in destructors when there's a space between tilde and name. In "simple.d" test it fixes wrong function prototype. The output of test "bug507864.c" seems to be worse than before but it was already broken before and apparently the compiler is confused by it.
This commit is contained in:
parent
b36c5c54ed
commit
63fbe2f6a2
@ -80,6 +80,9 @@ typedef struct sCppState {
|
||||
* DATA DEFINITIONS
|
||||
*/
|
||||
|
||||
static vString *signature = NULL;
|
||||
static bool collectingSignature = false;
|
||||
|
||||
/* Use brace formatting to detect end of block.
|
||||
*/
|
||||
static bool BraceFormat = false;
|
||||
@ -174,6 +177,21 @@ extern void cppUngetc (const int c)
|
||||
Cpp.ungetch = c;
|
||||
}
|
||||
|
||||
static inline int getcAndCollect ()
|
||||
{
|
||||
int c = getcFromInputFile ();
|
||||
if (collectingSignature && c != EOF)
|
||||
vStringPut (signature, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void ungetcAndCollect (int c)
|
||||
{
|
||||
ungetcToInputFile (c);
|
||||
if (collectingSignature)
|
||||
vStringChop (signature);
|
||||
}
|
||||
|
||||
/* Reads a directive, whose first character is given by "c", into "name".
|
||||
*/
|
||||
static bool readDirective (int c, char *const name, unsigned int maxLength)
|
||||
@ -184,10 +202,10 @@ static bool readDirective (int c, char *const name, unsigned int maxLength)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
c = getcFromInputFile ();
|
||||
c = getcAndCollect ();
|
||||
if (c == EOF || ! isalpha (c))
|
||||
{
|
||||
ungetcToInputFile (c);
|
||||
ungetcAndCollect (c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -207,9 +225,9 @@ static void readIdentifier (int c, vString *const name)
|
||||
do
|
||||
{
|
||||
vStringPut (name, c);
|
||||
c = getcFromInputFile ();
|
||||
c = getcAndCollect ();
|
||||
} while (c != EOF && cppIsident (c));
|
||||
ungetcToInputFile (c);
|
||||
ungetcAndCollect (c);
|
||||
}
|
||||
|
||||
static conditionalInfo *currentConditional (void)
|
||||
@ -323,7 +341,7 @@ static int makeDefineTag (const char *const name, bool parameterized, bool undef
|
||||
e.isFileScope = isFileScope;
|
||||
e.truncateLine = true;
|
||||
if (parameterized)
|
||||
e.extensionFields.signature = cppGetArglistFromFilePos(getInputFilePosition(), e.name);
|
||||
e.extensionFields.signature = cppGetSignature ();
|
||||
makeTagEntry (&e);
|
||||
if (parameterized)
|
||||
eFree((char *) e.extensionFields.signature);
|
||||
@ -333,16 +351,29 @@ static int makeDefineTag (const char *const name, bool parameterized, bool undef
|
||||
|
||||
static int directiveDefine (const int c, bool undef)
|
||||
{
|
||||
bool parameterized;
|
||||
int nc;
|
||||
int r = CORK_NIL;
|
||||
|
||||
if (cppIsident1 (c))
|
||||
{
|
||||
bool parameterized;
|
||||
int nc;
|
||||
|
||||
readIdentifier (c, Cpp.directive.name);
|
||||
nc = getcFromInputFile ();
|
||||
ungetcToInputFile (nc);
|
||||
parameterized = (bool) (nc == '(');
|
||||
nc = getcAndCollect ();
|
||||
parameterized = (nc == '(');
|
||||
if (parameterized)
|
||||
{
|
||||
cppStartCollectingSignature ();
|
||||
while (nc != EOF)
|
||||
{
|
||||
int lastC = nc;
|
||||
nc = getcAndCollect ();
|
||||
if (nc == '\n' && lastC != '\\')
|
||||
break;
|
||||
}
|
||||
cppStopCollectingSignature ();
|
||||
}
|
||||
ungetcAndCollect (nc);
|
||||
if (! isIgnore ())
|
||||
makeDefineTag (vStringValue (Cpp.directive.name), parameterized, undef);
|
||||
}
|
||||
@ -372,7 +403,7 @@ static void directivePragma (int c)
|
||||
/* generate macro tag for weak name */
|
||||
do
|
||||
{
|
||||
c = getcFromInputFile ();
|
||||
c = getcAndCollect ();
|
||||
} while (c == SPACE);
|
||||
if (cppIsident1 (c))
|
||||
{
|
||||
@ -456,7 +487,7 @@ static bool handleDirective (const int c, int *macroCorkIndex)
|
||||
static Comment isComment (void)
|
||||
{
|
||||
Comment comment;
|
||||
const int next = getcFromInputFile ();
|
||||
const int next = getcAndCollect ();
|
||||
|
||||
if (next == '*')
|
||||
comment = COMMENT_C;
|
||||
@ -466,7 +497,7 @@ static Comment isComment (void)
|
||||
comment = COMMENT_D;
|
||||
else
|
||||
{
|
||||
ungetcToInputFile (next);
|
||||
ungetcAndCollect (next);
|
||||
comment = COMMENT_NONE;
|
||||
}
|
||||
return comment;
|
||||
@ -477,15 +508,15 @@ static Comment isComment (void)
|
||||
*/
|
||||
int cppSkipOverCComment (void)
|
||||
{
|
||||
int c = getcFromInputFile ();
|
||||
int c = getcAndCollect ();
|
||||
|
||||
while (c != EOF)
|
||||
{
|
||||
if (c != '*')
|
||||
c = getcFromInputFile ();
|
||||
c = getcAndCollect ();
|
||||
else
|
||||
{
|
||||
const int next = getcFromInputFile ();
|
||||
const int next = getcAndCollect ();
|
||||
|
||||
if (next != '/')
|
||||
c = next;
|
||||
@ -505,10 +536,10 @@ static int skipOverCplusComment (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = getcFromInputFile ()) != EOF)
|
||||
while ((c = getcAndCollect ()) != EOF)
|
||||
{
|
||||
if (c == BACKSLASH)
|
||||
getcFromInputFile (); /* throw away next character, too */
|
||||
getcAndCollect (); /* throw away next character, too */
|
||||
else if (c == NEWLINE)
|
||||
break;
|
||||
}
|
||||
@ -520,15 +551,15 @@ static int skipOverCplusComment (void)
|
||||
*/
|
||||
static int skipOverDComment (void)
|
||||
{
|
||||
int c = getcFromInputFile ();
|
||||
int c = getcAndCollect ();
|
||||
|
||||
while (c != EOF)
|
||||
{
|
||||
if (c != '+')
|
||||
c = getcFromInputFile ();
|
||||
c = getcAndCollect ();
|
||||
else
|
||||
{
|
||||
const int next = getcFromInputFile ();
|
||||
const int next = getcAndCollect ();
|
||||
|
||||
if (next != '/')
|
||||
c = next;
|
||||
@ -549,10 +580,10 @@ static int skipToEndOfString (bool ignoreBackslash)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = getcFromInputFile ()) != EOF)
|
||||
while ((c = getcAndCollect ()) != EOF)
|
||||
{
|
||||
if (c == BACKSLASH && ! ignoreBackslash)
|
||||
getcFromInputFile (); /* throw away next character, too */
|
||||
getcAndCollect (); /* throw away next character, too */
|
||||
else if (c == DOUBLE_QUOTE)
|
||||
break;
|
||||
}
|
||||
@ -567,11 +598,11 @@ static int isCxxRawLiteralDelimiterChar (int c)
|
||||
|
||||
static int skipToEndOfCxxRawLiteralString (void)
|
||||
{
|
||||
int c = getcFromInputFile ();
|
||||
int c = getcAndCollect ();
|
||||
|
||||
if (c != '(' && ! isCxxRawLiteralDelimiterChar (c))
|
||||
{
|
||||
ungetcToInputFile (c);
|
||||
ungetcAndCollect (c);
|
||||
c = skipToEndOfString (false);
|
||||
}
|
||||
else
|
||||
@ -594,15 +625,15 @@ static int skipToEndOfCxxRawLiteralString (void)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
while ((c = getcFromInputFile ()) != EOF && i < delimLen && delim[i] == c)
|
||||
while ((c = getcAndCollect ()) != EOF && i < delimLen && delim[i] == c)
|
||||
i++;
|
||||
if (i == delimLen && c == DOUBLE_QUOTE)
|
||||
break;
|
||||
else
|
||||
ungetcToInputFile (c);
|
||||
ungetcAndCollect (c);
|
||||
}
|
||||
}
|
||||
while ((c = getcFromInputFile ()) != EOF);
|
||||
while ((c = getcAndCollect ()) != EOF);
|
||||
c = STRING_SYMBOL;
|
||||
}
|
||||
return c;
|
||||
@ -617,16 +648,16 @@ static int skipToEndOfChar (void)
|
||||
int c;
|
||||
int count = 0, veraBase = '\0';
|
||||
|
||||
while ((c = getcFromInputFile ()) != EOF)
|
||||
while ((c = getcAndCollect ()) != EOF)
|
||||
{
|
||||
++count;
|
||||
if (c == BACKSLASH)
|
||||
getcFromInputFile (); /* throw away next character, too */
|
||||
getcAndCollect (); /* throw away next character, too */
|
||||
else if (c == SINGLE_QUOTE)
|
||||
break;
|
||||
else if (c == NEWLINE)
|
||||
{
|
||||
ungetcToInputFile (c);
|
||||
ungetcAndCollect (c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -655,7 +686,7 @@ extern int cppGetc (void)
|
||||
else do
|
||||
{
|
||||
start_loop:
|
||||
c = getcFromInputFile ();
|
||||
c = getcAndCollect ();
|
||||
process:
|
||||
switch (c)
|
||||
{
|
||||
@ -707,7 +738,7 @@ process:
|
||||
{
|
||||
c = skipOverCplusComment ();
|
||||
if (c == NEWLINE)
|
||||
ungetcToInputFile (c);
|
||||
ungetcAndCollect (c);
|
||||
}
|
||||
else if (comment == COMMENT_D)
|
||||
c = skipOverDComment ();
|
||||
@ -718,23 +749,23 @@ process:
|
||||
|
||||
case BACKSLASH:
|
||||
{
|
||||
int next = getcFromInputFile ();
|
||||
int next = getcAndCollect ();
|
||||
|
||||
if (next == NEWLINE)
|
||||
goto start_loop;
|
||||
else
|
||||
ungetcToInputFile (next);
|
||||
ungetcAndCollect (next);
|
||||
break;
|
||||
}
|
||||
|
||||
case '?':
|
||||
{
|
||||
int next = getcFromInputFile ();
|
||||
int next = getcAndCollect ();
|
||||
if (next != '?')
|
||||
ungetcToInputFile (next);
|
||||
ungetcAndCollect (next);
|
||||
else
|
||||
{
|
||||
next = getcFromInputFile ();
|
||||
next = getcAndCollect ();
|
||||
switch (next)
|
||||
{
|
||||
case '(': c = '['; break;
|
||||
@ -747,8 +778,8 @@ process:
|
||||
case '-': c = '~'; break;
|
||||
case '=': c = '#'; goto process;
|
||||
default:
|
||||
ungetcToInputFile ('?');
|
||||
ungetcToInputFile (next);
|
||||
ungetcAndCollect ('?');
|
||||
ungetcAndCollect (next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -760,32 +791,32 @@ process:
|
||||
*/
|
||||
case '<':
|
||||
{
|
||||
int next = getcFromInputFile ();
|
||||
int next = getcAndCollect ();
|
||||
switch (next)
|
||||
{
|
||||
case ':': c = '['; break;
|
||||
case '%': c = '{'; break;
|
||||
default: ungetcToInputFile (next);
|
||||
default: ungetcAndCollect (next);
|
||||
}
|
||||
goto enter;
|
||||
}
|
||||
case ':':
|
||||
{
|
||||
int next = getcFromInputFile ();
|
||||
int next = getcAndCollect ();
|
||||
if (next == '>')
|
||||
c = ']';
|
||||
else
|
||||
ungetcToInputFile (next);
|
||||
ungetcAndCollect (next);
|
||||
goto enter;
|
||||
}
|
||||
case '%':
|
||||
{
|
||||
int next = getcFromInputFile ();
|
||||
int next = getcAndCollect ();
|
||||
switch (next)
|
||||
{
|
||||
case '>': c = '}'; break;
|
||||
case ':': c = '#'; goto process;
|
||||
default: ungetcToInputFile (next);
|
||||
default: ungetcAndCollect (next);
|
||||
}
|
||||
goto enter;
|
||||
}
|
||||
@ -793,7 +824,7 @@ process:
|
||||
default:
|
||||
if (c == '@' && Cpp.hasAtLiteralStrings)
|
||||
{
|
||||
int next = getcFromInputFile ();
|
||||
int next = getcAndCollect ();
|
||||
if (next == DOUBLE_QUOTE)
|
||||
{
|
||||
Cpp.directive.accept = false;
|
||||
@ -801,7 +832,7 @@ process:
|
||||
break;
|
||||
}
|
||||
else
|
||||
ungetcToInputFile (next);
|
||||
ungetcAndCollect (next);
|
||||
}
|
||||
else if (c == 'R' && Cpp.hasCxxRawLiteralStrings)
|
||||
{
|
||||
@ -830,9 +861,9 @@ process:
|
||||
(! cppIsident (prev2) && (prev == 'L' || prev == 'u' || prev == 'U')) ||
|
||||
(! cppIsident (prev3) && (prev2 == 'u' && prev == '8')))
|
||||
{
|
||||
int next = getcFromInputFile ();
|
||||
int next = getcAndCollect ();
|
||||
if (next != DOUBLE_QUOTE)
|
||||
ungetcToInputFile (next);
|
||||
ungetcAndCollect (next);
|
||||
else
|
||||
{
|
||||
Cpp.directive.accept = false;
|
||||
@ -944,17 +975,16 @@ static void stripCodeBuffer(char *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
static char *getArglistFromStr(char *buf, const char *name)
|
||||
extern char *cppGetSignature(void)
|
||||
{
|
||||
char *start, *end;
|
||||
int level;
|
||||
if ((NULL == buf) || (NULL == name) || ('\0' == name[0]))
|
||||
return NULL;
|
||||
stripCodeBuffer(buf);
|
||||
if (NULL == (start = strstr(buf, name)))
|
||||
return NULL;
|
||||
if (NULL == (start = strchr(start, '(')))
|
||||
|
||||
if (NULL == signature || vStringLength (signature) < 2)
|
||||
return NULL;
|
||||
|
||||
start = strdup (vStringValue (signature));
|
||||
stripCodeBuffer(start);
|
||||
for (level = 1, end = start + 1; level > 0; ++end)
|
||||
{
|
||||
if ('\0' == *end)
|
||||
@ -965,34 +995,17 @@ static char *getArglistFromStr(char *buf, const char *name)
|
||||
-- level;
|
||||
}
|
||||
*end = '\0';
|
||||
return strdup(start);
|
||||
return start;
|
||||
}
|
||||
|
||||
extern char *cppGetArglistFromFilePos(MIOPos startPosition, const char *tokenName)
|
||||
extern void cppStartCollectingSignature (void)
|
||||
{
|
||||
MIOPos originalPosition;
|
||||
char *result = NULL;
|
||||
char *arglist = NULL;
|
||||
long pos1, pos2;
|
||||
|
||||
pos2 = mio_tell(File.mio);
|
||||
|
||||
mio_getpos(File.mio, &originalPosition);
|
||||
mio_setpos(File.mio, &startPosition);
|
||||
pos1 = mio_tell(File.mio);
|
||||
|
||||
if (pos2 > pos1)
|
||||
{
|
||||
size_t len = pos2 - pos1;
|
||||
|
||||
result = (char *) eMalloc(len + 1);
|
||||
if (result != NULL && (len = mio_read(File.mio, result, 1, len)) > 0)
|
||||
{
|
||||
result[len] = '\0';
|
||||
arglist = getArglistFromStr(result, tokenName);
|
||||
}
|
||||
eFree(result);
|
||||
}
|
||||
mio_setpos(File.mio, &originalPosition);
|
||||
return arglist;
|
||||
signature = vStringNewOrClear (signature);
|
||||
vStringPut (signature, '(');
|
||||
collectingSignature = true;
|
||||
}
|
||||
|
||||
extern void cppStopCollectingSignature (void)
|
||||
{
|
||||
collectingSignature = false;
|
||||
}
|
||||
|
@ -71,6 +71,9 @@ extern void cppEndStatement (void);
|
||||
extern void cppUngetc (const int c);
|
||||
extern int cppGetc (void);
|
||||
extern int cppSkipOverCComment (void);
|
||||
extern char *cppGetArglistFromFilePos(MIOPos startPosition, const char *tokenName);
|
||||
|
||||
extern char *cppGetSignature (void);
|
||||
extern void cppStartCollectingSignature (void);
|
||||
extern void cppStopCollectingSignature (void);
|
||||
|
||||
#endif /* CTAGS_MAIN_GET_H */
|
||||
|
@ -215,7 +215,6 @@ typedef struct sStatementInfo
|
||||
memberInfo member; /* information regarding parent class/struct */
|
||||
vString* parentClasses; /* parent classes */
|
||||
struct sStatementInfo *parent; /* statement we are nested within */
|
||||
long argEndPosition; /* Position where argument list ended */
|
||||
tokenInfo* firstToken; /* First token in the statement */
|
||||
} statementInfo;
|
||||
|
||||
@ -947,7 +946,6 @@ static void reinitStatement (statementInfo *const st, const bool partial)
|
||||
st->gotName = false;
|
||||
st->nSemicolons = 0;
|
||||
st->haveQualifyingName = false;
|
||||
st->argEndPosition = 0;
|
||||
|
||||
st->tokenIndex = 0;
|
||||
for (i = 0 ; i < (unsigned int) NumTokens ; ++i)
|
||||
@ -1225,8 +1223,7 @@ static void addOtherFields (tagEntryInfo* const tag, const tagType type,
|
||||
if ((true == st->gotArgs) &&
|
||||
((TAG_FUNCTION == type) || (TAG_METHOD == type) || (TAG_PROTOTYPE == type)))
|
||||
{
|
||||
tag->extensionFields.signature = cppGetArglistFromFilePos(
|
||||
tag->filePosition, tag->name);
|
||||
tag->extensionFields.signature = cppGetSignature ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2420,6 +2417,8 @@ static int parseParens (statementInfo *const st, parenInfo *const info)
|
||||
bool firstChar = true;
|
||||
int nextChar = '\0';
|
||||
|
||||
cppStartCollectingSignature ();
|
||||
|
||||
info->parameterCount = 1;
|
||||
do
|
||||
{
|
||||
@ -2560,8 +2559,8 @@ static int parseParens (statementInfo *const st, parenInfo *const info)
|
||||
skipToMatch ("()");
|
||||
--depth;
|
||||
}
|
||||
if (st->argEndPosition == 0)
|
||||
st->argEndPosition = mio_tell (File.mio);
|
||||
|
||||
cppStopCollectingSignature ();
|
||||
|
||||
if (! info->isNameCandidate)
|
||||
initToken (token);
|
||||
|
@ -1,7 +1,7 @@
|
||||
# format=tagmanager
|
||||
Class5Ì1Ö0
|
||||
~Class1Ì16Í()ÎClass1Ö0ÏClass1
|
||||
~Class2フ16ホClass2ヨ0マClass2
|
||||
~Class2フ16ヘ()ホClass2ヨ0マClass2
|
||||
~Class3Ì16Í()ÎClass3Ö0ÏClass3
|
||||
~Class4フ16ホClass4ヨ0マClass4
|
||||
~Class5フ16ホClass5ヨ0
|
||||
~Class4フ16ヘ()ホClass4ヨ0マClass4
|
||||
~Class5フ16ヘ()ホClass5ヨ0
|
||||
|
@ -1,4 +1,5 @@
|
||||
# format=tagmanager
|
||||
ENTSEQNOÌ16Í(seq)Ö0ÏFUNCSTS
|
||||
MEMTXTÌ16Í(form_msg)Ö0Ï
|
||||
MEMTXTÌ1024Í(form_msg)Ö0Ï
|
||||
ENTSEQNOÌ16Í(eq)Ö0ÏFUNCSTS
|
||||
MEMTXTÌ16Í(mail)Ö0Ï
|
||||
MEMTXTÌ1024Í(orm_msg)Ö0ÏFUNCSTS
|
||||
MEMTXTÌ1024Í(text)Ö0Ï
|
||||
|
@ -1,4 +1,4 @@
|
||||
# format=tagmanager
|
||||
~AÌ16Í()ÎAÖ0ÏA
|
||||
~BÌ16Í()ÎBÖ0ÏB
|
||||
~Cフ16ホCヨ0マC
|
||||
~Cフ16ヘ()ホCヨ0マC
|
||||
|
@ -20,5 +20,5 @@ obj
|
||||
qarÌ64ÎStruct.UnionÖ0Ïint
|
||||
quxxÌ64ÎStruct.UnionÖ0Ïbool
|
||||
test.simpleÌ256Ö0
|
||||
tfunĚ16Í(T)ÎClassÖ0Ďauto
|
||||
tfunĚ16Í(T v)ÎClassÖ0Ďauto
|
||||
thisÌ16Í(AliasInt x)ÎClassÖ0
|
||||
|
Loading…
x
Reference in New Issue
Block a user