xref: /Universal-ctags/parsers/c.c (revision 081ee612a091a26ca86460bb8b7d642fe7599821)
13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO *   Copyright (c) 1996-2003, Darren Hiebert
33ae02089SMasatake YAMATO *
43ae02089SMasatake YAMATO *   This source code is released for free distribution under the terms of the
50ce38835Sviccuad *   GNU General Public License version 2 or (at your option) any later version.
63ae02089SMasatake YAMATO *
73ae02089SMasatake YAMATO *   This module contains functions for parsing and scanning C, C++, C#, D and Java
83ae02089SMasatake YAMATO *   source files.
93ae02089SMasatake YAMATO */
103ae02089SMasatake YAMATO 
113ae02089SMasatake YAMATO /*
123ae02089SMasatake YAMATO *   INCLUDE FILES
133ae02089SMasatake YAMATO */
143ae02089SMasatake YAMATO #include "general.h"        /* must always come first */
153ae02089SMasatake YAMATO 
163ae02089SMasatake YAMATO #include <string.h>
173ae02089SMasatake YAMATO #include <setjmp.h>
183ae02089SMasatake YAMATO 
193ae02089SMasatake YAMATO #include "debug.h"
203ae02089SMasatake YAMATO #include "entry.h"
2187214e15SMasatake YAMATO #include "cpreprocessor.h"
223ae02089SMasatake YAMATO #include "keyword.h"
233ae02089SMasatake YAMATO #include "options.h"
243ae02089SMasatake YAMATO #include "parse.h"
253ae02089SMasatake YAMATO #include "read.h"
263ae02089SMasatake YAMATO #include "routines.h"
278e1e6125SMasatake YAMATO #include "selectors.h"
2835c59e96SMasatake YAMATO #include "xtag.h"
293ae02089SMasatake YAMATO 
303ae02089SMasatake YAMATO /*
313ae02089SMasatake YAMATO *   MACROS
323ae02089SMasatake YAMATO */
333ae02089SMasatake YAMATO 
343ae02089SMasatake YAMATO #define activeToken(st)     ((st)->token [(int) (st)->tokenIndex])
353ae02089SMasatake YAMATO #define parentDecl(st)      ((st)->parent == NULL ? \
363ae02089SMasatake YAMATO                             DECL_NONE : (st)->parent->declaration)
37ce990805SThomas Braun #define isType(token,t)     (bool) ((token)->type == (t))
38ce990805SThomas Braun #define insideEnumBody(st)  ((st)->parent == NULL ? false : \
39ce990805SThomas Braun                             (bool) ((st)->parent->declaration == DECL_ENUM))
40ce990805SThomas Braun #define insideAnnotationBody(st)  ((st)->parent == NULL ? false : \
41ce990805SThomas Braun 								  (bool) ((st)->parent->declaration == DECL_ANNOTATION))
42ce990805SThomas Braun #define insideInterfaceBody(st) ((st)->parent == NULL ? false : \
43ce990805SThomas Braun                             (bool) ((st)->parent->declaration == DECL_INTERFACE))
44ce990805SThomas Braun #define isSignalDirection(token) (bool)(( (token)->keyword == KEYWORD_INPUT  ) ||\
4590230484SMasatake YAMATO 					   ( (token)->keyword == KEYWORD_OUTPUT ) ||\
4690230484SMasatake YAMATO 					   ( (token)->keyword == KEYWORD_INOUT  )  )
47ce990805SThomas Braun #define isExternCDecl(st,c) (bool) ((c) == STRING_SYMBOL  && \
483ae02089SMasatake YAMATO                     ! (st)->haveQualifyingName  && (st)->scope == SCOPE_EXTERN)
493ae02089SMasatake YAMATO 
50ce990805SThomas Braun #define isOneOf(c,s)        (bool) (strchr ((s), (c)) != NULL)
513ae02089SMasatake YAMATO 
523ae02089SMasatake YAMATO #define isHighChar(c)       ((c) != EOF && (unsigned int)(c) >= 0xc0 && \
533ae02089SMasatake YAMATO 							               (unsigned int)(c) <= 0xff)
543ae02089SMasatake YAMATO 
553ae02089SMasatake YAMATO /*
563ae02089SMasatake YAMATO *   DATA DECLARATIONS
573ae02089SMasatake YAMATO */
583ae02089SMasatake YAMATO 
593ae02089SMasatake YAMATO enum { NumTokens = 3 };
603ae02089SMasatake YAMATO 
613ae02089SMasatake YAMATO typedef enum eException {
623ae02089SMasatake YAMATO 	ExceptionNone, ExceptionEOF, ExceptionFormattingError,
633ae02089SMasatake YAMATO 	ExceptionBraceFormattingError
643ae02089SMasatake YAMATO } exception_t;
653ae02089SMasatake YAMATO 
663ae02089SMasatake YAMATO /*  Used to specify type of keyword.
673ae02089SMasatake YAMATO  */
684faa2076SColomban Wendling enum eKeywordId {
693ae02089SMasatake YAMATO 	KEYWORD_ALIAS, KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT,
703ae02089SMasatake YAMATO 	KEYWORD_BOOLEAN, KEYWORD_BYTE, KEYWORD_BAD_STATE, KEYWORD_BAD_TRANS,
713ae02089SMasatake YAMATO 	KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT,
7290230484SMasatake YAMATO 	KEYWORD_CASE, KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CLOCK, KEYWORD_CONST,
733ae02089SMasatake YAMATO 	KEYWORD_CONSTRAINT, KEYWORD_COVERAGE_BLOCK, KEYWORD_COVERAGE_DEF,
743ae02089SMasatake YAMATO 	KEYWORD_DEFAULT, KEYWORD_DELEGATE, KEYWORD_DELETE, KEYWORD_DO,
753ae02089SMasatake YAMATO 	KEYWORD_DOUBLE,
763ae02089SMasatake YAMATO 	KEYWORD_ELSE, KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN,
773ae02089SMasatake YAMATO 	KEYWORD_EXTENDS, KEYWORD_EVENT,
783ae02089SMasatake YAMATO 	KEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FOR, KEYWORD_FOREACH,
793ae02089SMasatake YAMATO 	KEYWORD_FRIEND, KEYWORD_FUNCTION,
803ae02089SMasatake YAMATO 	KEYWORD_GOTO,
8190230484SMasatake YAMATO 	KEYWORD_HDL_NODE,
823ae02089SMasatake YAMATO 	KEYWORD_IF, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_INLINE, KEYWORD_INT,
833ae02089SMasatake YAMATO 	KEYWORD_INOUT, KEYWORD_INPUT, KEYWORD_INTEGER, KEYWORD_INTERFACE,
843ae02089SMasatake YAMATO 	KEYWORD_INTERNAL,
853ae02089SMasatake YAMATO 	KEYWORD_LOCAL, KEYWORD_LONG,
863ae02089SMasatake YAMATO 	KEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS,
873ae02089SMasatake YAMATO 	KEYWORD_MUTABLE,
8890230484SMasatake YAMATO 	KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE,
8990230484SMasatake YAMATO 	KEYWORD_NHOLD, KEYWORD_NOEXCEPT, KEYWORD_NSAMPLE,
903ae02089SMasatake YAMATO 	KEYWORD_OPERATOR, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE,
9190230484SMasatake YAMATO 	KEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PHOLD, KEYWORD_PRIVATE,
9290230484SMasatake YAMATO 	KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PSAMPLE, KEYWORD_PUBLIC,
933ae02089SMasatake YAMATO 	KEYWORD_REGISTER, KEYWORD_RETURN,
943ae02089SMasatake YAMATO 	KEYWORD_SHADOW, KEYWORD_STATE,
953ae02089SMasatake YAMATO 	KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRING,
963ae02089SMasatake YAMATO 	KEYWORD_STRUCT, KEYWORD_SWITCH, KEYWORD_SYNCHRONIZED,
973ae02089SMasatake YAMATO 	KEYWORD_TASK, KEYWORD_TEMPLATE, KEYWORD_THIS, KEYWORD_THROW,
983ae02089SMasatake YAMATO 	KEYWORD_THROWS, KEYWORD_TRANSIENT, KEYWORD_TRANS, KEYWORD_TRANSITION,
993ae02089SMasatake YAMATO 	KEYWORD_TRY, KEYWORD_TYPEDEF, KEYWORD_TYPENAME,
1003ae02089SMasatake YAMATO 	KEYWORD_UINT, KEYWORD_ULONG, KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USHORT,
1013ae02089SMasatake YAMATO 	KEYWORD_USING,
1023ae02089SMasatake YAMATO 	KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE,
1033ae02089SMasatake YAMATO 	KEYWORD_WCHAR_T, KEYWORD_WHILE,
1043ae02089SMasatake YAMATO 	KEYWORD_ALIGN, KEYWORD_ASM, KEYWORD_ASSERT, KEYWORD_AUTO,
1053ae02089SMasatake YAMATO 	KEYWORD_BODY, KEYWORD_BOOL, KEYWORD_BREAK, KEYWORD_CAST,
1063ae02089SMasatake YAMATO 	KEYWORD_CDOUBLE, KEYWORD_CENT, KEYWORD_CFLOAT, KEYWORD_CONTINUE,
1073ae02089SMasatake YAMATO 	KEYWORD_CREAL, KEYWORD_DCHAR, KEYWORD_DEBUG,
1083ae02089SMasatake YAMATO 	KEYWORD_DEPRECATED, KEYWORD_EXPORT, KEYWORD_FALSE, KEYWORD_FINALLY,
1093ae02089SMasatake YAMATO 	KEYWORD_FOREACH_REVERSE, KEYWORD_IDOUBLE, KEYWORD_IFLOAT,
1103ae02089SMasatake YAMATO 	KEYWORD_IN, KEYWORD_INVARIANT, KEYWORD_IREAL, KEYWORD_IS,
1113ae02089SMasatake YAMATO 	KEYWORD_LAZY, KEYWORD_MIXIN, KEYWORD_MODULE, KEYWORD_NULL,
1123ae02089SMasatake YAMATO 	KEYWORD_OUT, KEYWORD_PRAGMA, KEYWORD_REAL, KEYWORD_SCOPE,
1133ae02089SMasatake YAMATO 	KEYWORD_SUPER, KEYWORD_TRUE, KEYWORD_TYPEID, KEYWORD_TYPEOF,
1143ae02089SMasatake YAMATO 	KEYWORD_UBYTE, KEYWORD_UCENT, KEYWORD_UNITTEST, KEYWORD_VERSION,
1153ae02089SMasatake YAMATO 	KEYWORD_WCHAR, KEYWORD_WITH
1164faa2076SColomban Wendling };
1174faa2076SColomban Wendling typedef int keywordId; /* to allow KEYWORD_NONE */
1183ae02089SMasatake YAMATO 
1193ae02089SMasatake YAMATO /*  Used to determine whether keyword is valid for the current language and
1203ae02089SMasatake YAMATO  *  what its ID is.
1213ae02089SMasatake YAMATO  */
1223ae02089SMasatake YAMATO typedef struct sKeywordDesc {
1233ae02089SMasatake YAMATO 	const char *name;
1243ae02089SMasatake YAMATO 	keywordId id;
1253ae02089SMasatake YAMATO 	short isValid [6]; /* indicates languages for which kw is valid */
1263ae02089SMasatake YAMATO } keywordDesc;
1273ae02089SMasatake YAMATO 
1283ae02089SMasatake YAMATO /*  Used for reporting the type of object parsed by nextToken ().
1293ae02089SMasatake YAMATO  */
1303ae02089SMasatake YAMATO typedef enum eTokenType {
1313ae02089SMasatake YAMATO 	TOKEN_NONE,          /* none */
1323ae02089SMasatake YAMATO 	TOKEN_ARGS,          /* a parenthetical pair and its contents */
1333ae02089SMasatake YAMATO 	TOKEN_BRACE_CLOSE,
1343ae02089SMasatake YAMATO 	TOKEN_BRACE_OPEN,
1353ae02089SMasatake YAMATO 	TOKEN_COLON,         /* the colon character */
1363ae02089SMasatake YAMATO 	TOKEN_COMMA,         /* the comma character */
1373ae02089SMasatake YAMATO 	TOKEN_DOUBLE_COLON,  /* double colon indicates nested-name-specifier */
1383ae02089SMasatake YAMATO 	TOKEN_KEYWORD,
1393ae02089SMasatake YAMATO 	TOKEN_NAME,          /* an unknown name */
1403ae02089SMasatake YAMATO 	TOKEN_PACKAGE,       /* a Java package name */
1413ae02089SMasatake YAMATO 	TOKEN_PAREN_NAME,    /* a single name in parentheses */
1423ae02089SMasatake YAMATO 	TOKEN_SEMICOLON,     /* the semicolon character */
1433ae02089SMasatake YAMATO 	TOKEN_SPEC,          /* a storage class specifier, qualifier, type, etc. */
1443ae02089SMasatake YAMATO 	TOKEN_COUNT
1453ae02089SMasatake YAMATO } tokenType;
1463ae02089SMasatake YAMATO 
1473ae02089SMasatake YAMATO /*  This describes the scoping of the current statement.
1483ae02089SMasatake YAMATO  */
1493ae02089SMasatake YAMATO typedef enum eTagScope {
1503ae02089SMasatake YAMATO 	SCOPE_GLOBAL,        /* no storage class specified */
1513ae02089SMasatake YAMATO 	SCOPE_STATIC,        /* static storage class */
1523ae02089SMasatake YAMATO 	SCOPE_EXTERN,        /* external storage class */
1533ae02089SMasatake YAMATO 	SCOPE_FRIEND,        /* declares access only */
1543ae02089SMasatake YAMATO 	SCOPE_TYPEDEF,       /* scoping depends upon context */
1553ae02089SMasatake YAMATO 	SCOPE_COUNT
1563ae02089SMasatake YAMATO } tagScope;
1573ae02089SMasatake YAMATO 
1583ae02089SMasatake YAMATO typedef enum eDeclaration {
1593ae02089SMasatake YAMATO 	DECL_NONE,
1603ae02089SMasatake YAMATO 	DECL_BASE,           /* base type (default) */
1613ae02089SMasatake YAMATO 	DECL_CLASS,
1623ae02089SMasatake YAMATO 	DECL_ENUM,
1633ae02089SMasatake YAMATO 	DECL_EVENT,
1643ae02089SMasatake YAMATO 	DECL_FUNCTION,
1653ae02089SMasatake YAMATO 	DECL_FUNCTION_TEMPLATE, /* D-only */
1663ae02089SMasatake YAMATO 	DECL_IGNORE,         /* non-taggable "declaration" */
1673ae02089SMasatake YAMATO 	DECL_INTERFACE,
1683ae02089SMasatake YAMATO 	DECL_MIXIN,
1693ae02089SMasatake YAMATO 	DECL_NAMESPACE,
1703ae02089SMasatake YAMATO 	DECL_NOMANGLE,       /* C++ name demangling block */
1713ae02089SMasatake YAMATO 	DECL_PACKAGE,
172fddb1356SMasatake YAMATO 	DECL_PACKAGEREF,
1733ae02089SMasatake YAMATO 	DECL_PRIVATE,
1743ae02089SMasatake YAMATO 	DECL_PROGRAM,        /* Vera program */
1753ae02089SMasatake YAMATO 	DECL_PROTECTED,
1763ae02089SMasatake YAMATO 	DECL_PUBLIC,
1773ae02089SMasatake YAMATO 	DECL_STRUCT,
1783ae02089SMasatake YAMATO 	DECL_TASK,           /* Vera task */
1793ae02089SMasatake YAMATO 	DECL_TEMPLATE,       /* D-only */
1803ae02089SMasatake YAMATO 	DECL_UNION,
1813ae02089SMasatake YAMATO 	DECL_USING,
1823ae02089SMasatake YAMATO 	DECL_VERSION,        /* D conditional compile */
183682a7f3bSJuan Pablo Civile 	DECL_ANNOTATION,     /* Java annotation */
1843ae02089SMasatake YAMATO 	DECL_COUNT
1853ae02089SMasatake YAMATO } declType;
1863ae02089SMasatake YAMATO 
1873ae02089SMasatake YAMATO typedef enum eVisibilityType {
1883ae02089SMasatake YAMATO 	ACCESS_UNDEFINED,
1893ae02089SMasatake YAMATO 	ACCESS_LOCAL,
1903ae02089SMasatake YAMATO 	ACCESS_PRIVATE,
1913ae02089SMasatake YAMATO 	ACCESS_PROTECTED,
1923ae02089SMasatake YAMATO 	ACCESS_PUBLIC,
1933ae02089SMasatake YAMATO 	ACCESS_DEFAULT,      /* Java-specific */
1943ae02089SMasatake YAMATO 	ACCESS_COUNT
1953ae02089SMasatake YAMATO } accessType;
1963ae02089SMasatake YAMATO 
1973ae02089SMasatake YAMATO /*  Information about the parent class of a member (if any).
1983ae02089SMasatake YAMATO  */
1993ae02089SMasatake YAMATO typedef struct sMemberInfo {
2003ae02089SMasatake YAMATO 	accessType access;           /* access of current statement */
2013ae02089SMasatake YAMATO 	accessType accessDefault;    /* access default for current statement */
2023ae02089SMasatake YAMATO } memberInfo;
2033ae02089SMasatake YAMATO 
2043ae02089SMasatake YAMATO typedef struct sTokenInfo {
2053ae02089SMasatake YAMATO 	tokenType     type;
2063ae02089SMasatake YAMATO 	keywordId     keyword;
2073ae02089SMasatake YAMATO 	vString*      name;          /* the name of the token */
2083ae02089SMasatake YAMATO 	unsigned long lineNumber;    /* line number of tag */
209509a47dbSJiří Techet 	MIOPos        filePosition;  /* file position of line containing name */
2103ae02089SMasatake YAMATO } tokenInfo;
2113ae02089SMasatake YAMATO 
2123ae02089SMasatake YAMATO typedef enum eImplementation {
2133ae02089SMasatake YAMATO 	IMP_DEFAULT,
2143ae02089SMasatake YAMATO 	IMP_ABSTRACT,
2153ae02089SMasatake YAMATO 	IMP_VIRTUAL,
2163ae02089SMasatake YAMATO 	IMP_PURE_VIRTUAL,
2173ae02089SMasatake YAMATO 	IMP_COUNT
2183ae02089SMasatake YAMATO } impType;
2193ae02089SMasatake YAMATO 
2203ae02089SMasatake YAMATO /*  Describes the statement currently undergoing analysis.
2213ae02089SMasatake YAMATO  */
2223ae02089SMasatake YAMATO typedef struct sStatementInfo {
2233ae02089SMasatake YAMATO 	tagScope	scope;
2243ae02089SMasatake YAMATO 	declType	declaration;    /* specifier associated with TOKEN_SPEC */
225ce990805SThomas Braun 	bool		gotName;        /* was a name parsed yet? */
226ce990805SThomas Braun 	bool		haveQualifyingName;  /* do we have a name we are considering? */
227ce990805SThomas Braun 	bool		gotParenName;   /* was a name inside parentheses parsed yet? */
228ce990805SThomas Braun 	bool		gotArgs;        /* was a list of parameters parsed yet? */
229ce990805SThomas Braun 	bool		isPointer;      /* is 'name' a pointer? */
230ce990805SThomas Braun 	bool     inFunction;     /* are we inside of a function? */
231ce990805SThomas Braun 	bool		assignment;     /* have we handled an '='? */
232ce990805SThomas Braun 	bool		notVariable;    /* has a variable declaration been disqualified ? */
2333ae02089SMasatake YAMATO 	impType		implementation; /* abstract or concrete implementation? */
2343ae02089SMasatake YAMATO 	unsigned int tokenIndex;    /* currently active token */
2353ae02089SMasatake YAMATO 	tokenInfo*	token [(int) NumTokens];
2363ae02089SMasatake YAMATO 	tokenInfo*	context;        /* accumulated scope of current statement */
2373ae02089SMasatake YAMATO 	tokenInfo*	blockName;      /* name of current block */
2383ae02089SMasatake YAMATO 	memberInfo	member;         /* information regarding parent class/struct */
2393ae02089SMasatake YAMATO 	vString*	parentClasses;  /* parent classes */
2403ae02089SMasatake YAMATO 	struct sStatementInfo *parent;  /* statement we are nested within */
2413ae02089SMasatake YAMATO } statementInfo;
2423ae02089SMasatake YAMATO 
2433ae02089SMasatake YAMATO /*  Describes the type of tag being generated.
2443ae02089SMasatake YAMATO  */
2453ae02089SMasatake YAMATO typedef enum eTagType {
2463ae02089SMasatake YAMATO 	TAG_UNDEFINED,
2473ae02089SMasatake YAMATO 	TAG_CLASS,       /* class name */
2483ae02089SMasatake YAMATO 	TAG_ENUM,        /* enumeration name */
2493ae02089SMasatake YAMATO 	TAG_ENUMERATOR,  /* enumerator (enumeration value) */
2503ae02089SMasatake YAMATO 	TAG_EVENT,       /* event */
2513ae02089SMasatake YAMATO 	TAG_FIELD,       /* field (Java) */
2523ae02089SMasatake YAMATO 	TAG_FUNCTION,    /* function definition */
2533ae02089SMasatake YAMATO 	TAG_INTERFACE,   /* interface declaration */
2543ae02089SMasatake YAMATO 	TAG_LOCAL,       /* local variable definition */
2553ae02089SMasatake YAMATO 	TAG_MEMBER,      /* structure, class or interface member */
2563ae02089SMasatake YAMATO 	TAG_METHOD,      /* method declaration */
2573ae02089SMasatake YAMATO 	TAG_MIXIN, 		 /* D mixin */
2583ae02089SMasatake YAMATO 	TAG_NAMESPACE,   /* namespace name */
2593ae02089SMasatake YAMATO 	TAG_PACKAGE,     /* package name / D module name */
260fddb1356SMasatake YAMATO 	TAG_PACKAGEREF,	 /* referenced package name */
2613ae02089SMasatake YAMATO 	TAG_PROGRAM,     /* program name */
2623ae02089SMasatake YAMATO 	TAG_PROPERTY,    /* property name */
2633ae02089SMasatake YAMATO 	TAG_PROTOTYPE,   /* function prototype or declaration */
26490230484SMasatake YAMATO 	TAG_SIGNAL,	 /* VERA signal name */
2653ae02089SMasatake YAMATO 	TAG_STRUCT,      /* structure name */
2663ae02089SMasatake YAMATO 	TAG_TASK,        /* task name */
2673ae02089SMasatake YAMATO 	TAG_TYPEDEF,     /* typedef name / D alias name */
2683ae02089SMasatake YAMATO 	TAG_TEMPLATE,    /* D template name */
2693ae02089SMasatake YAMATO 	TAG_UNION,       /* union name */
2703ae02089SMasatake YAMATO 	TAG_VARIABLE,    /* variable definition */
2713ae02089SMasatake YAMATO 	TAG_EXTERN_VAR,  /* external variable declaration */
2723ae02089SMasatake YAMATO 	TAG_VERSION, 	 /* conditional template compilation */
2736891b011SMasatake YAMATO 	TAG_LABEL,	 /* goto label */
274682a7f3bSJuan Pablo Civile 	TAG_ANNOTATION,  /* Java annotation definition */
2753ae02089SMasatake YAMATO 	TAG_COUNT        /* must be last */
2763ae02089SMasatake YAMATO } tagType;
2773ae02089SMasatake YAMATO 
2783ae02089SMasatake YAMATO typedef struct sParenInfo {
279ce990805SThomas Braun 	bool isPointer;
280ce990805SThomas Braun 	bool isParamList;
281ce990805SThomas Braun 	bool isKnrParamList;
282ce990805SThomas Braun 	bool isNameCandidate;
283ce990805SThomas Braun 	bool invalidContents;
284ce990805SThomas Braun 	bool nestedArgs;
2853ae02089SMasatake YAMATO 	unsigned int parameterCount;
2863ae02089SMasatake YAMATO } parenInfo;
2873ae02089SMasatake YAMATO 
2883ae02089SMasatake YAMATO /*
2893ae02089SMasatake YAMATO *   DATA DEFINITIONS
2903ae02089SMasatake YAMATO */
2913ae02089SMasatake YAMATO 
2923ae02089SMasatake YAMATO static jmp_buf Exception;
2933ae02089SMasatake YAMATO 
2943ae02089SMasatake YAMATO static langType Lang_c;
2953ae02089SMasatake YAMATO static langType Lang_cpp;
2963ae02089SMasatake YAMATO static langType Lang_csharp;
2973ae02089SMasatake YAMATO static langType Lang_d;
2983ae02089SMasatake YAMATO static langType Lang_java;
2993ae02089SMasatake YAMATO static langType Lang_vera;
3003ae02089SMasatake YAMATO static vString *Signature;
301ce990805SThomas Braun static bool CollectingSignature;
3023ae02089SMasatake YAMATO 
3033ae02089SMasatake YAMATO /* Number used to uniquely identify anonymous structs and unions. */
3043ae02089SMasatake YAMATO static int AnonymousID = 0;
3053ae02089SMasatake YAMATO 
306d34312c4SMasatake YAMATO #define COMMONK_UNDEFINED -1
307d34312c4SMasatake YAMATO 
3083230cfb0SMasatake YAMATO 
3093ae02089SMasatake YAMATO /* Used to index into the CKinds table. */
3103ae02089SMasatake YAMATO typedef enum {
3113230cfb0SMasatake YAMATO 	CR_MACRO_UNDEF,
312d00bddf9SMasatake YAMATO 	CR_MACRO_CONDITION,
3133230cfb0SMasatake YAMATO } cMacroRole;
3143230cfb0SMasatake YAMATO 
31513457258SMasatake YAMATO static roleDefinition CMacroRoles [] = {
3163230cfb0SMasatake YAMATO 	RoleTemplateUndef,
317d00bddf9SMasatake YAMATO 	RoleTemplateCondition,
3183230cfb0SMasatake YAMATO };
3193230cfb0SMasatake YAMATO 
3203230cfb0SMasatake YAMATO typedef enum {
321f64fda3dSMasatake YAMATO 	CR_HEADER_SYSTEM,
322f64fda3dSMasatake YAMATO 	CR_HEADER_LOCAL,
323f64fda3dSMasatake YAMATO } cHeaderRole;
324f64fda3dSMasatake YAMATO 
32513457258SMasatake YAMATO static roleDefinition CHeaderRoles [] = {
326f64fda3dSMasatake YAMATO 	RoleTemplateSystem,
327f64fda3dSMasatake YAMATO 	RoleTemplateLocal,
328f64fda3dSMasatake YAMATO };
329f64fda3dSMasatake YAMATO 
330f64fda3dSMasatake YAMATO typedef enum {
331d34312c4SMasatake YAMATO 	CK_UNDEFINED = COMMONK_UNDEFINED,
3323ae02089SMasatake YAMATO 	CK_CLASS, CK_DEFINE, CK_ENUMERATOR, CK_FUNCTION,
333d26963b2SMasatake YAMATO 	CK_ENUMERATION, CK_HEADER, CK_LOCAL, CK_MEMBER, CK_NAMESPACE, CK_PROTOTYPE,
3343ae02089SMasatake YAMATO 	CK_STRUCT, CK_TYPEDEF, CK_UNION, CK_VARIABLE,
3358e55f288SMasatake YAMATO 	CK_EXTERN_VARIABLE, CK_LABEL, CK_MACRO_PARAM,
3363ae02089SMasatake YAMATO } cKind;
3373ae02089SMasatake YAMATO 
338e112e8abSMasatake YAMATO static kindDefinition CKinds [] = {
339ce990805SThomas Braun 	{ true,  'c', "class",      "classes"},
340ce990805SThomas Braun 	{ true,  'd', "macro",      "macro definitions",
341ce990805SThomas Braun 	  .referenceOnly = false, ATTACH_ROLES(CMacroRoles)},
342ce990805SThomas Braun 	{ true,  'e', "enumerator", "enumerators (values inside an enumeration)"},
343ce990805SThomas Braun 	{ true,  'f', "function",   "function definitions"},
344ce990805SThomas Braun 	{ true,  'g', "enum",       "enumeration names"},
345ce990805SThomas Braun 	{ true,  'h', "header",     "included header files",
346ce990805SThomas Braun 	  .referenceOnly = true,  ATTACH_ROLES(CHeaderRoles)},
347ce990805SThomas Braun 	{ false, 'l', "local",      "local variables"},
348ce990805SThomas Braun 	{ true,  'm', "member",     "class, struct, and union members"},
349ce990805SThomas Braun 	{ true,  'n', "namespace",  "namespaces"},
350ce990805SThomas Braun 	{ false, 'p', "prototype",  "function prototypes"},
351ce990805SThomas Braun 	{ true,  's', "struct",     "structure names"},
352ce990805SThomas Braun 	{ true,  't', "typedef",    "typedefs"},
353ce990805SThomas Braun 	{ true,  'u', "union",      "union names"},
354ce990805SThomas Braun 	{ true,  'v', "variable",   "variable definitions"},
355ce990805SThomas Braun 	{ false, 'x', "externvar",  "external and forward variable declarations"},
356ce990805SThomas Braun 	{ false, 'L', "label",      "goto label"},
3578e55f288SMasatake YAMATO 	{ false, 'D', "macroparam", "cpp macro parameters"},
3583ae02089SMasatake YAMATO };
3593ae02089SMasatake YAMATO 
3603ae02089SMasatake YAMATO typedef enum {
361d34312c4SMasatake YAMATO 	CSK_UNDEFINED = COMMONK_UNDEFINED,
3623ae02089SMasatake YAMATO 	CSK_CLASS, CSK_DEFINE, CSK_ENUMERATOR, CSK_EVENT, CSK_FIELD,
3633ae02089SMasatake YAMATO 	CSK_ENUMERATION, CSK_INTERFACE, CSK_LOCAL, CSK_METHOD,
3643ae02089SMasatake YAMATO 	CSK_NAMESPACE, CSK_PROPERTY, CSK_STRUCT, CSK_TYPEDEF
3653ae02089SMasatake YAMATO } csharpKind;
3663ae02089SMasatake YAMATO 
367e112e8abSMasatake YAMATO static kindDefinition CsharpKinds [] = {
368ce990805SThomas Braun 	{ true,  'c', "class",      "classes"},
369ce990805SThomas Braun 	{ true,  'd', "macro",      "macro definitions"},
370ce990805SThomas Braun 	{ true,  'e', "enumerator", "enumerators (values inside an enumeration)"},
371ce990805SThomas Braun 	{ true,  'E', "event",      "events"},
372ce990805SThomas Braun 	{ true,  'f', "field",      "fields"},
373ce990805SThomas Braun 	{ true,  'g', "enum",       "enumeration names"},
374ce990805SThomas Braun 	{ true,  'i', "interface",  "interfaces"},
375ce990805SThomas Braun 	{ false, 'l', "local",      "local variables"},
376ce990805SThomas Braun 	{ true,  'm', "method",     "methods"},
377ce990805SThomas Braun 	{ true,  'n', "namespace",  "namespaces"},
378ce990805SThomas Braun 	{ true,  'p', "property",   "properties"},
379ce990805SThomas Braun 	{ true,  's', "struct",     "structure names"},
380ce990805SThomas Braun 	{ true,  't', "typedef",    "typedefs"},
3813ae02089SMasatake YAMATO };
3823ae02089SMasatake YAMATO 
3833ae02089SMasatake YAMATO typedef enum
3843ae02089SMasatake YAMATO {
385d34312c4SMasatake YAMATO 	DK_UNDEFINED = COMMONK_UNDEFINED,
3863ae02089SMasatake YAMATO 	DK_ALIAS, DK_CLASS, DK_ENUMERATION, DK_ENUMERATOR, DK_EXTERN_VARIABLE, DK_FUNCTION,
3873ae02089SMasatake YAMATO 	DK_INTERFACE, DK_LOCAL, DK_MEMBER, DK_MIXIN, DK_MODULE, DK_NAMESPACE,
3883ae02089SMasatake YAMATO 	DK_PROTOTYPE, DK_STRUCT, DK_TEMPLATE, DK_UNION,
3893ae02089SMasatake YAMATO 	DK_VARIABLE, DK_VERSION
3903ae02089SMasatake YAMATO } dKind;
3913ae02089SMasatake YAMATO 
392e112e8abSMasatake YAMATO static kindDefinition DKinds [] = {
393ce990805SThomas Braun 	{ true,  'a', "alias",      "aliases"},
394ce990805SThomas Braun 	{ true,  'c', "class",      "classes"},
395ce990805SThomas Braun 	{ true,  'g', "enum",       "enumeration names"},
396ce990805SThomas Braun 	{ true,  'e', "enumerator", "enumerators (values inside an enumeration)"},
397ce990805SThomas Braun 	{ false, 'x', "externvar",  "external variable declarations"},
398ce990805SThomas Braun 	{ true,  'f', "function",   "function definitions"},
399ce990805SThomas Braun 	{ true,  'i', "interface",  "interfaces"},
400ce990805SThomas Braun 	{ false, 'l', "local",      "local variables"},
401ce990805SThomas Braun 	{ true,  'm', "member",     "class, struct, and union members"},
402ce990805SThomas Braun 	{ true,  'X', "mixin",      "mixins"},
403ce990805SThomas Braun 	{ true,  'M', "module",     "modules"},
404ce990805SThomas Braun 	{ true,  'n', "namespace",  "namespaces"},
405ce990805SThomas Braun 	{ false, 'p', "prototype",  "function prototypes"},
406ce990805SThomas Braun 	{ true,  's', "struct",     "structure names"},
407ce990805SThomas Braun 	{ true,  'T', "template",   "templates"},
408ce990805SThomas Braun 	{ true,  'u', "union",      "union names"},
409ce990805SThomas Braun 	{ true,  'v', "variable",   "variable definitions"},
410ce990805SThomas Braun 	{ true,  'V', "version",    "version statements"}
4113ae02089SMasatake YAMATO };
4123ae02089SMasatake YAMATO 
4133ae02089SMasatake YAMATO /* Used to index into the JavaKinds table. */
4143ae02089SMasatake YAMATO typedef enum {
415fddb1356SMasatake YAMATO 	JAVAR_PACKAGE_IMPORTED,
416fddb1356SMasatake YAMATO } javaPackageRole;
417fddb1356SMasatake YAMATO 
41813457258SMasatake YAMATO static roleDefinition JavaPackageRoles [] = {
419ce990805SThomas Braun 	{ true, "imported", "imported package"},
420fddb1356SMasatake YAMATO };
421fddb1356SMasatake YAMATO 
422fddb1356SMasatake YAMATO typedef enum {
423d34312c4SMasatake YAMATO 	JK_UNDEFINED = COMMONK_UNDEFINED,
4246b61e611SMasatake YAMATO 	JK_ANNOTATION, JK_CLASS, JK_ENUM_CONSTANT, JK_FIELD, JK_ENUM, JK_INTERFACE,
4253ae02089SMasatake YAMATO 	JK_LOCAL, JK_METHOD, JK_PACKAGE, JK_ACCESS, JK_CLASS_PREFIX
4263ae02089SMasatake YAMATO } javaKind;
4273ae02089SMasatake YAMATO 
428e112e8abSMasatake YAMATO static kindDefinition JavaKinds [] = {
429ce990805SThomas Braun 	{ true,  'a', "annotation",    "annotation declarations" },
430ce990805SThomas Braun 	{ true,  'c', "class",         "classes"},
431ce990805SThomas Braun 	{ true,  'e', "enumConstant",  "enum constants"},
432ce990805SThomas Braun 	{ true,  'f', "field",         "fields"},
433ce990805SThomas Braun 	{ true,  'g', "enum",          "enum types"},
434ce990805SThomas Braun 	{ true,  'i', "interface",     "interfaces"},
435ce990805SThomas Braun 	{ false, 'l', "local",         "local variables"},
436ce990805SThomas Braun 	{ true,  'm', "method",        "methods"},
437ce990805SThomas Braun 	{ true,  'p', "package",       "packages",
438ce990805SThomas Braun 	  .referenceOnly = false, ATTACH_ROLES(JavaPackageRoles)},
4393ae02089SMasatake YAMATO };
4403ae02089SMasatake YAMATO 
4413ae02089SMasatake YAMATO /* Used to index into the VeraKinds table. */
4423ae02089SMasatake YAMATO typedef enum {
4433230cfb0SMasatake YAMATO 	VR_MACRO_UNDEF,
444d00bddf9SMasatake YAMATO 	VR_MACRO_CONDITION,
4453230cfb0SMasatake YAMATO } veraMacroRole;
4463230cfb0SMasatake YAMATO 
44713457258SMasatake YAMATO static roleDefinition VeraMacroRoles [] = {
4483230cfb0SMasatake YAMATO 	RoleTemplateUndef,
449d00bddf9SMasatake YAMATO 	RoleTemplateCondition,
4503230cfb0SMasatake YAMATO };
4513230cfb0SMasatake YAMATO 
452f64fda3dSMasatake YAMATO 
453f64fda3dSMasatake YAMATO typedef enum {
454f64fda3dSMasatake YAMATO 	VR_HEADER_SYSTEM,
455f64fda3dSMasatake YAMATO 	VR_HEADER_LOCAL,
456f64fda3dSMasatake YAMATO } veraHeaderRole;
457f64fda3dSMasatake YAMATO 
45813457258SMasatake YAMATO static roleDefinition VeraHeaderRoles [] = {
459f64fda3dSMasatake YAMATO 	RoleTemplateSystem,
460f64fda3dSMasatake YAMATO 	RoleTemplateLocal,
461f64fda3dSMasatake YAMATO };
462f64fda3dSMasatake YAMATO 
4633230cfb0SMasatake YAMATO typedef enum {
464d34312c4SMasatake YAMATO 	VK_UNDEFINED = COMMONK_UNDEFINED,
4653ae02089SMasatake YAMATO 	VK_CLASS, VK_DEFINE, VK_ENUMERATOR, VK_FUNCTION,
46690230484SMasatake YAMATO 	VK_ENUMERATION, VK_INTERFACE, VK_LOCAL, VK_MEMBER, VK_PROGRAM, VK_PROTOTYPE,
46790230484SMasatake YAMATO 	VK_SIGNAL, VK_TASK, VK_TYPEDEF, VK_VARIABLE,
4688e55f288SMasatake YAMATO 	VK_EXTERN_VARIABLE, VK_HEADER, VK_MACRO_PARAM,
4693ae02089SMasatake YAMATO } veraKind;
4703ae02089SMasatake YAMATO 
471e112e8abSMasatake YAMATO static kindDefinition VeraKinds [] = {
472ce990805SThomas Braun 	{ true,  'c', "class",      "classes"},
473ce990805SThomas Braun 	{ true,  'd', "macro",      "macro definitions",
474ce990805SThomas Braun 	  .referenceOnly = false, ATTACH_ROLES(VeraMacroRoles)},
475ce990805SThomas Braun 	{ true,  'e', "enumerator", "enumerators (values inside an enumeration)"},
476ce990805SThomas Braun 	{ true,  'f', "function",   "function definitions"},
477ce990805SThomas Braun 	{ true,  'g', "enum",       "enumeration names"},
478ce990805SThomas Braun 	{ true,  'i', "interface",  "interfaces"},
479ce990805SThomas Braun 	{ false, 'l', "local",      "local variables"},
480ce990805SThomas Braun 	{ true,  'm', "member",     "class, struct, and union members"},
481ce990805SThomas Braun 	{ true,  'p', "program",    "programs"},
482ce990805SThomas Braun 	{ false, 'P', "prototype",  "function prototypes"},
483ce990805SThomas Braun 	{ true,  's', "signal",     "signals"},
484ce990805SThomas Braun 	{ true,  't', "task",       "tasks"},
485ce990805SThomas Braun 	{ true,  'T', "typedef",    "typedefs"},
486ce990805SThomas Braun 	{ true,  'v', "variable",   "variable definitions"},
487ce990805SThomas Braun 	{ false, 'x', "externvar",  "external variable declarations"},
488ce990805SThomas Braun 	{ true,  'h', "header",     "included header files",
489ce990805SThomas Braun 	  .referenceOnly = true, ATTACH_ROLES(VeraHeaderRoles)},
4908e55f288SMasatake YAMATO 	{ false, 'D', "macroParameter", "cpp macro parameters"},
4913ae02089SMasatake YAMATO };
4923ae02089SMasatake YAMATO 
4933ae02089SMasatake YAMATO static const keywordDesc KeywordTable [] = {
4943ae02089SMasatake YAMATO      /*                                                C++    D          */
4953ae02089SMasatake YAMATO      /*                                         ANSI C  |  C# | Java     */
4963ae02089SMasatake YAMATO      /*                                              |  |  |  |  |  Vera */
4973ae02089SMasatake YAMATO      /* keyword           keyword ID                 |  |  |  |  |  |    */
4983ae02089SMasatake YAMATO      { "__attribute__",   KEYWORD_ATTRIBUTE,       { 1, 1, 1, 1, 0, 0 } },
4993ae02089SMasatake YAMATO      { "abstract",        KEYWORD_ABSTRACT,        { 0, 0, 1, 1, 1, 0 } },
5003ae02089SMasatake YAMATO      { "alias",           KEYWORD_ALIAS,           { 0, 0, 0, 1, 0, 0 } },
5013ae02089SMasatake YAMATO      { "align",           KEYWORD_ALIGN,           { 0, 0, 0, 1, 0, 0 } },
5023ae02089SMasatake YAMATO      { "asm",             KEYWORD_ASM,             { 0, 0, 0, 1, 0, 0 } },
5033ae02089SMasatake YAMATO      { "assert",          KEYWORD_ASSERT,          { 0, 0, 0, 1, 0, 0 } },
5043ae02089SMasatake YAMATO      { "auto",            KEYWORD_AUTO,            { 0, 0, 0, 1, 0, 0 } },
5053ae02089SMasatake YAMATO      { "bad_state",       KEYWORD_BAD_STATE,       { 0, 0, 0, 0, 0, 1 } },
5063ae02089SMasatake YAMATO      { "bad_trans",       KEYWORD_BAD_TRANS,       { 0, 0, 0, 0, 0, 1 } },
5073ae02089SMasatake YAMATO      { "bind",            KEYWORD_BIND,            { 0, 0, 0, 0, 0, 1 } },
5083ae02089SMasatake YAMATO      { "bind_var",        KEYWORD_BIND_VAR,        { 0, 0, 0, 0, 0, 1 } },
5093ae02089SMasatake YAMATO      { "bit",             KEYWORD_BIT,             { 0, 0, 0, 0, 0, 1 } },
5103ae02089SMasatake YAMATO      { "body",            KEYWORD_BODY,            { 0, 0, 0, 1, 0, 0 } },
5113ae02089SMasatake YAMATO      { "bool",            KEYWORD_BOOL,            { 0, 0, 0, 1, 0, 0 } },
51243630fd5SMasatake YAMATO      { "boolean",         KEYWORD_BOOLEAN,         { 0, 0, 0, 0, 1, 0 } },
5133ae02089SMasatake YAMATO      { "break",           KEYWORD_BREAK,           { 0, 0, 0, 1, 0, 0 } },
5143ae02089SMasatake YAMATO      { "byte",            KEYWORD_BYTE,            { 0, 0, 0, 1, 1, 0 } },
5153ae02089SMasatake YAMATO      { "case",            KEYWORD_CASE,            { 1, 1, 1, 1, 1, 0 } },
5163ae02089SMasatake YAMATO      { "cast",            KEYWORD_CAST,            { 0, 0, 0, 1, 0, 0 } },
5179aba9d08SMasatake YAMATO      { "catch",           KEYWORD_CATCH,           { 0, 1, 1, 1, 1, 0 } },
5183ae02089SMasatake YAMATO      { "cdouble",         KEYWORD_CDOUBLE,         { 0, 0, 0, 1, 0, 0 } },
5193ae02089SMasatake YAMATO      { "cent",            KEYWORD_CENT,            { 0, 0, 0, 1, 0, 0 } },
5203ae02089SMasatake YAMATO      { "cfloat",          KEYWORD_CFLOAT,          { 0, 0, 0, 1, 0, 0 } },
5213ae02089SMasatake YAMATO      { "char",            KEYWORD_CHAR,            { 1, 1, 1, 1, 1, 0 } },
5223ae02089SMasatake YAMATO      { "class",           KEYWORD_CLASS,           { 0, 1, 1, 1, 1, 1 } },
52390230484SMasatake YAMATO      { "CLOCK",           KEYWORD_CLOCK,           { 0, 0, 0, 0, 0, 1 } },
5243ae02089SMasatake YAMATO      { "const",           KEYWORD_CONST,           { 1, 1, 1, 1, 1, 0 } },
5253ae02089SMasatake YAMATO      { "constraint",      KEYWORD_CONSTRAINT,      { 0, 0, 0, 0, 0, 1 } },
5263ae02089SMasatake YAMATO      { "continue",        KEYWORD_CONTINUE,        { 0, 0, 0, 1, 0, 0 } },
5273ae02089SMasatake YAMATO      { "coverage_block",  KEYWORD_COVERAGE_BLOCK,  { 0, 0, 0, 0, 0, 1 } },
5283ae02089SMasatake YAMATO      { "coverage_def",    KEYWORD_COVERAGE_DEF,    { 0, 0, 0, 0, 0, 1 } },
5293ae02089SMasatake YAMATO      { "creal",           KEYWORD_CREAL,           { 0, 0, 0, 1, 0, 0 } },
5303ae02089SMasatake YAMATO      { "dchar",           KEYWORD_DCHAR,           { 0, 0, 0, 1, 0, 0 } },
5313ae02089SMasatake YAMATO      { "debug",           KEYWORD_DEBUG,           { 0, 0, 0, 1, 0, 0 } },
5323ae02089SMasatake YAMATO      { "default",         KEYWORD_DEFAULT,         { 1, 1, 1, 1, 1, 0 } },
5333ae02089SMasatake YAMATO      { "delegate",        KEYWORD_DELEGATE,        { 0, 0, 1, 1, 0, 0 } },
5343ae02089SMasatake YAMATO      { "delete",          KEYWORD_DELETE,          { 0, 1, 0, 1, 0, 0 } },
5353ae02089SMasatake YAMATO      { "deprecated",      KEYWORD_DEPRECATED,      { 0, 0, 0, 1, 0, 0 } },
5363ae02089SMasatake YAMATO      { "do",              KEYWORD_DO,              { 1, 1, 1, 1, 1, 0 } },
5373ae02089SMasatake YAMATO      { "double",          KEYWORD_DOUBLE,          { 1, 1, 1, 1, 1, 0 } },
5383ae02089SMasatake YAMATO      { "else",            KEYWORD_ELSE,            { 1, 1, 1, 1, 1, 0 } },
5393ae02089SMasatake YAMATO      { "enum",            KEYWORD_ENUM,            { 1, 1, 1, 1, 1, 1 } },
5403ae02089SMasatake YAMATO      { "event",           KEYWORD_EVENT,           { 0, 0, 1, 0, 0, 1 } },
5413ae02089SMasatake YAMATO      { "explicit",        KEYWORD_EXPLICIT,        { 0, 1, 1, 1, 0, 0 } },
5423ae02089SMasatake YAMATO      { "export",          KEYWORD_EXPORT,          { 0, 0, 0, 1, 0, 0 } },
5433ae02089SMasatake YAMATO      { "extends",         KEYWORD_EXTENDS,         { 0, 0, 0, 0, 1, 1 } },
5443ae02089SMasatake YAMATO      { "extern",          KEYWORD_EXTERN,          { 1, 1, 1, 1, 0, 1 } },
5453ae02089SMasatake YAMATO      { "false",           KEYWORD_FALSE,           { 0, 0, 0, 1, 0, 0 } },
5463ae02089SMasatake YAMATO      { "final",           KEYWORD_FINAL,           { 0, 0, 0, 1, 1, 0 } },
5473ae02089SMasatake YAMATO      { "finally",         KEYWORD_FINALLY,         { 0, 0, 0, 1, 0, 0 } },
5483ae02089SMasatake YAMATO      { "float",           KEYWORD_FLOAT,           { 1, 1, 1, 1, 1, 0 } },
5493ae02089SMasatake YAMATO      { "for",             KEYWORD_FOR,             { 1, 1, 1, 1, 1, 0 } },
5503ae02089SMasatake YAMATO      { "foreach",         KEYWORD_FOREACH,         { 0, 0, 1, 1, 0, 0 } },
5513ae02089SMasatake YAMATO      { "foreach_reverse", KEYWORD_FOREACH_REVERSE, { 0, 0, 0, 1, 0, 0 } },
5523ae02089SMasatake YAMATO      { "friend",          KEYWORD_FRIEND,          { 0, 1, 0, 1, 0, 0 } },
5533ae02089SMasatake YAMATO      { "function",        KEYWORD_FUNCTION,        { 0, 0, 0, 1, 0, 1 } },
5543ae02089SMasatake YAMATO      { "goto",            KEYWORD_GOTO,            { 1, 1, 1, 1, 1, 0 } },
55590230484SMasatake YAMATO      { "hdl_node",        KEYWORD_HDL_NODE,        { 0, 0, 0, 0, 0, 1 } },
5563ae02089SMasatake YAMATO      { "idouble",         KEYWORD_IDOUBLE,         { 0, 0, 0, 1, 0, 0 } },
5573ae02089SMasatake YAMATO      { "if",              KEYWORD_IF,              { 1, 1, 1, 1, 1, 0 } },
5583ae02089SMasatake YAMATO      { "ifloat",          KEYWORD_IFLOAT,          { 0, 0, 0, 1, 0, 0 } },
5593ae02089SMasatake YAMATO      { "implements",      KEYWORD_IMPLEMENTS,      { 0, 0, 0, 0, 1, 0 } },
5603ae02089SMasatake YAMATO      { "import",          KEYWORD_IMPORT,          { 0, 0, 0, 1, 1, 0 } },
5613ae02089SMasatake YAMATO      { "in",              KEYWORD_IN,              { 0, 0, 0, 1, 0, 0 } },
5623ae02089SMasatake YAMATO      { "inline",          KEYWORD_INLINE,          { 0, 1, 0, 1, 0, 0 } },
5633ae02089SMasatake YAMATO      { "inout",           KEYWORD_INOUT,           { 0, 0, 0, 1, 0, 1 } },
5643ae02089SMasatake YAMATO      { "input",           KEYWORD_INPUT,           { 0, 0, 0, 0, 0, 1 } },
5653ae02089SMasatake YAMATO      { "int",             KEYWORD_INT,             { 1, 1, 1, 1, 1, 0 } },
5663ae02089SMasatake YAMATO      { "integer",         KEYWORD_INTEGER,         { 0, 0, 0, 0, 0, 1 } },
5673ae02089SMasatake YAMATO      { "interface",       KEYWORD_INTERFACE,       { 0, 0, 1, 1, 1, 1 } },
5683ae02089SMasatake YAMATO      { "internal",        KEYWORD_INTERNAL,        { 0, 0, 1, 0, 0, 0 } },
5693ae02089SMasatake YAMATO      { "invariant",       KEYWORD_INVARIANT,       { 0, 0, 0, 1, 0, 0 } },
5703ae02089SMasatake YAMATO      { "ireal",           KEYWORD_IREAL,           { 0, 0, 0, 1, 0, 0 } },
5713ae02089SMasatake YAMATO      { "is",              KEYWORD_IS,              { 0, 0, 0, 1, 0, 0 } },
5723ae02089SMasatake YAMATO      { "lazy",            KEYWORD_LAZY,            { 0, 0, 0, 1, 0, 0 } },
5733ae02089SMasatake YAMATO      { "local",           KEYWORD_LOCAL,           { 0, 0, 0, 0, 0, 1 } },
5743ae02089SMasatake YAMATO      { "long",            KEYWORD_LONG,            { 1, 1, 1, 1, 1, 0 } },
5753ae02089SMasatake YAMATO      { "m_bad_state",     KEYWORD_M_BAD_STATE,     { 0, 0, 0, 0, 0, 1 } },
5763ae02089SMasatake YAMATO      { "m_bad_trans",     KEYWORD_M_BAD_TRANS,     { 0, 0, 0, 0, 0, 1 } },
5773ae02089SMasatake YAMATO      { "m_state",         KEYWORD_M_STATE,         { 0, 0, 0, 0, 0, 1 } },
5783ae02089SMasatake YAMATO      { "m_trans",         KEYWORD_M_TRANS,         { 0, 0, 0, 0, 0, 1 } },
5793ae02089SMasatake YAMATO      { "mixin",           KEYWORD_MIXIN,           { 0, 0, 0, 1, 0, 0 } },
5803ae02089SMasatake YAMATO      { "module",          KEYWORD_MODULE,          { 0, 0, 0, 1, 0, 0 } },
5813ae02089SMasatake YAMATO      { "mutable",         KEYWORD_MUTABLE,         { 0, 1, 0, 1, 0, 0 } },
5823ae02089SMasatake YAMATO      { "namespace",       KEYWORD_NAMESPACE,       { 0, 1, 1, 1, 0, 0 } },
5833ae02089SMasatake YAMATO      { "native",          KEYWORD_NATIVE,          { 0, 0, 0, 0, 1, 0 } },
5843ae02089SMasatake YAMATO      { "new",             KEYWORD_NEW,             { 0, 1, 1, 1, 1, 0 } },
5853ae02089SMasatake YAMATO      { "newcov",          KEYWORD_NEWCOV,          { 0, 0, 0, 0, 0, 1 } },
58690230484SMasatake YAMATO      { "NHOLD",           KEYWORD_NHOLD,           { 0, 0, 0, 0, 0, 1 } },
58701aa0161SColomban Wendling      { "noexcept",        KEYWORD_NOEXCEPT,        { 0, 1, 0, 0, 0, 0 } },
58890230484SMasatake YAMATO      { "NSAMPLE",         KEYWORD_NSAMPLE,         { 0, 0, 0, 0, 0, 1 } },
5893ae02089SMasatake YAMATO      { "null",            KEYWORD_NULL,            { 0, 0, 0, 1, 0, 0 } },
5903ae02089SMasatake YAMATO      { "operator",        KEYWORD_OPERATOR,        { 0, 1, 1, 1, 0, 0 } },
5913ae02089SMasatake YAMATO      { "out",             KEYWORD_OUT,             { 0, 0, 0, 1, 0, 0 } },
5923ae02089SMasatake YAMATO      { "output",          KEYWORD_OUTPUT,          { 0, 0, 0, 0, 0, 1 } },
5933ae02089SMasatake YAMATO      { "overload",        KEYWORD_OVERLOAD,        { 0, 1, 0, 1, 0, 0 } },
5943ae02089SMasatake YAMATO      { "override",        KEYWORD_OVERRIDE,        { 0, 0, 1, 1, 0, 0 } },
5953ae02089SMasatake YAMATO      { "package",         KEYWORD_PACKAGE,         { 0, 0, 0, 1, 1, 0 } },
5963ae02089SMasatake YAMATO      { "packed",          KEYWORD_PACKED,          { 0, 0, 0, 0, 0, 1 } },
59790230484SMasatake YAMATO      { "PHOLD",           KEYWORD_PHOLD,           { 0, 0, 0, 0, 0, 1 } },
5983ae02089SMasatake YAMATO      { "port",            KEYWORD_PORT,            { 0, 0, 0, 0, 0, 1 } },
5993ae02089SMasatake YAMATO      { "pragma",          KEYWORD_PRAGMA,          { 0, 0, 0, 1, 0, 0 } },
6003ae02089SMasatake YAMATO      { "private",         KEYWORD_PRIVATE,         { 0, 1, 1, 1, 1, 0 } },
6013ae02089SMasatake YAMATO      { "program",         KEYWORD_PROGRAM,         { 0, 0, 0, 0, 0, 1 } },
6023ae02089SMasatake YAMATO      { "protected",       KEYWORD_PROTECTED,       { 0, 1, 1, 1, 1, 1 } },
60390230484SMasatake YAMATO      { "PSAMPLE",         KEYWORD_PSAMPLE,         { 0, 0, 0, 0, 0, 1 } },
6043ae02089SMasatake YAMATO      { "public",          KEYWORD_PUBLIC,          { 0, 1, 1, 1, 1, 1 } },
6053ae02089SMasatake YAMATO      { "real",            KEYWORD_REAL,            { 0, 0, 0, 1, 0, 0 } },
6063ae02089SMasatake YAMATO      { "register",        KEYWORD_REGISTER,        { 1, 1, 0, 1, 0, 0 } },
6073ae02089SMasatake YAMATO      { "return",          KEYWORD_RETURN,          { 1, 1, 1, 1, 1, 0 } },
6083ae02089SMasatake YAMATO      { "scope",           KEYWORD_SCOPE,           { 0, 0, 0, 1, 0, 0 } },
6093ae02089SMasatake YAMATO      { "shadow",          KEYWORD_SHADOW,          { 0, 0, 0, 0, 0, 1 } },
6103ae02089SMasatake YAMATO      { "short",           KEYWORD_SHORT,           { 1, 1, 1, 1, 1, 0 } },
6113ae02089SMasatake YAMATO      { "signed",          KEYWORD_SIGNED,          { 1, 1, 0, 1, 0, 0 } },
6123ae02089SMasatake YAMATO      { "state",           KEYWORD_STATE,           { 0, 0, 0, 0, 0, 1 } },
6133ae02089SMasatake YAMATO      { "static",          KEYWORD_STATIC,          { 1, 1, 1, 1, 1, 1 } },
6143ae02089SMasatake YAMATO      { "string",          KEYWORD_STRING,          { 0, 0, 1, 0, 0, 1 } },
6153ae02089SMasatake YAMATO      { "struct",          KEYWORD_STRUCT,          { 1, 1, 1, 1, 0, 0 } },
6163ae02089SMasatake YAMATO      { "super",           KEYWORD_SUPER,           { 0, 0, 0, 1, 0, 0 } },
6173ae02089SMasatake YAMATO      { "switch",          KEYWORD_SWITCH,          { 1, 1, 1, 1, 1, 0 } },
6183ae02089SMasatake YAMATO      { "synchronized",    KEYWORD_SYNCHRONIZED,    { 0, 0, 0, 1, 1, 0 } },
6193ae02089SMasatake YAMATO      { "task",            KEYWORD_TASK,            { 0, 0, 0, 0, 0, 1 } },
6203ae02089SMasatake YAMATO      { "template",        KEYWORD_TEMPLATE,        { 0, 1, 0, 1, 0, 0 } },
6213ae02089SMasatake YAMATO      { "this",            KEYWORD_THIS,            { 0, 1, 1, 0, 1, 0 } },
6223ae02089SMasatake YAMATO      { "throw",           KEYWORD_THROW,           { 0, 1, 1, 1, 1, 0 } },
6233ae02089SMasatake YAMATO      { "throws",          KEYWORD_THROWS,          { 0, 0, 0, 0, 1, 0 } },
6243ae02089SMasatake YAMATO      { "trans",           KEYWORD_TRANS,           { 0, 0, 0, 0, 0, 1 } },
6253ae02089SMasatake YAMATO      { "transient",       KEYWORD_TRANSIENT,       { 0, 0, 0, 0, 1, 0 } },
6263ae02089SMasatake YAMATO      { "transition",      KEYWORD_TRANSITION,      { 0, 0, 0, 0, 0, 1 } },
6273ae02089SMasatake YAMATO      { "true",            KEYWORD_TRUE,            { 0, 0, 0, 1, 0, 0 } },
6283ae02089SMasatake YAMATO      { "try",             KEYWORD_TRY,             { 0, 1, 1, 1, 0, 0 } },
6293ae02089SMasatake YAMATO      { "typedef",         KEYWORD_TYPEDEF,         { 1, 1, 1, 1, 0, 1 } },
6303ae02089SMasatake YAMATO      { "typeid",          KEYWORD_TYPEID,          { 0, 0, 0, 1, 0, 0 } },
6313ae02089SMasatake YAMATO      { "typename",        KEYWORD_TYPENAME,        { 0, 1, 0, 1, 0, 0 } },
6323ae02089SMasatake YAMATO      { "typeof",          KEYWORD_TYPEOF,          { 0, 0, 0, 1, 0, 0 } },
6333ae02089SMasatake YAMATO      { "ubyte",           KEYWORD_UBYTE,           { 0, 0, 0, 1, 0, 0 } },
6343ae02089SMasatake YAMATO      { "ucent",           KEYWORD_UCENT,           { 0, 0, 0, 1, 0, 0 } },
6353ae02089SMasatake YAMATO      { "uint",            KEYWORD_UINT,            { 0, 0, 1, 1, 0, 0 } },
6363ae02089SMasatake YAMATO      { "ulong",           KEYWORD_ULONG,           { 0, 0, 1, 1, 0, 0 } },
6373ae02089SMasatake YAMATO      { "union",           KEYWORD_UNION,           { 1, 1, 0, 1, 0, 0 } },
6383ae02089SMasatake YAMATO      { "unittest",        KEYWORD_UNITTEST,        { 0, 0, 0, 1, 0, 0 } },
6393ae02089SMasatake YAMATO      { "unsigned",        KEYWORD_UNSIGNED,        { 1, 1, 1, 1, 0, 0 } },
6403ae02089SMasatake YAMATO      { "ushort",          KEYWORD_USHORT,          { 0, 0, 1, 1, 0, 0 } },
6413ae02089SMasatake YAMATO      { "using",           KEYWORD_USING,           { 0, 1, 1, 1, 0, 0 } },
6423ae02089SMasatake YAMATO      { "version",         KEYWORD_VERSION,         { 0, 0, 0, 1, 0, 0 } },
6433ae02089SMasatake YAMATO      { "virtual",         KEYWORD_VIRTUAL,         { 0, 1, 1, 1, 0, 1 } },
6443ae02089SMasatake YAMATO      { "void",            KEYWORD_VOID,            { 1, 1, 1, 1, 1, 1 } },
6453ae02089SMasatake YAMATO      { "volatile",        KEYWORD_VOLATILE,        { 1, 1, 1, 1, 1, 0 } },
6463ae02089SMasatake YAMATO      { "wchar",           KEYWORD_WCHAR,           { 0, 0, 0, 1, 0, 0 } },
6473ae02089SMasatake YAMATO      { "wchar_t",         KEYWORD_WCHAR_T,         { 0, 1, 1, 0, 0, 0 } },
6483ae02089SMasatake YAMATO      { "while",           KEYWORD_WHILE,           { 1, 1, 1, 1, 1, 0 } },
6493ae02089SMasatake YAMATO      { "with",            KEYWORD_WITH,            { 0, 0, 0, 1, 0, 0 } },
6503ae02089SMasatake YAMATO };
6513ae02089SMasatake YAMATO 
6523ae02089SMasatake YAMATO /*
6533ae02089SMasatake YAMATO *   FUNCTION PROTOTYPES
6543ae02089SMasatake YAMATO */
6553ae02089SMasatake YAMATO static void createTags (const unsigned int nestLevel, statementInfo *const parent);
6563ae02089SMasatake YAMATO 
6573ae02089SMasatake YAMATO /*
6583ae02089SMasatake YAMATO *   FUNCTION DEFINITIONS
6593ae02089SMasatake YAMATO */
6603ae02089SMasatake YAMATO 
6613ae02089SMasatake YAMATO /*
6623ae02089SMasatake YAMATO *   Token management
6633ae02089SMasatake YAMATO */
6643ae02089SMasatake YAMATO 
initToken(tokenInfo * const token)6653ae02089SMasatake YAMATO static void initToken (tokenInfo* const token)
6663ae02089SMasatake YAMATO {
6673ae02089SMasatake YAMATO 	token->type			= TOKEN_NONE;
6683ae02089SMasatake YAMATO 	token->keyword		= KEYWORD_NONE;
669a31b37dcSMasatake YAMATO 	token->lineNumber	= getInputLineNumber ();
6703ae02089SMasatake YAMATO 	token->filePosition	= getInputFilePosition ();
6713ae02089SMasatake YAMATO 	vStringClear (token->name);
6723ae02089SMasatake YAMATO }
6733ae02089SMasatake YAMATO 
advanceToken(statementInfo * const st)6743ae02089SMasatake YAMATO static void advanceToken (statementInfo* const st)
6753ae02089SMasatake YAMATO {
6763ae02089SMasatake YAMATO 	if (st->tokenIndex >= (unsigned int) NumTokens - 1)
6773ae02089SMasatake YAMATO 		st->tokenIndex = 0;
6783ae02089SMasatake YAMATO 	else
6793ae02089SMasatake YAMATO 		++st->tokenIndex;
6803ae02089SMasatake YAMATO 	initToken (st->token [st->tokenIndex]);
6813ae02089SMasatake YAMATO }
6823ae02089SMasatake YAMATO 
prevToken(const statementInfo * const st,unsigned int n)6833ae02089SMasatake YAMATO static tokenInfo *prevToken (const statementInfo *const st, unsigned int n)
6843ae02089SMasatake YAMATO {
6853ae02089SMasatake YAMATO 	unsigned int tokenIndex;
6863ae02089SMasatake YAMATO 	unsigned int num = (unsigned int) NumTokens;
6873ae02089SMasatake YAMATO 	Assert (n < num);
6883ae02089SMasatake YAMATO 	tokenIndex = (st->tokenIndex + num - n) % num;
6893ae02089SMasatake YAMATO 	return st->token [tokenIndex];
6903ae02089SMasatake YAMATO }
6913ae02089SMasatake YAMATO 
setToken(statementInfo * const st,const tokenType type)6923ae02089SMasatake YAMATO static void setToken (statementInfo *const st, const tokenType type)
6933ae02089SMasatake YAMATO {
6943ae02089SMasatake YAMATO 	tokenInfo *token;
6953ae02089SMasatake YAMATO 	token = activeToken (st);
6963ae02089SMasatake YAMATO 	initToken (token);
6973ae02089SMasatake YAMATO 	token->type = type;
6983ae02089SMasatake YAMATO }
6993ae02089SMasatake YAMATO 
retardToken(statementInfo * const st)7003ae02089SMasatake YAMATO static void retardToken (statementInfo *const st)
7013ae02089SMasatake YAMATO {
7023ae02089SMasatake YAMATO 	if (st->tokenIndex == 0)
7033ae02089SMasatake YAMATO 		st->tokenIndex = (unsigned int) NumTokens - 1;
7043ae02089SMasatake YAMATO 	else
7053ae02089SMasatake YAMATO 		--st->tokenIndex;
7063ae02089SMasatake YAMATO 	setToken (st, TOKEN_NONE);
7073ae02089SMasatake YAMATO }
7083ae02089SMasatake YAMATO 
newToken(void)7093ae02089SMasatake YAMATO static tokenInfo *newToken (void)
7103ae02089SMasatake YAMATO {
7113ae02089SMasatake YAMATO 	tokenInfo *const token = xMalloc (1, tokenInfo);
7123ae02089SMasatake YAMATO 	token->name = vStringNew ();
7133ae02089SMasatake YAMATO 	initToken (token);
7143ae02089SMasatake YAMATO 	return token;
7153ae02089SMasatake YAMATO }
7163ae02089SMasatake YAMATO 
deleteToken(tokenInfo * const token)7173ae02089SMasatake YAMATO static void deleteToken (tokenInfo *const token)
7183ae02089SMasatake YAMATO {
7193ae02089SMasatake YAMATO 	if (token != NULL)
7203ae02089SMasatake YAMATO 	{
7213ae02089SMasatake YAMATO 		vStringDelete (token->name);
7223ae02089SMasatake YAMATO 		eFree (token);
7233ae02089SMasatake YAMATO 	}
7243ae02089SMasatake YAMATO }
7253ae02089SMasatake YAMATO 
accessString(const accessType access)7263ae02089SMasatake YAMATO static const char *accessString (const accessType access)
7273ae02089SMasatake YAMATO {
7283ae02089SMasatake YAMATO 	static const char *const names [] = {
7293ae02089SMasatake YAMATO 		"?", "local", "private", "protected", "public", "default"
7303ae02089SMasatake YAMATO 	};
731158a3387SMasatake YAMATO 	Assert (ARRAY_SIZE (names) == ACCESS_COUNT);
7323ae02089SMasatake YAMATO 	Assert ((int) access < ACCESS_COUNT);
7333ae02089SMasatake YAMATO 	return names [(int) access];
7343ae02089SMasatake YAMATO }
7353ae02089SMasatake YAMATO 
implementationString(const impType imp)7363ae02089SMasatake YAMATO static const char *implementationString (const impType imp)
7373ae02089SMasatake YAMATO {
7383ae02089SMasatake YAMATO 	static const char *const names [] ={
7393ae02089SMasatake YAMATO 		"?", "abstract", "virtual", "pure virtual"
7403ae02089SMasatake YAMATO 	};
741158a3387SMasatake YAMATO 	Assert (ARRAY_SIZE (names) == IMP_COUNT);
7423ae02089SMasatake YAMATO 	Assert ((int) imp < IMP_COUNT);
7433ae02089SMasatake YAMATO 	return names [(int) imp];
7443ae02089SMasatake YAMATO }
7453ae02089SMasatake YAMATO 
7463ae02089SMasatake YAMATO /*
7473ae02089SMasatake YAMATO *   Debugging functions
7483ae02089SMasatake YAMATO */
7493ae02089SMasatake YAMATO 
7503ae02089SMasatake YAMATO #ifdef DEBUG
7513ae02089SMasatake YAMATO 
752ce990805SThomas Braun #define boolString(c)   ((c) ? "true" : "false")
7533ae02089SMasatake YAMATO 
tokenString(const tokenType type)7543ae02089SMasatake YAMATO static const char *tokenString (const tokenType type)
7553ae02089SMasatake YAMATO {
7563ae02089SMasatake YAMATO 	static const char *const names [] = {
7573ae02089SMasatake YAMATO 		"none", "args", "}", "{", "colon", "comma", "double colon", "keyword",
7583ae02089SMasatake YAMATO 		"name", "package", "paren-name", "semicolon", "specifier"
7593ae02089SMasatake YAMATO 	};
760158a3387SMasatake YAMATO 	Assert (ARRAY_SIZE (names) == TOKEN_COUNT);
7613ae02089SMasatake YAMATO 	Assert ((int) type < TOKEN_COUNT);
7623ae02089SMasatake YAMATO 	return names [(int) type];
7633ae02089SMasatake YAMATO }
7643ae02089SMasatake YAMATO 
scopeString(const tagScope scope)7653ae02089SMasatake YAMATO static const char *scopeString (const tagScope scope)
7663ae02089SMasatake YAMATO {
7673ae02089SMasatake YAMATO 	static const char *const names [] = {
7683ae02089SMasatake YAMATO 		"global", "static", "extern", "friend", "typedef"
7693ae02089SMasatake YAMATO 	};
770158a3387SMasatake YAMATO 	Assert (ARRAY_SIZE (names) == SCOPE_COUNT);
7713ae02089SMasatake YAMATO 	Assert ((int) scope < SCOPE_COUNT);
7723ae02089SMasatake YAMATO 	return names [(int) scope];
7733ae02089SMasatake YAMATO }
7743ae02089SMasatake YAMATO 
declString(const declType declaration)7753ae02089SMasatake YAMATO static const char *declString (const declType declaration)
7763ae02089SMasatake YAMATO {
7773ae02089SMasatake YAMATO 	static const char *const names [] = {
778682a7f3bSJuan Pablo Civile 		"?", "base", "class", "enum", "event", "function", "function template",
77999634bc3SSzymon Tomasz Stefanek 		"ignore", "interface", "mixin", "namespace", "no mangle", "package", "package ref",
780682a7f3bSJuan Pablo Civile 		"private", "program", "protected", "public", "struct", "task", "template",
781682a7f3bSJuan Pablo Civile 		"union", "using", "version", "annotation"
7823ae02089SMasatake YAMATO 	};
783158a3387SMasatake YAMATO 	Assert (ARRAY_SIZE (names) == DECL_COUNT);
7843ae02089SMasatake YAMATO 	Assert ((int) declaration < DECL_COUNT);
7853ae02089SMasatake YAMATO 	return names [(int) declaration];
7863ae02089SMasatake YAMATO }
7873ae02089SMasatake YAMATO 
keywordString(const keywordId keyword)7883ae02089SMasatake YAMATO static const char *keywordString (const keywordId keyword)
7893ae02089SMasatake YAMATO {
790158a3387SMasatake YAMATO 	const size_t count = ARRAY_SIZE (KeywordTable);
7913ae02089SMasatake YAMATO 	const char *name = "none";
7923ae02089SMasatake YAMATO 	size_t i;
7933ae02089SMasatake YAMATO 	for (i = 0  ;  i < count  ;  ++i)
7943ae02089SMasatake YAMATO 	{
7953ae02089SMasatake YAMATO 		const keywordDesc *p = &KeywordTable [i];
7963ae02089SMasatake YAMATO 		if (p->id == keyword)
7973ae02089SMasatake YAMATO 		{
7983ae02089SMasatake YAMATO 			name = p->name;
7993ae02089SMasatake YAMATO 			break;
8003ae02089SMasatake YAMATO 		}
8013ae02089SMasatake YAMATO 	}
8023ae02089SMasatake YAMATO 	return name;
8033ae02089SMasatake YAMATO }
8043ae02089SMasatake YAMATO 
pt(tokenInfo * const token)8058ccb7ee9SJiří Techet static void CTAGS_ATTR_UNUSED pt (tokenInfo *const token)
8063ae02089SMasatake YAMATO {
8073ae02089SMasatake YAMATO 	if (isType (token, TOKEN_NAME))
8083ae02089SMasatake YAMATO 		printf ("type: %-12s: %-13s   line: %lu\n",
8093ae02089SMasatake YAMATO 			tokenString (token->type), vStringValue (token->name),
8103ae02089SMasatake YAMATO 			token->lineNumber);
8113ae02089SMasatake YAMATO 	else if (isType (token, TOKEN_KEYWORD))
8123ae02089SMasatake YAMATO 		printf ("type: %-12s: %-13s   line: %lu\n",
8133ae02089SMasatake YAMATO 			tokenString (token->type), keywordString (token->keyword),
8143ae02089SMasatake YAMATO 			token->lineNumber);
8153ae02089SMasatake YAMATO 	else
8163ae02089SMasatake YAMATO 		printf ("type: %-12s                  line: %lu\n",
8173ae02089SMasatake YAMATO 			tokenString (token->type), token->lineNumber);
8183ae02089SMasatake YAMATO }
8193ae02089SMasatake YAMATO 
ps(statementInfo * const st)8208ccb7ee9SJiří Techet static void CTAGS_ATTR_UNUSED ps (statementInfo *const st)
8213ae02089SMasatake YAMATO {
822da02f554SMasatake YAMATO #define P	"[%-7u]"
823da02f554SMasatake YAMATO 	static unsigned int id = 0;
8243ae02089SMasatake YAMATO 	unsigned int i;
825da02f554SMasatake YAMATO 	printf (P"scope: %s   decl: %s   gotName: %s   gotParenName: %s\n", id,
8263ae02089SMasatake YAMATO 		scopeString (st->scope), declString (st->declaration),
8273ae02089SMasatake YAMATO 		boolString (st->gotName), boolString (st->gotParenName));
828da02f554SMasatake YAMATO 	printf (P"haveQualifyingName: %s\n", id, boolString (st->haveQualifyingName));
829da02f554SMasatake YAMATO 	printf (P"access: %s   default: %s\n", id, accessString (st->member.access),
8303ae02089SMasatake YAMATO 		accessString (st->member.accessDefault));
831da02f554SMasatake YAMATO 	printf (P"token  : ", id);
8323ae02089SMasatake YAMATO 	pt (activeToken (st));
8333ae02089SMasatake YAMATO 	for (i = 1  ;  i < (unsigned int) NumTokens  ;  ++i)
8343ae02089SMasatake YAMATO 	{
835da02f554SMasatake YAMATO 		printf (P"prev %u : ", id, i);
8363ae02089SMasatake YAMATO 		pt (prevToken (st, i));
8373ae02089SMasatake YAMATO 	}
838da02f554SMasatake YAMATO 	printf (P"context: ", id);
8393ae02089SMasatake YAMATO 	pt (st->context);
840da02f554SMasatake YAMATO 	id++;
841da02f554SMasatake YAMATO #undef P
8423ae02089SMasatake YAMATO }
8433ae02089SMasatake YAMATO 
8443ae02089SMasatake YAMATO #endif
8453ae02089SMasatake YAMATO 
8463ae02089SMasatake YAMATO /*
8473ae02089SMasatake YAMATO *   Statement management
8483ae02089SMasatake YAMATO */
8493ae02089SMasatake YAMATO 
isContextualKeyword(const tokenInfo * const token)850ce990805SThomas Braun static bool isContextualKeyword (const tokenInfo *const token)
8513ae02089SMasatake YAMATO {
852ce990805SThomas Braun 	bool result;
8533ae02089SMasatake YAMATO 	switch (token->keyword)
8543ae02089SMasatake YAMATO 	{
8553ae02089SMasatake YAMATO 		case KEYWORD_CLASS:
8563ae02089SMasatake YAMATO 		case KEYWORD_ENUM:
8573ae02089SMasatake YAMATO 		case KEYWORD_INTERFACE:
8583ae02089SMasatake YAMATO 		case KEYWORD_NAMESPACE:
8593ae02089SMasatake YAMATO 		case KEYWORD_STRUCT:
8603ae02089SMasatake YAMATO 		case KEYWORD_UNION:
8613ae02089SMasatake YAMATO 		case KEYWORD_VERSION:
8623ae02089SMasatake YAMATO 		case KEYWORD_TEMPLATE:
863ce990805SThomas Braun 			result = true;
8643ae02089SMasatake YAMATO 			break;
8653ae02089SMasatake YAMATO 
866ce990805SThomas Braun 		default: result = false; break;
8673ae02089SMasatake YAMATO 	}
8683ae02089SMasatake YAMATO 	return result;
8693ae02089SMasatake YAMATO }
8703ae02089SMasatake YAMATO 
isContextualStatement(const statementInfo * const st)871ce990805SThomas Braun static bool isContextualStatement (const statementInfo *const st)
8723ae02089SMasatake YAMATO {
873ce990805SThomas Braun 	bool result = false;
8743ae02089SMasatake YAMATO 	if (st != NULL) switch (st->declaration)
8753ae02089SMasatake YAMATO 	{
8763ae02089SMasatake YAMATO 		case DECL_CLASS:
8773ae02089SMasatake YAMATO 		case DECL_ENUM:
8783ae02089SMasatake YAMATO 		case DECL_INTERFACE:
8793ae02089SMasatake YAMATO 		case DECL_NAMESPACE:
8803ae02089SMasatake YAMATO 		case DECL_PRIVATE:
8813ae02089SMasatake YAMATO 		case DECL_PROTECTED:
8823ae02089SMasatake YAMATO 		case DECL_PUBLIC:
8833ae02089SMasatake YAMATO 		case DECL_STRUCT:
8843ae02089SMasatake YAMATO 		case DECL_UNION:
8853ae02089SMasatake YAMATO 		case DECL_TEMPLATE:
886682a7f3bSJuan Pablo Civile 		case DECL_ANNOTATION:
887ce990805SThomas Braun 			result = true;
8883ae02089SMasatake YAMATO 			break;
8893ae02089SMasatake YAMATO 
890ce990805SThomas Braun 		default: result = false; break;
8913ae02089SMasatake YAMATO 	}
8923ae02089SMasatake YAMATO 	return result;
8933ae02089SMasatake YAMATO }
8943ae02089SMasatake YAMATO 
isMember(const statementInfo * const st)895ce990805SThomas Braun static bool isMember (const statementInfo *const st)
8963ae02089SMasatake YAMATO {
897ce990805SThomas Braun 	bool result;
8983ae02089SMasatake YAMATO 	if (isType (st->context, TOKEN_NAME))
899ce990805SThomas Braun 		result = true;
9003ae02089SMasatake YAMATO 	else
901ce990805SThomas Braun 		result = (bool)
9023ae02089SMasatake YAMATO 			(st->parent != NULL && isContextualStatement (st->parent));
9033ae02089SMasatake YAMATO 	return result;
9043ae02089SMasatake YAMATO }
9053ae02089SMasatake YAMATO 
initMemberInfo(statementInfo * const st)9063ae02089SMasatake YAMATO static void initMemberInfo (statementInfo *const st)
9073ae02089SMasatake YAMATO {
9083ae02089SMasatake YAMATO 	accessType accessDefault = ACCESS_UNDEFINED;
9093ae02089SMasatake YAMATO 	if (st->parent != NULL) switch (st->parent->declaration)
9103ae02089SMasatake YAMATO 	{
9113ae02089SMasatake YAMATO 		case DECL_PRIVATE:
9123ae02089SMasatake YAMATO 			accessDefault = ACCESS_PRIVATE;
9133ae02089SMasatake YAMATO 			break;
9143ae02089SMasatake YAMATO 		case DECL_PROTECTED:
9153ae02089SMasatake YAMATO 			accessDefault = ACCESS_PROTECTED;
9163ae02089SMasatake YAMATO 			break;
9173ae02089SMasatake YAMATO 		case DECL_PUBLIC:
9183ae02089SMasatake YAMATO 			accessDefault = ACCESS_PUBLIC;
9193ae02089SMasatake YAMATO 			break;
9203ae02089SMasatake YAMATO 		case DECL_ENUM:
9217d90c743SMasatake YAMATO 			accessDefault = (isInputLanguage (Lang_java) ? ACCESS_PUBLIC : ACCESS_UNDEFINED);
9223ae02089SMasatake YAMATO 			break;
9233ae02089SMasatake YAMATO 		case DECL_NAMESPACE:
9243ae02089SMasatake YAMATO 			accessDefault = ACCESS_UNDEFINED;
9253ae02089SMasatake YAMATO 			break;
9263ae02089SMasatake YAMATO 
9273ae02089SMasatake YAMATO 		case DECL_CLASS:
9287d90c743SMasatake YAMATO 			if (isInputLanguage (Lang_java))
9293ae02089SMasatake YAMATO 				accessDefault = ACCESS_DEFAULT;
9307d90c743SMasatake YAMATO 			else if (isInputLanguage (Lang_d))
9313ae02089SMasatake YAMATO 				accessDefault = ACCESS_PUBLIC;
9323ae02089SMasatake YAMATO 			else
9333ae02089SMasatake YAMATO 				accessDefault = ACCESS_PRIVATE;
9343ae02089SMasatake YAMATO 			break;
9353ae02089SMasatake YAMATO 
9363ae02089SMasatake YAMATO 		case DECL_INTERFACE:
9373ae02089SMasatake YAMATO 		case DECL_STRUCT:
9383ae02089SMasatake YAMATO 		case DECL_UNION:
939682a7f3bSJuan Pablo Civile 		case DECL_ANNOTATION:
9403ae02089SMasatake YAMATO 			accessDefault = ACCESS_PUBLIC;
9413ae02089SMasatake YAMATO 			break;
9423ae02089SMasatake YAMATO 
9433ae02089SMasatake YAMATO 		default: break;
9443ae02089SMasatake YAMATO 	}
9453ae02089SMasatake YAMATO 	st->member.accessDefault = accessDefault;
9463ae02089SMasatake YAMATO 	st->member.access		 = accessDefault;
9473ae02089SMasatake YAMATO }
9483ae02089SMasatake YAMATO 
reinitStatement(statementInfo * const st,const bool partial)949ce990805SThomas Braun static void reinitStatement (statementInfo *const st, const bool partial)
9503ae02089SMasatake YAMATO {
9513ae02089SMasatake YAMATO 	unsigned int i;
9523ae02089SMasatake YAMATO 
9533ae02089SMasatake YAMATO 	if (! partial)
9543ae02089SMasatake YAMATO 	{
9553ae02089SMasatake YAMATO 		st->scope = SCOPE_GLOBAL;
9563ae02089SMasatake YAMATO 		if (isContextualStatement (st->parent))
9573ae02089SMasatake YAMATO 			st->declaration = DECL_BASE;
9583ae02089SMasatake YAMATO 		else
9593ae02089SMasatake YAMATO 			st->declaration = DECL_NONE;
9603ae02089SMasatake YAMATO 	}
961ce990805SThomas Braun 	st->gotParenName	= false;
962ce990805SThomas Braun 	st->isPointer		= false;
963ce990805SThomas Braun 	st->inFunction		= false;
964ce990805SThomas Braun 	st->assignment		= false;
965ce990805SThomas Braun 	st->notVariable		= false;
9663ae02089SMasatake YAMATO 	st->implementation	= IMP_DEFAULT;
967ce990805SThomas Braun 	st->gotArgs			= false;
968ce990805SThomas Braun 	st->gotName			= false;
969ce990805SThomas Braun 	st->haveQualifyingName = false;
9703ae02089SMasatake YAMATO 	st->tokenIndex		= 0;
9713ae02089SMasatake YAMATO 
9723ae02089SMasatake YAMATO 	if (st->parent != NULL)
9733ae02089SMasatake YAMATO 		st->inFunction = st->parent->inFunction;
9743ae02089SMasatake YAMATO 
9753ae02089SMasatake YAMATO 	for (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)
9763ae02089SMasatake YAMATO 		initToken (st->token [i]);
9773ae02089SMasatake YAMATO 
9783ae02089SMasatake YAMATO 	initToken (st->context);
9793ae02089SMasatake YAMATO 
9803ae02089SMasatake YAMATO 	/*	Keep the block name, so that a variable following after a comma will
9813ae02089SMasatake YAMATO 	 *	still have the structure name.
9823ae02089SMasatake YAMATO 	 */
9833ae02089SMasatake YAMATO 	if (! partial)
9843ae02089SMasatake YAMATO 		initToken (st->blockName);
9853ae02089SMasatake YAMATO 
9863ae02089SMasatake YAMATO 	vStringClear (st->parentClasses);
9873ae02089SMasatake YAMATO 
9883ae02089SMasatake YAMATO 	/*  Init member info.
9893ae02089SMasatake YAMATO 	 */
9903ae02089SMasatake YAMATO 	if (! partial)
9913ae02089SMasatake YAMATO 		st->member.access = st->member.accessDefault;
9923ae02089SMasatake YAMATO }
9933ae02089SMasatake YAMATO 
initStatement(statementInfo * const st,statementInfo * const parent)9943ae02089SMasatake YAMATO static void initStatement (statementInfo *const st, statementInfo *const parent)
9953ae02089SMasatake YAMATO {
9963ae02089SMasatake YAMATO 	st->parent = parent;
9973ae02089SMasatake YAMATO 	initMemberInfo (st);
998ce990805SThomas Braun 	reinitStatement (st, false);
9993ae02089SMasatake YAMATO }
10003ae02089SMasatake YAMATO 
10013ae02089SMasatake YAMATO /*
10023ae02089SMasatake YAMATO *   Tag generation functions
10033ae02089SMasatake YAMATO */
1004ce990805SThomas Braun #define cTagKind(type) cTagKindFull(type, true)
1005ce990805SThomas Braun #define cTagKindNoAssert(type) cTagKindFull(type, false)
cTagKindFull(const tagType type,const bool with_assert)1006ce990805SThomas Braun static cKind cTagKindFull (const tagType type, const bool with_assert)
10073ae02089SMasatake YAMATO {
10083ae02089SMasatake YAMATO 	cKind result = CK_UNDEFINED;
10093ae02089SMasatake YAMATO 	switch (type)
10103ae02089SMasatake YAMATO 	{
10113ae02089SMasatake YAMATO 		case TAG_CLASS:      result = CK_CLASS;       break;
10123ae02089SMasatake YAMATO 		case TAG_ENUM:       result = CK_ENUMERATION; break;
10133ae02089SMasatake YAMATO 		case TAG_ENUMERATOR: result = CK_ENUMERATOR;  break;
10143ae02089SMasatake YAMATO 		case TAG_FUNCTION:   result = CK_FUNCTION;    break;
10153ae02089SMasatake YAMATO 		case TAG_LOCAL:      result = CK_LOCAL;       break;
10163ae02089SMasatake YAMATO 		case TAG_MEMBER:     result = CK_MEMBER;      break;
10173ae02089SMasatake YAMATO 		case TAG_NAMESPACE:  result = CK_NAMESPACE;   break;
10183ae02089SMasatake YAMATO 		case TAG_PROTOTYPE:  result = CK_PROTOTYPE;   break;
10193ae02089SMasatake YAMATO 		case TAG_STRUCT:     result = CK_STRUCT;      break;
10203ae02089SMasatake YAMATO 		case TAG_TYPEDEF:    result = CK_TYPEDEF;     break;
10213ae02089SMasatake YAMATO 		case TAG_UNION:      result = CK_UNION;       break;
10223ae02089SMasatake YAMATO 		case TAG_VARIABLE:   result = CK_VARIABLE;    break;
10233ae02089SMasatake YAMATO 		case TAG_EXTERN_VAR: result = CK_EXTERN_VARIABLE; break;
10246891b011SMasatake YAMATO 		case TAG_LABEL:      result = CK_LABEL; break;
10253ae02089SMasatake YAMATO 
1026d34312c4SMasatake YAMATO 		default: if (with_assert) Assert ("Bad C tag type" == NULL); break;
10273ae02089SMasatake YAMATO 	}
10283ae02089SMasatake YAMATO 	return result;
10293ae02089SMasatake YAMATO }
10303ae02089SMasatake YAMATO 
1031ce990805SThomas Braun #define csharpTagKind(type) csharpTagKindFull(type, true)
1032ce990805SThomas Braun #define csharpTagKindNoAssert(type) csharpTagKindFull(type, false)
csharpTagKindFull(const tagType type,const bool with_assert)1033ce990805SThomas Braun static csharpKind csharpTagKindFull (const tagType type, const bool with_assert)
10343ae02089SMasatake YAMATO {
10353ae02089SMasatake YAMATO 	csharpKind result = CSK_UNDEFINED;
10363ae02089SMasatake YAMATO 	switch (type)
10373ae02089SMasatake YAMATO 	{
10383ae02089SMasatake YAMATO 		case TAG_CLASS:      result = CSK_CLASS;           break;
10393ae02089SMasatake YAMATO 		case TAG_ENUM:       result = CSK_ENUMERATION;     break;
10403ae02089SMasatake YAMATO 		case TAG_ENUMERATOR: result = CSK_ENUMERATOR;      break;
10413ae02089SMasatake YAMATO 		case TAG_EVENT:      result = CSK_EVENT;           break;
10423ae02089SMasatake YAMATO 		case TAG_FIELD:      result = CSK_FIELD ;          break;
10433ae02089SMasatake YAMATO 		case TAG_INTERFACE:  result = CSK_INTERFACE;       break;
10443ae02089SMasatake YAMATO 		case TAG_LOCAL:      result = CSK_LOCAL;           break;
10453ae02089SMasatake YAMATO 		case TAG_METHOD:     result = CSK_METHOD;          break;
10463ae02089SMasatake YAMATO 		case TAG_NAMESPACE:  result = CSK_NAMESPACE;       break;
10473ae02089SMasatake YAMATO 		case TAG_PROPERTY:   result = CSK_PROPERTY;        break;
10483ae02089SMasatake YAMATO 		case TAG_STRUCT:     result = CSK_STRUCT;          break;
10493ae02089SMasatake YAMATO 		case TAG_TYPEDEF:    result = CSK_TYPEDEF;         break;
10503ae02089SMasatake YAMATO 
1051d34312c4SMasatake YAMATO 		default: if (with_assert) Assert ("Bad C# tag type" == NULL); break;
10523ae02089SMasatake YAMATO 	}
10533ae02089SMasatake YAMATO 	return result;
10543ae02089SMasatake YAMATO }
10553ae02089SMasatake YAMATO 
1056ce990805SThomas Braun #define javaTagKind(type) javaTagKindFull(type, true)
1057ce990805SThomas Braun #define javaTagKindNoAssert(type) javaTagKindFull(type, false)
javaTagKindFull(const tagType type,bool with_assert)1058ce990805SThomas Braun static javaKind javaTagKindFull (const tagType type, bool with_assert)
10593ae02089SMasatake YAMATO {
10603ae02089SMasatake YAMATO 	javaKind result = JK_UNDEFINED;
10613ae02089SMasatake YAMATO 	switch (type)
10623ae02089SMasatake YAMATO 	{
10633ae02089SMasatake YAMATO 		case TAG_CLASS:      result = JK_CLASS;         break;
10643ae02089SMasatake YAMATO 		case TAG_ENUM:       result = JK_ENUM;          break;
10653ae02089SMasatake YAMATO 		case TAG_ENUMERATOR: result = JK_ENUM_CONSTANT; break;
10663ae02089SMasatake YAMATO 		case TAG_FIELD:      result = JK_FIELD;         break;
10673ae02089SMasatake YAMATO 		case TAG_INTERFACE:  result = JK_INTERFACE;     break;
10683ae02089SMasatake YAMATO 		case TAG_LOCAL:      result = JK_LOCAL;         break;
10693ae02089SMasatake YAMATO 		case TAG_METHOD:     result = JK_METHOD;        break;
1070fddb1356SMasatake YAMATO 		case TAG_PACKAGE:    /* Fall through */
1071fddb1356SMasatake YAMATO 		case TAG_PACKAGEREF: result = JK_PACKAGE;       break;
10726b61e611SMasatake YAMATO 		case TAG_ANNOTATION: result = JK_ANNOTATION;     break;
10733ae02089SMasatake YAMATO 
1074d34312c4SMasatake YAMATO 		default: if (with_assert) Assert ("Bad Java tag type" == NULL); break;
10753ae02089SMasatake YAMATO 	}
10763ae02089SMasatake YAMATO 	return result;
10773ae02089SMasatake YAMATO }
10783ae02089SMasatake YAMATO 
1079ce990805SThomas Braun #define dTagKind(type) dTagKindFull(type, true)
1080ce990805SThomas Braun #define dTagKindNoAssert(type) dTagKindFull(type, false)
dTagKindFull(const tagType type,bool with_assert)1081ce990805SThomas Braun static dKind dTagKindFull (const tagType type, bool with_assert)
10823ae02089SMasatake YAMATO {
10833ae02089SMasatake YAMATO 	dKind result = DK_UNDEFINED;
10843ae02089SMasatake YAMATO 	switch (type)
10853ae02089SMasatake YAMATO 	{
10863ae02089SMasatake YAMATO 		case TAG_TYPEDEF:    result = DK_ALIAS;           break;
10873ae02089SMasatake YAMATO 		case TAG_CLASS:      result = DK_CLASS;           break;
10883ae02089SMasatake YAMATO 		case TAG_ENUM:       result = DK_ENUMERATION;     break;
10893ae02089SMasatake YAMATO 		case TAG_ENUMERATOR: result = DK_ENUMERATOR;      break;
10903ae02089SMasatake YAMATO 		case TAG_EXTERN_VAR: result = DK_EXTERN_VARIABLE; break;
10913ae02089SMasatake YAMATO 		case TAG_FUNCTION:   result = DK_FUNCTION;        break;
10923ae02089SMasatake YAMATO 		case TAG_INTERFACE:  result = DK_INTERFACE;       break;
10933ae02089SMasatake YAMATO 		case TAG_LOCAL:      result = DK_LOCAL;           break;
10943ae02089SMasatake YAMATO 		case TAG_MEMBER:     result = DK_MEMBER;          break;
10953ae02089SMasatake YAMATO 		case TAG_MIXIN:      result = DK_MIXIN;           break;
10963ae02089SMasatake YAMATO 		case TAG_PACKAGE:    result = DK_MODULE;          break;
10973ae02089SMasatake YAMATO 		case TAG_NAMESPACE:  result = DK_NAMESPACE;       break;
10983ae02089SMasatake YAMATO 		case TAG_PROTOTYPE:  result = DK_PROTOTYPE;       break;
10993ae02089SMasatake YAMATO 		case TAG_STRUCT:     result = DK_STRUCT;          break;
11003ae02089SMasatake YAMATO 		case TAG_TEMPLATE:   result = DK_TEMPLATE;        break;
11013ae02089SMasatake YAMATO 		case TAG_UNION:      result = DK_UNION;           break;
11023ae02089SMasatake YAMATO 		case TAG_VARIABLE:   result = DK_VARIABLE;        break;
11033ae02089SMasatake YAMATO 		case TAG_VERSION:    result = DK_VERSION;         break;
11043ae02089SMasatake YAMATO 
1105d34312c4SMasatake YAMATO 		default: if (with_assert) Assert ("Bad D tag type" == NULL); break;
11063ae02089SMasatake YAMATO 	}
11073ae02089SMasatake YAMATO 	return result;
11083ae02089SMasatake YAMATO }
11093ae02089SMasatake YAMATO 
1110ce990805SThomas Braun #define veraTagKind(type) veraTagKindFull(type, true)
1111ce990805SThomas Braun #define veraTagKindNoAssert(type) veraTagKindFull(type, false)
veraTagKindFull(const tagType type,bool with_assert)1112ce990805SThomas Braun static veraKind veraTagKindFull (const tagType type, bool with_assert) {
11133ae02089SMasatake YAMATO 	veraKind result = VK_UNDEFINED;
11143ae02089SMasatake YAMATO 	switch (type)
11153ae02089SMasatake YAMATO 	{
11163ae02089SMasatake YAMATO 		case TAG_CLASS:      result = VK_CLASS;           break;
11173ae02089SMasatake YAMATO 		case TAG_ENUM:       result = VK_ENUMERATION;     break;
11183ae02089SMasatake YAMATO 		case TAG_ENUMERATOR: result = VK_ENUMERATOR;      break;
11193ae02089SMasatake YAMATO 		case TAG_FUNCTION:   result = VK_FUNCTION;        break;
112090230484SMasatake YAMATO 		case TAG_INTERFACE:  result = VK_INTERFACE;       break;
11213ae02089SMasatake YAMATO 		case TAG_LOCAL:      result = VK_LOCAL;           break;
11223ae02089SMasatake YAMATO 		case TAG_MEMBER:     result = VK_MEMBER;          break;
11233ae02089SMasatake YAMATO 		case TAG_PROGRAM:    result = VK_PROGRAM;         break;
11243ae02089SMasatake YAMATO 		case TAG_PROTOTYPE:  result = VK_PROTOTYPE;       break;
112590230484SMasatake YAMATO 		case TAG_SIGNAL:     result = VK_SIGNAL;          break;
11263ae02089SMasatake YAMATO 		case TAG_TASK:       result = VK_TASK;            break;
11273ae02089SMasatake YAMATO 		case TAG_TYPEDEF:    result = VK_TYPEDEF;         break;
11283ae02089SMasatake YAMATO 		case TAG_VARIABLE:   result = VK_VARIABLE;        break;
11293ae02089SMasatake YAMATO 		case TAG_EXTERN_VAR: result = VK_EXTERN_VARIABLE; break;
11303ae02089SMasatake YAMATO 
1131d34312c4SMasatake YAMATO 		default: if (with_assert) Assert ("Bad Vera tag type" == NULL); break;
11323ae02089SMasatake YAMATO 	}
11333ae02089SMasatake YAMATO 	return result;
11343ae02089SMasatake YAMATO }
11353ae02089SMasatake YAMATO 
kindIndexForType(const tagType type)113616a2541cSMasatake YAMATO static int kindIndexForType (const tagType type)
113716a2541cSMasatake YAMATO {
113816a2541cSMasatake YAMATO 	int result;
113916a2541cSMasatake YAMATO 	if (isInputLanguage (Lang_csharp))
114016a2541cSMasatake YAMATO 		result = csharpTagKind (type);
114116a2541cSMasatake YAMATO 	else if (isInputLanguage (Lang_java))
114216a2541cSMasatake YAMATO 		result = javaTagKind (type);
114316a2541cSMasatake YAMATO 	else if (isInputLanguage (Lang_d))
114416a2541cSMasatake YAMATO 		result = dTagKind (type);
114516a2541cSMasatake YAMATO 	else if (isInputLanguage (Lang_vera))
114616a2541cSMasatake YAMATO 		result = veraTagKind (type);
114716a2541cSMasatake YAMATO 	else
114816a2541cSMasatake YAMATO 		result = cTagKind (type);
114916a2541cSMasatake YAMATO 	return result;
115016a2541cSMasatake YAMATO }
115116a2541cSMasatake YAMATO 
roleForType(const tagType type)1152fddb1356SMasatake YAMATO static int roleForType (const tagType type)
1153fddb1356SMasatake YAMATO {
1154fddb1356SMasatake YAMATO 	int result;
1155fddb1356SMasatake YAMATO 
115624b256e3SMasatake YAMATO 	result = ROLE_DEFINITION_INDEX;
1157fddb1356SMasatake YAMATO 	if (isInputLanguage (Lang_java))
1158fddb1356SMasatake YAMATO 	{
1159fddb1356SMasatake YAMATO 		if (type == TAG_PACKAGEREF)
1160fddb1356SMasatake YAMATO 			result = JAVAR_PACKAGE_IMPORTED;
1161fddb1356SMasatake YAMATO 	}
1162fddb1356SMasatake YAMATO 
1163fddb1356SMasatake YAMATO 	return result;
1164fddb1356SMasatake YAMATO }
1165fddb1356SMasatake YAMATO 
tagName(const tagType type)11663ae02089SMasatake YAMATO static const char *tagName (const tagType type)
11673ae02089SMasatake YAMATO {
11683ae02089SMasatake YAMATO 	const char* result;
11697d90c743SMasatake YAMATO 	if (isInputLanguage (Lang_csharp))
11703ae02089SMasatake YAMATO 		result = CsharpKinds [csharpTagKind (type)].name;
11717d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_java))
11723ae02089SMasatake YAMATO 		result = JavaKinds [javaTagKind (type)].name;
11737d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_d))
11743ae02089SMasatake YAMATO 		result = DKinds [dTagKind (type)].name;
11757d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_vera))
11763ae02089SMasatake YAMATO 		result = VeraKinds [veraTagKind (type)].name;
11773ae02089SMasatake YAMATO 	else
11783ae02089SMasatake YAMATO 		result = CKinds [cTagKind (type)].name;
11793ae02089SMasatake YAMATO 	return result;
11803ae02089SMasatake YAMATO }
11813ae02089SMasatake YAMATO 
includeTag(const tagType type,const bool isFileScope)1182ce990805SThomas Braun static bool includeTag (const tagType type, const bool isFileScope)
11833ae02089SMasatake YAMATO {
1184ce990805SThomas Braun 	bool result;
1185d34312c4SMasatake YAMATO 	int k;
1186d34312c4SMasatake YAMATO 
118735c59e96SMasatake YAMATO 	if (isFileScope && !isXtagEnabled(XTAG_FILE_SCOPE))
1188f92e6bf2SMasatake YAMATO 		return false;
11897d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_csharp))
1190d34312c4SMasatake YAMATO 		k = csharpTagKindNoAssert (type);
11917d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_java))
1192d34312c4SMasatake YAMATO 		k = javaTagKindNoAssert (type);
11937d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_d))
1194d34312c4SMasatake YAMATO 		k = dTagKindNoAssert (type);
11957d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_vera))
1196d34312c4SMasatake YAMATO 		k = veraTagKindNoAssert (type);
11973ae02089SMasatake YAMATO 	else
1198d34312c4SMasatake YAMATO 		k = cTagKindNoAssert (type);
1199d34312c4SMasatake YAMATO 
1200d34312c4SMasatake YAMATO 	if (k == COMMONK_UNDEFINED)
1201ce990805SThomas Braun 		result = false;
1202d34312c4SMasatake YAMATO 	else
1203f92e6bf2SMasatake YAMATO 		result = isInputLanguageKindEnabled (k);
1204d34312c4SMasatake YAMATO 
12053ae02089SMasatake YAMATO 	return result;
12063ae02089SMasatake YAMATO }
12073ae02089SMasatake YAMATO 
declToTagType(const declType declaration)12083ae02089SMasatake YAMATO static tagType declToTagType (const declType declaration)
12093ae02089SMasatake YAMATO {
12103ae02089SMasatake YAMATO 	tagType type = TAG_UNDEFINED;
12113ae02089SMasatake YAMATO 
12123ae02089SMasatake YAMATO 	switch (declaration)
12133ae02089SMasatake YAMATO 	{
12143ae02089SMasatake YAMATO 		case DECL_CLASS:        type = TAG_CLASS;       break;
12153ae02089SMasatake YAMATO 		case DECL_ENUM:         type = TAG_ENUM;        break;
12163ae02089SMasatake YAMATO 		case DECL_EVENT:        type = TAG_EVENT;       break;
12173ae02089SMasatake YAMATO 		case DECL_FUNCTION:     type = TAG_FUNCTION;    break;
12183ae02089SMasatake YAMATO 		case DECL_FUNCTION_TEMPLATE: type = TAG_FUNCTION; break;
12193ae02089SMasatake YAMATO 		case DECL_INTERFACE:    type = TAG_INTERFACE;   break;
12203ae02089SMasatake YAMATO 		case DECL_NAMESPACE:    type = TAG_NAMESPACE;   break;
12213ae02089SMasatake YAMATO 		case DECL_PROGRAM:      type = TAG_PROGRAM;     break;
12223ae02089SMasatake YAMATO 		case DECL_PRIVATE:      type = TAG_CLASS;       break;
12233ae02089SMasatake YAMATO 		case DECL_PROTECTED:    type = TAG_CLASS;       break;
12243ae02089SMasatake YAMATO 		case DECL_PUBLIC:       type = TAG_CLASS;       break;
12253ae02089SMasatake YAMATO 		case DECL_TASK:         type = TAG_TASK;        break;
12263ae02089SMasatake YAMATO 		case DECL_TEMPLATE: 	type = TAG_TEMPLATE; 	break;
12273ae02089SMasatake YAMATO 		case DECL_STRUCT:       type = TAG_STRUCT;      break;
12283ae02089SMasatake YAMATO 		case DECL_UNION:        type = TAG_UNION;       break;
12293ae02089SMasatake YAMATO 		case DECL_VERSION: 		type = TAG_VERSION; 	break;
1230682a7f3bSJuan Pablo Civile 		case DECL_ANNOTATION:   type = TAG_ANNOTATION;  break;
12313ae02089SMasatake YAMATO 
12323ae02089SMasatake YAMATO 		default: Assert ("Unexpected declaration" == NULL); break;
12333ae02089SMasatake YAMATO 	}
12343ae02089SMasatake YAMATO 	return type;
12353ae02089SMasatake YAMATO }
12363ae02089SMasatake YAMATO 
accessField(const statementInfo * const st)12373ae02089SMasatake YAMATO static const char* accessField (const statementInfo *const st)
12383ae02089SMasatake YAMATO {
12393ae02089SMasatake YAMATO 	const char* result = NULL;
12407d90c743SMasatake YAMATO 	if (isInputLanguage (Lang_cpp)  &&  st->scope == SCOPE_FRIEND)
12413ae02089SMasatake YAMATO 		result = "friend";
12423ae02089SMasatake YAMATO 	else if (st->member.access != ACCESS_UNDEFINED)
12433ae02089SMasatake YAMATO 		result = accessString (st->member.access);
12443ae02089SMasatake YAMATO 	return result;
12453ae02089SMasatake YAMATO }
12463ae02089SMasatake YAMATO 
addContextSeparator(vString * const scope)12473ae02089SMasatake YAMATO static void addContextSeparator (vString *const scope)
12483ae02089SMasatake YAMATO {
12497d90c743SMasatake YAMATO 	if (isInputLanguage (Lang_c)  ||  isInputLanguage (Lang_cpp))
12503ae02089SMasatake YAMATO 		vStringCatS (scope, "::");
12517d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp) || isInputLanguage(Lang_d))
12521da6e7e4SMasatake YAMATO 		vStringPut (scope, '.');
12533ae02089SMasatake YAMATO }
12543ae02089SMasatake YAMATO 
addOtherFields(tagEntryInfo * const tag,const tagType type,const statementInfo * const st,vString * const scope,vString * const typeRef)12553ae02089SMasatake YAMATO static void addOtherFields (tagEntryInfo* const tag, const tagType type,
12563ae02089SMasatake YAMATO 							const statementInfo *const st,
12573ae02089SMasatake YAMATO 							vString *const scope, vString *const typeRef)
12583ae02089SMasatake YAMATO {
12593ae02089SMasatake YAMATO 	/*  For selected tag types, append an extension flag designating the
12603ae02089SMasatake YAMATO 	 *  parent object in which the tag is defined.
12613ae02089SMasatake YAMATO 	 */
12623ae02089SMasatake YAMATO 	switch (type)
12633ae02089SMasatake YAMATO 	{
12643ae02089SMasatake YAMATO 		default: break;
12653ae02089SMasatake YAMATO 
12663ae02089SMasatake YAMATO 		case TAG_FUNCTION:
12673ae02089SMasatake YAMATO 		case TAG_TEMPLATE:
12683ae02089SMasatake YAMATO 		case TAG_METHOD:
12693ae02089SMasatake YAMATO 		case TAG_PROTOTYPE:
12703ae02089SMasatake YAMATO 			if (vStringLength (Signature) > 0)
12713ae02089SMasatake YAMATO 				tag->extensionFields.signature = vStringValue (Signature);
12723ae02089SMasatake YAMATO 		case TAG_CLASS:
12733ae02089SMasatake YAMATO 		case TAG_ENUM:
12743ae02089SMasatake YAMATO 		case TAG_ENUMERATOR:
12753ae02089SMasatake YAMATO 		case TAG_EVENT:
12763ae02089SMasatake YAMATO 		case TAG_FIELD:
12773ae02089SMasatake YAMATO 		case TAG_INTERFACE:
12783ae02089SMasatake YAMATO 		case TAG_MEMBER:
12793ae02089SMasatake YAMATO 		case TAG_NAMESPACE:
12803ae02089SMasatake YAMATO 		case TAG_PROPERTY:
1281b651641cSMasatake YAMATO 		case TAG_SIGNAL:
12823ae02089SMasatake YAMATO 		case TAG_STRUCT:
12833ae02089SMasatake YAMATO 		case TAG_TASK:
12843ae02089SMasatake YAMATO 		case TAG_TYPEDEF:
12853ae02089SMasatake YAMATO 		case TAG_UNION:
1286682a7f3bSJuan Pablo Civile 		case TAG_ANNOTATION:
12873ae02089SMasatake YAMATO 			if (vStringLength (scope) > 0  &&
12883ae02089SMasatake YAMATO 				(isMember (st) || st->parent->declaration == DECL_NAMESPACE))
12893ae02089SMasatake YAMATO 			{
1290d34312c4SMasatake YAMATO 				tagType ptype;
1291d34312c4SMasatake YAMATO 
12923ae02089SMasatake YAMATO 				if (isType (st->context, TOKEN_NAME))
1293d34312c4SMasatake YAMATO 				{
1294f92e6bf2SMasatake YAMATO 					tag->extensionFields.scopeKindIndex = kindIndexForType (TAG_CLASS);
1295015ab54cSMasatake YAMATO 					tag->extensionFields.scopeName = vStringValue (scope);
12963ae02089SMasatake YAMATO 				}
1297d34312c4SMasatake YAMATO 				else if ((ptype = declToTagType (parentDecl (st))) &&
129835c59e96SMasatake YAMATO 					 includeTag (ptype, isXtagEnabled(XTAG_FILE_SCOPE)))
1299d34312c4SMasatake YAMATO 				{
1300f92e6bf2SMasatake YAMATO 					tag->extensionFields.scopeKindIndex = kindIndexForType (ptype);
1301015ab54cSMasatake YAMATO 					tag->extensionFields.scopeName = vStringValue (scope);
1302d34312c4SMasatake YAMATO 				}
1303d34312c4SMasatake YAMATO 			}
13043ae02089SMasatake YAMATO 			if ((type == TAG_CLASS  ||  type == TAG_INTERFACE  ||
1305682a7f3bSJuan Pablo Civile 				 type == TAG_STRUCT || type == TAG_ANNOTATION) && vStringLength (st->parentClasses) > 0)
13063ae02089SMasatake YAMATO 			{
13073ae02089SMasatake YAMATO 
13083ae02089SMasatake YAMATO 				tag->extensionFields.inheritance =
13093ae02089SMasatake YAMATO 						vStringValue (st->parentClasses);
13103ae02089SMasatake YAMATO 			}
13113ae02089SMasatake YAMATO 			if (st->implementation != IMP_DEFAULT &&
13127d90c743SMasatake YAMATO 				(isInputLanguage (Lang_cpp) || isInputLanguage (Lang_csharp) ||
13137d90c743SMasatake YAMATO 				 isInputLanguage (Lang_d) || isInputLanguage (Lang_java)))
13143ae02089SMasatake YAMATO 			{
13153ae02089SMasatake YAMATO 				tag->extensionFields.implementation =
13163ae02089SMasatake YAMATO 						implementationString (st->implementation);
13173ae02089SMasatake YAMATO 			}
13183ae02089SMasatake YAMATO 			if (isMember (st))
13193ae02089SMasatake YAMATO 			{
13203ae02089SMasatake YAMATO 				tag->extensionFields.access = accessField (st);
13213ae02089SMasatake YAMATO 			}
13223ae02089SMasatake YAMATO 			break;
13233ae02089SMasatake YAMATO 	}
13243ae02089SMasatake YAMATO 
13253ae02089SMasatake YAMATO 	/* Add typename info, type of the tag and name of struct/union/etc. */
13263ae02089SMasatake YAMATO 	if ((type == TAG_TYPEDEF || type == TAG_VARIABLE || type == TAG_MEMBER)
13273ae02089SMasatake YAMATO 			&& isContextualStatement(st))
13283ae02089SMasatake YAMATO 	{
13293ae02089SMasatake YAMATO 		char *p;
13303ae02089SMasatake YAMATO 
13313ae02089SMasatake YAMATO 		tag->extensionFields.typeRef [0] =
13323ae02089SMasatake YAMATO 						tagName (declToTagType (st->declaration));
13333ae02089SMasatake YAMATO 		p = vStringValue (st->blockName->name);
13343ae02089SMasatake YAMATO 
13353ae02089SMasatake YAMATO 		/*  If there was no {} block get the name from the token before the
13363ae02089SMasatake YAMATO 		 *  name (current token is ';' or ',', previous token is the name).
13373ae02089SMasatake YAMATO 		 */
13383ae02089SMasatake YAMATO 		if (p == NULL || *p == '\0')
13393ae02089SMasatake YAMATO 		{
13403ae02089SMasatake YAMATO 			tokenInfo *const prev2 = prevToken (st, 2);
13413ae02089SMasatake YAMATO 			if (isType (prev2, TOKEN_NAME))
13423ae02089SMasatake YAMATO 				p = vStringValue (prev2->name);
13433ae02089SMasatake YAMATO 		}
13443ae02089SMasatake YAMATO 
13453ae02089SMasatake YAMATO 		/* Prepend the scope name if there is one. */
13463ae02089SMasatake YAMATO 		if (vStringLength (scope) > 0)
13473ae02089SMasatake YAMATO 		{
13483ae02089SMasatake YAMATO 			vStringCopy(typeRef, scope);
13493ae02089SMasatake YAMATO 			addContextSeparator (typeRef);
13503ae02089SMasatake YAMATO 			vStringCatS(typeRef, p);
13513ae02089SMasatake YAMATO 			p = vStringValue (typeRef);
13523ae02089SMasatake YAMATO 		}
13533ae02089SMasatake YAMATO 		tag->extensionFields.typeRef [1] = p;
13543ae02089SMasatake YAMATO 	}
13553ae02089SMasatake YAMATO }
13563ae02089SMasatake YAMATO 
findScopeHierarchy(vString * const string,const statementInfo * const st)1357ce990805SThomas Braun static bool findScopeHierarchy (vString *const string, const statementInfo *const st)
13583ae02089SMasatake YAMATO {
1359ce990805SThomas Braun 	bool found = false;
13604ca10085SMasatake YAMATO 
13613ae02089SMasatake YAMATO 	vStringClear (string);
1362647929b8SMasatake YAMATO 
13633ae02089SMasatake YAMATO 	if (isType (st->context, TOKEN_NAME))
1364647929b8SMasatake YAMATO 	{
13653ae02089SMasatake YAMATO 		vStringCopy (string, st->context->name);
1366ce990805SThomas Braun 		found = true;
1367647929b8SMasatake YAMATO 	}
1368647929b8SMasatake YAMATO 
13693ae02089SMasatake YAMATO 	if (st->parent != NULL)
13703ae02089SMasatake YAMATO 	{
13713ae02089SMasatake YAMATO 		vString *temp = vStringNew ();
13723ae02089SMasatake YAMATO 		const statementInfo *s;
13733ae02089SMasatake YAMATO 		for (s = st->parent  ;  s != NULL  ;  s = s->parent)
13743ae02089SMasatake YAMATO 		{
13753ae02089SMasatake YAMATO 			if (isContextualStatement (s) ||
13763ae02089SMasatake YAMATO 				s->declaration == DECL_NAMESPACE ||
13773ae02089SMasatake YAMATO 				s->declaration == DECL_PROGRAM)
13783ae02089SMasatake YAMATO 			{
13793ae02089SMasatake YAMATO 				if (s->declaration == DECL_PRIVATE ||
13803ae02089SMasatake YAMATO 					s->declaration == DECL_PROTECTED ||
13813ae02089SMasatake YAMATO 					s->declaration == DECL_PUBLIC) {
13823ae02089SMasatake YAMATO 					continue;
13833ae02089SMasatake YAMATO 				}
13843ae02089SMasatake YAMATO 
1385ce990805SThomas Braun 				found = true;
13863ae02089SMasatake YAMATO 				vStringCopy (temp, string);
13873ae02089SMasatake YAMATO 				vStringClear (string);
13885ad547aeSMasatake YAMATO 				if (isType (s->blockName, TOKEN_NAME))
13894ca10085SMasatake YAMATO 				{
13903ae02089SMasatake YAMATO 					if (isType (s->context, TOKEN_NAME) &&
13913ae02089SMasatake YAMATO 					    vStringLength (s->context->name) > 0)
13923ae02089SMasatake YAMATO 					{
13933ae02089SMasatake YAMATO 						vStringCat (string, s->context->name);
13943ae02089SMasatake YAMATO 						addContextSeparator (string);
13953ae02089SMasatake YAMATO 					}
13963ae02089SMasatake YAMATO 					vStringCat (string, s->blockName->name);
13973ae02089SMasatake YAMATO 					if (vStringLength (temp) > 0)
13983ae02089SMasatake YAMATO 						addContextSeparator (string);
13993ae02089SMasatake YAMATO 					vStringCat (string, temp);
14003ae02089SMasatake YAMATO 				}
14015ad547aeSMasatake YAMATO 				else
14025ad547aeSMasatake YAMATO 				{
14035ad547aeSMasatake YAMATO 					/* Information for building scope string
14045ad547aeSMasatake YAMATO 					   is lacking. Maybe input is broken. */
1405ce990805SThomas Braun 					found = false;
14065ad547aeSMasatake YAMATO 				}
14075ad547aeSMasatake YAMATO 			}
14083ae02089SMasatake YAMATO 		}
14093ae02089SMasatake YAMATO 		vStringDelete (temp);
14103ae02089SMasatake YAMATO 	}
14114ca10085SMasatake YAMATO 	return found;
14123ae02089SMasatake YAMATO }
14133ae02089SMasatake YAMATO 
makeExtraTagEntry(const tagType type,tagEntryInfo * const e,vString * const scope)14143ae02089SMasatake YAMATO static void makeExtraTagEntry (const tagType type, tagEntryInfo *const e,
14153ae02089SMasatake YAMATO 							   vString *const scope)
14163ae02089SMasatake YAMATO {
141735c59e96SMasatake YAMATO 	if (isXtagEnabled(XTAG_QUALIFIED_TAGS)  &&
14183ae02089SMasatake YAMATO 		scope != NULL  &&  vStringLength (scope) > 0)
14193ae02089SMasatake YAMATO 	{
14203ae02089SMasatake YAMATO 		vString *const scopedName = vStringNew ();
14213ae02089SMasatake YAMATO 
14223ae02089SMasatake YAMATO 		if (type != TAG_ENUMERATOR)
14233ae02089SMasatake YAMATO 			vStringCopy (scopedName, scope);
14243ae02089SMasatake YAMATO 		else
14253ae02089SMasatake YAMATO 		{
14263ae02089SMasatake YAMATO 			/* remove last component (i.e. enumeration name) from scope */
14273ae02089SMasatake YAMATO 			const char* const sc = vStringValue (scope);
14283ae02089SMasatake YAMATO 			const char* colon = strrchr (sc, ':');
14293ae02089SMasatake YAMATO 			if (colon != NULL)
14303ae02089SMasatake YAMATO 			{
14313ae02089SMasatake YAMATO 				while (*colon == ':'  &&  colon > sc)
14323ae02089SMasatake YAMATO 					--colon;
14333ae02089SMasatake YAMATO 				vStringNCopy (scopedName, scope, colon + 1 - sc);
14343ae02089SMasatake YAMATO 			}
14353ae02089SMasatake YAMATO 		}
14363ae02089SMasatake YAMATO 		if (vStringLength (scopedName) > 0)
14373ae02089SMasatake YAMATO 		{
14383ae02089SMasatake YAMATO 			addContextSeparator (scopedName);
14393ae02089SMasatake YAMATO 			vStringCatS (scopedName, e->name);
14403ae02089SMasatake YAMATO 			e->name = vStringValue (scopedName);
14415022e63aSMasatake YAMATO 			markTagExtraBit (e, XTAG_QUALIFIED_TAGS);
14423ae02089SMasatake YAMATO 			makeTagEntry (e);
14433ae02089SMasatake YAMATO 		}
14443ae02089SMasatake YAMATO 		vStringDelete (scopedName);
14453ae02089SMasatake YAMATO 	}
14463ae02089SMasatake YAMATO }
14473ae02089SMasatake YAMATO 
makeTag(const tokenInfo * const token,const statementInfo * const st,bool isFileScope,const tagType type)14486248c9a7SMasatake YAMATO static int makeTag (const tokenInfo *const token,
14493ae02089SMasatake YAMATO 					 const statementInfo *const st,
1450ce990805SThomas Braun 					 bool isFileScope, const tagType type)
14513ae02089SMasatake YAMATO {
14526248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
14533ae02089SMasatake YAMATO 	/*  Nothing is really of file scope when it appears in a header file.
14543ae02089SMasatake YAMATO 	 */
1455ce990805SThomas Braun 	isFileScope = (bool) (isFileScope && ! isInputHeaderFile ());
14563ae02089SMasatake YAMATO 
14573ae02089SMasatake YAMATO 	if (isType (token, TOKEN_NAME)  &&  vStringLength (token->name) > 0  &&
14583ae02089SMasatake YAMATO 		includeTag (type, isFileScope))
14593ae02089SMasatake YAMATO 	{
1460fddb1356SMasatake YAMATO 		vString *scope;
1461fddb1356SMasatake YAMATO 		vString *typeRef;
1462ce990805SThomas Braun 		bool isScopeBuilt;
14633ae02089SMasatake YAMATO 		/* Use "typeRef" to store the typename from addOtherFields() until
14643ae02089SMasatake YAMATO 		 * it's used in makeTagEntry().
14653ae02089SMasatake YAMATO 		 */
14663ae02089SMasatake YAMATO 		tagEntryInfo e;
146716a2541cSMasatake YAMATO 		int kind;
1468fddb1356SMasatake YAMATO 		int role;
14693ae02089SMasatake YAMATO 
1470fddb1356SMasatake YAMATO 		role = roleForType (type);
147124b256e3SMasatake YAMATO 		if (! (role == ROLE_DEFINITION_INDEX || isXtagEnabled (XTAG_REFERENCE_TAGS)))
14726248c9a7SMasatake YAMATO 			return CORK_NIL;
1473fddb1356SMasatake YAMATO 
1474fddb1356SMasatake YAMATO 		scope  = vStringNew ();
1475fddb1356SMasatake YAMATO 		typeRef = vStringNew ();
1476fddb1356SMasatake YAMATO 
147716a2541cSMasatake YAMATO 		kind  = kindIndexForType(type);
147824b256e3SMasatake YAMATO 		if (role == ROLE_DEFINITION_INDEX)
1479fddb1356SMasatake YAMATO 			initTagEntry (&e, vStringValue (token->name), kind);
1480fddb1356SMasatake YAMATO 		else
1481fddb1356SMasatake YAMATO 			initRefTagEntry (&e, vStringValue (token->name), kind, role);
14823ae02089SMasatake YAMATO 
14833ae02089SMasatake YAMATO 		e.lineNumber	= token->lineNumber;
14843ae02089SMasatake YAMATO 		e.filePosition	= token->filePosition;
14853ae02089SMasatake YAMATO 		e.isFileScope	= isFileScope;
14863397ae72SMasatake YAMATO 		if (e.isFileScope)
14873397ae72SMasatake YAMATO 			markTagExtraBit (&e, XTAG_FILE_SCOPE);
14887c972a30SMasatake YAMATO 
14894ca10085SMasatake YAMATO 		isScopeBuilt = findScopeHierarchy (scope, st);
14903ae02089SMasatake YAMATO 		addOtherFields (&e, type, st, scope, typeRef);
14913ae02089SMasatake YAMATO 
14926248c9a7SMasatake YAMATO 		corkIndex = makeTagEntry (&e);
14934ca10085SMasatake YAMATO 		if (isScopeBuilt)
14943ae02089SMasatake YAMATO 			makeExtraTagEntry (type, &e, scope);
14953ae02089SMasatake YAMATO 		vStringDelete (scope);
14963ae02089SMasatake YAMATO 		vStringDelete (typeRef);
14973ae02089SMasatake YAMATO 	}
14986248c9a7SMasatake YAMATO 	return corkIndex;
14993ae02089SMasatake YAMATO }
15003ae02089SMasatake YAMATO 
isValidTypeSpecifier(const declType declaration)1501ce990805SThomas Braun static bool isValidTypeSpecifier (const declType declaration)
15023ae02089SMasatake YAMATO {
1503ce990805SThomas Braun 	bool result;
15043ae02089SMasatake YAMATO 	switch (declaration)
15053ae02089SMasatake YAMATO 	{
15063ae02089SMasatake YAMATO 		case DECL_BASE:
15073ae02089SMasatake YAMATO 		case DECL_CLASS:
15083ae02089SMasatake YAMATO 		case DECL_ENUM:
15093ae02089SMasatake YAMATO 		case DECL_EVENT:
15103ae02089SMasatake YAMATO 		case DECL_STRUCT:
15113ae02089SMasatake YAMATO 		case DECL_UNION:
1512682a7f3bSJuan Pablo Civile 		case DECL_ANNOTATION:
1513ce990805SThomas Braun 			result = true;
15143ae02089SMasatake YAMATO 			break;
15153ae02089SMasatake YAMATO 
15163ae02089SMasatake YAMATO 		default:
1517ce990805SThomas Braun 			result = false;
15183ae02089SMasatake YAMATO 			break;
15193ae02089SMasatake YAMATO 	}
15203ae02089SMasatake YAMATO 	return result;
15213ae02089SMasatake YAMATO }
15223ae02089SMasatake YAMATO 
qualifyEnumeratorTag(const statementInfo * const st,const tokenInfo * const nameToken)15236248c9a7SMasatake YAMATO static int qualifyEnumeratorTag (const statementInfo *const st,
15243ae02089SMasatake YAMATO 								 const tokenInfo *const nameToken)
15253ae02089SMasatake YAMATO {
15266248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
15273ae02089SMasatake YAMATO 	if (isType (nameToken, TOKEN_NAME))
15286248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, true, TAG_ENUMERATOR);
15296248c9a7SMasatake YAMATO 	return corkIndex;
15303ae02089SMasatake YAMATO }
15313ae02089SMasatake YAMATO 
qualifyFunctionTag(const statementInfo * const st,const tokenInfo * const nameToken)15326248c9a7SMasatake YAMATO static int qualifyFunctionTag (const statementInfo *const st,
15333ae02089SMasatake YAMATO 								const tokenInfo *const nameToken)
15343ae02089SMasatake YAMATO {
15356248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
15363ae02089SMasatake YAMATO 	if (isType (nameToken, TOKEN_NAME))
15373ae02089SMasatake YAMATO 	{
15383ae02089SMasatake YAMATO 		tagType type;
1539ce990805SThomas Braun 		const bool isFileScope =
1540ce990805SThomas Braun 						(bool) (st->member.access == ACCESS_PRIVATE ||
15413ae02089SMasatake YAMATO 						(!isMember (st)  &&  st->scope == SCOPE_STATIC));
15427d90c743SMasatake YAMATO 		if (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp))
15433ae02089SMasatake YAMATO 			type = TAG_METHOD;
15447d90c743SMasatake YAMATO 		else if (isInputLanguage (Lang_vera)  &&  st->declaration == DECL_TASK)
15453ae02089SMasatake YAMATO 			type = TAG_TASK;
15463ae02089SMasatake YAMATO 		else
15473ae02089SMasatake YAMATO 			type = TAG_FUNCTION;
15486248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, isFileScope, type);
15493ae02089SMasatake YAMATO 	}
15506248c9a7SMasatake YAMATO 	return corkIndex;
15513ae02089SMasatake YAMATO }
15523ae02089SMasatake YAMATO 
qualifyFunctionDeclTag(const statementInfo * const st,const tokenInfo * const nameToken)15536248c9a7SMasatake YAMATO static int qualifyFunctionDeclTag (const statementInfo *const st,
15543ae02089SMasatake YAMATO 									const tokenInfo *const nameToken)
15553ae02089SMasatake YAMATO {
15566248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
15573ae02089SMasatake YAMATO 	if (! isType (nameToken, TOKEN_NAME))
15583ae02089SMasatake YAMATO 		;
15597d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp))
15606248c9a7SMasatake YAMATO 		corkIndex = qualifyFunctionTag (st, nameToken);
15613ae02089SMasatake YAMATO 	else if (st->scope == SCOPE_TYPEDEF)
15626248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);
15637d90c743SMasatake YAMATO 	else if (isValidTypeSpecifier (st->declaration) && ! isInputLanguage (Lang_csharp))
15646248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, true, TAG_PROTOTYPE);
15656248c9a7SMasatake YAMATO 	return corkIndex;
15663ae02089SMasatake YAMATO }
15673ae02089SMasatake YAMATO 
qualifyCompoundTag(const statementInfo * const st,const tokenInfo * const nameToken)15686248c9a7SMasatake YAMATO static int qualifyCompoundTag (const statementInfo *const st,
15693ae02089SMasatake YAMATO 								const tokenInfo *const nameToken)
15703ae02089SMasatake YAMATO {
15716248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
15723ae02089SMasatake YAMATO 	if (isType (nameToken, TOKEN_NAME))
15733ae02089SMasatake YAMATO 	{
15743ae02089SMasatake YAMATO 		const tagType type = declToTagType (st->declaration);
1575ce990805SThomas Braun 		const bool fileScoped = (bool)
15767d90c743SMasatake YAMATO 				(!(isInputLanguage (Lang_java) ||
15777d90c743SMasatake YAMATO 				   isInputLanguage (Lang_csharp) ||
15787d90c743SMasatake YAMATO 				   isInputLanguage (Lang_vera)));
15793ae02089SMasatake YAMATO 
15803ae02089SMasatake YAMATO 		if (type != TAG_UNDEFINED)
15816248c9a7SMasatake YAMATO 			corkIndex = makeTag (nameToken, st, fileScoped, type);
15823ae02089SMasatake YAMATO 	}
15836248c9a7SMasatake YAMATO 	return corkIndex;
15843ae02089SMasatake YAMATO }
15853ae02089SMasatake YAMATO 
qualifyBlockTag(statementInfo * const st,const tokenInfo * const nameToken)15866248c9a7SMasatake YAMATO static int qualifyBlockTag (statementInfo *const st,
15873ae02089SMasatake YAMATO 							 const tokenInfo *const nameToken)
15883ae02089SMasatake YAMATO {
15896248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
15903ae02089SMasatake YAMATO 	switch (st->declaration)
15913ae02089SMasatake YAMATO 	{
1592682a7f3bSJuan Pablo Civile 
15933ae02089SMasatake YAMATO 		case DECL_CLASS:
15943ae02089SMasatake YAMATO 		case DECL_ENUM:
15953ae02089SMasatake YAMATO 		case DECL_INTERFACE:
15963ae02089SMasatake YAMATO 		case DECL_NAMESPACE:
15973ae02089SMasatake YAMATO 		case DECL_PROGRAM:
15983ae02089SMasatake YAMATO 		case DECL_STRUCT:
15993ae02089SMasatake YAMATO 		case DECL_UNION:
16003ae02089SMasatake YAMATO 		case DECL_TEMPLATE:
16013ae02089SMasatake YAMATO 		case DECL_VERSION:
1602682a7f3bSJuan Pablo Civile 		case DECL_ANNOTATION:
16036248c9a7SMasatake YAMATO 			corkIndex = qualifyCompoundTag (st, nameToken);
16043ae02089SMasatake YAMATO 			break;
16053ae02089SMasatake YAMATO 		default: break;
16063ae02089SMasatake YAMATO 	}
16076248c9a7SMasatake YAMATO 	return corkIndex;
16083ae02089SMasatake YAMATO }
16093ae02089SMasatake YAMATO 
qualifyVariableTag(const statementInfo * const st,const tokenInfo * const nameToken)16106248c9a7SMasatake YAMATO static int qualifyVariableTag (const statementInfo *const st,
16113ae02089SMasatake YAMATO 								const tokenInfo *const nameToken)
16123ae02089SMasatake YAMATO {
16136248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
16143ae02089SMasatake YAMATO 	/*	We have to watch that we do not interpret a declaration of the
16153ae02089SMasatake YAMATO 	 *	form "struct tag;" as a variable definition. In such a case, the
16163ae02089SMasatake YAMATO 	 *	token preceding the name will be a keyword.
16173ae02089SMasatake YAMATO 	 */
16183ae02089SMasatake YAMATO 	if (! isType (nameToken, TOKEN_NAME))
16193ae02089SMasatake YAMATO 		;
16203ae02089SMasatake YAMATO 	else if (st->scope == SCOPE_TYPEDEF)
16216248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);
16223ae02089SMasatake YAMATO 	else if (st->declaration == DECL_EVENT)
16236248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, (bool) (st->member.access == ACCESS_PRIVATE),
16243ae02089SMasatake YAMATO 							 TAG_EVENT);
16253ae02089SMasatake YAMATO 	else if (st->declaration == DECL_PACKAGE)
16266248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, false, TAG_PACKAGE);
1627fddb1356SMasatake YAMATO 	else if (st->declaration == DECL_PACKAGEREF)
16286248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, false, TAG_PACKAGEREF);
16293ae02089SMasatake YAMATO 	else if (st->declaration == DECL_USING && st->assignment)
16306248c9a7SMasatake YAMATO 		corkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);
16313ae02089SMasatake YAMATO 	else if (isValidTypeSpecifier (st->declaration))
16323ae02089SMasatake YAMATO 	{
16333ae02089SMasatake YAMATO 		if (st->notVariable)
16343ae02089SMasatake YAMATO 			;
16353ae02089SMasatake YAMATO 		else if (isMember (st))
16363ae02089SMasatake YAMATO 		{
16377d90c743SMasatake YAMATO 			if (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp))
16386248c9a7SMasatake YAMATO 				corkIndex = makeTag (nameToken, st,
1639ce990805SThomas Braun 									 (bool) (st->member.access == ACCESS_PRIVATE), TAG_FIELD);
16403ae02089SMasatake YAMATO 			else if (st->scope == SCOPE_GLOBAL  ||  st->scope == SCOPE_STATIC)
16416248c9a7SMasatake YAMATO 				corkIndex = makeTag (nameToken, st, true, TAG_MEMBER);
16423ae02089SMasatake YAMATO 		}
16433ae02089SMasatake YAMATO 		else
16443ae02089SMasatake YAMATO 		{
16453ae02089SMasatake YAMATO 			if (st->scope == SCOPE_EXTERN  ||  ! st->haveQualifyingName)
16466248c9a7SMasatake YAMATO 				corkIndex = makeTag (nameToken, st, false, TAG_EXTERN_VAR);
16473ae02089SMasatake YAMATO 			else if (st->inFunction)
16486248c9a7SMasatake YAMATO 				corkIndex = makeTag (nameToken, st, (bool) (st->scope == SCOPE_STATIC),
16493ae02089SMasatake YAMATO 									 TAG_LOCAL);
16503ae02089SMasatake YAMATO 			else
16516248c9a7SMasatake YAMATO 				corkIndex = makeTag (nameToken, st, (bool) (st->scope == SCOPE_STATIC),
16523ae02089SMasatake YAMATO 									 TAG_VARIABLE);
16533ae02089SMasatake YAMATO 		}
16543ae02089SMasatake YAMATO 	}
16556248c9a7SMasatake YAMATO 	return corkIndex;
16563ae02089SMasatake YAMATO }
16573ae02089SMasatake YAMATO 
16583ae02089SMasatake YAMATO /*
16593ae02089SMasatake YAMATO *   Parsing functions
16603ae02089SMasatake YAMATO */
16613ae02089SMasatake YAMATO 
skipToOneOf(const char * const chars)16623ae02089SMasatake YAMATO static int skipToOneOf (const char *const chars)
16633ae02089SMasatake YAMATO {
16643ae02089SMasatake YAMATO 	int c;
16653ae02089SMasatake YAMATO 	do
16663ae02089SMasatake YAMATO 		c = cppGetc ();
16673ae02089SMasatake YAMATO 	while (c != EOF  &&  c != '\0'  &&  strchr (chars, c) == NULL);
16683ae02089SMasatake YAMATO 	return c;
16693ae02089SMasatake YAMATO }
16703ae02089SMasatake YAMATO 
16713ae02089SMasatake YAMATO /*  Skip to the next non-white character.
16723ae02089SMasatake YAMATO  */
skipToNonWhite(void)16733ae02089SMasatake YAMATO static int skipToNonWhite (void)
16743ae02089SMasatake YAMATO {
1675ce990805SThomas Braun 	bool found = false;
16763ae02089SMasatake YAMATO 	int c;
16773ae02089SMasatake YAMATO 
16783ae02089SMasatake YAMATO #if 0
16793ae02089SMasatake YAMATO 	do
16803ae02089SMasatake YAMATO 		c = cppGetc ();
1681951f2c54SMasatake YAMATO 	while (cppIsspace (c));
16823ae02089SMasatake YAMATO #else
16833ae02089SMasatake YAMATO 	while (1)
16843ae02089SMasatake YAMATO 	{
16853ae02089SMasatake YAMATO 		c = cppGetc ();
1686951f2c54SMasatake YAMATO 		if (cppIsspace (c))
1687ce990805SThomas Braun 			found = true;
16883ae02089SMasatake YAMATO 		else
16893ae02089SMasatake YAMATO 			break;
16903ae02089SMasatake YAMATO 	}
16913ae02089SMasatake YAMATO 	if (CollectingSignature && found)
16923ae02089SMasatake YAMATO 		vStringPut (Signature, ' ');
16933ae02089SMasatake YAMATO #endif
16943ae02089SMasatake YAMATO 
16953ae02089SMasatake YAMATO 	return c;
16963ae02089SMasatake YAMATO }
16973ae02089SMasatake YAMATO 
16983ae02089SMasatake YAMATO /*  Skips to the next brace in column 1. This is intended for cases where
16993ae02089SMasatake YAMATO  *  preprocessor constructs result in unbalanced braces.
17003ae02089SMasatake YAMATO  */
skipToFormattedBraceMatch(void)17013ae02089SMasatake YAMATO static void skipToFormattedBraceMatch (void)
17023ae02089SMasatake YAMATO {
17033ae02089SMasatake YAMATO 	int c, next;
17043ae02089SMasatake YAMATO 
17053ae02089SMasatake YAMATO 	c = cppGetc ();
17063ae02089SMasatake YAMATO 	next = cppGetc ();
17073ae02089SMasatake YAMATO 	while (c != EOF  &&  (c != '\n'  ||  next != '}'))
17083ae02089SMasatake YAMATO 	{
17093ae02089SMasatake YAMATO 		c = next;
17103ae02089SMasatake YAMATO 		next = cppGetc ();
17113ae02089SMasatake YAMATO 	}
17123ae02089SMasatake YAMATO }
17133ae02089SMasatake YAMATO 
17143ae02089SMasatake YAMATO /*  Skip to the matching character indicated by the pair string. If skipping
17153ae02089SMasatake YAMATO  *  to a matching brace and any brace is found within a different level of a
17163ae02089SMasatake YAMATO  *  #if conditional statement while brace formatting is in effect, we skip to
17173ae02089SMasatake YAMATO  *  the brace matched by its formatting. It is assumed that we have already
17183ae02089SMasatake YAMATO  *  read the character which starts the group (i.e. the first character of
17193ae02089SMasatake YAMATO  *  "pair").
17203ae02089SMasatake YAMATO  */
skipToMatch(const char * const pair)17213ae02089SMasatake YAMATO static void skipToMatch (const char *const pair)
17223ae02089SMasatake YAMATO {
1723ce990805SThomas Braun 	const bool braceMatching = (bool) (strcmp ("{}", pair) == 0);
1724ce990805SThomas Braun 	const bool braceFormatting = (bool) (cppIsBraceFormat () && braceMatching);
1725b222f319SMasatake YAMATO 	const unsigned int initialLevel = cppGetDirectiveNestLevel ();
17263ae02089SMasatake YAMATO 	const int begin = pair [0], end = pair [1];
17273ae02089SMasatake YAMATO 	const unsigned long inputLineNumber = getInputLineNumber ();
17283ae02089SMasatake YAMATO 	int matchLevel = 1;
17293ae02089SMasatake YAMATO 	int c = '\0';
17303ae02089SMasatake YAMATO 
17313ae02089SMasatake YAMATO 	while (matchLevel > 0  &&  (c = skipToNonWhite ()) != EOF)
17323ae02089SMasatake YAMATO 	{
17333ae02089SMasatake YAMATO 		if (CollectingSignature)
17343ae02089SMasatake YAMATO 			vStringPut (Signature, c);
17353ae02089SMasatake YAMATO 		if (c == begin)
17363ae02089SMasatake YAMATO 		{
17373ae02089SMasatake YAMATO 			++matchLevel;
1738b222f319SMasatake YAMATO 			if (braceFormatting  &&  cppGetDirectiveNestLevel () != initialLevel)
17393ae02089SMasatake YAMATO 			{
17403ae02089SMasatake YAMATO 				skipToFormattedBraceMatch ();
17413ae02089SMasatake YAMATO 				break;
17423ae02089SMasatake YAMATO 			}
17433ae02089SMasatake YAMATO 		}
17443ae02089SMasatake YAMATO 		else if (c == end)
17453ae02089SMasatake YAMATO 		{
17463ae02089SMasatake YAMATO 			--matchLevel;
1747b222f319SMasatake YAMATO 			if (braceFormatting  &&  cppGetDirectiveNestLevel () != initialLevel)
17483ae02089SMasatake YAMATO 			{
17493ae02089SMasatake YAMATO 				skipToFormattedBraceMatch ();
17503ae02089SMasatake YAMATO 				break;
17513ae02089SMasatake YAMATO 			}
17523ae02089SMasatake YAMATO 		}
17533ae02089SMasatake YAMATO 	}
17543ae02089SMasatake YAMATO 	if (c == EOF)
17553ae02089SMasatake YAMATO 	{
17563ae02089SMasatake YAMATO 		verbose ("%s: failed to find match for '%c' at line %lu\n",
17573ae02089SMasatake YAMATO 				getInputFileName (), begin, inputLineNumber);
17583ae02089SMasatake YAMATO 		if (braceMatching)
17593ae02089SMasatake YAMATO 			longjmp (Exception, (int) ExceptionBraceFormattingError);
17603ae02089SMasatake YAMATO 		else
17613ae02089SMasatake YAMATO 			longjmp (Exception, (int) ExceptionFormattingError);
17623ae02089SMasatake YAMATO 	}
17633ae02089SMasatake YAMATO }
17643ae02089SMasatake YAMATO 
skipCppTemplateParameterList(void)17659a7ce233SMasatake YAMATO static void skipCppTemplateParameterList (void)
17669a7ce233SMasatake YAMATO {
17679a7ce233SMasatake YAMATO 	const unsigned long inputLineNumber = getInputLineNumber ();
17689a7ce233SMasatake YAMATO 	int angleBracketsLevel = 1;
17699a7ce233SMasatake YAMATO 	int c = '\0';
17709a7ce233SMasatake YAMATO 
17719a7ce233SMasatake YAMATO 	int roundBracketsLevel = 0;
1772ce990805SThomas Braun 	bool defaultValueExpected = false;
17739a7ce233SMasatake YAMATO 
17749a7ce233SMasatake YAMATO 	while (angleBracketsLevel > 0  &&  (c = skipToNonWhite ()) != EOF)
17759a7ce233SMasatake YAMATO 	{
17769a7ce233SMasatake YAMATO 		if (CollectingSignature)
17779a7ce233SMasatake YAMATO 			vStringPut (Signature, c);
17789a7ce233SMasatake YAMATO 
17799a7ce233SMasatake YAMATO 		if (c == '<')
17809a7ce233SMasatake YAMATO 		{
17819662ea9dSDaniel Garcia 			int x = cppGetc ();
17829662ea9dSDaniel Garcia 			if(x != '<')
17839662ea9dSDaniel Garcia 			{
17849662ea9dSDaniel Garcia 				cppUngetc (x);
17859a7ce233SMasatake YAMATO 				if (roundBracketsLevel == 0)
17869a7ce233SMasatake YAMATO 				{
1787ce990805SThomas Braun 					if (defaultValueExpected == false)
17889a7ce233SMasatake YAMATO 						++angleBracketsLevel;
17899a7ce233SMasatake YAMATO 				}
17909a7ce233SMasatake YAMATO 			}
1791d2d18e81SDaniel Garcia 			else if(CollectingSignature)
17925ad9461fSDaniel Garcia 				vStringPut (Signature, x);
17939662ea9dSDaniel Garcia 		}
17949a7ce233SMasatake YAMATO 		else if (c == '>')
17959a7ce233SMasatake YAMATO 		{
17969662ea9dSDaniel Garcia 			int x = cppGetc ();
17979662ea9dSDaniel Garcia 			if( x != '>')
17989662ea9dSDaniel Garcia 			{
17999662ea9dSDaniel Garcia 				cppUngetc (x);
18009a7ce233SMasatake YAMATO 				if (roundBracketsLevel == 0)
18019a7ce233SMasatake YAMATO 				{
18029a7ce233SMasatake YAMATO 					--angleBracketsLevel;
1803ce990805SThomas Braun 					defaultValueExpected = false;
18049a7ce233SMasatake YAMATO 				}
18059a7ce233SMasatake YAMATO 			}
1806d2d18e81SDaniel Garcia 			else if(CollectingSignature)
18075ad9461fSDaniel Garcia 				vStringPut (Signature, x);
18089662ea9dSDaniel Garcia 		}
18099a7ce233SMasatake YAMATO 		else if (c == '(')
18109a7ce233SMasatake YAMATO 			roundBracketsLevel ++;
18119a7ce233SMasatake YAMATO 		else if (c == ')')
18129a7ce233SMasatake YAMATO 			roundBracketsLevel --;
18139a7ce233SMasatake YAMATO 		else if (c == '=' && (roundBracketsLevel == 0))
1814ce990805SThomas Braun 			defaultValueExpected = true;
18159a7ce233SMasatake YAMATO 		else if (c == ',' && (roundBracketsLevel == 0))
1816ce990805SThomas Braun 			defaultValueExpected = false;
18179a7ce233SMasatake YAMATO 	}
18189a7ce233SMasatake YAMATO 
18199a7ce233SMasatake YAMATO 	if (c == EOF)
18209a7ce233SMasatake YAMATO 	{
18219a7ce233SMasatake YAMATO 		verbose ("%s: failed to find match for '%c' at line %lu\n",
18229a7ce233SMasatake YAMATO 				getInputFileName (), '<', inputLineNumber);
18239a7ce233SMasatake YAMATO 		longjmp (Exception, (int) ExceptionFormattingError);
18249a7ce233SMasatake YAMATO 	}
18259a7ce233SMasatake YAMATO }
18269a7ce233SMasatake YAMATO 
skipParens(void)18273ae02089SMasatake YAMATO static void skipParens (void)
18283ae02089SMasatake YAMATO {
18293ae02089SMasatake YAMATO 	const int c = skipToNonWhite ();
18303ae02089SMasatake YAMATO 
18313ae02089SMasatake YAMATO 	if (c == '(')
18323ae02089SMasatake YAMATO 		skipToMatch ("()");
18333ae02089SMasatake YAMATO 	else
18343ae02089SMasatake YAMATO 		cppUngetc (c);
18353ae02089SMasatake YAMATO }
18363ae02089SMasatake YAMATO 
skipBraces(void)18373ae02089SMasatake YAMATO static void skipBraces (void)
18383ae02089SMasatake YAMATO {
18393ae02089SMasatake YAMATO 	const int c = skipToNonWhite ();
18403ae02089SMasatake YAMATO 
18413ae02089SMasatake YAMATO 	if (c == '{')
18423ae02089SMasatake YAMATO 		skipToMatch ("{}");
18433ae02089SMasatake YAMATO 	else
18443ae02089SMasatake YAMATO 		cppUngetc (c);
18453ae02089SMasatake YAMATO }
18463ae02089SMasatake YAMATO 
analyzeKeyword(const char * const name)18473ae02089SMasatake YAMATO static keywordId analyzeKeyword (const char *const name)
18483ae02089SMasatake YAMATO {
1849a31b37dcSMasatake YAMATO 	const keywordId id = (keywordId) lookupKeyword (name, getInputLanguage ());
18503ae02089SMasatake YAMATO 	return id;
18513ae02089SMasatake YAMATO }
18523ae02089SMasatake YAMATO 
analyzeIdentifier(tokenInfo * const token)18533ae02089SMasatake YAMATO static void analyzeIdentifier (tokenInfo *const token)
18543ae02089SMasatake YAMATO {
1855e8f30158SSzymon Tomasz Stefanek 	const char * name = vStringValue (token->name);
18563ae02089SMasatake YAMATO 
1857f06d11a0SSzymon Tomasz Stefanek 	vString * replacement = NULL;
1858f06d11a0SSzymon Tomasz Stefanek 
1859e8f30158SSzymon Tomasz Stefanek 	if(!isInputLanguage(Lang_java))
18603ae02089SMasatake YAMATO 	{
1861e8f30158SSzymon Tomasz Stefanek 		// C: check for ignored token
1862e8f30158SSzymon Tomasz Stefanek 		// (FIXME: java doesn't support -I... but maybe it should?)
1863f06d11a0SSzymon Tomasz Stefanek 		const cppMacroInfo * macro = cppFindMacro(name);
18643ae02089SMasatake YAMATO 
1865f06d11a0SSzymon Tomasz Stefanek 		if(macro)
1866e8f30158SSzymon Tomasz Stefanek 		{
1867f06d11a0SSzymon Tomasz Stefanek 			if(macro->hasParameterList)
1868e8f30158SSzymon Tomasz Stefanek 			{
1869f06d11a0SSzymon Tomasz Stefanek 				// This old parser does not support macro parameters: we simply assume them to be empty
18703ae02089SMasatake YAMATO 				int c = skipToNonWhite ();
18713ae02089SMasatake YAMATO 
18723ae02089SMasatake YAMATO 				if (c == '(')
18733ae02089SMasatake YAMATO 					skipToMatch ("()");
18743ae02089SMasatake YAMATO 			}
1875f06d11a0SSzymon Tomasz Stefanek 
1876f06d11a0SSzymon Tomasz Stefanek 			if(macro->replacements)
1877f06d11a0SSzymon Tomasz Stefanek 			{
1878f06d11a0SSzymon Tomasz Stefanek 				// There is a replacement: analyze it
1879f06d11a0SSzymon Tomasz Stefanek 				replacement = cppBuildMacroReplacement(macro,NULL,0);
1880f06d11a0SSzymon Tomasz Stefanek 				name = replacement ? vStringValue(replacement) : NULL;
1881f06d11a0SSzymon Tomasz Stefanek 			} else {
1882f06d11a0SSzymon Tomasz Stefanek 				// There is no replacement: just ignore
1883f06d11a0SSzymon Tomasz Stefanek 				name = NULL;
1884f06d11a0SSzymon Tomasz Stefanek 			}
18853ae02089SMasatake YAMATO 		}
18863ae02089SMasatake YAMATO 	}
18873ae02089SMasatake YAMATO 
1888e8f30158SSzymon Tomasz Stefanek 	if(!name)
1889e8f30158SSzymon Tomasz Stefanek 	{
1890e8f30158SSzymon Tomasz Stefanek 		initToken(token);
1891f06d11a0SSzymon Tomasz Stefanek 		if(replacement)
1892f06d11a0SSzymon Tomasz Stefanek 			vStringDelete(replacement);
1893e8f30158SSzymon Tomasz Stefanek 		return;
1894e8f30158SSzymon Tomasz Stefanek 	}
1895e8f30158SSzymon Tomasz Stefanek 
1896e8f30158SSzymon Tomasz Stefanek 	token->keyword = analyzeKeyword (name);
1897e8f30158SSzymon Tomasz Stefanek 
1898e8f30158SSzymon Tomasz Stefanek 	if (token->keyword == KEYWORD_NONE)
1899e8f30158SSzymon Tomasz Stefanek 		token->type = TOKEN_NAME;
1900e8f30158SSzymon Tomasz Stefanek 	else
1901e8f30158SSzymon Tomasz Stefanek 		token->type = TOKEN_KEYWORD;
1902f06d11a0SSzymon Tomasz Stefanek 
1903f06d11a0SSzymon Tomasz Stefanek 	if(replacement)
1904f06d11a0SSzymon Tomasz Stefanek 		vStringDelete(replacement);
1905e8f30158SSzymon Tomasz Stefanek }
1906e8f30158SSzymon Tomasz Stefanek 
readIdentifier(tokenInfo * const token,const int firstChar)19073ae02089SMasatake YAMATO static void readIdentifier (tokenInfo *const token, const int firstChar)
19083ae02089SMasatake YAMATO {
19093ae02089SMasatake YAMATO 	vString *const name = token->name;
19103ae02089SMasatake YAMATO 	int c = firstChar;
1911ce990805SThomas Braun 	bool first = true;
19123ae02089SMasatake YAMATO 
19133ae02089SMasatake YAMATO 	initToken (token);
19143ae02089SMasatake YAMATO 
19153ae02089SMasatake YAMATO 	/* Bug #1585745: strangely, C++ destructors allow whitespace between
19163ae02089SMasatake YAMATO 	 * the ~ and the class name. */
19177d90c743SMasatake YAMATO 	if (isInputLanguage (Lang_cpp) && firstChar == '~')
19183ae02089SMasatake YAMATO 	{
19193ae02089SMasatake YAMATO 		vStringPut (name, c);
19203ae02089SMasatake YAMATO 		c = skipToNonWhite ();
19213ae02089SMasatake YAMATO 	}
19223ae02089SMasatake YAMATO 
19233ae02089SMasatake YAMATO 	do
19243ae02089SMasatake YAMATO 	{
19253ae02089SMasatake YAMATO 		vStringPut (name, c);
19263ae02089SMasatake YAMATO 		if (CollectingSignature)
19273ae02089SMasatake YAMATO 		{
19283ae02089SMasatake YAMATO 			if (!first)
19293ae02089SMasatake YAMATO 				vStringPut (Signature, c);
1930ce990805SThomas Braun 			first = false;
19313ae02089SMasatake YAMATO 		}
19323ae02089SMasatake YAMATO 		c = cppGetc ();
1933b222f319SMasatake YAMATO 	} while (cppIsident (c) || ((isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp)) && (isHighChar (c) || c == '.')));
19343ae02089SMasatake YAMATO 	cppUngetc (c);        /* unget non-identifier character */
19353ae02089SMasatake YAMATO 
19363ae02089SMasatake YAMATO 	analyzeIdentifier (token);
19373ae02089SMasatake YAMATO }
19383ae02089SMasatake YAMATO 
readPackageName(tokenInfo * const token,const int firstChar,bool allowWildCard)1939ce990805SThomas Braun static void readPackageName (tokenInfo *const token, const int firstChar, bool allowWildCard)
19403ae02089SMasatake YAMATO {
19413ae02089SMasatake YAMATO 	vString *const name = token->name;
19423ae02089SMasatake YAMATO 	int c = firstChar;
19433ae02089SMasatake YAMATO 
19443ae02089SMasatake YAMATO 	initToken (token);
19453ae02089SMasatake YAMATO 
1946b222f319SMasatake YAMATO 	while (cppIsident (c)  || (allowWildCard && (c == '*')) ||  c == '.')
19473ae02089SMasatake YAMATO 	{
19483ae02089SMasatake YAMATO 		vStringPut (name, c);
19493ae02089SMasatake YAMATO 		c = cppGetc ();
19503ae02089SMasatake YAMATO 	}
19513ae02089SMasatake YAMATO 	cppUngetc (c);        /* unget non-package character */
19523ae02089SMasatake YAMATO }
19533ae02089SMasatake YAMATO 
readPackageOrNamespace(statementInfo * const st,const declType declaration,bool allowWildCard)1954ce990805SThomas Braun static void readPackageOrNamespace (statementInfo *const st, const declType declaration, bool allowWildCard)
19553ae02089SMasatake YAMATO {
19563ae02089SMasatake YAMATO 	st->declaration = declaration;
19573ae02089SMasatake YAMATO 
19587d90c743SMasatake YAMATO 	if (declaration == DECL_NAMESPACE && !isInputLanguage (Lang_csharp))
19593ae02089SMasatake YAMATO 	{
19603ae02089SMasatake YAMATO 		/* In C++ a namespace is specified one level at a time. */
19613ae02089SMasatake YAMATO 		return;
19623ae02089SMasatake YAMATO 	}
19633ae02089SMasatake YAMATO 	else
19643ae02089SMasatake YAMATO 	{
19653ae02089SMasatake YAMATO 		/* In C#, a namespace can also be specified like a Java package name. */
19663ae02089SMasatake YAMATO 		tokenInfo *const token = activeToken (st);
19673ae02089SMasatake YAMATO 		Assert (isType (token, TOKEN_KEYWORD));
1968fddb1356SMasatake YAMATO 		readPackageName (token, skipToNonWhite (), allowWildCard);
19693ae02089SMasatake YAMATO 		token->type = TOKEN_NAME;
1970ce990805SThomas Braun 		st->gotName = true;
1971ce990805SThomas Braun 		st->haveQualifyingName = true;
19723ae02089SMasatake YAMATO 	}
19733ae02089SMasatake YAMATO }
19743ae02089SMasatake YAMATO 
readVersionName(tokenInfo * const token,const int firstChar)19753ae02089SMasatake YAMATO static void readVersionName (tokenInfo *const token, const int firstChar)
19763ae02089SMasatake YAMATO {
19773ae02089SMasatake YAMATO 	vString *const name = token->name;
19783ae02089SMasatake YAMATO 	int c = firstChar;
19793ae02089SMasatake YAMATO 
19803ae02089SMasatake YAMATO 	initToken (token);
19813ae02089SMasatake YAMATO 
1982b222f319SMasatake YAMATO 	while (cppIsident (c))
19833ae02089SMasatake YAMATO 	{
19843ae02089SMasatake YAMATO 		vStringPut (name, c);
19853ae02089SMasatake YAMATO 		c = cppGetc ();
19863ae02089SMasatake YAMATO 	}
19873ae02089SMasatake YAMATO     cppGetc ();
19883ae02089SMasatake YAMATO }
19893ae02089SMasatake YAMATO 
readVersion(statementInfo * const st)19903ae02089SMasatake YAMATO static void readVersion (statementInfo *const st)
19913ae02089SMasatake YAMATO {
19923ae02089SMasatake YAMATO     tokenInfo *const token = activeToken (st);
19933ae02089SMasatake YAMATO 	Assert (isType (token, TOKEN_KEYWORD));
19943ae02089SMasatake YAMATO     skipToNonWhite ();
19953ae02089SMasatake YAMATO 	readVersionName (token, cppGetc ());
19963ae02089SMasatake YAMATO 	token->type = TOKEN_NAME;
19973ae02089SMasatake YAMATO 	st->declaration = DECL_VERSION;
1998ce990805SThomas Braun 	st->gotName = true;
1999ce990805SThomas Braun 	st->haveQualifyingName = true;
20003ae02089SMasatake YAMATO }
20013ae02089SMasatake YAMATO 
processName(statementInfo * const st)20023ae02089SMasatake YAMATO static void processName (statementInfo *const st)
20033ae02089SMasatake YAMATO {
20043ae02089SMasatake YAMATO 	Assert (isType (activeToken (st), TOKEN_NAME));
20053ae02089SMasatake YAMATO 	if (st->gotName  &&  st->declaration == DECL_NONE)
20063ae02089SMasatake YAMATO 		st->declaration = DECL_BASE;
2007ce990805SThomas Braun 	st->gotName = true;
2008ce990805SThomas Braun 	st->haveQualifyingName = true;
20093ae02089SMasatake YAMATO }
20103ae02089SMasatake YAMATO 
readOperator(statementInfo * const st)20113ae02089SMasatake YAMATO static void readOperator (statementInfo *const st)
20123ae02089SMasatake YAMATO {
20133ae02089SMasatake YAMATO 	const char *const acceptable = "+-*/%^&|~!=<>,[]";
20143ae02089SMasatake YAMATO 	const tokenInfo* const prev = prevToken (st,1);
20153ae02089SMasatake YAMATO 	tokenInfo *const token = activeToken (st);
20163ae02089SMasatake YAMATO 	vString *const name = token->name;
20173ae02089SMasatake YAMATO 	int c = skipToNonWhite ();
20183ae02089SMasatake YAMATO 
20193ae02089SMasatake YAMATO 	/*  When we arrive here, we have the keyword "operator" in 'name'.
20203ae02089SMasatake YAMATO 	 */
20213ae02089SMasatake YAMATO 	if (isType (prev, TOKEN_KEYWORD) && (prev->keyword == KEYWORD_ENUM ||
20223ae02089SMasatake YAMATO 		 prev->keyword == KEYWORD_STRUCT || prev->keyword == KEYWORD_UNION))
20233ae02089SMasatake YAMATO 		;        /* ignore "operator" keyword if preceded by these keywords */
20243ae02089SMasatake YAMATO 	else if (c == '(')
20253ae02089SMasatake YAMATO 	{
20263ae02089SMasatake YAMATO 		/*  Verify whether this is a valid function call (i.e. "()") operator.
20273ae02089SMasatake YAMATO 		 */
20283ae02089SMasatake YAMATO 		if (cppGetc () == ')')
20293ae02089SMasatake YAMATO 		{
20303ae02089SMasatake YAMATO 			vStringPut (name, ' ');  /* always separate operator from keyword */
20313ae02089SMasatake YAMATO 			c = skipToNonWhite ();
20323ae02089SMasatake YAMATO 			if (c == '(')
20333ae02089SMasatake YAMATO 				vStringCatS (name, "()");
20343ae02089SMasatake YAMATO 		}
20353ae02089SMasatake YAMATO 		else
20363ae02089SMasatake YAMATO 		{
20373ae02089SMasatake YAMATO 			skipToMatch ("()");
20383ae02089SMasatake YAMATO 			c = cppGetc ();
20393ae02089SMasatake YAMATO 		}
20403ae02089SMasatake YAMATO 	}
2041b222f319SMasatake YAMATO 	else if (cppIsident1 (c))
20423ae02089SMasatake YAMATO 	{
20433ae02089SMasatake YAMATO 		/*  Handle "new" and "delete" operators, and conversion functions
20443ae02089SMasatake YAMATO 		 *  (per 13.3.1.1.2 [2] of the C++ spec).
20453ae02089SMasatake YAMATO 		 */
2046ce990805SThomas Braun 		bool whiteSpace = true;  /* default causes insertion of space */
20473ae02089SMasatake YAMATO 		do
20483ae02089SMasatake YAMATO 		{
2049951f2c54SMasatake YAMATO 			if (cppIsspace (c))
2050ce990805SThomas Braun 				whiteSpace = true;
20513ae02089SMasatake YAMATO 			else
20523ae02089SMasatake YAMATO 			{
20533ae02089SMasatake YAMATO 				if (whiteSpace)
20543ae02089SMasatake YAMATO 				{
20553ae02089SMasatake YAMATO 					vStringPut (name, ' ');
2056ce990805SThomas Braun 					whiteSpace = false;
20573ae02089SMasatake YAMATO 				}
20583ae02089SMasatake YAMATO 				vStringPut (name, c);
20593ae02089SMasatake YAMATO 			}
20603ae02089SMasatake YAMATO 			c = cppGetc ();
20613ae02089SMasatake YAMATO 		} while (! isOneOf (c, "(;")  &&  c != EOF);
20623ae02089SMasatake YAMATO 	}
20633ae02089SMasatake YAMATO 	else if (isOneOf (c, acceptable))
20643ae02089SMasatake YAMATO 	{
20653ae02089SMasatake YAMATO 		vStringPut (name, ' ');  /* always separate operator from keyword */
20663ae02089SMasatake YAMATO 		do
20673ae02089SMasatake YAMATO 		{
20683ae02089SMasatake YAMATO 			vStringPut (name, c);
20693ae02089SMasatake YAMATO 			c = cppGetc ();
20703ae02089SMasatake YAMATO 		} while (isOneOf (c, acceptable));
20713ae02089SMasatake YAMATO 	}
20723ae02089SMasatake YAMATO 
20733ae02089SMasatake YAMATO 	cppUngetc (c);
20743ae02089SMasatake YAMATO 
20753ae02089SMasatake YAMATO 	token->type	= TOKEN_NAME;
20763ae02089SMasatake YAMATO 	token->keyword = KEYWORD_NONE;
20773ae02089SMasatake YAMATO 	processName (st);
20783ae02089SMasatake YAMATO }
20793ae02089SMasatake YAMATO 
copyToken(tokenInfo * const dest,const tokenInfo * const src)20803ae02089SMasatake YAMATO static void copyToken (tokenInfo *const dest, const tokenInfo *const src)
20813ae02089SMasatake YAMATO {
20823ae02089SMasatake YAMATO 	dest->type         = src->type;
20833ae02089SMasatake YAMATO 	dest->keyword      = src->keyword;
20843ae02089SMasatake YAMATO 	dest->filePosition = src->filePosition;
20853ae02089SMasatake YAMATO 	dest->lineNumber   = src->lineNumber;
20863ae02089SMasatake YAMATO 	vStringCopy (dest->name, src->name);
20873ae02089SMasatake YAMATO }
20883ae02089SMasatake YAMATO 
setAccess(statementInfo * const st,const accessType access)20893ae02089SMasatake YAMATO static void setAccess (statementInfo *const st, const accessType access)
20903ae02089SMasatake YAMATO {
20917d90c743SMasatake YAMATO 	if (isInputLanguage (Lang_d))
20923ae02089SMasatake YAMATO 	{
20933ae02089SMasatake YAMATO 		int c = skipToNonWhite ();
20943ae02089SMasatake YAMATO 
20953ae02089SMasatake YAMATO 		if (c == '{')
20963ae02089SMasatake YAMATO 		{
20973ae02089SMasatake YAMATO 			switch(access)
20983ae02089SMasatake YAMATO 			{
20993ae02089SMasatake YAMATO 				case ACCESS_PRIVATE:
21003ae02089SMasatake YAMATO 					st->declaration = DECL_PRIVATE;
21013ae02089SMasatake YAMATO 					break;
21023ae02089SMasatake YAMATO 				case ACCESS_PUBLIC:
21033ae02089SMasatake YAMATO 					st->declaration = DECL_PUBLIC;
21043ae02089SMasatake YAMATO 					break;
21053ae02089SMasatake YAMATO 				case ACCESS_PROTECTED:
21063ae02089SMasatake YAMATO 					st->declaration = DECL_PROTECTED;
21073ae02089SMasatake YAMATO 					break;
21083ae02089SMasatake YAMATO 				default:
21093ae02089SMasatake YAMATO 					break;
21103ae02089SMasatake YAMATO 			}
21113ae02089SMasatake YAMATO 			st->member.access = access;
21123ae02089SMasatake YAMATO 			cppUngetc (c);
21133ae02089SMasatake YAMATO 		}
21143ae02089SMasatake YAMATO 		else if (c == ':') {
2115ce990805SThomas Braun 			reinitStatement (st, false);
21163ae02089SMasatake YAMATO 			st->member.accessDefault = access;
21173ae02089SMasatake YAMATO 		}
21183ae02089SMasatake YAMATO 		else {
21193ae02089SMasatake YAMATO 			cppUngetc (c);
21203ae02089SMasatake YAMATO 		}
21213ae02089SMasatake YAMATO 	}
21223ae02089SMasatake YAMATO 
21233ae02089SMasatake YAMATO 	if (isMember (st))
21243ae02089SMasatake YAMATO 	{
21257d90c743SMasatake YAMATO 		if (isInputLanguage (Lang_cpp))
21263ae02089SMasatake YAMATO 		{
21273ae02089SMasatake YAMATO 			int c = skipToNonWhite ();
21283ae02089SMasatake YAMATO 
21293ae02089SMasatake YAMATO 			if (c == ':')
2130ce990805SThomas Braun 				reinitStatement (st, false);
21313ae02089SMasatake YAMATO 			else
21323ae02089SMasatake YAMATO 				cppUngetc (c);
21333ae02089SMasatake YAMATO 
21343ae02089SMasatake YAMATO 			st->member.accessDefault = access;
21353ae02089SMasatake YAMATO 		}
21367d90c743SMasatake YAMATO 		else if (isInputLanguage (Lang_d))
21373ae02089SMasatake YAMATO 		{
21383ae02089SMasatake YAMATO 			if (st->parent != NULL &&
21393ae02089SMasatake YAMATO 				(st->parent->declaration == DECL_PRIVATE ||
21403ae02089SMasatake YAMATO 				st->parent->declaration == DECL_PROTECTED ||
21413ae02089SMasatake YAMATO 				st->parent->declaration == DECL_PUBLIC))
21423ae02089SMasatake YAMATO 			{
21433ae02089SMasatake YAMATO 				st->member.access = st->parent->member.access;
21443ae02089SMasatake YAMATO 				return;
21453ae02089SMasatake YAMATO 			}
21463ae02089SMasatake YAMATO 		}
21473ae02089SMasatake YAMATO 		st->member.access = access;
21483ae02089SMasatake YAMATO 	}
21493ae02089SMasatake YAMATO }
21503ae02089SMasatake YAMATO 
discardTypeList(tokenInfo * const token)21513ae02089SMasatake YAMATO static void discardTypeList (tokenInfo *const token)
21523ae02089SMasatake YAMATO {
21533ae02089SMasatake YAMATO 	int c = skipToNonWhite ();
2154b222f319SMasatake YAMATO 	while (cppIsident1 (c))
21553ae02089SMasatake YAMATO 	{
21563ae02089SMasatake YAMATO 		readIdentifier (token, c);
21573ae02089SMasatake YAMATO 		c = skipToNonWhite ();
21583ae02089SMasatake YAMATO 		if (c == '.'  ||  c == ',')
21593ae02089SMasatake YAMATO 			c = skipToNonWhite ();
21603ae02089SMasatake YAMATO 	}
21613ae02089SMasatake YAMATO 	cppUngetc (c);
21623ae02089SMasatake YAMATO }
21633ae02089SMasatake YAMATO 
addParentClass(statementInfo * const st,tokenInfo * const token)21643ae02089SMasatake YAMATO static void addParentClass (statementInfo *const st, tokenInfo *const token)
21653ae02089SMasatake YAMATO {
21663ae02089SMasatake YAMATO 	if (vStringLength (token->name) > 0  &&
21673ae02089SMasatake YAMATO 		vStringLength (st->parentClasses) > 0)
21683ae02089SMasatake YAMATO 	{
21693ae02089SMasatake YAMATO 		vStringPut (st->parentClasses, ',');
21703ae02089SMasatake YAMATO 	}
21713ae02089SMasatake YAMATO 	vStringCat (st->parentClasses, token->name);
21723ae02089SMasatake YAMATO }
21733ae02089SMasatake YAMATO 
readParents(statementInfo * const st,const int qualifier)21743ae02089SMasatake YAMATO static void readParents (statementInfo *const st, const int qualifier)
21753ae02089SMasatake YAMATO {
21763ae02089SMasatake YAMATO 	tokenInfo *const token = newToken ();
21773ae02089SMasatake YAMATO 	tokenInfo *const parent = newToken ();
21783ae02089SMasatake YAMATO 	int c;
21793ae02089SMasatake YAMATO 
21803ae02089SMasatake YAMATO 	do
21813ae02089SMasatake YAMATO 	{
21823ae02089SMasatake YAMATO 		c = skipToNonWhite ();
2183b222f319SMasatake YAMATO 		if (cppIsident1 (c))
21843ae02089SMasatake YAMATO 		{
21853ae02089SMasatake YAMATO 			readIdentifier (token, c);
21863ae02089SMasatake YAMATO 			if (isType (token, TOKEN_NAME))
21873ae02089SMasatake YAMATO 				vStringCat (parent->name, token->name);
21883ae02089SMasatake YAMATO 			else
21893ae02089SMasatake YAMATO 			{
21903ae02089SMasatake YAMATO 				addParentClass (st, parent);
21913ae02089SMasatake YAMATO 				initToken (parent);
21923ae02089SMasatake YAMATO 			}
21933ae02089SMasatake YAMATO 		}
21943ae02089SMasatake YAMATO 		else if (c == qualifier)
21953ae02089SMasatake YAMATO 			vStringPut (parent->name, c);
21963ae02089SMasatake YAMATO 		else if (c == '<')
21973ae02089SMasatake YAMATO 			skipToMatch ("<>");
21983ae02089SMasatake YAMATO 		else if (isType (token, TOKEN_NAME))
21993ae02089SMasatake YAMATO 		{
22003ae02089SMasatake YAMATO 			addParentClass (st, parent);
22013ae02089SMasatake YAMATO 			initToken (parent);
22023ae02089SMasatake YAMATO 		}
22033ae02089SMasatake YAMATO 	} while (c != '{'  &&  c != EOF);
22043ae02089SMasatake YAMATO 	cppUngetc (c);
22053ae02089SMasatake YAMATO 	deleteToken (parent);
22063ae02089SMasatake YAMATO 	deleteToken (token);
22073ae02089SMasatake YAMATO }
22083ae02089SMasatake YAMATO 
skipStatement(statementInfo * const st)22093ae02089SMasatake YAMATO static void skipStatement (statementInfo *const st)
22103ae02089SMasatake YAMATO {
22113ae02089SMasatake YAMATO 	st->declaration = DECL_IGNORE;
22123ae02089SMasatake YAMATO 	skipToOneOf (";");
22133ae02089SMasatake YAMATO }
22143ae02089SMasatake YAMATO 
processAnnotation(statementInfo * const st)221573564124SMasatake YAMATO static void processAnnotation (statementInfo *const st)
2216682a7f3bSJuan Pablo Civile {
2217682a7f3bSJuan Pablo Civile 	st->declaration = DECL_ANNOTATION;
2218682a7f3bSJuan Pablo Civile }
2219682a7f3bSJuan Pablo Civile 
processInterface(statementInfo * const st)22203ae02089SMasatake YAMATO static void processInterface (statementInfo *const st)
22213ae02089SMasatake YAMATO {
22223ae02089SMasatake YAMATO 	st->declaration = DECL_INTERFACE;
22233ae02089SMasatake YAMATO }
22243ae02089SMasatake YAMATO 
checkIsClassEnum(statementInfo * const st,const declType decl)22253ae02089SMasatake YAMATO static void checkIsClassEnum (statementInfo *const st, const declType decl)
22263ae02089SMasatake YAMATO {
22277d90c743SMasatake YAMATO 	if (! isInputLanguage (Lang_cpp) || st->declaration != DECL_ENUM)
22283ae02089SMasatake YAMATO 		st->declaration = decl;
22293ae02089SMasatake YAMATO }
22303ae02089SMasatake YAMATO 
processToken(tokenInfo * const token,statementInfo * const st)22313ae02089SMasatake YAMATO static void processToken (tokenInfo *const token, statementInfo *const st)
22323ae02089SMasatake YAMATO {
2233c92ffe5dSMasatake YAMATO 	switch ((int)token->keyword)        /* is it a reserved word? */
22343ae02089SMasatake YAMATO 	{
22353ae02089SMasatake YAMATO 		default: break;
22363ae02089SMasatake YAMATO 
22373ae02089SMasatake YAMATO 		case KEYWORD_NONE:      processName (st);                       break;
22383ae02089SMasatake YAMATO 		case KEYWORD_ABSTRACT:  st->implementation = IMP_ABSTRACT;      break;
22393ae02089SMasatake YAMATO 		case KEYWORD_ATTRIBUTE: skipParens (); initToken (token);       break;
22403ae02089SMasatake YAMATO 		case KEYWORD_BIND:      st->declaration = DECL_BASE;            break;
22413ae02089SMasatake YAMATO 		case KEYWORD_BIT:       st->declaration = DECL_BASE;            break;
22423ae02089SMasatake YAMATO 		case KEYWORD_CATCH:     skipParens (); skipBraces ();           break;
22433ae02089SMasatake YAMATO 		case KEYWORD_CHAR:      st->declaration = DECL_BASE;            break;
22443ae02089SMasatake YAMATO 		case KEYWORD_CLASS:     checkIsClassEnum (st, DECL_CLASS);      break;
22453ae02089SMasatake YAMATO 		case KEYWORD_CONST:     st->declaration = DECL_BASE;            break;
22463ae02089SMasatake YAMATO 		case KEYWORD_DOUBLE:    st->declaration = DECL_BASE;            break;
22473ae02089SMasatake YAMATO 		case KEYWORD_ENUM:      st->declaration = DECL_ENUM;            break;
22483ae02089SMasatake YAMATO 		case KEYWORD_EXTENDS:   readParents (st, '.');
22493ae02089SMasatake YAMATO 		                        setToken (st, TOKEN_NONE);              break;
22503ae02089SMasatake YAMATO 		case KEYWORD_FLOAT:     st->declaration = DECL_BASE;            break;
22513ae02089SMasatake YAMATO 		case KEYWORD_FUNCTION:  st->declaration = DECL_BASE;            break;
22523ae02089SMasatake YAMATO 		case KEYWORD_FRIEND:    st->scope       = SCOPE_FRIEND;         break;
22533ae02089SMasatake YAMATO 		case KEYWORD_GOTO:      skipStatement (st);                     break;
22543ae02089SMasatake YAMATO 		case KEYWORD_IMPLEMENTS:readParents (st, '.');
22553ae02089SMasatake YAMATO 		                        setToken (st, TOKEN_NONE);              break;
2256fddb1356SMasatake YAMATO 		case KEYWORD_IMPORT:
2257fddb1356SMasatake YAMATO 			if (isInputLanguage (Lang_java))
2258ce990805SThomas Braun 				readPackageOrNamespace (st, DECL_PACKAGEREF, true);
2259fddb1356SMasatake YAMATO 			else
2260fddb1356SMasatake YAMATO 				skipStatement (st);
2261fddb1356SMasatake YAMATO 			break;
22623ae02089SMasatake YAMATO 		case KEYWORD_INT:       st->declaration = DECL_BASE;            break;
22633ae02089SMasatake YAMATO 		case KEYWORD_INTEGER:   st->declaration = DECL_BASE;            break;
22643ae02089SMasatake YAMATO 		case KEYWORD_INTERFACE: processInterface (st);                  break;
22653ae02089SMasatake YAMATO 		case KEYWORD_LOCAL:     setAccess (st, ACCESS_LOCAL);           break;
22663ae02089SMasatake YAMATO 		case KEYWORD_LONG:      st->declaration = DECL_BASE;            break;
22673ae02089SMasatake YAMATO 		case KEYWORD_OPERATOR:  readOperator (st);                      break;
22683ae02089SMasatake YAMATO 		case KEYWORD_MIXIN:     st->declaration = DECL_MIXIN;           break;
22693ae02089SMasatake YAMATO 		case KEYWORD_PRIVATE:   setAccess (st, ACCESS_PRIVATE);         break;
22703ae02089SMasatake YAMATO 		case KEYWORD_PROGRAM:   st->declaration = DECL_PROGRAM;         break;
22713ae02089SMasatake YAMATO 		case KEYWORD_PROTECTED: setAccess (st, ACCESS_PROTECTED);       break;
22723ae02089SMasatake YAMATO 		case KEYWORD_PUBLIC:    setAccess (st, ACCESS_PUBLIC);          break;
22733ae02089SMasatake YAMATO 		case KEYWORD_RETURN:    skipStatement (st);                     break;
22743ae02089SMasatake YAMATO 		case KEYWORD_SHORT:     st->declaration = DECL_BASE;            break;
22753ae02089SMasatake YAMATO 		case KEYWORD_SIGNED:    st->declaration = DECL_BASE;            break;
22763ae02089SMasatake YAMATO 		case KEYWORD_STRING:    st->declaration = DECL_BASE;            break;
22773ae02089SMasatake YAMATO 		case KEYWORD_STRUCT:    checkIsClassEnum (st, DECL_STRUCT);     break;
22783ae02089SMasatake YAMATO 		case KEYWORD_TASK:      st->declaration = DECL_TASK;            break;
22793ae02089SMasatake YAMATO 		case KEYWORD_THROWS:    discardTypeList (token);                break;
22803ae02089SMasatake YAMATO 		case KEYWORD_UNION:     st->declaration = DECL_UNION;           break;
22813ae02089SMasatake YAMATO 		case KEYWORD_UNSIGNED:  st->declaration = DECL_BASE;            break;
22823ae02089SMasatake YAMATO 		case KEYWORD_USING:     st->declaration = DECL_USING;           break;
22833ae02089SMasatake YAMATO 		case KEYWORD_VOID:      st->declaration = DECL_BASE;            break;
22843ae02089SMasatake YAMATO 		case KEYWORD_VOLATILE:  st->declaration = DECL_BASE;            break;
22853ae02089SMasatake YAMATO 		case KEYWORD_VERSION:   readVersion(st);                        break;
22863ae02089SMasatake YAMATO 		case KEYWORD_VIRTUAL:   st->implementation = IMP_VIRTUAL;       break;
22873ae02089SMasatake YAMATO 		case KEYWORD_WCHAR_T:   st->declaration = DECL_BASE;            break;
22883ae02089SMasatake YAMATO 		case KEYWORD_TEMPLATE:
22897d90c743SMasatake YAMATO 			if (isInputLanguage (Lang_d))
22903ae02089SMasatake YAMATO 				st->declaration = DECL_TEMPLATE;
22913ae02089SMasatake YAMATO 			break;
2292ce990805SThomas Braun 		case KEYWORD_NAMESPACE: readPackageOrNamespace (st, DECL_NAMESPACE, false); break;
22933ae02089SMasatake YAMATO 		case KEYWORD_MODULE:
2294ce990805SThomas Braun 		case KEYWORD_PACKAGE:   readPackageOrNamespace (st, DECL_PACKAGE, false);   break;
22953ae02089SMasatake YAMATO 
22963ae02089SMasatake YAMATO 		case KEYWORD_EVENT:
22977d90c743SMasatake YAMATO 			if (isInputLanguage (Lang_csharp))
22983ae02089SMasatake YAMATO 				st->declaration = DECL_EVENT;
22993ae02089SMasatake YAMATO 			break;
23003ae02089SMasatake YAMATO 
23013ae02089SMasatake YAMATO 		case KEYWORD_ALIAS:
23023ae02089SMasatake YAMATO 		case KEYWORD_TYPEDEF:
2303ce990805SThomas Braun 			reinitStatement (st, false);
23043ae02089SMasatake YAMATO 			st->scope = SCOPE_TYPEDEF;
23053ae02089SMasatake YAMATO 			break;
23063ae02089SMasatake YAMATO 
23073ae02089SMasatake YAMATO 		case KEYWORD_EXTERN:
23087d90c743SMasatake YAMATO 			if (! isInputLanguage (Lang_csharp) || !st->gotName)
23093ae02089SMasatake YAMATO 			{
2310ce990805SThomas Braun 				reinitStatement (st, false);
23113ae02089SMasatake YAMATO 				st->scope = SCOPE_EXTERN;
23123ae02089SMasatake YAMATO 				st->declaration = DECL_BASE;
23133ae02089SMasatake YAMATO 			}
23143ae02089SMasatake YAMATO 			break;
23153ae02089SMasatake YAMATO 
23163ae02089SMasatake YAMATO 		case KEYWORD_STATIC:
23177d90c743SMasatake YAMATO 			if (! (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp)))
23183ae02089SMasatake YAMATO 			{
2319ce990805SThomas Braun 				reinitStatement (st, false);
23203ae02089SMasatake YAMATO 				st->scope = SCOPE_STATIC;
23213ae02089SMasatake YAMATO 				st->declaration = DECL_BASE;
23223ae02089SMasatake YAMATO 			}
23233ae02089SMasatake YAMATO 			break;
23243ae02089SMasatake YAMATO 
23253ae02089SMasatake YAMATO 		case KEYWORD_FOR:
23263ae02089SMasatake YAMATO 		case KEYWORD_FOREACH:
23273ae02089SMasatake YAMATO 		case KEYWORD_IF:
23283ae02089SMasatake YAMATO 		case KEYWORD_SWITCH:
23293ae02089SMasatake YAMATO 		case KEYWORD_WHILE:
23303ae02089SMasatake YAMATO 		{
23313ae02089SMasatake YAMATO 			int c = skipToNonWhite ();
23323ae02089SMasatake YAMATO 			if (c == '(')
23333ae02089SMasatake YAMATO 				skipToMatch ("()");
23343ae02089SMasatake YAMATO 			break;
23353ae02089SMasatake YAMATO 		}
23363ae02089SMasatake YAMATO 	}
23373ae02089SMasatake YAMATO }
23383ae02089SMasatake YAMATO 
23393ae02089SMasatake YAMATO /*
23403ae02089SMasatake YAMATO *   Parenthesis handling functions
23413ae02089SMasatake YAMATO */
23423ae02089SMasatake YAMATO 
restartStatement(statementInfo * const st)23433ae02089SMasatake YAMATO static void restartStatement (statementInfo *const st)
23443ae02089SMasatake YAMATO {
23453ae02089SMasatake YAMATO 	tokenInfo *const save = newToken ();
23463ae02089SMasatake YAMATO 	tokenInfo *token = activeToken (st);
23473ae02089SMasatake YAMATO 
23483ae02089SMasatake YAMATO 	copyToken (save, token);
23493ae02089SMasatake YAMATO 	DebugStatement ( if (debug (DEBUG_PARSE)) printf ("<ES>");)
2350ce990805SThomas Braun 	reinitStatement (st, false);
23513ae02089SMasatake YAMATO 	token = activeToken (st);
23523ae02089SMasatake YAMATO 	copyToken (token, save);
23533ae02089SMasatake YAMATO 	deleteToken (save);
23543ae02089SMasatake YAMATO 	processToken (token, st);
23553ae02089SMasatake YAMATO }
23563ae02089SMasatake YAMATO 
23579f084dcaSK.Takata /*  Skips over a mem-initializer-list of a ctor-initializer, defined as:
23583ae02089SMasatake YAMATO  *
23593ae02089SMasatake YAMATO  *  mem-initializer-list:
23603ae02089SMasatake YAMATO  *    mem-initializer, mem-initializer-list
23613ae02089SMasatake YAMATO  *
23623ae02089SMasatake YAMATO  *  mem-initializer:
23633ae02089SMasatake YAMATO  *    [::] [nested-name-spec] class-name (...)
23643ae02089SMasatake YAMATO  *    identifier
23653ae02089SMasatake YAMATO  */
skipMemIntializerList(tokenInfo * const token)23663ae02089SMasatake YAMATO static void skipMemIntializerList (tokenInfo *const token)
23673ae02089SMasatake YAMATO {
23683ae02089SMasatake YAMATO 	int c;
23693ae02089SMasatake YAMATO 
23703ae02089SMasatake YAMATO 	do
23713ae02089SMasatake YAMATO 	{
23723ae02089SMasatake YAMATO 		c = skipToNonWhite ();
2373b222f319SMasatake YAMATO 		while (cppIsident1 (c)  ||  c == ':')
23743ae02089SMasatake YAMATO 		{
23753ae02089SMasatake YAMATO 			if (c != ':')
23763ae02089SMasatake YAMATO 				readIdentifier (token, c);
23773ae02089SMasatake YAMATO 			c = skipToNonWhite ();
23783ae02089SMasatake YAMATO 		}
23793ae02089SMasatake YAMATO 		if (c == '<')
23803ae02089SMasatake YAMATO 		{
23813ae02089SMasatake YAMATO 			skipToMatch ("<>");
23823ae02089SMasatake YAMATO 			c = skipToNonWhite ();
23833ae02089SMasatake YAMATO 		}
23843ae02089SMasatake YAMATO 		if (c == '(')
23853ae02089SMasatake YAMATO 		{
23863ae02089SMasatake YAMATO 			skipToMatch ("()");
23873ae02089SMasatake YAMATO 			c = skipToNonWhite ();
23883ae02089SMasatake YAMATO 		}
23893ae02089SMasatake YAMATO 	} while (c == ',');
23903ae02089SMasatake YAMATO 	cppUngetc (c);
23913ae02089SMasatake YAMATO }
23923ae02089SMasatake YAMATO 
skipMacro(statementInfo * const st)23933ae02089SMasatake YAMATO static void skipMacro (statementInfo *const st)
23943ae02089SMasatake YAMATO {
23953ae02089SMasatake YAMATO 	tokenInfo *const prev2 = prevToken (st, 2);
23963ae02089SMasatake YAMATO 
23973ae02089SMasatake YAMATO 	if (isType (prev2, TOKEN_NAME))
23983ae02089SMasatake YAMATO 		retardToken (st);
23993ae02089SMasatake YAMATO 	skipToMatch ("()");
24003ae02089SMasatake YAMATO }
24013ae02089SMasatake YAMATO 
24023ae02089SMasatake YAMATO /*  Skips over characters following the parameter list. This will be either
24033ae02089SMasatake YAMATO  *  non-ANSI style function declarations or C++ stuff. Our choices:
24043ae02089SMasatake YAMATO  *
24053ae02089SMasatake YAMATO  *  C (K&R):
24063ae02089SMasatake YAMATO  *    int func ();
24073ae02089SMasatake YAMATO  *    int func (one, two) int one; float two; {...}
24083ae02089SMasatake YAMATO  *  C (ANSI):
24093ae02089SMasatake YAMATO  *    int func (int one, float two);
24103ae02089SMasatake YAMATO  *    int func (int one, float two) {...}
24113ae02089SMasatake YAMATO  *  C++:
24123ae02089SMasatake YAMATO  *    int foo (...) [const|volatile] [throw (...)];
24133ae02089SMasatake YAMATO  *    int foo (...) [const|volatile] [throw (...)] [ctor-initializer] {...}
24143ae02089SMasatake YAMATO  *    int foo (...) [const|volatile] [throw (...)] try [ctor-initializer] {...}
24153ae02089SMasatake YAMATO  *        catch (...) {...}
24163ae02089SMasatake YAMATO  */
skipPostArgumentStuff(statementInfo * const st,parenInfo * const info)2417ce990805SThomas Braun static bool skipPostArgumentStuff (
24183ae02089SMasatake YAMATO 		statementInfo *const st, parenInfo *const info)
24193ae02089SMasatake YAMATO {
24203ae02089SMasatake YAMATO 	tokenInfo *const token = activeToken (st);
24213ae02089SMasatake YAMATO 	unsigned int parameters = info->parameterCount;
24223ae02089SMasatake YAMATO 	unsigned int elementCount = 0;
2423ce990805SThomas Braun 	bool restart = false;
2424ce990805SThomas Braun 	bool end = false;
24253ae02089SMasatake YAMATO 	int c = skipToNonWhite ();
24263ae02089SMasatake YAMATO 
24273ae02089SMasatake YAMATO 	do
24283ae02089SMasatake YAMATO 	{
24293ae02089SMasatake YAMATO 		switch (c)
24303ae02089SMasatake YAMATO 		{
24313ae02089SMasatake YAMATO 		case ')':                               break;
24323ae02089SMasatake YAMATO 		case ':': skipMemIntializerList (token);break;  /* ctor-initializer */
24333ae02089SMasatake YAMATO 		case '[': skipToMatch ("[]");           break;
2434ce990805SThomas Braun 		case '=': cppUngetc (c); end = true;    break;
2435ce990805SThomas Braun 		case '{': cppUngetc (c); end = true;    break;
2436ce990805SThomas Braun 		case '}': cppUngetc (c); end = true;    break;
24373ae02089SMasatake YAMATO 
24383ae02089SMasatake YAMATO 		case '(':
24393ae02089SMasatake YAMATO 			if (elementCount > 0)
24403ae02089SMasatake YAMATO 				++elementCount;
24413ae02089SMasatake YAMATO 			skipToMatch ("()");
24423ae02089SMasatake YAMATO 			break;
24433ae02089SMasatake YAMATO 
24443ae02089SMasatake YAMATO 		case ';':
24453ae02089SMasatake YAMATO 			if (parameters == 0  ||  elementCount < 2)
24463ae02089SMasatake YAMATO 			{
24473ae02089SMasatake YAMATO 				cppUngetc (c);
2448ce990805SThomas Braun 				end = true;
24493ae02089SMasatake YAMATO 			}
24503ae02089SMasatake YAMATO 			else if (--parameters == 0)
2451ce990805SThomas Braun 				end = true;
24523ae02089SMasatake YAMATO 			break;
24533ae02089SMasatake YAMATO 
24543ae02089SMasatake YAMATO 		default:
2455b222f319SMasatake YAMATO 			if (cppIsident1 (c))
24563ae02089SMasatake YAMATO 			{
24573ae02089SMasatake YAMATO 				readIdentifier (token, c);
24583ae02089SMasatake YAMATO 				switch (token->keyword)
24593ae02089SMasatake YAMATO 				{
24603ae02089SMasatake YAMATO 				case KEYWORD_ATTRIBUTE: skipParens ();  break;
24613ae02089SMasatake YAMATO 				case KEYWORD_THROW:     skipParens ();  break;
24627d90c743SMasatake YAMATO 				case KEYWORD_IF:        if (isInputLanguage (Lang_d)) skipParens ();  break;
24633ae02089SMasatake YAMATO 				case KEYWORD_TRY:                       break;
246401aa0161SColomban Wendling 				case KEYWORD_NOEXCEPT:                  break;
24653ae02089SMasatake YAMATO 
24663ae02089SMasatake YAMATO 				case KEYWORD_CONST:
24673ae02089SMasatake YAMATO 				case KEYWORD_VOLATILE:
24683ae02089SMasatake YAMATO 					if (vStringLength (Signature) > 0)
24693ae02089SMasatake YAMATO 					{
24703ae02089SMasatake YAMATO 						vStringPut (Signature, ' ');
24713ae02089SMasatake YAMATO 						vStringCat (Signature, token->name);
24723ae02089SMasatake YAMATO 					}
24733ae02089SMasatake YAMATO 					break;
24743ae02089SMasatake YAMATO 				case KEYWORD_ALIAS:
24753ae02089SMasatake YAMATO 				case KEYWORD_CATCH:
24763ae02089SMasatake YAMATO 				case KEYWORD_CLASS:
24773ae02089SMasatake YAMATO 				case KEYWORD_EXPLICIT:
24783ae02089SMasatake YAMATO 				case KEYWORD_EXTERN:
24793ae02089SMasatake YAMATO 				case KEYWORD_FRIEND:
24803ae02089SMasatake YAMATO 				case KEYWORD_INLINE:
24813ae02089SMasatake YAMATO 				case KEYWORD_MUTABLE:
24823ae02089SMasatake YAMATO 				case KEYWORD_NAMESPACE:
24833ae02089SMasatake YAMATO 				case KEYWORD_NEW:
24843ae02089SMasatake YAMATO 				case KEYWORD_NEWCOV:
24853ae02089SMasatake YAMATO 				case KEYWORD_OPERATOR:
24863ae02089SMasatake YAMATO 				case KEYWORD_OVERLOAD:
24873ae02089SMasatake YAMATO 				case KEYWORD_PRIVATE:
24883ae02089SMasatake YAMATO 				case KEYWORD_PROTECTED:
24893ae02089SMasatake YAMATO 				case KEYWORD_PUBLIC:
24903ae02089SMasatake YAMATO 				case KEYWORD_STATIC:
24913ae02089SMasatake YAMATO 				case KEYWORD_TEMPLATE:
24923ae02089SMasatake YAMATO 				case KEYWORD_TYPEDEF:
24933ae02089SMasatake YAMATO 				case KEYWORD_TYPENAME:
24943ae02089SMasatake YAMATO 				case KEYWORD_USING:
24953ae02089SMasatake YAMATO 				case KEYWORD_VIRTUAL:
24963ae02089SMasatake YAMATO 					/* Never allowed within parameter declarations. */
2497ce990805SThomas Braun 					restart = true;
2498ce990805SThomas Braun 					end = true;
24993ae02089SMasatake YAMATO 					break;
25003ae02089SMasatake YAMATO 
25013ae02089SMasatake YAMATO 				default:
2502e1d6ab07SColomban Wendling 					/* "override" and "final" are only keywords in the declaration of a virtual
2503e1d6ab07SColomban Wendling 					 * member function, so need to be handled specially, not as keywords */
25047d90c743SMasatake YAMATO 					if (isInputLanguage(Lang_cpp) && isType (token, TOKEN_NAME) &&
2505e1d6ab07SColomban Wendling 						(strcmp ("override", vStringValue (token->name)) == 0 ||
2506e1d6ab07SColomban Wendling 						 strcmp ("final", vStringValue (token->name)) == 0))
2507e1d6ab07SColomban Wendling 						;
2508e1d6ab07SColomban Wendling 					else if (isType (token, TOKEN_NONE))
25093ae02089SMasatake YAMATO 						;
25103ae02089SMasatake YAMATO 					else if (info->isKnrParamList  &&  info->parameterCount > 0)
25113ae02089SMasatake YAMATO 						++elementCount;
25123ae02089SMasatake YAMATO 					else
25133ae02089SMasatake YAMATO 					{
25143ae02089SMasatake YAMATO 						/*  If we encounter any other identifier immediately
25153ae02089SMasatake YAMATO 						 *  following an empty parameter list, this is almost
25163ae02089SMasatake YAMATO 						 *  certainly one of those Microsoft macro "thingies"
25173ae02089SMasatake YAMATO 						 *  that the automatic source code generation sticks
25183ae02089SMasatake YAMATO 						 *  in. Terminate the current statement.
25193ae02089SMasatake YAMATO 						 */
2520ce990805SThomas Braun 						restart = true;
2521ce990805SThomas Braun 						end = true;
25223ae02089SMasatake YAMATO 					}
25233ae02089SMasatake YAMATO 					break;
25243ae02089SMasatake YAMATO 				}
25253ae02089SMasatake YAMATO 			}
25263ae02089SMasatake YAMATO 		}
25273ae02089SMasatake YAMATO 		if (! end)
25283ae02089SMasatake YAMATO 		{
25293ae02089SMasatake YAMATO 			c = skipToNonWhite ();
25303ae02089SMasatake YAMATO 			if (c == EOF)
2531ce990805SThomas Braun 				end = true;
25323ae02089SMasatake YAMATO 		}
25333ae02089SMasatake YAMATO 	} while (! end);
25343ae02089SMasatake YAMATO 
25353ae02089SMasatake YAMATO 	if (restart)
25363ae02089SMasatake YAMATO 		restartStatement (st);
25373ae02089SMasatake YAMATO 	else
25383ae02089SMasatake YAMATO 		setToken (st, TOKEN_NONE);
25393ae02089SMasatake YAMATO 
2540ce990805SThomas Braun 	return (bool) (c != EOF);
25413ae02089SMasatake YAMATO }
25423ae02089SMasatake YAMATO 
skipJavaThrows(statementInfo * const st)25433ae02089SMasatake YAMATO static void skipJavaThrows (statementInfo *const st)
25443ae02089SMasatake YAMATO {
25453ae02089SMasatake YAMATO 	tokenInfo *const token = activeToken (st);
25463ae02089SMasatake YAMATO 	int c = skipToNonWhite ();
25473ae02089SMasatake YAMATO 
2548b222f319SMasatake YAMATO 	if (cppIsident1 (c))
25493ae02089SMasatake YAMATO 	{
25503ae02089SMasatake YAMATO 		readIdentifier (token, c);
25513ae02089SMasatake YAMATO 		if (token->keyword == KEYWORD_THROWS)
25523ae02089SMasatake YAMATO 		{
25533ae02089SMasatake YAMATO 			do
25543ae02089SMasatake YAMATO 			{
25553ae02089SMasatake YAMATO 				c = skipToNonWhite ();
2556b222f319SMasatake YAMATO 				if (cppIsident1 (c))
25573ae02089SMasatake YAMATO 				{
25583ae02089SMasatake YAMATO 					readIdentifier (token, c);
25593ae02089SMasatake YAMATO 					c = skipToNonWhite ();
25603ae02089SMasatake YAMATO 				}
25613ae02089SMasatake YAMATO 			} while (c == '.'  ||  c == ',');
25623ae02089SMasatake YAMATO 		}
25633ae02089SMasatake YAMATO 	}
25643ae02089SMasatake YAMATO 	cppUngetc (c);
25653ae02089SMasatake YAMATO 	setToken (st, TOKEN_NONE);
25663ae02089SMasatake YAMATO }
25673ae02089SMasatake YAMATO 
analyzePostParens(statementInfo * const st,parenInfo * const info)25683ae02089SMasatake YAMATO static void analyzePostParens (statementInfo *const st, parenInfo *const info)
25693ae02089SMasatake YAMATO {
25703ae02089SMasatake YAMATO 	const unsigned long inputLineNumber = getInputLineNumber ();
25713ae02089SMasatake YAMATO 	int c = skipToNonWhite ();
25723ae02089SMasatake YAMATO 
25733ae02089SMasatake YAMATO 	cppUngetc (c);
25743ae02089SMasatake YAMATO 	if (isOneOf (c, "{;,="))
25753ae02089SMasatake YAMATO 		;
25767d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_java)) {
2577682a7f3bSJuan Pablo Civile 
2578682a7f3bSJuan Pablo Civile 		if (!insideAnnotationBody(st)) {
25793ae02089SMasatake YAMATO 			skipJavaThrows (st);
2580682a7f3bSJuan Pablo Civile 		}
2581ad245287SMasatake YAMATO 	} else {
25823ae02089SMasatake YAMATO 		if (! skipPostArgumentStuff (st, info))
25833ae02089SMasatake YAMATO 		{
25843ae02089SMasatake YAMATO 			verbose (
25853ae02089SMasatake YAMATO 				"%s: confusing argument declarations beginning at line %lu\n",
25863ae02089SMasatake YAMATO 				getInputFileName (), inputLineNumber);
25873ae02089SMasatake YAMATO 			longjmp (Exception, (int) ExceptionFormattingError);
25883ae02089SMasatake YAMATO 		}
25893ae02089SMasatake YAMATO 	}
25903ae02089SMasatake YAMATO }
25913ae02089SMasatake YAMATO 
languageSupportsGenerics(void)2592ce990805SThomas Braun static bool languageSupportsGenerics (void)
25933ae02089SMasatake YAMATO {
2594ce990805SThomas Braun 	return (bool) (isInputLanguage (Lang_cpp) || isInputLanguage (Lang_csharp) ||
25957d90c743SMasatake YAMATO 		isInputLanguage (Lang_java));
25963ae02089SMasatake YAMATO }
25973ae02089SMasatake YAMATO 
processAngleBracket(void)25983ae02089SMasatake YAMATO static void processAngleBracket (void)
25993ae02089SMasatake YAMATO {
26003ae02089SMasatake YAMATO 	int c = cppGetc ();
26013ae02089SMasatake YAMATO 	if (c == '>') {
26023ae02089SMasatake YAMATO 		/* already found match for template */
26033ae02089SMasatake YAMATO 	} else if (languageSupportsGenerics () && c != '<' && c != '=') {
26043ae02089SMasatake YAMATO 		/* this is a template */
26053ae02089SMasatake YAMATO 		cppUngetc (c);
26069a7ce233SMasatake YAMATO 		if (isInputLanguage (Lang_cpp))
26079a7ce233SMasatake YAMATO 			skipCppTemplateParameterList ();
26089a7ce233SMasatake YAMATO 		else
26093ae02089SMasatake YAMATO 			skipToMatch ("<>");
26103ae02089SMasatake YAMATO 	} else if (c == '<') {
26113ae02089SMasatake YAMATO 		/* skip "<<" or "<<=". */
26123ae02089SMasatake YAMATO 		c = cppGetc ();
26133ae02089SMasatake YAMATO 		if (c != '=') {
26143ae02089SMasatake YAMATO 			cppUngetc (c);
26153ae02089SMasatake YAMATO 		}
26163ae02089SMasatake YAMATO 	} else {
26173ae02089SMasatake YAMATO 		cppUngetc (c);
26183ae02089SMasatake YAMATO 	}
26193ae02089SMasatake YAMATO }
26203ae02089SMasatake YAMATO 
parseJavaAnnotation(statementInfo * const st)26213ae02089SMasatake YAMATO static void parseJavaAnnotation (statementInfo *const st)
26223ae02089SMasatake YAMATO {
26233ae02089SMasatake YAMATO 	/*
26243ae02089SMasatake YAMATO 	 * @Override
26253ae02089SMasatake YAMATO 	 * @Target(ElementType.METHOD)
26263ae02089SMasatake YAMATO 	 * @SuppressWarnings(value = "unchecked")
26273ae02089SMasatake YAMATO 	 *
26283ae02089SMasatake YAMATO 	 * But watch out for "@interface"!
26293ae02089SMasatake YAMATO 	 */
26303ae02089SMasatake YAMATO 	tokenInfo *const token = activeToken (st);
26313ae02089SMasatake YAMATO 
26323ae02089SMasatake YAMATO 	int c = skipToNonWhite ();
26333ae02089SMasatake YAMATO 	readIdentifier (token, c);
26343ae02089SMasatake YAMATO 	if (token->keyword == KEYWORD_INTERFACE)
26353ae02089SMasatake YAMATO 	{
26363ae02089SMasatake YAMATO 		/* Oops. This was actually "@interface" defining a new annotation. */
263773564124SMasatake YAMATO 		processAnnotation(st);
26383ae02089SMasatake YAMATO 	}
26393ae02089SMasatake YAMATO 	else
26403ae02089SMasatake YAMATO 	{
26413ae02089SMasatake YAMATO 		/* Bug #1691412: skip any annotation arguments. */
26423ae02089SMasatake YAMATO 		skipParens ();
26433ae02089SMasatake YAMATO 	}
26443ae02089SMasatake YAMATO }
26453ae02089SMasatake YAMATO 
parseParens(statementInfo * const st,parenInfo * const info)26463ae02089SMasatake YAMATO static int parseParens (statementInfo *const st, parenInfo *const info)
26473ae02089SMasatake YAMATO {
26483ae02089SMasatake YAMATO 	tokenInfo *const token = activeToken (st);
26493ae02089SMasatake YAMATO 	unsigned int identifierCount = 0;
26503ae02089SMasatake YAMATO 	unsigned int depth = 1;
2651ce990805SThomas Braun 	bool firstChar = true;
26523ae02089SMasatake YAMATO 	int nextChar = '\0';
26533ae02089SMasatake YAMATO 
2654ce990805SThomas Braun 	CollectingSignature = true;
26553ae02089SMasatake YAMATO 	vStringClear (Signature);
26563ae02089SMasatake YAMATO 	vStringPut (Signature, '(');
26573ae02089SMasatake YAMATO 	info->parameterCount = 1;
26583ae02089SMasatake YAMATO 	do
26593ae02089SMasatake YAMATO 	{
26603ae02089SMasatake YAMATO 		int c = skipToNonWhite ();
26613ae02089SMasatake YAMATO 		vStringPut (Signature, c);
26623ae02089SMasatake YAMATO 
26633ae02089SMasatake YAMATO 		switch (c)
26643ae02089SMasatake YAMATO 		{
26653ae02089SMasatake YAMATO 			case '^':
26663ae02089SMasatake YAMATO 				break;
26673ae02089SMasatake YAMATO 
26683ae02089SMasatake YAMATO 			case '&':
26693ae02089SMasatake YAMATO 			case '*':
2670ce990805SThomas Braun 				info->isPointer = true;
2671ce990805SThomas Braun 				info->isKnrParamList = false;
26723ae02089SMasatake YAMATO 				if (identifierCount == 0)
2673ce990805SThomas Braun 					info->isParamList = false;
26743ae02089SMasatake YAMATO 				initToken (token);
26753ae02089SMasatake YAMATO 				break;
26763ae02089SMasatake YAMATO 
26773ae02089SMasatake YAMATO 			case ':':
2678ce990805SThomas Braun 				info->isKnrParamList = false;
26793ae02089SMasatake YAMATO 				break;
26803ae02089SMasatake YAMATO 
26813ae02089SMasatake YAMATO 			case '.':
2682ce990805SThomas Braun 				info->isNameCandidate = false;
26833ae02089SMasatake YAMATO 				c = cppGetc ();
26843ae02089SMasatake YAMATO 				if (c != '.')
26853ae02089SMasatake YAMATO 				{
26863ae02089SMasatake YAMATO 					cppUngetc (c);
2687ce990805SThomas Braun 					info->isKnrParamList = false;
26883ae02089SMasatake YAMATO 				}
26893ae02089SMasatake YAMATO 				else
26903ae02089SMasatake YAMATO 				{
26913ae02089SMasatake YAMATO 					c = cppGetc ();
26923ae02089SMasatake YAMATO 					if (c != '.')
26933ae02089SMasatake YAMATO 					{
26943ae02089SMasatake YAMATO 						cppUngetc (c);
2695ce990805SThomas Braun 						info->isKnrParamList = false;
26963ae02089SMasatake YAMATO 					}
26973ae02089SMasatake YAMATO 					else
26983ae02089SMasatake YAMATO 						vStringCatS (Signature, "..."); /* variable arg list */
26993ae02089SMasatake YAMATO 				}
27003ae02089SMasatake YAMATO 				break;
27013ae02089SMasatake YAMATO 
27023ae02089SMasatake YAMATO 			case ',':
2703ce990805SThomas Braun 				info->isNameCandidate = false;
27043ae02089SMasatake YAMATO 				if (info->isKnrParamList)
27053ae02089SMasatake YAMATO 				{
27063ae02089SMasatake YAMATO 					++info->parameterCount;
27073ae02089SMasatake YAMATO 					identifierCount = 0;
27083ae02089SMasatake YAMATO 				}
27093ae02089SMasatake YAMATO 				break;
27103ae02089SMasatake YAMATO 
27113ae02089SMasatake YAMATO 			case '=':
2712ce990805SThomas Braun 				info->isKnrParamList = false;
2713ce990805SThomas Braun 				info->isNameCandidate = false;
27143ae02089SMasatake YAMATO 				if (firstChar)
27153ae02089SMasatake YAMATO 				{
2716ce990805SThomas Braun 					info->isParamList = false;
27173ae02089SMasatake YAMATO 					skipMacro (st);
27183ae02089SMasatake YAMATO 					depth = 0;
27193ae02089SMasatake YAMATO 				}
27203ae02089SMasatake YAMATO 				break;
27213ae02089SMasatake YAMATO 
27223ae02089SMasatake YAMATO 			case '[':
2723ce990805SThomas Braun 				info->isKnrParamList = false;
27243ae02089SMasatake YAMATO 				skipToMatch ("[]");
27253ae02089SMasatake YAMATO 				break;
27263ae02089SMasatake YAMATO 
27273ae02089SMasatake YAMATO 			case '<':
2728ce990805SThomas Braun 				info->isKnrParamList = false;
27293ae02089SMasatake YAMATO 				processAngleBracket ();
27303ae02089SMasatake YAMATO 				break;
27313ae02089SMasatake YAMATO 
27323ae02089SMasatake YAMATO 			case ')':
27333ae02089SMasatake YAMATO 				if (firstChar)
27343ae02089SMasatake YAMATO 					info->parameterCount = 0;
27353ae02089SMasatake YAMATO 				--depth;
27363ae02089SMasatake YAMATO 				break;
27373ae02089SMasatake YAMATO 
27383ae02089SMasatake YAMATO 			case '(':
2739ce990805SThomas Braun 				info->isKnrParamList = false;
27403ae02089SMasatake YAMATO 				if (firstChar)
27413ae02089SMasatake YAMATO 				{
2742ce990805SThomas Braun 					info->isNameCandidate = false;
27433ae02089SMasatake YAMATO 					cppUngetc (c);
27443ae02089SMasatake YAMATO 					vStringClear (Signature);
27453ae02089SMasatake YAMATO 					skipMacro (st);
27463ae02089SMasatake YAMATO 					depth = 0;
27473ae02089SMasatake YAMATO 					vStringChop (Signature);
27483ae02089SMasatake YAMATO 				}
27493ae02089SMasatake YAMATO 				else if (isType (token, TOKEN_PAREN_NAME))
27503ae02089SMasatake YAMATO 				{
27513ae02089SMasatake YAMATO 					c = skipToNonWhite ();
27523ae02089SMasatake YAMATO 					if (c == '*')        /* check for function pointer */
27533ae02089SMasatake YAMATO 					{
27543ae02089SMasatake YAMATO 						skipToMatch ("()");
27553ae02089SMasatake YAMATO 						c = skipToNonWhite ();
27563ae02089SMasatake YAMATO 						if (c == '(')
27573ae02089SMasatake YAMATO 							skipToMatch ("()");
27583ae02089SMasatake YAMATO 						else
27593ae02089SMasatake YAMATO 							cppUngetc (c);
27603ae02089SMasatake YAMATO 					}
27613ae02089SMasatake YAMATO 					else
27623ae02089SMasatake YAMATO 					{
27633ae02089SMasatake YAMATO 						cppUngetc (c);
27643ae02089SMasatake YAMATO 						cppUngetc ('(');
2765ce990805SThomas Braun 						info->nestedArgs = true;
27663ae02089SMasatake YAMATO 					}
27673ae02089SMasatake YAMATO 				}
27683ae02089SMasatake YAMATO 				else
27693ae02089SMasatake YAMATO 					++depth;
27703ae02089SMasatake YAMATO 				break;
27713ae02089SMasatake YAMATO 
27723ae02089SMasatake YAMATO 			default:
27737d90c743SMasatake YAMATO 				if (c == '@' && isInputLanguage (Lang_java))
27743ae02089SMasatake YAMATO 				{
27753ae02089SMasatake YAMATO 					parseJavaAnnotation(st);
27763ae02089SMasatake YAMATO 				}
2777b222f319SMasatake YAMATO 				else if (cppIsident1 (c))
27783ae02089SMasatake YAMATO 				{
27793ae02089SMasatake YAMATO 					if (++identifierCount > 1)
2780ce990805SThomas Braun 						info->isKnrParamList = false;
27813ae02089SMasatake YAMATO 					readIdentifier (token, c);
27823ae02089SMasatake YAMATO 					if (isType (token, TOKEN_NAME)  &&  info->isNameCandidate)
27833ae02089SMasatake YAMATO 						token->type = TOKEN_PAREN_NAME;
27843ae02089SMasatake YAMATO 					else if (isType (token, TOKEN_KEYWORD))
27853ae02089SMasatake YAMATO 					{
27863ae02089SMasatake YAMATO 						if (token->keyword != KEYWORD_CONST &&
27873ae02089SMasatake YAMATO 							token->keyword != KEYWORD_VOLATILE)
27883ae02089SMasatake YAMATO 						{
2789ce990805SThomas Braun 							info->isKnrParamList = false;
2790ce990805SThomas Braun 							info->isNameCandidate = false;
27913ae02089SMasatake YAMATO 						}
27923ae02089SMasatake YAMATO 					}
27933ae02089SMasatake YAMATO 				}
27943ae02089SMasatake YAMATO 				else
27953ae02089SMasatake YAMATO 				{
2796ce990805SThomas Braun 					info->isParamList     = false;
2797ce990805SThomas Braun 					info->isKnrParamList  = false;
2798ce990805SThomas Braun 					info->isNameCandidate = false;
2799ce990805SThomas Braun 					info->invalidContents = true;
28003ae02089SMasatake YAMATO 				}
28013ae02089SMasatake YAMATO 				break;
28023ae02089SMasatake YAMATO 		}
2803ce990805SThomas Braun 		firstChar = false;
28043ae02089SMasatake YAMATO 	} while (! info->nestedArgs  &&  depth > 0  &&
28053ae02089SMasatake YAMATO 			 (info->isKnrParamList  ||  info->isNameCandidate));
28063ae02089SMasatake YAMATO 
28073ae02089SMasatake YAMATO 	if (! info->nestedArgs) while (depth > 0)
28083ae02089SMasatake YAMATO 	{
28093ae02089SMasatake YAMATO 		skipToMatch ("()");
28103ae02089SMasatake YAMATO 		--depth;
28113ae02089SMasatake YAMATO 	}
28123ae02089SMasatake YAMATO 
28133ae02089SMasatake YAMATO 	if (! info->isNameCandidate)
28143ae02089SMasatake YAMATO 		initToken (token);
28153ae02089SMasatake YAMATO 
28163ae02089SMasatake YAMATO 	if (info->isKnrParamList)
28173ae02089SMasatake YAMATO 		vStringClear (Signature);
2818ce990805SThomas Braun 	CollectingSignature = false;
28193ae02089SMasatake YAMATO 	return nextChar;
28203ae02089SMasatake YAMATO }
28213ae02089SMasatake YAMATO 
initParenInfo(parenInfo * const info)28223ae02089SMasatake YAMATO static void initParenInfo (parenInfo *const info)
28233ae02089SMasatake YAMATO {
2824ce990805SThomas Braun 	info->isPointer				= false;
2825ce990805SThomas Braun 	info->isParamList			= true;
28267d90c743SMasatake YAMATO 	info->isKnrParamList		= isInputLanguage (Lang_c);
2827ce990805SThomas Braun 	info->isNameCandidate		= true;
2828ce990805SThomas Braun 	info->invalidContents		= false;
2829ce990805SThomas Braun 	info->nestedArgs			= false;
28303ae02089SMasatake YAMATO 	info->parameterCount		= 0;
28313ae02089SMasatake YAMATO }
28323ae02089SMasatake YAMATO 
analyzeParens(statementInfo * const st)28333ae02089SMasatake YAMATO static void analyzeParens (statementInfo *const st)
28343ae02089SMasatake YAMATO {
28353ae02089SMasatake YAMATO 	tokenInfo *const prev = prevToken (st, 1);
28360c5ba53dSSzymon Tomasz Stefanek 	const tokenInfo *const prev2 = prevToken (st, 2);
28373ae02089SMasatake YAMATO 
28380c5ba53dSSzymon Tomasz Stefanek 	if (
28390c5ba53dSSzymon Tomasz Stefanek 			st->inFunction &&
28400c5ba53dSSzymon Tomasz Stefanek 			!st->assignment &&
28410c5ba53dSSzymon Tomasz Stefanek 			!(
28420c5ba53dSSzymon Tomasz Stefanek 				/* C++: Accept Type var(...) as variable; */
28430c5ba53dSSzymon Tomasz Stefanek 				isInputLanguage(Lang_cpp) &&
28440c5ba53dSSzymon Tomasz Stefanek 				isType(prev,TOKEN_NAME) &&
28450c5ba53dSSzymon Tomasz Stefanek 				isType(prev2,TOKEN_NAME)
28460c5ba53dSSzymon Tomasz Stefanek 			)
28470c5ba53dSSzymon Tomasz Stefanek 		)
28480c5ba53dSSzymon Tomasz Stefanek 	{
2849ce990805SThomas Braun 		st->notVariable = true;
28500c5ba53dSSzymon Tomasz Stefanek 	}
28510c5ba53dSSzymon Tomasz Stefanek 
28523ae02089SMasatake YAMATO 	if (! isType (prev, TOKEN_NONE))  /* in case of ignored enclosing macros */
28533ae02089SMasatake YAMATO 	{
28543ae02089SMasatake YAMATO 		tokenInfo *const token = activeToken (st);
28553ae02089SMasatake YAMATO 		parenInfo info;
28563ae02089SMasatake YAMATO 		int c;
28573ae02089SMasatake YAMATO 
28583ae02089SMasatake YAMATO 		initParenInfo (&info);
28593ae02089SMasatake YAMATO 		parseParens (st, &info);
28603ae02089SMasatake YAMATO 		c = skipToNonWhite ();
28613ae02089SMasatake YAMATO 		cppUngetc (c);
28623ae02089SMasatake YAMATO 		if (info.invalidContents)
28630c5ba53dSSzymon Tomasz Stefanek 		{
28640c5ba53dSSzymon Tomasz Stefanek 			/* FIXME: This breaks parsing of variable instantiations that have
28650c5ba53dSSzymon Tomasz Stefanek 			   constants as parameters: Type var(0) or Type var("..."). */
2866ce990805SThomas Braun 			reinitStatement (st, false);
2867bae7d616SMasatake YAMATO 		}
2868bae7d616SMasatake YAMATO 		else if (info.isNameCandidate  &&  isType (token, TOKEN_PAREN_NAME)  &&
28693ae02089SMasatake YAMATO 				 ! st->gotParenName  &&
28703ae02089SMasatake YAMATO 				 (! info.isParamList || ! st->haveQualifyingName  ||
28713ae02089SMasatake YAMATO 				  c == '('  ||
28727d90c743SMasatake YAMATO 				  (c == '='  &&  st->implementation != IMP_VIRTUAL && !isInputLanguage (Lang_cpp)) ||
28733ae02089SMasatake YAMATO 				  (st->declaration == DECL_NONE  &&  isOneOf (c, ",;"))))
28743ae02089SMasatake YAMATO 		{
28753ae02089SMasatake YAMATO 			token->type = TOKEN_NAME;
28763ae02089SMasatake YAMATO 			processName (st);
2877ce990805SThomas Braun 			st->gotParenName = true;
28783ae02089SMasatake YAMATO 			if (! (c == '('  &&  info.nestedArgs))
28793ae02089SMasatake YAMATO 				st->isPointer = info.isPointer;
28807d90c743SMasatake YAMATO 			if (isInputLanguage(Lang_d) && c == '(' && isType (prev, TOKEN_NAME))
28813ae02089SMasatake YAMATO 			{
28823ae02089SMasatake YAMATO 				st->declaration = DECL_FUNCTION_TEMPLATE;
28833ae02089SMasatake YAMATO 				copyToken (st->blockName, prev);
28843ae02089SMasatake YAMATO 			}
28853ae02089SMasatake YAMATO 		}
28863ae02089SMasatake YAMATO 		else if (! st->gotArgs  &&  info.isParamList)
28873ae02089SMasatake YAMATO 		{
2888ce990805SThomas Braun 			st->gotArgs = true;
28893ae02089SMasatake YAMATO 			setToken (st, TOKEN_ARGS);
28903ae02089SMasatake YAMATO 			advanceToken (st);
28913ae02089SMasatake YAMATO 			if (st->scope != SCOPE_TYPEDEF)
28923ae02089SMasatake YAMATO 				analyzePostParens (st, &info);
28933ae02089SMasatake YAMATO 		}
28943ae02089SMasatake YAMATO 		else
28953ae02089SMasatake YAMATO 			setToken (st, TOKEN_NONE);
28963ae02089SMasatake YAMATO 	}
28973ae02089SMasatake YAMATO }
28983ae02089SMasatake YAMATO 
28993ae02089SMasatake YAMATO /*
29003ae02089SMasatake YAMATO *   Token parsing functions
29013ae02089SMasatake YAMATO */
29023ae02089SMasatake YAMATO 
addContext(statementInfo * const st,const tokenInfo * const token)29033ae02089SMasatake YAMATO static void addContext (statementInfo *const st, const tokenInfo* const token)
29043ae02089SMasatake YAMATO {
29053ae02089SMasatake YAMATO 	if (isType (token, TOKEN_NAME))
29063ae02089SMasatake YAMATO 	{
29073ae02089SMasatake YAMATO 		if (vStringLength (st->context->name) > 0)
29083ae02089SMasatake YAMATO 		{
29097d90c743SMasatake YAMATO 			if (isInputLanguage (Lang_c)  ||  isInputLanguage (Lang_cpp))
29103ae02089SMasatake YAMATO 				vStringCatS (st->context->name, "::");
29117d90c743SMasatake YAMATO 			else if (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp) ||
29127d90c743SMasatake YAMATO 				isInputLanguage (Lang_d))
29131da6e7e4SMasatake YAMATO 				vStringPut (st->context->name, '.');
29143ae02089SMasatake YAMATO 		}
29153ae02089SMasatake YAMATO 		vStringCat (st->context->name, token->name);
29163ae02089SMasatake YAMATO 		st->context->type = TOKEN_NAME;
29173ae02089SMasatake YAMATO 	}
29183ae02089SMasatake YAMATO }
29193ae02089SMasatake YAMATO 
inheritingDeclaration(declType decl)2920ce990805SThomas Braun static bool inheritingDeclaration (declType decl)
29213ae02089SMasatake YAMATO {
29223ae02089SMasatake YAMATO 	/* enum base types */
29233ae02089SMasatake YAMATO 	if (decl == DECL_ENUM)
29243ae02089SMasatake YAMATO 	{
2925ce990805SThomas Braun 		return (bool) (isInputLanguage (Lang_cpp) || isInputLanguage (Lang_csharp) ||
29267d90c743SMasatake YAMATO 			isInputLanguage (Lang_d));
29273ae02089SMasatake YAMATO 	}
2928ce990805SThomas Braun 	return (bool) (
29293ae02089SMasatake YAMATO 		decl == DECL_CLASS ||
29303ae02089SMasatake YAMATO 		decl == DECL_STRUCT ||
29313ae02089SMasatake YAMATO 		decl == DECL_INTERFACE);
29323ae02089SMasatake YAMATO }
29333ae02089SMasatake YAMATO 
processColon(statementInfo * const st)29343ae02089SMasatake YAMATO static void processColon (statementInfo *const st)
29353ae02089SMasatake YAMATO {
29367d90c743SMasatake YAMATO 	int c = (isInputLanguage (Lang_cpp) ? cppGetc () : skipToNonWhite ());
2937ce990805SThomas Braun 	const bool doubleColon = (bool) (c == ':');
29383ae02089SMasatake YAMATO 
29393ae02089SMasatake YAMATO 	if (doubleColon)
29403ae02089SMasatake YAMATO 	{
29413ae02089SMasatake YAMATO 		setToken (st, TOKEN_DOUBLE_COLON);
2942ce990805SThomas Braun 		st->haveQualifyingName = false;
29433ae02089SMasatake YAMATO 	}
29443ae02089SMasatake YAMATO 	else
29453ae02089SMasatake YAMATO 	{
29463ae02089SMasatake YAMATO 		cppUngetc (c);
29477d90c743SMasatake YAMATO 		if ((isInputLanguage (Lang_cpp) || isInputLanguage (Lang_csharp) || isInputLanguage (Lang_d))  &&
29483ae02089SMasatake YAMATO 			inheritingDeclaration (st->declaration))
29493ae02089SMasatake YAMATO 		{
29503ae02089SMasatake YAMATO 			readParents (st, ':');
29513ae02089SMasatake YAMATO 		}
29523ae02089SMasatake YAMATO 		else if (parentDecl (st) == DECL_STRUCT)
29533ae02089SMasatake YAMATO 		{
29543ae02089SMasatake YAMATO 			c = skipToOneOf (",;");
29553ae02089SMasatake YAMATO 			if (c == ',')
29563ae02089SMasatake YAMATO 				setToken (st, TOKEN_COMMA);
29573ae02089SMasatake YAMATO 			else if (c == ';')
29583ae02089SMasatake YAMATO 				setToken (st, TOKEN_SEMICOLON);
29593ae02089SMasatake YAMATO 		}
29603ae02089SMasatake YAMATO 		else
29613ae02089SMasatake YAMATO 		{
29623ae02089SMasatake YAMATO 			const tokenInfo *const prev  = prevToken (st, 1);
29633ae02089SMasatake YAMATO 			const tokenInfo *const prev2 = prevToken (st, 2);
29643ae02089SMasatake YAMATO 			if (prev->keyword == KEYWORD_DEFAULT ||
29656891b011SMasatake YAMATO 				prev2->keyword == KEYWORD_CASE)
29663ae02089SMasatake YAMATO 			{
2967ce990805SThomas Braun 				reinitStatement (st, false);
29683ae02089SMasatake YAMATO 			}
29696891b011SMasatake YAMATO 			else if (st->parent != NULL)
29706891b011SMasatake YAMATO 			{
2971a8562400SMasatake YAMATO 				if (prevToken (st->parent, 1)->keyword != KEYWORD_SWITCH)
2972ce990805SThomas Braun 					makeTag (prev, st, false, TAG_LABEL);
2973ce990805SThomas Braun 				reinitStatement (st, false);
29746891b011SMasatake YAMATO 			}
29753ae02089SMasatake YAMATO 		}
29763ae02089SMasatake YAMATO 	}
29773ae02089SMasatake YAMATO }
29783ae02089SMasatake YAMATO 
29793ae02089SMasatake YAMATO /*  Skips over any initializing value which may follow an '=' character in a
29803ae02089SMasatake YAMATO  *  variable definition.
29813ae02089SMasatake YAMATO  */
skipInitializer(statementInfo * const st)29823ae02089SMasatake YAMATO static int skipInitializer (statementInfo *const st)
29833ae02089SMasatake YAMATO {
2984ce990805SThomas Braun 	bool done = false;
29853ae02089SMasatake YAMATO 	int c;
29863ae02089SMasatake YAMATO 
29873ae02089SMasatake YAMATO 	while (! done)
29883ae02089SMasatake YAMATO 	{
29893ae02089SMasatake YAMATO 		c = skipToNonWhite ();
29903ae02089SMasatake YAMATO 
29913ae02089SMasatake YAMATO 		if (c == EOF)
29923ae02089SMasatake YAMATO 			longjmp (Exception, (int) ExceptionFormattingError);
29933ae02089SMasatake YAMATO 		else switch (c)
29943ae02089SMasatake YAMATO 		{
29953ae02089SMasatake YAMATO 			case ',':
2996ce990805SThomas Braun 			case ';': done = true; break;
29973ae02089SMasatake YAMATO 
29983ae02089SMasatake YAMATO 			case '0':
29993ae02089SMasatake YAMATO 				if (st->implementation == IMP_VIRTUAL)
30003ae02089SMasatake YAMATO 					st->implementation = IMP_PURE_VIRTUAL;
30013ae02089SMasatake YAMATO 				break;
30023ae02089SMasatake YAMATO 
30033ae02089SMasatake YAMATO 			case '[': skipToMatch ("[]"); break;
30043ae02089SMasatake YAMATO 			case '(': skipToMatch ("()"); break;
30053ae02089SMasatake YAMATO 			case '{': skipToMatch ("{}"); break;
30063ae02089SMasatake YAMATO 			case '<': processAngleBracket(); break;
30073ae02089SMasatake YAMATO 
30083ae02089SMasatake YAMATO 			case '}':
30093ae02089SMasatake YAMATO 				if (insideEnumBody (st))
3010ce990805SThomas Braun 					done = true;
3011b222f319SMasatake YAMATO 				else if (! cppIsBraceFormat ())
30123ae02089SMasatake YAMATO 				{
30133ae02089SMasatake YAMATO 					verbose ("%s: unexpected closing brace at line %lu\n",
30143ae02089SMasatake YAMATO 							getInputFileName (), getInputLineNumber ());
30153ae02089SMasatake YAMATO 					longjmp (Exception, (int) ExceptionBraceFormattingError);
30163ae02089SMasatake YAMATO 				}
30173ae02089SMasatake YAMATO 				break;
30183ae02089SMasatake YAMATO 
30193ae02089SMasatake YAMATO 			default: break;
30203ae02089SMasatake YAMATO 		}
30213ae02089SMasatake YAMATO 	}
30223ae02089SMasatake YAMATO 	return c;
30233ae02089SMasatake YAMATO }
30243ae02089SMasatake YAMATO 
processInitializer(statementInfo * const st)30253ae02089SMasatake YAMATO static void processInitializer (statementInfo *const st)
30263ae02089SMasatake YAMATO {
3027ce990805SThomas Braun 	const bool inEnumBody = insideEnumBody (st);
30283ae02089SMasatake YAMATO 	int c = cppGetc ();
30293ae02089SMasatake YAMATO 
30303ae02089SMasatake YAMATO 	if (c != '=')
30313ae02089SMasatake YAMATO 	{
30323ae02089SMasatake YAMATO 		cppUngetc (c);
30333ae02089SMasatake YAMATO 		c = skipInitializer (st);
3034ce990805SThomas Braun 		st->assignment = true;
30353ae02089SMasatake YAMATO 		if (c == ';')
30363ae02089SMasatake YAMATO 			setToken (st, TOKEN_SEMICOLON);
30373ae02089SMasatake YAMATO 		else if (c == ',')
30383ae02089SMasatake YAMATO 			setToken (st, TOKEN_COMMA);
30393ae02089SMasatake YAMATO 		else if (c == '}'  &&  inEnumBody)
30403ae02089SMasatake YAMATO 		{
30413ae02089SMasatake YAMATO 			cppUngetc (c);
30423ae02089SMasatake YAMATO 			setToken (st, TOKEN_COMMA);
30433ae02089SMasatake YAMATO 		}
30443ae02089SMasatake YAMATO 		if (st->scope == SCOPE_EXTERN)
30453ae02089SMasatake YAMATO 			st->scope = SCOPE_GLOBAL;
30463ae02089SMasatake YAMATO 	}
30473ae02089SMasatake YAMATO }
30483ae02089SMasatake YAMATO 
parseIdentifier(statementInfo * const st,const int c)30493ae02089SMasatake YAMATO static void parseIdentifier (statementInfo *const st, const int c)
30503ae02089SMasatake YAMATO {
30513ae02089SMasatake YAMATO 	tokenInfo *const token = activeToken (st);
30523ae02089SMasatake YAMATO 
30533ae02089SMasatake YAMATO 	readIdentifier (token, c);
30543ae02089SMasatake YAMATO 	if (! isType (token, TOKEN_NONE))
30553ae02089SMasatake YAMATO 		processToken (token, st);
30563ae02089SMasatake YAMATO }
30573ae02089SMasatake YAMATO 
parseGeneralToken(statementInfo * const st,const int c)30583ae02089SMasatake YAMATO static void parseGeneralToken (statementInfo *const st, const int c)
30593ae02089SMasatake YAMATO {
30603ae02089SMasatake YAMATO 	const tokenInfo *const prev = prevToken (st, 1);
30613ae02089SMasatake YAMATO 
3062b222f319SMasatake YAMATO 	if (cppIsident1 (c) || (isInputLanguage (Lang_java) && isHighChar (c)))
30633ae02089SMasatake YAMATO 	{
3064682a7f3bSJuan Pablo Civile 
30653ae02089SMasatake YAMATO 		parseIdentifier (st, c);
30663ae02089SMasatake YAMATO 		if (isType (st->context, TOKEN_NAME) &&
30673ae02089SMasatake YAMATO 			isType (activeToken (st), TOKEN_NAME) && isType (prev, TOKEN_NAME))
30683ae02089SMasatake YAMATO 		{
30693ae02089SMasatake YAMATO 			initToken (st->context);
30703ae02089SMasatake YAMATO 		}
30713ae02089SMasatake YAMATO 	}
30723ae02089SMasatake YAMATO 	else if (c == '.' || c == '-')
30733ae02089SMasatake YAMATO 	{
30743ae02089SMasatake YAMATO 		if (! st->assignment)
3075ce990805SThomas Braun 			st->notVariable = true;
30763ae02089SMasatake YAMATO 		if (c == '-')
30773ae02089SMasatake YAMATO 		{
30783ae02089SMasatake YAMATO 			int c2 = cppGetc ();
30793ae02089SMasatake YAMATO 			if (c2 != '>')
30803ae02089SMasatake YAMATO 				cppUngetc (c2);
30813ae02089SMasatake YAMATO 		}
30823ae02089SMasatake YAMATO 	}
30833ae02089SMasatake YAMATO 	else if (c == '!' || c == '>')
30843ae02089SMasatake YAMATO 	{
30853ae02089SMasatake YAMATO 		int c2 = cppGetc ();
30863ae02089SMasatake YAMATO 		if (c2 != '=')
30873ae02089SMasatake YAMATO 			cppUngetc (c2);
30883ae02089SMasatake YAMATO 	}
30897d90c743SMasatake YAMATO 	else if (c == '@' && isInputLanguage (Lang_java))
30903ae02089SMasatake YAMATO 	{
30913ae02089SMasatake YAMATO 		parseJavaAnnotation (st);
30923ae02089SMasatake YAMATO 	}
30933ae02089SMasatake YAMATO 	else if (isExternCDecl (st, c))
30943ae02089SMasatake YAMATO 	{
30953ae02089SMasatake YAMATO 		st->declaration = DECL_NOMANGLE;
30963ae02089SMasatake YAMATO 		st->scope = SCOPE_GLOBAL;
3097682a7f3bSJuan Pablo Civile 	} else if (c == STRING_SYMBOL) {
3098682a7f3bSJuan Pablo Civile 		setToken(st, TOKEN_NONE);
30993ae02089SMasatake YAMATO 	}
31003ae02089SMasatake YAMATO }
31013ae02089SMasatake YAMATO 
31023ae02089SMasatake YAMATO /*  Reads characters from the pre-processor and assembles tokens, setting
31033ae02089SMasatake YAMATO  *  the current statement state.
31043ae02089SMasatake YAMATO  */
nextToken(statementInfo * const st)31053ae02089SMasatake YAMATO static void nextToken (statementInfo *const st)
31063ae02089SMasatake YAMATO {
31073ae02089SMasatake YAMATO 	tokenInfo *token;
31083ae02089SMasatake YAMATO 	do
31093ae02089SMasatake YAMATO 	{
31103ae02089SMasatake YAMATO 		int c = skipToNonWhite ();
31113ae02089SMasatake YAMATO 		switch (c)
31123ae02089SMasatake YAMATO 		{
31133ae02089SMasatake YAMATO 			case EOF: longjmp (Exception, (int) ExceptionEOF);  break;
31143ae02089SMasatake YAMATO 			case '(': analyzeParens (st);                       break;
31153ae02089SMasatake YAMATO 			case '<': processAngleBracket ();                   break;
3116ce990805SThomas Braun 			case '*': st->haveQualifyingName = false;           break;
31173ae02089SMasatake YAMATO 			case ',': setToken (st, TOKEN_COMMA);               break;
31183ae02089SMasatake YAMATO 			case ':': processColon (st);                        break;
31193ae02089SMasatake YAMATO 			case ';': setToken (st, TOKEN_SEMICOLON);           break;
31203ae02089SMasatake YAMATO 			case '=': processInitializer (st);                  break;
31213ae02089SMasatake YAMATO 			case '[': skipToMatch ("[]");                       break;
31223ae02089SMasatake YAMATO 			case '{': setToken (st, TOKEN_BRACE_OPEN);          break;
31233ae02089SMasatake YAMATO 			case '}': setToken (st, TOKEN_BRACE_CLOSE);         break;
31243ae02089SMasatake YAMATO 			default:  parseGeneralToken (st, c);                break;
31253ae02089SMasatake YAMATO 		}
31263ae02089SMasatake YAMATO 		token = activeToken (st);
31273ae02089SMasatake YAMATO 	} while (isType (token, TOKEN_NONE));
31283ae02089SMasatake YAMATO }
31293ae02089SMasatake YAMATO 
31303ae02089SMasatake YAMATO /*
31313ae02089SMasatake YAMATO *   Scanning support functions
31323ae02089SMasatake YAMATO */
31333ae02089SMasatake YAMATO 
31343ae02089SMasatake YAMATO static statementInfo *CurrentStatement = NULL;
31353ae02089SMasatake YAMATO 
newStatement(statementInfo * const parent)31363ae02089SMasatake YAMATO static statementInfo *newStatement (statementInfo *const parent)
31373ae02089SMasatake YAMATO {
31383ae02089SMasatake YAMATO 	statementInfo *const st = xMalloc (1, statementInfo);
31393ae02089SMasatake YAMATO 	unsigned int i;
31403ae02089SMasatake YAMATO 
31413ae02089SMasatake YAMATO 	for (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)
31423ae02089SMasatake YAMATO 		st->token [i] = newToken ();
31433ae02089SMasatake YAMATO 
31443ae02089SMasatake YAMATO 	st->context = newToken ();
31453ae02089SMasatake YAMATO 	st->blockName = newToken ();
31463ae02089SMasatake YAMATO 	st->parentClasses = vStringNew ();
31473ae02089SMasatake YAMATO 
31483ae02089SMasatake YAMATO 	initStatement (st, parent);
31493ae02089SMasatake YAMATO 	CurrentStatement = st;
31503ae02089SMasatake YAMATO 
31513ae02089SMasatake YAMATO 	return st;
31523ae02089SMasatake YAMATO }
31533ae02089SMasatake YAMATO 
deleteStatement(void)31543ae02089SMasatake YAMATO static void deleteStatement (void)
31553ae02089SMasatake YAMATO {
31563ae02089SMasatake YAMATO 	statementInfo *const st = CurrentStatement;
31573ae02089SMasatake YAMATO 	statementInfo *const parent = st->parent;
31583ae02089SMasatake YAMATO 	unsigned int i;
31593ae02089SMasatake YAMATO 
31603ae02089SMasatake YAMATO 	for (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)
31613ae02089SMasatake YAMATO 	{
31623ae02089SMasatake YAMATO 		deleteToken (st->token [i]);       st->token [i] = NULL;
31633ae02089SMasatake YAMATO 	}
31643ae02089SMasatake YAMATO 	deleteToken (st->blockName);           st->blockName = NULL;
31653ae02089SMasatake YAMATO 	deleteToken (st->context);             st->context = NULL;
31663ae02089SMasatake YAMATO 	vStringDelete (st->parentClasses);     st->parentClasses = NULL;
31673ae02089SMasatake YAMATO 	eFree (st);
31683ae02089SMasatake YAMATO 	CurrentStatement = parent;
31693ae02089SMasatake YAMATO }
31703ae02089SMasatake YAMATO 
deleteAllStatements(void)31713ae02089SMasatake YAMATO static void deleteAllStatements (void)
31723ae02089SMasatake YAMATO {
31733ae02089SMasatake YAMATO 	while (CurrentStatement != NULL)
31743ae02089SMasatake YAMATO 		deleteStatement ();
31753ae02089SMasatake YAMATO }
31763ae02089SMasatake YAMATO 
isStatementEnd(const statementInfo * const st)3177ce990805SThomas Braun static bool isStatementEnd (const statementInfo *const st)
31783ae02089SMasatake YAMATO {
31793ae02089SMasatake YAMATO 	const tokenInfo *const token = activeToken (st);
3180ce990805SThomas Braun 	bool isEnd;
31813ae02089SMasatake YAMATO 
31823ae02089SMasatake YAMATO 	if (isType (token, TOKEN_SEMICOLON))
3183ce990805SThomas Braun 		isEnd = true;
31843ae02089SMasatake YAMATO 	else if (isType (token, TOKEN_BRACE_CLOSE))
31853ae02089SMasatake YAMATO 		/* Java and C# do not require semicolons to end a block. Neither do C++
31863ae02089SMasatake YAMATO 		 * namespaces. All other blocks require a semicolon to terminate them.
31873ae02089SMasatake YAMATO 		 */
3188ce990805SThomas Braun 		isEnd = (bool) (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp) ||
31897d90c743SMasatake YAMATO 				 isInputLanguage (Lang_d) || ! isContextualStatement (st));
31903ae02089SMasatake YAMATO 	else
3191ce990805SThomas Braun 		isEnd = false;
31923ae02089SMasatake YAMATO 
31933ae02089SMasatake YAMATO 	return isEnd;
31943ae02089SMasatake YAMATO }
31953ae02089SMasatake YAMATO 
checkStatementEnd(statementInfo * const st,int corkIndex)31966248c9a7SMasatake YAMATO static void checkStatementEnd (statementInfo *const st, int corkIndex)
31973ae02089SMasatake YAMATO {
31983ae02089SMasatake YAMATO 	const tokenInfo *const token = activeToken (st);
31993ae02089SMasatake YAMATO 
32006248c9a7SMasatake YAMATO 	tagEntryInfo *e = getEntryInCorkQueue (corkIndex);
32013671ad72SMasatake YAMATO 	if (e)
32026248c9a7SMasatake YAMATO 		e->extensionFields.endLine = token->lineNumber;
32036248c9a7SMasatake YAMATO 
32043ae02089SMasatake YAMATO 	if (isType (token, TOKEN_COMMA))
3205ce990805SThomas Braun 		reinitStatement (st, true);
32063ae02089SMasatake YAMATO 	else if (isStatementEnd (st))
32073ae02089SMasatake YAMATO 	{
32083ae02089SMasatake YAMATO 		DebugStatement ( if (debug (DEBUG_PARSE)) printf ("<ES>"); )
3209ce990805SThomas Braun 		reinitStatement (st, false);
32103ae02089SMasatake YAMATO 		cppEndStatement ();
32113ae02089SMasatake YAMATO 	}
32123ae02089SMasatake YAMATO 	else
32133ae02089SMasatake YAMATO 	{
32143ae02089SMasatake YAMATO 		cppBeginStatement ();
32153ae02089SMasatake YAMATO 		advanceToken (st);
32163ae02089SMasatake YAMATO 	}
32173ae02089SMasatake YAMATO }
32183ae02089SMasatake YAMATO 
nest(statementInfo * const st,const unsigned int nestLevel)32193ae02089SMasatake YAMATO static void nest (statementInfo *const st, const unsigned int nestLevel)
32203ae02089SMasatake YAMATO {
32213ae02089SMasatake YAMATO 	switch (st->declaration)
32223ae02089SMasatake YAMATO 	{
32233ae02089SMasatake YAMATO 		case DECL_TEMPLATE:
32243ae02089SMasatake YAMATO 		case DECL_VERSION:
3225ce990805SThomas Braun 			st->inFunction = false;
32263ae02089SMasatake YAMATO 		case DECL_CLASS:
32273ae02089SMasatake YAMATO 		case DECL_ENUM:
32283ae02089SMasatake YAMATO 		case DECL_INTERFACE:
32293ae02089SMasatake YAMATO 		case DECL_NAMESPACE:
32303ae02089SMasatake YAMATO 		case DECL_NOMANGLE:
32313ae02089SMasatake YAMATO 		case DECL_PRIVATE:
32323ae02089SMasatake YAMATO 		case DECL_PROTECTED:
32333ae02089SMasatake YAMATO 		case DECL_PUBLIC:
32343ae02089SMasatake YAMATO 		case DECL_STRUCT:
32353ae02089SMasatake YAMATO 		case DECL_UNION:
3236682a7f3bSJuan Pablo Civile 		case DECL_ANNOTATION:
32373ae02089SMasatake YAMATO 			createTags (nestLevel, st);
32383ae02089SMasatake YAMATO 			break;
32393ae02089SMasatake YAMATO 
32403ae02089SMasatake YAMATO 		case DECL_FUNCTION:
32413ae02089SMasatake YAMATO 		case DECL_TASK:
3242ce990805SThomas Braun 			st->inFunction = true;
32433ae02089SMasatake YAMATO 			/* fall through */
32443ae02089SMasatake YAMATO 		default:
3245ce990805SThomas Braun 			if (includeTag (TAG_LOCAL, false) || includeTag (TAG_LABEL, false))
32463ae02089SMasatake YAMATO 				createTags (nestLevel, st);
32473ae02089SMasatake YAMATO 			else
32483ae02089SMasatake YAMATO 				skipToMatch ("{}");
32493ae02089SMasatake YAMATO 			break;
32503ae02089SMasatake YAMATO 	}
32513ae02089SMasatake YAMATO 	advanceToken (st);
32523ae02089SMasatake YAMATO 	setToken (st, TOKEN_BRACE_CLOSE);
32533ae02089SMasatake YAMATO }
32543ae02089SMasatake YAMATO 
tagCheck(statementInfo * const st)32556248c9a7SMasatake YAMATO static int tagCheck (statementInfo *const st)
32563ae02089SMasatake YAMATO {
32573ae02089SMasatake YAMATO 	const tokenInfo *const token = activeToken (st);
32583ae02089SMasatake YAMATO 	const tokenInfo *const prev  = prevToken (st, 1);
32593ae02089SMasatake YAMATO 	const tokenInfo *const prev2 = prevToken (st, 2);
32606248c9a7SMasatake YAMATO 	int corkIndex = CORK_NIL;
32616248c9a7SMasatake YAMATO 
32623ae02089SMasatake YAMATO 	switch (token->type)
32633ae02089SMasatake YAMATO 	{
32643ae02089SMasatake YAMATO 		case TOKEN_NAME:
32653ae02089SMasatake YAMATO 			if (insideEnumBody (st))
32666248c9a7SMasatake YAMATO 				corkIndex = qualifyEnumeratorTag (st, token);
32673ae02089SMasatake YAMATO 			if (st->declaration == DECL_MIXIN)
32686248c9a7SMasatake YAMATO 				corkIndex = makeTag (token, st, false, TAG_MIXIN);
32697d90c743SMasatake YAMATO 			if (isInputLanguage (Lang_vera) && insideInterfaceBody (st))
327090230484SMasatake YAMATO 			{
327190230484SMasatake YAMATO 				/* Quoted from
327290230484SMasatake YAMATO 				   http://www.asic-world.com/vera/hdl1.html#Interface_Declaration
327390230484SMasatake YAMATO 				   ------------------------------------------------
327490230484SMasatake YAMATO 				   interface interface_name
327590230484SMasatake YAMATO 				   {
327690230484SMasatake YAMATO 				   signal_direction [signal_width] signal_name signal_type
327790230484SMasatake YAMATO 				   [skew] [depth value][vca q_value][force][hdl_node "hdl_path"];
327890230484SMasatake YAMATO 				   }
327990230484SMasatake YAMATO 				   Where
328090230484SMasatake YAMATO 				   signal_direction : This can be one of the following
328190230484SMasatake YAMATO 				        input : ...
328290230484SMasatake YAMATO 				        output : ...
328390230484SMasatake YAMATO 				        inout : ...
328490230484SMasatake YAMATO 				   signal_width : The signal_width is a range specifying the width of
328590230484SMasatake YAMATO 				                  a vector signal. It must be in the form [msb:lsb].
328690230484SMasatake YAMATO 						  Interface signals can have any integer lsb value,
328790230484SMasatake YAMATO 						  even a negative value. The default width is 1.
328890230484SMasatake YAMATO 				   signal_name : The signal_name identifies the signal being defined.
328990230484SMasatake YAMATO 				                 It is the Vera name for the HDL signal being connected.
329090230484SMasatake YAMATO 				   signal_type : There are many signals types, most commonly used one are
329190230484SMasatake YAMATO 					NHOLD : ...
329290230484SMasatake YAMATO 					PHOLD : ...
329390230484SMasatake YAMATO 					PHOLD NHOLD : ...
329490230484SMasatake YAMATO 					NSAMPLE : ...
329590230484SMasatake YAMATO 					PSAMPLE : ...
329690230484SMasatake YAMATO 					PSAMPLE NSAMPLE : ...
329790230484SMasatake YAMATO 					CLOCK : ...
329890230484SMasatake YAMATO 					PSAMPLE PHOLD : ...
329990230484SMasatake YAMATO 					NSAMPLE NHOLD : ...
330090230484SMasatake YAMATO 					PSAMPLE PHOLD NSAMPLE NHOLD : ...
330190230484SMasatake YAMATO 				   ------------------------------------------------
330290230484SMasatake YAMATO 				   We want to capture "signal_name" here.
330390230484SMasatake YAMATO 				*/
330490230484SMasatake YAMATO 				if (( isType (prev, TOKEN_KEYWORD)
330590230484SMasatake YAMATO 				      && isSignalDirection(prev) ) ||
330690230484SMasatake YAMATO 				    ( isType (prev2, TOKEN_KEYWORD)
330790230484SMasatake YAMATO 				      && isSignalDirection(prev) ))
33086248c9a7SMasatake YAMATO 					corkIndex = makeTag (token, st, false, TAG_SIGNAL);
330990230484SMasatake YAMATO 			}
33103ae02089SMasatake YAMATO 			break;
33113ae02089SMasatake YAMATO #if 0
33123ae02089SMasatake YAMATO 		case TOKEN_PACKAGE:
33133ae02089SMasatake YAMATO 			if (st->haveQualifyingName)
33146248c9a7SMasatake YAMATO 				corkIndex = makeTag (token, st, false, TAG_PACKAGE);
33153ae02089SMasatake YAMATO 			break;
33163ae02089SMasatake YAMATO #endif
33173ae02089SMasatake YAMATO 		case TOKEN_BRACE_OPEN:
33183ae02089SMasatake YAMATO 			if (isType (prev, TOKEN_ARGS))
33193ae02089SMasatake YAMATO 			{
33203ae02089SMasatake YAMATO 				if (st->declaration == DECL_TEMPLATE)
33216248c9a7SMasatake YAMATO 					corkIndex = qualifyBlockTag (st, prev2);
33223ae02089SMasatake YAMATO 				else if (st->declaration == DECL_FUNCTION_TEMPLATE) {
33236248c9a7SMasatake YAMATO 					corkIndex = qualifyFunctionTag (st, st->blockName);
33243ae02089SMasatake YAMATO 				}
33253ae02089SMasatake YAMATO 				else if (st->haveQualifyingName)
33263ae02089SMasatake YAMATO 				{
33273ae02089SMasatake YAMATO 					if (isType (prev2, TOKEN_NAME))
33283ae02089SMasatake YAMATO 						copyToken (st->blockName, prev2);
33293ae02089SMasatake YAMATO 
33303ae02089SMasatake YAMATO 					/* D declaration templates */
33317d90c743SMasatake YAMATO 					if (isInputLanguage (Lang_d) &&
33323ae02089SMasatake YAMATO 						(st->declaration == DECL_CLASS || st->declaration == DECL_STRUCT ||
33333ae02089SMasatake YAMATO 						st->declaration == DECL_INTERFACE || st->declaration == DECL_UNION))
33346248c9a7SMasatake YAMATO 						corkIndex = qualifyBlockTag (st, prev2);
33350c5ba53dSSzymon Tomasz Stefanek 					else if(isInputLanguage (Lang_cpp) && st->inFunction)
33363ae02089SMasatake YAMATO 					{
33370c5ba53dSSzymon Tomasz Stefanek 						/* Ignore. C/C++ allows nested function prototypes but
33380c5ba53dSSzymon Tomasz Stefanek 						   this code actually catches far too many of them.
33390c5ba53dSSzymon Tomasz Stefanek 						   Better some missing tags than a lot of false positives. */
3340bae7d616SMasatake YAMATO 					}
3341bae7d616SMasatake YAMATO 					else
3342bae7d616SMasatake YAMATO 					{
33437d90c743SMasatake YAMATO 						if (! isInputLanguage (Lang_vera))
33443ae02089SMasatake YAMATO 							st->declaration = DECL_FUNCTION;
33456248c9a7SMasatake YAMATO 						corkIndex = qualifyFunctionTag (st, prev2);
33463ae02089SMasatake YAMATO 					}
33473ae02089SMasatake YAMATO 				}
33483ae02089SMasatake YAMATO 			}
33493ae02089SMasatake YAMATO 			else if (isContextualStatement (st) ||
33503ae02089SMasatake YAMATO 					st->declaration == DECL_VERSION ||
33513ae02089SMasatake YAMATO 					st->declaration == DECL_PROGRAM)
33523ae02089SMasatake YAMATO 			{
33535322c0d0SColomban Wendling 				const tokenInfo *name_token = prev;
33545322c0d0SColomban Wendling 
33555322c0d0SColomban Wendling 				/* C++ 11 allows class <name> final { ... } */
33567d90c743SMasatake YAMATO 				if (isInputLanguage (Lang_cpp) && isType (prev, TOKEN_NAME) &&
33575322c0d0SColomban Wendling 					strcmp("final", vStringValue(prev->name)) == 0 &&
33585322c0d0SColomban Wendling 					isType(prev2, TOKEN_NAME))
33595322c0d0SColomban Wendling 				{
33605322c0d0SColomban Wendling 					name_token = prev2;
33615322c0d0SColomban Wendling 				}
33625322c0d0SColomban Wendling 
33635322c0d0SColomban Wendling 				if (isType (name_token, TOKEN_NAME))
33645322c0d0SColomban Wendling 					copyToken (st->blockName, name_token);
33653ae02089SMasatake YAMATO 				else
33663ae02089SMasatake YAMATO 				{
33673ae02089SMasatake YAMATO 					/*  For an anonymous struct or union we use a unique ID
33683ae02089SMasatake YAMATO 					 *  a number, so that the members can be found.
33693ae02089SMasatake YAMATO 					 */
33703ae02089SMasatake YAMATO 					char buf [20];  /* length of "_anon" + digits  + null */
33713ae02089SMasatake YAMATO 					sprintf (buf, "__anon%d", ++AnonymousID);
33723ae02089SMasatake YAMATO 					vStringCopyS (st->blockName->name, buf);
33733ae02089SMasatake YAMATO 					st->blockName->type = TOKEN_NAME;
33743ae02089SMasatake YAMATO 					st->blockName->keyword = KEYWORD_NONE;
33753ae02089SMasatake YAMATO 				}
33766248c9a7SMasatake YAMATO 				corkIndex = qualifyBlockTag (st, name_token);
33773ae02089SMasatake YAMATO 			}
33787d90c743SMasatake YAMATO 			else if (isInputLanguage (Lang_csharp))
33796248c9a7SMasatake YAMATO 				corkIndex = makeTag (prev, st, false, TAG_PROPERTY);
33803ae02089SMasatake YAMATO 			break;
33813ae02089SMasatake YAMATO 
3382682a7f3bSJuan Pablo Civile 		case TOKEN_KEYWORD:
3383682a7f3bSJuan Pablo Civile 
3384682a7f3bSJuan Pablo Civile 			if (token->keyword == KEYWORD_DEFAULT && isType(prev, TOKEN_ARGS) && insideAnnotationBody(st)) {
33856248c9a7SMasatake YAMATO 				corkIndex = qualifyFunctionDeclTag(st, prev2);
3386682a7f3bSJuan Pablo Civile 			}
3387682a7f3bSJuan Pablo Civile 			break;
3388682a7f3bSJuan Pablo Civile 
33893ae02089SMasatake YAMATO 		case TOKEN_SEMICOLON:
33903ae02089SMasatake YAMATO 		case TOKEN_COMMA:
33913ae02089SMasatake YAMATO 			if (insideEnumBody (st))
33923ae02089SMasatake YAMATO 				;
33933ae02089SMasatake YAMATO 			else if (isType (prev, TOKEN_NAME))
33943ae02089SMasatake YAMATO 			{
33953ae02089SMasatake YAMATO 				if (isContextualKeyword (prev2))
33966248c9a7SMasatake YAMATO 					corkIndex = makeTag (prev, st, true, TAG_EXTERN_VAR);
33973ae02089SMasatake YAMATO 				else
33986248c9a7SMasatake YAMATO 					corkIndex = qualifyVariableTag (st, prev);
33993ae02089SMasatake YAMATO 			}
34003ae02089SMasatake YAMATO 			else if (isType (prev, TOKEN_ARGS)  &&  isType (prev2, TOKEN_NAME))
34013ae02089SMasatake YAMATO 			{
34020c5ba53dSSzymon Tomasz Stefanek 				if (st->isPointer || st->inFunction)
34030c5ba53dSSzymon Tomasz Stefanek 				{
34040c5ba53dSSzymon Tomasz Stefanek 					/* If it looks like a pointer or we are in a function body then
34050c5ba53dSSzymon Tomasz Stefanek 					   it's far more likely to be a variable. */
34066248c9a7SMasatake YAMATO 					corkIndex = qualifyVariableTag (st, prev2);
3407bae7d616SMasatake YAMATO 				}
3408bae7d616SMasatake YAMATO 				else
34096248c9a7SMasatake YAMATO 					corkIndex = qualifyFunctionDeclTag (st, prev2);
34103ae02089SMasatake YAMATO 			}
34117d90c743SMasatake YAMATO 			if (isInputLanguage (Lang_java) && token->type == TOKEN_SEMICOLON && insideEnumBody (st))
34123ae02089SMasatake YAMATO 			{
34133ae02089SMasatake YAMATO 				/* In Java, after an initial enum-like part,
34143ae02089SMasatake YAMATO 				 * a semicolon introduces a class-like part.
34153ae02089SMasatake YAMATO 				 * See Bug #1730485 for the full rationale. */
34163ae02089SMasatake YAMATO 				st->parent->declaration = DECL_CLASS;
34173ae02089SMasatake YAMATO 			}
34183ae02089SMasatake YAMATO 			break;
34193ae02089SMasatake YAMATO 
34203ae02089SMasatake YAMATO 		default: break;
34213ae02089SMasatake YAMATO 	}
34226248c9a7SMasatake YAMATO 
34236248c9a7SMasatake YAMATO 	return corkIndex;
34243ae02089SMasatake YAMATO }
34253ae02089SMasatake YAMATO 
34263ae02089SMasatake YAMATO /*  Parses the current file and decides whether to write out and tags that
34273ae02089SMasatake YAMATO  *  are discovered.
34283ae02089SMasatake YAMATO  */
createTags(const unsigned int nestLevel,statementInfo * const parent)34293ae02089SMasatake YAMATO static void createTags (const unsigned int nestLevel,
34303ae02089SMasatake YAMATO 						statementInfo *const parent)
34313ae02089SMasatake YAMATO {
34323ae02089SMasatake YAMATO 	statementInfo *const st = newStatement (parent);
34333ae02089SMasatake YAMATO 
3434ce990805SThomas Braun 	DebugStatement ( if (nestLevel > 0) debugParseNest (true, nestLevel); )
3435ce990805SThomas Braun 	while (true)
34363ae02089SMasatake YAMATO 	{
34373ae02089SMasatake YAMATO 		tokenInfo *token;
34383ae02089SMasatake YAMATO 
34393ae02089SMasatake YAMATO 		nextToken (st);
34403ae02089SMasatake YAMATO 		token = activeToken (st);
34413ae02089SMasatake YAMATO 		if (isType (token, TOKEN_BRACE_CLOSE))
34423ae02089SMasatake YAMATO 		{
34433ae02089SMasatake YAMATO 			if (nestLevel > 0)
34443ae02089SMasatake YAMATO 				break;
34453ae02089SMasatake YAMATO 			else
34463ae02089SMasatake YAMATO 			{
34473ae02089SMasatake YAMATO 				verbose ("%s: unexpected closing brace at line %lu\n",
34483ae02089SMasatake YAMATO 						getInputFileName (), getInputLineNumber ());
34493ae02089SMasatake YAMATO 				longjmp (Exception, (int) ExceptionBraceFormattingError);
34503ae02089SMasatake YAMATO 			}
34513ae02089SMasatake YAMATO 		}
34523ae02089SMasatake YAMATO 		else if (isType (token, TOKEN_DOUBLE_COLON))
34533ae02089SMasatake YAMATO 		{
34543ae02089SMasatake YAMATO 			addContext (st, prevToken (st, 1));
34553ae02089SMasatake YAMATO 			advanceToken (st);
34563ae02089SMasatake YAMATO 		}
34573ae02089SMasatake YAMATO 		else
34583ae02089SMasatake YAMATO 		{
34596248c9a7SMasatake YAMATO 			int corkIndex = tagCheck (st);
34603ae02089SMasatake YAMATO 			if (isType (token, TOKEN_BRACE_OPEN))
34613ae02089SMasatake YAMATO 				nest (st, nestLevel + 1);
34626248c9a7SMasatake YAMATO 			checkStatementEnd (st, corkIndex);
34633ae02089SMasatake YAMATO 		}
34643ae02089SMasatake YAMATO 	}
34653ae02089SMasatake YAMATO 	deleteStatement ();
3466ce990805SThomas Braun 	DebugStatement ( if (nestLevel > 0) debugParseNest (false, nestLevel - 1); )
34673ae02089SMasatake YAMATO }
34683ae02089SMasatake YAMATO 
findCTags(const unsigned int passCount)34693ae02089SMasatake YAMATO static rescanReason findCTags (const unsigned int passCount)
34703ae02089SMasatake YAMATO {
34713ae02089SMasatake YAMATO 	exception_t exception;
34723ae02089SMasatake YAMATO 	rescanReason rescan;
347316a2541cSMasatake YAMATO 	int kind_for_define = KIND_GHOST_INDEX;
347416a2541cSMasatake YAMATO 	int kind_for_header = KIND_GHOST_INDEX;
34758e55f288SMasatake YAMATO 	int kind_for_param  = KIND_GHOST_INDEX;
347624b256e3SMasatake YAMATO 	int role_for_macro_undef = ROLE_DEFINITION_INDEX;
3477d00bddf9SMasatake YAMATO 	int role_for_macro_condition = ROLE_DEFINITION_INDEX;
347824b256e3SMasatake YAMATO 	int role_for_header_system   = ROLE_DEFINITION_INDEX;
347924b256e3SMasatake YAMATO 	int role_for_header_local   = ROLE_DEFINITION_INDEX;
34803ae02089SMasatake YAMATO 
34813ae02089SMasatake YAMATO 	Assert (passCount < 3);
3482d26963b2SMasatake YAMATO 
3483a332acefSMasatake YAMATO 	AnonymousID = 0;
3484a332acefSMasatake YAMATO 
34857d90c743SMasatake YAMATO 	if (isInputLanguage (Lang_c) || isInputLanguage (Lang_cpp))
348675236314SMasatake YAMATO 	{
348716a2541cSMasatake YAMATO 		kind_for_define = CK_DEFINE;
348816a2541cSMasatake YAMATO 		kind_for_header = CK_HEADER;
34898e55f288SMasatake YAMATO 		kind_for_param = CK_MACRO_PARAM,
34903230cfb0SMasatake YAMATO 		role_for_macro_undef = CR_MACRO_UNDEF;
3491d00bddf9SMasatake YAMATO 		role_for_macro_condition = CR_MACRO_CONDITION;
3492f64fda3dSMasatake YAMATO 		role_for_header_system = CR_HEADER_SYSTEM;
3493f64fda3dSMasatake YAMATO 		role_for_header_local = CR_HEADER_LOCAL;
349475236314SMasatake YAMATO 	}
34957d90c743SMasatake YAMATO 	else if (isInputLanguage (Lang_vera))
349675236314SMasatake YAMATO 	{
349716a2541cSMasatake YAMATO 		kind_for_define = VK_DEFINE;
349816a2541cSMasatake YAMATO 		kind_for_header = VK_HEADER;
34998e55f288SMasatake YAMATO 		kind_for_param  = VK_MACRO_PARAM,
35003230cfb0SMasatake YAMATO 		role_for_macro_undef = VR_MACRO_UNDEF;
3501d00bddf9SMasatake YAMATO 		role_for_macro_condition = VR_MACRO_CONDITION;
3502f64fda3dSMasatake YAMATO 		role_for_header_system = VR_HEADER_SYSTEM;
3503f64fda3dSMasatake YAMATO 		role_for_header_local = VR_HEADER_LOCAL;
350475236314SMasatake YAMATO 	}
350575236314SMasatake YAMATO 
3506ce990805SThomas Braun 	cppInit ((bool) (passCount > 1), isInputLanguage (Lang_csharp), isInputLanguage(Lang_cpp),
3507417dfee6SColomban Wendling 		 isInputLanguage(Lang_vera),
3508d00bddf9SMasatake YAMATO 		 kind_for_define, role_for_macro_undef, role_for_macro_condition, kind_for_param,
3509ee4d2ebdSMasatake YAMATO 		 kind_for_header, role_for_header_system, role_for_header_local,
3510ee4d2ebdSMasatake YAMATO 		 FIELD_UNKNOWN);
3511d26963b2SMasatake YAMATO 
35123ae02089SMasatake YAMATO 	Signature = vStringNew ();
35133ae02089SMasatake YAMATO 
35143ae02089SMasatake YAMATO 	exception = (exception_t) setjmp (Exception);
35153ae02089SMasatake YAMATO 	rescan = RESCAN_NONE;
35163ae02089SMasatake YAMATO 	if (exception == ExceptionNone)
35173ae02089SMasatake YAMATO 		createTags (0, NULL);
35183ae02089SMasatake YAMATO 	else
35193ae02089SMasatake YAMATO 	{
35203ae02089SMasatake YAMATO 		deleteAllStatements ();
35213ae02089SMasatake YAMATO 		if (exception == ExceptionBraceFormattingError  &&  passCount == 1)
35223ae02089SMasatake YAMATO 		{
35233ae02089SMasatake YAMATO 			rescan = RESCAN_FAILED;
35243ae02089SMasatake YAMATO 			verbose ("%s: retrying file with fallback brace matching algorithm\n",
35253ae02089SMasatake YAMATO 					getInputFileName ());
35263ae02089SMasatake YAMATO 		}
35273ae02089SMasatake YAMATO 	}
35283ae02089SMasatake YAMATO 	vStringDelete (Signature);
35293ae02089SMasatake YAMATO 	cppTerminate ();
35303ae02089SMasatake YAMATO 	return rescan;
35313ae02089SMasatake YAMATO }
35323ae02089SMasatake YAMATO 
buildKeywordHash(const langType language,unsigned int idx)35333ae02089SMasatake YAMATO static void buildKeywordHash (const langType language, unsigned int idx)
35343ae02089SMasatake YAMATO {
3535158a3387SMasatake YAMATO 	const size_t count = ARRAY_SIZE (KeywordTable);
35363ae02089SMasatake YAMATO 	size_t i;
35373ae02089SMasatake YAMATO 	for (i = 0  ;  i < count  ;  ++i)
35383ae02089SMasatake YAMATO 	{
35393ae02089SMasatake YAMATO 		const keywordDesc* const p = &KeywordTable [i];
35403ae02089SMasatake YAMATO 		if (p->isValid [idx])
35413ae02089SMasatake YAMATO 			addKeyword (p->name, language, (int) p->id);
35423ae02089SMasatake YAMATO 	}
35433ae02089SMasatake YAMATO }
35443ae02089SMasatake YAMATO 
initializeCParser(const langType language)35453ae02089SMasatake YAMATO static void initializeCParser (const langType language)
35463ae02089SMasatake YAMATO {
35473ae02089SMasatake YAMATO 	Lang_c = language;
35483ae02089SMasatake YAMATO 	buildKeywordHash (language, 0);
35493ae02089SMasatake YAMATO }
3550*081ee612SJiří Techet 
initializeCppParser(const langType language)35513ae02089SMasatake YAMATO static void initializeCppParser (const langType language)
35523ae02089SMasatake YAMATO {
35533ae02089SMasatake YAMATO 	Lang_cpp = language;
35543ae02089SMasatake YAMATO 	buildKeywordHash (language, 1);
35553ae02089SMasatake YAMATO }
35563ae02089SMasatake YAMATO 
OldCParser(void)35575034839dSSzymon Tomasz Stefanek extern parserDefinition* OldCParser (void)
35583ae02089SMasatake YAMATO {
35593ae02089SMasatake YAMATO 	static const char *const extensions [] = { "c", NULL };
3560bce9b9baSMasatake YAMATO 	parserDefinition* def = parserNew ("OldC");
356109ae690fSMasatake YAMATO 	def->kindTable      = CKinds;
35623db72c21SMasatake YAMATO 	def->kindCount  = ARRAY_SIZE (CKinds);
35633ae02089SMasatake YAMATO 	def->extensions = extensions;
35643ae02089SMasatake YAMATO 	def->parser2    = findCTags;
35653ae02089SMasatake YAMATO 	def->initialize = initializeCParser;
3566bce9b9baSMasatake YAMATO 	def->enabled = 0;
3567e484fe2eSMasatake YAMATO 
3568e484fe2eSMasatake YAMATO 	/* cpreprocessor wants corkQueue. */
35696b1a862eSMasatake YAMATO 	def->useCork    = CORK_QUEUE;
35703ae02089SMasatake YAMATO 	return def;
35713ae02089SMasatake YAMATO }
35723ae02089SMasatake YAMATO 
OldCppParser(void)35735034839dSSzymon Tomasz Stefanek extern parserDefinition* OldCppParser (void)
35743ae02089SMasatake YAMATO {
35753ae02089SMasatake YAMATO 	static const char *const extensions [] = {
35768d27f06fSMasatake YAMATO 		"c++", "cc", "cp", "cpp", "cxx",
35778d27f06fSMasatake YAMATO 		"h", "h++", "hh", "hp", "hpp", "hxx", "inl",
35783ae02089SMasatake YAMATO #ifndef CASE_INSENSITIVE_FILENAMES
35793ae02089SMasatake YAMATO 		"C", "H",
35803ae02089SMasatake YAMATO #endif
35813ae02089SMasatake YAMATO 		NULL
35823ae02089SMasatake YAMATO 	};
35838e1e6125SMasatake YAMATO 	static selectLanguage selectors[] = { selectByObjectiveCKeywords,
35848e1e6125SMasatake YAMATO 					      NULL };
35858e1e6125SMasatake YAMATO 
3586bce9b9baSMasatake YAMATO 	parserDefinition* def = parserNew ("OldC++");
358709ae690fSMasatake YAMATO 	def->kindTable      = CKinds;
35883db72c21SMasatake YAMATO 	def->kindCount  = ARRAY_SIZE (CKinds);
35893ae02089SMasatake YAMATO 	def->extensions = extensions;
35903ae02089SMasatake YAMATO 	def->parser2    = findCTags;
35913ae02089SMasatake YAMATO 	def->initialize = initializeCppParser;
35928e1e6125SMasatake YAMATO 	def->selectLanguage = selectors;
3593bce9b9baSMasatake YAMATO 	def->enabled = 0;
3594e484fe2eSMasatake YAMATO 
3595e484fe2eSMasatake YAMATO 	/* cpreprocessor wants corkQueue. */
35966b1a862eSMasatake YAMATO 	def->useCork    = CORK_QUEUE;
35973ae02089SMasatake YAMATO 	return def;
35983ae02089SMasatake YAMATO }
3599