Inferno  0.2
parse.hpp
Go to the documentation of this file.
00001 #ifndef PARSE_HPP
00002 #define PARSE_HPP
00003 
00004 #include "common/common.hpp"
00005 
00006 #include "llvm/ADT/APInt.h"
00007 #include "llvm/ADT/APSInt.h"
00008 #include "llvm/ADT/APFloat.h"
00009 #include "llvm/ADT/SmallString.h"
00010 #include "llvm/Support/raw_ostream.h"
00011 
00012 #include "clang/Basic/FileManager.h"
00013 #include "clang/Basic/Diagnostic.h"
00014 #include "clang/Basic/LangOptions.h"
00015 #include "clang/Basic/TokenKinds.h"
00016 #include "clang/Basic/TargetInfo.h"
00017 #include "clang/Basic/SourceManager.h"
00018 #include "clang/Lex/HeaderSearch.h"
00019 #include "clang/Lex/Preprocessor.h"
00020 #include "clang/Basic/IdentifierTable.h"
00021 #include "clang/Parse/Action.h"
00022 #include "clang/Parse/Parser.h"
00023 #include "clang/Parse/DeclSpec.h"
00024 #include "clang/Parse/Designator.h"
00025 #include "clang/Parse/Scope.h"
00026 #include "clang/Driver/TextDiagnosticPrinter.h"
00027 #include "clang/Lex/LiteralSupport.h"
00028 
00029 #include "tree/cpptree.hpp"
00030 #include "helpers/transformation.hpp"
00031 #include "common/trace.hpp"
00032 #include "tree/type_db.hpp"
00033 #include "tree/misc.hpp"
00034 #include "tree/typeof.hpp"
00035 
00036 #include "rc_hold.hpp"
00037 #include "identifier_tracker.hpp"
00038 
00039 using namespace CPPTree; // TODO put parse in cpp file so this using does not pollute
00040 
00041 #define INFERNO_TRIPLE "arm-linux"
00042 
00043 class Parse: public InPlaceTransformation
00044 {
00045 public:
00046   using Transformation::operator();
00047   Parse(string i) :
00048     infile(i)
00049   {
00050   }
00051 
00052   void operator()(TreePtr<Node> context, TreePtr<Node> *proot)
00053   {
00054     // Allow proot to point to a NULL TreePtr; in this case we will create a Program node and parse into it.
00055     // Otherwise *proot must be a Scope, and we will append whatever we parse into that scope.
00056     ASSERT( proot );
00057     if (!*proot)
00058     {
00059       *proot = TreePtr<Program> (new Program);
00060     }
00061     if (!context)
00062       context = *proot;
00063     TreePtr<Scope> root_scope = dynamic_pointer_cast<Scope> (*proot);
00064     ASSERT(root_scope)("Can only parse into a scope");
00065 
00066     clang::FileManager fm;
00067     llvm::raw_stderr_ostream errstream; // goes to stderr
00068     clang::TextDiagnosticPrinter diag_printer(errstream);
00069     clang::Diagnostic diags(&diag_printer);
00070     clang::LangOptions opts;
00071     opts.CPlusPlus = 1; // Note: always assume input is C++, even if file ends in .c
00072     clang::TargetInfo* ptarget = clang::TargetInfo::CreateTargetInfo(
00073         INFERNO_TRIPLE);
00074     ASSERT(ptarget);
00075     clang::SourceManager sm;
00076     clang::HeaderSearch headers(fm);
00077     
00078     std::vector<clang::DirectoryLookup> dirs;
00079     dirs.push_back( clang::DirectoryLookup( fm.getDirectory( string(get_current_dir_name()) + string("/resource/include") ), 
00080                                             clang::SrcMgr::C_System, 
00081                                             true, 
00082                                             false ) ); // TODO would prefer based on location of exe rather than CWD
00083     headers.SetSearchPaths( dirs, 0, false ); // make the directory in dirs be a system directory
00084 
00085     clang::Preprocessor pp(diags, opts, *ptarget, sm, headers);
00086     pp.setPredefines("#define __INFERNO__ 1\n");
00087 
00088     const clang::FileEntry *file = fm.getFile(infile);
00089     if (file)
00090       sm.createMainFileID(file, clang::SourceLocation());
00091     if (sm.getMainFileID() == 0)
00092     {
00093       fprintf(stderr, "Error reading '%s'!\n", infile.c_str());
00094       exit(1);
00095     }
00096     pp.EnterMainSourceFile();
00097 
00098     clang::IdentifierTable it(opts);
00099     InfernoAction actions(context, root_scope, it, pp, *ptarget);
00100     clang::Parser parser(pp, actions);
00101     TRACE("Start parse\n");
00102     parser.ParseTranslationUnit();
00103         ASSERT( !diags.hasErrorOccurred() )("Will not proceed into inferno because clang reported errors\n");
00104     TRACE("End parse\n");
00105   }
00106 
00107 private:
00108   string infile;
00109 
00110   class InfernoAction: public clang::Action
00111   {
00112   public:
00113     InfernoAction(TreePtr<Node> context, TreePtr<Scope> root_scope,
00114         clang::IdentifierTable &IT, clang::Preprocessor &pp,
00115         clang::TargetInfo &T) :
00116       preprocessor(pp), target_info(T), ident_track(context),
00117           global_scope(context), all_decls(new Program) // TODO Scope not Program
00118     {
00119       ASSERT( context );
00120       ASSERT( root_scope );
00121       inferno_scope_stack.push(root_scope); // things will be pushed into here
00122       backing_ordering[inferno_scope_stack.top()].clear();
00123     }
00124 
00125     ~InfernoAction()
00126     {
00127       inferno_scope_stack.pop();
00128       assert( inferno_scope_stack.empty() );
00129     }
00130 
00131   private:
00132     // Parameters are parsed outside function scope, so we defer entering them
00133     // into the ident_track until we're in the function. This stores the clang identifiers.
00134     map<TreePtr<Declaration> , clang::IdentifierInfo *> backing_params;
00135 
00136     // The statement after a label is parsed as a sub-construct under the label which
00137     // is not how the inferno tree does it. Remember that relationship here and
00138     // generate the extra nodes when rendering a compound statement.
00139     map<TreePtr<Label> , TreePtr<Statement> > backing_labels;
00140     map<TreePtr<SwitchTarget> , TreePtr<Statement> > backing_targets;
00141     Map<TreePtr<Declaration> , TreePtr<Declaration> >
00142         backing_paired_decl;
00143 
00144     // Members of records go in an unordered collection, but when parsing
00145     // we might need the order, eg for C-style initialisers or auto-generated
00146     // constructor calls.
00147     Map<TreePtr<Scope> , Sequence<Declaration> > backing_ordering;
00148 
00149     // In ActOnTag, when we see a record decl, we store it here and generate it
00150     // at the next IssueDeclaration, called from ActOnDeclaration. This allows
00151     // a seperate decl for records, since we so not support anon ones, and only
00152     // allow one thing to be decl'd at a time.
00153     TreePtr<Declaration> decl_to_insert;
00154 
00155     clang::Preprocessor &preprocessor;
00156     clang::TargetInfo &target_info;
00157 
00158     stack<TreePtr<Scope> > inferno_scope_stack;
00159     RCHold<Declaration, DeclTy *> hold_decl;
00160     RCHold<Base, DeclTy *> hold_base;
00161     RCHold<Expression, ExprTy *> hold_expr;
00162     RCHold<Statement, StmtTy *> hold_stmt;
00163     RCHold<Type, TypeTy *> hold_type;
00164     RCHold<LabelIdentifier, void *> hold_label_identifier;
00165     RCHold<Node, CXXScopeTy *> hold_scope;
00166     IdentifierTracker ident_track;
00167     TreePtr<Node> global_scope;
00168     TreePtr<Program> all_decls; // not the actual program, just a flattening of the decls
00169     // we maintain this because decls don't always make it
00170     // into the tree by the time we need them, thanks to the
00171     // way clang works. Decls go in here immediately.
00172 
00173     OwningStmtResult ToStmt(TreePtr<Statement> s)
00174     {
00175       return OwningStmtResult(*this, hold_stmt.ToRaw(s));
00176     }
00177 
00178     OwningExprResult ToExpr(TreePtr<Expression> e)
00179     {
00180       return OwningExprResult(*this, hold_expr.ToRaw(e));
00181     }
00182 
00183     TreePtr<Statement> FromClang(const StmtArg &s)
00184     {
00185       return hold_stmt.FromRaw(s.get());
00186     }
00187 
00188     TreePtr<Expression> FromClang(const ExprArg &e)
00189     {
00190       return hold_expr.FromRaw(e.get());
00191     }
00192 
00193     struct DeclarationAsStatement: Statement
00194     {
00195       NODE_FUNCTIONS
00196       TreePtr<Declaration> d;
00197     };
00198 
00199     struct DeclarationChain: Declaration
00200     {
00201       NODE_FUNCTIONS
00202       TreePtr<Declaration> first;
00203       TreePtr<Declaration> second;
00204     };
00205 
00206     // Turn a clang::CXXScopeSpec into a pointer to the corresponding scope node.
00207     // We have to deal with all the ways of it baing invalid, then just use hold_scope.
00208     TreePtr<Node> FromCXXScope(const clang::CXXScopeSpec *SS)
00209     {
00210       if (!SS)
00211         return TreePtr<Node> ();
00212 
00213       if (SS->isEmpty())
00214         return TreePtr<Node> ();
00215 
00216       if (!SS->isSet())
00217         return TreePtr<Node> ();
00218 
00219       return hold_scope.FromRaw(SS->getScopeRep());
00220     }
00221 
00222     clang::Action::TypeTy *isTypeName(clang::IdentifierInfo &II,
00223         clang::Scope *S, const clang::CXXScopeSpec *SS)
00224     {
00225       TreePtr<Node> n = ident_track.TryGet(&II, FromCXXScope(SS));
00226       if (n)
00227       {
00228         TreePtr<UserType> t = dynamic_pointer_cast<UserType> (n);
00229         if (t)
00230           return hold_type.ToRaw(t->identifier);
00231       }
00232 
00233       return 0;
00234     }
00235 
00236     virtual DeclTy *isTemplateName(clang::IdentifierInfo &II,
00237         clang::Scope *S, const clang::CXXScopeSpec *SS = 0)
00238     {
00239       return 0; // TODO templates
00240     }
00241 
00242     virtual bool isCurrentClassName(const clang::IdentifierInfo& II,
00243         clang::Scope *S, const clang::CXXScopeSpec *SS)
00244     {
00245         TRACE();
00246       ident_track.SeenScope(S);
00247 
00248       TreePtr<Node> cur = ident_track.GetCurrent();
00249       if (!dynamic_pointer_cast<Record> (cur))
00250         return false; // not even in a record
00251 
00252       TreePtr<Node> cxxs = FromCXXScope(SS);
00253       TreePtr<Node> n = ident_track.TryGet(&II, cxxs);
00254       return n == cur;
00255     }
00256 
00257     virtual void ActOnPopScope(clang::SourceLocation Loc, clang::Scope *S)
00258     {
00259         TRACE();
00260       ident_track.PopScope(S);
00261     }
00262 
00263     TreePtr<Integral> CreateIntegralType(int bits, bool default_signed,
00264         clang::DeclSpec::TSS type_spec_signed =
00265             clang::DeclSpec::TSS_unspecified)
00266     {
00267       TreePtr<Integral> i;
00268       bool sign;
00269       switch (type_spec_signed)
00270       {
00271       case clang::DeclSpec::TSS_signed:
00272         sign = true;
00273         break;
00274       case clang::DeclSpec::TSS_unsigned:
00275         sign = false;
00276         break;
00277       case clang::DeclSpec::TSS_unspecified:
00278         sign = default_signed;
00279         break;
00280       }
00281 
00282       if (sign)
00283         i = TreePtr<Signed> (new Signed);
00284       else
00285         i = TreePtr<Unsigned> (new Unsigned);
00286 
00287       i->width = CreateNumericConstant(bits);
00288       return i;
00289     }
00290 
00291     TreePtr<Floating> CreateFloatingType(const llvm::fltSemantics *s)
00292     {
00293       ASSERT(s);
00294       TreePtr<SpecificFloatSemantics> sem(
00295           new SpecificFloatSemantics(s));
00296       TreePtr<Floating> f(new Floating);
00297       f->semantics = sem;
00298       return f;
00299     }
00300 
00301     void FillParameters(TreePtr<CallableParams> p,
00302                     const clang::DeclaratorChunk::FunctionTypeInfo &fchunk)
00303     {
00304       backing_ordering[p].clear(); // ensure at least an empty sequence is in the map
00305       for (int i = 0; i < fchunk.NumArgs; i++)
00306       {
00307         TreePtr<Declaration> d = hold_decl.FromRaw(
00308             fchunk.ArgInfo[i].Param);
00309         TreePtr<Instance> inst = dynamic_pointer_cast<Instance> (d);
00310         ASSERT( inst );
00311         backing_ordering[p].push_back(inst);
00312         p->members.insert(inst);
00313       }
00314     }
00315 
00316     TreePtr<Type> CreateTypeNode(clang::Declarator &D, int depth = 0)
00317     {
00318       ASSERT( depth>=0 );
00319       ASSERT( depth<=D.getNumTypeObjects() );
00320 
00321       if (depth == D.getNumTypeObjects())
00322       {
00323         const clang::DeclSpec &DS = D.getDeclSpec();
00324         clang::DeclSpec::TST t = DS.getTypeSpecType();
00325         ASSERT( DS.getTypeSpecComplex() == clang::DeclSpec::TSC_unspecified )(
00326             "complex types not supported");
00327         switch (t)
00328         {
00329         case clang::DeclSpec::TST_int:
00330         case clang::DeclSpec::TST_unspecified:
00331           TRACE("int based %d %d\n", DS.getTypeSpecWidth(),
00332               DS.getTypeSpecSign());
00333           return CreateIntegralType(
00334               TypeDb::integral_bits[DS.getTypeSpecWidth()],
00335               TypeDb::int_default_signed, DS.getTypeSpecSign());
00336           break;
00337         case clang::DeclSpec::TST_char:
00338           TRACE("char based %d %d\n", DS.getTypeSpecWidth(),
00339               DS.getTypeSpecSign());
00340           return CreateIntegralType(TypeDb::char_bits,
00341               TypeDb::char_default_signed, DS.getTypeSpecSign());
00342           break;
00343         case clang::DeclSpec::TST_void:
00344           TRACE("void based %d %d\n", DS.getTypeSpecWidth(),
00345               DS.getTypeSpecSign());
00346           return TreePtr<Type> (new Void());
00347           break;
00348         case clang::DeclSpec::TST_bool:
00349           TRACE("bool based %d %d\n", DS.getTypeSpecWidth(),
00350               DS.getTypeSpecSign());
00351           return TreePtr<Type> (new Boolean());
00352           break;
00353         case clang::DeclSpec::TST_float:
00354           TRACE("float based %d %d\n", DS.getTypeSpecWidth(),
00355               DS.getTypeSpecSign());
00356           return CreateFloatingType(TypeDb::float_semantics);
00357           break;
00358         case clang::DeclSpec::TST_double:
00359           TRACE("double based %d %d\n", DS.getTypeSpecWidth(),
00360               DS.getTypeSpecSign());
00361           return CreateFloatingType(
00362               DS.getTypeSpecWidth() == clang::DeclSpec::TSW_long ? TypeDb::long_double_semantics
00363                   : TypeDb::double_semantics);
00364           break;
00365         case clang::DeclSpec::TST_typedef:
00366           TRACE("typedef\n");
00367           return hold_type.FromRaw(DS.getTypeRep());
00368           break;
00369         case clang::DeclSpec::TST_struct:
00370         case clang::DeclSpec::TST_union:
00371         case clang::DeclSpec::TST_class:
00372         case clang::DeclSpec::TST_enum:
00373           TRACE("struct/union/class/enum\n");
00374           // Disgustingly, clang casts the DeclTy returned from ActOnTag() to
00375           // a TypeTy.
00376           return dynamic_pointer_cast<Record> (hold_decl.FromRaw(
00377               DS.getTypeRep()))->identifier;
00378           break;
00379         default:
00380           ASSERTFAIL("unsupported type")
00381           ;
00382           break;
00383         }
00384       }
00385       else
00386       {
00387         const clang::DeclaratorChunk &chunk = D.getTypeObject(depth);
00388         switch (chunk.Kind)
00389         {
00390         case clang::DeclaratorChunk::Function:
00391         {
00392           const clang::DeclaratorChunk::FunctionTypeInfo &fchunk =
00393               chunk.Fun;
00394           switch (D.getKind())
00395           {
00396           case clang::Declarator::DK_Normal:
00397           {
00398             TreePtr<Function> f(new Function);
00399             FillParameters(f, fchunk);
00400             f->return_type = CreateTypeNode(D, depth + 1);
00401             return f;
00402           }
00403           case clang::Declarator::DK_Constructor:
00404           {
00405             TreePtr<Constructor> c(new Constructor);
00406             FillParameters(c, fchunk);
00407             return c;
00408           }
00409           case clang::Declarator::DK_Destructor:
00410           {
00411             TreePtr<Destructor> d(new Destructor);
00412             return d;
00413           }
00414           default:
00415             ASSERT("Unknown function kind\n");
00416             break;
00417           }
00418         }
00419 
00420         case clang::DeclaratorChunk::Pointer:
00421         {
00422           // TODO attributes
00423           TRACE("pointer to...\n");
00424           const clang::DeclaratorChunk::PointerTypeInfo &pchunk =
00425               chunk.Ptr;
00426           TreePtr<Pointer> p(new Pointer);
00427           p->destination = CreateTypeNode(D, depth + 1);
00428           return p;
00429         }
00430 
00431         case clang::DeclaratorChunk::Reference:
00432         {
00433           // TODO attributes
00434           TRACE("reference to...\n");
00435           const clang::DeclaratorChunk::ReferenceTypeInfo &rchunk =
00436               chunk.Ref;
00437           TreePtr<Reference> r(new Reference);
00438           ASSERT(r);
00439           r->destination = CreateTypeNode(D, depth + 1);
00440           return r;
00441         }
00442 
00443         case clang::DeclaratorChunk::Array:
00444         {
00445           // TODO attributes
00446           const clang::DeclaratorChunk::ArrayTypeInfo &achunk =
00447               chunk.Arr;
00448           TRACE("array [%d] of...\n", achunk.NumElts);
00449           TreePtr<Array> a(new Array);
00450           ASSERT(a);
00451           a->element = CreateTypeNode(D, depth + 1);
00452           if (achunk.NumElts)
00453             a->size = hold_expr.FromRaw(achunk.NumElts); // number of elements was specified
00454           else
00455             a->size = MakeTreePtr<Uninitialised> (); // number of elements was not specified eg int a[];
00456           return a;
00457         }
00458 
00459         default:
00460           ASSERTFAIL("Unknown type chunk")
00461           ;
00462           break;
00463         }
00464       }
00465     }
00466 
00467     TreePtr<InstanceIdentifier> CreateInstanceIdentifier(
00468         clang::IdentifierInfo *ID = 0)
00469     {
00470       if (ID)
00471       {
00472         TreePtr<SpecificInstanceIdentifier> ii(
00473             new SpecificInstanceIdentifier(ID->getName()));
00474         return ii;
00475       }
00476       else
00477       {
00478         TreePtr<SpecificInstanceIdentifier> ii(
00479             new SpecificInstanceIdentifier);
00480         return ii;
00481       }
00482     }
00483 
00484     TreePtr<TypeIdentifier> CreateTypeIdentifier(
00485         clang::IdentifierInfo *ID)
00486     {
00487       ASSERT( ID );
00488       TreePtr<SpecificTypeIdentifier> ti(new SpecificTypeIdentifier(
00489           ID->getName()));
00490       return ti;
00491     }
00492 
00493     TreePtr<TypeIdentifier> CreateTypeIdentifier(string s)
00494     {
00495       TreePtr<SpecificTypeIdentifier>
00496           ti(new SpecificTypeIdentifier(s));
00497       return ti;
00498     }
00499 
00500     TreePtr<LabelIdentifier> CreateLabelIdentifier(
00501         clang::IdentifierInfo *ID)
00502     {
00503       ASSERT( ID );
00504       TreePtr<SpecificLabelIdentifier> li(new SpecificLabelIdentifier(
00505           ID->getName()));
00506       return li;
00507     }
00508 
00509     TreePtr<Instance> CreateInstanceNode(clang::Scope *S,
00510         clang::Declarator &D, TreePtr<AccessSpec> access =
00511             TreePtr<AccessSpec> (), bool automatic = false)
00512     {
00513         TRACE();
00514       const clang::DeclSpec &DS = D.getDeclSpec();
00515       if (!access)
00516         access = TreePtr<Private> (new Private); // Most scopes are private unless specified otherwise
00517 
00518       TreePtr<Constancy> constancy;
00519       if (DS.getTypeQualifiers() & clang::DeclSpec::TQ_const)
00520         constancy = MakeTreePtr<Const> ();
00521       else
00522         constancy = MakeTreePtr<NonConst> ();
00523 
00524       TreePtr<Instance> o;
00525 
00526       if (automatic)
00527       {
00528         o = MakeTreePtr<Automatic> ();
00529       }
00530       else
00531       {
00532         clang::DeclSpec::SCS scs = DS.getStorageClassSpec();
00533         switch (scs)
00534         {
00535         case clang::DeclSpec::SCS_unspecified:
00536         {
00537           TRACE("scope flags 0x%x\n", S->getFlags());
00538           if (S->getFlags() & clang::Scope::CXXClassScope) // record scope
00539           {
00540             TreePtr<Field> no = MakeTreePtr<Field> ();
00541             o = no;
00542             if (DS.isVirtualSpecified())
00543             {
00544               no->virt = MakeTreePtr<Virtual> ();
00545             }
00546             else
00547             {
00548               no->virt = MakeTreePtr<NonVirtual> ();
00549             }
00550             no->access = access;
00551             no->constancy = constancy;
00552           }
00553           else if (S->getFnParent()) // in code
00554           {
00555             o = MakeTreePtr<Automatic> ();
00556           }
00557           else // top level
00558           {
00559             TreePtr<Static> no = MakeTreePtr<Static> ();
00560             o = no;
00561             no->constancy = constancy;
00562           }
00563           break;
00564         }
00565         case clang::DeclSpec::SCS_auto:
00566           o = MakeTreePtr<Automatic> ();
00567           break;
00568         case clang::DeclSpec::SCS_extern:// linking will be done "automatically" so no need to remember "extern" in the tree
00569         {
00570           TreePtr<Static> no = MakeTreePtr<Static> ();
00571           o = no;
00572           no->constancy = constancy;
00573         }
00574           break;
00575         case clang::DeclSpec::SCS_static:
00576         {
00577           TreePtr<Static> no = MakeTreePtr<Static> ();
00578           o = no;
00579           no->constancy = constancy;
00580         }
00581           break;
00582         default:
00583           ASSERTFAIL("Unsupported storage class")
00584           ;
00585           break;
00586         }
00587       }
00588 
00589       all_decls->members.insert(o);
00590 
00591       clang::IdentifierInfo *ID = D.getIdentifier();
00592       if (ID)
00593       {
00594         o->identifier = CreateInstanceIdentifier(ID);
00595         ident_track.Add(ID, o, S);
00596       }
00597       else
00598       {
00599         o->identifier = CreateInstanceIdentifier();
00600       }
00601       o->type = CreateTypeNode(D);
00602       o->initialiser = MakeTreePtr<Uninitialised> ();
00603 
00604       return o;
00605     }
00606 
00607     TreePtr<Typedef> CreateTypedefNode(clang::Scope *S,
00608         clang::Declarator &D)
00609     {
00610       TreePtr<Typedef> t(new Typedef);
00611       all_decls->members.insert(t);
00612       clang::IdentifierInfo *ID = D.getIdentifier();
00613       if (ID)
00614       {
00615         t->identifier = CreateTypeIdentifier(ID);
00616         ident_track.Add(ID, t, S);
00617       }
00618       t->type = CreateTypeNode(D);
00619 
00620       TRACE("%s %p %p\n", ID->getName(), t.get(), ID);
00621       return t;
00622     }
00623     /*
00624      TreePtr<Label> CreateLabelNode( clang::IdentifierInfo *ID )
00625      {
00626      TreePtr<Label> l(new Label);
00627      all_decls->members.insert(l);
00628      l->access = MakeTreePtr<Public>();
00629      l->identifier = CreateLabelIdentifier(ID);
00630      TRACE("%s %p %p\n", ID->getName(), l.get(), ID );
00631      return l;
00632      }
00633      */
00634     TreePtr<Declaration> FindExistingDeclaration(
00635         const clang::CXXScopeSpec &SS, clang::IdentifierInfo *ID,
00636         bool recurse)
00637     {
00638       if (!ID)
00639         return TreePtr<Declaration> (); // No name specified => doesn't match anything
00640 
00641       // See if we already have this record in the current scope, or specified scope
00642       // if Declarator has one
00643       TreePtr<Node> cxxs = FromCXXScope(&SS);
00644 
00645       // Use C++ scope if non-NULL; do not recurse (=precise match only)
00646       TreePtr<Node> found_n = ident_track.TryGet(ID, cxxs, recurse);
00647       TRACE("Looked for %s, result %p (%p)\n", ID->getName(),
00648           found_n.get(), cxxs.get());
00649       if (!found_n)
00650       {
00651         // Nothing was found with the supplied name
00652         ASSERT( !cxxs ); // If C++ scope was given explicitly, require successful find
00653         return TreePtr<Declaration> ();
00654       }
00655 
00656       TreePtr<Declaration> found_d =
00657           dynamic_pointer_cast<Declaration> (found_n);
00658       // If the found match is not a declaration, cast will fail and we'll return NULL for "not found"
00659       return found_d;
00660     }
00661 
00662     // Alternative parameters
00663     TreePtr<Declaration> FindExistingDeclaration(clang::Declarator &D,
00664         bool recurse)
00665     {
00666       return FindExistingDeclaration(D.getCXXScopeSpec(),
00667           D.getIdentifier(), recurse);
00668     }
00669 
00670     TreePtr<Declaration> CreateDelcaration(clang::Scope *S,
00671         clang::Declarator &D, TreePtr<AccessSpec> a = TreePtr<
00672             AccessSpec> ())
00673     {
00674       const clang::DeclSpec &DS = D.getDeclSpec();
00675       TreePtr<Declaration> d;
00676       if (DS.getStorageClassSpec() == clang::DeclSpec::SCS_typedef)
00677       {
00678         TreePtr<Typedef> t = CreateTypedefNode(S, D);
00679         TRACE();
00680         d = t;
00681       }
00682       else
00683       {
00684         TreePtr<Instance> o = CreateInstanceNode(S, D, a);
00685         d = o;
00686       }
00687 
00688       return d;
00689     }
00690 
00691     // Does 1 thing:
00692     // 1. Inserts a stored decl if there is one in decl_to_insert
00693     void IssueDeclaration(clang::Scope *S, TreePtr<Declaration> d)
00694     {
00695         int os = inferno_scope_stack.top()->members.size();
00696       // Did we leave a record decl lying around to insert later? If so, pack it together with
00697       // the current instance decl, for insertion into the code sequence.
00698       TRACE("Issuing instance decl ")(*d)(" scope flags %x ", S->getFlags());
00699       if (decl_to_insert)
00700       {
00701         inferno_scope_stack.top()->members.insert(decl_to_insert);
00702         backing_ordering[inferno_scope_stack.top()].push_back(
00703             decl_to_insert);
00704         backing_paired_decl[d] = decl_to_insert;
00705         decl_to_insert = TreePtr<Declaration> (); // don't need to generate it again
00706         TRACE("inserted record decl\n");
00707       }
00708 
00709       TRACE("no insert record decl\n");
00710       inferno_scope_stack.top()->members.insert(d);
00711       backing_ordering[inferno_scope_stack.top()].push_back(d);
00712       TRACE("From %d to %d decls\n", os, inferno_scope_stack.top()->members.size() );
00713     }
00714 
00715     virtual DeclTy *ActOnDeclarator(clang::Scope *S, clang::Declarator &D,
00716         DeclTy *LastInGroup)
00717     {
00718         TRACE("Scope S%p\n", S);
00719       ident_track.SeenScope(S);
00720       // TODO the spurious char __builtin_va_list; line comes from the target info.
00721       // Create an inferno target info customised for Inferno that doesn't do this.
00722       if (strcmp(D.getIdentifier()->getName(), "__builtin_va_list") == 0)
00723       {
00724         return 0;
00725       }
00726 
00727       TreePtr<Declaration> d = FindExistingDeclaration(D, false); // decl exists already?
00728       if (!d)
00729       {
00730         d = CreateDelcaration(S, D); // make a new one
00731         IssueDeclaration(S, d);
00732       }
00733       
00734       // Clang refuses to store all the DeclTys we return in cases like int a, b, c;
00735       // instead it provides us with the last one we parsed (LastInGroup) and we are
00736       // expected to chain them. Use a local node for this and untangle in AddStatementToCompound. 
00737       TRACE("LIG=%x\n", LastInGroup);
00738       if( LastInGroup )
00739       {
00740           TRACE("Chaining declarations\n");
00741           MakeTreePtr<DeclarationChain> dc;
00742           dc->first = hold_decl.FromRaw(LastInGroup);
00743           dc->second = d;
00744           d = dc;
00745       }     
00746       
00747       return hold_decl.ToRaw( d );
00748     }
00749 
00750     /// ActOnParamDeclarator - This callback is invoked when a parameter
00751     /// declarator is parsed. This callback only occurs for functions
00752     /// with prototypes. S is the function prototype scope for the
00753     /// parameters (C++ [basic.scope.proto]).
00754     virtual DeclTy *ActOnParamDeclarator(clang::Scope *S,
00755         clang::Declarator &D)
00756     {
00757 
00758       TreePtr<Instance> p = CreateInstanceNode(S, D,
00759           MakeTreePtr<Public> (), true);
00760       backing_params[p] = D.getIdentifier(); // allow us to register the object with ident_track once we're in the function body scope
00761       return hold_decl.ToRaw(p);
00762     }
00763 
00764     virtual void AddInitializerToDecl(DeclTy *Dcl, ExprArg Init)
00765     {
00766         TRACE();
00767       TreePtr<Declaration> d = hold_decl.FromRaw(Dcl);
00768 
00769       TreePtr<Instance> o = dynamic_pointer_cast<Instance> (d);
00770       ASSERT( o ); // Only objects can be initialised
00771 
00772       o->initialiser = FromClang(Init);
00773 
00774       // At this point, when we have the instance (and hence the type) and the initialiser
00775       // we can detect when an array initialiser has been inserted for a record instance and
00776       // change it.
00777       if ( TreePtr<MakeArray> ai = dynamic_pointer_cast<MakeArray>(o->initialiser) )
00778         if ( TreePtr<TypeIdentifier> ti = dynamic_pointer_cast<TypeIdentifier>(o->type) )
00779           if ( TreePtr<Record> r = GetRecordDeclaration(all_decls, ti) )
00780             o->initialiser = CreateRecordLiteralFromArrayLiteral(
00781                 ai, r);
00782     }
00783 
00784         /// AddCXXDirectInitializerToDecl - This action is called immediately after 
00785         /// ActOnDeclarator, when a C++ direct initializer is present.
00786         /// e.g: "int x(1);"
00787         virtual void AddCXXDirectInitializerToDecl(DeclTy *Dcl,
00788                                                    clang::SourceLocation LParenLoc,
00789                                                    ExprTy **Exprs, unsigned NumExprs,
00790                                                    clang::SourceLocation *CommaLocs,
00791                                                    clang::SourceLocation RParenLoc) 
00792         {
00793         TRACE();
00794       TreePtr<Declaration> d = hold_decl.FromRaw(Dcl);
00795       TreePtr<Instance> o = dynamic_pointer_cast<Instance> (d);
00796             TRACE("Ignoring C++ direct initialiser for SC Modules, not supported in general\n"); // TODO try the code below...
00797        // TreePtr<Instance> cm = GetConstructor( d->type );
00798        // ASSERT( cm );
00799        // ASSERT( cm->identifier );
00800        // Sequence<Expression> args;
00801        // CollectArgs( &args, Exprs, NumExprs );
00802        // TreePtr<Call> c = CreateCall( args, cm->identifier );
00803         }
00804         
00805     // Clang tends to parse parameters and function bodies in seperate
00806     // scopes so when we see them being used we don't recognise them
00807     // and cannot link back to the correct Instance node. This function
00808     // puts all the params back in the current scope assuming:
00809     // 1. They have been added to the Function node correctly and
00810     // 2. They feature in the backing list for params
00811     void AddParamsToScope( TreePtr<CallableParams> pp,
00812                        clang::Scope *FnBodyScope)
00813     {
00814       ASSERT(pp);
00815 
00816       FOREACH(TreePtr<Declaration> param, pp->members )
00817 {     TRACE();
00818       clang::IdentifierInfo *paramII = backing_params[param];
00819       backing_params.erase( param );
00820       TRACE("%p %p %s S%p\n", param.get(), paramII, paramII->getName(), FnBodyScope);
00821       if( paramII )
00822       ident_track.Add( paramII, param, FnBodyScope );
00823     }
00824   }
00825 
00826   // JSG this is like the default in Actions, except it passes the parent of the function
00827   // body to ActOnDeclarator, since the function decl itself is not inside its own body.
00828   virtual DeclTy *ActOnStartOfFunctionDef(clang::Scope *FnBodyScope, clang::Declarator &D)
00829   {
00830       TRACE();
00831       // Declarator is outside function sope, otherwise it would be in its own scope and unfindable
00832       DeclTy *DT = ActOnDeclarator(FnBodyScope->getParent(), D, 0);
00833       // Now enter function's scope. Use node from existing declaration so we get any enclosing classes
00834       TreePtr<Node> n = FindExistingDeclaration(D, false);
00835       ident_track.PushScope( FnBodyScope->getParent(), n );
00836     // Default to ActOnDeclarator.
00837     return ActOnStartOfFunctionDef(FnBodyScope, DT);
00838   }
00839 
00840   virtual DeclTy *ActOnStartOfFunctionDef(clang::Scope *FnBodyScope, DeclTy *D)
00841   {
00842     TRACE("FnBodyScope S%p\n", FnBodyScope);
00843     TreePtr<Instance> o = dynamic_pointer_cast<Instance>(hold_decl.FromRaw(D));
00844     ASSERT(o);    
00845     
00846     // Note: this line was commented out as of mid August, but I'm sure I put it 
00847     // in recently, to fix a bug. Can't remember why it was commented out. Uncommented
00848     // to fix scopes being popped without being pushed.
00849     ident_track.SeenScope( FnBodyScope );
00850 
00851     if( TreePtr<CallableParams> pp = dynamic_pointer_cast<CallableParams>( o->type ) )
00852     AddParamsToScope( pp, FnBodyScope );
00853 
00854     // This is just a junk scope because we will not use scopes collected
00855     // via the inferno_scope_stack mechanism within functions; instead, they
00856     // will appear among the Statements managed by clang and passed into
00857     // ActOnFinishFunctionBody() as a hierarchy of Compounds.
00858     // If we tried to do this ourselves we'd lose the nested compound
00859     // statement hierarchy.
00860     inferno_scope_stack.push( TreePtr<Scope>(new Scope) );
00861  
00862     return hold_decl.ToRaw( o );
00863   }
00864 
00865   virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtArg Body)
00866   {
00867     TRACE();
00868     TreePtr<Instance> o( dynamic_pointer_cast<Instance>( hold_decl.FromRaw(Decl) ) );
00869     ASSERT(o);
00870     TreePtr<Compound> cb( dynamic_pointer_cast<Compound>( FromClang( Body ) ) );
00871     ASSERT(cb); // function body must be a scope or 0
00872 
00873     if( dynamic_pointer_cast<Uninitialised>( o->initialiser ) )
00874     o->initialiser = cb;
00875     else if( TreePtr<Compound> c = dynamic_pointer_cast<Compound>( o->initialiser ) )
00876     c->statements = c->statements + cb->statements;
00877     else
00878     ASSERTFAIL("wrong thing in function instance");
00879 
00880     TRACE("finish fn %d statements %d total\n", cb->statements.size(), (dynamic_pointer_cast<Compound>(o->initialiser))->statements.size() );
00881 
00882     inferno_scope_stack.pop(); // we dont use these - we use the clang-managed compound statement instead (passed in via Body)
00883         ident_track.PopScope(NULL);
00884     return Decl;
00885   }
00886 
00887   virtual OwningStmtResult ActOnExprStmt(ExprArg Expr)
00888   {
00889     // TODO most of this is now unnecessary
00890     if( TreePtr<Expression> e = dynamic_pointer_cast<Expression>( FromClang(Expr) ) )
00891     {
00892       return ToStmt( e );
00893     }
00894     else
00895     {
00896       // Operands that are not Expressions have no side effects and so
00897       // they do nothing as Statements
00898       TreePtr<Nop> n(new Nop);
00899       return ToStmt( n );
00900     }
00901   }
00902 
00903   virtual StmtResult ActOnReturnStmt( clang::SourceLocation ReturnLoc,
00904       ExprTy *RetValExp )
00905   {
00906     TreePtr<Return> r(new Return);
00907     if( RetValExp )
00908     r->return_value = hold_expr.FromRaw(RetValExp);
00909     else
00910     r->return_value = MakeTreePtr<Uninitialised>();
00911     TRACE("aors %p\n", r.get() );
00912     return hold_stmt.ToRaw( r );
00913   }
00914 
00915   virtual ExprResult ActOnIdentifierExpr( clang::Scope *S,
00916       clang::SourceLocation Loc,
00917       clang::IdentifierInfo &II,
00918       bool HasTrailingLParen,
00919       const clang::CXXScopeSpec *SS = 0 )
00920   {
00921       TRACE("S%p\n", S);
00922     TreePtr<Node> n = ident_track.Get( &II, FromCXXScope( SS ) );
00923     TRACE("aoie %s %s\n", II.getName(), typeid(*n).name() );
00924     TreePtr<Instance> o = dynamic_pointer_cast<Instance>( n );
00925     ASSERT( o );
00926     return hold_expr.ToRaw( o->identifier );
00927   }
00928 
00929   TreePtr<Integer> CreateNumericConstant( int value )
00930   {
00931     TreePtr<SpecificInteger> nc( new SpecificInteger(value) );
00932     return nc;
00933   }
00934 
00935   TreePtr<Literal> CreateLiteral( int value )
00936   {
00937     return CreateNumericConstant( value );
00938   }
00939 
00940   TreePtr<Number> CreateNumericConstant(const clang::Token &tok)
00941   {
00942     llvm::SmallString<512> int_buffer;
00943     int_buffer.resize(tok.getLength());
00944     const char *this_tok_begin = &int_buffer[0];
00945 
00946     // Get the spelling of the token, which eliminates trigraphs, etc.
00947     unsigned actual_length = preprocessor.getSpelling(tok, this_tok_begin);
00948     clang::NumericLiteralParser literal(this_tok_begin, this_tok_begin+actual_length,
00949         tok.getLocation(), preprocessor);
00950     ASSERT(!literal.hadError);
00951 
00952     if (literal.isIntegerLiteral())
00953     {
00954       int bits;
00955       if( literal.isLong )
00956       bits = TypeDb::integral_bits[clang::DeclSpec::TSW_long];
00957       else if( literal.isLongLong )
00958       bits = TypeDb::integral_bits[clang::DeclSpec::TSW_longlong];
00959       else
00960       bits = TypeDb::integral_bits[clang::DeclSpec::TSW_unspecified];
00961 
00962       llvm::APSInt rv(bits, literal.isUnsigned);
00963       bool err = literal.GetIntegerValue(rv);
00964 
00965       ASSERT( !err )( "numeric literal too big for its own type" );
00966       TreePtr<SpecificInteger> nc( new SpecificInteger(rv) );
00967       return nc;
00968     }
00969     else if( literal.isFloatingLiteral() )
00970     {
00971       const llvm::fltSemantics *semantics;
00972       if( literal.isLong )
00973       semantics = TypeDb::long_double_semantics;
00974       else if( literal.isFloat )
00975       semantics = TypeDb::float_semantics;
00976       else
00977       semantics = TypeDb::double_semantics;
00978       llvm::APFloat rv( literal.GetFloatValue( *semantics ) );
00979 
00980       TreePtr<SpecificFloat> fc( new SpecificFloat( rv ) );
00981       return fc;
00982     }
00983     ASSERTFAIL("this sort of literal is not supported");
00984   }
00985 
00986   virtual ExprResult ActOnNumericConstant(const clang::Token &tok)
00987   {
00988     return hold_expr.ToRaw( CreateNumericConstant( tok ) );
00989   }
00990 
00991   virtual ExprResult ActOnBinOp(clang::Scope *S,
00992       clang::SourceLocation TokLoc, clang::tok::TokenKind Kind,
00993       ExprTy *LHS, ExprTy *RHS)
00994   {
00995     TRACE();
00996     TreePtr<Operator> o = TreePtr<Operator>();
00997     switch( Kind )
00998     {
00999 #define INFIX(TOK, TEXT, NODE, BASE, CAT) \
01000           case clang::tok::TOK: \
01001                 o=TreePtr<NODE>(new NODE);\
01002                 break;
01003 #include "tree/operator_db.inc"
01004     }
01005     ASSERT( o );
01006     if( TreePtr<NonCommutativeOperator> nco = dynamic_pointer_cast< NonCommutativeOperator >(o) )
01007     {
01008       nco->operands.push_back( hold_expr.FromRaw(LHS) );
01009       nco->operands.push_back( hold_expr.FromRaw(RHS) );
01010     }
01011     else if( TreePtr<CommutativeOperator> co = dynamic_pointer_cast< CommutativeOperator >(o) )
01012     {
01013       co->operands.insert( hold_expr.FromRaw(LHS) );
01014       co->operands.insert( hold_expr.FromRaw(RHS) );
01015     }
01016     else
01017     ASSERTFAIL("Binop was apparently neither Commutative nor NonCommutative");
01018 
01019     return hold_expr.ToRaw( o );
01020   }
01021 
01022   virtual ExprResult ActOnPostfixUnaryOp(clang::Scope *S, clang::SourceLocation OpLoc,
01023       clang::tok::TokenKind Kind, ExprTy *Input)
01024   {
01025     TreePtr<NonCommutativeOperator> o = TreePtr<NonCommutativeOperator>();
01026 
01027     switch( Kind )
01028     {
01029 #define POSTFIX(TOK, TEXT, NODE, BASE, CAT) \
01030           case clang::tok::TOK: \
01031               o=TreePtr<NODE>(new NODE); \
01032               break;
01033 #include "tree/operator_db.inc"
01034     }
01035     ASSERT( o );
01036     o->operands.push_back( hold_expr.FromRaw(Input) );
01037     return hold_expr.ToRaw( o );
01038   }
01039 
01040   virtual ExprResult ActOnUnaryOp( clang::Scope *S, clang::SourceLocation OpLoc,
01041       clang::tok::TokenKind Kind, ExprTy *Input)
01042   {
01043     TreePtr<NonCommutativeOperator> o = TreePtr<NonCommutativeOperator>();
01044 
01045     switch( Kind )
01046     {
01047 #define PREFIX(TOK, TEXT, NODE, BASE, CAT) \
01048           case clang::tok::TOK:\
01049                 o=TreePtr<NODE>(new NODE); \
01050                 break;
01051 #include "tree/operator_db.inc"
01052     }
01053     ASSERT( o );
01054     o->operands.push_back( hold_expr.FromRaw(Input) );
01055     return hold_expr.ToRaw( o );
01056   }
01057 
01058   virtual ExprResult ActOnConditionalOp(clang::SourceLocation QuestionLoc,
01059       clang::SourceLocation ColonLoc,
01060       ExprTy *Cond, ExprTy *LHS, ExprTy *RHS)
01061   {
01062     TreePtr<Multiplexor> co(new Multiplexor);
01063     co->operands.push_back( hold_expr.FromRaw(Cond) );
01064     ASSERT(LHS )( "gnu extension not supported");
01065     co->operands.push_back( hold_expr.FromRaw(LHS) );
01066     co->operands.push_back( hold_expr.FromRaw(RHS) );
01067     return hold_expr.ToRaw( co );
01068   }
01069 
01070   TreePtr<Call> CreateCall( Sequence<Expression> &args, TreePtr<Expression> callee )
01071   {
01072     // Make the Call node and fill in the called function
01073     TreePtr<Call> c(new Call);
01074     c->callee = callee;
01075 
01076     // If CallableParams, fill in the args map based on the supplied args and original function type
01077     TreePtr<Node> t = TypeOf::instance(all_decls, callee);
01078     if( TreePtr<CallableParams> p = dynamic_pointer_cast<CallableParams>(t) )
01079         PopulateMapOperator( c, args, p );
01080 
01081     return c;
01082   }
01083 
01084   virtual ExprResult ActOnCallExpr(clang::Scope *S, ExprTy *Fn, clang::SourceLocation LParenLoc,
01085       ExprTy **Args, unsigned NumArgs,
01086       clang::SourceLocation *CommaLocs,
01087       clang::SourceLocation RParenLoc)
01088   {
01089     // Get the args in a Sequence
01090     Sequence<Expression> args;
01091     CollectArgs( &args, Args, NumArgs );
01092     TreePtr<Call> c = CreateCall( args, hold_expr.FromRaw(Fn) );
01093     return hold_expr.ToRaw( c );
01094   }
01095 
01096   // Not sure if this one has been tested!!
01097   virtual TypeResult ActOnTypeName(clang::Scope *S, clang::Declarator &D)
01098   {
01099     TreePtr<Type> t = CreateTypeNode( D );
01100     return hold_type.ToRaw( t );
01101   }
01102 
01103   void AddDeclarationToCompound( TreePtr<Compound> s, TreePtr<Declaration> d )
01104   {
01105     if( TreePtr<DeclarationChain> dc = dynamic_pointer_cast<DeclarationChain>( d ) )
01106     {
01107         TRACE("Walking declaration chain\n");
01108         AddDeclarationToCompound( s, dc->first );
01109         AddDeclarationToCompound( s, dc->second );
01110         return;
01111     }
01112      
01113     if( TreePtr<Instance> i = dynamic_pointer_cast<Instance>(d) )
01114         AddStatementToCompound( s, i ); // Instances can have inits that require being in order, so append as a statement
01115     else
01116         s->members.insert( d );
01117   }
01118   
01119   void AddStatementToCompound( TreePtr<Compound> s, TreePtr<Statement> st )
01120   {
01121     /* if( TreePtr<ParseTwin> pt = dynamic_pointer_cast<ParseTwin>( st ) )
01122      {
01123      AddStatementToCompound( s, pt->d1 );
01124      AddStatementToCompound( s, pt->d2 );
01125      return;
01126      }
01127      */
01128     if( TreePtr<Declaration> d = dynamic_pointer_cast<Declaration>( st ) )
01129     {
01130       if( backing_paired_decl.IsExist(d) )
01131       {
01132         TreePtr<Declaration> bd = backing_paired_decl[d];
01133         ASSERT( bd );
01134                 AddDeclarationToCompound( s, bd );
01135         backing_paired_decl.erase(d);
01136       }
01137     }
01138 
01139     if( TreePtr<DeclarationAsStatement> das = dynamic_pointer_cast<DeclarationAsStatement>(st) )
01140         AddDeclarationToCompound( s, das->d );
01141     else
01142         s->statements.push_back( st );
01143 
01144     // FlattenNode the "sub" statements of labels etc
01145     if( TreePtr<Label> l = dynamic_pointer_cast<Label>( st ) )
01146     {
01147       ASSERT( backing_labels[l] );
01148       AddStatementToCompound( s, backing_labels[l] );
01149       backing_labels.erase(l);
01150     }
01151     else if( TreePtr<SwitchTarget> t = dynamic_pointer_cast<SwitchTarget>( st ) )
01152     {
01153       ASSERT( backing_targets[t] );
01154       AddStatementToCompound( s, backing_targets[t] );
01155       backing_targets.erase(t);
01156     }
01157   }
01158 
01159   virtual OwningStmtResult ActOnCompoundStmt(clang::SourceLocation L, clang::SourceLocation R,
01160       MultiStmtArg Elts,
01161       bool isStmtExpr)
01162   {
01163     // TODO helper fn for MultiStmtArg, like FromClang. Maybe.
01164     TreePtr<Compound> s(new Compound);
01165 
01166     for( int i=0; i<Elts.size(); i++ )
01167     AddStatementToCompound( s, hold_stmt.FromRaw( Elts.get()[i] ) );
01168 
01169     return ToStmt( s );
01170   }
01171 
01172   virtual OwningStmtResult ActOnDeclStmt(DeclTy *Decl, clang::SourceLocation StartLoc,
01173       clang::SourceLocation EndLoc)
01174   {
01175     TreePtr<Declaration> d( hold_decl.FromRaw(Decl) );
01176     // Basically we are being asked to turn a Declaration, which has already been parsed,
01177     // into a Statement. Instances are already both Declarations and Statements, so that's
01178     // OK. In other cases, we have to package up the Declaration in a special kind of
01179     // Statement node and pass it through that way. We will unpack later.
01180     if( TreePtr<Instance> i = dynamic_pointer_cast<Instance>(d) )
01181     {
01182       return ToStmt( i );
01183     }
01184     else
01185     {
01186       TreePtr<DeclarationAsStatement> das( new DeclarationAsStatement );
01187       das->d = d;
01188       return ToStmt( das );
01189     }
01190   }
01191 
01192   // Create a label identifier if there isn't already one with the same name (TODO scopes?)
01193   TreePtr<LabelIdentifier> MaybeCreateLabelIdentifier( clang::IdentifierInfo *II )
01194   {
01195     if( !(II->getFETokenInfo<void *>()) )
01196     II->setFETokenInfo( hold_label_identifier.ToRaw( CreateLabelIdentifier( II ) ) );
01197 
01198     return hold_label_identifier.FromRaw( II->getFETokenInfo<void *>() );
01199   }
01200 
01201   virtual StmtResult ActOnLabelStmt(clang::SourceLocation IdentLoc, clang::IdentifierInfo *II,
01202       clang::SourceLocation ColonLoc, StmtTy *SubStmt)
01203   {
01204     TreePtr<Label> l( new Label );
01205     l->identifier = MaybeCreateLabelIdentifier(II);
01206     backing_labels[l] = hold_stmt.FromRaw( SubStmt );
01207     return hold_stmt.ToRaw( l );
01208   }
01209 
01210   virtual StmtResult ActOnGotoStmt(clang::SourceLocation GotoLoc,
01211       clang::SourceLocation LabelLoc,
01212       clang::IdentifierInfo *LabelII)
01213   {
01214     TreePtr<Goto> g( new Goto );
01215     g->destination = MaybeCreateLabelIdentifier(LabelII);
01216     return hold_stmt.ToRaw( g );
01217   }
01218 
01219   virtual StmtResult ActOnIndirectGotoStmt(clang::SourceLocation GotoLoc,
01220       clang::SourceLocation StarLoc,
01221       ExprTy *DestExp)
01222   {
01223     TreePtr<Goto> g( new Goto );
01224     g->destination = hold_expr.FromRaw( DestExp );
01225     return hold_stmt.ToRaw( g );
01226   }
01227 
01228   virtual ExprResult ActOnAddrLabel(clang::SourceLocation OpLoc, clang::SourceLocation LabLoc,
01229       clang::IdentifierInfo *LabelII) // "&&foo"
01230 
01231   {
01232     // TODO doesn't && meaning label-as-variable conflict with C++0x right-reference thingy?
01233     return hold_expr.ToRaw( MaybeCreateLabelIdentifier(LabelII) );
01234   }
01235 
01236   virtual StmtResult ActOnIfStmt(clang::SourceLocation IfLoc, ExprTy *CondVal,
01237       StmtTy *ThenVal, clang::SourceLocation ElseLoc,
01238       StmtTy *ElseVal)
01239   {
01240     TreePtr<If> i( new If );
01241     i->condition = hold_expr.FromRaw( CondVal );
01242     i->body = hold_stmt.FromRaw( ThenVal );
01243     if( ElseVal )
01244     i->else_body = hold_stmt.FromRaw( ElseVal );
01245     else
01246     i->else_body = MakeTreePtr<Nop>(); // empty else clause
01247     return hold_stmt.ToRaw( i );
01248   }
01249 
01250   virtual StmtResult ActOnWhileStmt(clang::SourceLocation WhileLoc, ExprTy *Cond,
01251       StmtTy *Body)
01252   {
01253     TreePtr<While> w( new While );
01254     w->condition = hold_expr.FromRaw( Cond );
01255     w->body = hold_stmt.FromRaw( Body );
01256     return hold_stmt.ToRaw( w );
01257   }
01258 
01259   virtual StmtResult ActOnDoStmt(clang::SourceLocation DoLoc, StmtTy *Body,
01260       clang::SourceLocation WhileLoc, ExprTy *Cond)
01261   {
01262     TreePtr<Do> d( new Do );
01263     d->body = hold_stmt.FromRaw( Body );
01264     d->condition = hold_expr.FromRaw( Cond );
01265     return hold_stmt.ToRaw( d );
01266   }
01267 
01268   virtual StmtResult ActOnForStmt(clang::SourceLocation ForLoc,
01269       clang::SourceLocation LParenLoc,
01270       StmtTy *First, ExprTy *Second, ExprTy *Third,
01271       clang::SourceLocation RParenLoc, StmtTy *Body)
01272   {
01273     TreePtr<For> f( new For );
01274     if( First )
01275     f->initialisation = hold_stmt.FromRaw( First );
01276     else
01277     f->initialisation = MakeTreePtr<Nop>();
01278 
01279     if( Second )
01280     f->condition = hold_expr.FromRaw( Second );
01281     else
01282     f->condition = MakeTreePtr<True>();
01283 
01284     StmtTy *third = (StmtTy *)Third; // Third is really a statement, the Actions API is wrong
01285     if( third )
01286     f->increment = hold_stmt.FromRaw( third );
01287     else
01288     f->increment = MakeTreePtr<Nop>();
01289 
01290     f->body = hold_stmt.FromRaw( Body );
01291     return hold_stmt.ToRaw( f );
01292   }
01293 
01294   virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond)
01295   {
01296     TreePtr<Switch> s( new Switch );
01297     s->condition = hold_expr.FromRaw( Cond );
01298     return hold_stmt.ToRaw( s );
01299   }
01300 
01301   virtual StmtResult ActOnFinishSwitchStmt(clang::SourceLocation SwitchLoc,
01302       StmtTy *rsw, ExprTy *Body)
01303   {
01304     TreePtr<Statement> s( hold_stmt.FromRaw( rsw ) );
01305     TreePtr<Switch> sw( dynamic_pointer_cast<Switch>(s) );
01306     ASSERT(sw)("expecting a switch statement");
01307 
01308     StmtTy *body = (StmtTy *)Body; // Third is really a statement, the Actions API is wrong
01309     sw->body = hold_stmt.FromRaw( body );
01310     return hold_stmt.ToRaw( s );
01311   }
01312 
01313   /// ActOnCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
01314   /// which can specify an RHS value.
01315   virtual OwningStmtResult ActOnCaseStmt(clang::SourceLocation CaseLoc, ExprArg LHSVal,
01316       clang::SourceLocation DotDotDotLoc, ExprArg RHSVal,
01317       clang::SourceLocation ColonLoc, StmtArg SubStmt)
01318   {
01319     TRACE();
01320 
01321     if( RHSVal.get() )
01322     {
01323       TreePtr<RangeCase> rc( new RangeCase );
01324       rc->value_lo = FromClang( LHSVal );
01325       rc->value_hi = FromClang( RHSVal );
01326       backing_targets[rc] = FromClang( SubStmt );
01327       return ToStmt( rc );
01328     }
01329     else
01330     {
01331       TreePtr<Case> c( new Case );
01332       c->value = FromClang( LHSVal );
01333       backing_targets[c] = FromClang( SubStmt );
01334       return ToStmt( c );
01335     }
01336   }
01337 
01338   virtual OwningStmtResult ActOnDefaultStmt(clang::SourceLocation DefaultLoc,
01339       clang::SourceLocation ColonLoc, StmtArg SubStmt,
01340       clang::Scope *CurScope)
01341   {
01342     TRACE();
01343     TreePtr<Default> d( new Default );
01344     backing_targets[d] = FromClang( SubStmt );
01345     return ToStmt( d );
01346   }
01347 
01348   virtual StmtResult ActOnContinueStmt(clang::SourceLocation ContinueLoc,
01349       clang::Scope *CurScope)
01350   {
01351     return hold_stmt.ToRaw( TreePtr<Continue>( new Continue ) );
01352   }
01353 
01354   virtual StmtResult ActOnBreakStmt(clang::SourceLocation GotoLoc, clang::Scope *CurScope)
01355   {
01356     return hold_stmt.ToRaw( TreePtr<Break>( new Break ) );
01357   }
01358 
01359   TreePtr<AccessSpec> ConvertAccess( clang::AccessSpecifier AS, TreePtr<Record> rec = TreePtr<Record>() )
01360   {
01361     switch( AS )
01362     {
01363       case clang::AS_public:
01364       return TreePtr<Public>(new Public);
01365       break;
01366       case clang::AS_protected:
01367       return TreePtr<Protected>(new Protected);
01368       break;
01369       case clang::AS_private:
01370       return TreePtr<Private>(new Private);
01371       break;
01372       case clang::AS_none:
01373       ASSERT( rec )( "no access specifier and record not supplied so cannot deduce");
01374       // members are never AS_none because clang deals. Bases can be AS_none, so we supply the enclosing record type
01375       if( dynamic_pointer_cast<Class>(rec) )
01376       return TreePtr<Private>(new Private);
01377       else
01378       return TreePtr<Public>(new Public);
01379       break;
01380       default:
01381       ASSERTFAIL("Invalid access specfier");
01382       return TreePtr<Public>(new Public);
01383       break;
01384     }
01385   }
01386 
01387   virtual DeclTy *ActOnCXXMemberDeclarator(clang::Scope *S, clang::AccessSpecifier AS,
01388       clang::Declarator &D, ExprTy *BitfieldWidth,
01389       ExprTy *Init, DeclTy *LastInGroup)
01390   {
01391     const clang::DeclSpec &DS = D.getDeclSpec();
01392     TRACE("Element %p\n", Init);
01393     TreePtr<Declaration> d = CreateDelcaration( S, D, ConvertAccess( AS ) );
01394     TreePtr<Instance> o = dynamic_pointer_cast<Instance>(d);
01395 
01396     if( BitfieldWidth )
01397     {
01398       ASSERT( o )( "only Instances may be bitfields" );
01399       TreePtr<Integral> n( dynamic_pointer_cast<Integral>( o->type ) );
01400       ASSERT( n )( "cannot specify width of non-numeric type" );
01401       TreePtr<Expression> ee = hold_expr.FromRaw(BitfieldWidth);
01402       TreePtr<Literal> ll = dynamic_pointer_cast<Literal>(ee);
01403       ASSERT(ll )( "bitfield width must be literal, not expression"); // TODO evaluate
01404       TreePtr<SpecificInteger> ii = dynamic_pointer_cast<SpecificInteger>(ll);
01405       ASSERT(ll )( "bitfield width must be integer");
01406       n->width = ii;
01407     }
01408 
01409     if( Init )
01410     {
01411       ASSERT( o )( "only Instances may have initialisers");
01412       o->initialiser = hold_expr.FromRaw( Init );
01413     }
01414     
01415         IssueDeclaration( S, d );
01416     return hold_decl.ToRaw( d );
01417   }
01418 
01419   virtual DeclTy *ActOnTag(clang::Scope *S, unsigned TagType, TagKind TK,
01420       clang::SourceLocation KWLoc, const clang::CXXScopeSpec &SS,
01421       clang::IdentifierInfo *Name, clang::SourceLocation NameLoc,
01422       clang::AttributeList *Attr,
01423       MultiTemplateParamsArg TemplateParameterLists)
01424   {
01425     //ASSERT( !FromCXXScope(&SS) && "We're not doing anything with the C++ scope"); // TODO do something with the C++ scope
01426     // Now we're using it to link up with forward decls eg class foo { struct s; }; struct foo::s { blah } TODO is this even legal C++?
01427         
01428     TRACE("Tag type %d, kind %d\n", TagType, (int)TK);
01429     ident_track.SeenScope( S );
01430 
01431     // TagType is an instance of DeclSpec::TST, indicating what kind of tag this
01432     // is (struct/union/enum/class).
01433 
01434     // Proceed based on the context around the tag
01435     if( TK == clang::Action::TK_Reference )
01436     {
01437       // Tag is a reference, that is a usage rather than a definition. We therefore
01438       // expect to be able to find a previous definition/declaration for it. Recurse
01439       // the search through enclosing scopes until we find it.
01440       TreePtr<Declaration> ed = FindExistingDeclaration( SS, Name, true );
01441       ASSERT(ed)("Cannot find declaration of \"%s\"", Name->getName());
01442 
01443       return hold_decl.ToRaw( ed );
01444     }
01445 
01446     // Tag is a definition or declaration. Create if it doesn't already
01447     // exist, *but* don't recurse into enclosing scopes.
01448     if( TreePtr<Declaration> ed = FindExistingDeclaration( SS, Name, false ) )
01449     {
01450       // Note: members will be filled in later, so nothing to do here
01451       // even if the is the "complete" version of the record (=definition).
01452       return hold_decl.ToRaw( ed );
01453     }
01454 
01455     TreePtr<Record> h;
01456     switch( (clang::DeclSpec::TST)TagType )
01457     {
01458       case clang::DeclSpec::TST_union:
01459       h = TreePtr<Union>(new Union);
01460       break;
01461       case clang::DeclSpec::TST_struct:
01462       h = TreePtr<Struct>(new Struct);
01463       break;
01464       case clang::DeclSpec::TST_class:
01465       h = TreePtr<Class>(new Class);
01466       break;
01467       case clang::DeclSpec::TST_enum:
01468       h = TreePtr<Enum>(new Enum);
01469       break;
01470       default:
01471       ASSERTFAIL("Unknown type spec type");
01472       break;
01473     }
01474     all_decls->members.insert(h);
01475 
01476     if(Name)
01477     {
01478       h->identifier = CreateTypeIdentifier(Name);
01479       ident_track.Add(Name, h, S);
01480     }
01481     else
01482     {
01483       // TODO make a general-lurpose anon name generator
01484       char an[20];
01485       static int ac=0;
01486       sprintf( an, "__anon%d", ac++ );
01487       h->identifier = CreateTypeIdentifier(an);
01488       ident_track.Add(NULL, h, S);
01489     }
01490 
01491     //TODO should we do something with TagKind? Maybe needed for render.
01492     //TODO use the attibutes
01493 
01494     // struct/class/union pushed by ActOnFinishCXXClassDef()
01495     if( (clang::DeclSpec::TST)TagType == clang::DeclSpec::TST_enum )
01496     decl_to_insert = h;
01497 
01498     TRACE("done tag %p\n", h.get());
01499 
01500     return hold_decl.ToRaw( h );
01501   }
01502 
01503   /// ActOnStartCXXClassDef - This is called at the start of a class/struct/union
01504   /// definition, when on C++.
01505   virtual void ActOnStartCXXClassDef(clang::Scope *S, DeclTy *TagDecl,
01506       clang::SourceLocation LBrace)
01507   {
01508     TRACE("S%p\n", S);
01509 
01510     // Just populate the members container for the Record node
01511     // we already created. No need to return anything.
01512     TreePtr<Declaration> d = hold_decl.FromRaw( TagDecl );
01513     TreePtr<Record> h = dynamic_pointer_cast<Record>(d);
01514 
01515     // We're about to populate the Record; if it has been populated already
01516     // then something's wrong
01517     ASSERT( h->members.empty() )("Record has already been defined");
01518 
01519     ident_track.SetNextRecord( h );
01520 
01521     inferno_scope_stack.push( h ); // decls for members will go on this scope
01522     backing_ordering[inferno_scope_stack.top()].clear();
01523   }
01524 
01525   /// ActOnFinishCXXClassDef - This is called when a class/struct/union has
01526   /// completed parsing, when on C++.
01527   virtual void ActOnFinishCXXClassDef(DeclTy *TagDecl)
01528   {
01529     TRACE();
01530 
01531     inferno_scope_stack.pop(); // class scope is complete
01532     ident_track.SetNextRecord();
01533 
01534     // TODO are structs etc definable in functions? If so, this will put the decl outside the function
01535     TreePtr<Declaration> d = hold_decl.FromRaw( TagDecl );
01536     TreePtr<Record> h = dynamic_pointer_cast<Record>(d);
01537     decl_to_insert = h;
01538   }
01539 
01540   virtual ExprResult ActOnMemberReferenceExpr(clang::Scope *S, ExprTy *Base,
01541       clang::SourceLocation OpLoc,
01542       clang::tok::TokenKind OpKind,
01543       clang::SourceLocation MemberLoc,
01544       clang::IdentifierInfo &Member)
01545   {
01546     TRACE("kind %d\n", OpKind);
01547     TreePtr<Lookup> a( new Lookup );
01548 
01549     // Turn -> into * and .
01550     if( OpKind == clang::tok::arrow ) // Base->Member
01551 
01552     {
01553       TreePtr<Dereference> ou( new Dereference );
01554       ou->operands.push_back( hold_expr.FromRaw( Base ) );
01555       a->base = ou;
01556     }
01557     else if( OpKind == clang::tok::period ) // Base.Member
01558 
01559     {
01560       a->base = hold_expr.FromRaw( Base );
01561     }
01562     else
01563     {
01564       ASSERTFAIL("Unknown token accessing member");
01565     }
01566 
01567     // Find the specified member in the record implied by the expression on the left of .
01568     TreePtr<Node> tbase = TypeOf::instance( all_decls, a->base );
01569     TreePtr<TypeIdentifier> tibase = dynamic_pointer_cast<TypeIdentifier>(tbase);
01570     ASSERT( tibase );
01571     TreePtr<Record> rbase = GetRecordDeclaration(all_decls, tibase);
01572     ASSERT( rbase )( "thing on left of ./-> is not a record/record ptr" );
01573     TreePtr<Instance> m = FindMemberByName( all_decls, rbase, string(Member.getName()) );
01574     ASSERT(m)("in r.m or (&r)->m, could not find m in r\n"
01575               "m is %s, r is ", 
01576               Member.getName())
01577               (*rbase)
01578               (" named ")
01579               (*tibase);
01580 
01581     a->member = m->identifier;
01582 
01583     return hold_expr.ToRaw( a );
01584   }
01585 
01586   virtual ExprResult ActOnArraySubscriptExpr(clang::Scope *S,
01587       ExprTy *Base, clang::SourceLocation LLoc,
01588       ExprTy *Idx, clang::SourceLocation RLoc)
01589   {
01590     TreePtr<Subscript> su( new Subscript );
01591     su->operands.push_back( hold_expr.FromRaw( Base ) );
01592     su->operands.push_back( hold_expr.FromRaw( Idx ) );
01593     return hold_expr.ToRaw( su );
01594   }
01595 
01596   /// ActOnCXXBoolLiteral - Parse {true,false} literals.
01597   virtual ExprResult ActOnCXXBoolLiteral(clang::SourceLocation OpLoc,
01598       clang::tok::TokenKind Kind) //TODO not working - get node has no info
01599 
01600   {
01601     TreePtr<Literal> ic;
01602     TRACE("true/false tk %d %d %d\n", Kind, clang::tok::kw_true, clang::tok::kw_false );
01603 
01604     if(Kind == clang::tok::kw_true)
01605     ic = MakeTreePtr<True>();
01606     else
01607     ic = MakeTreePtr<False>();
01608     return hold_expr.ToRaw( ic );
01609   }
01610 
01611   virtual ExprResult ActOnCastExpr(clang::SourceLocation LParenLoc, TypeTy *Ty,
01612       clang::SourceLocation RParenLoc, ExprTy *Op)
01613   {
01614     TreePtr<Cast> c(new Cast);
01615     c->operand = hold_expr.FromRaw( Op );
01616     c->type = hold_type.FromRaw( Ty );
01617     return hold_expr.ToRaw( c );
01618   }
01619 
01620   virtual OwningStmtResult ActOnNullStmt(clang::SourceLocation SemiLoc)
01621   {
01622     TRACE();
01623     TreePtr<Nop> n(new Nop);
01624     return ToStmt( n );
01625   }
01626 
01627   virtual ExprResult ActOnCharacterConstant(const clang::Token &tok)
01628   {
01629     string t = preprocessor.getSpelling(tok);
01630 
01631     clang::CharLiteralParser literal(t.c_str(), t.c_str()+t.size(), tok.getLocation(), preprocessor);
01632 
01633     if (literal.hadError())
01634     return ExprResult(true);
01635 
01636     llvm::APSInt rv(TypeDb::char_bits, !TypeDb::char_default_signed);
01637     rv = literal.getValue();
01638     TreePtr<SpecificInteger> nc( new SpecificInteger(rv) );
01639 
01640     return hold_expr.ToRaw( nc );
01641   }
01642 
01643   virtual ExprResult ActOnInitList(clang::SourceLocation LParenLoc,
01644       ExprTy **InitList, unsigned NumInit,
01645       clang::InitListDesignations &Designators,
01646       clang::SourceLocation RParenLoc)
01647   {
01648     ASSERT( !Designators.hasAnyDesignators() )( "Designators in init lists unsupported" );
01649     // Assume initialiser is for an Array, and create an ArrayInitialiser node
01650     // even if it's really a struct init. We'll come along later and replace with a
01651     // RecordInitialiser when we can see what the struct is.
01652     TreePtr<MakeArray> ao(new MakeArray);
01653     for(int i=0; i<NumInit; i++)
01654     {
01655       TreePtr<Expression> e = hold_expr.FromRaw( InitList[i] );
01656       ao->operands.push_back( e );
01657     }
01658     return hold_expr.ToRaw( ao );
01659   }
01660 
01661   // Create a RecordInitialiser using the elements of the supplied ArrayInitialiser and matching
01662   // them against the members of the supplied record. Records are stored using an unordered
01663   // collection for the members, so we have to use the ordered backing map. Array inits are ordered.
01664   TreePtr<MakeRecord> CreateRecordLiteralFromArrayLiteral( TreePtr<MakeArray> ai,
01665       TreePtr<Record> r )
01666   {
01667     // Make new record initialiser and fill in the type
01668     TreePtr<MakeRecord> ri( new MakeRecord );
01669     ri->type = r->identifier;
01670 
01671     // Fill in the RecordLiteral operands collection with pairs that relate operands to their member ids
01672     TreePtr<Scope> s = r;
01673     PopulateMapOperator( ri, ai->operands, s );
01674 
01675     return ri;
01676   }
01677 
01678   // Populate a map operator using elements from a sequence of expressions
01679   void PopulateMapOperator( TreePtr<MapOperator> mapop, // MapOperands corresponding to the elements of ai go in here
01680       Sequence<Expression> &seq, // Operands to insert, ordered as per the input program
01681       TreePtr<Scope> scope ) // Original Scope that established ordering, must be in backing_ordering
01682 
01683   {
01684     // Get a reference to the ordered list of members for this scope from a backing list
01685     ASSERT( backing_ordering.IsExist(scope) )("Supplied scope did not make it into the backing ordering list");
01686     Sequence<Declaration> &scope_ordered = backing_ordering[scope];
01687     TRACE("%p %p\n", &scope->members, scope.get());
01688 
01689     // Go over the entire scope, keeping track of where we are in the Sequence
01690     int seq_index=0; // TODO rename
01691     FOREACH( TreePtr<Declaration> d, scope_ordered )
01692     {
01693       if( seq_index == seq.size() )
01694       {
01695           TRACE("Early out due to fewer elements in sequence than scope\n"); 
01696           break;
01697       }
01698       // We only care about instances...
01699       if( TreePtr<Instance> i = dynamic_pointer_cast<Instance>( d ) )
01700       {
01701         // ...and not function instances
01702         if( !dynamic_pointer_cast<Callable>( i->type ) )
01703         {
01704           // Get value out of array init and put it in record init together with member instance id
01705           TreePtr<Expression> v = seq[seq_index];
01706           TreePtr<MapOperand> mi( new MapOperand );
01707           mi->identifier = i->identifier;
01708           mi->value = v;
01709           mapop->operands.insert( mi );
01710 
01711           seq_index++;
01712         }
01713       }
01714     }   
01715     ASSERT( seq_index == seq.size() )
01716           ("Too many arguments to function/struct init (we allow too few for poor mans overlading, but not too many)\n")
01717           ("Scope was ")(*scope)(" for map operator ")(mapop)("\n");
01718   }
01719 
01720   TreePtr<String> CreateString( const char *s )
01721   {
01722     TreePtr<SpecificString> st( new SpecificString(s) );
01723     return st;
01724   }
01725 
01726   TreePtr<String> CreateString( clang::IdentifierInfo *Id )
01727   {
01728     return CreateString( Id->getName() );
01729   }
01730 
01731   /// ActOnStringLiteral - The specified tokens were lexed as pasted string
01732   /// fragments (e.g. "foo" "bar" L"baz").
01733   virtual ExprResult ActOnStringLiteral(const clang::Token *Toks, unsigned NumToks)
01734   {
01735     clang::StringLiteralParser literal(Toks, NumToks, preprocessor, target_info);
01736     if (literal.hadError)
01737     return ExprResult(true);
01738 
01739     return hold_expr.ToRaw( CreateString( literal.GetString() ) );
01740   }
01741 
01742   /// ActOnCXXThis - Parse the C++ 'this' pointer.
01743   virtual ExprResult ActOnCXXThis(clang::SourceLocation ThisLoc)
01744   {
01745     return hold_expr.ToRaw( TreePtr<This>( new This ) );
01746   }
01747 
01748   virtual DeclTy *ActOnEnumConstant(clang::Scope *S, DeclTy *EnumDecl,
01749       DeclTy *LastEnumConstant,
01750       clang::SourceLocation IdLoc, clang::IdentifierInfo *Id,
01751       clang::SourceLocation EqualLoc, ExprTy *Val)
01752   {
01753         TreePtr<Declaration> d( hold_decl.FromRaw( EnumDecl ) );
01754         TreePtr<Enum> e( dynamic_pointer_cast<Enum>(d) );
01755     TreePtr<Static> o(new Static());
01756     all_decls->members.insert(o);
01757     o->identifier = CreateInstanceIdentifier(Id);
01758     o->constancy = MakeTreePtr<Const>(); // static const member need not consume storage!!
01759     o->type = e->identifier;//CreateIntegralType( TypeDb::integral_bits[clang::DeclSpec::TSW_unspecified], false );
01760     if( Val )
01761     {
01762       o->initialiser = hold_expr.FromRaw( Val );
01763     }
01764     else if( LastEnumConstant )
01765     {
01766       TreePtr<Declaration> lastd( hold_decl.FromRaw( LastEnumConstant ) );
01767       TreePtr<Instance> lasto( dynamic_pointer_cast<Instance>(lastd) );
01768       ASSERT(lasto)( "unexpected kind of declaration inside an enum");
01769       TreePtr<Add> inf( new Add );
01770       TreePtr<Expression> ei = lasto->identifier;
01771       inf->operands.insert( ei );
01772       inf->operands.insert( CreateNumericConstant( 1 ) );
01773       o->initialiser = inf;
01774     }
01775     else
01776     {
01777       o->initialiser = CreateNumericConstant( 0 );
01778     }
01779     ident_track.Add(Id, o, S);
01780     return hold_decl.ToRaw( o );
01781   }
01782 
01783   virtual void ActOnEnumBody(clang::SourceLocation EnumLoc, DeclTy *EnumDecl,
01784       DeclTy **Elements, unsigned NumElements)
01785   {
01786     TreePtr<Declaration> d( hold_decl.FromRaw( EnumDecl ) );
01787     TreePtr<Enum> e( dynamic_pointer_cast<Enum>(d) );
01788     ASSERT( e )( "expected the declaration to be an enum");
01789     for( int i=0; i<NumElements; i++ )
01790         e->members.insert( hold_decl.FromRaw( Elements[i] ) );
01791   }
01792 
01793   /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
01794   /// no declarator (e.g. "struct foo;") is parsed.
01795   virtual DeclTy *ParsedFreeStandingDeclSpec(clang::Scope *S, clang::DeclSpec &DS)
01796   {
01797     TRACE();
01798     TreePtr<Declaration> d( hold_decl.FromRaw( DS.getTypeRep() ) );
01799     TreePtr<Record> h( dynamic_pointer_cast<Record>( d ) );
01800     ASSERT( h );
01801     if( decl_to_insert )
01802     {
01803       d = decl_to_insert;
01804       decl_to_insert = TreePtr<Declaration>();
01805     }
01806 
01807     // See if the declaration is already there (due to forwarding using
01808     // incomplete struct). If so, do not add it again
01809     Collection<Declaration> &sd = inferno_scope_stack.top()->members;
01810     FOREACH( const TreePtr<Declaration> &p, sd ) // TODO find()?
01811     if( TreePtr<Declaration>(p) == d )
01812     return hold_decl.ToRaw( d );
01813 
01814     inferno_scope_stack.top()->members.insert( d );
01815     backing_ordering[inferno_scope_stack.top()].push_back( d );
01816     return hold_decl.ToRaw( d );
01817   }
01818 
01819   virtual ExprResult
01820   ActOnSizeOfAlignOfExpr( clang::SourceLocation OpLoc, bool isSizeof, bool isType,
01821       void *TyOrEx, const clang::SourceRange &ArgRange)
01822   {
01823     TreePtr<TypeOperator> p;
01824     if( isSizeof )
01825     p = TreePtr<SizeOf>(new SizeOf);
01826     else
01827     p = TreePtr<AlignOf>(new AlignOf);
01828 
01829     if( isType )
01830     p->operand = hold_type.FromRaw(TyOrEx);
01831     else
01832     {
01833       ASSERT(0)("typeof() only supported on types at the moment");
01834       // TODO THis is wrong because we'll get 2 refs to the type, need to duplicate,
01835       // or maybe add an alternative node and convert in a S&R
01836       p->operand = TreePtr<Type>::DynamicCast( TypeOf::instance( all_decls, hold_expr.FromRaw(TyOrEx) ) );
01837     }
01838     return hold_expr.ToRaw( p );
01839   }
01840 
01841   virtual BaseResult ActOnBaseSpecifier(DeclTy *classdecl,
01842       clang::SourceRange SpecifierRange,
01843       bool Virt, clang::AccessSpecifier AccessSpec,
01844       TypeTy *basetype,
01845       clang::SourceLocation BaseLoc)
01846   {
01847     TreePtr<Type> t( hold_type.FromRaw( basetype ) );
01848     TreePtr<SpecificTypeIdentifier> ti = dynamic_pointer_cast<SpecificTypeIdentifier>(t);
01849     ASSERT( ti );
01850     TreePtr<Declaration> d = hold_decl.FromRaw( classdecl );
01851     TreePtr<Record> r = dynamic_pointer_cast<Record>( d );
01852     ASSERT( r );
01853 
01854     TreePtr<Base> base( new Base );
01855     base->record = ti;
01856     /*  if( Virt )
01857      base->storage = MakeTreePtr<Virtual>();
01858      else
01859      base->storage = MakeTreePtr<NonStatic>();
01860      base->constancy = MakeTreePtr<NonConst>(); */
01861     base->access = ConvertAccess( AccessSpec, r );
01862     return hold_base.ToRaw( base );
01863   }
01864 
01865   virtual void ActOnBaseSpecifiers(DeclTy *ClassDecl, BaseTy **Bases,
01866       unsigned NumBases)
01867   {
01868     TreePtr<Declaration> cd( hold_decl.FromRaw( ClassDecl ) );
01869     TreePtr<InheritanceRecord> ih( dynamic_pointer_cast<InheritanceRecord>(cd) );
01870     ASSERT( ih );
01871 
01872     for( int i=0; i<NumBases; i++ )
01873     {
01874       ih->bases.insert( hold_base.FromRaw( Bases[i] ) );
01875     }
01876   }
01877 
01878   /// ActOnCXXNestedNameSpecifier - Called during parsing of a
01879   /// nested-name-specifier. e.g. for "foo::bar::" we parsed "foo::" and now
01880   /// we want to resolve "bar::". 'SS' is empty or the previously parsed
01881   /// nested-name part ("foo::"), 'IdLoc' is the source location of 'bar',
01882   /// 'CCLoc' is the location of '::' and 'II' is the identifier for 'bar'.
01883   /// Returns a CXXScopeTy* object representing the C++ scope.
01884   virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(clang::Scope *S,
01885       const clang::CXXScopeSpec &SS,
01886       clang::SourceLocation IdLoc,
01887       clang::SourceLocation CCLoc,
01888       clang::IdentifierInfo &II)
01889   {
01890     TreePtr<Node> n( ident_track.Get( &II, FromCXXScope( &SS ) ) );
01891 
01892     return hold_scope.ToRaw( n );
01893   }
01894 
01895   /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
01896   /// global scope ('::').
01897   virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(clang::Scope *S,
01898       clang::SourceLocation CCLoc)
01899   {
01900     return hold_scope.ToRaw( global_scope );
01901   }
01902 
01903   /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
01904   /// scope or nested-name-specifier) is parsed, part of a declarator-id.
01905   /// After this method is called, according to [C++ 3.4.3p3], names should be
01906   /// looked up in the declarator-id's scope, until the declarator is parsed and
01907   /// ActOnCXXExitDeclaratorScope is called.
01908   /// The 'SS' should be a non-empty valid CXXScopeSpec.
01909   virtual void ActOnCXXEnterDeclaratorScope(clang::Scope *S, const clang::CXXScopeSpec &SS)
01910   {
01911     TRACE();
01912     TreePtr<Node> n = FromCXXScope( &SS );
01913     ASSERT(n);
01914     ident_track.PushScope( NULL, n );
01915   }
01916 
01917   /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
01918   /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
01919   /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
01920   /// Used to indicate that names should revert to being looked up in the
01921   /// defining scope.
01922   virtual void ActOnCXXExitDeclaratorScope(clang::Scope *S, const clang::CXXScopeSpec &SS)
01923   {
01924     TRACE();
01925     ident_track.PopScope( NULL );
01926   }
01927 
01928   TreePtr<Instance> GetConstructor( TreePtr<Type> t )
01929   {
01930     TreePtr<TypeIdentifier> id = dynamic_pointer_cast<TypeIdentifier>(t);
01931     ASSERT(id);
01932     TreePtr<Record> r = GetRecordDeclaration( all_decls, id );
01933 
01934     FOREACH( TreePtr<Declaration> d, r->members )
01935     {
01936       TreePtr<Instance> o( dynamic_pointer_cast<Instance>(d) );
01937       if( !o )
01938       continue;
01939       if( dynamic_pointer_cast<Constructor>(o->type) )
01940       return o;
01941     }
01942     ASSERTFAIL("missing constructor");
01943   }
01944 
01945   virtual MemInitResult ActOnMemInitializer( DeclTy *ConstructorDecl,
01946       clang::Scope *S,
01947       clang::IdentifierInfo *MemberOrBase,
01948       clang::SourceLocation IdLoc,
01949       clang::SourceLocation LParenLoc,
01950       ExprTy **Args, unsigned NumArgs,
01951       clang::SourceLocation *CommaLocs,
01952       clang::SourceLocation RParenLoc )
01953   {
01954     // Get (or make) the constructor we're invoking
01955     TreePtr<Node> n = ident_track.Get( MemberOrBase );
01956     TreePtr<Instance> om( dynamic_pointer_cast<Instance>(n) );
01957     ASSERT( om );
01958     TreePtr<Instance> cm = GetConstructor( om->type );
01959     ASSERT( cm );
01960     ASSERT( cm->identifier );
01961 
01962     // Build a lookup to the constructor, using the speiciifed subobject and the matching constructor
01963     TreePtr<Lookup> lu(new Lookup);
01964     lu->base = om->identifier;
01965     lu->member = cm->identifier;
01966 
01967     // Build a call to the constructor with supplied args
01968     Sequence<Expression> args;
01969     CollectArgs( &args, Args, NumArgs );
01970     TreePtr<Call> call = CreateCall( args, lu );
01971 
01972     // Get the constructor whose init list we're adding to (may need to start a
01973     // new compound statement)
01974     TreePtr<Declaration> d( hold_decl.FromRaw( ConstructorDecl ) );
01975     TreePtr<Instance> o( dynamic_pointer_cast<Instance>(d) );
01976     ASSERT(o);
01977     TreePtr<Compound> comp = dynamic_pointer_cast<Compound>(o->initialiser);
01978     if( !comp )
01979     {
01980       comp = TreePtr<Compound>( new Compound );
01981       o->initialiser = comp;
01982       TRACE();
01983     }
01984 
01985     // Add it
01986     comp->statements.push_back( call );
01987     return 0;
01988   }
01989 
01990   void CollectArgs( Sequence<Expression> *ps, ExprTy **Args, unsigned NumArgs )
01991   {
01992     for(int i=0; i<NumArgs; i++ )
01993     ps->push_back( hold_expr.FromRaw(Args[i]) );
01994   }
01995 
01996   /// ActOnCXXNew - Parsed a C++ 'new' expression. UseGlobal is true if the
01997   /// new was qualified (::new). In a full new like
01998   /// @code new (p1, p2) type(c1, c2) @endcode
01999   /// the p1 and p2 expressions will be in PlacementArgs and the c1 and c2
02000   /// expressions in ConstructorArgs. The type is passed as a declarator.
02001   virtual ExprResult ActOnCXXNew( clang::SourceLocation StartLoc, bool UseGlobal,
02002       clang::SourceLocation PlacementLParen,
02003       ExprTy **PlacementArgs, unsigned NumPlaceArgs,
02004       clang::SourceLocation PlacementRParen,
02005       bool ParenTypeId, clang::Declarator &D,
02006       clang::SourceLocation ConstructorLParen,
02007       ExprTy **ConstructorArgs, unsigned NumConsArgs,
02008       clang::SourceLocation ConstructorRParen )
02009   {
02010     TreePtr<New> n( new New );
02011     n->type = CreateTypeNode( D );
02012     CollectArgs( &(n->placement_arguments), PlacementArgs, NumPlaceArgs );
02013     CollectArgs( &(n->constructor_arguments), ConstructorArgs, NumConsArgs );
02014 
02015     if( UseGlobal )
02016     n->global = TreePtr<Global>( new Global );
02017     else
02018     n->global = TreePtr<NonGlobal>( new NonGlobal );
02019 
02020     // TODO cant figure out meaning of ParenTypeId
02021 
02022     return hold_expr.ToRaw( n );
02023   }
02024 
02025   /// ActOnCXXDelete - Parsed a C++ 'delete' expression. UseGlobal is true if
02026   /// the delete was qualified (::delete). ArrayForm is true if the array form
02027   /// was used (delete[]).
02028   virtual ExprResult ActOnCXXDelete( clang::SourceLocation StartLoc, bool UseGlobal,
02029       bool ArrayForm, ExprTy *Expression )
02030   {
02031     TreePtr<Delete> d( new Delete );
02032     d->pointer = hold_expr.FromRaw( Expression );
02033 
02034     if( ArrayForm )
02035     d->array = TreePtr<DeleteArray>( new DeleteArray );
02036     else
02037     d->array = TreePtr<DeleteNonArray>( new DeleteNonArray );
02038 
02039     if( UseGlobal )
02040     d->global = TreePtr<Global>( new Global );
02041     else
02042     d->global = TreePtr<NonGlobal>( new NonGlobal );
02043 
02044     return hold_expr.ToRaw( d );
02045   }
02046 
02047   virtual ExprResult ActOnCompoundLiteral(clang::SourceLocation LParen, TypeTy *Ty,
02048       clang::SourceLocation RParen, ExprTy *Op)
02049   {
02050     TreePtr<Type> t = hold_type.FromRaw( Ty );
02051     TreePtr<Expression> e = hold_expr.FromRaw( Op );
02052 
02053     TRACE("%p\n", t.get() );
02054 
02055     // At this point, when we have the instance (and hence the type) and the initialiser
02056     // we can detect when an array initialiser has been inserted for a record instance and
02057     // change it.
02058     if( TreePtr<MakeArray> ai = dynamic_pointer_cast<MakeArray>(e) )
02059     if( TreePtr<TypeIdentifier> ti = dynamic_pointer_cast<TypeIdentifier>(t) )
02060     if( TreePtr<Record> r = GetRecordDeclaration(all_decls, ti) )
02061     e = CreateRecordLiteralFromArrayLiteral( ai, r );
02062 
02063     return hold_expr.ToRaw( e );
02064   }
02065 
02066   //--------------------------------------------- unimplemented actions -----------------------------------------------
02067   // Note: only actions that return something (so we don't get NULL XTy going around the place). No obj-C or GCC
02068   // extensions. These all assert out immediately.
02069 
02070   virtual DeclTy *ActOnFileScopeAsmDecl(clang::SourceLocation Loc, ExprArg AsmString)
02071   {
02072     ASSERTFAIL("Unimplemented action");
02073     return 0;
02074   }
02075 
02076   virtual DeclTy *ActOnField(clang::Scope *S, DeclTy *TagD, clang::SourceLocation DeclStart,
02077       clang::Declarator &D, ExprTy *BitfieldWidth)
02078   {
02079     ASSERTFAIL("Unimplemented action"); // TODO is this C-not-C++ or ObjC?
02080     return 0;
02081   }
02082 
02083   virtual StmtResult ActOnAsmStmt(clang::SourceLocation AsmLoc,
02084       bool IsSimple,
02085       bool IsVolatile,
02086       unsigned NumOutputs,
02087       unsigned NumInputs,
02088       std::string *Names,
02089       ExprTy **Constraints,
02090       ExprTy **Exprs,
02091       ExprTy *AsmString,
02092       unsigned NumClobbers,
02093       ExprTy **Clobbers,
02094       clang::SourceLocation RParenLoc)
02095   {
02096     ASSERTFAIL("Unimplemented action");
02097     return 0;
02098   }
02099 
02100   virtual ExprResult ActOnPredefinedExpr(clang::SourceLocation Loc,
02101       clang::tok::TokenKind Kind)
02102   {
02103     ASSERTFAIL("Unimplemented action");
02104     return 0;
02105   }
02106 
02107   virtual DeclTy *ActOnStartNamespaceDef(clang::Scope *S, clang::SourceLocation IdentLoc,
02108       clang::IdentifierInfo *Ident,
02109       clang::SourceLocation LBrace)
02110   {
02111     ASSERTFAIL("Unimplemented action");
02112     return 0;
02113   }
02114 
02115   virtual ExprResult ActOnCXXNamedCast(clang::SourceLocation OpLoc, clang::tok::TokenKind Kind,
02116       clang::SourceLocation LAngleBracketLoc, TypeTy *Ty,
02117       clang::SourceLocation RAngleBracketLoc,
02118       clang::SourceLocation LParenLoc, ExprTy *Op,
02119       clang::SourceLocation RParenLoc)
02120   {
02121     ASSERTFAIL("Unimplemented action");
02122     return 0;
02123   }
02124 
02125   virtual ExprResult ActOnCXXThrow(clang::SourceLocation OpLoc,
02126       ExprTy *Op = 0)
02127   {
02128     ASSERTFAIL("Unimplemented action");
02129     return 0;
02130   }
02131 
02132   virtual ExprResult ActOnCXXTypeConstructExpr(clang::SourceRange TypeRange,
02133       TypeTy *TypeRep,
02134       clang::SourceLocation LParenLoc,
02135       ExprTy **Exprs,
02136       unsigned NumExprs,
02137       clang::SourceLocation *CommaLocs,
02138       clang::SourceLocation RParenLoc)
02139   {
02140     ASSERTFAIL("Unimplemented action");
02141     return 0;
02142   }
02143 
02144   virtual ExprResult ActOnCXXConditionDeclarationExpr(clang::Scope *S,
02145       clang::SourceLocation StartLoc,
02146       clang::Declarator &D,
02147       clang::SourceLocation EqualLoc,
02148       ExprTy *AssignExprVal)
02149   {
02150     ASSERTFAIL("Unimplemented action");
02151     return 0;
02152   }
02153 
02154   virtual DeclTy *ActOnExceptionDeclarator(clang::Scope *S, clang::Declarator &D)
02155   {
02156     ASSERTFAIL("Unimplemented action");
02157     return 0;
02158   }
02159 
02160   virtual OwningStmtResult ActOnCXXCatchBlock(clang::SourceLocation CatchLoc,
02161       DeclTy *ExceptionDecl,
02162       StmtArg HandlerBlock)
02163   {
02164     ASSERTFAIL("Unimplemented action");
02165     return StmtEmpty();
02166   }
02167 
02168   virtual OwningStmtResult ActOnCXXTryBlock(clang::SourceLocation TryLoc,
02169       StmtArg TryBlock,
02170       MultiStmtArg Handlers)
02171   {
02172     ASSERTFAIL("Unimplemented action");
02173     return StmtEmpty();
02174   }
02175   /// ActOnUsingDirective - This is called when using-directive is parsed.
02176   virtual DeclTy *ActOnUsingDirective(clang::Scope *CurScope,
02177       clang::SourceLocation UsingLoc,
02178       clang::SourceLocation NamespcLoc,
02179       const clang::CXXScopeSpec &SS,
02180       clang::SourceLocation IdentLoc,
02181       clang::IdentifierInfo *NamespcName,
02182       clang::AttributeList *AttrList)
02183   {
02184     ASSERTFAIL("Unimplemented action");
02185     return 0;
02186   }
02187 
02188   /// ActOnParamUnparsedDefaultArgument - We've seen a default
02189   /// argument for a function parameter, but we can't parse it yet
02190   /// because we're inside a class definition. Note that this default
02191   /// argument will be parsed later.
02192   virtual void ActOnParamUnparsedDefaultArgument(DeclTy *param,
02193       clang::SourceLocation EqualLoc)
02194   {
02195     ASSERTFAIL("Unimplemented action");
02196   }
02197 
02198   /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
02199   /// the default argument for the parameter param failed.
02200   virtual void ActOnParamDefaultArgumentError(DeclTy *param)
02201   {
02202     ASSERTFAIL("Unimplemented action");
02203   }
02204 
02205   virtual void ActOnEnumStartDefinition(clang::Scope *S, DeclTy *EnumDecl)
02206   {
02207     ASSERTFAIL("Unimplemented action");
02208   }
02209 };
02210 };
02211 
02212 #endif