[llvm-commits] [dragonegg] r129211 - in /dragonegg/trunk/www: disambiguate.diff index.html
Duncan Sands
baldrick at free.fr
Sat Apr 9 04:40:19 PDT 2011
Author: baldrick
Date: Sat Apr 9 06:40:18 2011
New Revision: 129211
URL: http://llvm.org/viewvc/llvm-project?rev=129211&view=rev
Log:
Provide a patch for fixing the build on case insensitive filesystems.
Added:
dragonegg/trunk/www/disambiguate.diff
Modified:
dragonegg/trunk/www/index.html
Added: dragonegg/trunk/www/disambiguate.diff
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/disambiguate.diff?rev=129211&view=auto
==============================================================================
--- dragonegg/trunk/www/disambiguate.diff (added)
+++ dragonegg/trunk/www/disambiguate.diff Sat Apr 9 06:40:18 2011
@@ -0,0 +1,7038 @@
+diff -r -u -N dragonegg-2.9-old/ABI.h dragonegg-2.9-new/ABI.h
+--- dragonegg-2.9-old/ABI.h 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/ABI.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,351 +0,0 @@
+-//===--------- ABI.h - Processor ABI customization hooks --------*- C++ -*-===//
+-//
+-// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
+-// Duncan Sands et al.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file specifies how argument values are passed and returned from function
+-// calls. This allows the target to specialize handling of things like how
+-// structures are passed by-value.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_ABI_H
+-#define DRAGONEGG_ABI_H
+-
+-// Plugin headers
+-#include "Internals.h"
+-#include "Target.h"
+-
+-// LLVM headers
+-#include "llvm/LLVMContext.h"
+-#include "llvm/Target/TargetData.h"
+-
+-namespace llvm {
+- class BasicBlock;
+-}
+-
+-/// DefaultABIClient - This is a simple implementation of the ABI client
+-/// interface that can be subclassed.
+-struct DefaultABIClient {
+- virtual ~DefaultABIClient() {}
+- virtual CallingConv::ID& getCallingConv(void) = 0;
+- virtual bool isShadowReturn() const { return false; }
+-
+- /// HandleScalarResult - This callback is invoked if the function returns a
+- /// simple scalar result value, which is of type RetTy.
+- virtual void HandleScalarResult(const Type * /*RetTy*/) {}
+-
+- /// HandleAggregateResultAsScalar - This callback is invoked if the function
+- /// returns an aggregate value by bit converting it to the specified scalar
+- /// type and returning that. The bit conversion should start at byte Offset
+- /// within the struct, and ScalarTy is not necessarily big enough to cover
+- /// the entire struct.
+- virtual void HandleAggregateResultAsScalar(const Type * /*ScalarTy*/,
+- unsigned /*Offset*/ = 0) {}
+-
+- /// HandleAggregateResultAsAggregate - This callback is invoked if the function
+- /// returns an aggregate value using multiple return values.
+- virtual void HandleAggregateResultAsAggregate(const Type * /*AggrTy*/) {}
+-
+- /// HandleAggregateShadowResult - This callback is invoked if the function
+- /// returns an aggregate value by using a "shadow" first parameter, which is
+- /// a pointer to the aggregate, of type PtrArgTy. If RetPtr is set to true,
+- /// the pointer argument itself is returned from the function.
+- virtual void HandleAggregateShadowResult(const PointerType * /*PtrArgTy*/,
+- bool /*RetPtr*/) {}
+-
+- /// HandleScalarShadowResult - This callback is invoked if the function
+- /// returns a scalar value by using a "shadow" first parameter, which is a
+- /// pointer to the scalar, of type PtrArgTy. If RetPtr is set to true,
+- /// the pointer argument itself is returned from the function.
+- virtual void HandleScalarShadowResult(const PointerType * /*PtrArgTy*/,
+- bool /*RetPtr*/) {}
+-
+-
+- /// HandleScalarArgument - This is the primary callback that specifies an
+- /// LLVM argument to pass. It is only used for first class types.
+- /// If RealSize is non Zero then it specifies number of bytes to access
+- /// from LLVMTy.
+- virtual void HandleScalarArgument(const llvm::Type * /*LLVMTy*/,
+- tree_node * /*type*/,
+- unsigned /*RealSize*/ = 0) {}
+-
+- /// HandleByInvisibleReferenceArgument - This callback is invoked if a pointer
+- /// (of type PtrTy) to the argument is passed rather than the argument itself.
+- virtual void HandleByInvisibleReferenceArgument(const llvm::Type * /*PtrTy*/,
+- tree_node * /*type*/) {}
+-
+- /// HandleByValArgument - This callback is invoked if the aggregate function
+- /// argument is passed by value.
+- virtual void HandleByValArgument(const llvm::Type * /*LLVMTy*/,
+- tree_node * /*type*/) {}
+-
+- /// HandleFCAArgument - This callback is invoked if the aggregate function
+- /// argument is passed by value as a first class aggregate.
+- virtual void HandleFCAArgument(const llvm::Type * /*LLVMTy*/,
+- tree_node * /*type*/) {}
+-
+- /// EnterField - Called when we're about the enter the field of a struct
+- /// or union. FieldNo is the number of the element we are entering in the
+- /// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
+- virtual void EnterField(unsigned /*FieldNo*/,
+- const llvm::Type * /*StructTy*/) {}
+- virtual void ExitField() {}
+- virtual void HandlePad(const llvm::Type * /*LLVMTy*/) {}
+-};
+-
+-// LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+-// special _Complex handling. Return true if X should be returned using
+-// multiple value return instruction.
+-#ifndef LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY
+-#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+- false
+-#endif
+-
+-// LLVM_SHOULD_NOT_USE_SHADOW_RETURN - A hook to allow aggregates to be
+-// returned in registers.
+-#ifndef LLVM_SHOULD_NOT_USE_SHADOW_RETURN
+-#define LLVM_SHOULD_NOT_USE_SHADOW_RETURN(X, CC) \
+- false
+-#endif
+-
+-// doNotUseShadowReturn - Return true if the specified GCC type
+-// should not be returned using a pointer to struct parameter.
+-extern bool doNotUseShadowReturn(tree_node *type, tree_node *fndecl,
+- CallingConv::ID CC);
+-
+-/// isSingleElementStructOrArray - If this is (recursively) a structure with one
+-/// field or an array with one element, return the field type, otherwise return
+-/// null. Returns null for complex number types. If ignoreZeroLength, the
+-/// struct (recursively) may include zero-length fields in addition to the
+-/// single element that has data. If rejectFatBitField, and the single element
+-/// is a bitfield of a type that's bigger than the struct, return null anyway.
+-extern tree_node *isSingleElementStructOrArray(tree_node *type,
+- bool ignoreZeroLength,
+- bool rejectFatBitfield);
+-
+-/// isZeroSizedStructOrUnion - Returns true if this is a struct or union
+-/// which is zero bits wide.
+-extern bool isZeroSizedStructOrUnion(tree_node *type);
+-
+-// getLLVMScalarTypeForStructReturn - Return LLVM Type if TY can be
+-// returned as a scalar, otherwise return NULL. This is the default
+-// target independent implementation.
+-static inline
+-const Type* getLLVMScalarTypeForStructReturn(tree_node *type, unsigned *Offset) {
+- const Type *Ty = ConvertType(type);
+- unsigned Size = getTargetData().getTypeAllocSize(Ty);
+- *Offset = 0;
+- if (Size == 0)
+- return Type::getVoidTy(getGlobalContext());
+- else if (Size == 1)
+- return Type::getInt8Ty(getGlobalContext());
+- else if (Size == 2)
+- return Type::getInt16Ty(getGlobalContext());
+- else if (Size <= 4)
+- return Type::getInt32Ty(getGlobalContext());
+- else if (Size <= 8)
+- return Type::getInt64Ty(getGlobalContext());
+- else if (Size <= 16)
+- return IntegerType::get(getGlobalContext(), 128);
+- else if (Size <= 32)
+- return IntegerType::get(getGlobalContext(), 256);
+-
+- return NULL;
+-}
+-
+-// getLLVMAggregateTypeForStructReturn - Return LLVM type if TY can be
+-// returns as multiple values, otherwise return NULL. This is the default
+-// target independent implementation.
+-static inline
+-const Type* getLLVMAggregateTypeForStructReturn(tree_node * /*type*/) {
+- return NULL;
+-}
+-
+-#ifndef LLVM_TRY_PASS_AGGREGATE_CUSTOM
+-#define LLVM_TRY_PASS_AGGREGATE_CUSTOM(T, E, CC, C) \
+- false
+-#endif
+-
+-// LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS - Return true if this vector
+-// type should be passed as integer registers. Generally vectors which are
+-// not part of the target architecture should do this.
+-#ifndef LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS
+-#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(TY) \
+- false
+-#endif
+-
+-// LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR - Return true if this vector
+-// type should be passed byval. Used for generic vectors on x86-64.
+-#ifndef LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR
+-#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
+- false
+-#endif
+-
+-// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate
+-// value should be passed by value, i.e. passing its address with the byval
+-// attribute bit set. The default is false.
+-#ifndef LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR
+-#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
+- false
+-#endif
+-
+-// LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if this aggregate value
+-// should be passed by value as a first class aggregate. The default is false.
+-#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+-#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+- false
+-#endif
+-
+-// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS - Return true if this aggregate
+-// value should be passed in a mixture of integer, floating point, and vector
+-// registers. The routine should also return by reference a vector of the
+-// types of the registers being used. The default is false.
+-#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS
+-#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
+- false
+-#endif
+-
+-// LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS - Only called if
+-// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS returns true. This returns true if
+-// there are only enough unused argument passing registers to pass a part of
+-// the aggregate. Note, this routine should return false if none of the needed
+-// registers are available.
+-#ifndef LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS
+-#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
+- false
+-#endif
+-
+-// LLVM_BYVAL_ALIGNMENT - Returns the alignment of the type in bytes, if known,
+-// in the getGlobalContext() of its use as a function parameter.
+-// Note that the alignment in the TYPE node is usually the alignment appropriate
+-// when the type is used within a struct, which may or may not be appropriate
+-// here.
+-#ifndef LLVM_BYVAL_ALIGNMENT
+-#define LLVM_BYVAL_ALIGNMENT(T) 0
+-#endif
+-
+-// LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
+-// value should be passed in integer registers. By default, we do this for all
+-// values that are not single-element structs. This ensures that things like
+-// {short,short} are passed in one 32-bit chunk, not as two arguments (which
+-// would often be 64-bits). We also do it for single-element structs when the
+-// single element is a bitfield of a type bigger than the struct; the code
+-// for field-by-field struct passing does not handle this one right.
+-#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
+-#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
+- !isSingleElementStructOrArray((X), false, true)
+-#endif
+-
+-// LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR - Return a TYPE tree if this single
+-// element struct should be returned using the convention for that scalar TYPE,
+-// 0 otherwise.
+-// The returned TYPE must be the same size as X for this to work; that is
+-// checked elsewhere. (Structs where this is not the case can be constructed
+-// by abusing the __aligned__ attribute.)
+-#ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
+-#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
+- isSingleElementStructOrArray(X, false, false)
+-#endif
+-
+-// LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR - Return a TYPE tree if this vector type
+-// should be returned using the convention for that scalar TYPE, 0 otherwise.
+-// X may be evaluated more than once.
+-#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR
+-#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,Y) 0
+-#endif
+-
+-// LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW - Return true if this vector type
+-// should be returned using the aggregate shadow (sret) convention, 0 otherwise.
+-// X may be evaluated more than once.
+-#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW
+-#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,Y) 0
+-#endif
+-
+-// LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+-// returned as a scalar, otherwise return NULL.
+-#ifndef LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN
+-#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
+- getLLVMScalarTypeForStructReturn((X), (Y))
+-#endif
+-
+-// LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+-// returned as an aggregate, otherwise return NULL.
+-#ifndef LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
+-#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
+- getLLVMAggregateTypeForStructReturn(X)
+-#endif
+-
+-// LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
+-// SRC and assign it to DEST. Each target that supports multiple return
+-// value must implement this hook.
+-#ifndef LLVM_EXTRACT_MULTIPLE_RETURN_VALUE
+-#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
+- llvm_default_extract_multiple_return_value((Src),(Dest),(V),(B))
+-#endif
+-static inline
+-void llvm_default_extract_multiple_return_value(Value * /*Src*/, Value * /*Dest*/,
+- bool /*isVolatile*/,
+- LLVMBuilder &/*Builder*/) {
+- assert (0 && "LLVM_EXTRACT_MULTIPLE_RETURN_VALUE is not implemented!");
+-}
+-
+-/// DefaultABI - This class implements the default LLVM ABI where structures are
+-/// passed by decimating them into individual components and unions are passed
+-/// by passing the largest member of the union.
+-///
+-class DefaultABI {
+-protected:
+- DefaultABIClient &C;
+-public:
+- DefaultABI(DefaultABIClient &c);
+-
+- bool isShadowReturn() const;
+-
+- /// HandleReturnType - This is invoked by the target-independent code for the
+- /// return type. It potentially breaks down the argument and invokes methods
+- /// on the client that indicate how its pieces should be handled. This
+- /// handles things like returning structures via hidden parameters.
+- void HandleReturnType(tree_node *type, tree_node *fn, bool isBuiltin);
+-
+- /// HandleArgument - This is invoked by the target-independent code for each
+- /// argument type passed into the function. It potentially breaks down the
+- /// argument and invokes methods on the client that indicate how its pieces
+- /// should be handled. This handles things like decimating structures into
+- /// their fields.
+- void HandleArgument(tree_node *type, std::vector<const Type*> &ScalarElts,
+- Attributes *Attributes = NULL);
+-
+- /// HandleUnion - Handle a UNION_TYPE or QUAL_UNION_TYPE tree.
+- ///
+- void HandleUnion(tree_node *type, std::vector<const Type*> &ScalarElts);
+-
+- /// PassInIntegerRegisters - Given an aggregate value that should be passed in
+- /// integer registers, convert it to a structure containing ints and pass all
+- /// of the struct elements in. If Size is set we pass only that many bytes.
+- void PassInIntegerRegisters(tree_node *type,
+- std::vector<const Type*> &ScalarElts,
+- unsigned origSize, bool DontCheckAlignment);
+-
+- /// PassInMixedRegisters - Given an aggregate value that should be passed in
+- /// mixed integer, floating point, and vector registers, convert it to a
+- /// structure containing the specified struct elements in.
+- void PassInMixedRegisters(const Type *Ty, std::vector<const Type*> &OrigElts,
+- std::vector<const Type*> &ScalarElts);
+-};
+-
+-#endif /* DRAGONEGG_ABI_H */
+diff -r -u -N dragonegg-2.9-old/ADT/IntervalList.h dragonegg-2.9-new/ADT/IntervalList.h
+--- dragonegg-2.9-old/ADT/IntervalList.h 2011-03-28 21:44:58.000000000 +0200
++++ dragonegg-2.9-new/ADT/IntervalList.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,215 +0,0 @@
+-//=--------- IntervalList.h - List of disjoint intervals ----------*- C++ -*-=//
+-//
+-// Copyright (C) 2011 Duncan Sands.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file declares a utility class for maintaining a collection of pairwise
+-// disjoint intervals.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_INTERVALLIST_H
+-#define DRAGONEGG_INTERVALLIST_H
+-
+-#include "Range.h"
+-#include "llvm/ADT/SmallVector.h"
+-
+-/// IntervalList - Maintains a list of disjoint intervals. Type 'T' represents
+-/// an interval, and should have a getRange method which returns a range of 'U'
+-/// values. In addition it should provide ChangeRangeTo for growing, shrinking
+-/// and otherwise changing the shape of the interval; and JoinWith for replacing
+-/// the interval with the convex hull of its union with another interval (which
+-/// is guaranteed to be disjoint from the original).
+-template <class T, typename U, unsigned N>
+-class IntervalList {
+- typedef typename llvm::SmallVector<T, N> List;
+- typedef typename List::iterator iterator;
+-
+- List Intervals;
+- // The actual intervals. Always disjoint, sorted and non-empty.
+-
+- /// CmpFirst - Compare intervals based on where they start.
+- static bool CmpFirst(const T &L, const T &R) {
+- return L.getRange().getFirst() < R.getRange().getFirst();
+- }
+-
+- /// CmpLast - Compare intervals based on where they stop.
+- static bool CmpLast(const T &L, const T &R) {
+- return L.getRange().getLast() < R.getRange().getLast();
+- }
+-
+- /// isSane - Return true if the intervals are non-empty, disjoint and
+- /// sorted.
+- bool isSane() const {
+- for (unsigned i = 0, e = Intervals.size(); i < e; ++i) {
+- if (Intervals[i].getRange().empty())
+- return false;
+- if (i && Intervals[i].getRange().getFirst() <
+- Intervals[i-1].getRange().getLast())
+- return false;
+- }
+- return true;
+- }
+-
+-public:
+-
+- /// AddInterval - Add the given interval to the list. If it overlaps any
+- /// existing intervals then the existing intervals are pruned by removing
+- /// exactly the parts of them that overlap the new interval. If the added
+- /// interval is empty then it will be discarded.
+- void AddInterval(const T &S);
+-
+- /// getNumIntervals - Return the number of intervals in the list.
+- unsigned getNumIntervals() const {
+- return Intervals.size();
+- }
+-
+- /// getInterval - Return the interval with the given index.
+- T getInterval(unsigned Idx) {
+- return Intervals[Idx];
+- }
+-
+- /// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
+- /// the given value.
+- void AlignBoundaries(unsigned Alignment);
+-};
+-
+-/// AddInterval - Add the given interval to the list. If it overlaps any
+-/// existing intervals then the existing intervals are pruned by removing
+-/// exactly the parts of them that overlap the new interval. If the added
+-/// interval is empty then it will be discarded.
+-template <class T, typename U, unsigned N>
+-void IntervalList<T, U, N>::AddInterval(const T &Interval) {
+- const Range<U> NewRange = Interval.getRange();
+-
+- // If the new interval is empty then there is no point in adding it.
+- if (NewRange.empty())
+- return;
+-
+- // If this is the first interval then it cannot overlap any others.
+- if (Intervals.empty()) {
+- Intervals.push_back(Interval);
+- return;
+- }
+-
+- // Check for overlap with existing intervals.
+- iterator Lo = std::lower_bound(Intervals.begin(), Intervals.end(), Interval,
+- CmpFirst);
+- iterator Hi = std::upper_bound(Intervals.begin(), Intervals.end(), Interval,
+- CmpLast);
+- if (Lo < Hi) {
+- // Intervals with index in [Lo, Hi) are those completely covered by the new
+- // interval. Throw them away.
+- for (iterator I = Lo; I != Hi; ++I)
+- assert(NewRange.contains(I->getRange()) && "Old interval not covered!");
+- Intervals.erase(Lo, Hi);
+- Hi = Lo;
+- } else if (Hi < Lo) {
+- // The new interval is contained in Hi with an excedent at each end. Chop
+- // the old interval into two pieces (the lower and upper parts) and insert
+- // the new interval between them.
+- const Range<U> OldRange = Hi->getRange();
+- assert(OldRange.contains(NewRange) && "New interval not contained in old!");
+- const Range<U> LowerRange(OldRange.getFirst(), NewRange.getFirst());
+- const Range<U> UpperRange(NewRange.getLast(), OldRange.getLast());
+- assert(!LowerRange.empty() && !UpperRange.empty() && "Degenerate end!");
+- T UpperPart = *Hi;
+- Hi->ChangeRangeTo(LowerRange);
+- UpperPart.ChangeRangeTo(UpperRange);
+- Lo = Intervals.insert(Lo, UpperPart);
+- Intervals.insert(Lo, Interval);
+- assert(isSane() && "Interval added wrong!");
+- return;
+- }
+- assert(Lo == Hi);
+- // Check for overlap with the preceding interval.
+- if (Lo != Intervals.begin()) {
+- const iterator Prev = Lo - 1;
+- const Range<U> PrevRange = Prev->getRange();
+- if (NewRange.getFirst() < PrevRange.getLast())
+- // Shrink the previous interval to remove the overlap.
+- Prev->ChangeRangeTo(Range<U>(PrevRange.getFirst(), NewRange.getFirst()));
+- }
+- // Check for overlap with the following interval.
+- if (Lo != Intervals.end()) {
+- const iterator Next = Lo;
+- const Range<U> NextRange = Next->getRange();
+- if (NextRange.getFirst() < NewRange.getLast())
+- // Shrink the next interval to remove the overlap.
+- Next->ChangeRangeTo(Range<U>(NewRange.getLast(), NextRange.getLast()));
+- }
+- // The new interval is now disjoint from any existing intervals. Insert it.
+- Intervals.insert(Lo, Interval);
+- assert(isSane() && "Interval added wrong!");
+-}
+-
+-/// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
+-/// the given value.
+-template <class T, typename U, unsigned N>
+-void IntervalList<T, U, N>::AlignBoundaries(unsigned Alignment) {
+- assert(Alignment > 0 && "Alignment should be positive!");
+- for (iterator SI = Intervals.begin(); SI != Intervals.end(); ++SI) {
+- T &Interval = *SI;
+- Range<U> OrigRange = Interval.getRange();
+-
+- // Round the start of the interval down and the end of the interval up to
+- // the nearest multiple of the alignment.
+- U RoundedFirst = OrigRange.getFirst() - (OrigRange.getFirst() % Alignment);
+- U RoundedLast = OrigRange.getLast() + Alignment - 1;
+- RoundedLast -= RoundedLast % Alignment;
+- Range<U> AlignedRange(RoundedFirst, RoundedLast);
+-
+- // There is nothing to do if the interval is already aligned.
+- if (OrigRange == AlignedRange)
+- continue;
+-
+- // Merge in all following intervals that start before RoundedLast.
+- iterator Next = SI + 1;
+- for (; Next != Intervals.end() && Next->getRange().getFirst() < RoundedLast;
+- ++Next)
+- Interval.JoinWith(*Next);
+- assert(Interval.getRange().getFirst() == OrigRange.getFirst() &&
+- "Merging at end changed start!");
+-
+- // If merging caused the interval to extend beyond RoundedLast then chop the
+- // interval in two at RoundedLast. This stops intervals getting huge due to
+- // repeated merging.
+- if (Interval.getRange().getLast() > RoundedLast) {
+- Range<U> LowerR(OrigRange.getFirst(), RoundedLast);
+- Range<U> UpperR(RoundedLast, Interval.getRange().getLast());
+- // We must have merged in at least the next interval. Reuse it to hold
+- // the part we chop off the end.
+- T &J = *(SI + 1) = Interval;
+- // Chop the end off the original interval so that it stops at RoundedLast
+- // and at the same time extend the start of the original interval down to
+- // the alignment boundary.
+- Interval.ChangeRangeTo(AlignedRange);
+- // Chop the start off the new (following) interval so that it begins at
+- // RoundedLast.
+- J.ChangeRangeTo(UpperR);
+- // Delete any other merged intervals.
+- Intervals.erase(SI + 2, Next);
+- } else {
+- // The interval didn't grow beyond the original alignment boundary. Round
+- // it to those boundaries.
+- Interval.ChangeRangeTo(AlignedRange);
+- // Delete any merged intervals.
+- Intervals.erase(SI + 1, Next);
+- }
+- }
+-}
+-
+-#endif /* DRAGONEGG_INTERVALLIST_H */
+diff -r -u -N dragonegg-2.9-old/ADT/Range.h dragonegg-2.9-new/ADT/Range.h
+--- dragonegg-2.9-old/ADT/Range.h 2011-03-28 21:44:58.000000000 +0200
++++ dragonegg-2.9-new/ADT/Range.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,106 +0,0 @@
+-//=------------------ Range.h - Interval of values ----------------*- C++ -*-=//
+-//
+-// Copyright (C) 2011 Duncan Sands.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file declares a utility class for representing an interval of values.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_RANGE_H
+-#define DRAGONEGG_RANGE_H
+-
+-/// Range - Represents the interval [First, Last).
+-template<typename T>
+-class Range {
+- T First, Last;
+-public:
+- Range() : First(0), Last(0) {}
+- Range(T first, T last) : First(first), Last(last) {}
+-
+- bool operator==(const Range &other) const {
+- return (empty() && other.empty()) ||
+- (First == other.First && Last == other.Last);
+- }
+-
+- /// empty - Return whether the range is empty.
+- bool empty() const {
+- return Last <= First;
+- }
+-
+- /// getFirst - Return the value defining the start of the range.
+- T getFirst() const {
+- assert(!empty() && "An empty range has no starting value!");
+- return First;
+- }
+-
+- /// getLast - Return the value defining the end of the range.
+- T getLast() const {
+- assert(!empty() && "An empty range has no ending value!");
+- return Last;
+- }
+-
+- /// getWidth - Return the number of values in the range.
+- T getWidth() const {
+- return empty() ? 0 : Last - First;
+- }
+-
+- /// contains - Return true if the given range is contained in this one.
+- bool contains(Range r) const {
+- if (r.empty())
+- return true;
+- if (empty())
+- return false;
+- return First <= r.First && Last >= r.Last;
+- }
+-
+- /// intersects - Return true if the given range intersects this one.
+- bool intersects(Range r) const {
+- if (empty() || r.empty())
+- return false;
+- return r.First < Last && r.Last > First;
+- }
+-
+- /// Displace - Return the range obtained by adding the given offset.
+- Range Displace(T Offset) const {
+- if (empty())
+- return Range();
+- assert(((Offset >= 0 && First + Offset >= First && Last + Offset >= Last) ||
+- (Offset < 0 && First + Offset < First && Last + Offset < Last)) &&
+- "Displacement wrapped range!");
+- return Range(First + Offset, Last + Offset);
+- }
+-
+- /// Join - Return the smallest range containing this range and the given one.
+- Range Join(Range other) const {
+- if (empty())
+- return other;
+- if (other.empty())
+- return *this;
+- return Range(First < other.First ? First : other.First,
+- Last > other.Last ? Last : other.Last);
+- }
+-
+- /// Meet - Return the intersection of this range and the given one.
+- Range Meet(Range other) const {
+- if (empty() || other.empty())
+- return Range();
+- return Range(First > other.First ? First : other.First,
+- Last < other.Last ? Last : other.Last);
+- }
+-};
+-
+-#endif /* DRAGONEGG_RANGE_H */
+diff -r -u -N dragonegg-2.9-old/Backend.cpp dragonegg-2.9-new/Backend.cpp
+--- dragonegg-2.9-old/Backend.cpp 2011-03-30 08:30:55.000000000 +0200
++++ dragonegg-2.9-new/Backend.cpp 2011-04-09 00:38:06.620098051 +0200
+@@ -23,12 +23,12 @@
+
+ // Plugin headers
+ extern "C" {
+-#include "cache.h"
++#include "dragonegg/cache.h"
+ }
+-#include "Constants.h"
+-#include "Debug.h"
+-#include "OS.h"
+-#include "Target.h"
++#include "dragonegg/Constants.h"
++#include "dragonegg/Debug.h"
++#include "dragonegg/OS.h"
++#include "dragonegg/Target.h"
+
+ // LLVM headers
+ #define DEBUG_TYPE "plugin"
+diff -r -u -N dragonegg-2.9-old/cache.c dragonegg-2.9-new/cache.c
+--- dragonegg-2.9-old/cache.c 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/cache.c 2011-04-09 00:38:06.620098051 +0200
+@@ -25,7 +25,7 @@
+ ===----------------------------------------------------------------------===*/
+
+ /* Plugin headers. */
+-#include "cache.h"
++#include "dragonegg/cache.h"
+
+ /* GCC headers. */
+ #include "config.h"
+@@ -49,7 +49,7 @@
+ htab_t llvm_cache;
+
+ /* Garbage collector header. */
+-#include "gt-cache.h"
++#include "dragonegg/gt-cache.h"
+
+ /* llvm_has_cached - Returns whether a value has been associated with the
+ tree. */
+diff -r -u -N dragonegg-2.9-old/cache.h dragonegg-2.9-new/cache.h
+--- dragonegg-2.9-old/cache.h 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/cache.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,45 +0,0 @@
+-/*===----------- cache.h - Caching values "in" GCC trees ----------*- C -*-===*\
+-|* *|
+-|* Copyright (C) 2009, 2010, 2011 Duncan Sands. *|
+-|* *|
+-|* This file is part of DragonEgg. *|
+-|* *|
+-|* DragonEgg is free software; you can redistribute it and/or modify it under *|
+-|* the terms of the GNU General Public License as published by the Free *|
+-|* Software Foundation; either version 2, or (at your option) any later *|
+-|* version. *|
+-|* *|
+-|* DragonEgg is distributed in the hope that it will be useful, but WITHOUT *|
+-|* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *|
+-|* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *|
+-|* more details. *|
+-|* You should have received a copy of the GNU General Public License along *|
+-|* with DragonEgg; see the file COPYING. If not, write to the Free Software *|
+-|* Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. *|
+-|* *|
+-|*===----------------------------------------------------------------------===*|
+-|* This code lets you to associate a void* with a tree, as if it were cached *|
+-|* inside the tree: if the tree is garbage collected and reallocated, then *|
+-|* the cached value will have been cleared. *|
+-\*===----------------------------------------------------------------------===*/
+-
+-#ifndef DRAGONEGG_CACHE_H
+-#define DRAGONEGG_CACHE_H
+-
+-union tree_node;
+-
+-/* llvm_has_cached - Returns whether a value has been associated with the
+- tree. */
+-extern int llvm_has_cached(union tree_node *tree);
+-
+-/* llvm_get_cached - Returns the value associated with the tree, or NULL. */
+-extern const void *llvm_get_cached(union tree_node *tree);
+-
+-/* llvm_set_cached - Associates the given value with the tree (and returns it).
+- To delete an association, pass NULL for the value. */
+-extern const void *llvm_set_cached(union tree_node *tree, const void *val);
+-
+-/* llvm_replace_cached - Replaces all occurrences of old_val with new_val. */
+-extern void llvm_replace_cached(const void *old_val, const void *new_val);
+-
+-#endif /* DRAGONEGG_CACHE_H */
+diff -r -u -N dragonegg-2.9-old/Constants.cpp dragonegg-2.9-new/Constants.cpp
+--- dragonegg-2.9-old/Constants.cpp 2011-03-31 17:57:30.000000000 +0200
++++ dragonegg-2.9-new/Constants.cpp 2011-04-09 00:38:06.620098051 +0200
+@@ -21,11 +21,11 @@
+ //===----------------------------------------------------------------------===//
+
+ // Plugin headers
+-#include "Constants.h"
+-#include "Internals.h"
+-#include "Trees.h"
+-#include "ADT/IntervalList.h"
+-#include "ADT/Range.h"
++#include "dragonegg/Constants.h"
++#include "dragonegg/Internals.h"
++#include "dragonegg/Trees.h"
++#include "dragonegg/ADT/IntervalList.h"
++#include "dragonegg/ADT/Range.h"
+
+ // LLVM headers
+ #include "llvm/GlobalVariable.h"
+diff -r -u -N dragonegg-2.9-old/Constants.h dragonegg-2.9-new/Constants.h
+--- dragonegg-2.9-old/Constants.h 2011-03-29 20:44:32.000000000 +0200
++++ dragonegg-2.9-new/Constants.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,60 +0,0 @@
+-//=----- Constants.h - Converting and working with constants ------*- C++ -*-=//
+-//
+-// Copyright (C) 2011 Duncan Sands.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file declares functions for converting GCC constants to LLVM and working
+-// with them.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_CONSTANTS_H
+-#define DRAGONEGG_CONSTANTS_H
+-
+-// Forward declarations.
+-namespace llvm {
+- class Constant;
+- class Type;
+-}
+-union tree_node;
+-
+-/// AddressOf - Given an expression with a constant address such as a constant,
+-/// a global variable or a label, returns the address. The type of the returned
+-/// is always a pointer type and, as long as 'exp' does not have void type, the
+-/// type of the pointee is the memory type that corresponds to the type of exp
+-/// (see ConvertType).
+-extern llvm::Constant *AddressOf(tree_node *exp);
+-
+-/// ConvertInitializer - Convert the initial value for a global variable to an
+-/// equivalent LLVM constant. Also handles constant constructors. The type of
+-/// the returned value may be pretty much anything. All that is guaranteed is
+-/// that its alloc size is equal to the size of the initial value and that its
+-/// alignment is less than or equal to the initial value's GCC type alignment.
+-/// Note that the GCC type may have variable size or no size, in which case the
+-/// size is determined by the initial value. When this happens the size of the
+-/// initial value may exceed the alloc size of the LLVM memory type generated
+-/// for the GCC type (see ConvertType); it is never smaller than the alloc size.
+-extern llvm::Constant *ConvertInitializer(tree_node *exp);
+-
+-/// InterpretAsType - Interpret the bits of the given constant (starting from
+-/// StartingBit) as representing a constant of type 'Ty'. This results in the
+-/// same constant as you would get by storing the bits of 'C' to memory (with
+-/// the first bit stored being 'StartingBit') and then loading out a (constant)
+-/// value of type 'Ty' from the stored to memory location.
+-extern llvm::Constant *InterpretAsType(llvm::Constant *C, const llvm::Type* Ty,
+- int StartingBit);
+-
+-#endif /* DRAGONEGG_CONSTANTS_H */
+diff -r -u -N dragonegg-2.9-old/Convert.cpp dragonegg-2.9-new/Convert.cpp
+--- dragonegg-2.9-old/Convert.cpp 2011-03-31 17:59:19.000000000 +0200
++++ dragonegg-2.9-new/Convert.cpp 2011-04-09 00:38:06.620098051 +0200
+@@ -22,10 +22,10 @@
+ //===----------------------------------------------------------------------===//
+
+ // Plugin headers
+-#include "ABI.h"
+-#include "Constants.h"
+-#include "Debug.h"
+-#include "Trees.h"
++#include "dragonegg/ABI.h"
++#include "dragonegg/Constants.h"
++#include "dragonegg/Debug.h"
++#include "dragonegg/Trees.h"
+
+ // LLVM headers
+ #include "llvm/Module.h"
+diff -r -u -N dragonegg-2.9-old/darwin/dragonegg/OS.h dragonegg-2.9-new/darwin/dragonegg/OS.h
+--- dragonegg-2.9-old/darwin/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/darwin/dragonegg/OS.h 2011-04-09 00:38:06.620098051 +0200
+@@ -0,0 +1,56 @@
++//===------------ OS.h - Darwin specific definitions ------------*- C++ -*-===//
++//
++// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file provides Darwin specific declarations.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_OS_H
++#define DRAGONEGG_OS_H
++
++/* Darwin X86-64 only supports PIC code generation. */
++#if defined (TARGET_386)
++#define LLVM_SET_TARGET_OPTIONS(argvec) \
++ if ((TARGET_64BIT) || flag_pic) \
++ argvec.push_back ("--relocation-model=pic"); \
++ else if (!MACHO_DYNAMIC_NO_PIC_P) \
++ argvec.push_back ("--relocation-model=static")
++#elif defined (TARGET_ARM)
++#define LLVM_SET_TARGET_OPTIONS(argvec) \
++ if (flag_pic) \
++ argvec.push_back ("--relocation-model=pic"); \
++ else if (!MACHO_DYNAMIC_NO_PIC_P) \
++ argvec.push_back ("--relocation-model=static"); \
++#else /* !TARGET_386 && !TARGET_ARM */
++#define LLVM_SET_TARGET_OPTIONS(argvec) \
++ if (flag_pic) \
++ argvec.push_back ("--relocation-model=pic"); \
++ else if (!MACHO_DYNAMIC_NO_PIC_P) \
++ argvec.push_back ("--relocation-model=static")
++#endif /* !TARGET_386 && !TARGET_ARM */
++
++/* Give a constant string a sufficient alignment for the platform. */
++/* radar 7291825 */
++#define TARGET_ADJUST_CSTRING_ALIGN(GV) \
++ do { \
++ if (GV->hasInternalLinkage()) { \
++ GV->setAlignment(TARGET_64BIT ? 8 : 4); \
++ } \
++ } while (0)
++
++#endif /* DRAGONEGG_OS_H */
+diff -r -u -N dragonegg-2.9-old/darwin/OS.h dragonegg-2.9-new/darwin/OS.h
+--- dragonegg-2.9-old/darwin/OS.h 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/darwin/OS.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,56 +0,0 @@
+-//===------------ OS.h - Darwin specific definitions ------------*- C++ -*-===//
+-//
+-// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file provides Darwin specific declarations.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_OS_H
+-#define DRAGONEGG_OS_H
+-
+-/* Darwin X86-64 only supports PIC code generation. */
+-#if defined (TARGET_386)
+-#define LLVM_SET_TARGET_OPTIONS(argvec) \
+- if ((TARGET_64BIT) || flag_pic) \
+- argvec.push_back ("--relocation-model=pic"); \
+- else if (!MACHO_DYNAMIC_NO_PIC_P) \
+- argvec.push_back ("--relocation-model=static")
+-#elif defined (TARGET_ARM)
+-#define LLVM_SET_TARGET_OPTIONS(argvec) \
+- if (flag_pic) \
+- argvec.push_back ("--relocation-model=pic"); \
+- else if (!MACHO_DYNAMIC_NO_PIC_P) \
+- argvec.push_back ("--relocation-model=static"); \
+-#else /* !TARGET_386 && !TARGET_ARM */
+-#define LLVM_SET_TARGET_OPTIONS(argvec) \
+- if (flag_pic) \
+- argvec.push_back ("--relocation-model=pic"); \
+- else if (!MACHO_DYNAMIC_NO_PIC_P) \
+- argvec.push_back ("--relocation-model=static")
+-#endif /* !TARGET_386 && !TARGET_ARM */
+-
+-/* Give a constant string a sufficient alignment for the platform. */
+-/* radar 7291825 */
+-#define TARGET_ADJUST_CSTRING_ALIGN(GV) \
+- do { \
+- if (GV->hasInternalLinkage()) { \
+- GV->setAlignment(TARGET_64BIT ? 8 : 4); \
+- } \
+- } while (0)
+-
+-#endif /* DRAGONEGG_OS_H */
+diff -r -u -N dragonegg-2.9-old/Debug.cpp dragonegg-2.9-new/Debug.cpp
+--- dragonegg-2.9-old/Debug.cpp 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/Debug.cpp 2011-04-09 00:38:06.620098051 +0200
+@@ -22,7 +22,7 @@
+ //===----------------------------------------------------------------------===//
+
+ // Plugin headers
+-#include "Debug.h"
++#include "dragonegg/Debug.h"
+
+ // LLVM headers
+ #include "llvm/Module.h"
+diff -r -u -N dragonegg-2.9-old/Debug.h dragonegg-2.9-new/Debug.h
+--- dragonegg-2.9-old/Debug.h 2011-03-29 12:46:17.000000000 +0200
++++ dragonegg-2.9-new/Debug.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,367 +0,0 @@
+-//===------ Debug.h - Interface for generating debug info -------*- C++ -*-===//
+-//
+-// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Jim Laskey, Duncan Sands
+-// et al.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file declares the debug interfaces shared among the dragonegg files.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_DEBUG_H
+-#define DRAGONEGG_DEBUG_H
+-
+-// Plugin headers
+-#include "Internals.h"
+-
+-// LLVM headers
+-#include "llvm/Analysis/DebugInfo.h"
+-#include "llvm/Support/Allocator.h"
+-#include "llvm/Support/ValueHandle.h"
+-
+-// System headers
+-#include <map>
+-
+-namespace llvm {
+-
+-// Forward declarations
+-class AllocaInst;
+-class BasicBlock;
+-class CallInst;
+-class Function;
+-class Module;
+-
+-/// DIFactory - This object assists with the construction of the various
+-/// descriptors.
+-class DIFactory {
+- Module &M;
+- LLVMContext& VMContext;
+-
+- Function *DeclareFn; // llvm.dbg.declare
+- Function *ValueFn; // llvm.dbg.value
+-
+- DIFactory(const DIFactory &); // DO NOT IMPLEMENT
+- void operator=(const DIFactory&); // DO NOT IMPLEMENT
+- public:
+- enum ComplexAddrKind { OpPlus=1, OpDeref };
+-
+- explicit DIFactory(Module &m);
+-
+- /// GetOrCreateArray - Create an descriptor for an array of descriptors.
+- /// This implicitly uniques the arrays created.
+- DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
+-
+- /// GetOrCreateSubrange - Create a descriptor for a value range. This
+- /// implicitly uniques the values returned.
+- DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi);
+-
+- /// CreateUnspecifiedParameter - Create unspeicified type descriptor
+- /// for a subroutine type.
+- DIDescriptor CreateUnspecifiedParameter();
+-
+- /// CreateCompileUnit - Create a new descriptor for the specified compile
+- /// unit.
+- DICompileUnit CreateCompileUnit(unsigned LangID,
+- StringRef Filename,
+- StringRef Directory,
+- StringRef Producer,
+- bool isMain = false,
+- bool isOptimized = false,
+- StringRef Flags = "",
+- unsigned RunTimeVer = 0);
+-
+- /// CreateFile - Create a new descriptor for the specified file.
+- DIFile CreateFile(StringRef Filename, StringRef Directory,
+- DICompileUnit CU);
+-
+- /// CreateEnumerator - Create a single enumerator value.
+- DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
+-
+- /// CreateBasicType - Create a basic type like int, float, etc.
+- DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
+- DIFile F, unsigned LineNumber,
+- uint64_t SizeInBits, uint64_t AlignInBits,
+- uint64_t OffsetInBits, unsigned Flags,
+- unsigned Encoding);
+-
+- /// CreateBasicType - Create a basic type like int, float, etc.
+- DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
+- DIFile F, unsigned LineNumber,
+- Constant *SizeInBits, Constant *AlignInBits,
+- Constant *OffsetInBits, unsigned Flags,
+- unsigned Encoding);
+-
+- /// CreateDerivedType - Create a derived type like const qualified type,
+- /// pointer, typedef, etc.
+- DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
+- StringRef Name,
+- DIFile F,
+- unsigned LineNumber,
+- uint64_t SizeInBits, uint64_t AlignInBits,
+- uint64_t OffsetInBits, unsigned Flags,
+- DIType DerivedFrom);
+-
+- /// CreateDerivedType - Create a derived type like const qualified type,
+- /// pointer, typedef, etc.
+- DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
+- StringRef Name,
+- DIFile F,
+- unsigned LineNumber,
+- Constant *SizeInBits,
+- Constant *AlignInBits,
+- Constant *OffsetInBits, unsigned Flags,
+- DIType DerivedFrom);
+-
+- /// CreateCompositeType - Create a composite type like array, struct, etc.
+- DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
+- StringRef Name,
+- DIFile F,
+- unsigned LineNumber,
+- uint64_t SizeInBits,
+- uint64_t AlignInBits,
+- uint64_t OffsetInBits, unsigned Flags,
+- DIType DerivedFrom,
+- DIArray Elements,
+- unsigned RunTimeLang = 0,
+- MDNode *ContainingType = 0);
+-
+- /// CreateTemporaryType - Create a temporary forward-declared type.
+- DIType CreateTemporaryType();
+- DIType CreateTemporaryType(DIFile F);
+-
+- /// CreateArtificialType - Create a new DIType with "artificial" flag set.
+- DIType CreateArtificialType(DIType Ty);
+-
+- /// CreateCompositeType - Create a composite type like array, struct, etc.
+- DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
+- StringRef Name,
+- DIFile F,
+- unsigned LineNumber,
+- Constant *SizeInBits,
+- Constant *AlignInBits,
+- Constant *OffsetInBits,
+- unsigned Flags,
+- DIType DerivedFrom,
+- DIArray Elements,
+- unsigned RunTimeLang = 0,
+- MDNode *ContainingType = 0);
+-
+- /// CreateSubprogram - Create a new descriptor for the specified subprogram.
+- /// See comments in DISubprogram for descriptions of these fields.
+- DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
+- StringRef DisplayName,
+- StringRef LinkageName,
+- DIFile F, unsigned LineNo,
+- DIType Ty, bool isLocalToUnit,
+- bool isDefinition,
+- unsigned VK = 0,
+- unsigned VIndex = 0,
+- DIType ContainingType = DIType(),
+- unsigned Flags = 0,
+- bool isOptimized = false,
+- Function *Fn = 0);
+-
+- /// CreateSubprogramDefinition - Create new subprogram descriptor for the
+- /// given declaration.
+- DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration);
+-
+- /// CreateGlobalVariable - Create a new descriptor for the specified global.
+- DIGlobalVariable
+- CreateGlobalVariable(DIDescriptor Context, StringRef Name,
+- StringRef DisplayName,
+- StringRef LinkageName,
+- DIFile F,
+- unsigned LineNo, DIType Ty, bool isLocalToUnit,
+- bool isDefinition, llvm::GlobalVariable *GV);
+-
+- /// CreateGlobalVariable - Create a new descriptor for the specified constant.
+- DIGlobalVariable
+- CreateGlobalVariable(DIDescriptor Context, StringRef Name,
+- StringRef DisplayName,
+- StringRef LinkageName,
+- DIFile F,
+- unsigned LineNo, DIType Ty, bool isLocalToUnit,
+- bool isDefinition, llvm::Constant *C);
+-
+- /// CreateVariable - Create a new descriptor for the specified variable.
+- DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
+- StringRef Name,
+- DIFile F, unsigned LineNo,
+- DIType Ty, bool AlwaysPreserve = false,
+- unsigned Flags = 0);
+-
+- /// CreateComplexVariable - Create a new descriptor for the specified
+- /// variable which has a complex address expression for its address.
+- DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
+- StringRef Name, DIFile F, unsigned LineNo,
+- DIType Ty, Value *const *Addr,
+- unsigned NumAddr);
+-
+- /// CreateLexicalBlock - This creates a descriptor for a lexical block
+- /// with the specified parent context.
+- DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
+- unsigned Line = 0, unsigned Col = 0);
+-
+- /// CreateNameSpace - This creates new descriptor for a namespace
+- /// with the specified parent context.
+- DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
+- DIFile F, unsigned LineNo);
+-
+- /// CreateLocation - Creates a debug info location.
+- DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
+- DIScope S, DILocation OrigLoc);
+-
+- /// CreateLocation - Creates a debug info location.
+- DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
+- DIScope S, MDNode *OrigLoc = 0);
+-
+- /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+- Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
+- BasicBlock *InsertAtEnd);
+-
+- /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+- Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
+- Instruction *InsertBefore);
+-
+- /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
+- DIVariable D, BasicBlock *InsertAtEnd);
+-
+- /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
+- DIVariable D, Instruction *InsertBefore);
+-
+- // RecordType - Record DIType in a module such that it is not lost even if
+- // it is not referenced through debug info anchors.
+- void RecordType(DIType T);
+-
+- private:
+- Constant *GetTagConstant(unsigned TAG);
+-};
+-
+-/// DebugInfo - This class gathers all debug information during compilation and
+-/// is responsible for emitting to llvm globals or pass directly to the backend.
+-class DebugInfo {
+-private:
+- Module *M; // The current module.
+- DIFactory DebugFactory;
+- const char *CurFullPath; // Previous location file encountered.
+- int CurLineNo; // Previous location line# encountered.
+- const char *PrevFullPath; // Previous location file encountered.
+- int PrevLineNo; // Previous location line# encountered.
+- BasicBlock *PrevBB; // Last basic block encountered.
+-
+- DICompileUnit TheCU; // The compile unit.
+-
+- std::map<tree_node *, WeakVH > TypeCache;
+- // Cache of previously constructed
+- // Types.
+- std::map<tree_node *, WeakVH > SPCache;
+- // Cache of previously constructed
+- // Subprograms.
+- std::map<tree_node *, WeakVH> NameSpaceCache;
+- // Cache of previously constructed name
+- // spaces.
+-
+- SmallVector<WeakVH, 4> RegionStack;
+- // Stack to track declarative scopes.
+-
+- std::map<tree_node *, WeakVH> RegionMap;
+-
+- /// FunctionNames - This is a storage for function names that are
+- /// constructed on demand. For example, C++ destructors, C++ operators etc..
+- llvm::BumpPtrAllocator FunctionNames;
+-
+-public:
+- DebugInfo(Module *m);
+-
+- /// Initialize - Initialize debug info by creating compile unit for
+- /// main_input_filename. This must be invoked after language dependent
+- /// initialization is done.
+- void Initialize();
+-
+- // Accessors.
+- void setLocationFile(const char *FullPath) { CurFullPath = FullPath; }
+- void setLocationLine(int LineNo) { CurLineNo = LineNo; }
+-
+- /// EmitFunctionStart - Constructs the debug code for entering a function -
+- /// "llvm.dbg.func.start."
+- void EmitFunctionStart(tree_node *FnDecl, Function *Fn);
+-
+- /// EmitFunctionEnd - Constructs the debug code for exiting a declarative
+- /// region - "llvm.dbg.region.end."
+- void EmitFunctionEnd(bool EndFunction);
+-
+- /// EmitDeclare - Constructs the debug code for allocation of a new variable.
+- /// region - "llvm.dbg.declare."
+- void EmitDeclare(tree_node *decl, unsigned Tag, const char *Name,
+- tree_node *type, Value *AI, LLVMBuilder &Builder);
+-
+- /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
+- /// source line.
+- void EmitStopPoint(BasicBlock *CurBB, LLVMBuilder &Builder);
+-
+- /// EmitGlobalVariable - Emit information about a global variable.
+- ///
+- void EmitGlobalVariable(GlobalVariable *GV, tree_node *decl);
+-
+- /// getOrCreateType - Get the type from the cache or create a new type if
+- /// necessary.
+- DIType getOrCreateType(tree_node *type);
+-
+- /// createBasicType - Create BasicType.
+- DIType createBasicType(tree_node *type);
+-
+- /// createMethodType - Create MethodType.
+- DIType createMethodType(tree_node *type);
+-
+- /// createPointerType - Create PointerType.
+- DIType createPointerType(tree_node *type);
+-
+- /// createArrayType - Create ArrayType.
+- DIType createArrayType(tree_node *type);
+-
+- /// createEnumType - Create EnumType.
+- DIType createEnumType(tree_node *type);
+-
+- /// createStructType - Create StructType for struct or union or class.
+- DIType createStructType(tree_node *type);
+-
+- /// createVarinatType - Create variant type or return MainTy.
+- DIType createVariantType(tree_node *type, DIType MainTy);
+-
+- /// getOrCreateCompileUnit - Create a new compile unit.
+- DICompileUnit getOrCreateCompileUnit(const char *FullPath,
+- bool isMain = false);
+-
+- /// getOrCreateFile - Get DIFile descriptor.
+- DIFile getOrCreateFile(const char *FullPath);
+-
+- /// findRegion - Find tree_node N's region.
+- DIDescriptor findRegion(tree_node *n);
+-
+- /// getOrCreateNameSpace - Get name space descriptor for the tree node.
+- DINameSpace getOrCreateNameSpace(tree_node *Node, DIDescriptor Context);
+-
+- /// getFunctionName - Get function name for the given FnDecl. If the
+- /// name is constructred on demand (e.g. C++ destructor) then the name
+- /// is stored on the side.
+- StringRef getFunctionName(tree_node *FnDecl);
+-};
+-
+-} // end namespace llvm
+-
+-#endif /* DRAGONEGG_DEBUG_H */
+diff -r -u -N dragonegg-2.9-old/DefaultABI.cpp dragonegg-2.9-new/DefaultABI.cpp
+--- dragonegg-2.9-old/DefaultABI.cpp 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/DefaultABI.cpp 2011-04-09 00:38:06.620098051 +0200
+@@ -21,7 +21,7 @@
+ //===----------------------------------------------------------------------===//
+
+ // Plugin headers
+-#include "ABI.h"
++#include "dragonegg/ABI.h"
+
+ // System headers
+ #include <gmp.h>
+diff -r -u -N dragonegg-2.9-old/freebsd/dragonegg/OS.h dragonegg-2.9-new/freebsd/dragonegg/OS.h
+--- dragonegg-2.9-old/freebsd/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/freebsd/dragonegg/OS.h 2011-04-09 00:38:06.620098051 +0200
+@@ -0,0 +1,33 @@
++//===------------ OS.h - FreeBSD specific definitions -----------*- C++ -*-===//
++//
++// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file provides FreeBSD specific declarations.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_OS_H
++#define DRAGONEGG_OS_H
++
++/* Yes, we support PIC codegen for FreeBSD targets! */
++#define LLVM_SET_TARGET_OPTIONS(argvec) \
++ if (flag_pic) \
++ argvec.push_back ("--relocation-model=pic"); \
++ else \
++ argvec.push_back ("--relocation-model=static");
++
++#endif /* DRAGONEGG_OS_H */
+diff -r -u -N dragonegg-2.9-old/freebsd/OS.h dragonegg-2.9-new/freebsd/OS.h
+--- dragonegg-2.9-old/freebsd/OS.h 2011-03-28 17:04:33.000000000 +0200
++++ dragonegg-2.9-new/freebsd/OS.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,33 +0,0 @@
+-//===------------ OS.h - FreeBSD specific definitions -----------*- C++ -*-===//
+-//
+-// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file provides FreeBSD specific declarations.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_OS_H
+-#define DRAGONEGG_OS_H
+-
+-/* Yes, we support PIC codegen for FreeBSD targets! */
+-#define LLVM_SET_TARGET_OPTIONS(argvec) \
+- if (flag_pic) \
+- argvec.push_back ("--relocation-model=pic"); \
+- else \
+- argvec.push_back ("--relocation-model=static");
+-
+-#endif /* DRAGONEGG_OS_H */
+diff -r -u -N dragonegg-2.9-old/gt-cache.h dragonegg-2.9-new/gt-cache.h
+--- dragonegg-2.9-old/gt-cache.h 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/gt-cache.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,802 +0,0 @@
+-/* Type information for GCC.
+- Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.
+-
+-This file is part of GCC.
+-
+-GCC is free software; you can redistribute it and/or modify it under
+-the terms of the GNU General Public License as published by the Free
+-Software Foundation; either version 3, or (at your option) any later
+-version.
+-
+-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+-WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GCC; see the file COPYING3. If not see
+-<http://www.gnu.org/licenses/>. */
+-
+-/* This file is machine generated. Do not edit. */
+-
+-/* GC marker procedures. */
+-/* macros and declarations */
+-#define gt_ggc_m_13tree_llvm_map(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_llvm_map (X);\
+- } while (0)
+-extern void gt_ggc_mx_tree_llvm_map (void *);
+-#define gt_ggc_m_15interface_tuple(X) do { \
+- if (X != NULL) gt_ggc_mx_interface_tuple (X);\
+- } while (0)
+-extern void gt_ggc_mx_interface_tuple (void *);
+-#define gt_ggc_m_16volatilized_type(X) do { \
+- if (X != NULL) gt_ggc_mx_volatilized_type (X);\
+- } while (0)
+-extern void gt_ggc_mx_volatilized_type (void *);
+-#define gt_ggc_m_17string_descriptor(X) do { \
+- if (X != NULL) gt_ggc_mx_string_descriptor (X);\
+- } while (0)
+-extern void gt_ggc_mx_string_descriptor (void *);
+-#define gt_ggc_m_15c_inline_static(X) do { \
+- if (X != NULL) gt_ggc_mx_c_inline_static (X);\
+- } while (0)
+-extern void gt_ggc_mx_c_inline_static (void *);
+-#define gt_ggc_m_24VEC_c_goto_bindings_p_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_c_goto_bindings_p_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_c_goto_bindings_p_gc (void *);
+-#define gt_ggc_m_15c_goto_bindings(X) do { \
+- if (X != NULL) gt_ggc_mx_c_goto_bindings (X);\
+- } while (0)
+-extern void gt_ggc_mx_c_goto_bindings (void *);
+-#define gt_ggc_m_7c_scope(X) do { \
+- if (X != NULL) gt_ggc_mx_c_scope (X);\
+- } while (0)
+-extern void gt_ggc_mx_c_scope (void *);
+-#define gt_ggc_m_9c_binding(X) do { \
+- if (X != NULL) gt_ggc_mx_c_binding (X);\
+- } while (0)
+-extern void gt_ggc_mx_c_binding (void *);
+-#define gt_ggc_m_12c_label_vars(X) do { \
+- if (X != NULL) gt_ggc_mx_c_label_vars (X);\
+- } while (0)
+-extern void gt_ggc_mx_c_label_vars (void *);
+-#define gt_ggc_m_8c_parser(X) do { \
+- if (X != NULL) gt_ggc_mx_c_parser (X);\
+- } while (0)
+-extern void gt_ggc_mx_c_parser (void *);
+-#define gt_ggc_m_9imp_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_imp_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_imp_entry (void *);
+-#define gt_ggc_m_16hashed_attribute(X) do { \
+- if (X != NULL) gt_ggc_mx_hashed_attribute (X);\
+- } while (0)
+-extern void gt_ggc_mx_hashed_attribute (void *);
+-#define gt_ggc_m_12hashed_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_hashed_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_hashed_entry (void *);
+-#define gt_ggc_m_14type_assertion(X) do { \
+- if (X != NULL) gt_ggc_mx_type_assertion (X);\
+- } while (0)
+-extern void gt_ggc_mx_type_assertion (void *);
+-#define gt_ggc_m_18treetreehash_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_treetreehash_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_treetreehash_entry (void *);
+-#define gt_ggc_m_5CPool(X) do { \
+- if (X != NULL) gt_ggc_mx_CPool (X);\
+- } while (0)
+-extern void gt_ggc_mx_CPool (void *);
+-#define gt_ggc_m_3JCF(X) do { \
+- if (X != NULL) gt_ggc_mx_JCF (X);\
+- } while (0)
+-extern void gt_ggc_mx_JCF (void *);
+-#define gt_ggc_m_17module_htab_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_module_htab_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_module_htab_entry (void *);
+-#define gt_ggc_m_13binding_level(X) do { \
+- if (X != NULL) gt_ggc_mx_binding_level (X);\
+- } while (0)
+-extern void gt_ggc_mx_binding_level (void *);
+-#define gt_ggc_m_9opt_stack(X) do { \
+- if (X != NULL) gt_ggc_mx_opt_stack (X);\
+- } while (0)
+-extern void gt_ggc_mx_opt_stack (void *);
+-#define gt_ggc_m_16def_pragma_macro(X) do { \
+- if (X != NULL) gt_ggc_mx_def_pragma_macro (X);\
+- } while (0)
+-extern void gt_ggc_mx_def_pragma_macro (void *);
+-#define gt_ggc_m_22def_pragma_macro_value(X) do { \
+- if (X != NULL) gt_ggc_mx_def_pragma_macro_value (X);\
+- } while (0)
+-extern void gt_ggc_mx_def_pragma_macro_value (void *);
+-#define gt_ggc_m_11align_stack(X) do { \
+- if (X != NULL) gt_ggc_mx_align_stack (X);\
+- } while (0)
+-extern void gt_ggc_mx_align_stack (void *);
+-#define gt_ggc_m_18VEC_tree_gc_vec_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_tree_gc_vec_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_tree_gc_vec_gc (void *);
+-#define gt_ggc_m_19VEC_const_char_p_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_const_char_p_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_const_char_p_gc (void *);
+-#define gt_ggc_m_21pending_abstract_type(X) do { \
+- if (X != NULL) gt_ggc_mx_pending_abstract_type (X);\
+- } while (0)
+-extern void gt_ggc_mx_pending_abstract_type (void *);
+-#define gt_ggc_m_15VEC_tree_int_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_tree_int_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_tree_int_gc (void *);
+-#define gt_ggc_m_9cp_parser(X) do { \
+- if (X != NULL) gt_ggc_mx_cp_parser (X);\
+- } while (0)
+-extern void gt_ggc_mx_cp_parser (void *);
+-#define gt_ggc_m_17cp_parser_context(X) do { \
+- if (X != NULL) gt_ggc_mx_cp_parser_context (X);\
+- } while (0)
+-extern void gt_ggc_mx_cp_parser_context (void *);
+-#define gt_ggc_m_8cp_lexer(X) do { \
+- if (X != NULL) gt_ggc_mx_cp_lexer (X);\
+- } while (0)
+-extern void gt_ggc_mx_cp_lexer (void *);
+-#define gt_ggc_m_10tree_check(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_check (X);\
+- } while (0)
+-extern void gt_ggc_mx_tree_check (void *);
+-#define gt_ggc_m_22VEC_deferred_access_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_deferred_access_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_deferred_access_gc (void *);
+-#define gt_ggc_m_10spec_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_spec_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_spec_entry (void *);
+-#define gt_ggc_m_16pending_template(X) do { \
+- if (X != NULL) gt_ggc_mx_pending_template (X);\
+- } while (0)
+-extern void gt_ggc_mx_pending_template (void *);
+-#define gt_ggc_m_21named_label_use_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_named_label_use_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_named_label_use_entry (void *);
+-#define gt_ggc_m_28VEC_deferred_access_check_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_deferred_access_check_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_deferred_access_check_gc (void *);
+-#define gt_ggc_m_11tinst_level(X) do { \
+- if (X != NULL) gt_ggc_mx_tinst_level (X);\
+- } while (0)
+-extern void gt_ggc_mx_tinst_level (void *);
+-#define gt_ggc_m_18sorted_fields_type(X) do { \
+- if (X != NULL) gt_ggc_mx_sorted_fields_type (X);\
+- } while (0)
+-extern void gt_ggc_mx_sorted_fields_type (void *);
+-#define gt_ggc_m_18VEC_tree_pair_s_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_tree_pair_s_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_tree_pair_s_gc (void *);
+-#define gt_ggc_m_17named_label_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_named_label_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_named_label_entry (void *);
+-#define gt_ggc_m_14cp_token_cache(X) do { \
+- if (X != NULL) gt_ggc_mx_cp_token_cache (X);\
+- } while (0)
+-extern void gt_ggc_mx_cp_token_cache (void *);
+-#define gt_ggc_m_11saved_scope(X) do { \
+- if (X != NULL) gt_ggc_mx_saved_scope (X);\
+- } while (0)
+-extern void gt_ggc_mx_saved_scope (void *);
+-#define gt_ggc_m_16cxx_int_tree_map(X) do { \
+- if (X != NULL) gt_ggc_mx_cxx_int_tree_map (X);\
+- } while (0)
+-extern void gt_ggc_mx_cxx_int_tree_map (void *);
+-#define gt_ggc_m_23VEC_cp_class_binding_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_cp_class_binding_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_cp_class_binding_gc (void *);
+-#define gt_ggc_m_24VEC_cxx_saved_binding_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_cxx_saved_binding_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_cxx_saved_binding_gc (void *);
+-#define gt_ggc_m_16cp_binding_level(X) do { \
+- if (X != NULL) gt_ggc_mx_cp_binding_level (X);\
+- } while (0)
+-extern void gt_ggc_mx_cp_binding_level (void *);
+-#define gt_ggc_m_11cxx_binding(X) do { \
+- if (X != NULL) gt_ggc_mx_cxx_binding (X);\
+- } while (0)
+-extern void gt_ggc_mx_cxx_binding (void *);
+-#define gt_ggc_m_15binding_entry_s(X) do { \
+- if (X != NULL) gt_ggc_mx_binding_entry_s (X);\
+- } while (0)
+-extern void gt_ggc_mx_binding_entry_s (void *);
+-#define gt_ggc_m_15binding_table_s(X) do { \
+- if (X != NULL) gt_ggc_mx_binding_table_s (X);\
+- } while (0)
+-extern void gt_ggc_mx_binding_table_s (void *);
+-#define gt_ggc_m_14VEC_tinfo_s_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_tinfo_s_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_tinfo_s_gc (void *);
+-#define gt_ggc_m_18gnat_binding_level(X) do { \
+- if (X != NULL) gt_ggc_mx_gnat_binding_level (X);\
+- } while (0)
+-extern void gt_ggc_mx_gnat_binding_level (void *);
+-#define gt_ggc_m_9elab_info(X) do { \
+- if (X != NULL) gt_ggc_mx_elab_info (X);\
+- } while (0)
+-extern void gt_ggc_mx_elab_info (void *);
+-#define gt_ggc_m_10stmt_group(X) do { \
+- if (X != NULL) gt_ggc_mx_stmt_group (X);\
+- } while (0)
+-extern void gt_ggc_mx_stmt_group (void *);
+-#define gt_ggc_m_16VEC_parm_attr_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_parm_attr_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_parm_attr_gc (void *);
+-#define gt_ggc_m_11parm_attr_d(X) do { \
+- if (X != NULL) gt_ggc_mx_parm_attr_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_parm_attr_d (void *);
+-#define gt_ggc_m_22VEC_ipa_edge_args_t_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_ipa_edge_args_t_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_ipa_edge_args_t_gc (void *);
+-#define gt_ggc_m_20lto_symtab_entry_def(X) do { \
+- if (X != NULL) gt_ggc_mx_lto_symtab_entry_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_lto_symtab_entry_def (void *);
+-#define gt_ggc_m_20ssa_operand_memory_d(X) do { \
+- if (X != NULL) gt_ggc_mx_ssa_operand_memory_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_ssa_operand_memory_d (void *);
+-#define gt_ggc_m_13scev_info_str(X) do { \
+- if (X != NULL) gt_ggc_mx_scev_info_str (X);\
+- } while (0)
+-extern void gt_ggc_mx_scev_info_str (void *);
+-#define gt_ggc_m_13VEC_gimple_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_gimple_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_gimple_gc (void *);
+-#define gt_ggc_m_9type_hash(X) do { \
+- if (X != NULL) gt_ggc_mx_type_hash (X);\
+- } while (0)
+-extern void gt_ggc_mx_type_hash (void *);
+-#define gt_ggc_m_16string_pool_data(X) do { \
+- if (X != NULL) gt_ggc_mx_string_pool_data (X);\
+- } while (0)
+-extern void gt_ggc_mx_string_pool_data (void *);
+-#define gt_ggc_m_13libfunc_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_libfunc_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_libfunc_entry (void *);
+-#define gt_ggc_m_23temp_slot_address_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_temp_slot_address_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_temp_slot_address_entry (void *);
+-#define gt_ggc_m_15throw_stmt_node(X) do { \
+- if (X != NULL) gt_ggc_mx_throw_stmt_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_throw_stmt_node (void *);
+-#define gt_ggc_m_21VEC_eh_landing_pad_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_eh_landing_pad_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_eh_landing_pad_gc (void *);
+-#define gt_ggc_m_16VEC_eh_region_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_eh_region_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_eh_region_gc (void *);
+-#define gt_ggc_m_10eh_catch_d(X) do { \
+- if (X != NULL) gt_ggc_mx_eh_catch_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_eh_catch_d (void *);
+-#define gt_ggc_m_16eh_landing_pad_d(X) do { \
+- if (X != NULL) gt_ggc_mx_eh_landing_pad_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_eh_landing_pad_d (void *);
+-#define gt_ggc_m_11eh_region_d(X) do { \
+- if (X != NULL) gt_ggc_mx_eh_region_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_eh_region_d (void *);
+-#define gt_ggc_m_10vcall_insn(X) do { \
+- if (X != NULL) gt_ggc_mx_vcall_insn (X);\
+- } while (0)
+-extern void gt_ggc_mx_vcall_insn (void *);
+-#define gt_ggc_m_18VEC_vcall_entry_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_vcall_entry_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_vcall_entry_gc (void *);
+-#define gt_ggc_m_18VEC_dcall_entry_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_dcall_entry_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_dcall_entry_gc (void *);
+-#define gt_ggc_m_16var_loc_list_def(X) do { \
+- if (X != NULL) gt_ggc_mx_var_loc_list_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_var_loc_list_def (void *);
+-#define gt_ggc_m_12var_loc_node(X) do { \
+- if (X != NULL) gt_ggc_mx_var_loc_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_var_loc_node (void *);
+-#define gt_ggc_m_20VEC_die_arg_entry_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_die_arg_entry_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_die_arg_entry_gc (void *);
+-#define gt_ggc_m_16limbo_die_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_limbo_die_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_limbo_die_struct (void *);
+-#define gt_ggc_m_20VEC_pubname_entry_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_pubname_entry_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_pubname_entry_gc (void *);
+-#define gt_ggc_m_19VEC_dw_attr_node_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_dw_attr_node_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_dw_attr_node_gc (void *);
+-#define gt_ggc_m_18comdat_type_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_comdat_type_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_comdat_type_struct (void *);
+-#define gt_ggc_m_25dw_ranges_by_label_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_ranges_by_label_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_ranges_by_label_struct (void *);
+-#define gt_ggc_m_16dw_ranges_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_ranges_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_ranges_struct (void *);
+-#define gt_ggc_m_28dw_separate_line_info_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_separate_line_info_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_separate_line_info_struct (void *);
+-#define gt_ggc_m_19dw_line_info_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_line_info_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_line_info_struct (void *);
+-#define gt_ggc_m_25VEC_deferred_locations_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_deferred_locations_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_deferred_locations_gc (void *);
+-#define gt_ggc_m_18dw_loc_list_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_loc_list_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_loc_list_struct (void *);
+-#define gt_ggc_m_15dwarf_file_data(X) do { \
+- if (X != NULL) gt_ggc_mx_dwarf_file_data (X);\
+- } while (0)
+-extern void gt_ggc_mx_dwarf_file_data (void *);
+-#define gt_ggc_m_15queued_reg_save(X) do { \
+- if (X != NULL) gt_ggc_mx_queued_reg_save (X);\
+- } while (0)
+-extern void gt_ggc_mx_queued_reg_save (void *);
+-#define gt_ggc_m_20indirect_string_node(X) do { \
+- if (X != NULL) gt_ggc_mx_indirect_string_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_indirect_string_node (void *);
+-#define gt_ggc_m_19dw_loc_descr_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_loc_descr_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_loc_descr_struct (void *);
+-#define gt_ggc_m_13dw_fde_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_fde_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_fde_struct (void *);
+-#define gt_ggc_m_13dw_cfi_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_dw_cfi_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_dw_cfi_struct (void *);
+-#define gt_ggc_m_8typeinfo(X) do { \
+- if (X != NULL) gt_ggc_mx_typeinfo (X);\
+- } while (0)
+-extern void gt_ggc_mx_typeinfo (void *);
+-#define gt_ggc_m_22VEC_alias_set_entry_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_alias_set_entry_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_alias_set_entry_gc (void *);
+-#define gt_ggc_m_17alias_set_entry_d(X) do { \
+- if (X != NULL) gt_ggc_mx_alias_set_entry_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_alias_set_entry_d (void *);
+-#define gt_ggc_m_24constant_descriptor_tree(X) do { \
+- if (X != NULL) gt_ggc_mx_constant_descriptor_tree (X);\
+- } while (0)
+-extern void gt_ggc_mx_constant_descriptor_tree (void *);
+-#define gt_ggc_m_15cgraph_asm_node(X) do { \
+- if (X != NULL) gt_ggc_mx_cgraph_asm_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_cgraph_asm_node (void *);
+-#define gt_ggc_m_12varpool_node(X) do { \
+- if (X != NULL) gt_ggc_mx_varpool_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_varpool_node (void *);
+-#define gt_ggc_m_22VEC_cgraph_node_set_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_cgraph_node_set_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_cgraph_node_set_gc (void *);
+-#define gt_ggc_m_19cgraph_node_set_def(X) do { \
+- if (X != NULL) gt_ggc_mx_cgraph_node_set_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_cgraph_node_set_def (void *);
+-#define gt_ggc_m_27cgraph_node_set_element_def(X) do { \
+- if (X != NULL) gt_ggc_mx_cgraph_node_set_element_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_cgraph_node_set_element_def (void *);
+-#define gt_ggc_m_22VEC_cgraph_node_ptr_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_cgraph_node_ptr_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_cgraph_node_ptr_gc (void *);
+-#define gt_ggc_m_11cgraph_edge(X) do { \
+- if (X != NULL) gt_ggc_mx_cgraph_edge (X);\
+- } while (0)
+-extern void gt_ggc_mx_cgraph_edge (void *);
+-#define gt_ggc_m_24VEC_ipa_replace_map_p_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_ipa_replace_map_p_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_ipa_replace_map_p_gc (void *);
+-#define gt_ggc_m_15ipa_replace_map(X) do { \
+- if (X != NULL) gt_ggc_mx_ipa_replace_map (X);\
+- } while (0)
+-extern void gt_ggc_mx_ipa_replace_map (void *);
+-#define gt_ggc_m_11cgraph_node(X) do { \
+- if (X != NULL) gt_ggc_mx_cgraph_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_cgraph_node (void *);
+-#define gt_ggc_m_18VEC_basic_block_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_basic_block_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_basic_block_gc (void *);
+-#define gt_ggc_m_14gimple_bb_info(X) do { \
+- if (X != NULL) gt_ggc_mx_gimple_bb_info (X);\
+- } while (0)
+-extern void gt_ggc_mx_gimple_bb_info (void *);
+-#define gt_ggc_m_11rtl_bb_info(X) do { \
+- if (X != NULL) gt_ggc_mx_rtl_bb_info (X);\
+- } while (0)
+-extern void gt_ggc_mx_rtl_bb_info (void *);
+-#define gt_ggc_m_11VEC_edge_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_edge_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_edge_gc (void *);
+-#define gt_ggc_m_17cselib_val_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_cselib_val_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_cselib_val_struct (void *);
+-#define gt_ggc_m_12elt_loc_list(X) do { \
+- if (X != NULL) gt_ggc_mx_elt_loc_list (X);\
+- } while (0)
+-extern void gt_ggc_mx_elt_loc_list (void *);
+-#define gt_ggc_m_13VEC_loop_p_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_loop_p_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_loop_p_gc (void *);
+-#define gt_ggc_m_4loop(X) do { \
+- if (X != NULL) gt_ggc_mx_loop (X);\
+- } while (0)
+-extern void gt_ggc_mx_loop (void *);
+-#define gt_ggc_m_9loop_exit(X) do { \
+- if (X != NULL) gt_ggc_mx_loop_exit (X);\
+- } while (0)
+-extern void gt_ggc_mx_loop_exit (void *);
+-#define gt_ggc_m_13nb_iter_bound(X) do { \
+- if (X != NULL) gt_ggc_mx_nb_iter_bound (X);\
+- } while (0)
+-extern void gt_ggc_mx_nb_iter_bound (void *);
+-#define gt_ggc_m_24types_used_by_vars_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_types_used_by_vars_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_types_used_by_vars_entry (void *);
+-#define gt_ggc_m_17language_function(X) do { \
+- if (X != NULL) gt_ggc_mx_language_function (X);\
+- } while (0)
+-extern void gt_ggc_mx_language_function (void *);
+-#define gt_ggc_m_5loops(X) do { \
+- if (X != NULL) gt_ggc_mx_loops (X);\
+- } while (0)
+-extern void gt_ggc_mx_loops (void *);
+-#define gt_ggc_m_18control_flow_graph(X) do { \
+- if (X != NULL) gt_ggc_mx_control_flow_graph (X);\
+- } while (0)
+-extern void gt_ggc_mx_control_flow_graph (void *);
+-#define gt_ggc_m_9eh_status(X) do { \
+- if (X != NULL) gt_ggc_mx_eh_status (X);\
+- } while (0)
+-extern void gt_ggc_mx_eh_status (void *);
+-#define gt_ggc_m_20initial_value_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_initial_value_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_initial_value_struct (void *);
+-#define gt_ggc_m_17rtx_constant_pool(X) do { \
+- if (X != NULL) gt_ggc_mx_rtx_constant_pool (X);\
+- } while (0)
+-extern void gt_ggc_mx_rtx_constant_pool (void *);
+-#define gt_ggc_m_18VEC_temp_slot_p_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_temp_slot_p_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_temp_slot_p_gc (void *);
+-#define gt_ggc_m_9temp_slot(X) do { \
+- if (X != NULL) gt_ggc_mx_temp_slot (X);\
+- } while (0)
+-extern void gt_ggc_mx_temp_slot (void *);
+-#define gt_ggc_m_9gimple_df(X) do { \
+- if (X != NULL) gt_ggc_mx_gimple_df (X);\
+- } while (0)
+-extern void gt_ggc_mx_gimple_df (void *);
+-#define gt_ggc_m_23VEC_call_site_record_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_call_site_record_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_call_site_record_gc (void *);
+-#define gt_ggc_m_18call_site_record_d(X) do { \
+- if (X != NULL) gt_ggc_mx_call_site_record_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_call_site_record_d (void *);
+-#define gt_ggc_m_14sequence_stack(X) do { \
+- if (X != NULL) gt_ggc_mx_sequence_stack (X);\
+- } while (0)
+-extern void gt_ggc_mx_sequence_stack (void *);
+-#define gt_ggc_m_8elt_list(X) do { \
+- if (X != NULL) gt_ggc_mx_elt_list (X);\
+- } while (0)
+-extern void gt_ggc_mx_elt_list (void *);
+-#define gt_ggc_m_17tree_priority_map(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_priority_map (X);\
+- } while (0)
+-extern void gt_ggc_mx_tree_priority_map (void *);
+-#define gt_ggc_m_12tree_int_map(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_int_map (X);\
+- } while (0)
+-extern void gt_ggc_mx_tree_int_map (void *);
+-#define gt_ggc_m_8tree_map(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_map (X);\
+- } while (0)
+-extern void gt_ggc_mx_tree_map (void *);
+-#define gt_ggc_m_14lang_tree_node(X) do { \
+- if (X != NULL) gt_ggc_mx_lang_tree_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_lang_tree_node (void *);
+-#define gt_ggc_m_24tree_statement_list_node(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_statement_list_node (X);\
+- } while (0)
+-extern void gt_ggc_mx_tree_statement_list_node (void *);
+-#define gt_ggc_m_9lang_decl(X) do { \
+- if (X != NULL) gt_ggc_mx_lang_decl (X);\
+- } while (0)
+-extern void gt_ggc_mx_lang_decl (void *);
+-#define gt_ggc_m_9lang_type(X) do { \
+- if (X != NULL) gt_ggc_mx_lang_type (X);\
+- } while (0)
+-extern void gt_ggc_mx_lang_type (void *);
+-#define gt_ggc_m_10die_struct(X) do { \
+- if (X != NULL) gt_ggc_mx_die_struct (X);\
+- } while (0)
+-extern void gt_ggc_mx_die_struct (void *);
+-#define gt_ggc_m_15varray_head_tag(X) do { \
+- if (X != NULL) gt_ggc_mx_varray_head_tag (X);\
+- } while (0)
+-extern void gt_ggc_mx_varray_head_tag (void *);
+-#define gt_ggc_m_12ptr_info_def(X) do { \
+- if (X != NULL) gt_ggc_mx_ptr_info_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_ptr_info_def (void *);
+-#define gt_ggc_m_22VEC_constructor_elt_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_constructor_elt_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_constructor_elt_gc (void *);
+-#define gt_ggc_m_10tree_ann_d(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_ann_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_tree_ann_d (void *);
+-#define gt_ggc_m_17VEC_alias_pair_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_alias_pair_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_alias_pair_gc (void *);
+-#define gt_ggc_m_11VEC_tree_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_tree_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_tree_gc (void *);
+-#define gt_ggc_m_12VEC_uchar_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_uchar_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_uchar_gc (void *);
+-#define gt_ggc_m_8function(X) do { \
+- if (X != NULL) gt_ggc_mx_function (X);\
+- } while (0)
+-extern void gt_ggc_mx_function (void *);
+-#define gt_ggc_m_23constant_descriptor_rtx(X) do { \
+- if (X != NULL) gt_ggc_mx_constant_descriptor_rtx (X);\
+- } while (0)
+-extern void gt_ggc_mx_constant_descriptor_rtx (void *);
+-#define gt_ggc_m_11fixed_value(X) do { \
+- if (X != NULL) gt_ggc_mx_fixed_value (X);\
+- } while (0)
+-extern void gt_ggc_mx_fixed_value (void *);
+-#define gt_ggc_m_10real_value(X) do { \
+- if (X != NULL) gt_ggc_mx_real_value (X);\
+- } while (0)
+-extern void gt_ggc_mx_real_value (void *);
+-#define gt_ggc_m_10VEC_rtx_gc(X) do { \
+- if (X != NULL) gt_ggc_mx_VEC_rtx_gc (X);\
+- } while (0)
+-extern void gt_ggc_mx_VEC_rtx_gc (void *);
+-#define gt_ggc_m_12object_block(X) do { \
+- if (X != NULL) gt_ggc_mx_object_block (X);\
+- } while (0)
+-extern void gt_ggc_mx_object_block (void *);
+-#define gt_ggc_m_9reg_attrs(X) do { \
+- if (X != NULL) gt_ggc_mx_reg_attrs (X);\
+- } while (0)
+-extern void gt_ggc_mx_reg_attrs (void *);
+-#define gt_ggc_m_9mem_attrs(X) do { \
+- if (X != NULL) gt_ggc_mx_mem_attrs (X);\
+- } while (0)
+-extern void gt_ggc_mx_mem_attrs (void *);
+-#define gt_ggc_m_14bitmap_obstack(X) do { \
+- if (X != NULL) gt_ggc_mx_bitmap_obstack (X);\
+- } while (0)
+-extern void gt_ggc_mx_bitmap_obstack (void *);
+-#define gt_ggc_m_18bitmap_element_def(X) do { \
+- if (X != NULL) gt_ggc_mx_bitmap_element_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_bitmap_element_def (void *);
+-#define gt_ggc_m_16machine_function(X) do { \
+- if (X != NULL) gt_ggc_mx_machine_function (X);\
+- } while (0)
+-extern void gt_ggc_mx_machine_function (void *);
+-#define gt_ggc_m_17stack_local_entry(X) do { \
+- if (X != NULL) gt_ggc_mx_stack_local_entry (X);\
+- } while (0)
+-extern void gt_ggc_mx_stack_local_entry (void *);
+-#define gt_ggc_m_15basic_block_def(X) do { \
+- if (X != NULL) gt_ggc_mx_basic_block_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_basic_block_def (void *);
+-#define gt_ggc_m_8edge_def(X) do { \
+- if (X != NULL) gt_ggc_mx_edge_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_edge_def (void *);
+-#define gt_ggc_m_17gimple_seq_node_d(X) do { \
+- if (X != NULL) gt_ggc_mx_gimple_seq_node_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_gimple_seq_node_d (void *);
+-#define gt_ggc_m_12gimple_seq_d(X) do { \
+- if (X != NULL) gt_ggc_mx_gimple_seq_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_gimple_seq_d (void *);
+-#define gt_ggc_m_7section(X) do { \
+- if (X != NULL) gt_ggc_mx_section (X);\
+- } while (0)
+-extern void gt_ggc_mx_section (void *);
+-#define gt_ggc_m_18gimple_statement_d(X) do { \
+- if (X != NULL) gt_ggc_mx_gimple_statement_d (X);\
+- } while (0)
+-extern void gt_ggc_mx_gimple_statement_d (void *);
+-#define gt_ggc_m_9rtvec_def(X) do { \
+- if (X != NULL) gt_ggc_mx_rtvec_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_rtvec_def (void *);
+-#define gt_ggc_m_7rtx_def(X) do { \
+- if (X != NULL) gt_ggc_mx_rtx_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_rtx_def (void *);
+-#define gt_ggc_m_15bitmap_head_def(X) do { \
+- if (X != NULL) gt_ggc_mx_bitmap_head_def (X);\
+- } while (0)
+-extern void gt_ggc_mx_bitmap_head_def (void *);
+-#define gt_ggc_m_9tree_node(X) do { \
+- if (X != NULL) gt_ggc_mx_tree_node (X);\
+- } while (0)
+-#define gt_ggc_mx_tree_node gt_ggc_mx_lang_tree_node
+-#define gt_ggc_m_6answer(X) do { \
+- if (X != NULL) gt_ggc_mx_answer (X);\
+- } while (0)
+-extern void gt_ggc_mx_answer (void *);
+-#define gt_ggc_m_9cpp_macro(X) do { \
+- if (X != NULL) gt_ggc_mx_cpp_macro (X);\
+- } while (0)
+-extern void gt_ggc_mx_cpp_macro (void *);
+-#define gt_ggc_m_9cpp_token(X) do { \
+- if (X != NULL) gt_ggc_mx_cpp_token (X);\
+- } while (0)
+-extern void gt_ggc_mx_cpp_token (void *);
+-#define gt_ggc_m_9line_maps(X) do { \
+- if (X != NULL) gt_ggc_mx_line_maps (X);\
+- } while (0)
+-extern void gt_ggc_mx_line_maps (void *);
+-extern void gt_ggc_m_II17splay_tree_node_s (void *);
+-extern void gt_ggc_m_SP9tree_node17splay_tree_node_s (void *);
+-extern void gt_ggc_m_P9tree_nodeP9tree_node17splay_tree_node_s (void *);
+-extern void gt_ggc_m_IP9tree_node17splay_tree_node_s (void *);
+-extern void gt_ggc_m_P13tree_llvm_map4htab (void *);
+-extern void gt_ggc_m_P15interface_tuple4htab (void *);
+-extern void gt_ggc_m_P16volatilized_type4htab (void *);
+-extern void gt_ggc_m_P17string_descriptor4htab (void *);
+-extern void gt_ggc_m_P14type_assertion4htab (void *);
+-extern void gt_ggc_m_P18treetreehash_entry4htab (void *);
+-extern void gt_ggc_m_P17module_htab_entry4htab (void *);
+-extern void gt_ggc_m_P16def_pragma_macro4htab (void *);
+-extern void gt_ggc_m_P21pending_abstract_type4htab (void *);
+-extern void gt_ggc_m_P10spec_entry4htab (void *);
+-extern void gt_ggc_m_P16cxx_int_tree_map4htab (void *);
+-extern void gt_ggc_m_P17named_label_entry4htab (void *);
+-extern void gt_ggc_m_P12tree_int_map4htab (void *);
+-extern void gt_ggc_m_P20lto_symtab_entry_def4htab (void *);
+-extern void gt_ggc_m_IP9tree_node12splay_tree_s (void *);
+-extern void gt_ggc_m_P9tree_nodeP9tree_node12splay_tree_s (void *);
+-extern void gt_ggc_m_P12varpool_node4htab (void *);
+-extern void gt_ggc_m_P13scev_info_str4htab (void *);
+-extern void gt_ggc_m_P23constant_descriptor_rtx4htab (void *);
+-extern void gt_ggc_m_P24constant_descriptor_tree4htab (void *);
+-extern void gt_ggc_m_P12object_block4htab (void *);
+-extern void gt_ggc_m_P7section4htab (void *);
+-extern void gt_ggc_m_P17tree_priority_map4htab (void *);
+-extern void gt_ggc_m_P8tree_map4htab (void *);
+-extern void gt_ggc_m_P9type_hash4htab (void *);
+-extern void gt_ggc_m_P13libfunc_entry4htab (void *);
+-extern void gt_ggc_m_P23temp_slot_address_entry4htab (void *);
+-extern void gt_ggc_m_P15throw_stmt_node4htab (void *);
+-extern void gt_ggc_m_P9reg_attrs4htab (void *);
+-extern void gt_ggc_m_P9mem_attrs4htab (void *);
+-extern void gt_ggc_m_P7rtx_def4htab (void *);
+-extern void gt_ggc_m_SP9tree_node12splay_tree_s (void *);
+-extern void gt_ggc_m_P10vcall_insn4htab (void *);
+-extern void gt_ggc_m_P16var_loc_list_def4htab (void *);
+-extern void gt_ggc_m_P10die_struct4htab (void *);
+-extern void gt_ggc_m_P15dwarf_file_data4htab (void *);
+-extern void gt_ggc_m_P20indirect_string_node4htab (void *);
+-extern void gt_ggc_m_P11cgraph_node4htab (void *);
+-extern void gt_ggc_m_II12splay_tree_s (void *);
+-extern void gt_ggc_m_P27cgraph_node_set_element_def4htab (void *);
+-extern void gt_ggc_m_P11cgraph_edge4htab (void *);
+-extern void gt_ggc_m_P9loop_exit4htab (void *);
+-extern void gt_ggc_m_P24types_used_by_vars_entry4htab (void *);
+-extern void gt_ggc_m_P9tree_node4htab (void *);
+-
+-/* functions code */
+-
+-void
+-gt_ggc_mx_tree_llvm_map (void *x_p)
+-{
+- struct tree_llvm_map * const x = (struct tree_llvm_map *)x_p;
+- if (ggc_test_and_set_mark (x))
+- {
+- gt_ggc_m_9tree_node ((*x).base.from);
+- }
+-}
+-
+-void
+-gt_ggc_m_P13tree_llvm_map4htab (void *x_p)
+-{
+- struct htab * const x = (struct htab *)x_p;
+- if (ggc_test_and_set_mark (x))
+- {
+- if ((*x).entries != NULL) {
+- size_t i0;
+- for (i0 = 0; i0 != (size_t)(((*x)).size); i0++) {
+- gt_ggc_m_13tree_llvm_map ((*x).entries[i0]);
+- }
+- ggc_mark ((*x).entries);
+- }
+- }
+-}
+-
+-/* GC roots. */
+-
+-EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc__gt_llvm_cache_h[] = {
+- {
+- &llvm_cache,
+- 1,
+- sizeof (llvm_cache),
+- >_ggc_mx_tree_llvm_map,
+- NULL,
+- &tree_llvm_map_marked_p
+- },
+- LAST_GGC_CACHE_TAB
+-};
+-
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/ABI.h dragonegg-2.9-new/include/dragonegg/ABI.h
+--- dragonegg-2.9-old/include/dragonegg/ABI.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/ABI.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,351 @@
++//===--------- ABI.h - Processor ABI customization hooks --------*- C++ -*-===//
++//
++// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
++// Duncan Sands et al.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file specifies how argument values are passed and returned from function
++// calls. This allows the target to specialize handling of things like how
++// structures are passed by-value.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_ABI_H
++#define DRAGONEGG_ABI_H
++
++// Plugin headers
++#include "dragonegg/Internals.h"
++#include "dragonegg/Target.h"
++
++// LLVM headers
++#include "llvm/LLVMContext.h"
++#include "llvm/Target/TargetData.h"
++
++namespace llvm {
++ class BasicBlock;
++}
++
++/// DefaultABIClient - This is a simple implementation of the ABI client
++/// interface that can be subclassed.
++struct DefaultABIClient {
++ virtual ~DefaultABIClient() {}
++ virtual CallingConv::ID& getCallingConv(void) = 0;
++ virtual bool isShadowReturn() const { return false; }
++
++ /// HandleScalarResult - This callback is invoked if the function returns a
++ /// simple scalar result value, which is of type RetTy.
++ virtual void HandleScalarResult(const Type * /*RetTy*/) {}
++
++ /// HandleAggregateResultAsScalar - This callback is invoked if the function
++ /// returns an aggregate value by bit converting it to the specified scalar
++ /// type and returning that. The bit conversion should start at byte Offset
++ /// within the struct, and ScalarTy is not necessarily big enough to cover
++ /// the entire struct.
++ virtual void HandleAggregateResultAsScalar(const Type * /*ScalarTy*/,
++ unsigned /*Offset*/ = 0) {}
++
++ /// HandleAggregateResultAsAggregate - This callback is invoked if the function
++ /// returns an aggregate value using multiple return values.
++ virtual void HandleAggregateResultAsAggregate(const Type * /*AggrTy*/) {}
++
++ /// HandleAggregateShadowResult - This callback is invoked if the function
++ /// returns an aggregate value by using a "shadow" first parameter, which is
++ /// a pointer to the aggregate, of type PtrArgTy. If RetPtr is set to true,
++ /// the pointer argument itself is returned from the function.
++ virtual void HandleAggregateShadowResult(const PointerType * /*PtrArgTy*/,
++ bool /*RetPtr*/) {}
++
++ /// HandleScalarShadowResult - This callback is invoked if the function
++ /// returns a scalar value by using a "shadow" first parameter, which is a
++ /// pointer to the scalar, of type PtrArgTy. If RetPtr is set to true,
++ /// the pointer argument itself is returned from the function.
++ virtual void HandleScalarShadowResult(const PointerType * /*PtrArgTy*/,
++ bool /*RetPtr*/) {}
++
++
++ /// HandleScalarArgument - This is the primary callback that specifies an
++ /// LLVM argument to pass. It is only used for first class types.
++ /// If RealSize is non Zero then it specifies number of bytes to access
++ /// from LLVMTy.
++ virtual void HandleScalarArgument(const llvm::Type * /*LLVMTy*/,
++ tree_node * /*type*/,
++ unsigned /*RealSize*/ = 0) {}
++
++ /// HandleByInvisibleReferenceArgument - This callback is invoked if a pointer
++ /// (of type PtrTy) to the argument is passed rather than the argument itself.
++ virtual void HandleByInvisibleReferenceArgument(const llvm::Type * /*PtrTy*/,
++ tree_node * /*type*/) {}
++
++ /// HandleByValArgument - This callback is invoked if the aggregate function
++ /// argument is passed by value.
++ virtual void HandleByValArgument(const llvm::Type * /*LLVMTy*/,
++ tree_node * /*type*/) {}
++
++ /// HandleFCAArgument - This callback is invoked if the aggregate function
++ /// argument is passed by value as a first class aggregate.
++ virtual void HandleFCAArgument(const llvm::Type * /*LLVMTy*/,
++ tree_node * /*type*/) {}
++
++ /// EnterField - Called when we're about the enter the field of a struct
++ /// or union. FieldNo is the number of the element we are entering in the
++ /// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
++ virtual void EnterField(unsigned /*FieldNo*/,
++ const llvm::Type * /*StructTy*/) {}
++ virtual void ExitField() {}
++ virtual void HandlePad(const llvm::Type * /*LLVMTy*/) {}
++};
++
++// LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
++// special _Complex handling. Return true if X should be returned using
++// multiple value return instruction.
++#ifndef LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY
++#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
++ false
++#endif
++
++// LLVM_SHOULD_NOT_USE_SHADOW_RETURN - A hook to allow aggregates to be
++// returned in registers.
++#ifndef LLVM_SHOULD_NOT_USE_SHADOW_RETURN
++#define LLVM_SHOULD_NOT_USE_SHADOW_RETURN(X, CC) \
++ false
++#endif
++
++// doNotUseShadowReturn - Return true if the specified GCC type
++// should not be returned using a pointer to struct parameter.
++extern bool doNotUseShadowReturn(tree_node *type, tree_node *fndecl,
++ CallingConv::ID CC);
++
++/// isSingleElementStructOrArray - If this is (recursively) a structure with one
++/// field or an array with one element, return the field type, otherwise return
++/// null. Returns null for complex number types. If ignoreZeroLength, the
++/// struct (recursively) may include zero-length fields in addition to the
++/// single element that has data. If rejectFatBitField, and the single element
++/// is a bitfield of a type that's bigger than the struct, return null anyway.
++extern tree_node *isSingleElementStructOrArray(tree_node *type,
++ bool ignoreZeroLength,
++ bool rejectFatBitfield);
++
++/// isZeroSizedStructOrUnion - Returns true if this is a struct or union
++/// which is zero bits wide.
++extern bool isZeroSizedStructOrUnion(tree_node *type);
++
++// getLLVMScalarTypeForStructReturn - Return LLVM Type if TY can be
++// returned as a scalar, otherwise return NULL. This is the default
++// target independent implementation.
++static inline
++const Type* getLLVMScalarTypeForStructReturn(tree_node *type, unsigned *Offset) {
++ const Type *Ty = ConvertType(type);
++ unsigned Size = getTargetData().getTypeAllocSize(Ty);
++ *Offset = 0;
++ if (Size == 0)
++ return Type::getVoidTy(getGlobalContext());
++ else if (Size == 1)
++ return Type::getInt8Ty(getGlobalContext());
++ else if (Size == 2)
++ return Type::getInt16Ty(getGlobalContext());
++ else if (Size <= 4)
++ return Type::getInt32Ty(getGlobalContext());
++ else if (Size <= 8)
++ return Type::getInt64Ty(getGlobalContext());
++ else if (Size <= 16)
++ return IntegerType::get(getGlobalContext(), 128);
++ else if (Size <= 32)
++ return IntegerType::get(getGlobalContext(), 256);
++
++ return NULL;
++}
++
++// getLLVMAggregateTypeForStructReturn - Return LLVM type if TY can be
++// returns as multiple values, otherwise return NULL. This is the default
++// target independent implementation.
++static inline
++const Type* getLLVMAggregateTypeForStructReturn(tree_node * /*type*/) {
++ return NULL;
++}
++
++#ifndef LLVM_TRY_PASS_AGGREGATE_CUSTOM
++#define LLVM_TRY_PASS_AGGREGATE_CUSTOM(T, E, CC, C) \
++ false
++#endif
++
++// LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS - Return true if this vector
++// type should be passed as integer registers. Generally vectors which are
++// not part of the target architecture should do this.
++#ifndef LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS
++#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(TY) \
++ false
++#endif
++
++// LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR - Return true if this vector
++// type should be passed byval. Used for generic vectors on x86-64.
++#ifndef LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR
++#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
++ false
++#endif
++
++// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate
++// value should be passed by value, i.e. passing its address with the byval
++// attribute bit set. The default is false.
++#ifndef LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR
++#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
++ false
++#endif
++
++// LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if this aggregate value
++// should be passed by value as a first class aggregate. The default is false.
++#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
++#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
++ false
++#endif
++
++// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS - Return true if this aggregate
++// value should be passed in a mixture of integer, floating point, and vector
++// registers. The routine should also return by reference a vector of the
++// types of the registers being used. The default is false.
++#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS
++#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
++ false
++#endif
++
++// LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS - Only called if
++// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS returns true. This returns true if
++// there are only enough unused argument passing registers to pass a part of
++// the aggregate. Note, this routine should return false if none of the needed
++// registers are available.
++#ifndef LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS
++#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
++ false
++#endif
++
++// LLVM_BYVAL_ALIGNMENT - Returns the alignment of the type in bytes, if known,
++// in the getGlobalContext() of its use as a function parameter.
++// Note that the alignment in the TYPE node is usually the alignment appropriate
++// when the type is used within a struct, which may or may not be appropriate
++// here.
++#ifndef LLVM_BYVAL_ALIGNMENT
++#define LLVM_BYVAL_ALIGNMENT(T) 0
++#endif
++
++// LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
++// value should be passed in integer registers. By default, we do this for all
++// values that are not single-element structs. This ensures that things like
++// {short,short} are passed in one 32-bit chunk, not as two arguments (which
++// would often be 64-bits). We also do it for single-element structs when the
++// single element is a bitfield of a type bigger than the struct; the code
++// for field-by-field struct passing does not handle this one right.
++#ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
++#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
++ !isSingleElementStructOrArray((X), false, true)
++#endif
++
++// LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR - Return a TYPE tree if this single
++// element struct should be returned using the convention for that scalar TYPE,
++// 0 otherwise.
++// The returned TYPE must be the same size as X for this to work; that is
++// checked elsewhere. (Structs where this is not the case can be constructed
++// by abusing the __aligned__ attribute.)
++#ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
++#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
++ isSingleElementStructOrArray(X, false, false)
++#endif
++
++// LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR - Return a TYPE tree if this vector type
++// should be returned using the convention for that scalar TYPE, 0 otherwise.
++// X may be evaluated more than once.
++#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR
++#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,Y) 0
++#endif
++
++// LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW - Return true if this vector type
++// should be returned using the aggregate shadow (sret) convention, 0 otherwise.
++// X may be evaluated more than once.
++#ifndef LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW
++#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,Y) 0
++#endif
++
++// LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
++// returned as a scalar, otherwise return NULL.
++#ifndef LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN
++#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
++ getLLVMScalarTypeForStructReturn((X), (Y))
++#endif
++
++// LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
++// returned as an aggregate, otherwise return NULL.
++#ifndef LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
++#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
++ getLLVMAggregateTypeForStructReturn(X)
++#endif
++
++// LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
++// SRC and assign it to DEST. Each target that supports multiple return
++// value must implement this hook.
++#ifndef LLVM_EXTRACT_MULTIPLE_RETURN_VALUE
++#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
++ llvm_default_extract_multiple_return_value((Src),(Dest),(V),(B))
++#endif
++static inline
++void llvm_default_extract_multiple_return_value(Value * /*Src*/, Value * /*Dest*/,
++ bool /*isVolatile*/,
++ LLVMBuilder &/*Builder*/) {
++ assert (0 && "LLVM_EXTRACT_MULTIPLE_RETURN_VALUE is not implemented!");
++}
++
++/// DefaultABI - This class implements the default LLVM ABI where structures are
++/// passed by decimating them into individual components and unions are passed
++/// by passing the largest member of the union.
++///
++class DefaultABI {
++protected:
++ DefaultABIClient &C;
++public:
++ DefaultABI(DefaultABIClient &c);
++
++ bool isShadowReturn() const;
++
++ /// HandleReturnType - This is invoked by the target-independent code for the
++ /// return type. It potentially breaks down the argument and invokes methods
++ /// on the client that indicate how its pieces should be handled. This
++ /// handles things like returning structures via hidden parameters.
++ void HandleReturnType(tree_node *type, tree_node *fn, bool isBuiltin);
++
++ /// HandleArgument - This is invoked by the target-independent code for each
++ /// argument type passed into the function. It potentially breaks down the
++ /// argument and invokes methods on the client that indicate how its pieces
++ /// should be handled. This handles things like decimating structures into
++ /// their fields.
++ void HandleArgument(tree_node *type, std::vector<const Type*> &ScalarElts,
++ Attributes *Attributes = NULL);
++
++ /// HandleUnion - Handle a UNION_TYPE or QUAL_UNION_TYPE tree.
++ ///
++ void HandleUnion(tree_node *type, std::vector<const Type*> &ScalarElts);
++
++ /// PassInIntegerRegisters - Given an aggregate value that should be passed in
++ /// integer registers, convert it to a structure containing ints and pass all
++ /// of the struct elements in. If Size is set we pass only that many bytes.
++ void PassInIntegerRegisters(tree_node *type,
++ std::vector<const Type*> &ScalarElts,
++ unsigned origSize, bool DontCheckAlignment);
++
++ /// PassInMixedRegisters - Given an aggregate value that should be passed in
++ /// mixed integer, floating point, and vector registers, convert it to a
++ /// structure containing the specified struct elements in.
++ void PassInMixedRegisters(const Type *Ty, std::vector<const Type*> &OrigElts,
++ std::vector<const Type*> &ScalarElts);
++};
++
++#endif /* DRAGONEGG_ABI_H */
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/ADT/IntervalList.h dragonegg-2.9-new/include/dragonegg/ADT/IntervalList.h
+--- dragonegg-2.9-old/include/dragonegg/ADT/IntervalList.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/ADT/IntervalList.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,218 @@
++//=--------- IntervalList.h - List of disjoint intervals ----------*- C++ -*-=//
++//
++// Copyright (C) 2011 Duncan Sands.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file declares a utility class for maintaining a collection of pairwise
++// disjoint intervals.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_INTERVALLIST_H
++#define DRAGONEGG_INTERVALLIST_H
++
++// Plugin headers
++#include "dragonegg/ADT/Range.h"
++
++// LLVM headers
++#include "llvm/ADT/SmallVector.h"
++
++/// IntervalList - Maintains a list of disjoint intervals. Type 'T' represents
++/// an interval, and should have a getRange method which returns a range of 'U'
++/// values. In addition it should provide ChangeRangeTo for growing, shrinking
++/// and otherwise changing the shape of the interval; and JoinWith for replacing
++/// the interval with the convex hull of its union with another interval (which
++/// is guaranteed to be disjoint from the original).
++template <class T, typename U, unsigned N>
++class IntervalList {
++ typedef typename llvm::SmallVector<T, N> List;
++ typedef typename List::iterator iterator;
++
++ List Intervals;
++ // The actual intervals. Always disjoint, sorted and non-empty.
++
++ /// CmpFirst - Compare intervals based on where they start.
++ static bool CmpFirst(const T &L, const T &R) {
++ return L.getRange().getFirst() < R.getRange().getFirst();
++ }
++
++ /// CmpLast - Compare intervals based on where they stop.
++ static bool CmpLast(const T &L, const T &R) {
++ return L.getRange().getLast() < R.getRange().getLast();
++ }
++
++ /// isSane - Return true if the intervals are non-empty, disjoint and
++ /// sorted.
++ bool isSane() const {
++ for (unsigned i = 0, e = Intervals.size(); i < e; ++i) {
++ if (Intervals[i].getRange().empty())
++ return false;
++ if (i && Intervals[i].getRange().getFirst() <
++ Intervals[i-1].getRange().getLast())
++ return false;
++ }
++ return true;
++ }
++
++public:
++
++ /// AddInterval - Add the given interval to the list. If it overlaps any
++ /// existing intervals then the existing intervals are pruned by removing
++ /// exactly the parts of them that overlap the new interval. If the added
++ /// interval is empty then it will be discarded.
++ void AddInterval(const T &S);
++
++ /// getNumIntervals - Return the number of intervals in the list.
++ unsigned getNumIntervals() const {
++ return Intervals.size();
++ }
++
++ /// getInterval - Return the interval with the given index.
++ T getInterval(unsigned Idx) {
++ return Intervals[Idx];
++ }
++
++ /// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
++ /// the given value.
++ void AlignBoundaries(unsigned Alignment);
++};
++
++/// AddInterval - Add the given interval to the list. If it overlaps any
++/// existing intervals then the existing intervals are pruned by removing
++/// exactly the parts of them that overlap the new interval. If the added
++/// interval is empty then it will be discarded.
++template <class T, typename U, unsigned N>
++void IntervalList<T, U, N>::AddInterval(const T &Interval) {
++ const Range<U> NewRange = Interval.getRange();
++
++ // If the new interval is empty then there is no point in adding it.
++ if (NewRange.empty())
++ return;
++
++ // If this is the first interval then it cannot overlap any others.
++ if (Intervals.empty()) {
++ Intervals.push_back(Interval);
++ return;
++ }
++
++ // Check for overlap with existing intervals.
++ iterator Lo = std::lower_bound(Intervals.begin(), Intervals.end(), Interval,
++ CmpFirst);
++ iterator Hi = std::upper_bound(Intervals.begin(), Intervals.end(), Interval,
++ CmpLast);
++ if (Lo < Hi) {
++ // Intervals with index in [Lo, Hi) are those completely covered by the new
++ // interval. Throw them away.
++ for (iterator I = Lo; I != Hi; ++I)
++ assert(NewRange.contains(I->getRange()) && "Old interval not covered!");
++ Intervals.erase(Lo, Hi);
++ Hi = Lo;
++ } else if (Hi < Lo) {
++ // The new interval is contained in Hi with an excedent at each end. Chop
++ // the old interval into two pieces (the lower and upper parts) and insert
++ // the new interval between them.
++ const Range<U> OldRange = Hi->getRange();
++ assert(OldRange.contains(NewRange) && "New interval not contained in old!");
++ const Range<U> LowerRange(OldRange.getFirst(), NewRange.getFirst());
++ const Range<U> UpperRange(NewRange.getLast(), OldRange.getLast());
++ assert(!LowerRange.empty() && !UpperRange.empty() && "Degenerate end!");
++ T UpperPart = *Hi;
++ Hi->ChangeRangeTo(LowerRange);
++ UpperPart.ChangeRangeTo(UpperRange);
++ Lo = Intervals.insert(Lo, UpperPart);
++ Intervals.insert(Lo, Interval);
++ assert(isSane() && "Interval added wrong!");
++ return;
++ }
++ assert(Lo == Hi);
++ // Check for overlap with the preceding interval.
++ if (Lo != Intervals.begin()) {
++ const iterator Prev = Lo - 1;
++ const Range<U> PrevRange = Prev->getRange();
++ if (NewRange.getFirst() < PrevRange.getLast())
++ // Shrink the previous interval to remove the overlap.
++ Prev->ChangeRangeTo(Range<U>(PrevRange.getFirst(), NewRange.getFirst()));
++ }
++ // Check for overlap with the following interval.
++ if (Lo != Intervals.end()) {
++ const iterator Next = Lo;
++ const Range<U> NextRange = Next->getRange();
++ if (NextRange.getFirst() < NewRange.getLast())
++ // Shrink the next interval to remove the overlap.
++ Next->ChangeRangeTo(Range<U>(NewRange.getLast(), NextRange.getLast()));
++ }
++ // The new interval is now disjoint from any existing intervals. Insert it.
++ Intervals.insert(Lo, Interval);
++ assert(isSane() && "Interval added wrong!");
++}
++
++/// AlignBoundaries - Ensure that all intervals begin and end on a multiple of
++/// the given value.
++template <class T, typename U, unsigned N>
++void IntervalList<T, U, N>::AlignBoundaries(unsigned Alignment) {
++ assert(Alignment > 0 && "Alignment should be positive!");
++ for (iterator SI = Intervals.begin(); SI != Intervals.end(); ++SI) {
++ T &Interval = *SI;
++ Range<U> OrigRange = Interval.getRange();
++
++ // Round the start of the interval down and the end of the interval up to
++ // the nearest multiple of the alignment.
++ U RoundedFirst = OrigRange.getFirst() - (OrigRange.getFirst() % Alignment);
++ U RoundedLast = OrigRange.getLast() + Alignment - 1;
++ RoundedLast -= RoundedLast % Alignment;
++ Range<U> AlignedRange(RoundedFirst, RoundedLast);
++
++ // There is nothing to do if the interval is already aligned.
++ if (OrigRange == AlignedRange)
++ continue;
++
++ // Merge in all following intervals that start before RoundedLast.
++ iterator Next = SI + 1;
++ for (; Next != Intervals.end() && Next->getRange().getFirst() < RoundedLast;
++ ++Next)
++ Interval.JoinWith(*Next);
++ assert(Interval.getRange().getFirst() == OrigRange.getFirst() &&
++ "Merging at end changed start!");
++
++ // If merging caused the interval to extend beyond RoundedLast then chop the
++ // interval in two at RoundedLast. This stops intervals getting huge due to
++ // repeated merging.
++ if (Interval.getRange().getLast() > RoundedLast) {
++ Range<U> LowerR(OrigRange.getFirst(), RoundedLast);
++ Range<U> UpperR(RoundedLast, Interval.getRange().getLast());
++ // We must have merged in at least the next interval. Reuse it to hold
++ // the part we chop off the end.
++ T &J = *(SI + 1) = Interval;
++ // Chop the end off the original interval so that it stops at RoundedLast
++ // and at the same time extend the start of the original interval down to
++ // the alignment boundary.
++ Interval.ChangeRangeTo(AlignedRange);
++ // Chop the start off the new (following) interval so that it begins at
++ // RoundedLast.
++ J.ChangeRangeTo(UpperR);
++ // Delete any other merged intervals.
++ Intervals.erase(SI + 2, Next);
++ } else {
++ // The interval didn't grow beyond the original alignment boundary. Round
++ // it to those boundaries.
++ Interval.ChangeRangeTo(AlignedRange);
++ // Delete any merged intervals.
++ Intervals.erase(SI + 1, Next);
++ }
++ }
++}
++
++#endif /* DRAGONEGG_INTERVALLIST_H */
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/ADT/Range.h dragonegg-2.9-new/include/dragonegg/ADT/Range.h
+--- dragonegg-2.9-old/include/dragonegg/ADT/Range.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/ADT/Range.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,106 @@
++//=------------------ Range.h - Interval of values ----------------*- C++ -*-=//
++//
++// Copyright (C) 2011 Duncan Sands.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file declares a utility class for representing an interval of values.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_RANGE_H
++#define DRAGONEGG_RANGE_H
++
++/// Range - Represents the interval [First, Last).
++template<typename T>
++class Range {
++ T First, Last;
++public:
++ Range() : First(0), Last(0) {}
++ Range(T first, T last) : First(first), Last(last) {}
++
++ bool operator==(const Range &other) const {
++ return (empty() && other.empty()) ||
++ (First == other.First && Last == other.Last);
++ }
++
++ /// empty - Return whether the range is empty.
++ bool empty() const {
++ return Last <= First;
++ }
++
++ /// getFirst - Return the value defining the start of the range.
++ T getFirst() const {
++ assert(!empty() && "An empty range has no starting value!");
++ return First;
++ }
++
++ /// getLast - Return the value defining the end of the range.
++ T getLast() const {
++ assert(!empty() && "An empty range has no ending value!");
++ return Last;
++ }
++
++ /// getWidth - Return the number of values in the range.
++ T getWidth() const {
++ return empty() ? 0 : Last - First;
++ }
++
++ /// contains - Return true if the given range is contained in this one.
++ bool contains(Range r) const {
++ if (r.empty())
++ return true;
++ if (empty())
++ return false;
++ return First <= r.First && Last >= r.Last;
++ }
++
++ /// intersects - Return true if the given range intersects this one.
++ bool intersects(Range r) const {
++ if (empty() || r.empty())
++ return false;
++ return r.First < Last && r.Last > First;
++ }
++
++ /// Displace - Return the range obtained by adding the given offset.
++ Range Displace(T Offset) const {
++ if (empty())
++ return Range();
++ assert(((Offset >= 0 && First + Offset >= First && Last + Offset >= Last) ||
++ (Offset < 0 && First + Offset < First && Last + Offset < Last)) &&
++ "Displacement wrapped range!");
++ return Range(First + Offset, Last + Offset);
++ }
++
++ /// Join - Return the smallest range containing this range and the given one.
++ Range Join(Range other) const {
++ if (empty())
++ return other;
++ if (other.empty())
++ return *this;
++ return Range(First < other.First ? First : other.First,
++ Last > other.Last ? Last : other.Last);
++ }
++
++ /// Meet - Return the intersection of this range and the given one.
++ Range Meet(Range other) const {
++ if (empty() || other.empty())
++ return Range();
++ return Range(First > other.First ? First : other.First,
++ Last < other.Last ? Last : other.Last);
++ }
++};
++
++#endif /* DRAGONEGG_RANGE_H */
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/cache.h dragonegg-2.9-new/include/dragonegg/cache.h
+--- dragonegg-2.9-old/include/dragonegg/cache.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/cache.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,45 @@
++/*===----------- cache.h - Caching values "in" GCC trees ----------*- C -*-===*\
++|* *|
++|* Copyright (C) 2009, 2010, 2011 Duncan Sands. *|
++|* *|
++|* This file is part of DragonEgg. *|
++|* *|
++|* DragonEgg is free software; you can redistribute it and/or modify it under *|
++|* the terms of the GNU General Public License as published by the Free *|
++|* Software Foundation; either version 2, or (at your option) any later *|
++|* version. *|
++|* *|
++|* DragonEgg is distributed in the hope that it will be useful, but WITHOUT *|
++|* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *|
++|* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *|
++|* more details. *|
++|* You should have received a copy of the GNU General Public License along *|
++|* with DragonEgg; see the file COPYING. If not, write to the Free Software *|
++|* Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. *|
++|* *|
++|*===----------------------------------------------------------------------===*|
++|* This code lets you to associate a void* with a tree, as if it were cached *|
++|* inside the tree: if the tree is garbage collected and reallocated, then *|
++|* the cached value will have been cleared. *|
++\*===----------------------------------------------------------------------===*/
++
++#ifndef DRAGONEGG_CACHE_H
++#define DRAGONEGG_CACHE_H
++
++union tree_node;
++
++/* llvm_has_cached - Returns whether a value has been associated with the
++ tree. */
++extern int llvm_has_cached(union tree_node *tree);
++
++/* llvm_get_cached - Returns the value associated with the tree, or NULL. */
++extern const void *llvm_get_cached(union tree_node *tree);
++
++/* llvm_set_cached - Associates the given value with the tree (and returns it).
++ To delete an association, pass NULL for the value. */
++extern const void *llvm_set_cached(union tree_node *tree, const void *val);
++
++/* llvm_replace_cached - Replaces all occurrences of old_val with new_val. */
++extern void llvm_replace_cached(const void *old_val, const void *new_val);
++
++#endif /* DRAGONEGG_CACHE_H */
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/Constants.h dragonegg-2.9-new/include/dragonegg/Constants.h
+--- dragonegg-2.9-old/include/dragonegg/Constants.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/Constants.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,60 @@
++//=----- Constants.h - Converting and working with constants ------*- C++ -*-=//
++//
++// Copyright (C) 2011 Duncan Sands.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file declares functions for converting GCC constants to LLVM and working
++// with them.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_CONSTANTS_H
++#define DRAGONEGG_CONSTANTS_H
++
++// Forward declarations.
++namespace llvm {
++ class Constant;
++ class Type;
++}
++union tree_node;
++
++/// AddressOf - Given an expression with a constant address such as a constant,
++/// a global variable or a label, returns the address. The type of the returned
++/// is always a pointer type and, as long as 'exp' does not have void type, the
++/// type of the pointee is the memory type that corresponds to the type of exp
++/// (see ConvertType).
++extern llvm::Constant *AddressOf(tree_node *exp);
++
++/// ConvertInitializer - Convert the initial value for a global variable to an
++/// equivalent LLVM constant. Also handles constant constructors. The type of
++/// the returned value may be pretty much anything. All that is guaranteed is
++/// that its alloc size is equal to the size of the initial value and that its
++/// alignment is less than or equal to the initial value's GCC type alignment.
++/// Note that the GCC type may have variable size or no size, in which case the
++/// size is determined by the initial value. When this happens the size of the
++/// initial value may exceed the alloc size of the LLVM memory type generated
++/// for the GCC type (see ConvertType); it is never smaller than the alloc size.
++extern llvm::Constant *ConvertInitializer(tree_node *exp);
++
++/// InterpretAsType - Interpret the bits of the given constant (starting from
++/// StartingBit) as representing a constant of type 'Ty'. This results in the
++/// same constant as you would get by storing the bits of 'C' to memory (with
++/// the first bit stored being 'StartingBit') and then loading out a (constant)
++/// value of type 'Ty' from the stored to memory location.
++extern llvm::Constant *InterpretAsType(llvm::Constant *C, const llvm::Type* Ty,
++ int StartingBit);
++
++#endif /* DRAGONEGG_CONSTANTS_H */
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/Debug.h dragonegg-2.9-new/include/dragonegg/Debug.h
+--- dragonegg-2.9-old/include/dragonegg/Debug.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/Debug.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,367 @@
++//===------ Debug.h - Interface for generating debug info -------*- C++ -*-===//
++//
++// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Jim Laskey, Duncan Sands
++// et al.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file declares the debug interfaces shared among the dragonegg files.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_DEBUG_H
++#define DRAGONEGG_DEBUG_H
++
++// Plugin headers
++#include "dragonegg/Internals.h"
++
++// LLVM headers
++#include "llvm/Analysis/DebugInfo.h"
++#include "llvm/Support/Allocator.h"
++#include "llvm/Support/ValueHandle.h"
++
++// System headers
++#include <map>
++
++namespace llvm {
++
++// Forward declarations
++class AllocaInst;
++class BasicBlock;
++class CallInst;
++class Function;
++class Module;
++
++/// DIFactory - This object assists with the construction of the various
++/// descriptors.
++class DIFactory {
++ Module &M;
++ LLVMContext& VMContext;
++
++ Function *DeclareFn; // llvm.dbg.declare
++ Function *ValueFn; // llvm.dbg.value
++
++ DIFactory(const DIFactory &); // DO NOT IMPLEMENT
++ void operator=(const DIFactory&); // DO NOT IMPLEMENT
++ public:
++ enum ComplexAddrKind { OpPlus=1, OpDeref };
++
++ explicit DIFactory(Module &m);
++
++ /// GetOrCreateArray - Create an descriptor for an array of descriptors.
++ /// This implicitly uniques the arrays created.
++ DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
++
++ /// GetOrCreateSubrange - Create a descriptor for a value range. This
++ /// implicitly uniques the values returned.
++ DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi);
++
++ /// CreateUnspecifiedParameter - Create unspeicified type descriptor
++ /// for a subroutine type.
++ DIDescriptor CreateUnspecifiedParameter();
++
++ /// CreateCompileUnit - Create a new descriptor for the specified compile
++ /// unit.
++ DICompileUnit CreateCompileUnit(unsigned LangID,
++ StringRef Filename,
++ StringRef Directory,
++ StringRef Producer,
++ bool isMain = false,
++ bool isOptimized = false,
++ StringRef Flags = "",
++ unsigned RunTimeVer = 0);
++
++ /// CreateFile - Create a new descriptor for the specified file.
++ DIFile CreateFile(StringRef Filename, StringRef Directory,
++ DICompileUnit CU);
++
++ /// CreateEnumerator - Create a single enumerator value.
++ DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
++
++ /// CreateBasicType - Create a basic type like int, float, etc.
++ DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
++ DIFile F, unsigned LineNumber,
++ uint64_t SizeInBits, uint64_t AlignInBits,
++ uint64_t OffsetInBits, unsigned Flags,
++ unsigned Encoding);
++
++ /// CreateBasicType - Create a basic type like int, float, etc.
++ DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
++ DIFile F, unsigned LineNumber,
++ Constant *SizeInBits, Constant *AlignInBits,
++ Constant *OffsetInBits, unsigned Flags,
++ unsigned Encoding);
++
++ /// CreateDerivedType - Create a derived type like const qualified type,
++ /// pointer, typedef, etc.
++ DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
++ StringRef Name,
++ DIFile F,
++ unsigned LineNumber,
++ uint64_t SizeInBits, uint64_t AlignInBits,
++ uint64_t OffsetInBits, unsigned Flags,
++ DIType DerivedFrom);
++
++ /// CreateDerivedType - Create a derived type like const qualified type,
++ /// pointer, typedef, etc.
++ DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
++ StringRef Name,
++ DIFile F,
++ unsigned LineNumber,
++ Constant *SizeInBits,
++ Constant *AlignInBits,
++ Constant *OffsetInBits, unsigned Flags,
++ DIType DerivedFrom);
++
++ /// CreateCompositeType - Create a composite type like array, struct, etc.
++ DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
++ StringRef Name,
++ DIFile F,
++ unsigned LineNumber,
++ uint64_t SizeInBits,
++ uint64_t AlignInBits,
++ uint64_t OffsetInBits, unsigned Flags,
++ DIType DerivedFrom,
++ DIArray Elements,
++ unsigned RunTimeLang = 0,
++ MDNode *ContainingType = 0);
++
++ /// CreateTemporaryType - Create a temporary forward-declared type.
++ DIType CreateTemporaryType();
++ DIType CreateTemporaryType(DIFile F);
++
++ /// CreateArtificialType - Create a new DIType with "artificial" flag set.
++ DIType CreateArtificialType(DIType Ty);
++
++ /// CreateCompositeType - Create a composite type like array, struct, etc.
++ DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
++ StringRef Name,
++ DIFile F,
++ unsigned LineNumber,
++ Constant *SizeInBits,
++ Constant *AlignInBits,
++ Constant *OffsetInBits,
++ unsigned Flags,
++ DIType DerivedFrom,
++ DIArray Elements,
++ unsigned RunTimeLang = 0,
++ MDNode *ContainingType = 0);
++
++ /// CreateSubprogram - Create a new descriptor for the specified subprogram.
++ /// See comments in DISubprogram for descriptions of these fields.
++ DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
++ StringRef DisplayName,
++ StringRef LinkageName,
++ DIFile F, unsigned LineNo,
++ DIType Ty, bool isLocalToUnit,
++ bool isDefinition,
++ unsigned VK = 0,
++ unsigned VIndex = 0,
++ DIType ContainingType = DIType(),
++ unsigned Flags = 0,
++ bool isOptimized = false,
++ Function *Fn = 0);
++
++ /// CreateSubprogramDefinition - Create new subprogram descriptor for the
++ /// given declaration.
++ DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration);
++
++ /// CreateGlobalVariable - Create a new descriptor for the specified global.
++ DIGlobalVariable
++ CreateGlobalVariable(DIDescriptor Context, StringRef Name,
++ StringRef DisplayName,
++ StringRef LinkageName,
++ DIFile F,
++ unsigned LineNo, DIType Ty, bool isLocalToUnit,
++ bool isDefinition, llvm::GlobalVariable *GV);
++
++ /// CreateGlobalVariable - Create a new descriptor for the specified constant.
++ DIGlobalVariable
++ CreateGlobalVariable(DIDescriptor Context, StringRef Name,
++ StringRef DisplayName,
++ StringRef LinkageName,
++ DIFile F,
++ unsigned LineNo, DIType Ty, bool isLocalToUnit,
++ bool isDefinition, llvm::Constant *C);
++
++ /// CreateVariable - Create a new descriptor for the specified variable.
++ DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
++ StringRef Name,
++ DIFile F, unsigned LineNo,
++ DIType Ty, bool AlwaysPreserve = false,
++ unsigned Flags = 0);
++
++ /// CreateComplexVariable - Create a new descriptor for the specified
++ /// variable which has a complex address expression for its address.
++ DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
++ StringRef Name, DIFile F, unsigned LineNo,
++ DIType Ty, Value *const *Addr,
++ unsigned NumAddr);
++
++ /// CreateLexicalBlock - This creates a descriptor for a lexical block
++ /// with the specified parent context.
++ DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
++ unsigned Line = 0, unsigned Col = 0);
++
++ /// CreateNameSpace - This creates new descriptor for a namespace
++ /// with the specified parent context.
++ DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
++ DIFile F, unsigned LineNo);
++
++ /// CreateLocation - Creates a debug info location.
++ DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
++ DIScope S, DILocation OrigLoc);
++
++ /// CreateLocation - Creates a debug info location.
++ DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
++ DIScope S, MDNode *OrigLoc = 0);
++
++ /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
++ Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
++ BasicBlock *InsertAtEnd);
++
++ /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
++ Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
++ Instruction *InsertBefore);
++
++ /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
++ Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
++ DIVariable D, BasicBlock *InsertAtEnd);
++
++ /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
++ Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
++ DIVariable D, Instruction *InsertBefore);
++
++ // RecordType - Record DIType in a module such that it is not lost even if
++ // it is not referenced through debug info anchors.
++ void RecordType(DIType T);
++
++ private:
++ Constant *GetTagConstant(unsigned TAG);
++};
++
++/// DebugInfo - This class gathers all debug information during compilation and
++/// is responsible for emitting to llvm globals or pass directly to the backend.
++class DebugInfo {
++private:
++ Module *M; // The current module.
++ DIFactory DebugFactory;
++ const char *CurFullPath; // Previous location file encountered.
++ int CurLineNo; // Previous location line# encountered.
++ const char *PrevFullPath; // Previous location file encountered.
++ int PrevLineNo; // Previous location line# encountered.
++ BasicBlock *PrevBB; // Last basic block encountered.
++
++ DICompileUnit TheCU; // The compile unit.
++
++ std::map<tree_node *, WeakVH > TypeCache;
++ // Cache of previously constructed
++ // Types.
++ std::map<tree_node *, WeakVH > SPCache;
++ // Cache of previously constructed
++ // Subprograms.
++ std::map<tree_node *, WeakVH> NameSpaceCache;
++ // Cache of previously constructed name
++ // spaces.
++
++ SmallVector<WeakVH, 4> RegionStack;
++ // Stack to track declarative scopes.
++
++ std::map<tree_node *, WeakVH> RegionMap;
++
++ /// FunctionNames - This is a storage for function names that are
++ /// constructed on demand. For example, C++ destructors, C++ operators etc..
++ llvm::BumpPtrAllocator FunctionNames;
++
++public:
++ DebugInfo(Module *m);
++
++ /// Initialize - Initialize debug info by creating compile unit for
++ /// main_input_filename. This must be invoked after language dependent
++ /// initialization is done.
++ void Initialize();
++
++ // Accessors.
++ void setLocationFile(const char *FullPath) { CurFullPath = FullPath; }
++ void setLocationLine(int LineNo) { CurLineNo = LineNo; }
++
++ /// EmitFunctionStart - Constructs the debug code for entering a function -
++ /// "llvm.dbg.func.start."
++ void EmitFunctionStart(tree_node *FnDecl, Function *Fn);
++
++ /// EmitFunctionEnd - Constructs the debug code for exiting a declarative
++ /// region - "llvm.dbg.region.end."
++ void EmitFunctionEnd(bool EndFunction);
++
++ /// EmitDeclare - Constructs the debug code for allocation of a new variable.
++ /// region - "llvm.dbg.declare."
++ void EmitDeclare(tree_node *decl, unsigned Tag, const char *Name,
++ tree_node *type, Value *AI, LLVMBuilder &Builder);
++
++ /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
++ /// source line.
++ void EmitStopPoint(BasicBlock *CurBB, LLVMBuilder &Builder);
++
++ /// EmitGlobalVariable - Emit information about a global variable.
++ ///
++ void EmitGlobalVariable(GlobalVariable *GV, tree_node *decl);
++
++ /// getOrCreateType - Get the type from the cache or create a new type if
++ /// necessary.
++ DIType getOrCreateType(tree_node *type);
++
++ /// createBasicType - Create BasicType.
++ DIType createBasicType(tree_node *type);
++
++ /// createMethodType - Create MethodType.
++ DIType createMethodType(tree_node *type);
++
++ /// createPointerType - Create PointerType.
++ DIType createPointerType(tree_node *type);
++
++ /// createArrayType - Create ArrayType.
++ DIType createArrayType(tree_node *type);
++
++ /// createEnumType - Create EnumType.
++ DIType createEnumType(tree_node *type);
++
++ /// createStructType - Create StructType for struct or union or class.
++ DIType createStructType(tree_node *type);
++
++ /// createVarinatType - Create variant type or return MainTy.
++ DIType createVariantType(tree_node *type, DIType MainTy);
++
++ /// getOrCreateCompileUnit - Create a new compile unit.
++ DICompileUnit getOrCreateCompileUnit(const char *FullPath,
++ bool isMain = false);
++
++ /// getOrCreateFile - Get DIFile descriptor.
++ DIFile getOrCreateFile(const char *FullPath);
++
++ /// findRegion - Find tree_node N's region.
++ DIDescriptor findRegion(tree_node *n);
++
++ /// getOrCreateNameSpace - Get name space descriptor for the tree node.
++ DINameSpace getOrCreateNameSpace(tree_node *Node, DIDescriptor Context);
++
++ /// getFunctionName - Get function name for the given FnDecl. If the
++ /// name is constructred on demand (e.g. C++ destructor) then the name
++ /// is stored on the side.
++ StringRef getFunctionName(tree_node *FnDecl);
++};
++
++} // end namespace llvm
++
++#endif /* DRAGONEGG_DEBUG_H */
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/gt-cache.h dragonegg-2.9-new/include/dragonegg/gt-cache.h
+--- dragonegg-2.9-old/include/dragonegg/gt-cache.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/gt-cache.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,802 @@
++/* Type information for GCC.
++ Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify it under
++the terms of the GNU General Public License as published by the Free
++Software Foundation; either version 3, or (at your option) any later
++version.
++
++GCC is distributed in the hope that it will be useful, but WITHOUT ANY
++WARRANTY; without even the implied warranty of MERCHANTABILITY or
++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3. If not see
++<http://www.gnu.org/licenses/>. */
++
++/* This file is machine generated. Do not edit. */
++
++/* GC marker procedures. */
++/* macros and declarations */
++#define gt_ggc_m_13tree_llvm_map(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_llvm_map (X);\
++ } while (0)
++extern void gt_ggc_mx_tree_llvm_map (void *);
++#define gt_ggc_m_15interface_tuple(X) do { \
++ if (X != NULL) gt_ggc_mx_interface_tuple (X);\
++ } while (0)
++extern void gt_ggc_mx_interface_tuple (void *);
++#define gt_ggc_m_16volatilized_type(X) do { \
++ if (X != NULL) gt_ggc_mx_volatilized_type (X);\
++ } while (0)
++extern void gt_ggc_mx_volatilized_type (void *);
++#define gt_ggc_m_17string_descriptor(X) do { \
++ if (X != NULL) gt_ggc_mx_string_descriptor (X);\
++ } while (0)
++extern void gt_ggc_mx_string_descriptor (void *);
++#define gt_ggc_m_15c_inline_static(X) do { \
++ if (X != NULL) gt_ggc_mx_c_inline_static (X);\
++ } while (0)
++extern void gt_ggc_mx_c_inline_static (void *);
++#define gt_ggc_m_24VEC_c_goto_bindings_p_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_c_goto_bindings_p_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_c_goto_bindings_p_gc (void *);
++#define gt_ggc_m_15c_goto_bindings(X) do { \
++ if (X != NULL) gt_ggc_mx_c_goto_bindings (X);\
++ } while (0)
++extern void gt_ggc_mx_c_goto_bindings (void *);
++#define gt_ggc_m_7c_scope(X) do { \
++ if (X != NULL) gt_ggc_mx_c_scope (X);\
++ } while (0)
++extern void gt_ggc_mx_c_scope (void *);
++#define gt_ggc_m_9c_binding(X) do { \
++ if (X != NULL) gt_ggc_mx_c_binding (X);\
++ } while (0)
++extern void gt_ggc_mx_c_binding (void *);
++#define gt_ggc_m_12c_label_vars(X) do { \
++ if (X != NULL) gt_ggc_mx_c_label_vars (X);\
++ } while (0)
++extern void gt_ggc_mx_c_label_vars (void *);
++#define gt_ggc_m_8c_parser(X) do { \
++ if (X != NULL) gt_ggc_mx_c_parser (X);\
++ } while (0)
++extern void gt_ggc_mx_c_parser (void *);
++#define gt_ggc_m_9imp_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_imp_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_imp_entry (void *);
++#define gt_ggc_m_16hashed_attribute(X) do { \
++ if (X != NULL) gt_ggc_mx_hashed_attribute (X);\
++ } while (0)
++extern void gt_ggc_mx_hashed_attribute (void *);
++#define gt_ggc_m_12hashed_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_hashed_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_hashed_entry (void *);
++#define gt_ggc_m_14type_assertion(X) do { \
++ if (X != NULL) gt_ggc_mx_type_assertion (X);\
++ } while (0)
++extern void gt_ggc_mx_type_assertion (void *);
++#define gt_ggc_m_18treetreehash_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_treetreehash_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_treetreehash_entry (void *);
++#define gt_ggc_m_5CPool(X) do { \
++ if (X != NULL) gt_ggc_mx_CPool (X);\
++ } while (0)
++extern void gt_ggc_mx_CPool (void *);
++#define gt_ggc_m_3JCF(X) do { \
++ if (X != NULL) gt_ggc_mx_JCF (X);\
++ } while (0)
++extern void gt_ggc_mx_JCF (void *);
++#define gt_ggc_m_17module_htab_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_module_htab_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_module_htab_entry (void *);
++#define gt_ggc_m_13binding_level(X) do { \
++ if (X != NULL) gt_ggc_mx_binding_level (X);\
++ } while (0)
++extern void gt_ggc_mx_binding_level (void *);
++#define gt_ggc_m_9opt_stack(X) do { \
++ if (X != NULL) gt_ggc_mx_opt_stack (X);\
++ } while (0)
++extern void gt_ggc_mx_opt_stack (void *);
++#define gt_ggc_m_16def_pragma_macro(X) do { \
++ if (X != NULL) gt_ggc_mx_def_pragma_macro (X);\
++ } while (0)
++extern void gt_ggc_mx_def_pragma_macro (void *);
++#define gt_ggc_m_22def_pragma_macro_value(X) do { \
++ if (X != NULL) gt_ggc_mx_def_pragma_macro_value (X);\
++ } while (0)
++extern void gt_ggc_mx_def_pragma_macro_value (void *);
++#define gt_ggc_m_11align_stack(X) do { \
++ if (X != NULL) gt_ggc_mx_align_stack (X);\
++ } while (0)
++extern void gt_ggc_mx_align_stack (void *);
++#define gt_ggc_m_18VEC_tree_gc_vec_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_tree_gc_vec_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_tree_gc_vec_gc (void *);
++#define gt_ggc_m_19VEC_const_char_p_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_const_char_p_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_const_char_p_gc (void *);
++#define gt_ggc_m_21pending_abstract_type(X) do { \
++ if (X != NULL) gt_ggc_mx_pending_abstract_type (X);\
++ } while (0)
++extern void gt_ggc_mx_pending_abstract_type (void *);
++#define gt_ggc_m_15VEC_tree_int_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_tree_int_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_tree_int_gc (void *);
++#define gt_ggc_m_9cp_parser(X) do { \
++ if (X != NULL) gt_ggc_mx_cp_parser (X);\
++ } while (0)
++extern void gt_ggc_mx_cp_parser (void *);
++#define gt_ggc_m_17cp_parser_context(X) do { \
++ if (X != NULL) gt_ggc_mx_cp_parser_context (X);\
++ } while (0)
++extern void gt_ggc_mx_cp_parser_context (void *);
++#define gt_ggc_m_8cp_lexer(X) do { \
++ if (X != NULL) gt_ggc_mx_cp_lexer (X);\
++ } while (0)
++extern void gt_ggc_mx_cp_lexer (void *);
++#define gt_ggc_m_10tree_check(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_check (X);\
++ } while (0)
++extern void gt_ggc_mx_tree_check (void *);
++#define gt_ggc_m_22VEC_deferred_access_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_deferred_access_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_deferred_access_gc (void *);
++#define gt_ggc_m_10spec_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_spec_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_spec_entry (void *);
++#define gt_ggc_m_16pending_template(X) do { \
++ if (X != NULL) gt_ggc_mx_pending_template (X);\
++ } while (0)
++extern void gt_ggc_mx_pending_template (void *);
++#define gt_ggc_m_21named_label_use_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_named_label_use_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_named_label_use_entry (void *);
++#define gt_ggc_m_28VEC_deferred_access_check_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_deferred_access_check_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_deferred_access_check_gc (void *);
++#define gt_ggc_m_11tinst_level(X) do { \
++ if (X != NULL) gt_ggc_mx_tinst_level (X);\
++ } while (0)
++extern void gt_ggc_mx_tinst_level (void *);
++#define gt_ggc_m_18sorted_fields_type(X) do { \
++ if (X != NULL) gt_ggc_mx_sorted_fields_type (X);\
++ } while (0)
++extern void gt_ggc_mx_sorted_fields_type (void *);
++#define gt_ggc_m_18VEC_tree_pair_s_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_tree_pair_s_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_tree_pair_s_gc (void *);
++#define gt_ggc_m_17named_label_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_named_label_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_named_label_entry (void *);
++#define gt_ggc_m_14cp_token_cache(X) do { \
++ if (X != NULL) gt_ggc_mx_cp_token_cache (X);\
++ } while (0)
++extern void gt_ggc_mx_cp_token_cache (void *);
++#define gt_ggc_m_11saved_scope(X) do { \
++ if (X != NULL) gt_ggc_mx_saved_scope (X);\
++ } while (0)
++extern void gt_ggc_mx_saved_scope (void *);
++#define gt_ggc_m_16cxx_int_tree_map(X) do { \
++ if (X != NULL) gt_ggc_mx_cxx_int_tree_map (X);\
++ } while (0)
++extern void gt_ggc_mx_cxx_int_tree_map (void *);
++#define gt_ggc_m_23VEC_cp_class_binding_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_cp_class_binding_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_cp_class_binding_gc (void *);
++#define gt_ggc_m_24VEC_cxx_saved_binding_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_cxx_saved_binding_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_cxx_saved_binding_gc (void *);
++#define gt_ggc_m_16cp_binding_level(X) do { \
++ if (X != NULL) gt_ggc_mx_cp_binding_level (X);\
++ } while (0)
++extern void gt_ggc_mx_cp_binding_level (void *);
++#define gt_ggc_m_11cxx_binding(X) do { \
++ if (X != NULL) gt_ggc_mx_cxx_binding (X);\
++ } while (0)
++extern void gt_ggc_mx_cxx_binding (void *);
++#define gt_ggc_m_15binding_entry_s(X) do { \
++ if (X != NULL) gt_ggc_mx_binding_entry_s (X);\
++ } while (0)
++extern void gt_ggc_mx_binding_entry_s (void *);
++#define gt_ggc_m_15binding_table_s(X) do { \
++ if (X != NULL) gt_ggc_mx_binding_table_s (X);\
++ } while (0)
++extern void gt_ggc_mx_binding_table_s (void *);
++#define gt_ggc_m_14VEC_tinfo_s_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_tinfo_s_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_tinfo_s_gc (void *);
++#define gt_ggc_m_18gnat_binding_level(X) do { \
++ if (X != NULL) gt_ggc_mx_gnat_binding_level (X);\
++ } while (0)
++extern void gt_ggc_mx_gnat_binding_level (void *);
++#define gt_ggc_m_9elab_info(X) do { \
++ if (X != NULL) gt_ggc_mx_elab_info (X);\
++ } while (0)
++extern void gt_ggc_mx_elab_info (void *);
++#define gt_ggc_m_10stmt_group(X) do { \
++ if (X != NULL) gt_ggc_mx_stmt_group (X);\
++ } while (0)
++extern void gt_ggc_mx_stmt_group (void *);
++#define gt_ggc_m_16VEC_parm_attr_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_parm_attr_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_parm_attr_gc (void *);
++#define gt_ggc_m_11parm_attr_d(X) do { \
++ if (X != NULL) gt_ggc_mx_parm_attr_d (X);\
++ } while (0)
++extern void gt_ggc_mx_parm_attr_d (void *);
++#define gt_ggc_m_22VEC_ipa_edge_args_t_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_ipa_edge_args_t_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_ipa_edge_args_t_gc (void *);
++#define gt_ggc_m_20lto_symtab_entry_def(X) do { \
++ if (X != NULL) gt_ggc_mx_lto_symtab_entry_def (X);\
++ } while (0)
++extern void gt_ggc_mx_lto_symtab_entry_def (void *);
++#define gt_ggc_m_20ssa_operand_memory_d(X) do { \
++ if (X != NULL) gt_ggc_mx_ssa_operand_memory_d (X);\
++ } while (0)
++extern void gt_ggc_mx_ssa_operand_memory_d (void *);
++#define gt_ggc_m_13scev_info_str(X) do { \
++ if (X != NULL) gt_ggc_mx_scev_info_str (X);\
++ } while (0)
++extern void gt_ggc_mx_scev_info_str (void *);
++#define gt_ggc_m_13VEC_gimple_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_gimple_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_gimple_gc (void *);
++#define gt_ggc_m_9type_hash(X) do { \
++ if (X != NULL) gt_ggc_mx_type_hash (X);\
++ } while (0)
++extern void gt_ggc_mx_type_hash (void *);
++#define gt_ggc_m_16string_pool_data(X) do { \
++ if (X != NULL) gt_ggc_mx_string_pool_data (X);\
++ } while (0)
++extern void gt_ggc_mx_string_pool_data (void *);
++#define gt_ggc_m_13libfunc_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_libfunc_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_libfunc_entry (void *);
++#define gt_ggc_m_23temp_slot_address_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_temp_slot_address_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_temp_slot_address_entry (void *);
++#define gt_ggc_m_15throw_stmt_node(X) do { \
++ if (X != NULL) gt_ggc_mx_throw_stmt_node (X);\
++ } while (0)
++extern void gt_ggc_mx_throw_stmt_node (void *);
++#define gt_ggc_m_21VEC_eh_landing_pad_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_eh_landing_pad_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_eh_landing_pad_gc (void *);
++#define gt_ggc_m_16VEC_eh_region_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_eh_region_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_eh_region_gc (void *);
++#define gt_ggc_m_10eh_catch_d(X) do { \
++ if (X != NULL) gt_ggc_mx_eh_catch_d (X);\
++ } while (0)
++extern void gt_ggc_mx_eh_catch_d (void *);
++#define gt_ggc_m_16eh_landing_pad_d(X) do { \
++ if (X != NULL) gt_ggc_mx_eh_landing_pad_d (X);\
++ } while (0)
++extern void gt_ggc_mx_eh_landing_pad_d (void *);
++#define gt_ggc_m_11eh_region_d(X) do { \
++ if (X != NULL) gt_ggc_mx_eh_region_d (X);\
++ } while (0)
++extern void gt_ggc_mx_eh_region_d (void *);
++#define gt_ggc_m_10vcall_insn(X) do { \
++ if (X != NULL) gt_ggc_mx_vcall_insn (X);\
++ } while (0)
++extern void gt_ggc_mx_vcall_insn (void *);
++#define gt_ggc_m_18VEC_vcall_entry_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_vcall_entry_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_vcall_entry_gc (void *);
++#define gt_ggc_m_18VEC_dcall_entry_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_dcall_entry_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_dcall_entry_gc (void *);
++#define gt_ggc_m_16var_loc_list_def(X) do { \
++ if (X != NULL) gt_ggc_mx_var_loc_list_def (X);\
++ } while (0)
++extern void gt_ggc_mx_var_loc_list_def (void *);
++#define gt_ggc_m_12var_loc_node(X) do { \
++ if (X != NULL) gt_ggc_mx_var_loc_node (X);\
++ } while (0)
++extern void gt_ggc_mx_var_loc_node (void *);
++#define gt_ggc_m_20VEC_die_arg_entry_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_die_arg_entry_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_die_arg_entry_gc (void *);
++#define gt_ggc_m_16limbo_die_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_limbo_die_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_limbo_die_struct (void *);
++#define gt_ggc_m_20VEC_pubname_entry_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_pubname_entry_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_pubname_entry_gc (void *);
++#define gt_ggc_m_19VEC_dw_attr_node_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_dw_attr_node_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_dw_attr_node_gc (void *);
++#define gt_ggc_m_18comdat_type_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_comdat_type_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_comdat_type_struct (void *);
++#define gt_ggc_m_25dw_ranges_by_label_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_ranges_by_label_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_ranges_by_label_struct (void *);
++#define gt_ggc_m_16dw_ranges_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_ranges_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_ranges_struct (void *);
++#define gt_ggc_m_28dw_separate_line_info_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_separate_line_info_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_separate_line_info_struct (void *);
++#define gt_ggc_m_19dw_line_info_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_line_info_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_line_info_struct (void *);
++#define gt_ggc_m_25VEC_deferred_locations_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_deferred_locations_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_deferred_locations_gc (void *);
++#define gt_ggc_m_18dw_loc_list_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_loc_list_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_loc_list_struct (void *);
++#define gt_ggc_m_15dwarf_file_data(X) do { \
++ if (X != NULL) gt_ggc_mx_dwarf_file_data (X);\
++ } while (0)
++extern void gt_ggc_mx_dwarf_file_data (void *);
++#define gt_ggc_m_15queued_reg_save(X) do { \
++ if (X != NULL) gt_ggc_mx_queued_reg_save (X);\
++ } while (0)
++extern void gt_ggc_mx_queued_reg_save (void *);
++#define gt_ggc_m_20indirect_string_node(X) do { \
++ if (X != NULL) gt_ggc_mx_indirect_string_node (X);\
++ } while (0)
++extern void gt_ggc_mx_indirect_string_node (void *);
++#define gt_ggc_m_19dw_loc_descr_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_loc_descr_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_loc_descr_struct (void *);
++#define gt_ggc_m_13dw_fde_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_fde_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_fde_struct (void *);
++#define gt_ggc_m_13dw_cfi_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_dw_cfi_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_dw_cfi_struct (void *);
++#define gt_ggc_m_8typeinfo(X) do { \
++ if (X != NULL) gt_ggc_mx_typeinfo (X);\
++ } while (0)
++extern void gt_ggc_mx_typeinfo (void *);
++#define gt_ggc_m_22VEC_alias_set_entry_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_alias_set_entry_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_alias_set_entry_gc (void *);
++#define gt_ggc_m_17alias_set_entry_d(X) do { \
++ if (X != NULL) gt_ggc_mx_alias_set_entry_d (X);\
++ } while (0)
++extern void gt_ggc_mx_alias_set_entry_d (void *);
++#define gt_ggc_m_24constant_descriptor_tree(X) do { \
++ if (X != NULL) gt_ggc_mx_constant_descriptor_tree (X);\
++ } while (0)
++extern void gt_ggc_mx_constant_descriptor_tree (void *);
++#define gt_ggc_m_15cgraph_asm_node(X) do { \
++ if (X != NULL) gt_ggc_mx_cgraph_asm_node (X);\
++ } while (0)
++extern void gt_ggc_mx_cgraph_asm_node (void *);
++#define gt_ggc_m_12varpool_node(X) do { \
++ if (X != NULL) gt_ggc_mx_varpool_node (X);\
++ } while (0)
++extern void gt_ggc_mx_varpool_node (void *);
++#define gt_ggc_m_22VEC_cgraph_node_set_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_cgraph_node_set_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_cgraph_node_set_gc (void *);
++#define gt_ggc_m_19cgraph_node_set_def(X) do { \
++ if (X != NULL) gt_ggc_mx_cgraph_node_set_def (X);\
++ } while (0)
++extern void gt_ggc_mx_cgraph_node_set_def (void *);
++#define gt_ggc_m_27cgraph_node_set_element_def(X) do { \
++ if (X != NULL) gt_ggc_mx_cgraph_node_set_element_def (X);\
++ } while (0)
++extern void gt_ggc_mx_cgraph_node_set_element_def (void *);
++#define gt_ggc_m_22VEC_cgraph_node_ptr_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_cgraph_node_ptr_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_cgraph_node_ptr_gc (void *);
++#define gt_ggc_m_11cgraph_edge(X) do { \
++ if (X != NULL) gt_ggc_mx_cgraph_edge (X);\
++ } while (0)
++extern void gt_ggc_mx_cgraph_edge (void *);
++#define gt_ggc_m_24VEC_ipa_replace_map_p_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_ipa_replace_map_p_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_ipa_replace_map_p_gc (void *);
++#define gt_ggc_m_15ipa_replace_map(X) do { \
++ if (X != NULL) gt_ggc_mx_ipa_replace_map (X);\
++ } while (0)
++extern void gt_ggc_mx_ipa_replace_map (void *);
++#define gt_ggc_m_11cgraph_node(X) do { \
++ if (X != NULL) gt_ggc_mx_cgraph_node (X);\
++ } while (0)
++extern void gt_ggc_mx_cgraph_node (void *);
++#define gt_ggc_m_18VEC_basic_block_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_basic_block_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_basic_block_gc (void *);
++#define gt_ggc_m_14gimple_bb_info(X) do { \
++ if (X != NULL) gt_ggc_mx_gimple_bb_info (X);\
++ } while (0)
++extern void gt_ggc_mx_gimple_bb_info (void *);
++#define gt_ggc_m_11rtl_bb_info(X) do { \
++ if (X != NULL) gt_ggc_mx_rtl_bb_info (X);\
++ } while (0)
++extern void gt_ggc_mx_rtl_bb_info (void *);
++#define gt_ggc_m_11VEC_edge_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_edge_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_edge_gc (void *);
++#define gt_ggc_m_17cselib_val_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_cselib_val_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_cselib_val_struct (void *);
++#define gt_ggc_m_12elt_loc_list(X) do { \
++ if (X != NULL) gt_ggc_mx_elt_loc_list (X);\
++ } while (0)
++extern void gt_ggc_mx_elt_loc_list (void *);
++#define gt_ggc_m_13VEC_loop_p_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_loop_p_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_loop_p_gc (void *);
++#define gt_ggc_m_4loop(X) do { \
++ if (X != NULL) gt_ggc_mx_loop (X);\
++ } while (0)
++extern void gt_ggc_mx_loop (void *);
++#define gt_ggc_m_9loop_exit(X) do { \
++ if (X != NULL) gt_ggc_mx_loop_exit (X);\
++ } while (0)
++extern void gt_ggc_mx_loop_exit (void *);
++#define gt_ggc_m_13nb_iter_bound(X) do { \
++ if (X != NULL) gt_ggc_mx_nb_iter_bound (X);\
++ } while (0)
++extern void gt_ggc_mx_nb_iter_bound (void *);
++#define gt_ggc_m_24types_used_by_vars_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_types_used_by_vars_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_types_used_by_vars_entry (void *);
++#define gt_ggc_m_17language_function(X) do { \
++ if (X != NULL) gt_ggc_mx_language_function (X);\
++ } while (0)
++extern void gt_ggc_mx_language_function (void *);
++#define gt_ggc_m_5loops(X) do { \
++ if (X != NULL) gt_ggc_mx_loops (X);\
++ } while (0)
++extern void gt_ggc_mx_loops (void *);
++#define gt_ggc_m_18control_flow_graph(X) do { \
++ if (X != NULL) gt_ggc_mx_control_flow_graph (X);\
++ } while (0)
++extern void gt_ggc_mx_control_flow_graph (void *);
++#define gt_ggc_m_9eh_status(X) do { \
++ if (X != NULL) gt_ggc_mx_eh_status (X);\
++ } while (0)
++extern void gt_ggc_mx_eh_status (void *);
++#define gt_ggc_m_20initial_value_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_initial_value_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_initial_value_struct (void *);
++#define gt_ggc_m_17rtx_constant_pool(X) do { \
++ if (X != NULL) gt_ggc_mx_rtx_constant_pool (X);\
++ } while (0)
++extern void gt_ggc_mx_rtx_constant_pool (void *);
++#define gt_ggc_m_18VEC_temp_slot_p_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_temp_slot_p_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_temp_slot_p_gc (void *);
++#define gt_ggc_m_9temp_slot(X) do { \
++ if (X != NULL) gt_ggc_mx_temp_slot (X);\
++ } while (0)
++extern void gt_ggc_mx_temp_slot (void *);
++#define gt_ggc_m_9gimple_df(X) do { \
++ if (X != NULL) gt_ggc_mx_gimple_df (X);\
++ } while (0)
++extern void gt_ggc_mx_gimple_df (void *);
++#define gt_ggc_m_23VEC_call_site_record_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_call_site_record_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_call_site_record_gc (void *);
++#define gt_ggc_m_18call_site_record_d(X) do { \
++ if (X != NULL) gt_ggc_mx_call_site_record_d (X);\
++ } while (0)
++extern void gt_ggc_mx_call_site_record_d (void *);
++#define gt_ggc_m_14sequence_stack(X) do { \
++ if (X != NULL) gt_ggc_mx_sequence_stack (X);\
++ } while (0)
++extern void gt_ggc_mx_sequence_stack (void *);
++#define gt_ggc_m_8elt_list(X) do { \
++ if (X != NULL) gt_ggc_mx_elt_list (X);\
++ } while (0)
++extern void gt_ggc_mx_elt_list (void *);
++#define gt_ggc_m_17tree_priority_map(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_priority_map (X);\
++ } while (0)
++extern void gt_ggc_mx_tree_priority_map (void *);
++#define gt_ggc_m_12tree_int_map(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_int_map (X);\
++ } while (0)
++extern void gt_ggc_mx_tree_int_map (void *);
++#define gt_ggc_m_8tree_map(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_map (X);\
++ } while (0)
++extern void gt_ggc_mx_tree_map (void *);
++#define gt_ggc_m_14lang_tree_node(X) do { \
++ if (X != NULL) gt_ggc_mx_lang_tree_node (X);\
++ } while (0)
++extern void gt_ggc_mx_lang_tree_node (void *);
++#define gt_ggc_m_24tree_statement_list_node(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_statement_list_node (X);\
++ } while (0)
++extern void gt_ggc_mx_tree_statement_list_node (void *);
++#define gt_ggc_m_9lang_decl(X) do { \
++ if (X != NULL) gt_ggc_mx_lang_decl (X);\
++ } while (0)
++extern void gt_ggc_mx_lang_decl (void *);
++#define gt_ggc_m_9lang_type(X) do { \
++ if (X != NULL) gt_ggc_mx_lang_type (X);\
++ } while (0)
++extern void gt_ggc_mx_lang_type (void *);
++#define gt_ggc_m_10die_struct(X) do { \
++ if (X != NULL) gt_ggc_mx_die_struct (X);\
++ } while (0)
++extern void gt_ggc_mx_die_struct (void *);
++#define gt_ggc_m_15varray_head_tag(X) do { \
++ if (X != NULL) gt_ggc_mx_varray_head_tag (X);\
++ } while (0)
++extern void gt_ggc_mx_varray_head_tag (void *);
++#define gt_ggc_m_12ptr_info_def(X) do { \
++ if (X != NULL) gt_ggc_mx_ptr_info_def (X);\
++ } while (0)
++extern void gt_ggc_mx_ptr_info_def (void *);
++#define gt_ggc_m_22VEC_constructor_elt_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_constructor_elt_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_constructor_elt_gc (void *);
++#define gt_ggc_m_10tree_ann_d(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_ann_d (X);\
++ } while (0)
++extern void gt_ggc_mx_tree_ann_d (void *);
++#define gt_ggc_m_17VEC_alias_pair_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_alias_pair_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_alias_pair_gc (void *);
++#define gt_ggc_m_11VEC_tree_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_tree_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_tree_gc (void *);
++#define gt_ggc_m_12VEC_uchar_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_uchar_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_uchar_gc (void *);
++#define gt_ggc_m_8function(X) do { \
++ if (X != NULL) gt_ggc_mx_function (X);\
++ } while (0)
++extern void gt_ggc_mx_function (void *);
++#define gt_ggc_m_23constant_descriptor_rtx(X) do { \
++ if (X != NULL) gt_ggc_mx_constant_descriptor_rtx (X);\
++ } while (0)
++extern void gt_ggc_mx_constant_descriptor_rtx (void *);
++#define gt_ggc_m_11fixed_value(X) do { \
++ if (X != NULL) gt_ggc_mx_fixed_value (X);\
++ } while (0)
++extern void gt_ggc_mx_fixed_value (void *);
++#define gt_ggc_m_10real_value(X) do { \
++ if (X != NULL) gt_ggc_mx_real_value (X);\
++ } while (0)
++extern void gt_ggc_mx_real_value (void *);
++#define gt_ggc_m_10VEC_rtx_gc(X) do { \
++ if (X != NULL) gt_ggc_mx_VEC_rtx_gc (X);\
++ } while (0)
++extern void gt_ggc_mx_VEC_rtx_gc (void *);
++#define gt_ggc_m_12object_block(X) do { \
++ if (X != NULL) gt_ggc_mx_object_block (X);\
++ } while (0)
++extern void gt_ggc_mx_object_block (void *);
++#define gt_ggc_m_9reg_attrs(X) do { \
++ if (X != NULL) gt_ggc_mx_reg_attrs (X);\
++ } while (0)
++extern void gt_ggc_mx_reg_attrs (void *);
++#define gt_ggc_m_9mem_attrs(X) do { \
++ if (X != NULL) gt_ggc_mx_mem_attrs (X);\
++ } while (0)
++extern void gt_ggc_mx_mem_attrs (void *);
++#define gt_ggc_m_14bitmap_obstack(X) do { \
++ if (X != NULL) gt_ggc_mx_bitmap_obstack (X);\
++ } while (0)
++extern void gt_ggc_mx_bitmap_obstack (void *);
++#define gt_ggc_m_18bitmap_element_def(X) do { \
++ if (X != NULL) gt_ggc_mx_bitmap_element_def (X);\
++ } while (0)
++extern void gt_ggc_mx_bitmap_element_def (void *);
++#define gt_ggc_m_16machine_function(X) do { \
++ if (X != NULL) gt_ggc_mx_machine_function (X);\
++ } while (0)
++extern void gt_ggc_mx_machine_function (void *);
++#define gt_ggc_m_17stack_local_entry(X) do { \
++ if (X != NULL) gt_ggc_mx_stack_local_entry (X);\
++ } while (0)
++extern void gt_ggc_mx_stack_local_entry (void *);
++#define gt_ggc_m_15basic_block_def(X) do { \
++ if (X != NULL) gt_ggc_mx_basic_block_def (X);\
++ } while (0)
++extern void gt_ggc_mx_basic_block_def (void *);
++#define gt_ggc_m_8edge_def(X) do { \
++ if (X != NULL) gt_ggc_mx_edge_def (X);\
++ } while (0)
++extern void gt_ggc_mx_edge_def (void *);
++#define gt_ggc_m_17gimple_seq_node_d(X) do { \
++ if (X != NULL) gt_ggc_mx_gimple_seq_node_d (X);\
++ } while (0)
++extern void gt_ggc_mx_gimple_seq_node_d (void *);
++#define gt_ggc_m_12gimple_seq_d(X) do { \
++ if (X != NULL) gt_ggc_mx_gimple_seq_d (X);\
++ } while (0)
++extern void gt_ggc_mx_gimple_seq_d (void *);
++#define gt_ggc_m_7section(X) do { \
++ if (X != NULL) gt_ggc_mx_section (X);\
++ } while (0)
++extern void gt_ggc_mx_section (void *);
++#define gt_ggc_m_18gimple_statement_d(X) do { \
++ if (X != NULL) gt_ggc_mx_gimple_statement_d (X);\
++ } while (0)
++extern void gt_ggc_mx_gimple_statement_d (void *);
++#define gt_ggc_m_9rtvec_def(X) do { \
++ if (X != NULL) gt_ggc_mx_rtvec_def (X);\
++ } while (0)
++extern void gt_ggc_mx_rtvec_def (void *);
++#define gt_ggc_m_7rtx_def(X) do { \
++ if (X != NULL) gt_ggc_mx_rtx_def (X);\
++ } while (0)
++extern void gt_ggc_mx_rtx_def (void *);
++#define gt_ggc_m_15bitmap_head_def(X) do { \
++ if (X != NULL) gt_ggc_mx_bitmap_head_def (X);\
++ } while (0)
++extern void gt_ggc_mx_bitmap_head_def (void *);
++#define gt_ggc_m_9tree_node(X) do { \
++ if (X != NULL) gt_ggc_mx_tree_node (X);\
++ } while (0)
++#define gt_ggc_mx_tree_node gt_ggc_mx_lang_tree_node
++#define gt_ggc_m_6answer(X) do { \
++ if (X != NULL) gt_ggc_mx_answer (X);\
++ } while (0)
++extern void gt_ggc_mx_answer (void *);
++#define gt_ggc_m_9cpp_macro(X) do { \
++ if (X != NULL) gt_ggc_mx_cpp_macro (X);\
++ } while (0)
++extern void gt_ggc_mx_cpp_macro (void *);
++#define gt_ggc_m_9cpp_token(X) do { \
++ if (X != NULL) gt_ggc_mx_cpp_token (X);\
++ } while (0)
++extern void gt_ggc_mx_cpp_token (void *);
++#define gt_ggc_m_9line_maps(X) do { \
++ if (X != NULL) gt_ggc_mx_line_maps (X);\
++ } while (0)
++extern void gt_ggc_mx_line_maps (void *);
++extern void gt_ggc_m_II17splay_tree_node_s (void *);
++extern void gt_ggc_m_SP9tree_node17splay_tree_node_s (void *);
++extern void gt_ggc_m_P9tree_nodeP9tree_node17splay_tree_node_s (void *);
++extern void gt_ggc_m_IP9tree_node17splay_tree_node_s (void *);
++extern void gt_ggc_m_P13tree_llvm_map4htab (void *);
++extern void gt_ggc_m_P15interface_tuple4htab (void *);
++extern void gt_ggc_m_P16volatilized_type4htab (void *);
++extern void gt_ggc_m_P17string_descriptor4htab (void *);
++extern void gt_ggc_m_P14type_assertion4htab (void *);
++extern void gt_ggc_m_P18treetreehash_entry4htab (void *);
++extern void gt_ggc_m_P17module_htab_entry4htab (void *);
++extern void gt_ggc_m_P16def_pragma_macro4htab (void *);
++extern void gt_ggc_m_P21pending_abstract_type4htab (void *);
++extern void gt_ggc_m_P10spec_entry4htab (void *);
++extern void gt_ggc_m_P16cxx_int_tree_map4htab (void *);
++extern void gt_ggc_m_P17named_label_entry4htab (void *);
++extern void gt_ggc_m_P12tree_int_map4htab (void *);
++extern void gt_ggc_m_P20lto_symtab_entry_def4htab (void *);
++extern void gt_ggc_m_IP9tree_node12splay_tree_s (void *);
++extern void gt_ggc_m_P9tree_nodeP9tree_node12splay_tree_s (void *);
++extern void gt_ggc_m_P12varpool_node4htab (void *);
++extern void gt_ggc_m_P13scev_info_str4htab (void *);
++extern void gt_ggc_m_P23constant_descriptor_rtx4htab (void *);
++extern void gt_ggc_m_P24constant_descriptor_tree4htab (void *);
++extern void gt_ggc_m_P12object_block4htab (void *);
++extern void gt_ggc_m_P7section4htab (void *);
++extern void gt_ggc_m_P17tree_priority_map4htab (void *);
++extern void gt_ggc_m_P8tree_map4htab (void *);
++extern void gt_ggc_m_P9type_hash4htab (void *);
++extern void gt_ggc_m_P13libfunc_entry4htab (void *);
++extern void gt_ggc_m_P23temp_slot_address_entry4htab (void *);
++extern void gt_ggc_m_P15throw_stmt_node4htab (void *);
++extern void gt_ggc_m_P9reg_attrs4htab (void *);
++extern void gt_ggc_m_P9mem_attrs4htab (void *);
++extern void gt_ggc_m_P7rtx_def4htab (void *);
++extern void gt_ggc_m_SP9tree_node12splay_tree_s (void *);
++extern void gt_ggc_m_P10vcall_insn4htab (void *);
++extern void gt_ggc_m_P16var_loc_list_def4htab (void *);
++extern void gt_ggc_m_P10die_struct4htab (void *);
++extern void gt_ggc_m_P15dwarf_file_data4htab (void *);
++extern void gt_ggc_m_P20indirect_string_node4htab (void *);
++extern void gt_ggc_m_P11cgraph_node4htab (void *);
++extern void gt_ggc_m_II12splay_tree_s (void *);
++extern void gt_ggc_m_P27cgraph_node_set_element_def4htab (void *);
++extern void gt_ggc_m_P11cgraph_edge4htab (void *);
++extern void gt_ggc_m_P9loop_exit4htab (void *);
++extern void gt_ggc_m_P24types_used_by_vars_entry4htab (void *);
++extern void gt_ggc_m_P9tree_node4htab (void *);
++
++/* functions code */
++
++void
++gt_ggc_mx_tree_llvm_map (void *x_p)
++{
++ struct tree_llvm_map * const x = (struct tree_llvm_map *)x_p;
++ if (ggc_test_and_set_mark (x))
++ {
++ gt_ggc_m_9tree_node ((*x).base.from);
++ }
++}
++
++void
++gt_ggc_m_P13tree_llvm_map4htab (void *x_p)
++{
++ struct htab * const x = (struct htab *)x_p;
++ if (ggc_test_and_set_mark (x))
++ {
++ if ((*x).entries != NULL) {
++ size_t i0;
++ for (i0 = 0; i0 != (size_t)(((*x)).size); i0++) {
++ gt_ggc_m_13tree_llvm_map ((*x).entries[i0]);
++ }
++ ggc_mark ((*x).entries);
++ }
++ }
++}
++
++/* GC roots. */
++
++EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc__gt_llvm_cache_h[] = {
++ {
++ &llvm_cache,
++ 1,
++ sizeof (llvm_cache),
++ >_ggc_mx_tree_llvm_map,
++ NULL,
++ &tree_llvm_map_marked_p
++ },
++ LAST_GGC_CACHE_TAB
++};
++
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/Internals.h dragonegg-2.9-new/include/dragonegg/Internals.h
+--- dragonegg-2.9-old/include/dragonegg/Internals.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/Internals.h 2011-04-09 00:38:28.299623547 +0200
+@@ -0,0 +1,866 @@
++//=---- Internals.h - Interface between the backend components ----*- C++ -*-=//
++//
++// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
++// Duncan Sands et al.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file declares the internal interfaces shared among the dragonegg files.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_INTERNALS_H
++#define DRAGONEGG_INTERNALS_H
++
++// LLVM headers
++#include "llvm/Intrinsics.h"
++#include "llvm/ADT/DenseMap.h"
++#include "llvm/ADT/SetVector.h"
++#include "llvm/Support/IRBuilder.h"
++#include "llvm/Support/TargetFolder.h"
++
++struct basic_block_def;
++union gimple_statement_d;
++union tree_node;
++
++namespace llvm {
++ class Module;
++ class GlobalVariable;
++ class Function;
++ class GlobalValue;
++ class BasicBlock;
++ class Instruction;
++ class AllocaInst;
++ class BranchInst;
++ class Value;
++ class Constant;
++ class ConstantInt;
++ class Type;
++ class FunctionType;
++ class TargetMachine;
++ class TargetData;
++ class DebugInfo;
++ template<typename> class AssertingVH;
++ template<typename> class TrackingVH;
++}
++using namespace llvm;
++
++typedef IRBuilder<true, TargetFolder> LLVMBuilder;
++
++// Global state.
++
++/// TheModule - This is the current global module that we are compiling into.
++///
++extern llvm::Module *TheModule;
++
++/// TheDebugInfo - This object is responsible for gather all debug information.
++/// If it's value is NULL then no debug information should be gathered.
++extern llvm::DebugInfo *TheDebugInfo;
++
++/// TheTarget - The current target being compiled for.
++///
++extern llvm::TargetMachine *TheTarget;
++
++/// TheFolder - The constant folder to use.
++extern TargetFolder *TheFolder;
++
++/// getTargetData - Return the current TargetData object from TheTarget.
++const TargetData &getTargetData();
++
++/// flag_default_initialize_globals - Whether global variables with no explicit
++/// initial value should be zero initialized.
++extern bool flag_default_initialize_globals;
++
++/// flag_odr - Whether the language being compiled obeys the One Definition Rule
++/// (i.e. if the same function is defined in multiple compilation units, all the
++/// definitions are equivalent).
++extern bool flag_odr;
++
++/// flag_vararg_requires_arguments - Do not consider functions with no arguments
++/// to take a variable number of arguments (...). If set then a function like
++/// "T foo() {}" will be treated like "T foo(void) {}" and not "T foo(...) {}".
++extern bool flag_vararg_requires_arguments;
++
++/// flag_force_vararg_prototypes - Force prototypes to take a variable number of
++/// arguments (...). This is helpful if the language front-end sometimes emits
++/// calls where the call arguments do not match the callee function declaration.
++extern bool flag_force_vararg_prototypes;
++
++/// AttributeUsedGlobals - The list of globals that are marked attribute(used).
++extern SmallSetVector<Constant *,32> AttributeUsedGlobals;
++
++extern Constant* ConvertMetadataStringToGV(const char *str);
++
++/// AddAnnotateAttrsToGlobal - Adds decls that have a
++/// annotate attribute to a vector to be emitted later.
++extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree_node *decl);
++
++// Mapping between GCC declarations and LLVM values. The GCC declaration must
++// satisfy HAS_RTL_P.
++
++/// DECL_LLVM - Returns the LLVM declaration of a global variable or function.
++extern Value *make_decl_llvm(tree_node *);
++#define DECL_LLVM(NODE) make_decl_llvm(NODE)
++
++/// SET_DECL_LLVM - Set the DECL_LLVM for NODE to LLVM.
++extern Value *set_decl_llvm(tree_node *, Value *);
++#define SET_DECL_LLVM(NODE, LLVM) set_decl_llvm(NODE, LLVM)
++
++/// DECL_LLVM_IF_SET - The DECL_LLVM for NODE, if it is set, or NULL, if it is
++/// not set.
++extern Value *get_decl_llvm(tree_node *);
++#define DECL_LLVM_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_llvm(NODE) : NULL)
++
++/// DECL_LLVM_SET_P - Returns nonzero if the DECL_LLVM for NODE has already
++/// been set.
++#define DECL_LLVM_SET_P(NODE) (DECL_LLVM_IF_SET(NODE) != NULL)
++
++/// DEFINITION_LLVM - Ensures that the body or initial value of the given GCC
++/// global will be output, and returns a declaration for it.
++Value *make_definition_llvm(tree_node *decl);
++#define DEFINITION_LLVM(NODE) make_definition_llvm(NODE)
++
++// Mapping between GCC declarations and non-negative integers. The GCC
++// declaration must not satisfy HAS_RTL_P.
++
++/// set_decl_index - Associate a non-negative number with the given GCC
++/// declaration.
++int set_decl_index(tree_node *, int);
++
++/// get_decl_index - Get the non-negative number associated with the given GCC
++/// declaration. Returns a negative value if no such association has been made.
++int get_decl_index(tree_node *);
++
++void changeLLVMConstant(Constant *Old, Constant *New);
++void register_ctor_dtor(Function *, int, bool);
++void readLLVMTypesStringTable();
++void writeLLVMTypesStringTable();
++void readLLVMValues();
++void writeLLVMValues();
++void clearTargetBuiltinCache();
++const char *extractRegisterName(tree_node *);
++void handleVisibility(tree_node *decl, GlobalValue *GV);
++Twine getLLVMAssemblerName(tree_node *);
++
++struct StructTypeConversionInfo;
++
++/// Return true if and only if field no. N from struct type T is a padding
++/// element added to match llvm struct type size and gcc struct type size.
++bool isPaddingElement(tree_node*, unsigned N);
++
++/// TypeConverter - Implement the converter from GCC types to LLVM types.
++///
++class TypeConverter {
++ /// ConvertingStruct - If we are converting a RECORD or UNION to an LLVM type
++ /// we set this flag to true.
++ bool ConvertingStruct;
++
++ /// PointersToReresolve - When ConvertingStruct is true, we handling of
++ /// POINTER_TYPE and REFERENCE_TYPE is changed to return
++ /// opaque*'s instead of recursively calling ConvertType. When this happens,
++ /// we add the POINTER_TYPE to this list.
++ ///
++ std::vector<tree_node*> PointersToReresolve;
++public:
++ TypeConverter() : ConvertingStruct(false) {}
++
++ /// ConvertType - Returns the LLVM type to use for memory that holds a value
++ /// of the given GCC type (GetRegType should be used for values in registers).
++ const Type *ConvertType(tree_node *type);
++
++ /// GCCTypeOverlapsWithLLVMTypePadding - Return true if the specified GCC type
++ /// has any data that overlaps with structure padding in the specified LLVM
++ /// type.
++ static bool GCCTypeOverlapsWithLLVMTypePadding(tree_node *t, const Type *Ty);
++
++
++ /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE
++ /// tree to an LLVM type. This does the same thing that ConvertType does, but
++ /// it also returns the function's LLVM calling convention and attributes.
++ const FunctionType *ConvertFunctionType(tree_node *type,
++ tree_node *decl,
++ tree_node *static_chain,
++ CallingConv::ID &CallingConv,
++ AttrListPtr &PAL);
++
++ /// ConvertArgListToFnType - Given a DECL_ARGUMENTS list on an GCC tree,
++ /// return the LLVM type corresponding to the function. This is useful for
++ /// turning "T foo(...)" functions into "T foo(void)" functions.
++ const FunctionType *ConvertArgListToFnType(tree_node *type,
++ tree_node *arglist,
++ tree_node *static_chain,
++ CallingConv::ID &CallingConv,
++ AttrListPtr &PAL);
++
++private:
++ const Type *ConvertRECORD(tree_node *type);
++ bool DecodeStructFields(tree_node *Field, StructTypeConversionInfo &Info);
++ void DecodeStructBitField(tree_node *Field, StructTypeConversionInfo &Info);
++ void SelectUnionMember(tree_node *type, StructTypeConversionInfo &Info);
++};
++
++extern TypeConverter *TheTypeConverter;
++
++/// ConvertType - Returns the LLVM type to use for memory that holds a value
++/// of the given GCC type (GetRegType should be used for values in registers).
++inline const Type *ConvertType(tree_node *type) {
++ return TheTypeConverter->ConvertType(type);
++}
++
++/// getDefaultValue - Return the default value to use for a constant or global
++/// that has no value specified. For example in C like languages such variables
++/// are initialized to zero, while in Ada they hold an undefined value.
++inline Constant *getDefaultValue(const Type *Ty) {
++ return flag_default_initialize_globals ?
++ Constant::getNullValue(Ty) : UndefValue::get(Ty);
++}
++
++/// GetUnitType - Returns an integer one address unit wide if 'NumUnits' is 1;
++/// otherwise returns an array of such integers with 'NumUnits' elements. For
++/// example, on a machine which has 16 bit bytes returns an i16 or an array of
++/// i16.
++extern const Type *GetUnitType(LLVMContext &C, unsigned NumUnits = 1);
++
++/// GetUnitPointerType - Returns an LLVM pointer type which points to memory one
++/// address unit wide. For example, on a machine which has 16 bit bytes returns
++/// an i16*.
++extern const Type *GetUnitPointerType(LLVMContext &C, unsigned AddrSpace = 0);
++
++/// GetFieldIndex - Return the index of the field in the given LLVM type that
++/// corresponds to the GCC field declaration 'decl'. This means that the LLVM
++/// and GCC fields start in the same byte (if 'decl' is a bitfield, this means
++/// that its first bit is within the byte the LLVM field starts at). Returns
++/// INT_MAX if there is no such LLVM field.
++int GetFieldIndex(tree_node *decl, const Type *Ty);
++
++/// getINTEGER_CSTVal - Return the specified INTEGER_CST value as a uint64_t.
++///
++uint64_t getINTEGER_CSTVal(tree_node *exp);
++
++/// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer.
++/// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is
++/// true, returns whether the value is non-negative and fits in a uint64_t.
++/// Always returns false for overflowed constants or if t is NULL.
++bool isInt64(tree_node *t, bool Unsigned);
++
++/// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If
++/// Unsigned is false, the value must fit in a int64_t. If Unsigned is true,
++/// the value must be non-negative and fit in a uint64_t. Must not be used on
++/// overflowed constants. These conditions can be checked by calling isInt64.
++uint64_t getInt64(tree_node *t, bool Unsigned);
++
++/// isPassedByInvisibleReference - Return true if the specified type should be
++/// passed by 'invisible reference'. In other words, instead of passing the
++/// thing by value, pass the address of a temporary.
++bool isPassedByInvisibleReference(tree_node *type);
++
++/// isSequentialCompatible - Return true if the specified gcc array or pointer
++/// type and the corresponding LLVM SequentialType lay out their components
++/// identically in memory, so doing a GEP accesses the right memory location.
++/// We assume that objects without a known size do not.
++extern bool isSequentialCompatible(tree_node *type);
++
++/// OffsetIsLLVMCompatible - Return true if the given field is offset from the
++/// start of the record by a constant amount which is not humongously big.
++extern bool OffsetIsLLVMCompatible(tree_node *field_decl);
++
++/// ArrayLengthOf - Returns the length of the given gcc array type, or ~0ULL if
++/// the array has variable or unknown length.
++extern uint64_t ArrayLengthOf(tree_node *type);
++
++/// isBitfield - Returns whether to treat the specified field as a bitfield.
++bool isBitfield(tree_node *field_decl);
++
++/// getFieldOffsetInBits - Return the bit offset of a FIELD_DECL in a structure.
++extern uint64_t getFieldOffsetInBits(tree_node *field);
++
++/// ValidateRegisterVariable - Check that a static "asm" variable is
++/// well-formed. If not, emit error messages and return true. If so, return
++/// false.
++bool ValidateRegisterVariable(tree_node *decl);
++
++/// MemRef - This struct holds the information needed for a memory access:
++/// a pointer to the memory, its alignment and whether the access is volatile.
++class MemRef {
++public:
++ Value *Ptr;
++ bool Volatile;
++private:
++ unsigned char LogAlign;
++public:
++ explicit MemRef() : Ptr(0), Volatile(false), LogAlign(0) {}
++ explicit MemRef(Value *P, uint32_t A, bool V) : Ptr(P), Volatile(V) {
++ // Forbid alignment 0 along with non-power-of-2 alignment values.
++ assert(isPowerOf2_32(A) && "Alignment not a power of 2!");
++ LogAlign = Log2_32(A);
++ }
++
++ uint32_t getAlignment() const {
++ return 1U << LogAlign;
++ }
++
++ void setAlignment(uint32_t A) {
++ LogAlign = Log2_32(A);
++ }
++};
++
++/// LValue - This struct represents an lvalue in the program. In particular,
++/// the Ptr member indicates the memory that the lvalue lives in. Alignment
++/// is the alignment of the memory (in bytes).If this is a bitfield reference,
++/// BitStart indicates the first bit in the memory that is part of the field
++/// and BitSize indicates the extent.
++///
++/// "LValue" is intended to be a light-weight object passed around by-value.
++class LValue : public MemRef {
++public:
++ unsigned char BitStart;
++ unsigned char BitSize;
++public:
++ explicit LValue() : BitStart(255), BitSize(255) {}
++ explicit LValue(MemRef &M) : MemRef(M), BitStart(255), BitSize(255) {}
++ LValue(Value *P, uint32_t A, bool V = false) :
++ MemRef(P, A, V), BitStart(255), BitSize(255) {}
++ LValue(Value *P, uint32_t A, unsigned BSt, unsigned BSi, bool V = false) :
++ MemRef(P, A, V), BitStart(BSt), BitSize(BSi) {
++ assert(BitStart == BSt && BitSize == BSi &&
++ "Bit values larger than 256?");
++ }
++
++ bool isBitfield() const { return BitStart != 255; }
++};
++
++/// PhiRecord - This struct holds the LLVM PHI node associated with a GCC phi.
++struct PhiRecord {
++ gimple_statement_d *gcc_phi;
++ PHINode *PHI;
++};
++
++/// TreeToLLVM - An instance of this class is created and used to convert the
++/// body of each function to LLVM.
++///
++class TreeToLLVM {
++ // State that is initialized when the function starts.
++ const TargetData &TD;
++ tree_node *FnDecl;
++ Function *Fn;
++ BasicBlock *ReturnBB;
++ unsigned ReturnOffset;
++
++ // State that changes as the function is emitted.
++
++ /// Builder - Instruction creator, the location to insert into is always the
++ /// same as &Fn->back().
++ LLVMBuilder Builder;
++
++ // AllocaInsertionPoint - Place to insert alloca instructions. Lazily created
++ // and managed by CreateTemporary.
++ Instruction *AllocaInsertionPoint;
++
++ // SSAInsertionPoint - Place to insert reads corresponding to SSA default
++ // definitions.
++ Instruction *SSAInsertionPoint;
++
++ /// BasicBlocks - Map from GCC to LLVM basic blocks.
++ DenseMap<basic_block_def *, BasicBlock*> BasicBlocks;
++
++ /// LocalDecls - Map from local declarations to their associated LLVM values.
++ DenseMap<tree_node *, AssertingVH<Value> > LocalDecls;
++
++ /// PendingPhis - Phi nodes which have not yet been populated with operands.
++ SmallVector<PhiRecord, 16> PendingPhis;
++
++ // SSANames - Map from GCC ssa names to the defining LLVM value.
++ DenseMap<tree_node *, TrackingVH<Value> > SSANames;
++
++public:
++
++ //===---------------------- Local Declarations --------------------------===//
++
++ /// DECL_LOCAL - Like DECL_LLVM, returns the LLVM declaration of a variable or
++ /// function. However DECL_LOCAL can be used with declarations local to the
++ /// current function as well as with global declarations.
++ Value *make_decl_local(tree_node *);
++ #define DECL_LOCAL(NODE) make_decl_local(NODE)
++
++ /// DEFINITION_LOCAL - Like DEFINITION_LLVM, ensures that the initial value or
++ /// body of a variable or function will be output. However DEFINITION_LOCAL
++ /// can be used with declarations local to the current function as well as
++ /// with global declarations.
++ Value *make_definition_local(tree_node *);
++ #define DEFINITION_LOCAL(NODE) make_definition_local(NODE)
++
++ /// SET_DECL_LOCAL - Set the DECL_LOCAL for NODE to LLVM.
++ Value *set_decl_local(tree_node *, Value *);
++ #define SET_DECL_LOCAL(NODE, LLVM) set_decl_local(NODE, LLVM)
++
++ /// DECL_LOCAL_IF_SET - The DECL_LOCAL for NODE, if it is set, or NULL, if it
++ /// is not set.
++ Value *get_decl_local(tree_node *);
++ #define DECL_LOCAL_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_local(NODE) : NULL)
++
++ /// DECL_LOCAL_SET_P - Returns nonzero if the DECL_LOCAL for NODE has already
++ /// been set.
++ #define DECL_LOCAL_SET_P(NODE) (DECL_LOCAL_IF_SET(NODE) != NULL)
++
++
++private:
++
++ //===---------------------- Exception Handling --------------------------===//
++
++ /// NormalInvokes - Mapping from landing pad number to the set of invoke
++ /// instructions that unwind to that landing pad.
++ SmallVector<SmallVector<InvokeInst *, 8>, 16> NormalInvokes;
++
++ /// ExceptionPtrs - Mapping from EH region index to the local holding the
++ /// exception pointer for that region.
++ SmallVector<AllocaInst *, 16> ExceptionPtrs;
++
++ /// ExceptionFilters - Mapping from EH region index to the local holding the
++ /// filter value for that region.
++ SmallVector<AllocaInst *, 16> ExceptionFilters;
++
++ /// FailureBlocks - Mapping from the index of a must-not-throw EH region to
++ /// the block containing the failure code for the region (the code that is
++ /// run if an exception is thrown in this region).
++ SmallVector<BasicBlock *, 16> FailureBlocks;
++
++ /// RewindBB - Block containing code that continues unwinding an exception.
++ BasicBlock *RewindBB;
++
++ /// RewindTmp - Local holding the exception to continue unwinding.
++ AllocaInst *RewindTmp;
++
++public:
++ TreeToLLVM(tree_node *fndecl);
++ ~TreeToLLVM();
++
++ /// getFUNCTION_DECL - Return the FUNCTION_DECL node for the current function
++ /// being compiled.
++ tree_node *getFUNCTION_DECL() const { return FnDecl; }
++
++ /// EmitFunction - Convert 'fndecl' to LLVM code.
++ Function *EmitFunction();
++
++ /// EmitBasicBlock - Convert the given basic block.
++ void EmitBasicBlock(basic_block_def *bb);
++
++ /// EmitLV - Convert the specified l-value tree node to LLVM code, returning
++ /// the address of the result.
++ LValue EmitLV(tree_node *exp);
++
++ void TODO(tree_node *exp = 0);
++
++ /// CastToAnyType - Cast the specified value to the specified type regardless
++ /// of the types involved. This is an inferred cast.
++ Value *CastToAnyType (Value *V, bool VSigned, const Type *Ty, bool TySigned);
++
++ /// CastToUIntType - Cast the specified value to the specified type assuming
++ /// that V's type and Ty are integral types. This arbitrates between BitCast,
++ /// Trunc and ZExt.
++ Value *CastToUIntType(Value *V, const Type *Ty);
++
++ /// CastToSIntType - Cast the specified value to the specified type assuming
++ /// that V's type and Ty are integral types. This arbitrates between BitCast,
++ /// Trunc and SExt.
++ Value *CastToSIntType(Value *V, const Type *Ty);
++
++ /// CastToFPType - Cast the specified value to the specified type assuming
++ /// that V's type and Ty are floating point types. This arbitrates between
++ /// BitCast, FPTrunc and FPExt.
++ Value *CastToFPType(Value *V, const Type *Ty);
++
++ /// CreateAnyAdd - Add two LLVM scalar values with the given GCC type. Does
++ /// not support complex numbers. The type is used to set overflow flags.
++ Value *CreateAnyAdd(Value *LHS, Value *RHS, tree_node *type);
++
++ /// CreateAnyMul - Multiply two LLVM scalar values with the given GCC type.
++ /// Does not support complex numbers. The type is used to set overflow flags.
++ Value *CreateAnyMul(Value *LHS, Value *RHS, tree_node *type);
++
++ /// CreateAnyNeg - Negate an LLVM scalar value with the given GCC type. Does
++ /// not support complex numbers. The type is used to set overflow flags.
++ Value *CreateAnyNeg(Value *V, tree_node *type);
++
++ /// CreateAnySub - Subtract two LLVM scalar values with the given GCC type.
++ /// Does not support complex numbers.
++ Value *CreateAnySub(Value *LHS, Value *RHS, tree_node *type);
++
++ /// CreateTemporary - Create a new alloca instruction of the specified type,
++ /// inserting it into the entry block and returning it. The resulting
++ /// instruction's type is a pointer to the specified type.
++ AllocaInst *CreateTemporary(const Type *Ty, unsigned align=0);
++
++ /// CreateTempLoc - Like CreateTemporary, but returns a MemRef.
++ MemRef CreateTempLoc(const Type *Ty);
++
++ /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
++ /// GCC type specified by GCCType to know which elements to copy.
++ void EmitAggregateCopy(MemRef DestLoc, MemRef SrcLoc, tree_node *GCCType);
++
++ /// EmitAggregate - Store the specified tree node into the location given by
++ /// DestLoc.
++ void EmitAggregate(tree_node *exp, const MemRef &DestLoc);
++
++private: // Helper functions.
++
++ /// StartFunctionBody - Start the emission of 'fndecl', outputing all
++ /// declarations for parameters and setting things up.
++ void StartFunctionBody();
++
++ /// FinishFunctionBody - Once the body of the function has been emitted, this
++ /// cleans up and returns the result function.
++ Function *FinishFunctionBody();
++
++ /// PopulatePhiNodes - Populate generated phi nodes with their operands.
++ void PopulatePhiNodes();
++
++ /// getBasicBlock - Find or create the LLVM basic block corresponding to BB.
++ BasicBlock *getBasicBlock(basic_block_def *bb);
++
++ /// getLabelDeclBlock - Lazily get and create a basic block for the specified
++ /// label.
++ BasicBlock *getLabelDeclBlock(tree_node *LabelDecl);
++
++ /// DefineSSAName - Use the given value as the definition of the given SSA
++ /// name. Returns the provided value as a convenience.
++ Value *DefineSSAName(tree_node *reg, Value *Val);
++
++ /// BeginBlock - Add the specified basic block to the end of the function. If
++ /// the previous block falls through into it, add an explicit branch.
++ void BeginBlock(BasicBlock *BB);
++
++ /// EmitAggregateZero - Zero the elements of DestLoc.
++ void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);
++
++ /// EmitMemCpy/EmitMemMove/EmitMemSet - Emit an llvm.memcpy/llvm.memmove or
++ /// llvm.memset call with the specified operands. Returns DestPtr bitcast
++ /// to i8*.
++ Value *EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
++ Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
++ Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
++
++ /// EmitLandingPads - Emit EH landing pads.
++ void EmitLandingPads();
++
++ /// EmitFailureBlocks - Emit the blocks containing failure code executed when
++ /// an exception is thrown in a must-not-throw region.
++ void EmitFailureBlocks();
++
++ /// EmitRewindBlock - Emit the block containing code to continue unwinding an
++ /// exception.
++ void EmitRewindBlock();
++
++ /// EmitDebugInfo - Return true if debug info is to be emitted for current
++ /// function.
++ bool EmitDebugInfo();
++
++private: // Helpers for exception handling.
++
++ /// getLandingPad - Return the landing pad for the given exception handling
++ /// region, creating it if necessary.
++ BasicBlock *getLandingPad(unsigned RegionNo);
++
++ /// getExceptionPtr - Return the local holding the exception pointer for the
++ /// given exception handling region, creating it if necessary.
++ AllocaInst *getExceptionPtr(unsigned RegionNo);
++
++ /// getExceptionFilter - Return the local holding the filter value for the
++ /// given exception handling region, creating it if necessary.
++ AllocaInst *getExceptionFilter(unsigned RegionNo);
++
++ /// getFailureBlock - Return the basic block containing the failure code for
++ /// the given exception handling region, creating it if necessary.
++ BasicBlock *getFailureBlock(unsigned RegionNo);
++
++private:
++ void EmitAutomaticVariableDecl(tree_node *decl);
++
++ /// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic
++ void EmitAnnotateIntrinsic(Value *V, tree_node *decl);
++
++ /// EmitTypeGcroot - Emits call to make type a gcroot
++ void EmitTypeGcroot(Value *V);
++
++private:
++
++ //===------------------ Render* - Convert GIMPLE to LLVM ----------------===//
++
++ void RenderGIMPLE_ASM(gimple_statement_d *stmt);
++ void RenderGIMPLE_ASSIGN(gimple_statement_d *stmt);
++ void RenderGIMPLE_CALL(gimple_statement_d *stmt);
++ void RenderGIMPLE_COND(gimple_statement_d *stmt);
++ void RenderGIMPLE_EH_DISPATCH(gimple_statement_d *stmt);
++ void RenderGIMPLE_GOTO(gimple_statement_d *stmt);
++ void RenderGIMPLE_RESX(gimple_statement_d *stmt);
++ void RenderGIMPLE_RETURN(gimple_statement_d *stmt);
++ void RenderGIMPLE_SWITCH(gimple_statement_d *stmt);
++
++ // Render helpers.
++
++ /// EmitAssignRHS - Convert the RHS of a scalar GIMPLE_ASSIGN to LLVM.
++ Value *EmitAssignRHS(gimple_statement_d *stmt);
++
++ /// EmitAssignSingleRHS - Helper for EmitAssignRHS. Handles those RHS that
++ /// are not register expressions.
++ Value *EmitAssignSingleRHS(tree_node *rhs);
++
++ /// OutputCallRHS - Convert the RHS of a GIMPLE_CALL.
++ Value *OutputCallRHS(gimple_statement_d *stmt, const MemRef *DestLoc);
++
++ /// WriteScalarToLHS - Store RHS, a non-aggregate value, into the given LHS.
++ void WriteScalarToLHS(tree_node *lhs, Value *Scalar);
++
++private:
++
++ //===---------- EmitReg* - Convert register expression to LLVM ----------===//
++
++ /// GetRegType - Returns the LLVM type to use for registers that hold a value
++ /// of the scalar GCC type 'type'. All of the EmitReg* routines use this to
++ /// determine the LLVM type to return.
++ const Type *GetRegType(tree_node *type);
++
++ /// UselesslyTypeConvert - The useless_type_conversion_p predicate implicitly
++ /// defines the GCC middle-end type system. For scalar GCC types inner_type
++ /// and outer_type, if 'useless_type_conversion_p(outer_type, inner_type)' is
++ /// true then the corresponding LLVM inner and outer types (see GetRegType)
++ /// are equal except possibly if they are both pointer types (casts to 'void*'
++ /// are considered useless for example) or types derived from pointer types
++ /// (vector types with pointer element type are the only possibility here).
++ /// This method converts LLVM values of the inner type to the outer type.
++ Value *UselesslyTypeConvert(Value *V, const Type *Ty) {
++ return Builder.CreateBitCast(V, Ty);
++ }
++
++ /// EmitRegister - Convert the specified gimple register or local constant of
++ /// register type to an LLVM value. Only creates code in the entry block.
++ Value *EmitRegister(tree_node *reg);
++
++ /// EmitReg_SSA_NAME - Return the defining value of the given SSA_NAME.
++ /// Only creates code in the entry block.
++ Value *EmitReg_SSA_NAME(tree_node *reg);
++
++ // Unary expressions.
++ Value *EmitReg_ABS_EXPR(tree_node *op);
++ Value *EmitReg_BIT_NOT_EXPR(tree_node *op);
++ Value *EmitReg_CONJ_EXPR(tree_node *op);
++ Value *EmitReg_CONVERT_EXPR(tree_node *type, tree_node *op);
++ Value *EmitReg_NEGATE_EXPR(tree_node *op);
++ Value *EmitReg_PAREN_EXPR(tree_node *exp);
++ Value *EmitReg_TRUTH_NOT_EXPR(tree_node *type, tree_node *op);
++
++ // Comparisons.
++
++ /// EmitCompare - Compare LHS with RHS using the appropriate comparison code.
++ /// The result is an i1 boolean.
++ Value *EmitCompare(tree_node *lhs, tree_node *rhs, unsigned code);
++
++ // Binary expressions.
++ Value *EmitReg_MinMaxExpr(tree_node *type, tree_node *op0, tree_node *op1,
++ unsigned UIPred, unsigned SIPred, unsigned Opc,
++ bool isMax);
++ Value *EmitReg_RotateOp(tree_node *type, tree_node *op0, tree_node *op1,
++ unsigned Opc1, unsigned Opc2);
++ Value *EmitReg_ShiftOp(tree_node *op0, tree_node *op1, unsigned Opc);
++ Value *EmitReg_TruthOp(tree_node *type, tree_node *op0, tree_node *op1,
++ unsigned Opc);
++ Value *EmitReg_BIT_AND_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_BIT_IOR_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_BIT_XOR_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_CEIL_DIV_EXPR(tree_node *type, tree_node *op0, tree_node *op1);
++ Value *EmitReg_COMPLEX_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_FLOOR_DIV_EXPR(tree_node *type, tree_node *op0,
++ tree_node *op1);
++ Value *EmitReg_FLOOR_MOD_EXPR(tree_node *type, tree_node *op0,
++ tree_node *op1);
++ Value *EmitReg_MINUS_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_MULT_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_PLUS_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_POINTER_PLUS_EXPR(tree_node *type, tree_node *op0,
++ tree_node *op1);
++ Value *EmitReg_RDIV_EXPR(tree_node *op0, tree_node *op1);
++ Value *EmitReg_ROUND_DIV_EXPR(tree_node *type, tree_node *op0,
++ tree_node *op1);
++ Value *EmitReg_TRUNC_DIV_EXPR(tree_node *op0, tree_node *op1, bool isExact);
++ Value *EmitReg_TRUNC_MOD_EXPR(tree_node *op0, tree_node *op1);
++
++ Value *EmitLoadOfLValue(tree_node *exp);
++ Value *EmitOBJ_TYPE_REF(tree_node *exp);
++ Value *EmitADDR_EXPR(tree_node *exp);
++ Value *EmitCallOf(Value *Callee, gimple_statement_d *stmt,
++ const MemRef *DestLoc, const AttrListPtr &PAL);
++ CallInst *EmitSimpleCall(StringRef CalleeName, tree_node *ret_type,
++ /* arguments */ ...) END_WITH_NULL;
++ Value *EmitFieldAnnotation(Value *FieldPtr, tree_node *FieldDecl);
++
++ // Inline Assembly and Register Variables.
++ Value *EmitReadOfRegisterVariable(tree_node *vardecl);
++ void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);
++
++ // Helpers for Builtin Function Expansion.
++ void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);
++ Value *BuildVector(const std::vector<Value*> &Elts);
++ Value *BuildVector(Value *Elt, ...);
++ Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
++ Value *BuildBinaryAtomicBuiltin(gimple_statement_d *stmt, Intrinsic::ID id);
++ Value *BuildCmpAndSwapAtomicBuiltin(gimple_statement_d *stmt, tree_node *type,
++ bool isBool);
++
++ // Builtin Function Expansion.
++ bool EmitBuiltinCall(gimple_statement_d *stmt, tree_node *fndecl,
++ const MemRef *DestLoc, Value *&Result);
++ bool EmitFrontendExpandedBuiltinCall(gimple_statement_d *stmt,
++ tree_node *fndecl, const MemRef *DestLoc,
++ Value *&Result);
++ bool EmitBuiltinUnaryOp(Value *InVal, Value *&Result, Intrinsic::ID Id);
++ Value *EmitBuiltinSQRT(gimple_statement_d *stmt);
++ Value *EmitBuiltinPOWI(gimple_statement_d *stmt);
++ Value *EmitBuiltinPOW(gimple_statement_d *stmt);
++ Value *EmitBuiltinLCEIL(gimple_statement_d *stmt);
++ Value *EmitBuiltinLFLOOR(gimple_statement_d *stmt);
++
++ bool EmitBuiltinConstantP(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinAlloca(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinExpect(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinExtendPointer(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinVAStart(gimple_statement_d *stmt);
++ bool EmitBuiltinVAEnd(gimple_statement_d *stmt);
++ bool EmitBuiltinVACopy(gimple_statement_d *stmt);
++ bool EmitBuiltinMemCopy(gimple_statement_d *stmt, Value *&Result,
++ bool isMemMove, bool SizeCheck);
++ bool EmitBuiltinMemSet(gimple_statement_d *stmt, Value *&Result,
++ bool SizeCheck);
++ bool EmitBuiltinBZero(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinPrefetch(gimple_statement_d *stmt);
++ bool EmitBuiltinReturnAddr(gimple_statement_d *stmt, Value *&Result,
++ bool isFrame);
++ bool EmitBuiltinExtractReturnAddr(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinFrobReturnAddr(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinStackSave(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinStackRestore(gimple_statement_d *stmt);
++ bool EmitBuiltinEHPointer(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinDwarfCFA(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinDwarfSPColumn(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinEHReturnDataRegno(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinEHReturn(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinInitDwarfRegSizes(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinUnwindInit(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinAdjustTrampoline(gimple_statement_d *stmt, Value *&Result);
++ bool EmitBuiltinInitTrampoline(gimple_statement_d *stmt, Value *&Result);
++
++ // Complex Math Expressions.
++ Value *CreateComplex(Value *Real, Value *Imag, tree_node *elt_type);
++ void SplitComplex(Value *Complex, Value *&Real, Value *&Imag,
++ tree_node *elt_type);
++
++ // L-Value Expressions.
++ LValue EmitLV_ARRAY_REF(tree_node *exp);
++ LValue EmitLV_BIT_FIELD_REF(tree_node *exp);
++ LValue EmitLV_COMPONENT_REF(tree_node *exp);
++ LValue EmitLV_DECL(tree_node *exp);
++ LValue EmitLV_INDIRECT_REF(tree_node *exp);
++ LValue EmitLV_VIEW_CONVERT_EXPR(tree_node *exp);
++ LValue EmitLV_WITH_SIZE_EXPR(tree_node *exp);
++ LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
++ LValue EmitLV_SSA_NAME(tree_node *exp);
++ LValue EmitLV_TARGET_MEM_REF(tree_node *exp);
++
++ // Constant Expressions.
++ Value *EmitINTEGER_CST(tree_node *exp);
++ Value *EmitREAL_CST(tree_node *exp);
++ Value *EmitCONSTRUCTOR(tree_node *exp, const MemRef *DestLoc);
++
++
++ // Emit helpers.
++
++ /// EmitMinInvariant - The given value is constant in this function. Return
++ /// the corresponding LLVM value. Only creates code in the entry block.
++ Value *EmitMinInvariant(tree_node *reg);
++
++ /// EmitInvariantAddress - The given address is constant in this function.
++ /// Return the corresponding LLVM value. Only creates code in the entry block.
++ Value *EmitInvariantAddress(tree_node *addr);
++
++ /// EmitRegisterConstant - Convert the given global constant of register type
++ /// to an LLVM constant. Creates no code, only constants.
++ Constant *EmitRegisterConstant(tree_node *reg);
++
++ /// EmitComplexRegisterConstant - Turn the given COMPLEX_CST into an LLVM
++ /// constant of the corresponding register type.
++ Constant *EmitComplexRegisterConstant(tree_node *reg);
++
++ /// EmitIntegerRegisterConstant - Turn the given INTEGER_CST into an LLVM
++ /// constant of the corresponding register type.
++ Constant *EmitIntegerRegisterConstant(tree_node *reg);
++
++ /// EmitRealRegisterConstant - Turn the given REAL_CST into an LLVM constant
++ /// of the corresponding register type.
++ Constant *EmitRealRegisterConstant(tree_node *reg);
++
++ /// EmitConstantVectorConstructor - Turn the given constant CONSTRUCTOR into
++ /// an LLVM constant of the corresponding vector register type.
++ Constant *EmitConstantVectorConstructor(tree_node *reg);
++
++ /// EmitVectorRegisterConstant - Turn the given VECTOR_CST into an LLVM
++ /// constant of the corresponding register type.
++ Constant *EmitVectorRegisterConstant(tree_node *reg);
++
++ /// Mem2Reg - Convert a value of in-memory type (that given by ConvertType)
++ /// to in-register type (that given by GetRegType). TODO: Eliminate these
++ /// methods: "memory" values should never be held in registers. Currently
++ /// this is mainly used for marshalling function parameters and return values,
++ /// but that should be completely independent of the reg vs mem value logic.
++ Value *Mem2Reg(Value *V, tree_node *type, LLVMBuilder &Builder);
++ Constant *Mem2Reg(Constant *C, tree_node *type, TargetFolder &Folder);
++
++ /// Reg2Mem - Convert a value of in-register type (that given by GetRegType)
++ /// to in-memory type (that given by ConvertType). TODO: Eliminate this
++ /// method: "memory" values should never be held in registers. Currently
++ /// this is mainly used for marshalling function parameters and return values,
++ /// but that should be completely independent of the reg vs mem value logic.
++ Value *Reg2Mem(Value *V, tree_node *type, LLVMBuilder &Builder);
++
++ /// EmitMemory - Convert the specified gimple register or local constant of
++ /// register type to an LLVM value with in-memory type (given by ConvertType).
++ /// TODO: Eliminate this method, see Mem2Reg and Reg2Mem above.
++ Value *EmitMemory(tree_node *reg);
++
++ /// LoadRegisterFromMemory - Loads a value of the given scalar GCC type from
++ /// the memory location pointed to by Loc. Takes care of adjusting for any
++ /// differences between in-memory and in-register types (the returned value
++ /// is of in-register type, as returned by GetRegType).
++ Value *LoadRegisterFromMemory(MemRef Loc, tree_node *type,
++ LLVMBuilder &Builder);
++
++ /// StoreRegisterToMemory - Stores the given value to the memory pointed to by
++ /// Loc. Takes care of adjusting for any differences between the value's type
++ /// (which is the in-register type given by GetRegType) and the in-memory type.
++ void StoreRegisterToMemory(Value *V, MemRef Loc, tree_node *type,
++ LLVMBuilder &Builder);
++
++private:
++ // Optional target defined builtin intrinsic expanding function.
++ bool TargetIntrinsicLower(gimple_statement_d *stmt,
++ tree_node *fndecl,
++ const MemRef *DestLoc,
++ Value *&Result,
++ const Type *ResultType,
++ std::vector<Value*> &Ops);
++
++public:
++ // Helper for taking the address of a label.
++ Constant *AddressOfLABEL_DECL(tree_node *exp);
++};
++
++#endif /* DRAGONEGG_INTERNALS_H */
+diff -r -u -N dragonegg-2.9-old/include/dragonegg/Trees.h dragonegg-2.9-new/include/dragonegg/Trees.h
+--- dragonegg-2.9-old/include/dragonegg/Trees.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/include/dragonegg/Trees.h 2011-04-09 00:38:06.630097839 +0200
+@@ -0,0 +1,44 @@
++//=---- Trees.h - Utility functions for working with GCC trees ----*- C++ -*-=//
++//
++// Copyright (C) 2010, 2011 Duncan Sands.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file declares utility functions for working with GCC trees.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_TREES_H
++#define DRAGONEGG_TREES_H
++
++// System headers
++#include <string>
++
++union tree_node;
++
++/// getDescriptiveName - Return a helpful name for the given tree, or an empty
++/// string if no sensible name was found. These names are used to make the IR
++/// more readable, and have no official status.
++std::string getDescriptiveName(union tree_node *t);
++
++/// hasNUW - Return whether overflowing unsigned operations on this type result
++/// in undefined behaviour.
++bool hasNUW(tree_node *type);
++
++/// hasNSW - Return whether overflowing signed operations on this type result
++/// in undefined behaviour.
++bool hasNSW(tree_node *type);
++
++#endif /* DRAGONEGG_TREES_H */
+diff -r -u -N dragonegg-2.9-old/Internals.h dragonegg-2.9-new/Internals.h
+--- dragonegg-2.9-old/Internals.h 2011-03-29 08:26:30.000000000 +0200
++++ dragonegg-2.9-new/Internals.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,866 +0,0 @@
+-//=---- Internals.h - Interface between the backend components ----*- C++ -*-=//
+-//
+-// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Chris Lattner,
+-// Duncan Sands et al.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file declares the internal interfaces shared among the dragonegg files.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_INTERNALS_H
+-#define DRAGONEGG_INTERNALS_H
+-
+-// LLVM headers
+-#include "llvm/Intrinsics.h"
+-#include "llvm/ADT/DenseMap.h"
+-#include "llvm/ADT/SetVector.h"
+-#include "llvm/Support/IRBuilder.h"
+-#include "llvm/Support/TargetFolder.h"
+-
+-struct basic_block_def;
+-union gimple_statement_d;
+-union tree_node;
+-
+-namespace llvm {
+- class Module;
+- class GlobalVariable;
+- class Function;
+- class GlobalValue;
+- class BasicBlock;
+- class Instruction;
+- class AllocaInst;
+- class BranchInst;
+- class Value;
+- class Constant;
+- class ConstantInt;
+- class Type;
+- class FunctionType;
+- class TargetMachine;
+- class TargetData;
+- class DebugInfo;
+- template<typename> class AssertingVH;
+- template<typename> class TrackingVH;
+-}
+-using namespace llvm;
+-
+-typedef IRBuilder<true, TargetFolder> LLVMBuilder;
+-
+-// Global state.
+-
+-/// TheModule - This is the current global module that we are compiling into.
+-///
+-extern llvm::Module *TheModule;
+-
+-/// TheDebugInfo - This object is responsible for gather all debug information.
+-/// If it's value is NULL then no debug information should be gathered.
+-extern llvm::DebugInfo *TheDebugInfo;
+-
+-/// TheTarget - The current target being compiled for.
+-///
+-extern llvm::TargetMachine *TheTarget;
+-
+-/// TheFolder - The constant folder to use.
+-extern TargetFolder *TheFolder;
+-
+-/// getTargetData - Return the current TargetData object from TheTarget.
+-const TargetData &getTargetData();
+-
+-/// flag_default_initialize_globals - Whether global variables with no explicit
+-/// initial value should be zero initialized.
+-extern bool flag_default_initialize_globals;
+-
+-/// flag_odr - Whether the language being compiled obeys the One Definition Rule
+-/// (i.e. if the same function is defined in multiple compilation units, all the
+-/// definitions are equivalent).
+-extern bool flag_odr;
+-
+-/// flag_vararg_requires_arguments - Do not consider functions with no arguments
+-/// to take a variable number of arguments (...). If set then a function like
+-/// "T foo() {}" will be treated like "T foo(void) {}" and not "T foo(...) {}".
+-extern bool flag_vararg_requires_arguments;
+-
+-/// flag_force_vararg_prototypes - Force prototypes to take a variable number of
+-/// arguments (...). This is helpful if the language front-end sometimes emits
+-/// calls where the call arguments do not match the callee function declaration.
+-extern bool flag_force_vararg_prototypes;
+-
+-/// AttributeUsedGlobals - The list of globals that are marked attribute(used).
+-extern SmallSetVector<Constant *,32> AttributeUsedGlobals;
+-
+-extern Constant* ConvertMetadataStringToGV(const char *str);
+-
+-/// AddAnnotateAttrsToGlobal - Adds decls that have a
+-/// annotate attribute to a vector to be emitted later.
+-extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree_node *decl);
+-
+-// Mapping between GCC declarations and LLVM values. The GCC declaration must
+-// satisfy HAS_RTL_P.
+-
+-/// DECL_LLVM - Returns the LLVM declaration of a global variable or function.
+-extern Value *make_decl_llvm(tree_node *);
+-#define DECL_LLVM(NODE) make_decl_llvm(NODE)
+-
+-/// SET_DECL_LLVM - Set the DECL_LLVM for NODE to LLVM.
+-extern Value *set_decl_llvm(tree_node *, Value *);
+-#define SET_DECL_LLVM(NODE, LLVM) set_decl_llvm(NODE, LLVM)
+-
+-/// DECL_LLVM_IF_SET - The DECL_LLVM for NODE, if it is set, or NULL, if it is
+-/// not set.
+-extern Value *get_decl_llvm(tree_node *);
+-#define DECL_LLVM_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_llvm(NODE) : NULL)
+-
+-/// DECL_LLVM_SET_P - Returns nonzero if the DECL_LLVM for NODE has already
+-/// been set.
+-#define DECL_LLVM_SET_P(NODE) (DECL_LLVM_IF_SET(NODE) != NULL)
+-
+-/// DEFINITION_LLVM - Ensures that the body or initial value of the given GCC
+-/// global will be output, and returns a declaration for it.
+-Value *make_definition_llvm(tree_node *decl);
+-#define DEFINITION_LLVM(NODE) make_definition_llvm(NODE)
+-
+-// Mapping between GCC declarations and non-negative integers. The GCC
+-// declaration must not satisfy HAS_RTL_P.
+-
+-/// set_decl_index - Associate a non-negative number with the given GCC
+-/// declaration.
+-int set_decl_index(tree_node *, int);
+-
+-/// get_decl_index - Get the non-negative number associated with the given GCC
+-/// declaration. Returns a negative value if no such association has been made.
+-int get_decl_index(tree_node *);
+-
+-void changeLLVMConstant(Constant *Old, Constant *New);
+-void register_ctor_dtor(Function *, int, bool);
+-void readLLVMTypesStringTable();
+-void writeLLVMTypesStringTable();
+-void readLLVMValues();
+-void writeLLVMValues();
+-void clearTargetBuiltinCache();
+-const char *extractRegisterName(tree_node *);
+-void handleVisibility(tree_node *decl, GlobalValue *GV);
+-Twine getLLVMAssemblerName(tree_node *);
+-
+-struct StructTypeConversionInfo;
+-
+-/// Return true if and only if field no. N from struct type T is a padding
+-/// element added to match llvm struct type size and gcc struct type size.
+-bool isPaddingElement(tree_node*, unsigned N);
+-
+-/// TypeConverter - Implement the converter from GCC types to LLVM types.
+-///
+-class TypeConverter {
+- /// ConvertingStruct - If we are converting a RECORD or UNION to an LLVM type
+- /// we set this flag to true.
+- bool ConvertingStruct;
+-
+- /// PointersToReresolve - When ConvertingStruct is true, we handling of
+- /// POINTER_TYPE and REFERENCE_TYPE is changed to return
+- /// opaque*'s instead of recursively calling ConvertType. When this happens,
+- /// we add the POINTER_TYPE to this list.
+- ///
+- std::vector<tree_node*> PointersToReresolve;
+-public:
+- TypeConverter() : ConvertingStruct(false) {}
+-
+- /// ConvertType - Returns the LLVM type to use for memory that holds a value
+- /// of the given GCC type (GetRegType should be used for values in registers).
+- const Type *ConvertType(tree_node *type);
+-
+- /// GCCTypeOverlapsWithLLVMTypePadding - Return true if the specified GCC type
+- /// has any data that overlaps with structure padding in the specified LLVM
+- /// type.
+- static bool GCCTypeOverlapsWithLLVMTypePadding(tree_node *t, const Type *Ty);
+-
+-
+- /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE
+- /// tree to an LLVM type. This does the same thing that ConvertType does, but
+- /// it also returns the function's LLVM calling convention and attributes.
+- const FunctionType *ConvertFunctionType(tree_node *type,
+- tree_node *decl,
+- tree_node *static_chain,
+- CallingConv::ID &CallingConv,
+- AttrListPtr &PAL);
+-
+- /// ConvertArgListToFnType - Given a DECL_ARGUMENTS list on an GCC tree,
+- /// return the LLVM type corresponding to the function. This is useful for
+- /// turning "T foo(...)" functions into "T foo(void)" functions.
+- const FunctionType *ConvertArgListToFnType(tree_node *type,
+- tree_node *arglist,
+- tree_node *static_chain,
+- CallingConv::ID &CallingConv,
+- AttrListPtr &PAL);
+-
+-private:
+- const Type *ConvertRECORD(tree_node *type);
+- bool DecodeStructFields(tree_node *Field, StructTypeConversionInfo &Info);
+- void DecodeStructBitField(tree_node *Field, StructTypeConversionInfo &Info);
+- void SelectUnionMember(tree_node *type, StructTypeConversionInfo &Info);
+-};
+-
+-extern TypeConverter *TheTypeConverter;
+-
+-/// ConvertType - Returns the LLVM type to use for memory that holds a value
+-/// of the given GCC type (GetRegType should be used for values in registers).
+-inline const Type *ConvertType(tree_node *type) {
+- return TheTypeConverter->ConvertType(type);
+-}
+-
+-/// getDefaultValue - Return the default value to use for a constant or global
+-/// that has no value specified. For example in C like languages such variables
+-/// are initialized to zero, while in Ada they hold an undefined value.
+-inline Constant *getDefaultValue(const Type *Ty) {
+- return flag_default_initialize_globals ?
+- Constant::getNullValue(Ty) : UndefValue::get(Ty);
+-}
+-
+-/// GetUnitType - Returns an integer one address unit wide if 'NumUnits' is 1;
+-/// otherwise returns an array of such integers with 'NumUnits' elements. For
+-/// example, on a machine which has 16 bit bytes returns an i16 or an array of
+-/// i16.
+-extern const Type *GetUnitType(LLVMContext &C, unsigned NumUnits = 1);
+-
+-/// GetUnitPointerType - Returns an LLVM pointer type which points to memory one
+-/// address unit wide. For example, on a machine which has 16 bit bytes returns
+-/// an i16*.
+-extern const Type *GetUnitPointerType(LLVMContext &C, unsigned AddrSpace = 0);
+-
+-/// GetFieldIndex - Return the index of the field in the given LLVM type that
+-/// corresponds to the GCC field declaration 'decl'. This means that the LLVM
+-/// and GCC fields start in the same byte (if 'decl' is a bitfield, this means
+-/// that its first bit is within the byte the LLVM field starts at). Returns
+-/// INT_MAX if there is no such LLVM field.
+-int GetFieldIndex(tree_node *decl, const Type *Ty);
+-
+-/// getINTEGER_CSTVal - Return the specified INTEGER_CST value as a uint64_t.
+-///
+-uint64_t getINTEGER_CSTVal(tree_node *exp);
+-
+-/// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer.
+-/// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is
+-/// true, returns whether the value is non-negative and fits in a uint64_t.
+-/// Always returns false for overflowed constants or if t is NULL.
+-bool isInt64(tree_node *t, bool Unsigned);
+-
+-/// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If
+-/// Unsigned is false, the value must fit in a int64_t. If Unsigned is true,
+-/// the value must be non-negative and fit in a uint64_t. Must not be used on
+-/// overflowed constants. These conditions can be checked by calling isInt64.
+-uint64_t getInt64(tree_node *t, bool Unsigned);
+-
+-/// isPassedByInvisibleReference - Return true if the specified type should be
+-/// passed by 'invisible reference'. In other words, instead of passing the
+-/// thing by value, pass the address of a temporary.
+-bool isPassedByInvisibleReference(tree_node *type);
+-
+-/// isSequentialCompatible - Return true if the specified gcc array or pointer
+-/// type and the corresponding LLVM SequentialType lay out their components
+-/// identically in memory, so doing a GEP accesses the right memory location.
+-/// We assume that objects without a known size do not.
+-extern bool isSequentialCompatible(tree_node *type);
+-
+-/// OffsetIsLLVMCompatible - Return true if the given field is offset from the
+-/// start of the record by a constant amount which is not humongously big.
+-extern bool OffsetIsLLVMCompatible(tree_node *field_decl);
+-
+-/// ArrayLengthOf - Returns the length of the given gcc array type, or ~0ULL if
+-/// the array has variable or unknown length.
+-extern uint64_t ArrayLengthOf(tree_node *type);
+-
+-/// isBitfield - Returns whether to treat the specified field as a bitfield.
+-bool isBitfield(tree_node *field_decl);
+-
+-/// getFieldOffsetInBits - Return the bit offset of a FIELD_DECL in a structure.
+-extern uint64_t getFieldOffsetInBits(tree_node *field);
+-
+-/// ValidateRegisterVariable - Check that a static "asm" variable is
+-/// well-formed. If not, emit error messages and return true. If so, return
+-/// false.
+-bool ValidateRegisterVariable(tree_node *decl);
+-
+-/// MemRef - This struct holds the information needed for a memory access:
+-/// a pointer to the memory, its alignment and whether the access is volatile.
+-class MemRef {
+-public:
+- Value *Ptr;
+- bool Volatile;
+-private:
+- unsigned char LogAlign;
+-public:
+- explicit MemRef() : Ptr(0), Volatile(false), LogAlign(0) {}
+- explicit MemRef(Value *P, uint32_t A, bool V) : Ptr(P), Volatile(V) {
+- // Forbid alignment 0 along with non-power-of-2 alignment values.
+- assert(isPowerOf2_32(A) && "Alignment not a power of 2!");
+- LogAlign = Log2_32(A);
+- }
+-
+- uint32_t getAlignment() const {
+- return 1U << LogAlign;
+- }
+-
+- void setAlignment(uint32_t A) {
+- LogAlign = Log2_32(A);
+- }
+-};
+-
+-/// LValue - This struct represents an lvalue in the program. In particular,
+-/// the Ptr member indicates the memory that the lvalue lives in. Alignment
+-/// is the alignment of the memory (in bytes).If this is a bitfield reference,
+-/// BitStart indicates the first bit in the memory that is part of the field
+-/// and BitSize indicates the extent.
+-///
+-/// "LValue" is intended to be a light-weight object passed around by-value.
+-class LValue : public MemRef {
+-public:
+- unsigned char BitStart;
+- unsigned char BitSize;
+-public:
+- explicit LValue() : BitStart(255), BitSize(255) {}
+- explicit LValue(MemRef &M) : MemRef(M), BitStart(255), BitSize(255) {}
+- LValue(Value *P, uint32_t A, bool V = false) :
+- MemRef(P, A, V), BitStart(255), BitSize(255) {}
+- LValue(Value *P, uint32_t A, unsigned BSt, unsigned BSi, bool V = false) :
+- MemRef(P, A, V), BitStart(BSt), BitSize(BSi) {
+- assert(BitStart == BSt && BitSize == BSi &&
+- "Bit values larger than 256?");
+- }
+-
+- bool isBitfield() const { return BitStart != 255; }
+-};
+-
+-/// PhiRecord - This struct holds the LLVM PHI node associated with a GCC phi.
+-struct PhiRecord {
+- gimple_statement_d *gcc_phi;
+- PHINode *PHI;
+-};
+-
+-/// TreeToLLVM - An instance of this class is created and used to convert the
+-/// body of each function to LLVM.
+-///
+-class TreeToLLVM {
+- // State that is initialized when the function starts.
+- const TargetData &TD;
+- tree_node *FnDecl;
+- Function *Fn;
+- BasicBlock *ReturnBB;
+- unsigned ReturnOffset;
+-
+- // State that changes as the function is emitted.
+-
+- /// Builder - Instruction creator, the location to insert into is always the
+- /// same as &Fn->back().
+- LLVMBuilder Builder;
+-
+- // AllocaInsertionPoint - Place to insert alloca instructions. Lazily created
+- // and managed by CreateTemporary.
+- Instruction *AllocaInsertionPoint;
+-
+- // SSAInsertionPoint - Place to insert reads corresponding to SSA default
+- // definitions.
+- Instruction *SSAInsertionPoint;
+-
+- /// BasicBlocks - Map from GCC to LLVM basic blocks.
+- DenseMap<basic_block_def *, BasicBlock*> BasicBlocks;
+-
+- /// LocalDecls - Map from local declarations to their associated LLVM values.
+- DenseMap<tree_node *, AssertingVH<Value> > LocalDecls;
+-
+- /// PendingPhis - Phi nodes which have not yet been populated with operands.
+- SmallVector<PhiRecord, 16> PendingPhis;
+-
+- // SSANames - Map from GCC ssa names to the defining LLVM value.
+- DenseMap<tree_node *, TrackingVH<Value> > SSANames;
+-
+-public:
+-
+- //===---------------------- Local Declarations --------------------------===//
+-
+- /// DECL_LOCAL - Like DECL_LLVM, returns the LLVM declaration of a variable or
+- /// function. However DECL_LOCAL can be used with declarations local to the
+- /// current function as well as with global declarations.
+- Value *make_decl_local(tree_node *);
+- #define DECL_LOCAL(NODE) make_decl_local(NODE)
+-
+- /// DEFINITION_LOCAL - Like DEFINITION_LLVM, ensures that the initial value or
+- /// body of a variable or function will be output. However DEFINITION_LOCAL
+- /// can be used with declarations local to the current function as well as
+- /// with global declarations.
+- Value *make_definition_local(tree_node *);
+- #define DEFINITION_LOCAL(NODE) make_definition_local(NODE)
+-
+- /// SET_DECL_LOCAL - Set the DECL_LOCAL for NODE to LLVM.
+- Value *set_decl_local(tree_node *, Value *);
+- #define SET_DECL_LOCAL(NODE, LLVM) set_decl_local(NODE, LLVM)
+-
+- /// DECL_LOCAL_IF_SET - The DECL_LOCAL for NODE, if it is set, or NULL, if it
+- /// is not set.
+- Value *get_decl_local(tree_node *);
+- #define DECL_LOCAL_IF_SET(NODE) (HAS_RTL_P(NODE) ? get_decl_local(NODE) : NULL)
+-
+- /// DECL_LOCAL_SET_P - Returns nonzero if the DECL_LOCAL for NODE has already
+- /// been set.
+- #define DECL_LOCAL_SET_P(NODE) (DECL_LOCAL_IF_SET(NODE) != NULL)
+-
+-
+-private:
+-
+- //===---------------------- Exception Handling --------------------------===//
+-
+- /// NormalInvokes - Mapping from landing pad number to the set of invoke
+- /// instructions that unwind to that landing pad.
+- SmallVector<SmallVector<InvokeInst *, 8>, 16> NormalInvokes;
+-
+- /// ExceptionPtrs - Mapping from EH region index to the local holding the
+- /// exception pointer for that region.
+- SmallVector<AllocaInst *, 16> ExceptionPtrs;
+-
+- /// ExceptionFilters - Mapping from EH region index to the local holding the
+- /// filter value for that region.
+- SmallVector<AllocaInst *, 16> ExceptionFilters;
+-
+- /// FailureBlocks - Mapping from the index of a must-not-throw EH region to
+- /// the block containing the failure code for the region (the code that is
+- /// run if an exception is thrown in this region).
+- SmallVector<BasicBlock *, 16> FailureBlocks;
+-
+- /// RewindBB - Block containing code that continues unwinding an exception.
+- BasicBlock *RewindBB;
+-
+- /// RewindTmp - Local holding the exception to continue unwinding.
+- AllocaInst *RewindTmp;
+-
+-public:
+- TreeToLLVM(tree_node *fndecl);
+- ~TreeToLLVM();
+-
+- /// getFUNCTION_DECL - Return the FUNCTION_DECL node for the current function
+- /// being compiled.
+- tree_node *getFUNCTION_DECL() const { return FnDecl; }
+-
+- /// EmitFunction - Convert 'fndecl' to LLVM code.
+- Function *EmitFunction();
+-
+- /// EmitBasicBlock - Convert the given basic block.
+- void EmitBasicBlock(basic_block_def *bb);
+-
+- /// EmitLV - Convert the specified l-value tree node to LLVM code, returning
+- /// the address of the result.
+- LValue EmitLV(tree_node *exp);
+-
+- void TODO(tree_node *exp = 0);
+-
+- /// CastToAnyType - Cast the specified value to the specified type regardless
+- /// of the types involved. This is an inferred cast.
+- Value *CastToAnyType (Value *V, bool VSigned, const Type *Ty, bool TySigned);
+-
+- /// CastToUIntType - Cast the specified value to the specified type assuming
+- /// that V's type and Ty are integral types. This arbitrates between BitCast,
+- /// Trunc and ZExt.
+- Value *CastToUIntType(Value *V, const Type *Ty);
+-
+- /// CastToSIntType - Cast the specified value to the specified type assuming
+- /// that V's type and Ty are integral types. This arbitrates between BitCast,
+- /// Trunc and SExt.
+- Value *CastToSIntType(Value *V, const Type *Ty);
+-
+- /// CastToFPType - Cast the specified value to the specified type assuming
+- /// that V's type and Ty are floating point types. This arbitrates between
+- /// BitCast, FPTrunc and FPExt.
+- Value *CastToFPType(Value *V, const Type *Ty);
+-
+- /// CreateAnyAdd - Add two LLVM scalar values with the given GCC type. Does
+- /// not support complex numbers. The type is used to set overflow flags.
+- Value *CreateAnyAdd(Value *LHS, Value *RHS, tree_node *type);
+-
+- /// CreateAnyMul - Multiply two LLVM scalar values with the given GCC type.
+- /// Does not support complex numbers. The type is used to set overflow flags.
+- Value *CreateAnyMul(Value *LHS, Value *RHS, tree_node *type);
+-
+- /// CreateAnyNeg - Negate an LLVM scalar value with the given GCC type. Does
+- /// not support complex numbers. The type is used to set overflow flags.
+- Value *CreateAnyNeg(Value *V, tree_node *type);
+-
+- /// CreateAnySub - Subtract two LLVM scalar values with the given GCC type.
+- /// Does not support complex numbers.
+- Value *CreateAnySub(Value *LHS, Value *RHS, tree_node *type);
+-
+- /// CreateTemporary - Create a new alloca instruction of the specified type,
+- /// inserting it into the entry block and returning it. The resulting
+- /// instruction's type is a pointer to the specified type.
+- AllocaInst *CreateTemporary(const Type *Ty, unsigned align=0);
+-
+- /// CreateTempLoc - Like CreateTemporary, but returns a MemRef.
+- MemRef CreateTempLoc(const Type *Ty);
+-
+- /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
+- /// GCC type specified by GCCType to know which elements to copy.
+- void EmitAggregateCopy(MemRef DestLoc, MemRef SrcLoc, tree_node *GCCType);
+-
+- /// EmitAggregate - Store the specified tree node into the location given by
+- /// DestLoc.
+- void EmitAggregate(tree_node *exp, const MemRef &DestLoc);
+-
+-private: // Helper functions.
+-
+- /// StartFunctionBody - Start the emission of 'fndecl', outputing all
+- /// declarations for parameters and setting things up.
+- void StartFunctionBody();
+-
+- /// FinishFunctionBody - Once the body of the function has been emitted, this
+- /// cleans up and returns the result function.
+- Function *FinishFunctionBody();
+-
+- /// PopulatePhiNodes - Populate generated phi nodes with their operands.
+- void PopulatePhiNodes();
+-
+- /// getBasicBlock - Find or create the LLVM basic block corresponding to BB.
+- BasicBlock *getBasicBlock(basic_block_def *bb);
+-
+- /// getLabelDeclBlock - Lazily get and create a basic block for the specified
+- /// label.
+- BasicBlock *getLabelDeclBlock(tree_node *LabelDecl);
+-
+- /// DefineSSAName - Use the given value as the definition of the given SSA
+- /// name. Returns the provided value as a convenience.
+- Value *DefineSSAName(tree_node *reg, Value *Val);
+-
+- /// BeginBlock - Add the specified basic block to the end of the function. If
+- /// the previous block falls through into it, add an explicit branch.
+- void BeginBlock(BasicBlock *BB);
+-
+- /// EmitAggregateZero - Zero the elements of DestLoc.
+- void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);
+-
+- /// EmitMemCpy/EmitMemMove/EmitMemSet - Emit an llvm.memcpy/llvm.memmove or
+- /// llvm.memset call with the specified operands. Returns DestPtr bitcast
+- /// to i8*.
+- Value *EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
+- Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
+- Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
+-
+- /// EmitLandingPads - Emit EH landing pads.
+- void EmitLandingPads();
+-
+- /// EmitFailureBlocks - Emit the blocks containing failure code executed when
+- /// an exception is thrown in a must-not-throw region.
+- void EmitFailureBlocks();
+-
+- /// EmitRewindBlock - Emit the block containing code to continue unwinding an
+- /// exception.
+- void EmitRewindBlock();
+-
+- /// EmitDebugInfo - Return true if debug info is to be emitted for current
+- /// function.
+- bool EmitDebugInfo();
+-
+-private: // Helpers for exception handling.
+-
+- /// getLandingPad - Return the landing pad for the given exception handling
+- /// region, creating it if necessary.
+- BasicBlock *getLandingPad(unsigned RegionNo);
+-
+- /// getExceptionPtr - Return the local holding the exception pointer for the
+- /// given exception handling region, creating it if necessary.
+- AllocaInst *getExceptionPtr(unsigned RegionNo);
+-
+- /// getExceptionFilter - Return the local holding the filter value for the
+- /// given exception handling region, creating it if necessary.
+- AllocaInst *getExceptionFilter(unsigned RegionNo);
+-
+- /// getFailureBlock - Return the basic block containing the failure code for
+- /// the given exception handling region, creating it if necessary.
+- BasicBlock *getFailureBlock(unsigned RegionNo);
+-
+-private:
+- void EmitAutomaticVariableDecl(tree_node *decl);
+-
+- /// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic
+- void EmitAnnotateIntrinsic(Value *V, tree_node *decl);
+-
+- /// EmitTypeGcroot - Emits call to make type a gcroot
+- void EmitTypeGcroot(Value *V);
+-
+-private:
+-
+- //===------------------ Render* - Convert GIMPLE to LLVM ----------------===//
+-
+- void RenderGIMPLE_ASM(gimple_statement_d *stmt);
+- void RenderGIMPLE_ASSIGN(gimple_statement_d *stmt);
+- void RenderGIMPLE_CALL(gimple_statement_d *stmt);
+- void RenderGIMPLE_COND(gimple_statement_d *stmt);
+- void RenderGIMPLE_EH_DISPATCH(gimple_statement_d *stmt);
+- void RenderGIMPLE_GOTO(gimple_statement_d *stmt);
+- void RenderGIMPLE_RESX(gimple_statement_d *stmt);
+- void RenderGIMPLE_RETURN(gimple_statement_d *stmt);
+- void RenderGIMPLE_SWITCH(gimple_statement_d *stmt);
+-
+- // Render helpers.
+-
+- /// EmitAssignRHS - Convert the RHS of a scalar GIMPLE_ASSIGN to LLVM.
+- Value *EmitAssignRHS(gimple_statement_d *stmt);
+-
+- /// EmitAssignSingleRHS - Helper for EmitAssignRHS. Handles those RHS that
+- /// are not register expressions.
+- Value *EmitAssignSingleRHS(tree_node *rhs);
+-
+- /// OutputCallRHS - Convert the RHS of a GIMPLE_CALL.
+- Value *OutputCallRHS(gimple_statement_d *stmt, const MemRef *DestLoc);
+-
+- /// WriteScalarToLHS - Store RHS, a non-aggregate value, into the given LHS.
+- void WriteScalarToLHS(tree_node *lhs, Value *Scalar);
+-
+-private:
+-
+- //===---------- EmitReg* - Convert register expression to LLVM ----------===//
+-
+- /// GetRegType - Returns the LLVM type to use for registers that hold a value
+- /// of the scalar GCC type 'type'. All of the EmitReg* routines use this to
+- /// determine the LLVM type to return.
+- const Type *GetRegType(tree_node *type);
+-
+- /// UselesslyTypeConvert - The useless_type_conversion_p predicate implicitly
+- /// defines the GCC middle-end type system. For scalar GCC types inner_type
+- /// and outer_type, if 'useless_type_conversion_p(outer_type, inner_type)' is
+- /// true then the corresponding LLVM inner and outer types (see GetRegType)
+- /// are equal except possibly if they are both pointer types (casts to 'void*'
+- /// are considered useless for example) or types derived from pointer types
+- /// (vector types with pointer element type are the only possibility here).
+- /// This method converts LLVM values of the inner type to the outer type.
+- Value *UselesslyTypeConvert(Value *V, const Type *Ty) {
+- return Builder.CreateBitCast(V, Ty);
+- }
+-
+- /// EmitRegister - Convert the specified gimple register or local constant of
+- /// register type to an LLVM value. Only creates code in the entry block.
+- Value *EmitRegister(tree_node *reg);
+-
+- /// EmitReg_SSA_NAME - Return the defining value of the given SSA_NAME.
+- /// Only creates code in the entry block.
+- Value *EmitReg_SSA_NAME(tree_node *reg);
+-
+- // Unary expressions.
+- Value *EmitReg_ABS_EXPR(tree_node *op);
+- Value *EmitReg_BIT_NOT_EXPR(tree_node *op);
+- Value *EmitReg_CONJ_EXPR(tree_node *op);
+- Value *EmitReg_CONVERT_EXPR(tree_node *type, tree_node *op);
+- Value *EmitReg_NEGATE_EXPR(tree_node *op);
+- Value *EmitReg_PAREN_EXPR(tree_node *exp);
+- Value *EmitReg_TRUTH_NOT_EXPR(tree_node *type, tree_node *op);
+-
+- // Comparisons.
+-
+- /// EmitCompare - Compare LHS with RHS using the appropriate comparison code.
+- /// The result is an i1 boolean.
+- Value *EmitCompare(tree_node *lhs, tree_node *rhs, unsigned code);
+-
+- // Binary expressions.
+- Value *EmitReg_MinMaxExpr(tree_node *type, tree_node *op0, tree_node *op1,
+- unsigned UIPred, unsigned SIPred, unsigned Opc,
+- bool isMax);
+- Value *EmitReg_RotateOp(tree_node *type, tree_node *op0, tree_node *op1,
+- unsigned Opc1, unsigned Opc2);
+- Value *EmitReg_ShiftOp(tree_node *op0, tree_node *op1, unsigned Opc);
+- Value *EmitReg_TruthOp(tree_node *type, tree_node *op0, tree_node *op1,
+- unsigned Opc);
+- Value *EmitReg_BIT_AND_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_BIT_IOR_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_BIT_XOR_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_CEIL_DIV_EXPR(tree_node *type, tree_node *op0, tree_node *op1);
+- Value *EmitReg_COMPLEX_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_FLOOR_DIV_EXPR(tree_node *type, tree_node *op0,
+- tree_node *op1);
+- Value *EmitReg_FLOOR_MOD_EXPR(tree_node *type, tree_node *op0,
+- tree_node *op1);
+- Value *EmitReg_MINUS_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_MULT_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_PLUS_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_POINTER_PLUS_EXPR(tree_node *type, tree_node *op0,
+- tree_node *op1);
+- Value *EmitReg_RDIV_EXPR(tree_node *op0, tree_node *op1);
+- Value *EmitReg_ROUND_DIV_EXPR(tree_node *type, tree_node *op0,
+- tree_node *op1);
+- Value *EmitReg_TRUNC_DIV_EXPR(tree_node *op0, tree_node *op1, bool isExact);
+- Value *EmitReg_TRUNC_MOD_EXPR(tree_node *op0, tree_node *op1);
+-
+- Value *EmitLoadOfLValue(tree_node *exp);
+- Value *EmitOBJ_TYPE_REF(tree_node *exp);
+- Value *EmitADDR_EXPR(tree_node *exp);
+- Value *EmitCallOf(Value *Callee, gimple_statement_d *stmt,
+- const MemRef *DestLoc, const AttrListPtr &PAL);
+- CallInst *EmitSimpleCall(StringRef CalleeName, tree_node *ret_type,
+- /* arguments */ ...) END_WITH_NULL;
+- Value *EmitFieldAnnotation(Value *FieldPtr, tree_node *FieldDecl);
+-
+- // Inline Assembly and Register Variables.
+- Value *EmitReadOfRegisterVariable(tree_node *vardecl);
+- void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);
+-
+- // Helpers for Builtin Function Expansion.
+- void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);
+- Value *BuildVector(const std::vector<Value*> &Elts);
+- Value *BuildVector(Value *Elt, ...);
+- Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
+- Value *BuildBinaryAtomicBuiltin(gimple_statement_d *stmt, Intrinsic::ID id);
+- Value *BuildCmpAndSwapAtomicBuiltin(gimple_statement_d *stmt, tree_node *type,
+- bool isBool);
+-
+- // Builtin Function Expansion.
+- bool EmitBuiltinCall(gimple_statement_d *stmt, tree_node *fndecl,
+- const MemRef *DestLoc, Value *&Result);
+- bool EmitFrontendExpandedBuiltinCall(gimple_statement_d *stmt,
+- tree_node *fndecl, const MemRef *DestLoc,
+- Value *&Result);
+- bool EmitBuiltinUnaryOp(Value *InVal, Value *&Result, Intrinsic::ID Id);
+- Value *EmitBuiltinSQRT(gimple_statement_d *stmt);
+- Value *EmitBuiltinPOWI(gimple_statement_d *stmt);
+- Value *EmitBuiltinPOW(gimple_statement_d *stmt);
+- Value *EmitBuiltinLCEIL(gimple_statement_d *stmt);
+- Value *EmitBuiltinLFLOOR(gimple_statement_d *stmt);
+-
+- bool EmitBuiltinConstantP(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinAlloca(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinExpect(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinExtendPointer(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinVAStart(gimple_statement_d *stmt);
+- bool EmitBuiltinVAEnd(gimple_statement_d *stmt);
+- bool EmitBuiltinVACopy(gimple_statement_d *stmt);
+- bool EmitBuiltinMemCopy(gimple_statement_d *stmt, Value *&Result,
+- bool isMemMove, bool SizeCheck);
+- bool EmitBuiltinMemSet(gimple_statement_d *stmt, Value *&Result,
+- bool SizeCheck);
+- bool EmitBuiltinBZero(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinPrefetch(gimple_statement_d *stmt);
+- bool EmitBuiltinReturnAddr(gimple_statement_d *stmt, Value *&Result,
+- bool isFrame);
+- bool EmitBuiltinExtractReturnAddr(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinFrobReturnAddr(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinStackSave(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinStackRestore(gimple_statement_d *stmt);
+- bool EmitBuiltinEHPointer(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinDwarfCFA(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinDwarfSPColumn(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinEHReturnDataRegno(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinEHReturn(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinInitDwarfRegSizes(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinUnwindInit(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinAdjustTrampoline(gimple_statement_d *stmt, Value *&Result);
+- bool EmitBuiltinInitTrampoline(gimple_statement_d *stmt, Value *&Result);
+-
+- // Complex Math Expressions.
+- Value *CreateComplex(Value *Real, Value *Imag, tree_node *elt_type);
+- void SplitComplex(Value *Complex, Value *&Real, Value *&Imag,
+- tree_node *elt_type);
+-
+- // L-Value Expressions.
+- LValue EmitLV_ARRAY_REF(tree_node *exp);
+- LValue EmitLV_BIT_FIELD_REF(tree_node *exp);
+- LValue EmitLV_COMPONENT_REF(tree_node *exp);
+- LValue EmitLV_DECL(tree_node *exp);
+- LValue EmitLV_INDIRECT_REF(tree_node *exp);
+- LValue EmitLV_VIEW_CONVERT_EXPR(tree_node *exp);
+- LValue EmitLV_WITH_SIZE_EXPR(tree_node *exp);
+- LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
+- LValue EmitLV_SSA_NAME(tree_node *exp);
+- LValue EmitLV_TARGET_MEM_REF(tree_node *exp);
+-
+- // Constant Expressions.
+- Value *EmitINTEGER_CST(tree_node *exp);
+- Value *EmitREAL_CST(tree_node *exp);
+- Value *EmitCONSTRUCTOR(tree_node *exp, const MemRef *DestLoc);
+-
+-
+- // Emit helpers.
+-
+- /// EmitMinInvariant - The given value is constant in this function. Return
+- /// the corresponding LLVM value. Only creates code in the entry block.
+- Value *EmitMinInvariant(tree_node *reg);
+-
+- /// EmitInvariantAddress - The given address is constant in this function.
+- /// Return the corresponding LLVM value. Only creates code in the entry block.
+- Value *EmitInvariantAddress(tree_node *addr);
+-
+- /// EmitRegisterConstant - Convert the given global constant of register type
+- /// to an LLVM constant. Creates no code, only constants.
+- Constant *EmitRegisterConstant(tree_node *reg);
+-
+- /// EmitComplexRegisterConstant - Turn the given COMPLEX_CST into an LLVM
+- /// constant of the corresponding register type.
+- Constant *EmitComplexRegisterConstant(tree_node *reg);
+-
+- /// EmitIntegerRegisterConstant - Turn the given INTEGER_CST into an LLVM
+- /// constant of the corresponding register type.
+- Constant *EmitIntegerRegisterConstant(tree_node *reg);
+-
+- /// EmitRealRegisterConstant - Turn the given REAL_CST into an LLVM constant
+- /// of the corresponding register type.
+- Constant *EmitRealRegisterConstant(tree_node *reg);
+-
+- /// EmitConstantVectorConstructor - Turn the given constant CONSTRUCTOR into
+- /// an LLVM constant of the corresponding vector register type.
+- Constant *EmitConstantVectorConstructor(tree_node *reg);
+-
+- /// EmitVectorRegisterConstant - Turn the given VECTOR_CST into an LLVM
+- /// constant of the corresponding register type.
+- Constant *EmitVectorRegisterConstant(tree_node *reg);
+-
+- /// Mem2Reg - Convert a value of in-memory type (that given by ConvertType)
+- /// to in-register type (that given by GetRegType). TODO: Eliminate these
+- /// methods: "memory" values should never be held in registers. Currently
+- /// this is mainly used for marshalling function parameters and return values,
+- /// but that should be completely independent of the reg vs mem value logic.
+- Value *Mem2Reg(Value *V, tree_node *type, LLVMBuilder &Builder);
+- Constant *Mem2Reg(Constant *C, tree_node *type, TargetFolder &Folder);
+-
+- /// Reg2Mem - Convert a value of in-register type (that given by GetRegType)
+- /// to in-memory type (that given by ConvertType). TODO: Eliminate this
+- /// method: "memory" values should never be held in registers. Currently
+- /// this is mainly used for marshalling function parameters and return values,
+- /// but that should be completely independent of the reg vs mem value logic.
+- Value *Reg2Mem(Value *V, tree_node *type, LLVMBuilder &Builder);
+-
+- /// EmitMemory - Convert the specified gimple register or local constant of
+- /// register type to an LLVM value with in-memory type (given by ConvertType).
+- /// TODO: Eliminate this method, see Mem2Reg and Reg2Mem above.
+- Value *EmitMemory(tree_node *reg);
+-
+- /// LoadRegisterFromMemory - Loads a value of the given scalar GCC type from
+- /// the memory location pointed to by Loc. Takes care of adjusting for any
+- /// differences between in-memory and in-register types (the returned value
+- /// is of in-register type, as returned by GetRegType).
+- Value *LoadRegisterFromMemory(MemRef Loc, tree_node *type,
+- LLVMBuilder &Builder);
+-
+- /// StoreRegisterToMemory - Stores the given value to the memory pointed to by
+- /// Loc. Takes care of adjusting for any differences between the value's type
+- /// (which is the in-register type given by GetRegType) and the in-memory type.
+- void StoreRegisterToMemory(Value *V, MemRef Loc, tree_node *type,
+- LLVMBuilder &Builder);
+-
+-private:
+- // Optional target defined builtin intrinsic expanding function.
+- bool TargetIntrinsicLower(gimple_statement_d *stmt,
+- tree_node *fndecl,
+- const MemRef *DestLoc,
+- Value *&Result,
+- const Type *ResultType,
+- std::vector<Value*> &Ops);
+-
+-public:
+- // Helper for taking the address of a label.
+- Constant *AddressOfLABEL_DECL(tree_node *exp);
+-};
+-
+-#endif /* DRAGONEGG_INTERNALS_H */
+diff -r -u -N dragonegg-2.9-old/linux/dragonegg/OS.h dragonegg-2.9-new/linux/dragonegg/OS.h
+--- dragonegg-2.9-old/linux/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/linux/dragonegg/OS.h 2011-04-09 00:38:11.339997171 +0200
+@@ -0,0 +1,33 @@
++//===------------- OS.h - Linux specific definitions ------------*- C++ -*-===//
++//
++// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file provides Linux specific declarations.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_OS_H
++#define DRAGONEGG_OS_H
++
++/* Yes, we support PIC codegen for linux targets! */
++#define LLVM_SET_TARGET_OPTIONS(argvec) \
++ if (flag_pic) \
++ argvec.push_back ("--relocation-model=pic"); \
++ else \
++ argvec.push_back ("--relocation-model=static");
++
++#endif /* DRAGONEGG_OS_H */
+diff -r -u -N dragonegg-2.9-old/linux/OS.h dragonegg-2.9-new/linux/OS.h
+--- dragonegg-2.9-old/linux/OS.h 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/linux/OS.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,33 +0,0 @@
+-//===------------- OS.h - Linux specific definitions ------------*- C++ -*-===//
+-//
+-// Copyright (C) 2009, 2010, 2011 Duncan Sands et al.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file provides Linux specific declarations.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_OS_H
+-#define DRAGONEGG_OS_H
+-
+-/* Yes, we support PIC codegen for linux targets! */
+-#define LLVM_SET_TARGET_OPTIONS(argvec) \
+- if (flag_pic) \
+- argvec.push_back ("--relocation-model=pic"); \
+- else \
+- argvec.push_back ("--relocation-model=static");
+-
+-#endif /* DRAGONEGG_OS_H */
+diff -r -u -N dragonegg-2.9-old/Makefile dragonegg-2.9-new/Makefile
+--- dragonegg-2.9-old/Makefile 2011-03-28 21:44:58.000000000 +0200
++++ dragonegg-2.9-new/Makefile 2011-04-09 00:38:11.339997171 +0200
+@@ -52,7 +52,7 @@
+ -MD -MP \
+ -DIN_GCC -DREVISION=\"$(REVISION)\" \
+ -DGCC_MAJOR=$(GCC_MAJOR) -DGCC_MINOR=$(GCC_MINOR) \
+- -I$(SRC_DIR) -I$(SRC_DIR)/ADT -I$(GCC_PLUGIN_DIR)/include
++ -I$(SRC_DIR)/include -I$(GCC_PLUGIN_DIR)/include
+
+ LD_OPTIONS+=$(shell $(LLVM_CONFIG) --ldflags) $(LDFLAGS)
+
+diff -r -u -N dragonegg-2.9-old/Trees.cpp dragonegg-2.9-new/Trees.cpp
+--- dragonegg-2.9-old/Trees.cpp 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/Trees.cpp 2011-04-09 00:38:11.339997171 +0200
+@@ -21,7 +21,7 @@
+ //===----------------------------------------------------------------------===//
+
+ // Plugin headers
+-#include "Trees.h"
++#include "dragonegg/Trees.h"
+
+ // LLVM headers
+ #include "llvm/ADT/Twine.h"
+diff -r -u -N dragonegg-2.9-old/Trees.h dragonegg-2.9-new/Trees.h
+--- dragonegg-2.9-old/Trees.h 2011-03-29 12:46:17.000000000 +0200
++++ dragonegg-2.9-new/Trees.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,44 +0,0 @@
+-//=---- Trees.h - Utility functions for working with GCC trees ----*- C++ -*-=//
+-//
+-// Copyright (C) 2010, 2011 Duncan Sands.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file declares utility functions for working with GCC trees.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_TREES_H
+-#define DRAGONEGG_TREES_H
+-
+-// System headers
+-#include <string>
+-
+-union tree_node;
+-
+-/// getDescriptiveName - Return a helpful name for the given tree, or an empty
+-/// string if no sensible name was found. These names are used to make the IR
+-/// more readable, and have no official status.
+-std::string getDescriptiveName(union tree_node *t);
+-
+-/// hasNUW - Return whether overflowing unsigned operations on this type result
+-/// in undefined behaviour.
+-bool hasNUW(tree_node *type);
+-
+-/// hasNSW - Return whether overflowing signed operations on this type result
+-/// in undefined behaviour.
+-bool hasNSW(tree_node *type);
+-
+-#endif /* DRAGONEGG_TREES_H */
+diff -r -u -N dragonegg-2.9-old/Types.cpp dragonegg-2.9-new/Types.cpp
+--- dragonegg-2.9-old/Types.cpp 2011-03-29 08:26:30.000000000 +0200
++++ dragonegg-2.9-new/Types.cpp 2011-04-09 00:38:11.349996956 +0200
+@@ -22,10 +22,10 @@
+ //===----------------------------------------------------------------------===//
+
+ // Plugin headers
+-#include "ABI.h"
+-#include "Trees.h"
++#include "dragonegg/ABI.h"
++#include "dragonegg/Trees.h"
+ extern "C" {
+-#include "cache.h"
++#include "dragonegg/cache.h"
+ }
+
+ // LLVM headers
+diff -r -u -N dragonegg-2.9-old/unknown/dragonegg/OS.h dragonegg-2.9-new/unknown/dragonegg/OS.h
+--- dragonegg-2.9-old/unknown/dragonegg/OS.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/unknown/dragonegg/OS.h 2011-04-09 00:38:11.349996956 +0200
+@@ -0,0 +1 @@
++#error Unknown target operating system
+diff -r -u -N dragonegg-2.9-old/unknown/OS.h dragonegg-2.9-new/unknown/OS.h
+--- dragonegg-2.9-old/unknown/OS.h 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/unknown/OS.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1 +0,0 @@
+-#error Unknown target operating system
+diff -r -u -N dragonegg-2.9-old/x86/dragonegg/Target.h dragonegg-2.9-new/x86/dragonegg/Target.h
+--- dragonegg-2.9-old/x86/dragonegg/Target.h 1970-01-01 01:00:00.000000000 +0100
++++ dragonegg-2.9-new/x86/dragonegg/Target.h 2011-04-09 00:38:11.349996956 +0200
+@@ -0,0 +1,403 @@
++//==----- Target.h - Target hooks for GCC to LLVM conversion -----*- C++ -*-==//
++//
++// Copyright (C) 2007, 2008, 2009, 2010, 2011 Anton Korobeynikov, Duncan Sands
++// et al.
++//
++// This file is part of DragonEgg.
++//
++// DragonEgg is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free Software
++// Foundation; either version 2, or (at your option) any later version.
++//
++// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
++// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
++// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License along with
++// DragonEgg; see the file COPYING. If not, write to the Free Software
++// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
++//
++//===----------------------------------------------------------------------===//
++// This file declares some target-specific hooks for GCC to LLVM conversion.
++//===----------------------------------------------------------------------===//
++
++#ifndef DRAGONEGG_TARGET_H
++#define DRAGONEGG_TARGET_H
++
++/* LLVM specific stuff for supporting calling convention output */
++#define TARGET_ADJUST_LLVM_CC(CC, type) \
++ { \
++ tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
++ if (lookup_attribute ("stdcall", type_attributes)) { \
++ CC = CallingConv::X86_StdCall; \
++ } else if (lookup_attribute("fastcall", type_attributes)) { \
++ CC = CallingConv::X86_FastCall; \
++ } \
++ }
++
++#define TARGET_ADJUST_LLVM_RETATTR(Rattributes, type) \
++ { \
++ tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
++ if (!TARGET_64BIT && (TARGET_SSEREGPARM || \
++ lookup_attribute("sseregparm", type_attributes)))\
++ RAttributes |= Attribute::InReg; \
++ }
++
++/* LLVM specific stuff for converting gcc's `regparm` attribute to LLVM's
++ `inreg` parameter attribute */
++#define LLVM_TARGET_ENABLE_REGPARM
++
++extern "C" int ix86_regparm;
++
++#define LLVM_TARGET_INIT_REGPARM(local_regparm, local_fp_regparm, type) \
++ { \
++ tree_node *attr; \
++ local_regparm = ix86_regparm; \
++ local_fp_regparm = TARGET_SSEREGPARM ? 3 : 0; \
++ attr = lookup_attribute ("regparm", \
++ TYPE_ATTRIBUTES (type)); \
++ if (attr) { \
++ local_regparm = TREE_INT_CST_LOW (TREE_VALUE \
++ (TREE_VALUE (attr))); \
++ } \
++ attr = lookup_attribute("sseregparm", \
++ TYPE_ATTRIBUTES (type)); \
++ if (attr) \
++ local_fp_regparm = 3; \
++ }
++
++#define LLVM_ADJUST_REGPARM_ATTRIBUTE(PAttribute, Type, Size, \
++ local_regparm, \
++ local_fp_regparm) \
++ { \
++ if (!TARGET_64BIT) { \
++ if (TREE_CODE(Type) == REAL_TYPE && \
++ (TYPE_PRECISION(Type)==32 || \
++ TYPE_PRECISION(Type)==64)) { \
++ local_fp_regparm -= 1; \
++ if (local_fp_regparm >= 0) \
++ PAttribute |= Attribute::InReg; \
++ else \
++ local_fp_regparm = 0; \
++ } else if (INTEGRAL_TYPE_P(Type) || \
++ POINTER_TYPE_P(Type)) { \
++ int words = \
++ (Size + BITS_PER_WORD - 1) / BITS_PER_WORD; \
++ local_regparm -= words; \
++ if (local_regparm>=0) \
++ PAttribute |= Attribute::InReg; \
++ else \
++ local_regparm = 0; \
++ } \
++ } \
++ }
++
++#define LLVM_SET_RED_ZONE_FLAG(disable_red_zone) \
++ if (TARGET_64BIT && TARGET_NO_RED_ZONE) \
++ disable_red_zone = 1;
++
++#ifdef DRAGONEGG_ABI_H
++
++/* On x86-32 objects containing SSE vectors are 16 byte aligned, everything
++ else 4. On x86-64 vectors are 8-byte aligned, everything else can
++ be figured out by the back end. */
++#define LLVM_BYVAL_ALIGNMENT(T) \
++ (TYPE_ALIGN(T) / 8)
++
++extern tree_node *llvm_x86_should_return_selt_struct_as_scalar(tree_node *);
++
++/* Structs containing a single data field plus zero-length fields are
++ considered as if they were the type of the data field. On x86-64,
++ if the element type is an MMX vector, return it as double (which will
++ get it into XMM0). */
++
++#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
++ llvm_x86_should_return_selt_struct_as_scalar((X))
++
++extern bool llvm_x86_should_pass_aggregate_in_integer_regs(tree_node *,
++ unsigned*, bool*);
++
++/* LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
++ value should be passed in integer registers. This differs from the usual
++ handling in that x86-64 passes 128-bit structs and unions which only
++ contain data in the first 64 bits, as 64-bit objects. (These can be
++ created by abusing __attribute__((aligned)). */
++#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
++ llvm_x86_should_pass_aggregate_in_integer_regs((X), (Y), (Z))
++
++extern const Type *llvm_x86_scalar_type_for_struct_return(tree_node *type,
++ unsigned *Offset);
++
++/* LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
++ returned as a scalar, otherwise return NULL. */
++#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
++ llvm_x86_scalar_type_for_struct_return((X), (Y))
++
++extern const Type *llvm_x86_aggr_type_for_struct_return(tree_node *type);
++
++/* LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
++ returned as an aggregate, otherwise return NULL. */
++#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
++ llvm_x86_aggr_type_for_struct_return(X)
++
++extern void llvm_x86_extract_multiple_return_value(Value *Src, Value *Dest,
++ bool isVolatile,
++ LLVMBuilder &B);
++
++/* LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
++ SRC and assign it to DEST. */
++#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
++ llvm_x86_extract_multiple_return_value((Src),(Dest),(V),(B))
++
++extern bool llvm_x86_should_pass_vector_using_byval_attr(tree_node *);
++
++/* On x86-64, vectors which are not MMX nor SSE should be passed byval. */
++#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
++ llvm_x86_should_pass_vector_using_byval_attr((X))
++
++extern bool llvm_x86_should_pass_vector_in_integer_regs(tree_node *);
++
++/* On x86-32, vectors which are not MMX nor SSE should be passed as integers. */
++#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X) \
++ llvm_x86_should_pass_vector_in_integer_regs((X))
++
++extern tree_node *llvm_x86_should_return_vector_as_scalar(tree_node *, bool);
++
++/* The MMX vector v1i64 is returned in EAX and EDX on Darwin. Communicate
++ this by returning i64 here. Likewise, (generic) vectors such as v2i16
++ are returned in EAX.
++ On Darwin x86-64, MMX vectors are returned in XMM0. Communicate this by
++ returning f64. */
++#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin)\
++ llvm_x86_should_return_vector_as_scalar((X), (isBuiltin))
++
++extern bool llvm_x86_should_return_vector_as_shadow(tree_node *, bool);
++
++/* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
++ 32-bit. Vectors bigger than 128 are returned using sret. */
++#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
++ llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
++
++extern bool
++llvm_x86_should_not_return_complex_in_memory(tree_node *type);
++
++/* LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
++ special _Complex handling. Return true if X should be returned using
++ multiple value return instruction. */
++#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
++ llvm_x86_should_not_return_complex_in_memory((X))
++
++extern bool
++llvm_x86_should_pass_aggregate_as_fca(tree_node *type, const Type *);
++
++/* LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if an aggregate of the
++ specified type should be passed as a first-class aggregate. */
++#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
++#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
++ llvm_x86_should_pass_aggregate_as_fca(X, TY)
++#endif
++
++extern bool llvm_x86_should_pass_aggregate_in_memory(tree_node *, const Type *);
++
++#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
++ llvm_x86_should_pass_aggregate_in_memory(X, TY)
++
++
++extern bool
++llvm_x86_64_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
++ std::vector<const Type*>&);
++extern bool
++llvm_x86_32_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
++ std::vector<const Type*>&);
++
++#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
++ (TARGET_64BIT ? \
++ llvm_x86_64_should_pass_aggregate_in_mixed_regs((T), (TY), (E)) : \
++ llvm_x86_32_should_pass_aggregate_in_mixed_regs((T), (TY), (E)))
++
++extern
++bool llvm_x86_64_aggregate_partially_passed_in_regs(std::vector<const Type*>&,
++ std::vector<const Type*>&,
++ bool);
++
++#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
++ (TARGET_64BIT ? \
++ llvm_x86_64_aggregate_partially_passed_in_regs((E), (SE), (ISR)) : \
++ false)
++
++#endif /* DRAGONEGG_ABI_H */
++
++/* Register class used for passing given 64bit part of the argument.
++ These represent classes as documented by the PS ABI, with the exception
++ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
++ use SF or DFmode move instead of DImode to avoid reformatting penalties.
++
++ Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
++ whenever possible (upper half does contain padding).
++ */
++enum x86_64_reg_class
++ {
++ X86_64_NO_CLASS,
++ X86_64_INTEGER_CLASS,
++ X86_64_INTEGERSI_CLASS,
++ X86_64_SSE_CLASS,
++ X86_64_SSESF_CLASS,
++ X86_64_SSEDF_CLASS,
++ X86_64_SSEUP_CLASS,
++ X86_64_X87_CLASS,
++ X86_64_X87UP_CLASS,
++ X86_64_COMPLEX_X87_CLASS,
++ X86_64_MEMORY_CLASS
++ };
++
++/* LLVM_TARGET_INTRINSIC_PREFIX - Specify what prefix this target uses for its
++ * intrinsics.
++ */
++#define LLVM_TARGET_INTRINSIC_PREFIX "x86"
++
++/* LLVM_TARGET_NAME - This specifies the name of the target, which correlates to
++ * the llvm::InitializeXXXTarget() function.
++ */
++#define LLVM_TARGET_NAME X86
++
++/* Turn -march=xx into a CPU type.
++ */
++#define LLVM_SET_SUBTARGET_FEATURES(F) \
++ { if (TARGET_MACHO && ! strcmp (ix86_arch_string, "apple")) \
++ F.setCPU(TARGET_64BIT ? "core2" : "yonah"); \
++ else \
++ F.setCPU(ix86_arch_string); \
++ \
++ if (TARGET_64BIT) \
++ F.AddFeature("64bit"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_64BIT) \
++ F.AddFeature("64bit", false); \
++ \
++ if (TARGET_MMX) \
++ F.AddFeature("mmx"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_MMX) \
++ F.AddFeature("mmx", false); \
++ \
++ if (TARGET_3DNOW) \
++ F.AddFeature("3dnow"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW) \
++ F.AddFeature("3dnow", false); \
++ \
++ if (TARGET_3DNOW_A) \
++ F.AddFeature("3dnowa"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW_A) \
++ F.AddFeature("3dnowa", false); \
++ \
++ if (TARGET_SSE) \
++ F.AddFeature("sse"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_SSE) \
++ F.AddFeature("sse", false); \
++ \
++ if (TARGET_SSE2) \
++ F.AddFeature("sse2"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_SSE2) \
++ F.AddFeature("sse2", false); \
++ \
++ if (TARGET_SSE3) \
++ F.AddFeature("sse3"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_SSE3) \
++ F.AddFeature("sse3", false); \
++ \
++ if (TARGET_SSSE3) \
++ F.AddFeature("ssse3"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_SSSE3) \
++ F.AddFeature("ssse3", false); \
++ \
++ if (TARGET_SSE4_1) \
++ F.AddFeature("sse41"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_1) \
++ F.AddFeature("sse41", false); \
++ \
++ if (TARGET_SSE4_2) \
++ F.AddFeature("sse42"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_2) \
++ F.AddFeature("sse42", false); \
++ \
++ if (TARGET_AVX) \
++ F.AddFeature("avx"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_AVX) \
++ F.AddFeature("avx", false); \
++ \
++ if (TARGET_FMA) \
++ F.AddFeature("fma3"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_FMA) \
++ F.AddFeature("fma3", false); \
++ \
++ if (TARGET_SSE4A) \
++ F.AddFeature("sse4a"); \
++ else if (target_flags_explicit & OPTION_MASK_ISA_SSE4A) \
++ F.AddFeature("sse4a", false); \
++ }
++
++#define LLVM_SET_IMPLICIT_FLOAT(flag_no_implicit_float) \
++ if (!TARGET_80387) \
++ flag_no_implicit_float = 1; \
++ else \
++ flag_no_implicit_float = 0;
++
++/* LLVM ABI definition macros. */
++
++/* When -m64 is specified, set the architecture to x86_64-os-blah even if the
++ * compiler was configured for i[3456]86-os-blah.
++ */
++#define LLVM_OVERRIDE_TARGET_ARCH() \
++ (TARGET_64BIT ? "x86_64" : "i386")
++
++/* LLVM_TARGET_INTRINSIC_LOWER - To handle builtins, we want to expand the
++ * invocation into normal LLVM code. If the target can handle the builtin, this
++ * macro should call the target TreeToLLVM::TargetIntrinsicLower method and
++ * return true.This macro is invoked from a method in the TreeToLLVM class.
++ */
++#define LLVM_TARGET_INTRINSIC_LOWER(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS) \
++ TargetIntrinsicLower(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS);
++
++/* LLVM_GET_REG_NAME - When extracting a register name for a constraint, use
++ the string extracted from the magic symbol built for that register, rather
++ than reg_names. The latter maps both AH and AL to the same thing, which
++ means we can't distinguish them. */
++#define LLVM_GET_REG_NAME(REG_NAME, REG_NUM) __extension__ \
++ ({ const char *nm = (REG_NAME); \
++ if (nm && (*nm == '%' || *nm == '#')) ++nm; \
++ ((!nm || ISDIGIT (*nm)) ? reg_names[REG_NUM] : nm); })
++
++/* LLVM_CANONICAL_ADDRESS_CONSTRAINTS - Valid x86 memory addresses include
++ symbolic values and immediates. Canonicalize GCC's "p" constraint for
++ memory addresses to allow both memory and immediate operands. */
++#define LLVM_CANONICAL_ADDRESS_CONSTRAINTS "im"
++
++/* Propagate code model setting to backend */
++#define LLVM_SET_MACHINE_OPTIONS(argvec) \
++ do { \
++ switch (ix86_cmodel) { \
++ default: \
++ sorry ("code model %<%s%> not supported yet", \
++ ix86_cmodel_string); \
++ break; \
++ case CM_SMALL: \
++ case CM_SMALL_PIC: \
++ argvec.push_back("--code-model=small"); \
++ break; \
++ case CM_KERNEL: \
++ argvec.push_back("--code-model=kernel"); \
++ break; \
++ case CM_MEDIUM: \
++ case CM_MEDIUM_PIC: \
++ argvec.push_back("--code-model=medium"); \
++ break; \
++ case CM_32: \
++ argvec.push_back("--code-model=default"); \
++ break; \
++ } \
++ if (TARGET_OMIT_LEAF_FRAME_POINTER) \
++ argvec.push_back("--disable-non-leaf-fp-elim"); \
++ \
++ if (ix86_force_align_arg_pointer) \
++ argvec.push_back("-force-align-stack"); \
++ } while (0)
++
++#endif /* DRAGONEGG_TARGET_H */
+diff -r -u -N dragonegg-2.9-old/x86/Target.cpp dragonegg-2.9-new/x86/Target.cpp
+--- dragonegg-2.9-old/x86/Target.cpp 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/x86/Target.cpp 2011-04-09 00:38:11.359996741 +0200
+@@ -22,8 +22,8 @@
+ //===----------------------------------------------------------------------===//
+
+ // Plugin headers
+-#include "ABI.h"
+-#include "Target.h"
++#include "dragonegg/ABI.h"
++#include "dragonegg/Target.h"
+
+ // LLVM headers
+ #include "llvm/Module.h"
+diff -r -u -N dragonegg-2.9-old/x86/Target.h dragonegg-2.9-new/x86/Target.h
+--- dragonegg-2.9-old/x86/Target.h 2011-03-10 17:05:54.000000000 +0100
++++ dragonegg-2.9-new/x86/Target.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,403 +0,0 @@
+-//==----- Target.h - Target hooks for GCC to LLVM conversion -----*- C++ -*-==//
+-//
+-// Copyright (C) 2007, 2008, 2009, 2010, 2011 Anton Korobeynikov, Duncan Sands
+-// et al.
+-//
+-// This file is part of DragonEgg.
+-//
+-// DragonEgg is free software; you can redistribute it and/or modify it under
+-// the terms of the GNU General Public License as published by the Free Software
+-// Foundation; either version 2, or (at your option) any later version.
+-//
+-// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
+-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+-//
+-// You should have received a copy of the GNU General Public License along with
+-// DragonEgg; see the file COPYING. If not, write to the Free Software
+-// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+-//
+-//===----------------------------------------------------------------------===//
+-// This file declares some target-specific hooks for GCC to LLVM conversion.
+-//===----------------------------------------------------------------------===//
+-
+-#ifndef DRAGONEGG_TARGET_H
+-#define DRAGONEGG_TARGET_H
+-
+-/* LLVM specific stuff for supporting calling convention output */
+-#define TARGET_ADJUST_LLVM_CC(CC, type) \
+- { \
+- tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
+- if (lookup_attribute ("stdcall", type_attributes)) { \
+- CC = CallingConv::X86_StdCall; \
+- } else if (lookup_attribute("fastcall", type_attributes)) { \
+- CC = CallingConv::X86_FastCall; \
+- } \
+- }
+-
+-#define TARGET_ADJUST_LLVM_RETATTR(Rattributes, type) \
+- { \
+- tree_node *type_attributes = TYPE_ATTRIBUTES (type); \
+- if (!TARGET_64BIT && (TARGET_SSEREGPARM || \
+- lookup_attribute("sseregparm", type_attributes)))\
+- RAttributes |= Attribute::InReg; \
+- }
+-
+-/* LLVM specific stuff for converting gcc's `regparm` attribute to LLVM's
+- `inreg` parameter attribute */
+-#define LLVM_TARGET_ENABLE_REGPARM
+-
+-extern "C" int ix86_regparm;
+-
+-#define LLVM_TARGET_INIT_REGPARM(local_regparm, local_fp_regparm, type) \
+- { \
+- tree_node *attr; \
+- local_regparm = ix86_regparm; \
+- local_fp_regparm = TARGET_SSEREGPARM ? 3 : 0; \
+- attr = lookup_attribute ("regparm", \
+- TYPE_ATTRIBUTES (type)); \
+- if (attr) { \
+- local_regparm = TREE_INT_CST_LOW (TREE_VALUE \
+- (TREE_VALUE (attr))); \
+- } \
+- attr = lookup_attribute("sseregparm", \
+- TYPE_ATTRIBUTES (type)); \
+- if (attr) \
+- local_fp_regparm = 3; \
+- }
+-
+-#define LLVM_ADJUST_REGPARM_ATTRIBUTE(PAttribute, Type, Size, \
+- local_regparm, \
+- local_fp_regparm) \
+- { \
+- if (!TARGET_64BIT) { \
+- if (TREE_CODE(Type) == REAL_TYPE && \
+- (TYPE_PRECISION(Type)==32 || \
+- TYPE_PRECISION(Type)==64)) { \
+- local_fp_regparm -= 1; \
+- if (local_fp_regparm >= 0) \
+- PAttribute |= Attribute::InReg; \
+- else \
+- local_fp_regparm = 0; \
+- } else if (INTEGRAL_TYPE_P(Type) || \
+- POINTER_TYPE_P(Type)) { \
+- int words = \
+- (Size + BITS_PER_WORD - 1) / BITS_PER_WORD; \
+- local_regparm -= words; \
+- if (local_regparm>=0) \
+- PAttribute |= Attribute::InReg; \
+- else \
+- local_regparm = 0; \
+- } \
+- } \
+- }
+-
+-#define LLVM_SET_RED_ZONE_FLAG(disable_red_zone) \
+- if (TARGET_64BIT && TARGET_NO_RED_ZONE) \
+- disable_red_zone = 1;
+-
+-#ifdef DRAGONEGG_ABI_H
+-
+-/* On x86-32 objects containing SSE vectors are 16 byte aligned, everything
+- else 4. On x86-64 vectors are 8-byte aligned, everything else can
+- be figured out by the back end. */
+-#define LLVM_BYVAL_ALIGNMENT(T) \
+- (TYPE_ALIGN(T) / 8)
+-
+-extern tree_node *llvm_x86_should_return_selt_struct_as_scalar(tree_node *);
+-
+-/* Structs containing a single data field plus zero-length fields are
+- considered as if they were the type of the data field. On x86-64,
+- if the element type is an MMX vector, return it as double (which will
+- get it into XMM0). */
+-
+-#define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
+- llvm_x86_should_return_selt_struct_as_scalar((X))
+-
+-extern bool llvm_x86_should_pass_aggregate_in_integer_regs(tree_node *,
+- unsigned*, bool*);
+-
+-/* LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if this aggregate
+- value should be passed in integer registers. This differs from the usual
+- handling in that x86-64 passes 128-bit structs and unions which only
+- contain data in the first 64 bits, as 64-bit objects. (These can be
+- created by abusing __attribute__((aligned)). */
+-#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y, Z) \
+- llvm_x86_should_pass_aggregate_in_integer_regs((X), (Y), (Z))
+-
+-extern const Type *llvm_x86_scalar_type_for_struct_return(tree_node *type,
+- unsigned *Offset);
+-
+-/* LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+- returned as a scalar, otherwise return NULL. */
+-#define LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(X, Y) \
+- llvm_x86_scalar_type_for_struct_return((X), (Y))
+-
+-extern const Type *llvm_x86_aggr_type_for_struct_return(tree_node *type);
+-
+-/* LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
+- returned as an aggregate, otherwise return NULL. */
+-#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
+- llvm_x86_aggr_type_for_struct_return(X)
+-
+-extern void llvm_x86_extract_multiple_return_value(Value *Src, Value *Dest,
+- bool isVolatile,
+- LLVMBuilder &B);
+-
+-/* LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return value from
+- SRC and assign it to DEST. */
+-#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
+- llvm_x86_extract_multiple_return_value((Src),(Dest),(V),(B))
+-
+-extern bool llvm_x86_should_pass_vector_using_byval_attr(tree_node *);
+-
+-/* On x86-64, vectors which are not MMX nor SSE should be passed byval. */
+-#define LLVM_SHOULD_PASS_VECTOR_USING_BYVAL_ATTR(X) \
+- llvm_x86_should_pass_vector_using_byval_attr((X))
+-
+-extern bool llvm_x86_should_pass_vector_in_integer_regs(tree_node *);
+-
+-/* On x86-32, vectors which are not MMX nor SSE should be passed as integers. */
+-#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X) \
+- llvm_x86_should_pass_vector_in_integer_regs((X))
+-
+-extern tree_node *llvm_x86_should_return_vector_as_scalar(tree_node *, bool);
+-
+-/* The MMX vector v1i64 is returned in EAX and EDX on Darwin. Communicate
+- this by returning i64 here. Likewise, (generic) vectors such as v2i16
+- are returned in EAX.
+- On Darwin x86-64, MMX vectors are returned in XMM0. Communicate this by
+- returning f64. */
+-#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin)\
+- llvm_x86_should_return_vector_as_scalar((X), (isBuiltin))
+-
+-extern bool llvm_x86_should_return_vector_as_shadow(tree_node *, bool);
+-
+-/* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
+- 32-bit. Vectors bigger than 128 are returned using sret. */
+-#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
+- llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
+-
+-extern bool
+-llvm_x86_should_not_return_complex_in_memory(tree_node *type);
+-
+-/* LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+- special _Complex handling. Return true if X should be returned using
+- multiple value return instruction. */
+-#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+- llvm_x86_should_not_return_complex_in_memory((X))
+-
+-extern bool
+-llvm_x86_should_pass_aggregate_as_fca(tree_node *type, const Type *);
+-
+-/* LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if an aggregate of the
+- specified type should be passed as a first-class aggregate. */
+-#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+-#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+- llvm_x86_should_pass_aggregate_as_fca(X, TY)
+-#endif
+-
+-extern bool llvm_x86_should_pass_aggregate_in_memory(tree_node *, const Type *);
+-
+-#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
+- llvm_x86_should_pass_aggregate_in_memory(X, TY)
+-
+-
+-extern bool
+-llvm_x86_64_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
+- std::vector<const Type*>&);
+-extern bool
+-llvm_x86_32_should_pass_aggregate_in_mixed_regs(tree_node *, const Type *Ty,
+- std::vector<const Type*>&);
+-
+-#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
+- (TARGET_64BIT ? \
+- llvm_x86_64_should_pass_aggregate_in_mixed_regs((T), (TY), (E)) : \
+- llvm_x86_32_should_pass_aggregate_in_mixed_regs((T), (TY), (E)))
+-
+-extern
+-bool llvm_x86_64_aggregate_partially_passed_in_regs(std::vector<const Type*>&,
+- std::vector<const Type*>&,
+- bool);
+-
+-#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
+- (TARGET_64BIT ? \
+- llvm_x86_64_aggregate_partially_passed_in_regs((E), (SE), (ISR)) : \
+- false)
+-
+-#endif /* DRAGONEGG_ABI_H */
+-
+-/* Register class used for passing given 64bit part of the argument.
+- These represent classes as documented by the PS ABI, with the exception
+- of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+- use SF or DFmode move instead of DImode to avoid reformatting penalties.
+-
+- Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
+- whenever possible (upper half does contain padding).
+- */
+-enum x86_64_reg_class
+- {
+- X86_64_NO_CLASS,
+- X86_64_INTEGER_CLASS,
+- X86_64_INTEGERSI_CLASS,
+- X86_64_SSE_CLASS,
+- X86_64_SSESF_CLASS,
+- X86_64_SSEDF_CLASS,
+- X86_64_SSEUP_CLASS,
+- X86_64_X87_CLASS,
+- X86_64_X87UP_CLASS,
+- X86_64_COMPLEX_X87_CLASS,
+- X86_64_MEMORY_CLASS
+- };
+-
+-/* LLVM_TARGET_INTRINSIC_PREFIX - Specify what prefix this target uses for its
+- * intrinsics.
+- */
+-#define LLVM_TARGET_INTRINSIC_PREFIX "x86"
+-
+-/* LLVM_TARGET_NAME - This specifies the name of the target, which correlates to
+- * the llvm::InitializeXXXTarget() function.
+- */
+-#define LLVM_TARGET_NAME X86
+-
+-/* Turn -march=xx into a CPU type.
+- */
+-#define LLVM_SET_SUBTARGET_FEATURES(F) \
+- { if (TARGET_MACHO && ! strcmp (ix86_arch_string, "apple")) \
+- F.setCPU(TARGET_64BIT ? "core2" : "yonah"); \
+- else \
+- F.setCPU(ix86_arch_string); \
+- \
+- if (TARGET_64BIT) \
+- F.AddFeature("64bit"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_64BIT) \
+- F.AddFeature("64bit", false); \
+- \
+- if (TARGET_MMX) \
+- F.AddFeature("mmx"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_MMX) \
+- F.AddFeature("mmx", false); \
+- \
+- if (TARGET_3DNOW) \
+- F.AddFeature("3dnow"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW) \
+- F.AddFeature("3dnow", false); \
+- \
+- if (TARGET_3DNOW_A) \
+- F.AddFeature("3dnowa"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_3DNOW_A) \
+- F.AddFeature("3dnowa", false); \
+- \
+- if (TARGET_SSE) \
+- F.AddFeature("sse"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_SSE) \
+- F.AddFeature("sse", false); \
+- \
+- if (TARGET_SSE2) \
+- F.AddFeature("sse2"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_SSE2) \
+- F.AddFeature("sse2", false); \
+- \
+- if (TARGET_SSE3) \
+- F.AddFeature("sse3"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_SSE3) \
+- F.AddFeature("sse3", false); \
+- \
+- if (TARGET_SSSE3) \
+- F.AddFeature("ssse3"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_SSSE3) \
+- F.AddFeature("ssse3", false); \
+- \
+- if (TARGET_SSE4_1) \
+- F.AddFeature("sse41"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_1) \
+- F.AddFeature("sse41", false); \
+- \
+- if (TARGET_SSE4_2) \
+- F.AddFeature("sse42"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_SSE4_2) \
+- F.AddFeature("sse42", false); \
+- \
+- if (TARGET_AVX) \
+- F.AddFeature("avx"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_AVX) \
+- F.AddFeature("avx", false); \
+- \
+- if (TARGET_FMA) \
+- F.AddFeature("fma3"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_FMA) \
+- F.AddFeature("fma3", false); \
+- \
+- if (TARGET_SSE4A) \
+- F.AddFeature("sse4a"); \
+- else if (target_flags_explicit & OPTION_MASK_ISA_SSE4A) \
+- F.AddFeature("sse4a", false); \
+- }
+-
+-#define LLVM_SET_IMPLICIT_FLOAT(flag_no_implicit_float) \
+- if (!TARGET_80387) \
+- flag_no_implicit_float = 1; \
+- else \
+- flag_no_implicit_float = 0;
+-
+-/* LLVM ABI definition macros. */
+-
+-/* When -m64 is specified, set the architecture to x86_64-os-blah even if the
+- * compiler was configured for i[3456]86-os-blah.
+- */
+-#define LLVM_OVERRIDE_TARGET_ARCH() \
+- (TARGET_64BIT ? "x86_64" : "i386")
+-
+-/* LLVM_TARGET_INTRINSIC_LOWER - To handle builtins, we want to expand the
+- * invocation into normal LLVM code. If the target can handle the builtin, this
+- * macro should call the target TreeToLLVM::TargetIntrinsicLower method and
+- * return true.This macro is invoked from a method in the TreeToLLVM class.
+- */
+-#define LLVM_TARGET_INTRINSIC_LOWER(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS) \
+- TargetIntrinsicLower(STMT, FNDECL, DESTLOC, RESULT, DESTTY, OPS);
+-
+-/* LLVM_GET_REG_NAME - When extracting a register name for a constraint, use
+- the string extracted from the magic symbol built for that register, rather
+- than reg_names. The latter maps both AH and AL to the same thing, which
+- means we can't distinguish them. */
+-#define LLVM_GET_REG_NAME(REG_NAME, REG_NUM) __extension__ \
+- ({ const char *nm = (REG_NAME); \
+- if (nm && (*nm == '%' || *nm == '#')) ++nm; \
+- ((!nm || ISDIGIT (*nm)) ? reg_names[REG_NUM] : nm); })
+-
+-/* LLVM_CANONICAL_ADDRESS_CONSTRAINTS - Valid x86 memory addresses include
+- symbolic values and immediates. Canonicalize GCC's "p" constraint for
+- memory addresses to allow both memory and immediate operands. */
+-#define LLVM_CANONICAL_ADDRESS_CONSTRAINTS "im"
+-
+-/* Propagate code model setting to backend */
+-#define LLVM_SET_MACHINE_OPTIONS(argvec) \
+- do { \
+- switch (ix86_cmodel) { \
+- default: \
+- sorry ("code model %<%s%> not supported yet", \
+- ix86_cmodel_string); \
+- break; \
+- case CM_SMALL: \
+- case CM_SMALL_PIC: \
+- argvec.push_back("--code-model=small"); \
+- break; \
+- case CM_KERNEL: \
+- argvec.push_back("--code-model=kernel"); \
+- break; \
+- case CM_MEDIUM: \
+- case CM_MEDIUM_PIC: \
+- argvec.push_back("--code-model=medium"); \
+- break; \
+- case CM_32: \
+- argvec.push_back("--code-model=default"); \
+- break; \
+- } \
+- if (TARGET_OMIT_LEAF_FRAME_POINTER) \
+- argvec.push_back("--disable-non-leaf-fp-elim"); \
+- \
+- if (ix86_force_align_arg_pointer) \
+- argvec.push_back("-force-align-stack"); \
+- } while (0)
+-
+-#endif /* DRAGONEGG_TARGET_H */
Modified: dragonegg/trunk/www/index.html
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/index.html?rev=129211&r1=129210&r2=129211&view=diff
==============================================================================
--- dragonegg/trunk/www/index.html (original)
+++ dragonegg/trunk/www/index.html Sat Apr 9 06:40:18 2011
@@ -88,7 +88,9 @@
</pre>
</li>
<li>
- The build fails if you are using a case insensitive file system.
+ The build fails if you are using a case insensitive file system, such as
+ the default darwin filesystem <tt>HFS+</tt>. To fix this, apply
+ <a href="disambiguate.diff">this patch</a>.
</li>
</ul>
<li><p><a href="#gettingrelease">DragonEgg-2.8</a> was the second
More information about the llvm-commits
mailing list