/*
 * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g)
 *
 * Authors: Sumana Srinivasan, NeXT Inc.;            sumana_srinivasan@next.com
 *          Terence Parr, Parr Research Corporation; parrt@parr-research.com
 *          Russell Quong, Purdue University;        quong@ecn.purdue.edu
 *
 * VERSION 1.1
 *
 * SOFTWARE RIGHTS
 *
 * This file is a part of the ANTLR-based C++ grammar and is free
 * software.  We do not reserve any LEGAL rights to its use or
 * distribution, but you may NOT claim ownership or authorship of this
 * grammar or support code.  An individual or company may otherwise do
 * whatever they wish with the grammar distributed herewith including the
 * incorporation of the grammar or the output generated by ANTLR into
 * commerical software.  You may redistribute in source or binary form
 * without payment of royalties to us as long as this header remains
 * in all source distributions.
 *
 * We encourage users to develop parsers/tools using this grammar.
 * In return, we ask that credit is given to us for developing this
 * grammar.  By "credit", we mean that if you incorporate our grammar or
 * the generated code into one of your programs (commercial product,
 * research project, or otherwise) that you acknowledge this fact in the
 * documentation, research report, etc....  In addition, you should say nice
 * things about us at every opportunity.
 *
 * As long as these guidelines are kept, we expect to continue enhancing
 * this grammar.  Feel free to send us enhancements, fixes, bug reports,
 * suggestions, or general words of encouragement at parrt@parr-research.com.
 *
 * NeXT Computer Inc.
 * 900 Chesapeake Dr.
 * Redwood City, CA 94555
 * 12/02/1994
 *
 * Restructured for public consumption by Terence Parr late February, 1995.
 *
 * DISCLAIMER: we make no guarantees that this grammar works, makes sense,
 *             or can be used to do anything useful.
 */
/*
 * 2001-2003 Version 2.0 September 2003
 *
 * Some modifications were made to this file to support a project by
 * Jianguo Zuo and David Wigg at
 * The Centre for Systems and Software Engineering
 * South Bank University
 * London, UK.
 * wiggjd@bcs.ac.uk
 * blackse@lsbu.ac.uk
 *
 * These C++ functions are required to support the correct functioning of
 *	the CPP_parser.g definition of the C++ language.
*/
/* 2003-2004 Version 3.0 July 2004
 * Modified by David Wigg at London South Bank University for CPP_parser.g
 */
/* 2004-1005 Version 3.1 November 2005
 * Modified by David Wigg at London South Bank University for CPP_parser.g
 *
 * See MyReadMe.txt for further information
 *
 * This file is best viewed in courier font with tabs set to 4 spaces
 */

extern "C" {
#ifndef WIN32
#include <unistd.h>
#endif
}

#include <iostream>
#include <stdio.h>
#include <string.h>
#include "../CPPParser/CPPParser.hpp"

extern int
    statementTrace;  // Used to control selected tracing at statement level
//	for testing and program verification purposes

// Shorthand for a string of (qualifiedItemIs()==xxx||...)
int CPPParser::qualifiedItemIsOneOf(
    QualifiedItem qiFlags,  // Ored combination of flags
    int lookahead_offset) {
  QualifiedItem qi = qualifiedItemIs(lookahead_offset);
  return (qi & qiFlags) != 0;
}

// This is an important function, but will be replaced with
// an enhanced predicate in the future, once predicates
// and/or predicate guards can contain loops.
//
// Scan past the ::T::B:: to see what lies beyond.
// Return qiType if the qualified item can pose as type name.
// Note that T::T is NOT a type; it is a constructor.  Also,
// class T { ... T...} yields the enclosed T as a ctor.  This
// is probably a type as I separate out the constructor defs/decls,
// I want it consistent with T::T.
//
// In the below examples, I use A,B,T and example types, and
// a,b as example ids.
// In the below examples, any A or B may be a
// qualified template, i.e.,  A<...>
//
// T::T outside of class T yields qiCtor.
// T<...>::T outside of class T yields qiCtor.
// T inside of class T {...} yields qiCtor.
// T, ::T, A::T outside of class T yields qiType.
// a, ::a,  A::B::a yields qiId
// a::b yields qiInvalid
// ::operator, operator, A::B::operator yield qiOPerator
// A::*, A::B::* yield qiPtrMember
// ::*, * yields qiInvalid
// ::~T, ~T, A::~T yield qiDtor
// ~a, ~A::a, A::~T::, ~T:: yield qiInvalid

CPPParser::QualifiedItem CPPParser::qualifiedItemIs(int lookahead_offset) {
  int offset = lookahead_offset + 1;
  int final_type_idx = 0;
  // Skip leading "::"
  if (LT(offset)->getType() == SCOPE) {
    offset++;
  }
  // Skip sequences of T:: or T<...>::
  // DW 11/02/05 Note that LT(offset)->getType() is not a "type" but a type of
  // token, eg. ID
  // printf("support.cpp qualifiedItemIs while reached offset %d %s type %d
  // isType %d, isClass %d, guessing %d\n",
  //	offset,(LT(offset)->getText()).data(),LT(offset)->getType(),isTypeName((LT(offset)->getText()).data()),isClassName((LT(offset)->getText()).data()),inputState->guessing);
  while (LT(offset)->getType() == ID &&
         isTypeName((LT(offset)->getText()).data())) {  // If this type is the
                                                        // same as the last
                                                        // type, then ctor
    if (final_type_idx != 0 &&
        strcmp((LT(final_type_idx)->getText()).data(),
               (LT(offset)->getText()).data()) == 0) {  // Like T::T
      // As an extra check, do not allow T::T::
      if (LT(offset + 1)->getType() == SCOPE) {  // printf("support.cpp
                                                 // qualifiedItemIs qiInvalid
                                                 // returned\n");
        return qiInvalid;
      } else {  // printf("support.cpp qualifiedItemIs qiCtor_1 returned %s %s
                // %s \n",
        // enclosingClass,(LT(lookahead_offset+1)->getText()).data(),
        //(LT(final_type_idx)->getText()).data());
        return qiCtor;
      }
    }

    // Record this as the most recent type seen in the series
    final_type_idx = offset;

    // Skip this token
    offset++;

    // Skip over any template qualifiers <...>
    // I believe that "T<..." cannot be anything valid but a template
    if (LT(offset)->getType() == LESSTHAN) {
      if (!skipTemplateQualifiers(offset)) {  // printf("support.cpp
                                              // qualifiedItemIs qiInvalid_2
                                              // returned\n");
        return qiInvalid;
      }
      // printf("support.cpp qualifiedItemIs template skipped, offset
      // %d\n",offset);
      // offset has been updated to token following <...>
    }

    // Skip any "::" and keep going
    if (LT(offset)->getType() == SCOPE) {
      offset++;
    }
    // Otherwise series terminated -- last ID in the sequence was a type
    else {
      // Return ctor if last type is in containing class
      // We already checked for T::T inside loop
      if (strcmp(enclosingClass, (LT(final_type_idx)->getText()).data()) ==
          0) {  // Like class T  T()
        // printf("support.cpp qualifiedItemIs qiCtor_2 returned %s %s %s\n",
        //	enclosingClass,(LT(lookahead_offset+1)->getText()).data(),
        //	(LT(final_type_idx)->getText()).data());
        return qiCtor;
      } else {  // printf("support.cpp qualifiedItemIs qiType returned\n");
        return qiType;
      }
    }
  }

  // LT(offset) is not an ID, or it is an ID but not a typename.
  // printf("support.cpp qualifiedItemIs second switch reached with type
  // %d\n",LT(offset)->getType());
  switch (LT(offset)->getType()) {
    case ID:
      // ID but not a typename
      // Do not allow id::
      if (LT(offset + 1)->getType() == SCOPE) {
        // printf("support.cpp qualifiedItemIs qiInvalid_3 returned\n");
        return qiInvalid;
      }
      if (strcmp(enclosingClass, (LT(offset)->getText()).data()) ==
          0) {  // Like class T  T()
        // printf("support.cpp qualifiedItemIs qiCtor_3 returned
        // %s\n",enclosingClass);
        return qiCtor;
      } else {
        if (isTypeName((LT(offset)->getText()).data())) {
          return qiType;
        } else {
          // printf("support.cpp qualifiedItemIs qiVar returned\n");
          return qiVar;  // DW 19/03/04 was qiVar Could be function, qiFun?
        }
      }
    case TILDE:
      // check for dtor
      if (LT(offset + 1)->getType() == ID &&
          isTypeName((LT(offset + 1)->getText()).data()) &&
          LT(offset + 2)->getType() != SCOPE) {  // Like ~B or A::B::~B
        // Also (incorrectly?) matches ::~A.
        // printf("support.cpp qualifiedItemIs qiDtor returned\n");
        return qiDtor;
      } else {  // ~a or ~A::a is qiInvalid
        // printf("support.cpp qualifiedItemIs qiInvalid_4 returned\n");
        return qiInvalid;
      }
      break;
    case STAR:
      // Like A::*
      // Do not allow * or ::*
      if (final_type_idx == 0) {  // Haven't seen a type yet
        // printf("support.cpp qualifiedItemIs qiInvalid_5 returned\n");
        return qiInvalid;
      } else {  // printf("support.cpp qualifiedItemIs qiPtrMember returned\n");
        return qiPtrMember;
      }
    case OPERATOR:
      // Like A::operator, ::operator, or operator
      // printf("support.cpp qualifiedItemIs qiOperator returned\n");
      return qiOperator;
    default:
      // Something that neither starts with :: or ID, or
      // a :: not followed by ID, operator, ~, or *
      // printf("support.cpp qualifiedItemIs qiInvalid_6 returned\n");
      return qiInvalid;
  }
}

// Skip over <...>.  This correctly handles nested <> and (), e.g:
//    <T>
//    < (i>3) >
//    < T2<...> >
// but not
//    < i>3 >
//
// On input, kInOut is the index of the "<"
// On output, if the return is true, then
//                kInOut is the index of the token after ">"
//            else
//                kInOut is unchanged
int CPPParser::skipTemplateQualifiers(int &kInOut) {  // Start after "<"
  int offset = kInOut + 1;

  while (LT(offset)->getType() != GREATERTHAN)  // scan to end of <...>
  {
    switch (LT(offset)->getType()) {
      case EOF:
        return 0;
      case LESSTHAN:
        if (!skipTemplateQualifiers(offset)) {
          return 0;
        }
        break;
      case LPAREN:
        if (!skipNestedParens(offset)) {
          return 0;
        }
        break;
      default:
        offset++;  // skip everything else
        break;
    }
    if (offset > MaxTemplateTokenScan) {
      return 0;
    }
  }

  // Update output argument to point past ">"
  kInOut = offset + 1;
  return 1;
}

// Skip over (...).  This correctly handles nested (), e.g:
//    (i>3, (i>5))
//
// On input, kInOut is the index of the "("
// On output, if the return is true, then
//                kInOut is the index of the token after ")"
//            else
//                kInOut is unchanged
int CPPParser::skipNestedParens(int &kInOut) {  // Start after "("
  int offset = kInOut + 1;

  while (LT(offset)->getType() != RPAREN)  // scan to end of (...)
  {
    switch (LT(offset)->getType()) {
      case EOF:
        return 0;
      case LPAREN:
        if (!skipNestedParens(offset)) {
          return 0;
        }
        break;
      default:
        offset++;  // skip everything else
        break;
    }
    if (offset > MaxTemplateTokenScan) {
      return 0;
    }
  }

  // Update output argument to point past ")"
  kInOut = offset + 1;
  return 1;
}

// Return true if "::blah" or "foo::bar<args>::..." found.
int CPPParser::scopedItem(int k) {
  // printf("support.cpp scopedItem k %d\n",k);
  return (LT(k)->getType() == SCOPE ||
          (LT(k)->getType() == ID && !finalQualifier(k)));
}

// Return true if ID<...> or ID is last item in qualified item list.
// Return false if LT(k) is not an ID.
// ID must be a type to check for ID<...>,
// or else we would get confused by "i<3"
int CPPParser::finalQualifier(int k) {
  if (LT(k)->getType() == ID) {
    if (isTypeName((LT(k)->getText()).data()) &&
        LT(k + 1)->getType() == LESSTHAN) {  // Starts with "T<".  Skip <...>
      k++;
      skipTemplateQualifiers(k);
    } else {  // skip ID;
      k++;
    }
    return (LT(k)->getType() != SCOPE);
  } else {  // not an ID
    return 0;
  }
}

/*
 * Return true if 's' can pose as a type name
 */
int CPPParser::isTypeName(
    const char *s) {  // printf("isTypeName entered with %s\n",s);
  // To look for any type name only
  return 1;
  /*
  CPPSymbol *cs = ( CPPSymbol * ) symbols->lookup( s,CPPSymbol::otTypename );

  if ( cs==NULL )
  {
    printf("support.cpp isTypeName %s not found\n",s);
    return 0;
  }

  // This should now be redundant
  if ( cs->getType()==CPPSymbol::otTypedef||
       cs->getType()==CPPSymbol::otEnum||
       cs->getType()==CPPSymbol::otClass||
       cs->getType()==CPPSymbol::otStruct||
       cs->getType()==CPPSymbol::otUnion )
  {
    return 1;
  }

  return 0;
  */
}

/*
 * Return true if 's' is a class name (or a struct which is a class
 * with all members public).
 */
int CPPParser::isClassName(const char *s) {
  return 1;
  /*
  // To look for any type name omly
  CPPSymbol *cs = ( CPPSymbol * ) symbols->lookup( s,CPPSymbol::otTypename );

  if ( cs==NULL )
  {
    printf("support.cpp isClassName %s not found\n",s);
    return 0;
  }

  if ( cs->getType()==CPPSymbol::otClass||
       cs->getType()==CPPSymbol::otStruct||
       cs->getType()==CPPSymbol::otUnion )
  {
    return 1;
  }

  return 0;
  */
}

void CPPParser::beginDeclaration() {}

void CPPParser::endDeclaration() {}

void CPPParser::beginFunctionDefinition() { functionDefinition = 1; }

void CPPParser::endFunctionDefinition() {
  // Remove parameter scope
  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  // printf("endFunctionDefinition remove parameter
  // scope(%d):\n",symbols->getCurrentScopeIndex());
  symbols->removeScope();   // Remove symbols stored in current scope
  symbols->restoreScope();  // Reduce currentScope (higher level)
  // printf("endFunctionDefinition restoreScope() now
  // %d\n",symbols->getCurrentScopeIndex());
  functionDefinition = 0;
}

void CPPParser::beginConstructorDefinition() { functionDefinition = 1; }

void CPPParser::endConstructorDefinition() {
  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();      // Remove symbols stored in current scope
  symbols->restoreScope();     // Reduce currentScope (higher level)
  // printf("endConstructorDefinition restoreScope() now
  // %d\n",symbols->getCurrentScopeIndex());
  functionDefinition = 0;
}

void CPPParser::beginConstructorDeclaration(const char *ctor) {}

void CPPParser::endConstructorDeclaration() {}

void CPPParser::beginDestructorDefinition() { functionDefinition = 1; }

void CPPParser::endDestructorDefinition() {
  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();      // Remove symbols stored in current scope
  symbols->restoreScope();     // Reduce currentScope (higher level)
  // printf("endDestructorDefinition restoreScope() now
  // %d\n",symbols->getCurrentScopeIndex());
  functionDefinition = 0;
}

void CPPParser::beginDestructorDeclaration(const char *dtor) {}

void CPPParser::endDestructorDeclaration() {}

void CPPParser::beginParameterDeclaration() {}

void CPPParser::beginFieldDeclaration() {}

void CPPParser::declarationSpecifier(bool td, bool fd, StorageClass sc,
                                     TypeQualifier tq, TypeSpecifier ts,
                                     FunctionSpecifier fs) {
  // printf("support.cpp declarationSpecifier td %d, fd %d, sc %d, tq %d, ts %d,
  // fs %d\n",
  //	td,fd,sc,tq,ts,fs);
  _td = td;  // For typedef
  _fd = fd;  // For friend
  _sc = sc;
  _tq = tq;
  _ts = ts;
  _fs = fs;
}

/* Symbols from declarators are added to the symbol table here.
 * The symbol is added to external scope or whatever the current scope is, in
 * the symbol table.
 * See list of object types below.
 */
void CPPParser::declaratorID(const char *id, QualifiedItem qi) {
  // printf("declaratorID  entered for %s\n",id);
  CPPSymbol *c;
  // printf("support.cpp declaratorID line %d %s found, _ts = %d, _td = %d, qi =
  // %d\n",
  //        LT(1)->getLine(),id,_ts,_td,qi);
  if (qi == qiType || qi == qiNamespace)  // Check for type declaration
  {
    c = new CPPSymbol(id, CPPSymbol::otTypedef);
    if (c == NULL) panic("can't alloc CPPSymbol");
    symbols->defineInScope(id, c, externalScope);
    if (statementTrace >= 2) {
      printf(
          "%d support.cpp declaratorID declare %s in external scope 1, "
          "ObjectType %d\n",
          LT(1)->getLine(), id, c->getType());
    }
    // DW 04/08/03 Scoping not fully implemented
    // Typedefs all recorded in 'external' scope and therefor never removed
  } else if (qi == qiFun)  // Check for function declaration
  {
    c = new CPPSymbol(id, CPPSymbol::otFunction);
    if (c == NULL) panic("can't alloc CPPSymbol");
    symbols->define(id, c);  // Add to current scope
    if (statementTrace >= 2) {
      printf(
          "%d support.cpp declaratorID declare %s in current scope %d, "
          "ObjectType %d\n",
          LT(1)->getLine(), id, symbols->getCurrentScopeIndex(), c->getType());
    }
  } else {
    if (qi != qiVar) {
      fprintf(
          stderr,
          "%d support.cpp declaratorID warning qi (%d) not qiVar (%d) for %s\n",
          LT(1)->getLine(), qi, qiVar, id);
    }

    c = new CPPSymbol(id, CPPSymbol::otVariable);
    if (c == NULL) panic("can't alloc CPPSymbol");
    symbols->define(id, c);  // Add to current scope
    if (statementTrace >= 2) {
      printf(
          "%d support.cpp declaratorID declare %s in current scope %d, "
          "ObjectType %d\n",
          LT(1)->getLine(), id, symbols->getCurrentScopeIndex(), c->getType());
    }
  }
}
/* These are the object types
        0 = otInvalid
        1 = otFunction
        2 = otVariable
        3 = otTypedef	Note. 3-7 are type names
        4 = otStruct	Note. 4, 5 & 7 are class names
        5 = otUnion
        6 = otEnum
        7 = otClass
   10 = otTypename
   11 = otNonTypename
*/

void CPPParser::declaratorArray() {}

void CPPParser::declaratorParameterList(int def) {
  symbols->saveScope();  // Advance currentScope (lower level)
  // printf("declaratorParameterList saveScope() now
  // %d\n",symbols->getCurrentScopeIndex());
}

void CPPParser::declaratorEndParameterList(int def) {
  if (!def) {
    symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
    symbols->removeScope();      // Remove symbols stored in current scope
    symbols->restoreScope();     // Reduce currentScope (higher level)
    // printf("declaratorEndParameterList restoreScope() now
    // %d\n",symbols->getCurrentScopeIndex());
  }
}

void CPPParser::functionParameterList() {
  symbols->saveScope();  // Advance currentScope (lower level)
  // printf("functionParameterList saveScope() now
  // %d\n",symbols->getCurrentScopeIndex());
  // DW 25/3/97 change flag from function to parameter list
  functionDefinition = 2;
}

void CPPParser::functionEndParameterList(int def) {
  // If this parameter list is not in a definition then this
  if (!def) {
    symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
    symbols->removeScope();      // Remove symbols stored in current scope
    symbols->restoreScope();     // Reduce currentScope (higher level)
    // printf("functionEndParameterList restoreScope() now
    // %d\n",symbols->getCurrentScopeIndex());
  } else {
    // Change flag from parameter list to body of definition
    functionDefinition = 3;
  }
  // Otherwise endFunctionDefinition removes the parameters from scope
}

void CPPParser::enterNewLocalScope() {
  symbols->saveScope();  // Advance currentScope (lower level)
  // printf("enterNewLocalScope saveScope() now
  // %d\n",symbols->getCurrentScopeIndex());
}

void CPPParser::exitLocalScope() {
  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();      // Remove symbols stored in current scope
  symbols->restoreScope();     // Reduce currentScope (higher level)
  // printf("exitLocalScope restoreScope() now
  // %d\n",symbols->getCurrentScopeIndex());
}

void CPPParser::enterExternalScope() {  // Scope has been initialised to 1 in
                                        // CPPParser.init() in CPPParser.hpp
  functionDefinition = 0;
}

void CPPParser::exitExternalScope() {
  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();      // Remove symbols stored in current scope s/b 2
  symbols->restoreScope();     // Reduce currentScope (higher level)

  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();      // Remove symbols stored in current scope s/b 1
  symbols->restoreScope();     // Reduce currentScope (higher level)

  if (symbols->getCurrentScopeIndex() == 0) {
    if (statementTrace >= 2) {
      fprintf(stdout, "\nSupport exitExternalScope, scope now %d as required\n",
              symbols->getCurrentScopeIndex());
    }
  } else {
    fprintf(stderr, "\nSupport exitExternalScope, scope now %d, should be 0\n",
            symbols->getCurrentScopeIndex());
  }
}

void CPPParser::classForwardDeclaration(TypeSpecifier ts, FunctionSpecifier fs,
                                        const char *tag)
// classForwardDeclaration(const char *tag, TypeSpecifier ts, FunctionSpecifier
// fs)
{
  CPPSymbol *c = NULL;

  // if already in symbol table as a class, don't add
  // of course, this is incorrect as you can rename
  // classes by entering a new scope, but our limited
  // example basically keeps all types globally visible.
  if (symbols->lookup(tag, CPPSymbol::otTypename) != NULL) {
    CPPSymbol *cs = (CPPSymbol *)symbols->lookup(tag, CPPSymbol::otTypename);
    if (statementTrace >= 2) {
      printf(
          "%d support.cpp classForwardDeclaration %s already stored in "
          "dictionary, ObjectType %d\n",
          LT(1)->getLine(), tag, cs->getType());
    }
    return;
  }

  switch (ts) {
    case tsSTRUCT:
      c = new CPPSymbol(tag, CPPSymbol::otStruct);
      break;
    case tsUNION:
      c = new CPPSymbol(tag, CPPSymbol::otUnion);
      break;
    case tsCLASS:
      c = new CPPSymbol(tag, CPPSymbol::otClass);
      break;
  }

  if (c == NULL) panic("can't alloc CPPSymbol");

  symbols->defineInScope(tag, c, externalScope);
  if (statementTrace >= 2) {
    printf(
        "%d support.cpp classForwardDeclaration declare %s in external scope, "
        "ObjectType %d\n",
        LT(1)->getLine(), tag, c->getType());
  }

  // If it's a friend class forward decl, put in global scope also.
  // DW 04/07/03 No need if already in external scope. See above.
  // if ( ds==dsFRIEND )
  //	{
  //	CPPSymbol *ext_c = new CPPSymbol(tag, CPPSymbol::otClass);
  //	if ( ext_c==NULL ) panic("can't alloc CPPSymbol");
  //	if ( symbols->getCurrentScopeIndex()!=externalScope )	// DW 04/07/03
  // Not sure this test is really necessary
  //		{
  //		printf("classForwardDeclaration
  // defineInScope(externalScope)\n");
  //		symbols->defineInScope(tag, ext_c, externalScope);
  //		}
  //	}
}

void CPPParser::exitNamespaceScope() {}

void CPPParser::beginClassDefinition(TypeSpecifier ts, const char *tag) {
  CPPSymbol *c = NULL;

  // if already in symbol table as a class, don't add
  // of course, this is incorrect as you can rename
  // classes by entering a new scope, but our limited
  // example basically keeps all types globally visible.
  if (symbols->lookup(tag, CPPSymbol::otTypename) != NULL) {
    symbols->saveScope();  // still have to use scope to collect members
    // printf("support.cpp beginClassDefinition_1 saveScope() now
    // %d\n",symbols->getCurrentScopeIndex());
    if (statementTrace >= 2) {
      printf(
          "%d support.cpp beginClassDefinition classname %s already in "
          "dictionary\n",
          LT(1)->getLine(), tag);
    }
    return;
  }

  switch (ts) {
    case tsSTRUCT:
      c = new CPPSymbol(tag, CPPSymbol::otStruct);
      break;
    case tsUNION:
      c = new CPPSymbol(tag, CPPSymbol::otUnion);
      break;
    case tsCLASS:
      c = new CPPSymbol(tag, CPPSymbol::otClass);
      break;
  }
  if (c == NULL) panic("can't alloc CPPSymbol");

  symbols->defineInScope(tag, c, externalScope);

  if (statementTrace >= 2) {
    printf(
        "%d support.cpp beginClassDefinition define %s in external scope (1), "
        "ObjectType %d\n",
        LT(1)->getLine(), tag, c->getType());
  }

  strcat(qualifierPrefix, tag);
  strcat(qualifierPrefix, "::");

  // add all member type symbols into the global scope (not correct, but
  // will work for most code).
  // This symbol lives until the end of the file
  symbols->saveScope();  // Advance currentScope (lower level)
}

void CPPParser::endClassDefinition() {
  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();      // Remove symbols stored in current scope
  symbols->restoreScope();     // Reduce currentScope (higher level)
  // remove final T:: from A::B::C::T::
  // upon backing out of last class, qualifierPrefix is set to ""
  char *p = &(qualifierPrefix[strlen(qualifierPrefix) - 3]);
  while (p > &(qualifierPrefix[0]) && *p != ':') {
    p--;
  }
  if (p > &(qualifierPrefix[0])) p++;
  *p = '\0';
}

void CPPParser::enumElement(const char *e) {}

void CPPParser::beginEnumDefinition(
    const char *e) {  // DW 26/3/97 Set flag for new class

  // add all enum tags into the global scope (not correct, but
  // will work for most code).
  // This symbol lives until the end of the file
  CPPSymbol *c = new CPPSymbol(e, CPPSymbol::otEnum);
  symbols->defineInScope(e, c, externalScope);
  if (statementTrace >= 2) {
    printf(
        "%d support.cpp beginEnumDefinition %s define in external scope, "
        "ObjectType %d\n",
        LT(1)->getLine(), e, c->getType());
  }
}

void CPPParser::endEnumDefinition() {}

void CPPParser::templateTypeParameter(const char *t) {
  // DW 11/06/03 Symbol saved in templateParameterScope (0)
  //  as a temporary measure until scope is implemented fully
  // This symbol lives until the end of the file
  CPPSymbol *e = new CPPSymbol(t, CPPSymbol::otTypedef);  // DW 22/03/05
  //	CPPSymbol *e = new CPPSymbol(t, CPPSymbol::otClass);
  if (e == NULL) panic("can't alloc CPPSymbol");
  //	symbols->defineInScope(t, e, templateParameterScope);	// DW 22/03/05
  // DW 10/08/05 Replaced to make template parameters local
  symbols->defineInScope(t, e, externalScope);
  //	symbols->define(t,e);	// Save template parameter in local scope
  if (statementTrace >= 2) {
    //		printf("%d support.cpp templateTypeParameter declare %s in
    // parameter
    // scope (0), ObjectType %d\n",
    printf(
        "%d support.cpp templateTypeParameter declare %s in  external scope "
        "(1), ObjectType %d\n",
        LT(1)->getLine(), t, e->getType());
  }
  //		printf("%d support.cpp templateTypeParameter declare %s in
  // current
  // scope %d, ObjectType %d\n",
  //			LT(1)->getLine(),t,symbols->getCurrentScopeIndex(),e->getType());
}

void CPPParser::beginTemplateDeclaration() {
  symbols->saveScope();  // Advance currentScope (lower level)
  // printf("Support beginTemplateDeclaration, Scope now
  // %d\n",symbols->getCurrentScopeIndex());
}

void CPPParser::endTemplateDeclaration() {
  symbols->dumpScope(stdout);  // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();      // Remove symbols stored in current scope
  symbols->restoreScope();     // Reduce currentScope (higher level)
  // printf("Support endTemplateDeclaration, Scope now
  // %d\n",symbols->getCurrentScopeIndex());
}

void CPPParser::beginTemplateDefinition() {}

void CPPParser::endTemplateDefinition() {}

void CPPParser::beginTemplateParameterList() {
  // DW 26/05/03 To scope template parameters
  symbols->saveScope();  // Advance currentScope (lower level)
}

void CPPParser::endTemplateParameterList() {
  // DW 26/05/03 To end scope template parameters
  symbols->restoreScope();  // Reduce currentScope (higher level)
}

void CPPParser::exceptionBeginHandler() {}

void CPPParser::exceptionEndHandler() {  // remove parm elements from the
                                         // handler scope
  symbols->dumpScope(stdout);            // Diagnostic - See CPPDictionary.hpp
  symbols->removeScope();   // Remove symbols stored in current scope
  symbols->restoreScope();  // Reduce currentScope (higher level)
}

void CPPParser::end_of_stmt() {
#ifdef MYCODE
  myCode_end_of_stmt();
#endif  // MYCODE
}

void CPPParser::panic(const char *err) {
  fprintf(stdout, "CPPParser: %s\n", err);
  _exit(-1);
}

/* DW 090204 leave out of support.cpp for the time being
// want to see how supplied routine in LLkParser works first
void CPPParser::
tracein(char *r)
{
// testing
        printf("support tracein entered\n");
        getchar();
   if ( !doTracing ) return;
   for (int i=1; i<=traceIndentLevel; i++)
           fprintf(stdout, " ");
   traceIndentLevel++;
   fprintf(stdout, "enter %s('%s %s')%s\n",
      r,
      (LT(1)->getText()).data(),
      (LT(2)->getText()).data(),
      inputState->guessing?" [guessing]":""
   );
   fflush(stdout);
}

void CPPParser::
traceout(char *r)
{
   if ( !doTracing ) return;
   traceIndentLevel--;
   for (int i=1; i<=traceIndentLevel; i++)
           fprintf(stdout, " ");
   fprintf(stdout, "exit %s('%s %s')%s\n",
      r,
      (LT(1)->getText()).data(),
      (LT(2)->getText()).data(),
      inputState->guessing?" [guessing]":""
   );
   fflush(stdout);
}
*/

//	Functions which may be overridden by MyCode subclass

void CPPParser::myCode_pre_processing(int argc, char *argv[]) {}

void CPPParser::myCode_post_processing() {}

void CPPParser::myCode_end_of_stmt() {}

void CPPParser::myCode_function_direct_declarator(const char *id) {
  // printf("support myCode_function_direct_declarator entered for %s\n",id);
}
