X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/dcaf75eaed37623f27c23241c146ad25910208f3..5c2f3045ca9662b32e0369d10771eecf8dfe0231:/src/cscanner.l?ds=sidebyside diff --git a/src/cscanner.l b/src/cscanner.l index def0183..eddfd1d 100644 --- a/src/cscanner.l +++ b/src/cscanner.l @@ -1,46 +1,57 @@ /*;-*-C-*-; -** Copyright (c) Massachusetts Institute of Technology 1994-1998. -** All Rights Reserved. -** Unpublished rights reserved under the copyright laws of -** the United States. +** Splint - annotation-assisted static program checker +** Copyright (C) 1994-2001 University of Virginia, +** Massachusetts Institute of Technology ** -** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED -** OR IMPLIED. ANY USE IS AT YOUR OWN RISK. +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 2 of the License, or (at your +** option) any later version. +** +** This program is distributed in the hope that it will be useful, but +** WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** The GNU General Public License is available from http://www.gnu.org/ or +** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +** MA 02111-1307, USA. ** -** This code is distributed freely and may be used freely under the -** following conditions: -** -** 1. This notice may not be removed or altered. +** For information on lclint: lclint-request@cs.virginia.edu +** To report a bug: lclint-bug@cs.virginia.edu +** For more information: http://www.splint.org +*/ +/* +** cscanner.l ** -** 2. Works derived from this code are not distributed for -** commercial gain without explicit permission from MIT -** (for permission contact lclint-request@sds.lcs.mit.edu). +** Flex lexer for C. +** Based on a C lexer by Nate Osgood +** from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993 */ /* - * Modified by Herbert 08/19/97: - * - added #include for IBM's OS/2 compiler. - * - fixed weird bug with lookup of tmp files (OS/2 and MSDOS only). - */ - +** Modified by Herbert 08/19/97: +** - added #include for IBM's OS/2 compiler. +** - fixed weird bug with lookup of tmp files (OS/2 and MSDOS only). +*/ /* - * Modified by Mike Smith - * Corrected missing 'line' in scanf() calls in handleSpecial(). - * Without this, I get an error when LCLint hits a '#line' directive - * in the pre-pre-processed source files. For safety, I have made these - * conditional on OS2 and MSDOS because I don't understand why noone else - * has seen this problem. - * - * Modified by Mike Smith, 4th June 1997 - * Finally resolved the #line problem. The scanf() calls have been fixed to - * allow the following #line forms:- - * - * #line 123 "filename" - * #line 123 - * # 123 "filename" - * # 123 - * - * The last two are generated by the GNU pre-processor, apparently - */ +** Modified by Mike Smith +** Corrected missing 'line' in scanf() calls in handleSpecial(). +** Without this, I get an error when LCLint hits a '#line' directive +** in the pre-pre-processed source files. For safety, I have made these +** conditional on OS2 and MSDOS because I don't understand why noone else +** has seen this problem. +** +** Modified by Mike Smith, 4th June 1997 +** Finally resolved the #line problem. The scanf() calls have been fixed to +** allow the following #line forms:- +** +** #line 123 "filename" +** #line 123 +** # 123 "filename" +** # 123 +** +** The last two are generated by the GNU pre-processor, apparently +*/ Digit [0-9] Letter [a-zA-Z_$] @@ -53,13 +64,14 @@ IS (u|U|l|L)* ULSuffix ({U}{L}|{L}{U}) %{ -/* -** based on original C lexer by Nate Osgood -** from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993 -** -*/ - # include "lclintMacros.nf" +# if defined(OS2) && defined(__IBMC__) + /* needed for isatty()... */ +# include +# else +# include +# endif + # include "basic.h" # include "cgrammar.h" @@ -68,25 +80,13 @@ ULSuffix ({U}{L}|{L}{U}) # include "fileIdList.h" # include "portab.h" -# if defined(OS2) && defined(__IBMC__) - /* needed for isatty()... */ -# include -# endif - static bool lastWasString = FALSE; static char savechar = '\0'; /*@notfunction@*/ # define yyinput() (incColumn (), getc (yyin)) -/*@-noparams@*/ -/*@-incondefs@*/ -extern /*@external@*/ int read (); -/*@=incondefs@*/ -/*@=noparams@*/ - static /*@owned@*/ cstring lastidprocessed = cstring_undefined; - static int lminput (void); static int tokLength = 0; static bool inSpecPart = FALSE; @@ -114,6 +114,8 @@ static /*@only@*/ cstring makeIdentifier (char *); /* yes, this is exported! */ bool g_expectingTypeName = TRUE; /* beginning of file can be type name! */ +static bool expectingMetaStateName = FALSE; + static int returnInt (ctype, long); static int returnFloat (ctype, double); static int returnChar (char); @@ -172,6 +174,7 @@ static void setTokLength (int len) { addColumn (len); tokLength = len; + DPRINTF (("Set tok length: %d", len)); } static void setTokLengthT (size_t len) @@ -180,6 +183,9 @@ static void setTokLengthT (size_t len) } # include "flex.head" + +/*@-unrecog@*/ /*@i5343@*/ + %} %% @@ -194,7 +200,8 @@ static void setTokLengthT (size_t len) { if (lastWasString) { - ; + /* was nothing! */ /*@i32@*/ + RETURN_STRING (cstring_makeLiteral ("\"\"")); } else { @@ -265,6 +272,7 @@ static void setTokLengthT (size_t len) "static" { setTokLength (6); RETURN_TOK (QSTATIC); } \"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); } +L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); } "out" { return (processSpec (QOUT)); } "in" { return (processSpec (QIN)); } "partial" { return (processSpec (QPARTIAL)); } @@ -303,7 +311,9 @@ static void setTokLengthT (size_t len) "killed" { return (processSpec (QKILLED)); } "nullterminated" { return (processSpec (QNULLTERMINATED));} "MaxSet" { return (processSpec (QMAXSET));} -"MaxRead" { return (processSpec (QMAXREAD));} +"MaxRead" { return (processSpec (QMAXREAD));} +"maxSet" { return (processSpec (QMAXSET));} +"maxRead" { return (processSpec (QMAXREAD));} {Letter}({Letter}|{Digit})* { int tok; context_saveLocation (); @@ -359,6 +369,8 @@ static void setTokLengthT (size_t len) RETURN_INT (ctype_ullint, processDec ()); } '(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); RETURN_CHAR (processChar ()); } +L'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); + RETURN_CHAR (processChar ()); } {Digit}+{E}[fF] { setTokLengthT (mstring_length (yytext)); RETURN_FLOAT (ctype_float, processFloat ()); } {Digit}+{E}[lL] { setTokLengthT (mstring_length (yytext)); @@ -434,6 +446,16 @@ static void setTokLengthT (size_t len) [ \t\v\f] { incColumn (); } \n { context_incLineno (); + if (tokLength != 0) { + tokLength = 0; + /* No error to report + voptgenerror + (FLG_SYNTAX, + message ("Likely parse error: token spans multiple lines."), + g_currentloc); + */ + } + if (continueLine) { continueLine = FALSE; @@ -487,6 +509,8 @@ static void setTokLengthT (size_t len) if (processMacro ()) { + DPRINTF (("Here we are: %s", context_unparse ())); + if (context_inIterDef ()) { RETURN_TOK (LLMACROITER); @@ -503,6 +527,7 @@ static void setTokLengthT (size_t len) } } "@.CT" { setTokLength (4); lldiagmsg (ctype_unparseTable ()); } +"@.FA" { setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); } "@.F" { setTokLength (3); lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc))); } @@ -524,9 +549,15 @@ static void setTokLengthT (size_t len) int tok; incColumn (); incColumn (); tok = handleLlSpecial (); + if (tok != BADTOK) { - RETURN_TOK (tok); + if (tok == CANNOTATION) { + return (tok); + } else { + /* Beware - this bashes yylval! */ + RETURN_TOK (tok); + } } } "%}" { /* AFTER_COMMENT_MARKER */ @@ -535,11 +566,15 @@ static void setTokLengthT (size_t len) RETURN_TOK (QENDMACRO); } "\\" { incColumn (); continueLine = TRUE; } . { incColumn (); - voptgenerror - (FLG_SYNTAX, - message ("Invalid character (ascii: %d), skipping character", - (int)(*yytext)), - g_currentloc); + if ((int) *yytext == 13 ) { + ; + } else { + voptgenerror + (FLG_SYNTAX, + message ("Invalid character (ascii: %d), skipping character", + (int)(*yytext)), + g_currentloc); + } } %% @@ -558,6 +593,7 @@ struct skeyword s_parsetable[] = { { "modifies", QMODIFIES } , { "globals", QGLOBALS } , { "alt", QALT } , + { "warn", QWARN } , { "constant", QCONSTANT } , { "function", QFUNCTION } , { "iter", QITER } , @@ -568,12 +604,12 @@ struct skeyword s_parsetable[] = { { "releases", QRELEASES } , { "pre", QPRECLAUSE } , { "post", QPOSTCLAUSE } , - {"setBufferSize", QSETBUFFERSIZE}, - {"requires", QBUFFERCONSTRAINT}, - {"ensures", QENSURESCONSTRAINT}, - {"setStringLength", QSETSTRINGLENGTH}, - {"testinRange", QTESTINRANGE}, - { NULL, BADTOK } + { "setBufferSize", QSETBUFFERSIZE}, + { "setStringLength", QSETSTRINGLENGTH}, + { "testinRange", QTESTINRANGE}, + { "requires", QPRECLAUSE } , + { "ensures", QPOSTCLAUSE } , + { NULL, BADTOK } } ; /* @@ -617,8 +653,6 @@ struct skeyword s_keytable[] = { { "relnull", QRELNULL } , { "nullterminated", QNULLTERMINATED }, { "setBufferSize", QSETBUFFERSIZE }, - { "requires", QBUFFERCONSTRAINT }, - { "ensures", QENSURESCONSTRAINT }, { "testInRange", QTESTINRANGE}, { "MaxSet", QMAXSET}, { "MaxRead", QMAXREAD}, @@ -662,6 +696,7 @@ static bool isArtificial (cstring s) { return (cstring_equalLit (s, "modifies") || cstring_equalLit (s, "globals") + || cstring_equalLit (s, "warn") || cstring_equalLit (s, "alt")); } @@ -687,7 +722,7 @@ void swallowMacro (void) } else { - checkUngetc (i, yyin); + reader_checkUngetc (i, yyin); return; } } @@ -695,7 +730,7 @@ void swallowMacro (void) if (i != EOF) { - checkUngetc (i, yyin); + reader_checkUngetc (i, yyin); } } @@ -705,6 +740,8 @@ static int commentMarkerToken (cstring s) while (s_parsetable[i].name != NULL) { + DPRINTF (("Try :%s:%s:", s, s_parsetable[i].name)); + if (cstring_equalLit (s, s_parsetable[i].name)) { return s_parsetable[i].token; @@ -733,7 +770,7 @@ static int tokenMacroCode (cstring s) "This is interpreted by " "LCLint in the same way as most Unix lints, but it is " "preferable to replace it with the /*@fallthrough@*/ " - "stylized comment"), + "semantic comment"), g_currentloc); return QFALLTHROUGH; } @@ -746,7 +783,7 @@ static int tokenMacroCode (cstring s) "This is interpreted by " "LCLint in the same way as most Unix lints, but it is " "preferable to replace it with the /*@fallthrough@*/ " - "stylized comment"), + "semantic comment"), g_currentloc); return QFALLTHROUGH; } @@ -759,14 +796,14 @@ static int tokenMacroCode (cstring s) "This is interpreted by " "LCLint in the same way as most Unix lints, but it is " "preferable to replace it with the /*@notreached@*/ " - "stylized comment."), + "semantic comment."), g_currentloc); return QNOTREACHED; } else if (s_keytable[i].token == QPRINTFLIKE) { - setSpecialFunction (QU_PRINTFLIKE); + setSpecialFunction (qual_createPrintfLike ()); return SKIPTOK; } else if (s_keytable[i].token == QLINTPRINTFLIKE) @@ -781,17 +818,17 @@ static int tokenMacroCode (cstring s) "/*@scanflike@*/ or /*@messagelike@*/."), g_currentloc); - setSpecialFunction (QU_PRINTFLIKE); + setSpecialFunction (qual_createPrintfLike ()); return SKIPTOK; } else if (s_keytable[i].token == QSCANFLIKE) { - setSpecialFunction (QU_SCANFLIKE); + setSpecialFunction (qual_createScanfLike ()); return SKIPTOK; } else if (s_keytable[i].token == QMESSAGELIKE) { - setSpecialFunction (QU_MESSAGELIKE); + setSpecialFunction (qual_createMessageLike ()); return SKIPTOK; } else if (s_keytable[i].token == QARGSUSED) @@ -924,6 +961,7 @@ static char macro_nextChar () } else /* if (c == '@') */ { + llassert (FALSE); /*@i23@*/ if (handleLlSpecial () != BADTOK) { llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax"); @@ -993,7 +1031,7 @@ static char macro_nextChar () } /* -** keeps stylized comments +** keeps semantic comments */ static char macro_nextCharC () @@ -1135,7 +1173,6 @@ static void handleMacro () if (macrocode == BADTOK && !isArtificial (mac)) { - DPRINTF (("Add macro: %s", mac)); context_addMacroCache (mac); } else @@ -1210,14 +1247,12 @@ static bool processMacro (void) } hasParams = (c == '('); - if (usymtab_exists (fname)) { e2 = usymtab_lookupExpose (fname); ct = uentry_getType (e2); - if (uentry_isCodeDefined (e2) && fileloc_isUser (uentry_whereDefined (e2))) { @@ -1290,7 +1325,7 @@ static bool processMacro (void) uentry_showWhereSpecified (e2); uentry_setType (e2, ctype_unknown); - uentry_makeVarFunction (e2); + uentry_makeConstantFunction (e2); uentry_setDefined (e2, g_currentloc); uentry_setFunctionDefined (e2, g_currentloc); context_enterUnknownMacro (e2); @@ -1435,24 +1470,47 @@ static bool processMacro (void) { uentry ce; - voptgenerror - (FLG_MACROMATCHNAME, - message ("Unexpanded macro %s does not match name of a constant " - "or iter declaration. The name used in the control " - "comment on the previous line should match. " - "(Assuming macro defines a constant.)", - fname), - loc); - - - ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined); - uentry_setUsed (ce, loc); /* perhaps bogus? */ - e2 = usymtab_supEntryReturn (ce); - - context_enterConstantMacro (e2); - cstring_free (fname); - fileloc_free (loc); - return res; + /* evans 2001-09-09 - if it has params, assume a function */ + if (hasParams) + { + voptgenerror + (FLG_MACROMATCHNAME, + message ("Unexpanded macro %s does not match name of a declared " + "function. The name used in the control " + "comment on the previous line should match.", + fname), + loc); + + ce = uentry_makeFunction (fname, ctype_unknown, + typeId_invalid, + globSet_undefined, + sRefSet_undefined, + warnClause_undefined, + fileloc_undefined); + uentry_setUsed (ce, loc); /* perhaps bogus? */ + e2 = usymtab_supEntryReturn (ce); + context_enterUnknownMacro (e2); + } + else + { + voptgenerror + (FLG_MACROMATCHNAME, + message ("Unexpanded macro %s does not match name of a constant " + "or iter declaration. The name used in the control " + "comment on the previous line should match. " + "(Assuming macro defines a constant.)", + fname), + loc); + + ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined); + uentry_setUsed (ce, loc); /* perhaps bogus? */ + e2 = usymtab_supEntryReturn (ce); + + context_enterConstantMacro (e2); + cstring_free (fname); + fileloc_free (loc); + return res; + } } /* in macros, ( must follow immediatetly after name */ @@ -1501,14 +1559,14 @@ static bool processMacro (void) && !uentry_isElipsisMarker (uentryList_getN (specparams, paramno))) { + fileloc sloc = context_getSaveLocation (); uentry decl = uentryList_getN (specparams, paramno); sRef sr; param = uentry_nameCopy (paramname, decl); - uentry_setParam (param); - sr = sRef_makeParam (paramno, uentry_getType (param)); + sr = sRef_makeParam (paramno, uentry_getType (param), stateInfo_makeLoc (sloc)); if (sRef_getNullState (sr) == NS_ABSNULL) { @@ -1525,12 +1583,12 @@ static bool processMacro (void) } else { - sRef_setNullState (sr, NS_UNKNOWN, g_currentloc); + sRef_setNullState (sr, NS_UNKNOWN, sloc); } } uentry_setSref (param, sr); - uentry_setDeclaredForceOnly (param, context_getSaveLocation ()); + uentry_setDeclaredForceOnly (param, sloc); skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno)); } @@ -1539,11 +1597,12 @@ static bool processMacro (void) fileloc sloc = context_getSaveLocation (); param = uentry_makeVariableSrefParam - (paramname, ctype_unknown, sRef_makeParam (paramno, ctype_unknown)); + (paramname, ctype_unknown, fileloc_copy (sloc), + sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (sloc))); + DPRINTF (("Unknown param: %s", uentry_unparseFull (param))); cstring_free (paramname); sRef_setPosNull (uentry_getSref (param), sloc); - uentry_setDeclaredForce (param, sloc); skipparam = FALSE; @@ -1636,7 +1695,6 @@ static bool processMacro (void) static bool handleSpecial (char *yyt) { char *l = mstring_create (MAX_NAME_LENGTH); - static bool reportcpp = FALSE; int lineno = 0; char c; char *ol; @@ -1657,7 +1715,7 @@ static bool handleSpecial (char *yyt) *l = '\0'; olc = cstring_fromChars (ol); - if (cstring_equalPrefix (olc, "pragma")) + if (cstring_equalPrefixLit (olc, "pragma")) { char *pname = mstring_create (longUnsigned_fromInt (MAX_PRAGMA_LEN)); char *opname = pname; @@ -1715,7 +1773,7 @@ static bool handleSpecial (char *yyt) cstring_free (exname); } } - else if (cstring_equalPrefix (olc, "ident")) + else if (cstring_equalPrefixLit (olc, "ident")) { /* Some pre-processors will leave these in the code. Ignore rest of line */ } @@ -1727,9 +1785,10 @@ static bool handleSpecial (char *yyt) || (sscanf (ol, " %d \"", &lineno) == 1)) { char *tmp = ol; - char *fname; + cstring fname; fileId fid; + /*@access cstring@*/ while (*tmp != '\"' && *tmp != '\0') { tmp++; @@ -1738,6 +1797,7 @@ static bool handleSpecial (char *yyt) llassert (*tmp == '\"'); tmp++; + fname = tmp; while (*tmp != '\"' && *tmp != '\0') @@ -1749,8 +1809,6 @@ static bool handleSpecial (char *yyt) *tmp = '\0'; - DPRINTF (("fname: %s", fname)); - # if defined(OS2) || defined(MSDOS) || defined(WIN32) /* @@ -1768,15 +1826,11 @@ static bool handleSpecial (char *yyt) ** Skip past the drive marker. */ - DPRINTF (("stmp: %s / %s", stmp, fname)); - if (strchr (stmp, ':') != NULL) { stmp = strchr (stmp, ':') + 1; } - DPRINTF (("stmp: %s / %s", stmp, fname)); - while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL ) { if (*(stmp+1) == CONNECTCHAR) @@ -1785,41 +1839,38 @@ static bool handleSpecial (char *yyt) } stmp++; - DPRINTF (("stmp: %s / %s", stmp, fname)); } - DPRINTF (("Now: base = %s", fname)); - - fid = fileTable_lookupBase (context_fileTable (), - cstring_fromChars (fname)); + fid = fileTable_lookupBase (context_fileTable (), fname); if (!(fileId_isValid (fid))) { fname = removePreDirs (fname); - fid = fileTable_lookupBase (context_fileTable (), - cstring_fromChars (fname)); + fid = fileTable_lookupBase (context_fileTable (), fname); } } # else /* !defined(OS2) && !defined(MSDOS) */ fname = removePreDirs (fname); - fid = fileTable_lookupBase (context_fileTable (), - cstring_fromChars (fname)); + fid = fileTable_lookupBase (context_fileTable (), fname); # endif /* !defined(OS2) && !defined(MSDOS) */ if (!(fileId_isValid (fid))) { - if (isHeaderFile (cstring_fromChars (fname))) + if (context_inXHFile ()) + { + fid = fileTable_addXHFile (context_fileTable (), fname); + } + else if (isHeaderFile (fname)) { - fid = fileTable_addHeaderFile (context_fileTable (), - cstring_fromChars (fname)); + fid = fileTable_addHeaderFile (context_fileTable (), fname); } else { - fid = fileTable_addFile (context_fileTable (), - cstring_fromChars (fname)); + fid = fileTable_addFile (context_fileTable (), fname); } } setFileLine (fid, lineno); + /*@noaccess cstring@*/ } else if ((sscanf (ol, "line %d", &lineno) == 1) || (sscanf (ol, " %d", &lineno) == 1)) @@ -1837,18 +1888,15 @@ static bool handleSpecial (char *yyt) mstring_free (ol); return FALSE; } else { - if (!reportcpp) - { - - } else { - llbug (message ("File contains preprocessor command: #%s", - cstring_fromChars (ol))); - reportcpp = TRUE; - } + voptgenerror + (FLG_UNRECOGDIRECTIVE, + message ("Unrecognized pre-processor directive: #%s", + cstring_fromChars (ol)), + g_currentloc); } sfree (ol); - return TRUE; + return FALSE; /* evans 2001-12-30: was: TRUE; */ } sfree (ol); @@ -1857,12 +1905,17 @@ static bool handleSpecial (char *yyt) static int handleLlSpecial () { + bool hasnl = FALSE; int ic; char c; char *s = mstring_createEmpty (); char *os; int tok; int charsread = 0; + fileloc loc; + + loc = fileloc_copy (g_currentloc); + DPRINTF (("Handle special: %s", fileloc_unparse (loc))); while (((ic = ninput ()) != 0) && isalpha (ic)) { @@ -1871,6 +1924,7 @@ static int handleLlSpecial () charsread++; } + DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc))); os = s; if (charsread == 0 && ic == (int) AFTER_COMMENT_MARKER[0]) @@ -1878,19 +1932,16 @@ static int handleLlSpecial () ic = ninput (); llassert (ic == AFTER_COMMENT_MARKER[1]); - - if (isProcessingGlobMods () && (*s == '\0')) + if (*s == '\0') { sfree (os); + fileloc_free (loc); return QNOMODS; /* special token no modifications token */ } - else - { - ; - } } + DPRINTF (("Coment marker: %s", os)); tok = commentMarkerToken (cstring_fromChars (os)); if (tok != BADTOK) @@ -1898,15 +1949,16 @@ static int handleLlSpecial () tokLength = charsread; sfree (os); inSpecPart = TRUE; + fileloc_free (loc); return tok; } - + + DPRINTF (("Not a comment marker...")); /* Add rest of the comment */ if (ic != 0 && ic != EOF) { c = (char) ic; - s = mstring_append (s, c); charsread++; @@ -1915,11 +1967,27 @@ static int handleLlSpecial () && (ic != AFTER_COMMENT_MARKER[0])) { c = (char) ic; + + /* evans 2001-09-01 added to prevent assertion failures for uncloses syntactic comments */ + + if (c == '\n') { + hasnl = TRUE; /* This prevents tokLength from being set later. */ + tokLength = 0; + + voptgenerror + (FLG_SYNTAX, + message ("Likely parse error: syntactic comment token spans multiple lines: %s", + cstring_fromChars (s)), + g_currentloc); + } + s = mstring_append (s, c); charsread++; } } + DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc))); + if (ic == AFTER_COMMENT_MARKER[0]) { int nc = ninput (); @@ -1927,7 +1995,6 @@ static int handleLlSpecial () charsread++; } - os = s; while (*s == ' ' || *s == '\t' || *s == '\n') @@ -1974,7 +2041,7 @@ static int handleLlSpecial () llerror (FLG_BADFLAG, message - ("Stylized comment attempts to restore flag %s. " + ("Semantic comment attempts to restore flag %s. " "A mode flag cannot be restored.", flagname)); } @@ -1985,20 +2052,22 @@ static int handleLlSpecial () } else { - llerror - (FLG_BADFLAG, - message ("Unrecognized option in stylized comment: %s", - flagname)); + voptgenerror + (FLG_UNRECOGFLAGCOMMENTS, + message ("Unrecognized option in semantic comment: %s", + flagname), + g_currentloc); } } else if (flagcode_isGlobalFlag (fflag)) { - llerror + voptgenerror (FLG_BADFLAG, message - ("Stylized comment attempts to set global flag %s. " + ("Semantic comment attempts to set global flag %s. " "A global flag cannot be set locally.", - flagname)); + flagname), + g_currentloc); } else { @@ -2008,12 +2077,13 @@ static int handleLlSpecial () { if (ynm_isMaybe (set)) { - llerror + voptgenerror (FLG_BADFLAG, message - ("Stylized comment attempts to restore flag %s. " + ("Semantic comment attempts to restore flag %s. " "A flag for setting a value cannot be restored.", - flagname)); + flagname), + g_currentloc); } else { /* cut-and-pastied from llmain...blecch */ @@ -2049,7 +2119,7 @@ static int handleLlSpecial () llerror (FLG_BADFLAG, message - ("Flag %s (in stylized comment) must be followed by an argument", + ("Flag %s (in semantic comment) must be followed by an argument", flagcode_unparse (fflag))); } else @@ -2087,7 +2157,8 @@ static int handleLlSpecial () if (context_inHeader () && !isArtificial (cstring_fromChars (os))) { - context_addComment (cstring_fromCharsNew (os)); + DPRINTF (("Here adding comment: %s", os)); + context_addComment (cstring_fromCharsNew (os)); } else { @@ -2099,6 +2170,7 @@ static int handleLlSpecial () char *t = s; int macrocode; char tchar = '\0'; + annotationInfo ainfo; while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n') { @@ -2117,11 +2189,11 @@ static int handleLlSpecial () if (macrocode != BADTOK) { - tokLength = mstring_length (t); - + tokLength = hasnl ? 0 : mstring_length (t); sfree (t); sfree (os); + fileloc_free (loc); if (macrocode == SKIPTOK) { @@ -2131,6 +2203,18 @@ static int handleLlSpecial () return macrocode; } + ainfo = context_lookupAnnotation (cstring_fromChars (os)); + + if (annotationInfo_isDefined (ainfo)) { + DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo))); + /*@i324@*/ yylval.annotation = ainfo; + tokLength = 0; + sfree (os); + sfree (t); + fileloc_free (loc); + return CANNOTATION; + } + if (context_inHeader ()) { if (tchar != '\0') @@ -2142,6 +2226,7 @@ static int handleLlSpecial () && macrocode != SKIPTOK && !isArtificial (cstring_fromChars (os))) { + DPRINTF (("Add comment: %s", os)); context_addComment (cstring_fromCharsNew (os)); } else @@ -2236,24 +2321,42 @@ static int handleLlSpecial () *s = '\0'; - + DPRINTF (("Access %s", tname)); + if (!context_getFlag (FLG_NOCOMMENTS) && !context_getFlag (FLG_NOACCESS)) { if (usymtab_existsType (tname)) { - usymId uid = usymtab_getTypeId (tname); - context_addFileAccessType (uid); + typeId uid = usymtab_getTypeId (tname); + uentry ue = usymtab_getTypeEntry (uid); + + if (uentry_isAbstractDatatype (ue)) + { + context_addFileAccessType (uid); + DPRINTF (("Adding access to: %s / %d", tname, uid)); + } + else + { + voptgenerror + (FLG_COMMENTERROR, + message + ("Non-abstract type %s used in access comment", + tname), + g_currentloc); + } } else { if (!(context_inSuppressRegion () || context_inSuppressZone (g_currentloc))) { - llmsg - (message - ("%q: Unrecognized type %s used in access comment", - fileloc_unparse (g_currentloc), tname)); + voptgenerror + (FLG_COMMENTERROR, + message + ("Unrecognized type %s used in access comment", + tname), + g_currentloc); } } } @@ -2305,6 +2408,7 @@ static int handleLlSpecial () if (context_couldHaveAccess (tuid)) { + DPRINTF (("Removing access: %s", tname)); context_removeFileAccessType (tuid); } else @@ -2316,17 +2420,21 @@ static int handleLlSpecial () if (uentry_isAbstractDatatype (ue)) { - llmsg - (message - ("%q: Non-accessible abstract type %s used in noaccess comment", - fileloc_unparse (g_currentloc), tname)); + voptgenerror + (FLG_COMMENTERROR, + message + ("Non-accessible abstract type %s used in noaccess comment", + tname), + g_currentloc); } else { - llmsg - (message - ("%q: Non-abstract type %s used in noaccess comment", - fileloc_unparse (g_currentloc), tname)); + voptgenerror + (FLG_COMMENTERROR, + message + ("Non-abstract type %s used in noaccess comment", + tname), + g_currentloc); } } } @@ -2336,10 +2444,12 @@ static int handleLlSpecial () if (!(context_inSuppressRegion () || context_inSuppressZone (g_currentloc))) { - llmsg - (message - ("%q: Unrecognized type %s used in noaccess comment", - fileloc_unparse (g_currentloc), tname)); + voptgenerror + (FLG_COMMENTERROR, + message + ("Unrecognized type %s used in noaccess comment", + tname), + g_currentloc); } } } @@ -2357,18 +2467,16 @@ static int handleLlSpecial () } else { - setTokLength (- (2 + charsread)); - voptgenerror (FLG_UNRECOGCOMMENTS, - message ("Stylized comment unrecognized: %s", - cstring_fromChars (os)), - g_currentloc); + message ("Semantic comment unrecognized: %s", + cstring_fromChars (os)), loc); } sfree (t); } - sfree (os); + sfree (os); + fileloc_free (loc); return BADTOK; } @@ -2436,14 +2544,18 @@ static int processIdentifier (cstring id) { uentry le; - DPRINTF (("Process identifier: %s", id)); + if (context_getFlag (FLG_GRAMMAR)) + { + lldiagmsg (message ("Process identifier: %s", id)); + } context_clearJustPopped (); lastidprocessed = id; - if (context_inFunctionDecl ()) + if (context_inFunctionHeader ()) { int tok = commentMarkerToken (id); + DPRINTF (("in function decl...")); if (tok != BADTOK) { @@ -2457,6 +2569,38 @@ static int processIdentifier (cstring id) { return tok; } + else + { + annotationInfo ainfo; + + if (expectingMetaStateName) + { + metaStateInfo msinfo = context_lookupMetaStateInfo (id); + + if (metaStateInfo_isDefined (msinfo)) + { + yylval.msinfo = msinfo; + return METASTATE_NAME; + } + else + { + DPRINTF (("Not meta state name: %s", cstring_toCharsSafe (id))); + } + } + + ainfo = context_lookupAnnotation (id); + + if (annotationInfo_isDefined (ainfo)) + { + DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo))); + /*@i324@*/ yylval.annotation = ainfo; + return CANNOTATION; + } + else + { + DPRINTF (("Not annotation: %s", id)); + } + } } } @@ -2496,7 +2640,8 @@ static int processIdentifier (cstring id) || cstring_equalLit (id, "__PRETTY_FUNCTION__")) { /* These tokens hold the name of the current function as strings */ - yylval.expr = exprNode_stringLiteral (id, fileloc_copy (g_currentloc)); + /* evans 2001-12-30: changed from exprNode_stringLiteral; bug reported by Jim Zelenka. */ + yylval.expr = exprNode_makeConstantString (id, fileloc_copy (g_currentloc)); tokLength = 0; lastWasString = TRUE; tok = CCONSTANT; @@ -2624,12 +2769,12 @@ static int processIdentifier (cstring id) if (uentry_isIter (le)) { - yylval.entry = le; + /*@i32@*/ yylval.entry = le; return (ITER_NAME); } else if (uentry_isEndIter (le)) { - yylval.entry = le; + /*@i32@*/ yylval.entry = le; return (ITER_ENDNAME); } else if (uentry_isUndefined (le)) @@ -2655,7 +2800,7 @@ static int processIdentifier (cstring id) } else { - yylval.entry = le; + /*@i32@*/ yylval.entry = le; return (IDENTIFIER); } } @@ -2677,7 +2822,7 @@ static int processIdentifier (cstring id) } else { - yylval.entry = le; + /*@i32@*/ yylval.entry = le; return (IDENTIFIER); } @@ -2707,6 +2852,10 @@ static bool processHashIdentifier (/*@only@*/ cstring id) } else { + /* + ** Will be handled by handleLlSpecial + */ + cstring_free (id); return FALSE; } @@ -2842,6 +2991,22 @@ long processOctal () if (c >= '0' && c <= '7') { tval = (int) c - (int) '0'; + } else if (c == 'U' || c == 'L' || c == 'u' || c == 'l') { + index++; + while (yytext[index] != '\0') { + if (c == 'U' || c == 'L' || c == 'u' || c == 'l') { + ; + } else { + voptgenerror + (FLG_SYNTAX, + message ("Invalid character (%c) following specifier in octal constant: %s", + c, cstring_fromChars (yytext)), + g_currentloc); + } + index++; + } + + break; } else { voptgenerror (FLG_SYNTAX, @@ -2869,7 +3034,6 @@ static int processSpec (int tok) { size_t length = strlen (yytext); - if (inSpecPart) { @@ -2884,3 +3048,16 @@ processSpec (int tok) return (processIdentifier (makeIdentifier (yytext))); } } + +void cscanner_expectingMetaStateName () +{ + llassert (!expectingMetaStateName); + llassert (context_inFunctionHeader ()); + expectingMetaStateName = TRUE; +} + +void cscanner_clearExpectingMetaStateName () +{ + llassert (expectingMetaStateName); + expectingMetaStateName = FALSE; +}