diff --git a/elkhound/glr.cc b/elkhound/glr.cc index 7074e0d..640ed65 100644 --- a/elkhound/glr.cc +++ b/elkhound/glr.cc @@ -938,7 +938,7 @@ STATICDEF bool GLR // some debugging streams so the TRSPARSE etc. macros work bool trParse = glr.trParse; - ostream &trsParse = glr.trsParse; + std::ostream &trsParse = glr.trsParse; #endif for (;;) { // debugging diff --git a/elkhound/glrconfig.h b/elkhound/glrconfig.h new file mode 100644 index 0000000..716e19e --- /dev/null +++ b/elkhound/glrconfig.h @@ -0,0 +1,90 @@ +// glrconfig.h see license.txt for copyright and terms of use +// compile-time configuration options which affect the generated +// GLR parser, and the interface to the user actions + +#ifndef GLRCONFIG_H +#define GLRCONFIG_H + + +// when NO_GLR_SOURCELOC is #defined, we disable all support for +// automatically propagating source location information in the +// parser; user actions can still refer to 'loc', but they just get +// a dummy no-location value +#ifndef GLR_SOURCELOC + #define GLR_SOURCELOC 1 // set by ./configure +#endif + +#if GLR_SOURCELOC + #define SOURCELOC(stuff) stuff + #define ENDSOURCELOC(stuff) stuff + + // this one adds a leading comma (I can't put that into the + // argument , because then it looks like the macro is + // being passed 2 arguments) + #define SOURCELOCARG(stuff) , stuff + #define ENDSOURCELOCARG(stuff) , stuff + + #define NOSOURCELOC(stuff) +#else + #define SOURCELOC(stuff) + #define SOURCELOCARG(stuff) + #define NOSOURCELOC(stuff) stuff +#endif + + +// when enabled, NODE_COLUMN tracks in each stack node the +// appropriate column to display it for in debugging dump. +// in the new RWL core, this is required to always be 1. +#ifndef ENABLE_NODE_COLUMNS + #define ENABLE_NODE_COLUMNS 1 +#endif +#if ENABLE_NODE_COLUMNS + #define NODE_COLUMN(stuff) stuff +#else + #define NODE_COLUMN(stuff) +#endif + + +// when enabled, YIELD_COUNT keeps track of the number of times a +// given semantic value is yielded; this is useful for warning the +// user when a merge is performed but one of the merged values has +// already been yielded to another semantic action, which implies +// that the induced parse forest is incomplete +#ifndef ENABLE_YIELD_COUNT + #define ENABLE_YIELD_COUNT 1 +#endif +#if ENABLE_YIELD_COUNT + #define YIELD_COUNT(stuff) stuff +#else + #define YIELD_COUNT(stuff) +#endif + + +// when true, error entries in the action table are extracted into +// their own bitmap; this then enables compression on the action +// table, since it makes it sparse +#ifndef ENABLE_EEF_COMPRESSION + #define ENABLE_EEF_COMPRESSION 0 +#endif + +// when true, the action and goto tables are compressed using +// graph coloring +#ifndef ENABLE_GCS_COMPRESSION + #define ENABLE_GCS_COMPRESSION 0 +#endif + +// when true, action and goto *columns* are merged during GCS; +// otherwise, only rows are merged +#ifndef ENABLE_GCS_COLUMN_COMPRESSION + #define ENABLE_GCS_COLUMN_COMPRESSION 0 +#endif + +// when true, entries in the action and goto tables are a +// 1-byte index into an appropriate map +#ifndef ENABLE_CRS_COMPRESSION + #define ENABLE_CRS_COMPRESSION 0 +#endif + + + +#endif // GLRCONFIG_H diff --git a/elsa/baselexer.cc b/elsa/baselexer.cc index b25a102..bf62d12 100644 --- a/elsa/baselexer.cc +++ b/elsa/baselexer.cc @@ -20,11 +20,11 @@ #else // should work on any compiler that implements the C++98 standard // (istrstream is deprecated but still standard) - #include // istrstream + #include // istrstream inline std::istream *construct_istrstream(char const *buf, int len) { - return new istrstream(buf, len); + return new std::istrstream(buf, len); } #endif diff --git a/elsa/cc_flags.h b/elsa/cc_flags.h index 1652d14..cf99d36 100644 --- a/elsa/cc_flags.h +++ b/elsa/cc_flags.h @@ -68,7 +68,8 @@ void fromXml(CVFlags &out, char const *str); ENUM_BITWISE_OPS(CVFlags, CV_ALL) // experiment: superset operator -inline bool operator>= (CVFlags cv1, CVFlags cv2) +// replaced 'operator >=' with 'superset()' to solve VisualStudio enum operator overloading bug +inline bool superset(CVFlags cv1, CVFlags cv2) { return (cv1 & cv2) == cv2; } @@ -143,7 +144,8 @@ void fromXml(DeclFlags &out, char const *str); ENUM_BITWISE_OPS(DeclFlags, ALL_DECLFLAGS) -inline bool operator>= (DeclFlags df1, DeclFlags df2) +// replaced 'operator >=' with 'superset()' to solve VisualStudio enum operator overloading bug +inline bool superset(DeclFlags df1, DeclFlags df2) { return (df1 & df2) == df2; } // helper of possibly general purpose diff --git a/elsa/cc_tcheck.cc b/elsa/cc_tcheck.cc index 8c73cf1..12585e4 100644 --- a/elsa/cc_tcheck.cc +++ b/elsa/cc_tcheck.cc @@ -457,7 +457,7 @@ void Function::tcheck(Env &env, Variable *instV) // supply DF_DEFINITION? DeclFlags dfDefn = (checkBody? DF_DEFINITION : DF_NONE); - if (dflags >= (DF_EXTERN | DF_INLINE) && + if (superset(dflags, (DF_EXTERN | DF_INLINE)) && env.lang.handleExternInlineSpecially && handleExternInline_asPrototype()) { // gcc treats extern-inline function definitions specially: @@ -674,7 +674,7 @@ void Function::tcheckBody(Env &env) // stop extending the named scope, if there was one env.retractScopeSeq(qualifierScopes); - if (dflags >= (DF_EXTERN | DF_INLINE) && + if (superset(dflags, (DF_EXTERN | DF_INLINE)) && env.lang.handleExternInlineSpecially && handleExternInline_asPrototype()) { // more extern-inline nonsense; skip 'funcDefn' setting @@ -3572,7 +3572,7 @@ void Declarator::mid_tcheck(Env &env, Tcheck &dt) // DF_FRIEND gets turned off by 'declareNewVariable' ... bool isFriend = !!(dt.dflags & DF_FRIEND); - if ((dt.dflags >= (DF_EXTERN | DF_INLINE)) && env.lang.handleExternInlineSpecially) { + if (superset(dt.dflags, (DF_EXTERN | DF_INLINE)) && env.lang.handleExternInlineSpecially) { // dsw: We want to add a flag saying that this isn't really an // extern inline. This is necessary because sometimes we still // need to know later that it started off as an extern inline even @@ -8467,7 +8467,7 @@ Type *attemptCondConversion(Env &env, ImplicitConversion &ic /*OUT*/, t2Class->hasBaseClass(t1Class))) { // bullet 2.1 if (t1Class->hasBaseClass(t2Class) && - t2->asRval()->getCVFlags() >= t1->asRval()->getCVFlags()) { + superset(t2->asRval()->getCVFlags(), t1->asRval()->getCVFlags())) { ic.addStdConv(SC_IDENTITY); return t2->asRval(); } diff --git a/elsa/configure.pl b/elsa/configure.pl index a472589..820fe4c 100755 --- a/elsa/configure.pl +++ b/elsa/configure.pl @@ -41,6 +41,7 @@ # defaults @LDFLAGS = ("-g -Wall"); +@CCFLAGS = "-DXML"; $AST = "../ast"; $ELKHOUND = "../elkhound"; $USE_GNU = "1"; @@ -152,6 +153,7 @@ package options: $summary .= <<"OUTER_EOF"; cat < "@LDFLAGS", + "CCFLAGS" => "@CCFLAGS", "SMBASE" => "$SMBASE", "AST" => "$AST", "ELKHOUND" => "$ELKHOUND", diff --git a/elsa/main.cc b/elsa/main.cc index 68cdd8b..90c8dd9 100644 --- a/elsa/main.cc +++ b/elsa/main.cc @@ -25,10 +25,12 @@ #include "smregexp.h" // regexpMatch #include "cc_elaborate.h" // ElabVisitor #include "integrity.h" // IntegrityVisitor -#include "xml_file_writer.h" // XmlFileWriter -#include "xml_reader.h" // xmlDanglingPointersAllowed -#include "xml_do_read.h" // xmlDoRead() -#include "xml_type_writer.h" // XmlTypeWriter +#if XML +# include "xml_file_writer.h" // XmlFileWriter +# include "xml_reader.h" // xmlDanglingPointersAllowed +# include "xml_do_read.h" // xmlDoRead() +# include "xml_type_writer.h" // XmlTypeWriter +#endif #include "bpprint.h" // bppTranslationUnit #include "cc2c.h" // cc_to_c @@ -395,6 +397,7 @@ void doit(int argc, char **argv) int parseWarnings = 0; long parseTime = 0; +#if XML if (tracingSys("parseXml")) { if (tracingSys("parseXml-no-danglingPointers")) { xmlDanglingPointersAllowed = false; @@ -402,7 +405,9 @@ void doit(int argc, char **argv) unit = xmlDoRead(strTable, inputFname); if (!unit) return; } - else { + else +#endif + { SectionTimer timer(parseTime); SemanticValue treeTop; ParseTreeAndTokens tree(lang, treeTop, strTable, inputFname); @@ -723,6 +728,7 @@ void doit(int argc, char **argv) bppTranslationUnit(std::cout, *unit); } +#if XML // dsw: xml printing of the raw ast if (tracingSys("xmlPrintAST")) { traceProgress() << "dsw xml print...\n"; @@ -762,6 +768,7 @@ void doit(int argc, char **argv) std::cout << "---- STOP ----" << std::endl; traceProgress() << "dsw xml print... done\n"; } +#endif // test AST cloning if (tracingSys("testClone")) { diff --git a/elsa/mtype.cc b/elsa/mtype.cc index e17b3d9..d7eb84f 100644 --- a/elsa/mtype.cc +++ b/elsa/mtype.cc @@ -688,7 +688,7 @@ bool IMType::equalWithAppliedCV(Type const *conc, Binding *binding, CVFlags cv, if (!( flags & MF_OK_DIFFERENT_CV )) { // The 'cv' flags supplied are subtracted from those in 'conc'. CVFlags concCV = conc->getCVFlags(); - if (concCV >= cv) { + if (superset(concCV, cv)) { // example: // conc = 'struct B volatile const' // binding = 'struct B' @@ -934,7 +934,7 @@ bool IMType::imatchCVFlags(CVFlags conc, CVFlags pat, MatchFlags flags) // TODO: this is wrong, as it does not correctly implement // 14.8.2.1; I am only implementing this because it emulates // what matchtype does right now - if (pat >= conc) { + if (superset(pat, conc)) { return true; } else { @@ -966,7 +966,7 @@ bool IMType::imatchReferenceType(ReferenceType const *conc, ReferenceType const // this only approximates 14.8.2.1, but emulates current matchtype // behavior (actually, it emulates only the intended matchtype // behavior; see comment added 2005-08-03 to MatchTypes::match_ref) - if (pat->atType->getCVFlags() >= conc->atType->getCVFlags()) { + if (superset(pat->atType->getCVFlags(), conc->atType->getCVFlags())) { // disable further comparison of these cv-flags flags |= MF_IGNORE_TOP_CV; } diff --git a/smbase/ckheap.h b/smbase/ckheap.h index 8c3990c..9f8fee3 100644 --- a/smbase/ckheap.h +++ b/smbase/ckheap.h @@ -9,9 +9,12 @@ extern "C" { #endif -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(_WIN32) + // don't want to try to get dlmalloc working... // don't want to try to get dlmalloc working... #define checkHeapNode(n) /*nothing*/ + #define checkHeap() /*nothing*/ + #define numMallocCalls() /*nothing*/ #define malloc_stats() ((void)0) #else diff --git a/smbase/cycles.h b/smbase/cycles.h index 496c7a9..393753b 100644 --- a/smbase/cycles.h +++ b/smbase/cycles.h @@ -17,6 +17,8 @@ void getCycles(unsigned *lowp, unsigned *highp); // if we're using gcc, so the 'long long' type is available, // here's a more convenient version unsigned long long getCycles_ll(void); +#else +inline unsigned long long getCycles_ll(void) { return 0; } // !!! #endif diff --git a/smbase/flexlexer.h b/smbase/flexlexer.h new file mode 100644 index 0000000..a64697c --- /dev/null +++ b/smbase/flexlexer.h @@ -0,0 +1,186 @@ +// $Header: /home/daffy/u0/vern/flex/RCS/FlexLexer.h,v 1.19 96/05/25 20:43:02 vern Exp $ + +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms with or without +// modification are permitted provided that: (1) source distributions retain +// this entire copyright notice and comment, and (2) distributions including +// binaries display the following acknowledgement: ``This product includes +// software developed by the University of California, Berkeley and its +// contributors'' in the documentation or other materials provided with the +// distribution and in all advertising materials mentioning features or use +// of this software. Neither the name of the University nor the names of +// its contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H +#include + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() { return yytext; } + int YYLeng() { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( std::istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( std::istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( std::istream* new_in, std::ostream* new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( std::istream* new_in = 0, + std::ostream* new_out = 0 ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex man page. +#define yyFlexLexerOnce + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( std::istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( std::istream* s ); + + virtual int yylex(); + virtual void switch_streams( std::istream* new_in, std::ostream* new_out ); + +protected: + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state* b, std::istream* s ); + void yy_flush_buffer( struct yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + std::istream* yyin; // input source for default LexerInput + std::ostream* yyout; // output sink for default LexerOutput + + struct yy_buffer_state* yy_current_buffer; + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +#endif diff --git a/smbase/nonport.cpp b/smbase/nonport.cpp index 01f9da9..c0cff4f 100644 --- a/smbase/nonport.cpp +++ b/smbase/nonport.cpp @@ -6,7 +6,7 @@ #include // abort, exit #include // strncpy -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(_WIN32) # ifdef USE_MINWIN_H # include "minwin.h" // api # else @@ -35,12 +35,12 @@ # define DIRSLASHES "\\/" #else // unix +# include // write, mkdir, sleep, chdir, geteuid # include // struct timeval, gettimeofday +# include // getpwuid, struct passwd # include // mkdir constants, DIR, struct dirent # include // mkdir constants -# include // mkdir, sleep, chdir, geteuid # include // errno -# include // getpwuid, struct passwd # define DIRSLASH '/' # define DIRSLASHES "/" @@ -48,10 +48,13 @@ #include // chmod, mode macros #include // tzset, localtime, time +#include // mkdir constants #include // cout #if !defined(__WIN32__) || defined(__BORLANDC__) - #include // opendir +# ifndef _WIN32 +# include // opendir +# endif #endif #include "nonport.h" // this module @@ -115,7 +118,7 @@ char getConsoleChar() // constant for the life of the program, event long getMilliseconds() { -# ifdef __WIN32__ +#if defined(__WIN32__) || defined(_WIN32) // # of milliseconds since program started return GetTickCount(); @@ -151,7 +154,7 @@ bool limitFileAccess(char const *fname) bool createDirectory(char const *dirname) { int res; -# ifdef __WIN32__ +# if defined(__WIN32__) || defined(_WIN32) // no 'mode' argument res = mkdir(dirname); # else // unix @@ -235,7 +238,7 @@ void portableSleep(unsigned seconds) void getCurrentUsername(char *buf, int buflen) { - #ifdef __WIN32__ +# if defined(__WIN32__) || defined(_WIN32) DWORD len = buflen; if (!GetUserName(buf, &len)) { fail("GetUserName"); @@ -330,7 +333,7 @@ void applyToDirContents(char const *dirName, // trash section) // DOB: VC doesn't have opendir- // I think this is the only way to do it in the Win32 API - #if defined(__WIN32__) && !defined(__BORLANDC__) + #if (defined(__WIN32__) && !defined(__BORLANDC__)) || defined(_WIN32) struct _finddata_t fb; char* buf = new char[strlen(dirName)+5]; strcpy(buf, dirName); @@ -384,7 +387,7 @@ bool isDirectory(char const *path) fail("stat", path); return false; } - #if defined(__WIN32__) && !defined(__BORLANDC__) + #if (defined(__WIN32__) && !defined(__BORLANDC__)) || defined(_WIN32) return !!(st.st_mode & _S_IFDIR); // this is how it works for VC #else return S_ISDIR(st.st_mode); @@ -485,7 +488,7 @@ bool hasSystemCryptoRandom() // of things hasSystemCryptoRandom checks) unsigned getSystemCryptoRandom() { - #if !defined(__WIN32__) // unix + #if !(defined(__WIN32__) || defined(_WIN32)) // open /dev/random int fd = open("/dev/random", O_RDONLY); if (!fd) { @@ -530,7 +533,7 @@ unsigned getSystemCryptoRandom() int getProcessId() { - #ifdef __WIN32__ + #if defined(__WIN32__) || defined(_WIN32) return GetCurrentProcessId(); #else // unix diff --git a/smbase/ofstreamts.cc b/smbase/ofstreamts.cc index b2d87db..4edb070 100644 --- a/smbase/ofstreamts.cc +++ b/smbase/ofstreamts.cc @@ -6,7 +6,11 @@ #include "exc.h" #include +#ifndef _WIN32 #include +#else +#include +#endif size_t getFileSize(std::istream &i) { diff --git a/smbase/run-flex.pl b/smbase/run-flex.pl index fed9d4f..e9c3510 100755 --- a/smbase/run-flex.pl +++ b/smbase/run-flex.pl @@ -37,6 +37,8 @@ # library classes other than those two. # # 4. Emit proper #line directives for merged extensions. +# +# 5. Added -win flag for GnuWin32 flex 2.5.4 for VisualStudio2010 build. # Given that I make so many changes, and they are so dependent on # the details of the generated file, it might seem easier to just @@ -53,6 +55,7 @@ $makeMethodCopies = 0; # if true, do step 2b above $outputFile = ""; # name of eventual output file $inputFile = ""; # name if input file +$win = 0; # hack for GnuWin32 flex 2.5.4 @flexArgs = ("flex"); # arguments to pass to flex if (@ARGV == 0) { @@ -84,6 +87,11 @@ next; } + if ($ARGV[0] eq "-win") { + $win = 1; + next; + } + my ($s) = ($ARGV[0] =~ m/^-o(.+)/); if (defined($s)) { diagnostic("saw output file: $s\n"); @@ -172,6 +180,24 @@ if ($line =~ m/class istream;/) { $lineno++; print OUT ("#include // class istream\n"); + if ($win != 0) { + $lineno++; + print OUT ("using std::istream;\n"); + $lineno++; + print OUT ("using std::ostream;\n"); + $lineno++; + print OUT ("using std::cin;\n"); + $lineno++; + print OUT ("using std::cout;\n"); + $lineno++; + print OUT ("using std::cerr;\n"); + } + next; + } + + if ($win != 0 && $line =~ m/#include /) { + $lineno++; + print OUT ("#include \n"); next; } diff --git a/smbase/str.cpp b/smbase/str.cpp index 40ad1c4..31ddadf 100644 --- a/smbase/str.cpp +++ b/smbase/str.cpp @@ -10,15 +10,17 @@ #include // strcmp #include // ostream << char* #include // assert +#ifndef _WIN32 #include // write - +#else +#include +#endif #include "xassert.h" // xassert #include "ckheap.h" // checkHeapNode #include "flatten.h" // Flatten #include "nonport.h" // vnprintf #include "array.h" // Array - // ----------------------- string --------------------- // put the empty string itself in read-only memory