summaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-10-14 17:57:32 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-10-14 17:57:32 +0000
commitcd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch)
treeb21f6de4e08b89bb7931806bab798fc2a5e3a686 /include/llvm/Support
parent72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff)
downloadFreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip
FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz
Update llvm to r84119.
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/Allocator.h97
-rw-r--r--include/llvm/Support/CFG.h19
-rw-r--r--include/llvm/Support/CallSite.h7
-rw-r--r--include/llvm/Support/Casting.h4
-rw-r--r--include/llvm/Support/CommandLine.h104
-rw-r--r--include/llvm/Support/Compiler.h8
-rw-r--r--include/llvm/Support/ConstantFolder.h42
-rw-r--r--include/llvm/Support/ConstantRange.h61
-rw-r--r--include/llvm/Support/DataTypes.h.cmake79
-rw-r--r--include/llvm/Support/DataTypes.h.in69
-rw-r--r--include/llvm/Support/Debug.h52
-rw-r--r--include/llvm/Support/DebugLoc.h33
-rw-r--r--include/llvm/Support/Dwarf.h1
-rw-r--r--include/llvm/Support/ErrorHandling.h87
-rw-r--r--include/llvm/Support/Format.h61
-rw-r--r--include/llvm/Support/FormattedStream.h150
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h5
-rw-r--r--include/llvm/Support/GraphWriter.h107
-rw-r--r--include/llvm/Support/IRBuilder.h541
-rw-r--r--include/llvm/Support/IRReader.h115
-rw-r--r--include/llvm/Support/InstVisitor.h22
-rw-r--r--include/llvm/Support/LeakDetector.h6
-rw-r--r--include/llvm/Support/ManagedStatic.h18
-rw-r--r--include/llvm/Support/Mangler.h74
-rw-r--r--include/llvm/Support/MathExtras.h21
-rw-r--r--include/llvm/Support/MemoryBuffer.h5
-rw-r--r--include/llvm/Support/MemoryObject.h70
-rw-r--r--include/llvm/Support/NoFolder.h27
-rw-r--r--include/llvm/Support/PassNameParser.h5
-rw-r--r--include/llvm/Support/PatternMatch.h26
-rw-r--r--include/llvm/Support/PointerLikeTypeTraits.h10
-rw-r--r--include/llvm/Support/PrettyStackTrace.h6
-rw-r--r--include/llvm/Support/Recycler.h3
-rw-r--r--include/llvm/Support/Regex.h63
-rw-r--r--include/llvm/Support/Registry.h3
-rw-r--r--include/llvm/Support/SourceMgr.h17
-rw-r--r--include/llvm/Support/StandardPasses.h130
-rw-r--r--include/llvm/Support/StringPool.h13
-rw-r--r--include/llvm/Support/SystemUtils.h18
-rw-r--r--include/llvm/Support/TargetFolder.h33
-rw-r--r--include/llvm/Support/Timer.h6
-rw-r--r--include/llvm/Support/TypeBuilder.h259
-rw-r--r--include/llvm/Support/ValueHandle.h155
-rw-r--r--include/llvm/Support/raw_os_ostream.h42
-rw-r--r--include/llvm/Support/raw_ostream.h277
-rw-r--r--include/llvm/Support/type_traits.h40
46 files changed, 2060 insertions, 931 deletions
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index c0414f9..4c84878 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -15,6 +15,8 @@
#define LLVM_SUPPORT_ALLOCATOR_H
#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
#include <cstdlib>
namespace llvm {
@@ -41,21 +43,104 @@ public:
void PrintStats() const {}
};
-/// BumpPtrAllocator - This allocator is useful for containers that need very
-/// simple memory allocation strategies. In particular, this just keeps
+/// MemSlab - This structure lives at the beginning of every slab allocated by
+/// the bump allocator.
+class MemSlab {
+public:
+ size_t Size;
+ MemSlab *NextPtr;
+};
+
+/// SlabAllocator - This class can be used to parameterize the underlying
+/// allocation strategy for the bump allocator. In particular, this is used
+/// by the JIT to allocate contiguous swathes of executable memory. The
+/// interface uses MemSlab's instead of void *'s so that the allocator
+/// doesn't have to remember the size of the pointer it allocated.
+class SlabAllocator {
+public:
+ virtual ~SlabAllocator();
+ virtual MemSlab *Allocate(size_t Size) = 0;
+ virtual void Deallocate(MemSlab *Slab) = 0;
+};
+
+/// MallocSlabAllocator - The default slab allocator for the bump allocator
+/// is an adapter class for MallocAllocator that just forwards the method
+/// calls and translates the arguments.
+class MallocSlabAllocator : public SlabAllocator {
+ /// Allocator - The underlying allocator that we forward to.
+ ///
+ MallocAllocator Allocator;
+
+public:
+ MallocSlabAllocator() : Allocator() { }
+ virtual ~MallocSlabAllocator();
+ virtual MemSlab *Allocate(size_t Size);
+ virtual void Deallocate(MemSlab *Slab);
+};
+
+/// BumpPtrAllocator - This allocator is useful for containers that need
+/// very simple memory allocation strategies. In particular, this just keeps
/// allocating memory, and never deletes it until the entire block is dead. This
/// makes allocation speedy, but must only be used when the trade-off is ok.
class BumpPtrAllocator {
BumpPtrAllocator(const BumpPtrAllocator &); // do not implement
void operator=(const BumpPtrAllocator &); // do not implement
- void *TheMemory;
+ /// SlabSize - Allocate data into slabs of this size unless we get an
+ /// allocation above SizeThreshold.
+ size_t SlabSize;
+
+ /// SizeThreshold - For any allocation larger than this threshold, we should
+ /// allocate a separate slab.
+ size_t SizeThreshold;
+
+ /// Allocator - The underlying allocator we use to get slabs of memory. This
+ /// defaults to MallocSlabAllocator, which wraps malloc, but it could be
+ /// changed to use a custom allocator.
+ SlabAllocator &Allocator;
+
+ /// CurSlab - The slab that we are currently allocating into.
+ ///
+ MemSlab *CurSlab;
+
+ /// CurPtr - The current pointer into the current slab. This points to the
+ /// next free byte in the slab.
+ char *CurPtr;
+
+ /// End - The end of the current slab.
+ ///
+ char *End;
+
+ /// BytesAllocated - This field tracks how many bytes we've allocated, so
+ /// that we can compute how much space was wasted.
+ size_t BytesAllocated;
+
+ /// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should
+ /// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and
+ /// AlignPtr(8, 4) == 8.
+ static char *AlignPtr(char *Ptr, size_t Alignment);
+
+ /// StartNewSlab - Allocate a new slab and move the bump pointers over into
+ /// the new slab. Modifies CurPtr and End.
+ void StartNewSlab();
+
+ /// DeallocateSlabs - Deallocate all memory slabs after and including this
+ /// one.
+ void DeallocateSlabs(MemSlab *Slab);
+
+ static MallocSlabAllocator DefaultSlabAllocator;
+
public:
- BumpPtrAllocator();
+ BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
+ SlabAllocator &allocator = DefaultSlabAllocator);
~BumpPtrAllocator();
+ /// Reset - Deallocate all but the current slab and reset the current pointer
+ /// to the beginning of it, freeing all memory allocated so far.
void Reset();
+ /// Allocate - Allocate space at the specified alignment.
+ ///
void *Allocate(size_t Size, size_t Alignment);
/// Allocate space, but do not construct, one object.
@@ -83,9 +168,11 @@ public:
void Deallocate(const void * /*Ptr*/) {}
+ unsigned GetNumSlabs() const;
+
void PrintStats() const;
};
} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_ALLOCATOR_H
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index b0b857b..3a20696 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -18,17 +18,17 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Function.h"
#include "llvm/InstrTypes.h"
-#include "llvm/ADT/iterator.h"
namespace llvm {
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
// BasicBlock pred_iterator definition
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
template <class _Ptr, class _USE_iterator> // Predecessor Iterator
-class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> {
- typedef forward_iterator<_Ptr, ptrdiff_t> super;
+class PredIterator : public std::iterator<std::forward_iterator_tag,
+ _Ptr, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag, _Ptr, ptrdiff_t> super;
_USE_iterator It;
public:
typedef PredIterator<_Ptr,_USE_iterator> _Self;
@@ -80,15 +80,16 @@ inline pred_const_iterator pred_end(const BasicBlock *BB) {
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
// BasicBlock succ_iterator definition
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
template <class Term_, class BB_> // Successor Iterator
-class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> {
+class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
+ BB_, ptrdiff_t> {
const Term_ Term;
unsigned idx;
- typedef bidirectional_iterator<BB_, ptrdiff_t> super;
+ typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super;
public:
typedef SuccIterator<Term_, BB_> _Self;
typedef typename super::pointer pointer;
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index dc41590..285b558 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -26,6 +26,7 @@
#include "llvm/Attributes.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/BasicBlock.h"
+#include "llvm/CallingConv.h"
#include "llvm/Instruction.h"
namespace llvm {
@@ -40,8 +41,6 @@ public:
CallSite(CallInst *CI) : I(reinterpret_cast<Instruction*>(CI), true) {}
CallSite(InvokeInst *II) : I(reinterpret_cast<Instruction*>(II), false) {}
CallSite(Instruction *C);
- CallSite(const CallSite &CS) : I(CS.I) {}
- CallSite &operator=(const CallSite &CS) { I = CS.I; return *this; }
bool operator==(const CallSite &CS) const { return I == CS.I; }
bool operator!=(const CallSite &CS) const { return I != CS.I; }
@@ -63,8 +62,8 @@ public:
/// getCallingConv/setCallingConv - get or set the calling convention of the
/// call.
- unsigned getCallingConv() const;
- void setCallingConv(unsigned CC);
+ CallingConv::ID getCallingConv() const;
+ void setCallingConv(CallingConv::ID CC);
/// getAttributes/setAttributes - get or set the parameter attributes of
/// the call.
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 48988f8..35fb29e 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -235,7 +235,7 @@ inline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(const Y &Val) {
#ifdef DEBUG_CAST_OPERATORS
-#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
struct bar {
bar() {}
@@ -251,7 +251,7 @@ struct foo {
};
template <> inline bool isa_impl<foo,bar>(const bar &Val) {
- cerr << "Classof: " << &Val << "\n";
+ errs() << "Classof: " << &Val << "\n";
return true;
}
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 3ae5013..dc73979 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -21,18 +21,17 @@
#define LLVM_SUPPORT_COMMANDLINE_H
#include "llvm/Support/type_traits.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
#include <cassert>
#include <climits>
#include <cstdarg>
-#include <string>
#include <utility>
#include <vector>
namespace llvm {
-
+
/// cl Namespace - This namespace contains all of the command line option
/// processing machinery. It is intentionally a short name to make qualified
/// usage concise.
@@ -68,7 +67,7 @@ void MarkOptionsChanged();
// Flags permitted to be passed to command line arguments
//
-enum NumOccurrences { // Flags for the number of occurrences allowed
+enum NumOccurrencesFlag { // Flags for the number of occurrences allowed
Optional = 0x01, // Zero or One occurrence
ZeroOrMore = 0x02, // Zero or more occurrences allowed
Required = 0x03, // One occurrence required
@@ -143,8 +142,8 @@ class Option {
// an argument. Should return true if there was an error processing the
// argument and the program should exit.
//
- virtual bool handleOccurrence(unsigned pos, const char *ArgName,
- const std::string &Arg) = 0;
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) = 0;
virtual enum ValueExpected getValueExpectedFlagDefault() const {
return ValueOptional;
@@ -163,8 +162,8 @@ public:
const char *HelpStr; // The descriptive text message for --help
const char *ValueStr; // String describing what the value of this option is
- inline enum NumOccurrences getNumOccurrencesFlag() const {
- return static_cast<enum NumOccurrences>(Flags & OccurrencesMask);
+ inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
+ return static_cast<enum NumOccurrencesFlag>(Flags & OccurrencesMask);
}
inline enum ValueExpected getValueExpectedFlag() const {
int VE = Flags & ValueMask;
@@ -198,7 +197,7 @@ public:
Flags |= Flag;
}
- void setNumOccurrencesFlag(enum NumOccurrences Val) {
+ void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) {
setFlag(Val, OccurrencesMask);
}
void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); }
@@ -215,8 +214,7 @@ protected:
getOptionHiddenFlag() != 0 && "Not all default flags specified!");
}
- inline void setNumAdditionalVals(unsigned n)
- { AdditionalVals = n; }
+ inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
public:
// addArgument - Register this argument with the commandline system.
//
@@ -232,15 +230,15 @@ public:
//
virtual void printOptionInfo(size_t GlobalWidth) const = 0;
- virtual void getExtraOptionNames(std::vector<const char*> &) {}
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &) {}
- // addOccurrence - Wrapper around handleOccurrence that enforces Flags
+ // addOccurrence - Wrapper around handleOccurrence that enforces Flags.
//
- bool addOccurrence(unsigned pos, const char *ArgName,
- const std::string &Value, bool MultiArg = false);
+ bool addOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Value, bool MultiArg = false);
// Prints option name followed by message. Always returns true.
- bool error(std::string Message, const char *ArgName = 0);
+ bool error(const Twine &Message, StringRef ArgName = StringRef());
public:
inline int getNumOccurrences() const { return NumOccurrences; }
@@ -399,7 +397,7 @@ struct generic_parser_base {
hasArgStr = O.hasArgStr();
}
- void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
// If there has been no argstr specified, that means that we need to add an
// argument for every possible option. This ensures that our options are
// vectored to us.
@@ -458,9 +456,8 @@ public:
}
// parse - Return true on error.
- bool parse(Option &O, const char *ArgName, const std::string &Arg,
- DataType &V) {
- std::string ArgVal;
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) {
+ StringRef ArgVal;
if (hasArgStr)
ArgVal = Arg;
else
@@ -468,12 +465,12 @@ public:
for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
i != e; ++i)
- if (ArgVal == Values[i].first) {
+ if (Values[i].first == ArgVal) {
V = Values[i].second.first;
return false;
}
- return O.error(": Cannot find option named '" + ArgVal + "'!");
+ return O.error("Cannot find option named '" + ArgVal + "'!");
}
/// addLiteralOption - Add an entry to the mapping table.
@@ -505,7 +502,7 @@ struct basic_parser_impl { // non-template implementation of basic_parser<t>
return ValueRequired;
}
- void getExtraOptionNames(std::vector<const char*> &) {}
+ void getExtraOptionNames(SmallVectorImpl<const char*> &) {}
void initialize(Option &) {}
@@ -541,7 +538,7 @@ class parser<bool> : public basic_parser<bool> {
public:
// parse - Return true on error.
- bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val);
template <class Opt>
void initialize(Opt &O) {
@@ -568,8 +565,7 @@ template<>
class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
public:
// parse - Return true on error.
- bool parse(Option &O, const char *ArgName, const std::string &Arg,
- boolOrDefault &Val);
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val);
enum ValueExpected getValueExpectedFlagDefault() const {
return ValueOptional;
@@ -591,7 +587,7 @@ template<>
class parser<int> : public basic_parser<int> {
public:
// parse - Return true on error.
- bool parse(Option &O, const char *ArgName, const std::string &Arg, int &Val);
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val);
// getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "int"; }
@@ -610,7 +606,7 @@ template<>
class parser<unsigned> : public basic_parser<unsigned> {
public:
// parse - Return true on error.
- bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val);
// getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "uint"; }
@@ -628,7 +624,7 @@ template<>
class parser<double> : public basic_parser<double> {
public:
// parse - Return true on error.
- bool parse(Option &O, const char *AN, const std::string &Arg, double &Val);
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val);
// getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "number"; }
@@ -646,7 +642,7 @@ template<>
class parser<float> : public basic_parser<float> {
public:
// parse - Return true on error.
- bool parse(Option &O, const char *AN, const std::string &Arg, float &Val);
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val);
// getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "number"; }
@@ -664,9 +660,8 @@ template<>
class parser<std::string> : public basic_parser<std::string> {
public:
// parse - Return true on error.
- bool parse(Option &, const char *, const std::string &Arg,
- std::string &Value) {
- Value = Arg;
+ bool parse(Option &, StringRef ArgName, StringRef Arg, std::string &Value) {
+ Value = Arg.str();
return false;
}
@@ -686,8 +681,7 @@ template<>
class parser<char> : public basic_parser<char> {
public:
// parse - Return true on error.
- bool parse(Option &, const char *, const std::string &Arg,
- char &Value) {
+ bool parse(Option &, StringRef ArgName, StringRef Arg, char &Value) {
Value = Arg[0];
return false;
}
@@ -726,8 +720,10 @@ template<> struct applicator<const char*> {
static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
};
-template<> struct applicator<NumOccurrences> {
- static void opt(NumOccurrences NO, Option &O) { O.setNumOccurrencesFlag(NO); }
+template<> struct applicator<NumOccurrencesFlag> {
+ static void opt(NumOccurrencesFlag NO, Option &O) {
+ O.setNumOccurrencesFlag(NO);
+ }
};
template<> struct applicator<ValueExpected> {
static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
@@ -770,7 +766,7 @@ public:
bool setLocation(Option &O, DataType &L) {
if (Location)
- return O.error(": cl::location(x) specified more than once!");
+ return O.error("cl::location(x) specified more than once!");
Location = &L;
return false;
}
@@ -833,8 +829,8 @@ class opt : public Option,
is_class<DataType>::value> {
ParserClass Parser;
- virtual bool handleOccurrence(unsigned pos, const char *ArgName,
- const std::string &Arg) {
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -847,7 +843,7 @@ class opt : public Option,
virtual enum ValueExpected getValueExpectedFlagDefault() const {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
return Parser.getExtraOptionNames(OptionNames);
}
@@ -964,7 +960,7 @@ public:
bool setLocation(Option &O, StorageClass &L) {
if (Location)
- return O.error(": cl::location(x) specified more than once!");
+ return O.error("cl::location(x) specified more than once!");
Location = &L;
return false;
}
@@ -1002,12 +998,11 @@ class list : public Option, public list_storage<DataType, Storage> {
virtual enum ValueExpected getValueExpectedFlagDefault() const {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, const char *ArgName,
- const std::string &Arg) {
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1139,7 +1134,7 @@ public:
bool setLocation(Option &O, unsigned &L) {
if (Location)
- return O.error(": cl::location(x) specified more than once!");
+ return O.error("cl::location(x) specified more than once!");
Location = &L;
return false;
}
@@ -1202,12 +1197,11 @@ class bits : public Option, public bits_storage<DataType, Storage> {
virtual enum ValueExpected getValueExpectedFlagDefault() const {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, const char *ArgName,
- const std::string &Arg) {
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1307,8 +1301,8 @@ public:
class alias : public Option {
Option *AliasFor;
- virtual bool handleOccurrence(unsigned pos, const char * /*ArgName*/,
- const std::string &Arg) {
+ virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
+ StringRef Arg) {
return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
}
// Handle printing stuff...
@@ -1317,15 +1311,15 @@ class alias : public Option {
void done() {
if (!hasArgStr())
- error(": cl::alias must have argument name specified!");
+ error("cl::alias must have argument name specified!");
if (AliasFor == 0)
- error(": cl::alias must have an cl::aliasopt(option) specified!");
+ error("cl::alias must have an cl::aliasopt(option) specified!");
addArgument();
}
public:
void setAliasFor(Option &O) {
if (AliasFor)
- error(": cl::alias must only have one cl::aliasopt(...) specified!");
+ error("cl::alias must only have one cl::aliasopt(...) specified!");
AliasFor = &O;
}
@@ -1366,7 +1360,7 @@ struct aliasopt {
// extrahelp - provide additional help at the end of the normal help
// output. All occurrences of cl::extrahelp will be accumulated and
-// printed to std::cerr at the end of the regular help, just before
+// printed to stderr at the end of the regular help, just before
// exit is called.
struct extrahelp {
const char * morehelp;
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 90292df..342a97d 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -23,7 +23,7 @@
#define VISIBILITY_HIDDEN
#endif
-#if (__GNUC__ >= 4)
+#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define ATTRIBUTE_USED __attribute__((__used__))
#else
#define ATTRIBUTE_USED
@@ -56,4 +56,10 @@
#define DISABLE_INLINE
#endif
+#ifdef __GNUC__
+#define NORETURN __attribute__((noreturn))
+#else
+#define NORETURN
+#endif
+
#endif
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
index 35065a0..99cb920 100644
--- a/include/llvm/Support/ConstantFolder.h
+++ b/include/llvm/Support/ConstantFolder.h
@@ -21,9 +21,12 @@
namespace llvm {
+class LLVMContext;
+
/// ConstantFolder - Create constants with minimum, target independent, folding.
class ConstantFolder {
public:
+ explicit ConstantFolder(LLVMContext &) {}
//===--------------------------------------------------------------------===//
// Binary Operators
@@ -32,12 +35,18 @@ public:
Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getAdd(LHS, RHS);
}
+ Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getNSWAdd(LHS, RHS);
+ }
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFAdd(LHS, RHS);
}
Constant *CreateSub(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getSub(LHS, RHS);
}
+ Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getNSWSub(LHS, RHS);
+ }
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFSub(LHS, RHS);
}
@@ -53,6 +62,9 @@ public:
Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getSDiv(LHS, RHS);
}
+ Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getExactSDiv(LHS, RHS);
+ }
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFDiv(LHS, RHS);
}
@@ -116,6 +128,15 @@ public:
return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);
}
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
+ }
+
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
@@ -124,10 +145,16 @@ public:
const Type *DestTy) const {
return ConstantExpr::getCast(Op, C, DestTy);
}
+ Constant *CreatePointerCast(Constant *C, const Type *DestTy) const {
+ return ConstantExpr::getPointerCast(C, DestTy);
+ }
Constant *CreateIntCast(Constant *C, const Type *DestTy,
bool isSigned) const {
return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
}
+ Constant *CreateFPCast(Constant *C, const Type *DestTy) const {
+ return ConstantExpr::getFPCast(C, DestTy);
+ }
Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
return CreateCast(Instruction::BitCast, C, DestTy);
@@ -138,6 +165,13 @@ public:
Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const {
return CreateCast(Instruction::PtrToInt, C, DestTy);
}
+ Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const {
+ return ConstantExpr::getZExtOrBitCast(C, DestTy);
+ }
+ Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const {
+ return ConstantExpr::getSExtOrBitCast(C, DestTy);
+ }
+
Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
return ConstantExpr::getTruncOrBitCast(C, DestTy);
}
@@ -154,14 +188,6 @@ public:
Constant *RHS) const {
return ConstantExpr::getCompare(P, LHS, RHS);
}
- Constant *CreateVICmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return ConstantExpr::getCompare(P, LHS, RHS);
- }
- Constant *CreateVFCmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return ConstantExpr::getCompare(P, LHS, RHS);
- }
//===--------------------------------------------------------------------===//
// Other Instructions
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index 098fab5..e9c8c7c 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/Support/ConstantRange.h
@@ -24,7 +24,9 @@
// [0, 0) = {} = Empty set
// [255, 255) = {0..255} = Full Set
//
-// Note that ConstantRange always keeps unsigned values.
+// Note that ConstantRange can be used to represent either signed or
+// unsigned ranges.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
@@ -35,11 +37,14 @@
namespace llvm {
+/// ConstantRange - This class represents an range of values.
+///
class ConstantRange {
APInt Lower, Upper;
static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
const ConstantRange &RHS);
- public:
+
+public:
/// Initialize a full (the default) or empty set for the specified bit width.
///
explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true);
@@ -53,6 +58,16 @@ class ConstantRange {
/// assert out if the two APInt's are not the same bit width.
ConstantRange(const APInt& Lower, const APInt& Upper);
+ /// makeICmpRegion - Produce the smallest range that contains all values that
+ /// might satisfy the comparison specified by Pred when compared to any value
+ /// contained within Other.
+ ///
+ /// Solves for range X in 'for all x in X, there exists a y in Y such that
+ /// icmp op x, y is true'. Every value that might make the comparison true
+ /// is included in the resulting range.
+ static ConstantRange makeICmpRegion(unsigned Pred,
+ const ConstantRange &Other);
+
/// getLower - Return the lower value for this range...
///
const APInt &getLower() const { return Lower; }
@@ -83,6 +98,10 @@ class ConstantRange {
///
bool contains(const APInt &Val) const;
+ /// contains - Return true if the other range is a subset of this one.
+ ///
+ bool contains(const ConstantRange &CR) const;
+
/// getSingleElement - If this set contains a single element, return it,
/// otherwise return null.
///
@@ -134,21 +153,13 @@ class ConstantRange {
ConstantRange subtract(const APInt &CI) const;
/// intersectWith - Return the range that results from the intersection of
- /// this range with another range. The resultant range is pruned as much as
- /// possible, but there may be cases where elements are included that are in
- /// one of the sets but not the other. For example: [100, 8) intersect [3,
- /// 120) yields [3, 120)
- ///
- ConstantRange intersectWith(const ConstantRange &CR) const;
-
- /// maximalIntersectWith - Return the range that results from the intersection
- /// of this range with another range. The resultant range is guaranteed to
+ /// this range with another range. The resultant range is guaranteed to
/// include all elements contained in both input ranges, and to have the
/// smallest possible set size that does so. Because there may be two
- /// intersections with the same set size, A.maximalIntersectWith(B) might not
- /// be equal to B.maximalIntersectWith(A).
+ /// intersections with the same set size, A.intersectWith(B) might not
+ /// be equal to B.intersectWith(A).
///
- ConstantRange maximalIntersectWith(const ConstantRange &CR) const;
+ ConstantRange intersectWith(const ConstantRange &CR) const;
/// unionWith - Return the range that results from the union of this range
/// with another range. The resultant range is guaranteed to include the
@@ -176,6 +187,28 @@ class ConstantRange {
/// truncated to the specified type.
ConstantRange truncate(uint32_t BitWidth) const;
+ /// add - Return a new range representing the possible values resulting
+ /// from an addition of a value in this range and a value in Other.
+ ConstantRange add(const ConstantRange &Other) const;
+
+ /// multiply - Return a new range representing the possible values resulting
+ /// from a multiplication of a value in this range and a value in Other.
+ /// TODO: This isn't fully implemented yet.
+ ConstantRange multiply(const ConstantRange &Other) const;
+
+ /// smax - Return a new range representing the possible values resulting
+ /// from a signed maximum of a value in this range and a value in Other.
+ ConstantRange smax(const ConstantRange &Other) const;
+
+ /// umax - Return a new range representing the possible values resulting
+ /// from an unsigned maximum of a value in this range and a value in Other.
+ ConstantRange umax(const ConstantRange &Other) const;
+
+ /// udiv - Return a new range representing the possible values resulting
+ /// from an unsigned division of a value in this range and a value in Other.
+ /// TODO: This isn't fully implemented yet.
+ ConstantRange udiv(const ConstantRange &Other) const;
+
/// print - Print out the bounds to a stream...
///
void print(raw_ostream &OS) const;
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index 4d6fcc8..ad210ed 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -1,22 +1,25 @@
-//===-- include/Support/DataTypes.h - Define fixed size types ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains definitions to figure out the size of _HOST_ data types.
-// This file is important because different host OS's define different macros,
-// which makes portability tough. This file exports the following definitions:
-//
-// [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types
-// [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values.
-//
-// No library is required when using these functinons.
-//
-//===----------------------------------------------------------------------===//
+/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file contains definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough. This file exports the following *|
+|* definitions: *|
+|* *|
+|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+|* *|
+|* No library is required when using these functinons. *|
+|* *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
@@ -24,18 +27,21 @@
#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
-#undef HAVE_UINT64_T
-#undef HAVE_U_INT64_T
+#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T}
+#cmakedefine HAVE_U_INT64_T ${HAVE_U_INT64_T}
-// FIXME: UGLY HACK (Added by Kevin)
-#define HAVE_UINT64_T 1
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
#ifndef _MSC_VER
-// Note that this header's correct operation depends on __STDC_LIMIT_MACROS
-// being defined. We would define it here, but in order to prevent Bad Things
-// happening when system headers or C++ STL headers include stdint.h before
-// we define it here, we define it on the g++ command line (in Makefile.rules).
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+ being defined. We would define it here, but in order to prevent Bad Things
+ happening when system headers or C++ STL headers include stdint.h before we
+ define it here, we define it on the g++ command line (in Makefile.rules). */
#if !defined(__STDC_LIMIT_MACROS)
# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
#endif
@@ -45,7 +51,7 @@
"#including Support/DataTypes.h"
#endif
-// Note that <inttypes.h> includes <stdint.h>, if this is a C99 system.
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -58,17 +64,11 @@
#include <stdint.h>
#endif
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-
#ifdef _AIX
#include "llvm/Support/AIXDataTypesFix.h"
#endif
-// Handle incorrect definition of uint64_t as u_int64_t
+/* Handle incorrect definition of uint64_t as u_int64_t */
#ifndef HAVE_UINT64_T
#ifdef HAVE_U_INT64_T
typedef u_int64_t uint64_t;
@@ -90,11 +90,16 @@ typedef u_int64_t uint64_t;
#endif
#else /* _MSC_VER */
-// Visual C++ doesn't provide standard integer headers, but it does provide
-// built-in data types.
+/* Visual C++ doesn't provide standard integer headers, but it does provide
+ built-in data types. */
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef signed int int32_t;
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index 72063f7..405f476 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -1,22 +1,25 @@
-//===-- include/Support/DataTypes.h - Define fixed size types ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains definitions to figure out the size of _HOST_ data types.
-// This file is important because different host OS's define different macros,
-// which makes portability tough. This file exports the following definitions:
-//
-// [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types
-// [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values.
-//
-// No library is required when using these functinons.
-//
-//===----------------------------------------------------------------------===//
+/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file contains definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough. This file exports the following *|
+|* definitions: *|
+|* *|
+|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+|* *|
+|* No library is required when using these functinons. *|
+|* *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
@@ -27,12 +30,18 @@
#undef HAVE_UINT64_T
#undef HAVE_U_INT64_T
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
#ifndef _MSC_VER
-// Note that this header's correct operation depends on __STDC_LIMIT_MACROS
-// being defined. We would define it here, but in order to prevent Bad Things
-// happening when system headers or C++ STL headers include stdint.h before
-// we define it here, we define it on the g++ command line (in Makefile.rules).
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+ being defined. We would define it here, but in order to prevent Bad Things
+ happening when system headers or C++ STL headers include stdint.h before we
+ define it here, we define it on the g++ command line (in Makefile.rules). */
#if !defined(__STDC_LIMIT_MACROS)
# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
#endif
@@ -42,7 +51,7 @@
"#including Support/DataTypes.h"
#endif
-// Note that <inttypes.h> includes <stdint.h>, if this is a C99 system.
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -55,17 +64,11 @@
#include <stdint.h>
#endif
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-
#ifdef _AIX
#include "llvm/Support/AIXDataTypesFix.h"
#endif
-// Handle incorrect definition of uint64_t as u_int64_t
+/* Handle incorrect definition of uint64_t as u_int64_t */
#ifndef HAVE_UINT64_T
#ifdef HAVE_U_INT64_T
typedef u_int64_t uint64_t;
@@ -87,8 +90,8 @@ typedef u_int64_t uint64_t;
#endif
#else /* _MSC_VER */
-// Visual C++ doesn't provide standard integer headers, but it does provide
-// built-in data types.
+/* Visual C++ doesn't provide standard integer headers, but it does provide
+ built-in data types. */
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index 52d0d3f..6f82ea7 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -18,61 +18,65 @@
// can specify '-debug-only=foo' to enable JUST the debug information for the
// foo class.
//
-// When compiling in release mode, the -debug-* options and all code in DEBUG()
-// statements disappears, so it does not effect the runtime of the code.
+// When compiling without assertions, the -debug-* options and all code in
+// DEBUG() statements disappears, so it does not effect the runtime of the code.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_DEBUG_H
#define LLVM_SUPPORT_DEBUG_H
-#include "llvm/Support/Streams.h"
-
namespace llvm {
// DebugFlag - This boolean is set to true if the '-debug' command line option
// is specified. This should probably not be referenced directly, instead, use
// the DEBUG macro below.
//
+#ifndef NDEBUG
extern bool DebugFlag;
+#endif
// isCurrentDebugType - Return true if the specified string is the debug type
// specified on the command line, or if none was specified on the command line
// with the -debug-only=X option.
//
+#ifndef NDEBUG
bool isCurrentDebugType(const char *Type);
+#else
+#define isCurrentDebugType(X) (false)
+#endif
+
+// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
+// information. In the '-debug' option is specified on the commandline, and if
+// this is a debug build, then the code specified as the option to the macro
+// will be executed. Otherwise it will not be. Example:
+//
+// DEBUG_WITH_TYPE("bitset", errs() << "Bitset contains: " << Bitset << "\n");
+//
+// This will emit the debug information if -debug is present, and -debug-only is
+// not specified, or is specified as "bitset".
+
+#ifdef NDEBUG
+#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
+#else
+#define DEBUG_WITH_TYPE(TYPE, X) \
+ do { if (DebugFlag && isCurrentDebugType(TYPE)) { X; } } while (0)
+#endif
// DEBUG macro - This macro should be used by passes to emit debug information.
// In the '-debug' option is specified on the commandline, and if this is a
// debug build, then the code specified as the option to the macro will be
// executed. Otherwise it will not be. Example:
//
-// DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
+// DEBUG(errs() << "Bitset contains: " << Bitset << "\n");
//
#ifndef DEBUG_TYPE
#define DEBUG_TYPE ""
#endif
-#ifdef NDEBUG
-#define DEBUG(X)
-#else
-#define DEBUG(X) \
- do { if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { X; } } while (0)
-#endif
-
-/// getErrorOutputStream - Returns the error output stream (std::cerr). This
-/// places the std::c* I/O streams into one .cpp file and relieves the whole
-/// program from having to have hundreds of static c'tor/d'tors for them.
-///
-OStream &getErrorOutputStream(const char *DebugType);
-
-#ifdef NDEBUG
-#define DOUT llvm::OStream(0)
-#else
-#define DOUT llvm::getErrorOutputStream(DEBUG_TYPE)
-#endif
-
+#define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X)
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index 5c089ef..55c3c4f 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -19,20 +19,25 @@
#include <vector>
namespace llvm {
- class GlobalVariable;
+ class MDNode;
/// DebugLocTuple - Debug location tuple of filename id, line and column.
///
struct DebugLocTuple {
- GlobalVariable *CompileUnit;
+ MDNode *Scope;
+ MDNode *InlinedAtLoc;
unsigned Line, Col;
- DebugLocTuple(GlobalVariable *v, unsigned l, unsigned c)
- : CompileUnit(v), Line(l), Col(c) {};
+ DebugLocTuple()
+ : Scope(0), InlinedAtLoc(0), Line(~0U), Col(~0U) {};
+
+ DebugLocTuple(MDNode *n, MDNode *i, unsigned l, unsigned c)
+ : Scope(n), InlinedAtLoc(i), Line(l), Col(c) {};
bool operator==(const DebugLocTuple &DLT) const {
- return CompileUnit == DLT.CompileUnit &&
- Line == DLT.Line && Col == DLT.Col;
+ return Scope == DLT.Scope &&
+ InlinedAtLoc == DLT.InlinedAtLoc &&
+ Line == DLT.Line && Col == DLT.Col;
}
bool operator!=(const DebugLocTuple &DLT) const {
return !(*this == DLT);
@@ -60,23 +65,25 @@ namespace llvm {
bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
};
- // Partially specialize DenseMapInfo for DebugLocTyple.
+ // Specialize DenseMapInfo for DebugLocTuple.
template<> struct DenseMapInfo<DebugLocTuple> {
static inline DebugLocTuple getEmptyKey() {
- return DebugLocTuple(0, ~0U, ~0U);
+ return DebugLocTuple(0, 0, ~0U, ~0U);
}
static inline DebugLocTuple getTombstoneKey() {
- return DebugLocTuple((GlobalVariable*)~1U, ~1U, ~1U);
+ return DebugLocTuple((MDNode*)~1U, (MDNode*)~1U, ~1U, ~1U);
}
static unsigned getHashValue(const DebugLocTuple &Val) {
- return DenseMapInfo<GlobalVariable*>::getHashValue(Val.CompileUnit) ^
+ return DenseMapInfo<MDNode*>::getHashValue(Val.Scope) ^
+ DenseMapInfo<MDNode*>::getHashValue(Val.InlinedAtLoc) ^
DenseMapInfo<unsigned>::getHashValue(Val.Line) ^
DenseMapInfo<unsigned>::getHashValue(Val.Col);
}
static bool isEqual(const DebugLocTuple &LHS, const DebugLocTuple &RHS) {
- return LHS.CompileUnit == RHS.CompileUnit &&
- LHS.Line == RHS.Line &&
- LHS.Col == RHS.Col;
+ return LHS.Scope == RHS.Scope &&
+ LHS.InlinedAtLoc == RHS.InlinedAtLoc &&
+ LHS.Line == RHS.Line &&
+ LHS.Col == RHS.Col;
}
static bool isPod() { return true; }
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 55838b8..bfccc52 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -449,6 +449,7 @@ enum dwarf_constants {
// Call frame instruction encodings
DW_CFA_extended = 0x00,
+ DW_CFA_nop = 0x00,
DW_CFA_advance_loc = 0x40,
DW_CFA_offset = 0x80,
DW_CFA_restore = 0xc0,
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
new file mode 100644
index 0000000..67bccf0
--- /dev/null
+++ b/include/llvm/Support/ErrorHandling.h
@@ -0,0 +1,87 @@
+//===- llvm/Support/ErrorHandling.h - Callbacks for errors ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an API used to indicate error conditions.
+// Callbacks can be registered for these errors through this API.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERRORHANDLING_H
+#define LLVM_SUPPORT_ERRORHANDLING_H
+
+#include "llvm/Support/Compiler.h"
+#include <string>
+
+namespace llvm {
+ class Twine;
+
+ /// An error handler callback.
+ typedef void (*llvm_error_handler_t)(void *user_data,
+ const std::string& reason);
+
+ /// llvm_instal_error_handler - Installs a new error handler to be used
+ /// whenever a serious (non-recoverable) error is encountered by LLVM.
+ ///
+ /// If you are using llvm_start_multithreaded, you should register the handler
+ /// before doing that.
+ ///
+ /// If no error handler is installed the default is to print the error message
+ /// to stderr, and call exit(1). If an error handler is installed then it is
+ /// the handler's responsibility to log the message, it will no longer be
+ /// printed to stderr. If the error handler returns, then exit(1) will be
+ /// called.
+ ///
+ /// It is dangerous to naively use an error handler which throws an exception.
+ /// Even though some applications desire to gracefully recover from arbitrary
+ /// faults, blindly throwing exceptions through unfamiliar code isn't a way to
+ /// achieve this.
+ ///
+ /// \param user_data - An argument which will be passed to the install error
+ /// handler.
+ void llvm_install_error_handler(llvm_error_handler_t handler,
+ void *user_data = 0);
+
+ /// Restores default error handling behaviour.
+ /// This must not be called between llvm_start_multithreaded() and
+ /// llvm_stop_multithreaded().
+ void llvm_remove_error_handler();
+
+ /// Reports a serious error, calling any installed error handler. These
+ /// functions are intended to be used for error conditions which are outside
+ /// the control of the compiler (I/O errors, invalid user input, etc.)
+ ///
+ /// If no error handler is installed the default is to print the message to
+ /// standard error, followed by a newline.
+ /// After the error handler is called this function will call exit(1), it
+ /// does not return.
+ void llvm_report_error(const char *reason) NORETURN;
+ void llvm_report_error(const std::string &reason) NORETURN;
+ void llvm_report_error(const Twine &reason) NORETURN;
+
+ /// This function calls abort(), and prints the optional message to stderr.
+ /// Use the llvm_unreachable macro (that adds location info), instead of
+ /// calling this function directly.
+ void llvm_unreachable_internal(const char *msg=0, const char *file=0,
+ unsigned line=0) NORETURN;
+}
+
+/// Prints the message and location info to stderr in !NDEBUG builds.
+/// This is intended to be used for "impossible" situations that imply
+/// a bug in the compiler.
+///
+/// In NDEBUG mode it only prints "UNREACHABLE executed".
+/// Use this instead of assert(0), so that the compiler knows this path
+/// is not reachable even for NDEBUG builds.
+#ifndef NDEBUG
+#define llvm_unreachable(msg) llvm_unreachable_internal(msg, __FILE__, __LINE__)
+#else
+#define llvm_unreachable(msg) llvm_unreachable_internal()
+#endif
+
+#endif
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index 2ab097f..df03f66 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -36,6 +36,10 @@ class format_object_base {
protected:
const char *Fmt;
virtual void home(); // Out of line virtual method.
+
+ /// snprint - Call snprintf() for this object, on the given buffer and size.
+ virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
+
public:
format_object_base(const char *fmt) : Fmt(fmt) {}
virtual ~format_object_base() {}
@@ -43,7 +47,23 @@ public:
/// print - Format the object into the specified buffer. On success, this
/// returns the length of the formatted string. If the buffer is too small,
/// this returns a length to retry with, which will be larger than BufferSize.
- virtual unsigned print(char *Buffer, unsigned BufferSize) const = 0;
+ unsigned print(char *Buffer, unsigned BufferSize) const {
+ assert(BufferSize && "Invalid buffer size!");
+
+ // Print the string, leaving room for the terminating null.
+ int N = snprint(Buffer, BufferSize);
+
+ // VC++ and old GlibC return negative on overflow, just double the size.
+ if (N < 0)
+ return BufferSize*2;
+
+ // Other impls yield number of bytes needed, not including the final '\0'.
+ if (unsigned(N) >= BufferSize)
+ return N+1;
+
+ // Otherwise N is the length of output (not including the final '\0').
+ return N;
+ }
};
/// format_object1 - This is a templated helper class used by the format
@@ -58,17 +78,8 @@ public:
: format_object_base(fmt), Val(val) {
}
- /// print - Format the object into the specified buffer. On success, this
- /// returns the length of the formatted string. If the buffer is too small,
- /// this returns a length to retry with, which will be larger than BufferSize.
- virtual unsigned print(char *Buffer, unsigned BufferSize) const {
- int N = snprintf(Buffer, BufferSize-1, Fmt, Val);
- if (N < 0) // VC++ and old GlibC return negative on overflow.
- return BufferSize*2;
- if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed.
- return N+1;
- // If N is positive and <= BufferSize-1, then the string fit, yay.
- return N;
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val);
}
};
@@ -85,17 +96,8 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2) {
}
- /// print - Format the object into the specified buffer. On success, this
- /// returns the length of the formatted string. If the buffer is too small,
- /// this returns a length to retry with, which will be larger than BufferSize.
- virtual unsigned print(char *Buffer, unsigned BufferSize) const {
- int N = snprintf(Buffer, BufferSize-1, Fmt, Val1, Val2);
- if (N < 0) // VC++ and old GlibC return negative on overflow.
- return BufferSize*2;
- if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed.
- return N+1;
- // If N is positive and <= BufferSize-1, then the string fit, yay.
- return N;
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2);
}
};
@@ -113,17 +115,8 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
}
- /// print - Format the object into the specified buffer. On success, this
- /// returns the length of the formatted string. If the buffer is too small,
- /// this returns a length to retry with, which will be larger than BufferSize.
- virtual unsigned print(char *Buffer, unsigned BufferSize) const {
- int N = snprintf(Buffer, BufferSize-1, Fmt, Val1, Val2, Val3);
- if (N < 0) // VC++ and old GlibC return negative on overflow.
- return BufferSize*2;
- if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed.
- return N+1;
- // If N is positive and <= BufferSize-1, then the string fit, yay.
- return N;
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3);
}
};
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
new file mode 100644
index 0000000..24a3546
--- /dev/null
+++ b/include/llvm/Support/FormattedStream.h
@@ -0,0 +1,150 @@
+//===-- llvm/CodeGen/FormattedStream.h - Formatted streams ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains raw_ostream implementations for streams to do
+// things like pretty-print comments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
+#define LLVM_SUPPORT_FORMATTEDSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm
+{
+ /// formatted_raw_ostream - Formatted raw_fd_ostream to handle
+ /// asm-specific constructs.
+ ///
+ class formatted_raw_ostream : public raw_ostream {
+ public:
+ /// DELETE_STREAM - Tell the destructor to delete the held stream.
+ ///
+ static const bool DELETE_STREAM = true;
+
+ /// PRESERVE_STREAM - Tell the destructor to not delete the held
+ /// stream.
+ ///
+ static const bool PRESERVE_STREAM = false;
+
+ private:
+ /// TheStream - The real stream we output to. We set it to be
+ /// unbuffered, since we're already doing our own buffering.
+ ///
+ raw_ostream *TheStream;
+
+ /// DeleteStream - Do we need to delete TheStream in the
+ /// destructor?
+ ///
+ bool DeleteStream;
+
+ /// ColumnScanned - The current output column of the data that's
+ /// been flushed and the portion of the buffer that's been
+ /// scanned. The column scheme is zero-based.
+ ///
+ unsigned ColumnScanned;
+
+ /// Scanned - This points to one past the last character in the
+ /// buffer we've scanned.
+ ///
+ const char *Scanned;
+
+ virtual void write_impl(const char *Ptr, size_t Size);
+
+ /// current_pos - Return the current position within the stream,
+ /// not counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() {
+ // This has the same effect as calling TheStream.current_pos(),
+ // but that interface is private.
+ return TheStream->tell() - TheStream->GetNumBytesInBuffer();
+ }
+
+ /// ComputeColumn - Examine the given output buffer and figure out which
+ /// column we end up in after output.
+ ///
+ void ComputeColumn(const char *Ptr, size_t size);
+
+ public:
+ /// formatted_raw_ostream - Open the specified file for
+ /// writing. If an error occurs, information about the error is
+ /// put into ErrorInfo, and the stream should be immediately
+ /// destroyed; the string will be empty if no error occurred.
+ ///
+ /// As a side effect, the given Stream is set to be Unbuffered.
+ /// This is because formatted_raw_ostream does its own buffering,
+ /// so it doesn't want another layer of buffering to be happening
+ /// underneath it.
+ ///
+ formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
+ : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
+ setStream(Stream, Delete);
+ }
+ explicit formatted_raw_ostream()
+ : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
+ Scanned = 0;
+ }
+
+ ~formatted_raw_ostream() {
+ flush();
+ releaseStream();
+ }
+
+ void setStream(raw_ostream &Stream, bool Delete = false) {
+ releaseStream();
+
+ TheStream = &Stream;
+ DeleteStream = Delete;
+
+ // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
+ // own buffering, and it doesn't need or want TheStream to do another
+ // layer of buffering underneath. Resize the buffer to what TheStream
+ // had been using, and tell TheStream not to do its own buffering.
+ if (size_t BufferSize = TheStream->GetBufferSize())
+ SetBufferSize(BufferSize);
+ else
+ SetUnbuffered();
+ TheStream->SetUnbuffered();
+
+ Scanned = 0;
+ }
+
+ /// PadToColumn - Align the output to some column number. If the current
+ /// column is already equal to or more than NewCol, PadToColumn inserts one
+ /// space.
+ ///
+ /// \param NewCol - The column to move to.
+ void PadToColumn(unsigned NewCol);
+
+ private:
+ void releaseStream() {
+ // Delete the stream if needed. Otherwise, transfer the buffer
+ // settings from this raw_ostream back to the underlying stream.
+ if (!TheStream)
+ return;
+ if (DeleteStream)
+ delete TheStream;
+ else if (size_t BufferSize = GetBufferSize())
+ TheStream->SetBufferSize(BufferSize);
+ else
+ TheStream->SetUnbuffered();
+ }
+ };
+
+/// fouts() - This returns a reference to a formatted_raw_ostream for
+/// standard output. Use it like: fouts() << "foo" << "bar";
+formatted_raw_ostream &fouts();
+
+/// ferrs() - This returns a reference to a formatted_raw_ostream for
+/// standard error. Use it like: ferrs() << "foo" << "bar";
+formatted_raw_ostream &ferrs();
+
+} // end llvm namespace
+
+
+#endif
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
index e1cda75..f5915c9 100644
--- a/include/llvm/Support/GetElementPtrTypeIterator.h
+++ b/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -21,8 +21,9 @@
namespace llvm {
template<typename ItTy = User::const_op_iterator>
class generic_gep_type_iterator
- : public forward_iterator<const Type *, ptrdiff_t> {
- typedef forward_iterator<const Type*, ptrdiff_t> super;
+ : public std::iterator<std::forward_iterator_tag, const Type *, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag,
+ const Type *, ptrdiff_t> super;
ItTy OpIt;
const Type *CurTy;
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 01b44d0..bd3fcea 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -24,53 +24,33 @@
#define LLVM_SUPPORT_GRAPHWRITER_H
#include "llvm/Support/DOTGraphTraits.h"
-#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/System/Path.h"
-#include <fstream>
#include <vector>
+#include <cassert>
namespace llvm {
namespace DOT { // Private functions...
- inline std::string EscapeString(const std::string &Label) {
- std::string Str(Label);
- for (unsigned i = 0; i != Str.length(); ++i)
- switch (Str[i]) {
- case '\n':
- Str.insert(Str.begin()+i, '\\'); // Escape character...
- ++i;
- Str[i] = 'n';
- break;
- case '\t':
- Str.insert(Str.begin()+i, ' '); // Convert to two spaces
- ++i;
- Str[i] = ' ';
- break;
- case '\\':
- if (i+1 != Str.length())
- switch (Str[i+1]) {
- case 'l': continue; // don't disturb \l
- case '|': case '{': case '}':
- Str.erase(Str.begin()+i); continue;
- default: break;
- }
- case '{': case '}':
- case '<': case '>':
- case '|': case '"':
- Str.insert(Str.begin()+i, '\\'); // Escape character...
- ++i; // don't infinite loop
- break;
- }
- return Str;
- }
+ std::string EscapeString(const std::string &Label);
+}
+
+namespace GraphProgram {
+ enum Name {
+ DOT,
+ FDP,
+ NEATO,
+ TWOPI,
+ CIRCO
+ };
}
-void DisplayGraph(const sys::Path& Filename);
+void DisplayGraph(const sys::Path& Filename, bool wait=true, GraphProgram::Name program = GraphProgram::DOT);
template<typename GraphType>
class GraphWriter {
- std::ostream &O;
+ raw_ostream &O;
const GraphType &G;
bool ShortNames;
@@ -80,7 +60,7 @@ class GraphWriter {
typedef typename GTraits::nodes_iterator node_iterator;
typedef typename GTraits::ChildIteratorType child_iterator;
public:
- GraphWriter(std::ostream &o, const GraphType &g, bool SN) :
+ GraphWriter(raw_ostream &o, const GraphType &g, bool SN) :
O(o), G(g), ShortNames(SN) {}
void writeHeader(const std::string &Name) {
@@ -222,7 +202,7 @@ public:
for (unsigned i = 0; i != NumEdgeSources; ++i) {
if (i) O << "|";
- O << "<g" << i << ">";
+ O << "<s" << i << ">";
if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i];
}
O << "}}";
@@ -241,8 +221,12 @@ public:
if (SrcNodePort >= 0)
O << ":s" << SrcNodePort;
O << " -> Node" << DestNodeID;
- if (DestNodePort >= 0)
- O << ":d" << DestNodePort;
+ if (DestNodePort >= 0) {
+ if (DOTTraits::hasEdgeDestLabels())
+ O << ":d" << DestNodePort;
+ else
+ O << ":s" << DestNodePort;
+ }
if (!Attrs.empty())
O << "[" << Attrs << "]";
@@ -251,10 +235,10 @@ public:
};
template<typename GraphType>
-std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
- bool ShortNames = false,
- const std::string &Name = "",
- const std::string &Title = "") {
+raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
+ bool ShortNames = false,
+ const std::string &Name = "",
+ const std::string &Title = "") {
// Start the graph emission process...
GraphWriter<GraphType> W(O, G, ShortNames);
@@ -273,33 +257,30 @@ std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
}
template<typename GraphType>
-sys::Path WriteGraph(const GraphType &G,
- const std::string& Name,
- bool ShortNames = false,
- const std::string& Title = "") {
+sys::Path WriteGraph(const GraphType &G, const std::string &Name,
+ bool ShortNames = false, const std::string &Title = "") {
std::string ErrMsg;
sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
if (Filename.isEmpty()) {
- cerr << "Error: " << ErrMsg << "\n";
+ errs() << "Error: " << ErrMsg << "\n";
return Filename;
}
Filename.appendComponent(Name + ".dot");
if (Filename.makeUnique(true,&ErrMsg)) {
- cerr << "Error: " << ErrMsg << "\n";
+ errs() << "Error: " << ErrMsg << "\n";
return sys::Path();
}
- cerr << "Writing '" << Filename << "'... ";
+ errs() << "Writing '" << Filename.str() << "'... ";
- std::ofstream O(Filename.c_str());
+ std::string ErrorInfo;
+ raw_fd_ostream O(Filename.c_str(), ErrorInfo);
- if (O.good()) {
+ if (ErrorInfo.empty()) {
WriteGraph(O, G, ShortNames, Name, Title);
- cerr << " done. \n";
-
- O.close();
+ errs() << " done. \n";
} else {
- cerr << "error opening file for writing!\n";
+ errs() << "error opening file '" << Filename.str() << "' for writing!\n";
Filename.clear();
}
@@ -310,17 +291,15 @@ sys::Path WriteGraph(const GraphType &G,
/// then cleanup. For use from the debugger.
///
template<typename GraphType>
-void ViewGraph(const GraphType& G,
- const std::string& Name,
- bool ShortNames = false,
- const std::string& Title = "") {
- sys::Path Filename = WriteGraph(G, Name, ShortNames, Title);
+void ViewGraph(const GraphType &G, const std::string &Name,
+ bool ShortNames = false, const std::string &Title = "",
+ GraphProgram::Name Program = GraphProgram::DOT) {
+ sys::Path Filename = WriteGraph(G, Name, ShortNames, Title);
- if (Filename.isEmpty()) {
+ if (Filename.isEmpty())
return;
- }
- DisplayGraph(Filename);
+ DisplayGraph(Filename, true, Program);
}
} // End llvm namespace
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index ed6a3f1..1f65978 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -20,37 +20,86 @@
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
+#include "llvm/Metadata.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/ConstantFolder.h"
namespace llvm {
+/// IRBuilderDefaultInserter - This provides the default implementation of the
+/// IRBuilder 'InsertHelper' method that is called whenever an instruction is
+/// created by IRBuilder and needs to be inserted. By default, this inserts the
+/// instruction at the insertion point.
+template <bool preserveNames = true>
+class IRBuilderDefaultInserter {
+protected:
+ void InsertHelper(Instruction *I, const Twine &Name,
+ BasicBlock *BB, BasicBlock::iterator InsertPt) const {
+ if (BB) BB->getInstList().insert(InsertPt, I);
+ if (preserveNames)
+ I->setName(Name);
+ }
+};
+
+
/// IRBuilder - This provides a uniform API for creating instructions and
/// inserting them into a basic block: either at the end of a BasicBlock, or
/// at a specific iterator location in a block.
///
/// Note that the builder does not expose the full generality of LLVM
-/// instructions. For example, it cannot be used to create instructions with
-/// arbitrary names (specifically, names with nul characters in them) - It only
-/// supports nul-terminated C strings. For fully generic names, use
-/// I->setName(). For access to extra instruction properties, use the mutators
+/// instructions. For access to extra instruction properties, use the mutators
/// (e.g. setVolatile) on the instructions after they have been created.
/// The first template argument handles whether or not to preserve names in the
/// final instruction output. This defaults to on. The second template argument
/// specifies a class to use for creating constants. This defaults to creating
-/// minimally folded constants.
-template <bool preserveNames=true, typename T = ConstantFolder> class IRBuilder{
+/// minimally folded constants. The fourth template argument allows clients to
+/// specify custom insertion hooks that are called on every newly created
+/// insertion.
+template<bool preserveNames = true, typename T = ConstantFolder,
+ typename Inserter = IRBuilderDefaultInserter<preserveNames> >
+class IRBuilder : public Inserter {
BasicBlock *BB;
BasicBlock::iterator InsertPt;
+ unsigned MDKind;
+ MDNode *CurDbgLocation;
+ LLVMContext &Context;
T Folder;
public:
- IRBuilder(const T& F = T()) : Folder(F) { ClearInsertionPoint(); }
- explicit IRBuilder(BasicBlock *TheBB, const T& F = T())
- : Folder(F) { SetInsertPoint(TheBB); }
- IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F = T())
- : Folder(F) { SetInsertPoint(TheBB, IP); }
+ IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter())
+ : Inserter(I), MDKind(0), CurDbgLocation(0), Context(C), Folder(F) {
+ ClearInsertionPoint();
+ }
+
+ explicit IRBuilder(LLVMContext &C)
+ : MDKind(0), CurDbgLocation(0), Context(C), Folder(C) {
+ ClearInsertionPoint();
+ }
+
+ explicit IRBuilder(BasicBlock *TheBB, const T &F)
+ : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), Folder(F) {
+ SetInsertPoint(TheBB);
+ }
+
+ explicit IRBuilder(BasicBlock *TheBB)
+ : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()),
+ Folder(Context) {
+ SetInsertPoint(TheBB);
+ }
+
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F)
+ : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()), Folder(F) {
+ SetInsertPoint(TheBB, IP);
+ }
+
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP)
+ : MDKind(0), CurDbgLocation(0), Context(TheBB->getContext()),
+ Folder(Context) {
+ SetInsertPoint(TheBB, IP);
+ }
/// getFolder - Get the constant folder being used.
- const T& getFolder() { return Folder; }
+ const T &getFolder() { return Folder; }
/// isNamePreserving - Return true if this builder is configured to actually
/// add the requested names to IR created through it.
@@ -84,20 +133,75 @@ public:
InsertPt = IP;
}
+ /// SetCurrentDebugLocation - Set location information used by debugging
+ /// information.
+ void SetCurrentDebugLocation(MDNode *L) {
+ if (MDKind == 0)
+ MDKind = Context.getMetadata().getMDKind("dbg");
+ if (MDKind == 0)
+ MDKind = Context.getMetadata().RegisterMDKind("dbg");
+ CurDbgLocation = L;
+ }
+
+ MDNode *getCurrentDebugLocation() const { return CurDbgLocation; }
+
+ /// SetDebugLocation - Set location information for the given instruction.
+ void SetDebugLocation(Instruction *I) {
+ if (CurDbgLocation)
+ Context.getMetadata().addMD(MDKind, CurDbgLocation, I);
+ }
+
/// Insert - Insert and return the specified instruction.
template<typename InstTy>
- InstTy *Insert(InstTy *I, const char *Name = "") const {
- InsertHelper(I, Name);
+ InstTy *Insert(InstTy *I, const Twine &Name = "") const {
+ this->InsertHelper(I, Name, BB, InsertPt);
+ if (CurDbgLocation)
+ Context.getMetadata().addMD(MDKind, CurDbgLocation, I);
return I;
}
- /// InsertHelper - Insert the specified instruction at the specified insertion
- /// point. This is split out of Insert so that it isn't duplicated for every
- /// template instantiation.
- void InsertHelper(Instruction *I, const char *Name) const {
- if (BB) BB->getInstList().insert(InsertPt, I);
- if (preserveNames && Name[0])
- I->setName(Name);
+ //===--------------------------------------------------------------------===//
+ // Type creation methods
+ //===--------------------------------------------------------------------===//
+
+ /// getInt1Ty - Fetch the type representing a single bit
+ const Type *getInt1Ty() {
+ return Type::getInt1Ty(Context);
+ }
+
+ /// getInt8Ty - Fetch the type representing an 8-bit integer.
+ const Type *getInt8Ty() {
+ return Type::getInt8Ty(Context);
+ }
+
+ /// getInt16Ty - Fetch the type representing a 16-bit integer.
+ const Type *getInt16Ty() {
+ return Type::getInt16Ty(Context);
+ }
+
+ /// getInt32Ty - Fetch the type resepresenting a 32-bit integer.
+ const Type *getInt32Ty() {
+ return Type::getInt32Ty(Context);
+ }
+
+ /// getInt64Ty - Fetch the type representing a 64-bit integer.
+ const Type *getInt64Ty() {
+ return Type::getInt64Ty(Context);
+ }
+
+ /// getFloatTy - Fetch the type representing a 32-bit floating point value.
+ const Type *getFloatTy() {
+ return Type::getFloatTy(Context);
+ }
+
+ /// getDoubleTy - Fetch the type representing a 64-bit floating point value.
+ const Type *getDoubleTy() {
+ return Type::getDoubleTy(Context);
+ }
+
+ /// getVoidTy - Fetch the type representing void.
+ const Type *getVoidTy() {
+ return Type::getVoidTy(Context);
}
//===--------------------------------------------------------------------===//
@@ -106,14 +210,14 @@ public:
/// CreateRetVoid - Create a 'ret void' instruction.
ReturnInst *CreateRetVoid() {
- return Insert(ReturnInst::Create());
+ return Insert(ReturnInst::Create(Context));
}
/// @verbatim
/// CreateRet - Create a 'ret <val>' instruction.
/// @endverbatim
ReturnInst *CreateRet(Value *V) {
- return Insert(ReturnInst::Create(V));
+ return Insert(ReturnInst::Create(Context, V));
}
/// CreateAggregateRet - Create a sequence of N insertvalue instructions,
@@ -128,7 +232,7 @@ public:
Value *V = UndefValue::get(RetType);
for (unsigned i = 0; i != N; ++i)
V = CreateInsertValue(V, retVals[i], i, "mrv");
- return Insert(ReturnInst::Create(V));
+ return Insert(ReturnInst::Create(Context, V));
}
/// CreateBr - Create an unconditional 'br label X' instruction.
@@ -153,126 +257,144 @@ public:
template<typename InputIterator>
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, InputIterator ArgBegin,
- InputIterator ArgEnd, const char *Name = "") {
+ InputIterator ArgEnd, const Twine &Name = "") {
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
ArgBegin, ArgEnd), Name);
}
UnwindInst *CreateUnwind() {
- return Insert(new UnwindInst());
+ return Insert(new UnwindInst(Context));
}
UnreachableInst *CreateUnreachable() {
- return Insert(new UnreachableInst());
+ return Insert(new UnreachableInst(Context));
}
//===--------------------------------------------------------------------===//
// Instruction creation methods: Binary Operators
//===--------------------------------------------------------------------===//
- Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateAdd(LC, RC);
return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name);
}
- Value *CreateFAdd(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateNSWAdd(LC, RC);
+ return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name);
+ }
+ Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFAdd(LC, RC);
return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name);
}
- Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateSub(LC, RC);
return Insert(BinaryOperator::CreateSub(LHS, RHS), Name);
}
- Value *CreateFSub(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateNSWSub(LC, RC);
+ return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name);
+ }
+ Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFSub(LC, RC);
return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name);
}
- Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateMul(LC, RC);
return Insert(BinaryOperator::CreateMul(LHS, RHS), Name);
}
- Value *CreateFMul(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFMul(LC, RC);
return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name);
}
- Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateUDiv(LC, RC);
return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
}
- Value *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateSDiv(LC, RC);
return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
}
- Value *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateExactSDiv(LC, RC);
+ return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
+ }
+ Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFDiv(LC, RC);
return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name);
}
- Value *CreateURem(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateURem(LC, RC);
return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
}
- Value *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateSRem(LC, RC);
return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
}
- Value *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFRem(LC, RC);
return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name);
}
- Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateShl(LC, RC);
return Insert(BinaryOperator::CreateShl(LHS, RHS), Name);
}
- Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateLShr(LC, RC);
return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
}
- Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateAShr(LC, RC);
return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
}
- Value *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateAnd(LC, RC);
return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
}
- Value *CreateOr(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateOr(LC, RC);
return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
}
- Value *CreateXor(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateXor(LC, RC);
@@ -280,24 +402,24 @@ public:
}
Value *CreateBinOp(Instruction::BinaryOps Opc,
- Value *LHS, Value *RHS, const char *Name = "") {
+ Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateBinOp(Opc, LC, RC);
return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
}
- Value *CreateNeg(Value *V, const char *Name = "") {
+ Value *CreateNeg(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateNeg(VC);
return Insert(BinaryOperator::CreateNeg(V), Name);
}
- Value *CreateFNeg(Value *V, const char *Name = "") {
+ Value *CreateFNeg(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateFNeg(VC);
return Insert(BinaryOperator::CreateFNeg(V), Name);
}
- Value *CreateNot(Value *V, const char *Name = "") {
+ Value *CreateNot(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateNot(VC);
return Insert(BinaryOperator::CreateNot(V), Name);
@@ -308,20 +430,25 @@ public:
//===--------------------------------------------------------------------===//
MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0,
- const char *Name = "") {
+ const Twine &Name = "") {
return Insert(new MallocInst(Ty, ArraySize), Name);
}
AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0,
- const char *Name = "") {
+ const Twine &Name = "") {
return Insert(new AllocaInst(Ty, ArraySize), Name);
}
FreeInst *CreateFree(Value *Ptr) {
return Insert(new FreeInst(Ptr));
}
- LoadInst *CreateLoad(Value *Ptr, const char *Name = "") {
+ // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
+ // converting the string to 'bool' for the isVolatile parameter.
+ LoadInst *CreateLoad(Value *Ptr, const char *Name) {
+ return Insert(new LoadInst(Ptr), Name);
+ }
+ LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") {
return Insert(new LoadInst(Ptr), Name);
}
- LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = "") {
+ LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") {
return Insert(new LoadInst(Ptr, 0, isVolatile), Name);
}
StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
@@ -329,38 +456,69 @@ public:
}
template<typename InputIterator>
Value *CreateGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr)) {
// Every index must be constant.
InputIterator i;
- for (i = IdxBegin; i < IdxEnd; ++i) {
- if (!dyn_cast<Constant>(*i))
+ for (i = IdxBegin; i < IdxEnd; ++i)
+ if (!isa<Constant>(*i))
break;
- }
if (i == IdxEnd)
return Folder.CreateGetElementPtr(PC, &IdxBegin[0], IdxEnd - IdxBegin);
}
return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name);
}
- Value *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
+ template<typename InputIterator>
+ Value *CreateInBoundsGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+ const Twine &Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+ // Every index must be constant.
+ InputIterator i;
+ for (i = IdxBegin; i < IdxEnd; ++i)
+ if (!isa<Constant>(*i))
+ break;
+ if (i == IdxEnd)
+ return Folder.CreateInBoundsGetElementPtr(PC,
+ &IdxBegin[0],
+ IdxEnd - IdxBegin);
+ }
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxBegin, IdxEnd),
+ Name);
+ }
+ Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
return Folder.CreateGetElementPtr(PC, &IC, 1);
return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
}
- Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const char *Name = "") {
- Value *Idx = ConstantInt::get(Type::Int32Ty, Idx0);
+ Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Folder.CreateInBoundsGetElementPtr(PC, &IC, 1);
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ }
+ Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Folder.CreateGetElementPtr(PC, &Idx, 1);
return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
}
+ Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
+ const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
+ }
Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
- const char *Name = "") {
+ const Twine &Name = "") {
Value *Idxs[] = {
- ConstantInt::get(Type::Int32Ty, Idx0),
- ConstantInt::get(Type::Int32Ty, Idx1)
+ ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
@@ -368,19 +526,40 @@ public:
return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
}
- Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const char *Name = "") {
- Value *Idx = ConstantInt::get(Type::Int64Ty, Idx0);
+ Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+ const Twine &Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt32Ty(Context), Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
+ }
+ Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Folder.CreateGetElementPtr(PC, &Idx, 1);
return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
}
- Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
- const char *Name = "") {
+ Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
+ const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
+ }
+ Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+ const Twine &Name = "") {
Value *Idxs[] = {
- ConstantInt::get(Type::Int64Ty, Idx0),
- ConstantInt::get(Type::Int64Ty, Idx1)
+ ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt64Ty(Context), Idx1)
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
@@ -388,235 +567,272 @@ public:
return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
}
- Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") {
- return CreateConstGEP2_32(Ptr, 0, Idx, Name);
+ Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+ const Twine &Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt64Ty(Context), Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
+ }
+ Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
+ return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
}
- Value *CreateGlobalString(const char *Str = "", const char *Name = "") {
- Constant *StrConstant = ConstantArray::get(Str, true);
- GlobalVariable *gv = new GlobalVariable(StrConstant->getType(),
+ Value *CreateGlobalString(const char *Str = "", const Twine &Name = "") {
+ Constant *StrConstant = ConstantArray::get(Context, Str, true);
+ Module &M = *BB->getParent()->getParent();
+ GlobalVariable *gv = new GlobalVariable(M,
+ StrConstant->getType(),
true,
GlobalValue::InternalLinkage,
StrConstant,
"",
- BB->getParent()->getParent(),
+ 0,
false);
gv->setName(Name);
return gv;
}
- Value *CreateGlobalStringPtr(const char *Str = "", const char *Name = "") {
+ Value *CreateGlobalStringPtr(const char *Str = "", const Twine &Name = "") {
Value *gv = CreateGlobalString(Str, Name);
- Value *zero = ConstantInt::get(Type::Int32Ty, 0);
+ Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
Value *Args[] = { zero, zero };
- return CreateGEP(gv, Args, Args+2, Name);
+ return CreateInBoundsGEP(gv, Args, Args+2, Name);
}
//===--------------------------------------------------------------------===//
// Instruction creation methods: Cast/Conversion Operators
//===--------------------------------------------------------------------===//
- Value *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") {
+ Value *CreateTrunc(Value *V, const Type *DestTy, const Twine &Name = "") {
return CreateCast(Instruction::Trunc, V, DestTy, Name);
}
- Value *CreateZExt(Value *V, const Type *DestTy, const char *Name = "") {
+ Value *CreateZExt(Value *V, const Type *DestTy, const Twine &Name = "") {
return CreateCast(Instruction::ZExt, V, DestTy, Name);
}
- Value *CreateSExt(Value *V, const Type *DestTy, const char *Name = "") {
+ Value *CreateSExt(Value *V, const Type *DestTy, const Twine &Name = "") {
return CreateCast(Instruction::SExt, V, DestTy, Name);
}
- Value *CreateFPToUI(Value *V, const Type *DestTy, const char *Name = ""){
+ Value *CreateFPToUI(Value *V, const Type *DestTy, const Twine &Name = ""){
return CreateCast(Instruction::FPToUI, V, DestTy, Name);
}
- Value *CreateFPToSI(Value *V, const Type *DestTy, const char *Name = ""){
+ Value *CreateFPToSI(Value *V, const Type *DestTy, const Twine &Name = ""){
return CreateCast(Instruction::FPToSI, V, DestTy, Name);
}
- Value *CreateUIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ Value *CreateUIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){
return CreateCast(Instruction::UIToFP, V, DestTy, Name);
}
- Value *CreateSIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ Value *CreateSIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){
return CreateCast(Instruction::SIToFP, V, DestTy, Name);
}
Value *CreateFPTrunc(Value *V, const Type *DestTy,
- const char *Name = "") {
+ const Twine &Name = "") {
return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
}
- Value *CreateFPExt(Value *V, const Type *DestTy, const char *Name = "") {
+ Value *CreateFPExt(Value *V, const Type *DestTy, const Twine &Name = "") {
return CreateCast(Instruction::FPExt, V, DestTy, Name);
}
Value *CreatePtrToInt(Value *V, const Type *DestTy,
- const char *Name = "") {
+ const Twine &Name = "") {
return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
}
Value *CreateIntToPtr(Value *V, const Type *DestTy,
- const char *Name = "") {
+ const Twine &Name = "") {
return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
}
Value *CreateBitCast(Value *V, const Type *DestTy,
- const char *Name = "") {
+ const Twine &Name = "") {
return CreateCast(Instruction::BitCast, V, DestTy, Name);
}
-
+ Value *CreateZExtOrBitCast(Value *V, const Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateZExtOrBitCast(VC, DestTy);
+ return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name);
+ }
+ Value *CreateSExtOrBitCast(Value *V, const Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateSExtOrBitCast(VC, DestTy);
+ return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name);
+ }
+ Value *CreateTruncOrBitCast(Value *V, const Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateTruncOrBitCast(VC, DestTy);
+ return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name);
+ }
Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy,
- const char *Name = "") {
+ const Twine &Name = "") {
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateCast(Op, VC, DestTy);
return Insert(CastInst::Create(Op, V, DestTy), Name);
}
+ Value *CreatePointerCast(Value *V, const Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreatePointerCast(VC, DestTy);
+ return Insert(CastInst::CreatePointerCast(V, DestTy), Name);
+ }
Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
- const char *Name = "") {
+ const Twine &Name = "") {
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateIntCast(VC, DestTy, isSigned);
return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
}
+ Value *CreateFPCast(Value *V, const Type *DestTy, const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateFPCast(VC, DestTy);
+ return Insert(CastInst::CreateFPCast(V, DestTy), Name);
+ }
//===--------------------------------------------------------------------===//
// Instruction creation methods: Compare Instructions
//===--------------------------------------------------------------------===//
- Value *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
}
- Value *CreateICmpNE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name);
}
- Value *CreateICmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name);
}
- Value *CreateICmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name);
}
- Value *CreateICmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name);
}
- Value *CreateICmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name);
}
- Value *CreateICmpSGT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name);
}
- Value *CreateICmpSGE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name);
}
- Value *CreateICmpSLT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name);
}
- Value *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
}
- Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
}
- Value *CreateFCmpOGT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
}
- Value *CreateFCmpOGE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
}
- Value *CreateFCmpOLT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
}
- Value *CreateFCmpOLE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
}
- Value *CreateFCmpONE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
}
- Value *CreateFCmpORD(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
}
- Value *CreateFCmpUNO(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
}
- Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
}
- Value *CreateFCmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
}
- Value *CreateFCmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
}
- Value *CreateFCmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
}
- Value *CreateFCmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
}
- Value *CreateFCmpUNE(Value *LHS, Value *RHS, const char *Name = "") {
+ Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
}
Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateICmp(P, LC, RC);
return Insert(new ICmpInst(P, LHS, RHS), Name);
}
Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFCmp(P, LC, RC);
return Insert(new FCmpInst(P, LHS, RHS), Name);
}
- Value *CreateVICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
- const char *Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateVICmp(P, LC, RC);
- return Insert(new VICmpInst(P, LHS, RHS), Name);
- }
- Value *CreateVFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
- const char *Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateVFCmp(P, LC, RC);
- return Insert(new VFCmpInst(P, LHS, RHS), Name);
- }
-
//===--------------------------------------------------------------------===//
// Instruction creation methods: Other Instructions
//===--------------------------------------------------------------------===//
- PHINode *CreatePHI(const Type *Ty, const char *Name = "") {
+ PHINode *CreatePHI(const Type *Ty, const Twine &Name = "") {
return Insert(PHINode::Create(Ty), Name);
}
- CallInst *CreateCall(Value *Callee, const char *Name = "") {
+ CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
return Insert(CallInst::Create(Callee), Name);
}
- CallInst *CreateCall(Value *Callee, Value *Arg, const char *Name = "") {
+ CallInst *CreateCall(Value *Callee, Value *Arg, const Twine &Name = "") {
return Insert(CallInst::Create(Callee, Arg), Name);
}
CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
- const char *Name = "") {
+ const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2 };
return Insert(CallInst::Create(Callee, Args, Args+2), Name);
}
CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- const char *Name = "") {
+ const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2, Arg3 };
return Insert(CallInst::Create(Callee, Args, Args+3), Name);
}
CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- Value *Arg4, const char *Name = "") {
+ Value *Arg4, const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
return Insert(CallInst::Create(Callee, Args, Args+4), Name);
}
template<typename InputIterator>
CallInst *CreateCall(Value *Callee, InputIterator ArgBegin,
- InputIterator ArgEnd, const char *Name = "") {
+ InputIterator ArgEnd, const Twine &Name = "") {
return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name);
}
Value *CreateSelect(Value *C, Value *True, Value *False,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *CC = dyn_cast<Constant>(C))
if (Constant *TC = dyn_cast<Constant>(True))
if (Constant *FC = dyn_cast<Constant>(False))
@@ -624,20 +840,20 @@ public:
return Insert(SelectInst::Create(C, True, False), Name);
}
- VAArgInst *CreateVAArg(Value *List, const Type *Ty, const char *Name = "") {
+ VAArgInst *CreateVAArg(Value *List, const Type *Ty, const Twine &Name = "") {
return Insert(new VAArgInst(List, Ty), Name);
}
Value *CreateExtractElement(Value *Vec, Value *Idx,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(Vec))
if (Constant *IC = dyn_cast<Constant>(Idx))
return Folder.CreateExtractElement(VC, IC);
- return Insert(new ExtractElementInst(Vec, Idx), Name);
+ return Insert(ExtractElementInst::Create(Vec, Idx), Name);
}
Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(Vec))
if (Constant *NC = dyn_cast<Constant>(NewElt))
if (Constant *IC = dyn_cast<Constant>(Idx))
@@ -646,7 +862,7 @@ public:
}
Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *V1C = dyn_cast<Constant>(V1))
if (Constant *V2C = dyn_cast<Constant>(V2))
if (Constant *MC = dyn_cast<Constant>(Mask))
@@ -655,7 +871,7 @@ public:
}
Value *CreateExtractValue(Value *Agg, unsigned Idx,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
return Folder.CreateExtractValue(AggC, &Idx, 1);
return Insert(ExtractValueInst::Create(Agg, Idx), Name);
@@ -665,14 +881,14 @@ public:
Value *CreateExtractValue(Value *Agg,
InputIterator IdxBegin,
InputIterator IdxEnd,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
return Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd - IdxBegin);
return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name);
}
Value *CreateInsertValue(Value *Agg, Value *Val, unsigned Idx,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
if (Constant *ValC = dyn_cast<Constant>(Val))
return Folder.CreateInsertValue(AggC, ValC, &Idx, 1);
@@ -683,11 +899,10 @@ public:
Value *CreateInsertValue(Value *Agg, Value *Val,
InputIterator IdxBegin,
InputIterator IdxEnd,
- const char *Name = "") {
+ const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
if (Constant *ValC = dyn_cast<Constant>(Val))
- return Folder.CreateInsertValue(AggC, ValC,
- IdxBegin, IdxEnd - IdxBegin);
+ return Folder.CreateInsertValue(AggC, ValC, IdxBegin, IdxEnd-IdxBegin);
return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name);
}
@@ -696,30 +911,32 @@ public:
//===--------------------------------------------------------------------===//
/// CreateIsNull - Return an i1 value testing if \arg Arg is null.
- Value *CreateIsNull(Value *Arg, const char *Name = "") {
+ Value *CreateIsNull(Value *Arg, const Twine &Name = "") {
return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
Name);
}
/// CreateIsNotNull - Return an i1 value testing if \arg Arg is not null.
- Value *CreateIsNotNull(Value *Arg, const char *Name = "") {
+ Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") {
return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
Name);
}
/// CreatePtrDiff - Return the i64 difference between two pointer values,
/// dividing out the size of the pointed-to objects. This is intended to
- /// implement C-style pointer subtraction.
- Value *CreatePtrDiff(Value *LHS, Value *RHS, const char *Name = "") {
+ /// implement C-style pointer subtraction. As such, the pointers must be
+ /// appropriately aligned for their element types and pointing into the
+ /// same object.
+ Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
assert(LHS->getType() == RHS->getType() &&
"Pointer subtraction operand types must match!");
const PointerType *ArgType = cast<PointerType>(LHS->getType());
- Value *LHS_int = CreatePtrToInt(LHS, Type::Int64Ty);
- Value *RHS_int = CreatePtrToInt(RHS, Type::Int64Ty);
+ Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
+ Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
Value *Difference = CreateSub(LHS_int, RHS_int);
- return CreateSDiv(Difference,
- ConstantExpr::getSizeOf(ArgType->getElementType()),
- Name);
+ return CreateExactSDiv(Difference,
+ ConstantExpr::getSizeOf(ArgType->getElementType()),
+ Name);
}
};
diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h
new file mode 100644
index 0000000..e7780b0
--- /dev/null
+++ b/include/llvm/Support/IRReader.h
@@ -0,0 +1,115 @@
+//===---- llvm/Support/IRReader.h - Reader for LLVM IR files ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines functions for reading LLVM IR. They support both
+// Bitcode and Assembly, automatically detecting the input format.
+//
+// These functions must be defined in a header file in order to avoid
+// library dependencies, since they reference both Bitcode and Assembly
+// functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_IRREADER_H
+#define LLVM_SUPPORT_IRREADER_H
+
+#include "llvm/Assembly/Parser.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/ModuleProvider.h"
+
+namespace llvm {
+
+ /// If the given MemoryBuffer holds a bitcode image, return a ModuleProvider
+ /// for it which does lazy deserialization of function bodies. Otherwise,
+ /// attempt to parse it as LLVM Assembly and return a fully populated
+ /// ModuleProvider. This function *always* takes ownership of the given
+ /// MemoryBuffer.
+ inline ModuleProvider *getIRModuleProvider(MemoryBuffer *Buffer,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
+ (const unsigned char *)Buffer->getBufferEnd())) {
+ std::string ErrMsg;
+ ModuleProvider *MP = getBitcodeModuleProvider(Buffer, Context, &ErrMsg);
+ if (MP == 0) {
+ Err = SMDiagnostic(Buffer->getBufferIdentifier(), -1, -1, ErrMsg, "");
+ // ParseBitcodeFile does not take ownership of the Buffer in the
+ // case of an error.
+ delete Buffer;
+ }
+ return MP;
+ }
+
+ Module *M = ParseAssembly(Buffer, 0, Err, Context);
+ if (M == 0)
+ return 0;
+ return new ExistingModuleProvider(M);
+ }
+
+ /// If the given file holds a bitcode image, return a ModuleProvider
+ /// for it which does lazy deserialization of function bodies. Otherwise,
+ /// attempt to parse it as LLVM Assembly and return a fully populated
+ /// ModuleProvider.
+ inline ModuleProvider *getIRFileModuleProvider(const std::string &Filename,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ std::string ErrMsg;
+ MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg);
+ if (F == 0) {
+ Err = SMDiagnostic(Filename, -1, -1,
+ "Could not open input file '" + Filename + "'", "");
+ return 0;
+ }
+
+ return getIRModuleProvider(F, Err, Context);
+ }
+
+ /// If the given MemoryBuffer holds a bitcode image, return a Module
+ /// for it. Otherwise, attempt to parse it as LLVM Assembly and return
+ /// a Module for it. This function *always* takes ownership of the given
+ /// MemoryBuffer.
+ inline Module *ParseIR(MemoryBuffer *Buffer,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
+ (const unsigned char *)Buffer->getBufferEnd())) {
+ std::string ErrMsg;
+ Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg);
+ // ParseBitcodeFile does not take ownership of the Buffer.
+ delete Buffer;
+ if (M == 0)
+ Err = SMDiagnostic(Buffer->getBufferIdentifier(), -1, -1, ErrMsg, "");
+ return M;
+ }
+
+ return ParseAssembly(Buffer, 0, Err, Context);
+ }
+
+ /// If the given file holds a bitcode image, return a Module for it.
+ /// Otherwise, attempt to parse it as LLVM Assembly and return a Module
+ /// for it.
+ inline Module *ParseIRFile(const std::string &Filename,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ std::string ErrMsg;
+ MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg);
+ if (F == 0) {
+ Err = SMDiagnostic(Filename, -1, -1,
+ "Could not open input file '" + Filename + "'", "");
+ return 0;
+ }
+
+ return ParseIR(F, Err, Context);
+ }
+
+}
+
+#endif
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index 597cc9d..5d7c2f7 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -14,6 +14,7 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
+#include "llvm/Support/ErrorHandling.h"
namespace llvm {
@@ -30,13 +31,13 @@ namespace llvm {
/// @brief Base class for instruction visitors
///
-/// Instruction visitors are used when you want to perform different action for
-/// different kinds of instruction without without having to use lots of casts
-/// and a big switch statement (in your code that is).
+/// Instruction visitors are used when you want to perform different actions
+/// for different kinds of instructions without having to use lots of casts
+/// and a big switch statement (in your code, that is).
///
/// To define your own visitor, inherit from this class, specifying your
/// new type for the 'SubClass' template parameter, and "override" visitXXX
-/// functions in your class. I say "overriding" because this class is defined
+/// functions in your class. I say "override" because this class is defined
/// in terms of statically resolved overloading, not virtual functions.
///
/// For example, here is a visitor that counts the number of malloc
@@ -58,12 +59,12 @@ namespace llvm {
/// NumMallocs = CMV.Count;
///
/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
-/// Function, and Module, which recursively process all conained instructions.
+/// Function, and Module, which recursively process all contained instructions.
///
/// Note that if you don't implement visitXXX for some instruction type,
/// the visitXXX method for instruction superclass will be invoked. So
/// if instructions are added in the future, they will be automatically
-/// supported, if you handle on of their superclasses.
+/// supported, if you handle one of their superclasses.
///
/// The optional second template argument specifies the type that instruction
/// visitation functions should return. If you specify this, you *MUST* provide
@@ -113,8 +114,7 @@ public:
//
RetTy visit(Instruction &I) {
switch (I.getOpcode()) {
- default: assert(0 && "Unknown instruction type encountered!");
- abort();
+ default: llvm_unreachable("Unknown instruction type encountered!");
// Build the switch statement using the Instruction.def file...
#define HANDLE_INST(NUM, OPCODE, CLASS) \
case Instruction::OPCODE: return \
@@ -165,8 +165,6 @@ public:
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
- RetTy visitVICmpInst(VICmpInst &I) { DELEGATE(CmpInst);}
- RetTy visitVFCmpInst(VFCmpInst &I) { DELEGATE(CmpInst);}
RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
@@ -195,7 +193,7 @@ public:
RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);}
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
- // Next level propagators... if the user does not overload a specific
+ // Next level propagators: If the user does not overload a specific
// instruction type, they can overload one of these to get the whole class
// of instructions...
//
@@ -206,7 +204,7 @@ public:
RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); }
// If the user wants a 'default' case, they can choose to override this
- // function. If this function is not overloaded in the users subclass, then
+ // function. If this function is not overloaded in the user's subclass, then
// this instruction just gets ignored.
//
// Note that you MUST override this function if your return type is not void.
diff --git a/include/llvm/Support/LeakDetector.h b/include/llvm/Support/LeakDetector.h
index 8d74ac6..7dbfdbf 100644
--- a/include/llvm/Support/LeakDetector.h
+++ b/include/llvm/Support/LeakDetector.h
@@ -56,9 +56,9 @@ struct LeakDetector {
/// The specified message will be printed indicating when the check was
/// performed.
///
- static void checkForGarbage(const std::string &Message) {
+ static void checkForGarbage(LLVMContext &C, const std::string &Message) {
#ifndef NDEBUG
- checkForGarbageImpl(Message);
+ checkForGarbageImpl(C, Message);
#endif
}
@@ -83,7 +83,7 @@ private:
static void removeGarbageObjectImpl(const Value *Object);
static void addGarbageObjectImpl(void *Object);
static void removeGarbageObjectImpl(void *Object);
- static void checkForGarbageImpl(const std::string &Message);
+ static void checkForGarbageImpl(LLVMContext &C, const std::string &Message);
};
} // End llvm namespace
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 4fc6483..b8e2235 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -27,10 +27,12 @@ void* object_creator() {
/// object_deleter - Helper method for ManagedStatic.
///
-template<class C>
-void object_deleter(void *Ptr) {
- delete (C*)Ptr;
-}
+template<typename T> struct object_deleter {
+ static void call(void * Ptr) { delete (T*)Ptr; }
+};
+template<typename T, size_t N> struct object_deleter<T[N]> {
+ static void call(void * Ptr) { delete[] (T*)Ptr; }
+};
/// ManagedStaticBase - Common base class for ManagedStatic instances.
class ManagedStaticBase {
@@ -62,28 +64,28 @@ public:
C &operator*() {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return *static_cast<C*>(Ptr);
}
C *operator->() {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return static_cast<C*>(Ptr);
}
const C &operator*() const {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return *static_cast<C*>(Ptr);
}
const C *operator->() const {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return static_cast<C*>(Ptr);
}
diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h
index 8f672bd..03c5648 100644
--- a/include/llvm/Support/Mangler.h
+++ b/include/llvm/Support/Mangler.h
@@ -23,8 +23,17 @@ class Type;
class Module;
class Value;
class GlobalValue;
+template <typename T> class SmallVectorImpl;
class Mangler {
+public:
+ enum ManglerPrefixTy {
+ Default, ///< Emit default string before each symbol.
+ Private, ///< Emit "private" prefix before each symbol.
+ LinkerPrivate ///< Emit "linker private" prefix before each symbol.
+ };
+
+private:
/// Prefix - This string is added to each symbol that is emitted, unless the
/// symbol is marked as not needing this prefix.
const char *Prefix;
@@ -33,48 +42,50 @@ class Mangler {
/// linkage.
const char *PrivatePrefix;
+ /// LinkerPrivatePrefix - This string is emitted before each symbol with
+ /// "linker_private" linkage.
+ const char *LinkerPrivatePrefix;
+
/// UseQuotes - If this is set, the target accepts global names in quotes,
/// e.g. "foo bar" is a legal name. This syntax is used instead of escaping
/// the space character. By default, this is false.
bool UseQuotes;
- /// PreserveAsmNames - If this is set, the asm escape character is not removed
- /// from names with 'asm' specifiers.
- bool PreserveAsmNames;
+ /// SymbolsCanStartWithDigit - If this is set, the target allows symbols to
+ /// start with digits (e.g., "0x0021"). By default, this is false.
+ bool SymbolsCanStartWithDigit;
- /// Memo - This is used to remember the name that we assign a value.
+ /// AnonGlobalIDs - We need to give global values the same name every time
+ /// they are mangled. This keeps track of the number we give to anonymous
+ /// ones.
///
- DenseMap<const Value*, std::string> Memo;
+ DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs;
- /// Count - This simple counter is used to unique value names.
+ /// NextAnonGlobalID - This simple counter is used to unique value names.
///
- unsigned Count;
-
- /// TypeMap - If the client wants us to unique types, this keeps track of the
- /// current assignments and TypeCounter keeps track of the next id to assign.
- DenseMap<const Type*, unsigned> TypeMap;
- unsigned TypeCounter;
+ unsigned NextAnonGlobalID;
/// AcceptableChars - This bitfield contains a one for each character that is
/// allowed to be part of an unmangled name.
- unsigned AcceptableChars[256/32];
-public:
+ unsigned AcceptableChars[256 / 32];
+public:
// Mangler ctor - if a prefix is specified, it will be prepended onto all
// symbols.
- Mangler(Module &M, const char *Prefix = "", const char *privatePrefix = "");
+ Mangler(Module &M, const char *Prefix = "", const char *privatePrefix = "",
+ const char *linkerPrivatePrefix = "");
/// setUseQuotes - If UseQuotes is set to true, this target accepts quoted
/// strings for assembler labels.
void setUseQuotes(bool Val) { UseQuotes = Val; }
- /// setPreserveAsmNames - If the mangler should not strip off the asm name
- /// @verbatim identifier (\001), this should be set. @endverbatim
- void setPreserveAsmNames(bool Val) { PreserveAsmNames = Val; }
+ /// setSymbolsCanStartWithDigit - If SymbolsCanStartWithDigit is set to true,
+ /// this target allows symbols to start with digits.
+ void setSymbolsCanStartWithDigit(bool Val) { SymbolsCanStartWithDigit = Val; }
/// Acceptable Characters - This allows the target to specify which characters
/// are acceptable to the assembler without being mangled. By default we
- /// allow letters, numbers, '_', '$', and '.', which is what GAS accepts.
+ /// allow letters, numbers, '_', '$', '.', which is what GAS accepts, and '@'.
void markCharAcceptable(unsigned char X) {
AcceptableChars[X/32] |= 1 << (X&31);
}
@@ -85,11 +96,13 @@ public:
return (AcceptableChars[X/32] & (1 << (X&31))) != 0;
}
- /// getValueName - Returns the mangled name of V, an LLVM Value,
- /// in the current module.
+ /// getMangledName - Returns the mangled name of V, an LLVM Value,
+ /// in the current module. If 'Suffix' is specified, the name ends with the
+ /// specified suffix. If 'ForcePrivate' is specified, the label is specified
+ /// to have a private label prefix.
///
- std::string getValueName(const GlobalValue *V, const char *Suffix = "");
- std::string getValueName(const Value *V);
+ std::string getMangledName(const GlobalValue *V, const char *Suffix = "",
+ bool ForcePrivate = false);
/// makeNameProper - We don't want identifier names with ., space, or
/// - in them, so we mangle these characters into the strings "d_",
@@ -98,13 +111,14 @@ public:
/// does this for you, so there's no point calling it on the result
/// from getValueName.
///
- std::string makeNameProper(const std::string &x, const char *Prefix = 0,
- const char *PrivatePrefix = 0);
-
-private:
- /// getTypeID - Return a unique ID for the specified LLVM type.
- ///
- unsigned getTypeID(const Type *Ty);
+ std::string makeNameProper(const std::string &x,
+ ManglerPrefixTy PrefixTy = Mangler::Default);
+
+ /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
+ /// and the specified global variable's name. If the global variable doesn't
+ /// have a name, this fills in a unique name for the global.
+ void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
+ bool isImplicitlyPrivate);
};
} // End llvm namespace
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 85e19ac..6fa618e 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -52,6 +52,16 @@ inline bool isUInt32(int64_t Value) {
return static_cast<uint32_t>(Value) == Value;
}
+template<unsigned N>
+inline bool isInt(int64_t x) {
+ return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+}
+
+template<unsigned N>
+inline bool isUint(uint64_t x) {
+ return N >= 64 || x < (UINT64_C(1)<<N);
+}
+
/// isMask_32 - This function returns true if the argument is a sequence of ones
/// starting at the least significant bit with the remainder zero (32 bit
/// version). Ex. isMask_32(0x0000FFFFU) == true.
@@ -108,7 +118,7 @@ inline uint16_t ByteSwap_16(uint16_t Value) {
/// ByteSwap_32 - This function returns a byte-swapped representation of the
/// 32-bit argument, Value.
inline uint32_t ByteSwap_32(uint32_t Value) {
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
return __builtin_bswap32(Value);
#elif defined(_MSC_VER) && !defined(_DEBUG)
return _byteswap_ulong(Value);
@@ -124,7 +134,7 @@ inline uint32_t ByteSwap_32(uint32_t Value) {
/// ByteSwap_64 - This function returns a byte-swapped representation of the
/// 64-bit argument, Value.
inline uint64_t ByteSwap_64(uint64_t Value) {
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
return __builtin_bswap64(Value);
#elif defined(_MSC_VER) && !defined(_DEBUG)
return _byteswap_uint64(Value);
@@ -425,6 +435,13 @@ inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
return ((Value + Align - 1) / Align) * Align;
}
+/// OffsetToAlignment - Return the offset to the next integer (mod 2**64) that
+/// is greater than or equal to \arg Value and is a multiple of \arg
+/// Align. Align must be non-zero.
+inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
+ return RoundUpToAlignment(Value, Align) - Value;
+}
+
/// abs64 - absolute value of a 64-bit int. Not all environments support
/// "abs" on whatever their name for the 64-bit int type is. The absolute
/// value of the largest negative number is undefined, as with "abs".
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 58a217f..eb4784c 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
#define LLVM_SUPPORT_MEMORYBUFFER_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include <string>
@@ -42,6 +43,10 @@ public:
const char *getBufferEnd() const { return BufferEnd; }
size_t getBufferSize() const { return BufferEnd-BufferStart; }
+ StringRef getBuffer() const {
+ return StringRef(BufferStart, getBufferSize());
+ }
+
/// getBufferIdentifier - Return an identifier for this buffer, typically the
/// filename it was read from.
virtual const char *getBufferIdentifier() const {
diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h
new file mode 100644
index 0000000..dec0f13
--- /dev/null
+++ b/include/llvm/Support/MemoryObject.h
@@ -0,0 +1,70 @@
+//===- MemoryObject.h - Abstract memory interface ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MEMORYOBJECT_H
+#define MEMORYOBJECT_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// MemoryObject - Abstract base class for contiguous addressable memory.
+/// Necessary for cases in which the memory is in another process, in a
+/// file, or on a remote machine.
+/// All size and offset parameters are uint64_ts, to allow 32-bit processes
+/// access to 64-bit address spaces.
+class MemoryObject {
+public:
+ /// Destructor - Override as necessary.
+ virtual ~MemoryObject();
+
+ /// getBase - Returns the lowest valid address in the region.
+ ///
+ /// @result - The lowest valid address.
+ virtual uint64_t getBase() const = 0;
+
+ /// getExtent - Returns the size of the region in bytes. (The region is
+ /// contiguous, so the highest valid address of the region
+ /// is getBase() + getExtent() - 1).
+ ///
+ /// @result - The size of the region.
+ virtual uint64_t getExtent() const = 0;
+
+ /// readByte - Tries to read a single byte from the region.
+ ///
+ /// @param address - The address of the byte, in the same space as getBase().
+ /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
+
+ /// readBytes - Tries to read a contiguous range of bytes from the
+ /// region, up to the end of the region.
+ /// You should override this function if there is a quicker
+ /// way than going back and forth with individual bytes.
+ ///
+ /// @param address - The address of the first byte, in the same space as
+ /// getBase().
+ /// @param size - The maximum number of bytes to copy.
+ /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
+ /// and large enough to hold size bytes.
+ /// @param copied - A pointer to a nunber that is filled in with the number
+ /// of bytes actually read. May be NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readBytes(uint64_t address,
+ uint64_t size,
+ uint8_t* buf,
+ uint64_t* copied) const;
+};
+
+}
+
+#endif
+
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
index a49cf84..1f671c1 100644
--- a/include/llvm/Support/NoFolder.h
+++ b/include/llvm/Support/NoFolder.h
@@ -28,9 +28,12 @@
namespace llvm {
+class LLVMContext;
+
/// NoFolder - Create "constants" (actually, values) with no folding.
class NoFolder {
public:
+ explicit NoFolder(LLVMContext &) {}
//===--------------------------------------------------------------------===//
// Binary Operators
@@ -39,12 +42,18 @@ public:
Value *CreateAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateAdd(LHS, RHS);
}
+ Value *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNSWAdd(LHS, RHS);
+ }
Value *CreateFAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFAdd(LHS, RHS);
}
Value *CreateSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateSub(LHS, RHS);
}
+ Value *CreateNSWSub(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNSWSub(LHS, RHS);
+ }
Value *CreateFSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFSub(LHS, RHS);
}
@@ -60,6 +69,9 @@ public:
Value *CreateSDiv(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateSDiv(LHS, RHS);
}
+ Value *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateExactSDiv(LHS, RHS);
+ }
Value *CreateFDiv(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFDiv(LHS, RHS);
}
@@ -120,6 +132,15 @@ public:
return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx);
}
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
+ }
+ Value *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return GetElementPtrInst::CreateInBounds(C, IdxList, IdxList+NumIdx);
+ }
+
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
@@ -143,12 +164,6 @@ public:
Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
return new FCmpInst(P, LHS, RHS);
}
- Value *CreateVICmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
- return new VICmpInst(P, LHS, RHS);
- }
- Value *CreateVFCmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
- return new VFCmpInst(P, LHS, RHS);
- }
//===--------------------------------------------------------------------===//
// Other Instructions
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
index e489e0a..66ce3f2 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/include/llvm/Support/PassNameParser.h
@@ -24,6 +24,7 @@
#define LLVM_SUPPORT_PASS_NAME_PARSER_H
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Pass.h"
#include <algorithm>
#include <cstring>
@@ -65,9 +66,9 @@ public:
virtual void passRegistered(const PassInfo *P) {
if (ignorablePass(P) || !Opt) return;
if (findOption(P->getPassArgument()) != getNumOptions()) {
- cerr << "Two passes with the same argument (-"
+ errs() << "Two passes with the same argument (-"
<< P->getPassArgument() << ") attempted to be registered!\n";
- abort();
+ llvm_unreachable(0);
}
addLiteralOption(P->getPassArgument(), P, P->getPassName());
}
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index fda925f..c0b6a6b 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -58,7 +58,7 @@ struct constantint_ty {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
const APInt &CIV = CI->getValue();
if (Val >= 0)
- return CIV == Val;
+ return CIV == static_cast<uint64_t>(Val);
// If Val is negative, and CI is shorter than it, truncate to the right
// number of bits. If it is larger, then we have to sign extend. Just
// compare their negated values.
@@ -87,6 +87,18 @@ struct zero_ty {
/// m_Zero() - Match an arbitrary zero/null constant.
inline zero_ty m_Zero() { return zero_ty(); }
+struct one_ty {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const ConstantInt *C = dyn_cast<ConstantInt>(V))
+ return C->isOne();
+ return false;
+ }
+};
+
+/// m_One() - Match a an integer 1.
+inline one_ty m_One() { return one_ty(); }
+
template<typename Class>
struct bind_ty {
@@ -311,7 +323,8 @@ struct BinaryOpClass_match {
template<typename OpTy>
bool match(OpTy *V) {
if (Class *I = dyn_cast<Class>(V))
- if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ if (L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1))) {
if (Opcode)
*Opcode = I->getOpcode();
return true;
@@ -356,7 +369,8 @@ struct CmpClass_match {
template<typename OpTy>
bool match(OpTy *V) {
if (Class *I = dyn_cast<Class>(V))
- if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ if (L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1))) {
Predicate = I->getPredicate();
return true;
}
@@ -403,7 +417,7 @@ struct SelectClass_match {
};
template<typename Cond, typename LHS, typename RHS>
-inline SelectClass_match<Cond, RHS, LHS>
+inline SelectClass_match<Cond, LHS, RHS>
m_Select(const Cond &C, const LHS &L, const RHS &R) {
return SelectClass_match<Cond, LHS, RHS>(C, L, R);
}
@@ -503,7 +517,7 @@ struct neg_match {
}
private:
bool matchIfNeg(Value *LHS, Value *RHS) {
- return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) &&
+ return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
L.match(RHS);
}
};
@@ -532,7 +546,7 @@ struct fneg_match {
}
private:
bool matchIfFNeg(Value *LHS, Value *RHS) {
- return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) &&
+ return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
L.match(RHS);
}
};
diff --git a/include/llvm/Support/PointerLikeTypeTraits.h b/include/llvm/Support/PointerLikeTypeTraits.h
index b0edd3b..d64993f 100644
--- a/include/llvm/Support/PointerLikeTypeTraits.h
+++ b/include/llvm/Support/PointerLikeTypeTraits.h
@@ -50,12 +50,16 @@ public:
// Provide PointerLikeTypeTraits for const pointers.
template<typename T>
class PointerLikeTypeTraits<const T*> {
+ typedef PointerLikeTypeTraits<T*> NonConst;
+
public:
- static inline const void *getAsVoidPointer(const T* P) { return P; }
+ static inline const void *getAsVoidPointer(const T* P) {
+ return NonConst::getAsVoidPointer(const_cast<T*>(P));
+ }
static inline const T *getFromVoidPointer(const void *P) {
- return static_cast<const T*>(P);
+ return NonConst::getFromVoidPointer(const_cast<void*>(P));
}
- enum { NumLowBitsAvailable = 2 };
+ enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
};
// Provide PointerLikeTypeTraits for uintptr_t.
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 909d286..0db84e1 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -18,6 +18,12 @@
namespace llvm {
class raw_ostream;
+
+ /// DisablePrettyStackTrace - Set this to true to disable this module. This
+ /// might be neccessary if the host application installs its own signal
+ /// handlers which conflict with the ones installed by this module.
+ /// Defaults to false.
+ extern bool DisablePrettyStackTrace;
/// PrettyStackTraceEntry - This class is used to represent a frame of the
/// "pretty" stack trace that is dumped when a program crashes. You can define
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
index 2fa0365..d8f8c78 100644
--- a/include/llvm/Support/Recycler.h
+++ b/include/llvm/Support/Recycler.h
@@ -34,7 +34,8 @@ struct RecyclerStruct {
};
template<>
-struct ilist_traits<RecyclerStruct> : ilist_default_traits<RecyclerStruct> {
+struct ilist_traits<RecyclerStruct> :
+ public ilist_default_traits<RecyclerStruct> {
static RecyclerStruct *getPrev(const RecyclerStruct *t) { return t->Prev; }
static RecyclerStruct *getNext(const RecyclerStruct *t) { return t->Next; }
static void setPrev(RecyclerStruct *t, RecyclerStruct *p) { t->Prev = p; }
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
new file mode 100644
index 0000000..c954c0d
--- /dev/null
+++ b/include/llvm/Support/Regex.h
@@ -0,0 +1,63 @@
+//===-- Regex.h - Regular Expression matcher implementation -*- C++ -*-----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a POSIX regular expression matcher.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+
+struct llvm_regex;
+
+namespace llvm {
+ class StringRef;
+ template<typename T> class SmallVectorImpl;
+
+ class Regex {
+ public:
+ enum {
+ NoFlags=0,
+ /// Compile for matching that ignores upper/lower case distinctions.
+ IgnoreCase=1,
+ /// Compile for newline-sensitive matching. With this flag '[^' bracket
+ /// expressions and '.' never match newline. A ^ anchor matches the
+ /// null string after any newline in the string in addition to its normal
+ /// function, and the $ anchor matches the null string before any
+ /// newline in the string in addition to its normal function.
+ Newline=2
+ };
+
+ /// Compiles the given POSIX Extended Regular Expression \arg Regex.
+ /// This implementation supports regexes and matching strings with embedded
+ /// NUL characters.
+ Regex(const StringRef &Regex, unsigned Flags = NoFlags);
+ ~Regex();
+
+ /// isValid - returns the error encountered during regex compilation, or
+ /// matching, if any.
+ bool isValid(std::string &Error);
+
+ /// getNumMatches - In a valid regex, return the number of parenthesized
+ /// matches it contains. The number filled in by match will include this
+ /// many entries plus one for the whole regex (as element 0).
+ unsigned getNumMatches() const;
+
+ /// matches - Match the regex against a given \arg String.
+ ///
+ /// \param Matches - If given, on a succesful match this will be filled in
+ /// with references to the matched group expressions (inside \arg String),
+ /// the first group is always the entire pattern.
+ ///
+ /// This returns true on a successful match.
+ bool match(const StringRef &String, SmallVectorImpl<StringRef> *Matches=0);
+ private:
+ struct llvm_regex *preg;
+ int error;
+ };
+}
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
index 454679b..4db8882 100644
--- a/include/llvm/Support/Registry.h
+++ b/include/llvm/Support/Registry.h
@@ -77,9 +77,6 @@ namespace llvm {
static listener *ListenerHead, *ListenerTail;
public:
- class iterator;
-
-
/// Node in linked list of entries.
///
class node {
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 7c8a139..5b6f56b 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -65,10 +65,14 @@ class SourceMgr {
// include files in.
std::vector<std::string> IncludeDirectories;
+ /// LineNoCache - This is a cache for line number queries, its implementation
+ /// is really private to SourceMgr.cpp.
+ mutable void *LineNoCache;
+
SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT
void operator=(const SourceMgr&); // DO NOT IMPLEMENT
public:
- SourceMgr() {}
+ SourceMgr() : LineNoCache(0) {}
~SourceMgr();
void setIncludeDirs(const std::vector<std::string> &Dirs) {
@@ -145,17 +149,6 @@ public:
const std::string &Msg, const std::string &LineStr)
: Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
LineContents(LineStr) {}
- SMDiagnostic(const SMDiagnostic &RHS) {
- operator=(RHS);
- }
-
- void operator=(const SMDiagnostic &E) {
- Filename = E.Filename;
- LineNo = E.LineNo;
- ColumnNo = E.ColumnNo;
- Message = E.Message;
- LineContents = E.LineContents;
- }
void Print(const char *ProgName, raw_ostream &S);
};
diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h
index 5c63034..c71e6b9 100644
--- a/include/llvm/Support/StandardPasses.h
+++ b/include/llvm/Support/StandardPasses.h
@@ -80,6 +80,8 @@ namespace llvm {
}
}
+ /// createStandardModulePasses - Add the standard module passes. This is
+ /// expected to be run after the standard function passes.
static inline void createStandardModulePasses(PassManager *PM,
unsigned OptimizationLevel,
bool OptimizeSize,
@@ -91,71 +93,69 @@ namespace llvm {
if (OptimizationLevel == 0) {
if (InliningPass)
PM->add(InliningPass);
- } else {
- if (UnitAtATime)
- PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
- PM->add(createCFGSimplificationPass()); // Clean up disgusting code
- // Kill useless allocas
- PM->add(createPromoteMemoryToRegisterPass());
- if (UnitAtATime) {
- PM->add(createGlobalOptimizerPass()); // Optimize out global vars
- PM->add(createGlobalDCEPass()); // Remove unused fns and globs
- // IP Constant Propagation
- PM->add(createIPConstantPropagationPass());
- PM->add(createDeadArgEliminationPass()); // Dead argument elimination
- }
- PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
- PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
- if (UnitAtATime) {
- if (HaveExceptions)
- PM->add(createPruneEHPass()); // Remove dead EH info
- PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs
- }
- if (InliningPass)
- PM->add(InliningPass);
- if (OptimizationLevel > 2)
- PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
- if (SimplifyLibCalls)
- PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
- PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
- PM->add(createJumpThreadingPass()); // Thread jumps.
- PM->add(createCFGSimplificationPass()); // Merge & remove BBs
- PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas
- PM->add(createInstructionCombiningPass()); // Combine silly seq's
- PM->add(createCondPropagationPass()); // Propagate conditionals
- PM->add(createTailCallEliminationPass()); // Eliminate tail calls
- PM->add(createCFGSimplificationPass()); // Merge & remove BBs
- PM->add(createReassociatePass()); // Reassociate expressions
- PM->add(createLoopRotatePass()); // Rotate Loop
- PM->add(createLICMPass()); // Hoist loop invariants
- PM->add(createLoopUnswitchPass(OptimizeSize));
- PM->add(createLoopIndexSplitPass()); // Split loop index
- PM->add(createInstructionCombiningPass());
- PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
- PM->add(createLoopDeletionPass()); // Delete dead loops
- if (UnrollLoops)
- PM->add(createLoopUnrollPass()); // Unroll small loops
- PM->add(createInstructionCombiningPass()); // Clean up after the unroller
- PM->add(createGVNPass()); // Remove redundancies
- PM->add(createMemCpyOptPass()); // Remove memcpy / form memset
- PM->add(createSCCPPass()); // Constant prop with SCCP
+ return;
+ }
- // Run instcombine after redundancy elimination to exploit opportunities
- // opened up by them.
- PM->add(createInstructionCombiningPass());
- PM->add(createCondPropagationPass()); // Propagate conditionals
- PM->add(createDeadStoreEliminationPass()); // Delete dead stores
- PM->add(createAggressiveDCEPass()); // Delete dead instructions
- PM->add(createCFGSimplificationPass()); // Merge & remove BBs
-
- if (UnitAtATime) {
- PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
- PM->add(createDeadTypeEliminationPass()); // Eliminate dead types
- }
-
- if (OptimizationLevel > 1 && UnitAtATime)
- PM->add(createConstantMergePass()); // Merge dup global constants
+ if (UnitAtATime)
+ PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
+ PM->add(createCFGSimplificationPass()); // Clean up disgusting code
+ if (UnitAtATime) {
+ PM->add(createGlobalOptimizerPass()); // Optimize out global vars
+ PM->add(createGlobalDCEPass()); // Remove unused fns and globs
+ // IP Constant Propagation
+ PM->add(createIPConstantPropagationPass());
+ PM->add(createDeadArgEliminationPass()); // Dead argument elimination
}
+ PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
+ PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
+ if (UnitAtATime) {
+ if (HaveExceptions)
+ PM->add(createPruneEHPass()); // Remove dead EH info
+ PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs
+ }
+ if (InliningPass)
+ PM->add(InliningPass);
+ if (OptimizationLevel > 2)
+ PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
+ if (SimplifyLibCalls)
+ PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
+ PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
+ PM->add(createJumpThreadingPass()); // Thread jumps.
+ PM->add(createCFGSimplificationPass()); // Merge & remove BBs
+ PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas
+ PM->add(createInstructionCombiningPass()); // Combine silly seq's
+ PM->add(createCondPropagationPass()); // Propagate conditionals
+ PM->add(createTailCallEliminationPass()); // Eliminate tail calls
+ PM->add(createCFGSimplificationPass()); // Merge & remove BBs
+ PM->add(createReassociatePass()); // Reassociate expressions
+ PM->add(createLoopRotatePass()); // Rotate Loop
+ PM->add(createLICMPass()); // Hoist loop invariants
+ PM->add(createLoopUnswitchPass(OptimizeSize));
+ PM->add(createInstructionCombiningPass());
+ PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
+ PM->add(createLoopDeletionPass()); // Delete dead loops
+ if (UnrollLoops)
+ PM->add(createLoopUnrollPass()); // Unroll small loops
+ PM->add(createInstructionCombiningPass()); // Clean up after the unroller
+ PM->add(createGVNPass()); // Remove redundancies
+ PM->add(createMemCpyOptPass()); // Remove memcpy / form memset
+ PM->add(createSCCPPass()); // Constant prop with SCCP
+
+ // Run instcombine after redundancy elimination to exploit opportunities
+ // opened up by them.
+ PM->add(createInstructionCombiningPass());
+ PM->add(createCondPropagationPass()); // Propagate conditionals
+ PM->add(createDeadStoreEliminationPass()); // Delete dead stores
+ PM->add(createAggressiveDCEPass()); // Delete dead instructions
+ PM->add(createCFGSimplificationPass()); // Merge & remove BBs
+
+ if (UnitAtATime) {
+ PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
+ PM->add(createDeadTypeEliminationPass()); // Eliminate dead types
+ }
+
+ if (OptimizationLevel > 1 && UnitAtATime)
+ PM->add(createConstantMergePass()); // Merge dup global constants
}
static inline void addOnePass(PassManager *PM, Pass *P, bool AndVerify) {
@@ -230,10 +230,8 @@ namespace llvm {
addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
addOnePass(PM, createJumpThreadingPass(), VerifyEach);
- // Cleanup jump threading.
- addOnePass(PM, createPromoteMemoryToRegisterPass(), VerifyEach);
- // Delete basic blocks, which optimization passes may have killed...
+ // Delete basic blocks, which optimization passes may have killed.
addOnePass(PM, createCFGSimplificationPass(), VerifyEach);
// Now that we have optimized the program, discard unreachable functions.
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index 98db8e2..82e46d4 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -1,4 +1,4 @@
-//===-- StringPool.h - Interned string pool -------------------------------===//
+//===-- StringPool.h - Interned string pool ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -64,12 +64,7 @@ namespace llvm {
/// intern - Adds a string to the pool and returns a reference-counted
/// pointer to it. No additional memory is allocated if the string already
/// exists in the pool.
- PooledStringPtr intern(const char *Begin, const char *End);
-
- /// intern - Adds a null-terminated string to the pool and returns a
- /// reference-counted pointer to it. No additional memory is allocated if
- /// the string already exists in the pool.
- inline PooledStringPtr intern(const char *Str);
+ PooledStringPtr intern(const StringRef &Str);
/// empty - Checks whether the pool is empty. Returns true if so.
///
@@ -139,10 +134,6 @@ namespace llvm {
inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
};
- PooledStringPtr StringPool::intern(const char *Str) {
- return intern(Str, Str + strlen(Str));
- }
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
index 9a33fa3..b3d83fc 100644
--- a/include/llvm/Support/SystemUtils.h
+++ b/include/llvm/Support/SystemUtils.h
@@ -15,27 +15,29 @@
#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
#define LLVM_SUPPORT_SYSTEMUTILS_H
-#include "llvm/System/Program.h"
+#include <string>
namespace llvm {
+ class raw_ostream;
+ namespace sys { class Path; }
-/// Determine if the ostream provided is connected to the std::cout and
+/// Determine if the raw_ostream provided is connected to the outs() and
/// displayed or not (to a console window). If so, generate a warning message
/// advising against display of bitcode and return true. Otherwise just return
/// false
/// @brief Check for output written to a console
bool CheckBitcodeOutputToConsole(
- std::ostream* stream_to_check, ///< The stream to be checked
- bool print_warning = true ///< Control whether warnings are printed
+ raw_ostream &stream_to_check, ///< The stream to be checked
+ bool print_warning = true ///< Control whether warnings are printed
);
/// FindExecutable - Find a named executable, giving the argv[0] of program
-/// being executed. This allows us to find another LLVM tool if it is built into
-/// the same directory, but that directory is neither the current directory, nor
-/// in the PATH. If the executable cannot be found, return an empty string.
+/// being executed. This allows us to find another LLVM tool if it is built in
+/// the same directory. If the executable cannot be found, return an
+/// empty string.
/// @brief Find a named executable.
sys::Path FindExecutable(const std::string &ExeName,
- const std::string &ProgramPath);
+ const char *Argv0, void *MainAddr);
} // End llvm namespace
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index b0700c1..8e28632 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -25,21 +25,24 @@
namespace llvm {
class TargetData;
+class LLVMContext;
/// TargetFolder - Create constants with target dependent folding.
class TargetFolder {
const TargetData *TD;
+ LLVMContext &Context;
/// Fold - Fold the constant using target specific information.
Constant *Fold(Constant *C) const {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
- if (Constant *CF = ConstantFoldConstantExpression(CE, TD))
+ if (Constant *CF = ConstantFoldConstantExpression(CE, Context, TD))
return CF;
return C;
}
public:
- explicit TargetFolder(const TargetData *TheTD) : TD(TheTD) {}
+ explicit TargetFolder(const TargetData *TheTD, LLVMContext &C) :
+ TD(TheTD), Context(C) {}
//===--------------------------------------------------------------------===//
// Binary Operators
@@ -48,12 +51,18 @@ public:
Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getAdd(LHS, RHS));
}
+ Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getNSWAdd(LHS, RHS));
+ }
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFAdd(LHS, RHS));
}
Constant *CreateSub(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getSub(LHS, RHS));
}
+ Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getNSWSub(LHS, RHS));
+ }
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFSub(LHS, RHS));
}
@@ -69,6 +78,9 @@ public:
Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getSDiv(LHS, RHS));
}
+ Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getExactSDiv(LHS, RHS));
+ }
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFDiv(LHS, RHS));
}
@@ -132,6 +144,15 @@ public:
return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
}
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx));
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx));
+ }
+
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
@@ -176,14 +197,6 @@ public:
Constant *RHS) const {
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
}
- Constant *CreateVICmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return Fold(ConstantExpr::getCompare(P, LHS, RHS));
- }
- Constant *CreateVFCmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return Fold(ConstantExpr::getCompare(P, LHS, RHS));
- }
//===--------------------------------------------------------------------===//
// Other Instructions
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index 71b7ee5..54f1da9 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -19,15 +19,15 @@
#include "llvm/System/Mutex.h"
#include <string>
#include <vector>
-#include <iosfwd>
#include <cassert>
namespace llvm {
class TimerGroup;
+class raw_ostream;
/// Timer - This class is used to track the amount of time spent between
-/// invocations of it's startTimer()/stopTimer() methods. Given appropriate OS
+/// invocations of its startTimer()/stopTimer() methods. Given appropriate OS
/// support it can also keep track of the RSS of the program at various points.
/// By default, the Timer will print the amount of time it has captured to
/// standard error when the laster timer is destroyed, otherwise it is printed
@@ -112,7 +112,7 @@ public:
/// print - Print the current timer to standard error, and reset the "Started"
/// flag.
- void print(const Timer &Total, std::ostream &OS);
+ void print(const Timer &Total, raw_ostream &OS);
private:
friend class TimerGroup;
diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h
index b0ae516..fb22e3f 100644
--- a/include/llvm/Support/TypeBuilder.h
+++ b/include/llvm/Support/TypeBuilder.h
@@ -16,6 +16,7 @@
#define LLVM_SUPPORT_TYPEBUILDER_H
#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
#include <limits.h>
namespace llvm {
@@ -49,15 +50,14 @@ namespace llvm {
/// namespace llvm {
/// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
/// public:
-/// static const StructType *get() {
-/// // Using the static result variable ensures that the type is
-/// // only looked up once.
-/// static const StructType *const result = StructType::get(
-/// TypeBuilder<types::i<32>, xcompile>::get(),
-/// TypeBuilder<types::i<32>*, xcompile>::get(),
-/// TypeBuilder<types::i<8>*[], xcompile>::get(),
+/// static const StructType *get(LLVMContext &Context) {
+/// // If you cache this result, be sure to cache it separately
+/// // for each LLVMContext.
+/// return StructType::get(
+/// TypeBuilder<types::i<32>, xcompile>::get(Context),
+/// TypeBuilder<types::i<32>*, xcompile>::get(Context),
+/// TypeBuilder<types::i<8>*[], xcompile>::get(Context),
/// NULL);
-/// return result;
/// }
///
/// // You may find this a convenient place to put some constants
@@ -71,9 +71,6 @@ namespace llvm {
/// }
/// } // namespace llvm
///
-/// Using the static result variable ensures that the type is only looked up
-/// once.
-///
/// TypeBuilder cannot handle recursive types or types you only know at runtime.
/// If you try to give it a recursive type, it will deadlock, infinitely
/// recurse, or throw a recursive_init exception.
@@ -104,10 +101,8 @@ template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
// Pointers
template<typename T, bool cross> class TypeBuilder<T*, cross> {
public:
- static const PointerType *get() {
- static const PointerType *const result =
- PointerType::getUnqual(TypeBuilder<T,cross>::get());
- return result;
+ static const PointerType *get(LLVMContext &Context) {
+ return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
}
};
@@ -117,19 +112,15 @@ template<typename T, bool cross> class TypeBuilder<T&, cross> {};
// Arrays
template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
public:
- static const ArrayType *get() {
- static const ArrayType *const result =
- ArrayType::get(TypeBuilder<T, cross>::get(), N);
- return result;
+ static const ArrayType *get(LLVMContext &Context) {
+ return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
}
};
/// LLVM uses an array of length 0 to represent an unknown-length array.
template<typename T, bool cross> class TypeBuilder<T[], cross> {
public:
- static const ArrayType *get() {
- static const ArrayType *const result =
- ArrayType::get(TypeBuilder<T, cross>::get(), 0);
- return result;
+ static const ArrayType *get(LLVMContext &Context) {
+ return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
}
};
@@ -158,10 +149,8 @@ public:
#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
template<> class TypeBuilder<T, false> { \
public: \
- static const IntegerType *get() { \
- static const IntegerType *const result = \
- IntegerType::get(sizeof(T) * CHAR_BIT); \
- return result; \
+ static const IntegerType *get(LLVMContext &Context) { \
+ return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
} \
}; \
template<> class TypeBuilder<T, true> { \
@@ -189,53 +178,52 @@ DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
template<uint32_t num_bits, bool cross>
class TypeBuilder<types::i<num_bits>, cross> {
public:
- static const IntegerType *get() {
- static const IntegerType *const result = IntegerType::get(num_bits);
- return result;
+ static const IntegerType *get(LLVMContext &C) {
+ return IntegerType::get(C, num_bits);
}
};
template<> class TypeBuilder<float, false> {
public:
- static const Type *get() {
- return Type::FloatTy;
+ static const Type *get(LLVMContext& C) {
+ return Type::getFloatTy(C);
}
};
template<> class TypeBuilder<float, true> {};
template<> class TypeBuilder<double, false> {
public:
- static const Type *get() {
- return Type::DoubleTy;
+ static const Type *get(LLVMContext& C) {
+ return Type::getDoubleTy(C);
}
};
template<> class TypeBuilder<double, true> {};
template<bool cross> class TypeBuilder<types::ieee_float, cross> {
public:
- static const Type *get() { return Type::FloatTy; }
+ static const Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
};
template<bool cross> class TypeBuilder<types::ieee_double, cross> {
public:
- static const Type *get() { return Type::DoubleTy; }
+ static const Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
};
template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
public:
- static const Type *get() { return Type::X86_FP80Ty; }
+ static const Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
};
template<bool cross> class TypeBuilder<types::fp128, cross> {
public:
- static const Type *get() { return Type::FP128Ty; }
+ static const Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
};
template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
public:
- static const Type *get() { return Type::PPC_FP128Ty; }
+ static const Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
};
template<bool cross> class TypeBuilder<void, cross> {
public:
- static const Type *get() {
- return Type::VoidTy;
+ static const Type *get(LLVMContext &C) {
+ return Type::getVoidTy(C);
}
};
@@ -246,64 +234,43 @@ template<> class TypeBuilder<void*, false>
template<typename R, bool cross> class TypeBuilder<R(), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
- return FunctionType::get(TypeBuilder<R, cross>::get(), false);
+ static const FunctionType *get(LLVMContext &Context) {
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
}
};
template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(1);
- params.push_back(TypeBuilder<A1, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
}
};
template<typename R, typename A1, typename A2, bool cross>
class TypeBuilder<R(A1, A2), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(2);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
}
};
template<typename R, typename A1, typename A2, typename A3, bool cross>
class TypeBuilder<R(A1, A2, A3), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(3);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- params.push_back(TypeBuilder<A3, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ params.push_back(TypeBuilder<A3, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
}
};
@@ -311,20 +278,15 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
bool cross>
class TypeBuilder<R(A1, A2, A3, A4), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(4);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- params.push_back(TypeBuilder<A3, cross>::get());
- params.push_back(TypeBuilder<A4, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ params.push_back(TypeBuilder<A3, cross>::get(Context));
+ params.push_back(TypeBuilder<A4, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
}
};
@@ -332,85 +294,58 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, bool cross>
class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(5);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- params.push_back(TypeBuilder<A3, cross>::get());
- params.push_back(TypeBuilder<A4, cross>::get());
- params.push_back(TypeBuilder<A5, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ params.push_back(TypeBuilder<A3, cross>::get(Context));
+ params.push_back(TypeBuilder<A4, cross>::get(Context));
+ params.push_back(TypeBuilder<A5, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
}
};
template<typename R, bool cross> class TypeBuilder<R(...), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
- return FunctionType::get(TypeBuilder<R, cross>::get(), true);
+ static const FunctionType *get(LLVMContext &Context) {
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
}
};
template<typename R, typename A1, bool cross>
class TypeBuilder<R(A1, ...), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(1);
- params.push_back(TypeBuilder<A1, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
}
};
template<typename R, typename A1, typename A2, bool cross>
class TypeBuilder<R(A1, A2, ...), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(2);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
}
};
template<typename R, typename A1, typename A2, typename A3, bool cross>
class TypeBuilder<R(A1, A2, A3, ...), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(3);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- params.push_back(TypeBuilder<A3, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ params.push_back(TypeBuilder<A3, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
}
};
@@ -418,20 +353,15 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
bool cross>
class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(4);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- params.push_back(TypeBuilder<A3, cross>::get());
- params.push_back(TypeBuilder<A4, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ params.push_back(TypeBuilder<A3, cross>::get(Context));
+ params.push_back(TypeBuilder<A4, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
}
};
@@ -439,21 +369,16 @@ template<typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, bool cross>
class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
public:
- static const FunctionType *get() {
- static const FunctionType *const result = create();
- return result;
- }
-
-private:
- static const FunctionType *create() {
+ static const FunctionType *get(LLVMContext &Context) {
std::vector<const Type*> params;
params.reserve(5);
- params.push_back(TypeBuilder<A1, cross>::get());
- params.push_back(TypeBuilder<A2, cross>::get());
- params.push_back(TypeBuilder<A3, cross>::get());
- params.push_back(TypeBuilder<A4, cross>::get());
- params.push_back(TypeBuilder<A5, cross>::get());
- return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
+ params.push_back(TypeBuilder<A1, cross>::get(Context));
+ params.push_back(TypeBuilder<A2, cross>::get(Context));
+ params.push_back(TypeBuilder<A3, cross>::get(Context));
+ params.push_back(TypeBuilder<A4, cross>::get(Context));
+ params.push_back(TypeBuilder<A5, cross>::get(Context));
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
}
};
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index a97a5e8..e6363ff 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_VALUEHANDLE_H
#define LLVM_SUPPORT_VALUEHANDLE_H
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Value.h"
@@ -44,73 +45,87 @@ protected:
/// fully general Callback version does have a vtable.
enum HandleBaseKind {
Assert,
- Weak,
- Callback
+ Callback,
+ Tracking,
+ Weak
};
private:
-
+
PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
ValueHandleBase *Next;
Value *VP;
+
+ explicit ValueHandleBase(const ValueHandleBase&); // DO NOT IMPLEMENT.
public:
explicit ValueHandleBase(HandleBaseKind Kind)
: PrevPair(0, Kind), Next(0), VP(0) {}
ValueHandleBase(HandleBaseKind Kind, Value *V)
: PrevPair(0, Kind), Next(0), VP(V) {
- if (V)
+ if (isValid(VP))
AddToUseList();
}
ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
: PrevPair(0, Kind), Next(0), VP(RHS.VP) {
- if (VP)
+ if (isValid(VP))
AddToExistingUseList(RHS.getPrevPtr());
}
~ValueHandleBase() {
- if (VP)
- RemoveFromUseList();
+ if (isValid(VP))
+ RemoveFromUseList();
}
-
+
Value *operator=(Value *RHS) {
if (VP == RHS) return RHS;
- if (VP) RemoveFromUseList();
+ if (isValid(VP)) RemoveFromUseList();
VP = RHS;
- if (VP) AddToUseList();
+ if (isValid(VP)) AddToUseList();
return RHS;
}
Value *operator=(const ValueHandleBase &RHS) {
if (VP == RHS.VP) return RHS.VP;
- if (VP) RemoveFromUseList();
+ if (isValid(VP)) RemoveFromUseList();
VP = RHS.VP;
- if (VP) AddToExistingUseList(RHS.getPrevPtr());
+ if (isValid(VP)) AddToExistingUseList(RHS.getPrevPtr());
return VP;
}
-
+
Value *operator->() const { return getValPtr(); }
Value &operator*() const { return *getValPtr(); }
protected:
Value *getValPtr() const { return VP; }
+ static bool isValid(Value *V) {
+ return V &&
+ V != DenseMapInfo<Value *>::getEmptyKey() &&
+ V != DenseMapInfo<Value *>::getTombstoneKey();
+ }
+
private:
// Callbacks made from Value.
static void ValueIsDeleted(Value *V);
static void ValueIsRAUWd(Value *Old, Value *New);
-
+
// Internal implementation details.
ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
HandleBaseKind getKind() const { return PrevPair.getInt(); }
void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
-
- /// AddToUseList - Add this ValueHandle to the use list for VP, where List is
- /// known to point into the existing use list.
+
+ /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
+ /// List is the address of either the head of the list or a Next node within
+ /// the existing use list.
void AddToExistingUseList(ValueHandleBase **List);
-
+
+ /// AddToExistingUseListAfter - Add this ValueHandle to the use list after
+ /// Node.
+ void AddToExistingUseListAfter(ValueHandleBase *Node);
+
/// AddToUseList - Add this ValueHandle to the use list for VP.
void AddToUseList();
/// RemoveFromUseList - Remove this ValueHandle from its current use list.
void RemoveFromUseList();
};
-
+
/// WeakVH - This is a value handle that tries hard to point to a Value, even
/// across RAUW operations, but will null itself out if the value is destroyed.
/// this is useful for advisory sorts of information, but should not be used as
@@ -123,6 +138,13 @@ public:
WeakVH(const WeakVH &RHS)
: ValueHandleBase(Weak, RHS) {}
+ Value *operator=(Value *RHS) {
+ return ValueHandleBase::operator=(RHS);
+ }
+ Value *operator=(const ValueHandleBase &RHS) {
+ return ValueHandleBase::operator=(RHS);
+ }
+
operator Value*() const {
return getValPtr();
}
@@ -153,7 +175,7 @@ template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH> {};
/// AssertingVH's as it moves. This is required because in non-assert mode this
/// class turns into a trivial wrapper around a pointer.
template <typename ValueTy>
-class AssertingVH
+class AssertingVH
#ifndef NDEBUG
: public ValueHandleBase
#endif
@@ -164,7 +186,7 @@ class AssertingVH
return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
}
void setValPtr(ValueTy *P) {
- ValueHandleBase::operator=(P);
+ ValueHandleBase::operator=(GetAsValue(P));
}
#else
ValueTy *ThePtr;
@@ -172,10 +194,15 @@ class AssertingVH
void setValPtr(ValueTy *P) { ThePtr = P; }
#endif
+ // Convert a ValueTy*, which may be const, to the type the base
+ // class expects.
+ static Value *GetAsValue(Value *V) { return V; }
+ static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
+
public:
#ifndef NDEBUG
AssertingVH() : ValueHandleBase(Assert) {}
- AssertingVH(ValueTy *P) : ValueHandleBase(Assert, P) {}
+ AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
#else
AssertingVH() : ThePtr(0) {}
@@ -190,7 +217,7 @@ public:
setValPtr(RHS);
return getValPtr();
}
- ValueTy *operator=(AssertingVH<ValueTy> &RHS) {
+ ValueTy *operator=(const AssertingVH<ValueTy> &RHS) {
setValPtr(RHS.getValPtr());
return getValPtr();
}
@@ -211,6 +238,88 @@ template<> struct simplify_type<const AssertingVH<Value> > {
template<> struct simplify_type<AssertingVH<Value> >
: public simplify_type<const AssertingVH<Value> > {};
+/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
+/// even across RAUW operations.
+///
+/// TrackingVH is designed for situations where a client needs to hold a handle
+/// to a Value (or subclass) across some operations which may move that value,
+/// but should never destroy it or replace it with some unacceptable type.
+///
+/// It is an error to do anything with a TrackingVH whose value has been
+/// destroyed, except to destruct it.
+///
+/// It is an error to attempt to replace a value with one of a type which is
+/// incompatible with any of its outstanding TrackingVHs.
+template<typename ValueTy>
+class TrackingVH : public ValueHandleBase {
+ void CheckValidity() const {
+ Value *VP = ValueHandleBase::getValPtr();
+
+ // Null is always ok.
+ if (!VP)
+ return;
+
+ // Check that this value is valid (i.e., it hasn't been deleted). We
+ // explicitly delay this check until access to avoid requiring clients to be
+ // unnecessarily careful w.r.t. destruction.
+ assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
+
+ // Check that the value is a member of the correct subclass. We would like
+ // to check this property on assignment for better debugging, but we don't
+ // want to require a virtual interface on this VH. Instead we allow RAUW to
+ // replace this value with a value of an invalid type, and check it here.
+ assert(isa<ValueTy>(VP) &&
+ "Tracked Value was replaced by one with an invalid type!");
+ }
+
+ ValueTy *getValPtr() const {
+ CheckValidity();
+ return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
+ }
+ void setValPtr(ValueTy *P) {
+ CheckValidity();
+ ValueHandleBase::operator=(GetAsValue(P));
+ }
+
+ // Convert a ValueTy*, which may be const, to the type the base
+ // class expects.
+ static Value *GetAsValue(Value *V) { return V; }
+ static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
+
+public:
+ TrackingVH() : ValueHandleBase(Tracking) {}
+ TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, P) {}
+ TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
+
+ operator ValueTy*() const {
+ return getValPtr();
+ }
+
+ ValueTy *operator=(ValueTy *RHS) {
+ setValPtr(RHS);
+ return getValPtr();
+ }
+ ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
+ setValPtr(RHS.getValPtr());
+ return getValPtr();
+ }
+
+ ValueTy *operator->() const { return getValPtr(); }
+ ValueTy &operator*() const { return *getValPtr(); }
+};
+
+// Specialize simplify_type to allow TrackingVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const TrackingVH<Value> > {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) {
+ return static_cast<Value *>(AVH);
+ }
+};
+template<> struct simplify_type<TrackingVH<Value> >
+ : public simplify_type<const TrackingVH<Value> > {};
+
/// CallbackVH - This is a value handle that allows subclasses to define
/// callbacks that run when the underlying Value has RAUW called on it or is
/// destroyed. This class can be used as the key of a map, as long as the user
diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h
new file mode 100644
index 0000000..e0978b2
--- /dev/null
+++ b/include/llvm/Support/raw_os_ostream.h
@@ -0,0 +1,42 @@
+//===- raw_os_ostream.h - std::ostream adaptor for raw_ostream --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the raw_os_ostream class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RAW_OS_OSTREAM_H
+#define LLVM_SUPPORT_RAW_OS_OSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+#include <iosfwd>
+
+namespace llvm {
+
+/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a
+/// simple adaptor class. It does not check for output errors; clients should
+/// use the underlying stream to detect errors.
+class raw_os_ostream : public raw_ostream {
+ std::ostream &OS;
+
+ /// write_impl - See raw_ostream::write_impl.
+ virtual void write_impl(const char *Ptr, size_t Size);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos();
+
+public:
+ raw_os_ostream(std::ostream &O) : OS(O) {}
+ ~raw_os_ostream();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 8242f04..7827dd8 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -14,11 +14,8 @@
#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
#define LLVM_SUPPORT_RAW_OSTREAM_H
-#include "llvm/ADT/StringExtras.h"
-#include <cassert>
-#include <cstring>
-#include <string>
-#include <iosfwd>
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class format_object_base;
@@ -31,18 +28,39 @@ namespace llvm {
/// a chunk at a time.
class raw_ostream {
private:
+ // Do not implement. raw_ostream is noncopyable.
+ void operator=(const raw_ostream &);
+ raw_ostream(const raw_ostream &);
+
/// The buffer is handled in such a way that the buffer is
/// uninitialized, unbuffered, or out of space when OutBufCur >=
/// OutBufEnd. Thus a single comparison suffices to determine if we
/// need to take the slow path to write a single character.
///
/// The buffer is in one of three states:
- /// 1. Unbuffered (Unbuffered == true)
- /// 1. Uninitialized (Unbuffered == false && OutBufStart == 0).
- /// 2. Buffered (Unbuffered == false && OutBufStart != 0 &&
- /// OutBufEnd - OutBufStart >= 64).
+ /// 1. Unbuffered (BufferMode == Unbuffered)
+ /// 1. Uninitialized (BufferMode != Unbuffered && OutBufStart == 0).
+ /// 2. Buffered (BufferMode != Unbuffered && OutBufStart != 0 &&
+ /// OutBufEnd - OutBufStart >= 1).
+ ///
+ /// If buffered, then the raw_ostream owns the buffer if (BufferMode ==
+ /// InternalBuffer); otherwise the buffer has been set via SetBuffer and is
+ /// managed by the subclass.
+ ///
+ /// If a subclass installs an external buffer using SetBuffer then it can wait
+ /// for a \see write_impl() call to handle the data which has been put into
+ /// this buffer.
char *OutBufStart, *OutBufEnd, *OutBufCur;
- bool Unbuffered;
+
+ enum BufferKind {
+ Unbuffered = 0,
+ InternalBuffer,
+ ExternalBuffer
+ } BufferMode;
+
+ /// Error This flag is true if an error of any kind has been detected.
+ ///
+ bool Error;
public:
// color order matches ANSI escape sequence, don't change
@@ -58,49 +76,66 @@ public:
SAVEDCOLOR
};
- explicit raw_ostream(bool unbuffered=false) : Unbuffered(unbuffered) {
+ explicit raw_ostream(bool unbuffered=false)
+ : BufferMode(unbuffered ? Unbuffered : InternalBuffer), Error(false) {
// Start out ready to flush.
OutBufStart = OutBufEnd = OutBufCur = 0;
}
- virtual ~raw_ostream() {
- delete [] OutBufStart;
- }
+ virtual ~raw_ostream();
/// tell - Return the current offset with the file.
uint64_t tell() { return current_pos() + GetNumBytesInBuffer(); }
+ /// has_error - Return the value of the flag in this raw_ostream indicating
+ /// whether an output error has been encountered.
+ bool has_error() const {
+ return Error;
+ }
+
+ /// clear_error - Set the flag read by has_error() to false. If the error
+ /// flag is set at the time when this raw_ostream's destructor is called,
+ /// llvm_report_error is called to report the error. Use clear_error()
+ /// after handling the error to avoid this behavior.
+ void clear_error() {
+ Error = false;
+ }
+
//===--------------------------------------------------------------------===//
// Configuration Interface
//===--------------------------------------------------------------------===//
- /// SetBufferSize - Set the internal buffer size to the specified amount
- /// instead of the default.
- void SetBufferSize(unsigned Size=4096) {
- assert(Size >= 64 &&
- "Buffer size must be somewhat large for invariants to hold");
+ /// SetBuffered - Set the stream to be buffered, with an automatically
+ /// determined buffer size.
+ void SetBuffered();
+
+ /// SetBufferSize - Set the stream to be buffered, using the
+ /// specified buffer size.
+ void SetBufferSize(size_t Size) {
flush();
+ SetBufferAndMode(new char[Size], Size, InternalBuffer);
+ }
- delete [] OutBufStart;
- OutBufStart = new char[Size];
- OutBufEnd = OutBufStart+Size;
- OutBufCur = OutBufStart;
- Unbuffered = false;
+ size_t GetBufferSize() {
+ // If we're supposed to be buffered but haven't actually gotten around
+ // to allocating the buffer yet, return the value that would be used.
+ if (BufferMode != Unbuffered && OutBufStart == 0)
+ return preferred_buffer_size();
+
+ // Otherwise just return the size of the allocated buffer.
+ return OutBufEnd - OutBufStart;
}
- /// SetUnbuffered - Set the streams buffering status. When
- /// unbuffered the stream will flush after every write. This routine
+ /// SetUnbuffered - Set the stream to be unbuffered. When
+ /// unbuffered, the stream will flush after every write. This routine
/// will also flush the buffer immediately when the stream is being
/// set to unbuffered.
void SetUnbuffered() {
flush();
-
- delete [] OutBufStart;
- OutBufStart = OutBufEnd = OutBufCur = 0;
- Unbuffered = true;
+ SetBufferAndMode(0, 0, Unbuffered);
}
- unsigned GetNumBytesInBuffer() const {
+ size_t GetNumBytesInBuffer() const {
return OutBufCur - OutBufStart;
}
@@ -134,22 +169,29 @@ public:
return *this;
}
- raw_ostream &operator<<(const char *Str) {
- // Inline fast path, particulary for constant strings where a
- // sufficiently smart compiler will simplify strlen.
-
- unsigned Size = strlen(Str);
+ raw_ostream &operator<<(const StringRef &Str) {
+ // Inline fast path, particularly for strings with a known length.
+ size_t Size = Str.size();
// Make sure we can use the fast path.
if (OutBufCur+Size > OutBufEnd)
- return write(Str, Size);
+ return write(Str.data(), Size);
- memcpy(OutBufCur, Str, Size);
+ memcpy(OutBufCur, Str.data(), Size);
OutBufCur += Size;
return *this;
}
- raw_ostream &operator<<(const std::string& Str) {
+ raw_ostream &operator<<(const char *Str) {
+ // Inline fast path, particulary for constant strings where a sufficiently
+ // smart compiler will simplify strlen.
+
+ this->operator<<(StringRef(Str));
+ return *this;
+ }
+
+ raw_ostream &operator<<(const std::string &Str) {
+ // Avoid the fast path, it would only increase code size for a marginal win.
write(Str.data(), Str.length());
return *this;
}
@@ -169,17 +211,21 @@ public:
return *this;
}
- raw_ostream &operator<<(double N) {
- this->operator<<(ftostr(N));
- return *this;
- }
+ raw_ostream &operator<<(double N);
+
+ /// write_hex - Output \arg N in hexadecimal, without any prefix or padding.
+ raw_ostream &write_hex(unsigned long long N);
raw_ostream &write(unsigned char C);
- raw_ostream &write(const char *Ptr, unsigned Size);
+ raw_ostream &write(const char *Ptr, size_t Size);
// Formatted output, see the format() function in Support/Format.h.
raw_ostream &operator<<(const format_object_base &Fmt);
+ /// indent - Insert 'NumSpaces' spaces.
+ raw_ostream &indent(unsigned NumSpaces);
+
+
/// Changes the foreground color of text that will be output from this point
/// forward.
/// @param colors ANSI color to use, the special SAVEDCOLOR can be used to
@@ -194,6 +240,11 @@ public:
/// outputting colored text, or before program exit.
virtual raw_ostream &resetColor() { return *this; }
+ /// This function determines if this stream is connected to a "tty" or
+ /// "console" window. That is, the output would be displayed to the user
+ /// rather than being put on a pipe or stored in a file.
+ virtual bool is_displayed() const { return false; }
+
//===--------------------------------------------------------------------===//
// Subclass Interface
//===--------------------------------------------------------------------===//
@@ -203,8 +254,15 @@ private:
/// by subclasses. This writes the \args Size bytes starting at
/// \arg Ptr to the underlying stream.
///
+ /// This function is guaranteed to only be called at a point at which it is
+ /// safe for the subclass to install a new buffer via SetBuffer.
+ ///
+ /// \arg Ptr - The start of the data to be written. For buffered streams this
+ /// is guaranteed to be the start of the buffer.
+ /// \arg Size - The number of bytes to be written.
+ ///
/// \invariant { Size > 0 }
- virtual void write_impl(const char *Ptr, unsigned Size) = 0;
+ virtual void write_impl(const char *Ptr, size_t Size) = 0;
// An out of line virtual method to provide a home for the class vtable.
virtual void handle();
@@ -213,14 +271,42 @@ private:
/// counting the bytes currently in the buffer.
virtual uint64_t current_pos() = 0;
+protected:
+ /// SetBuffer - Use the provided buffer as the raw_ostream buffer. This is
+ /// intended for use only by subclasses which can arrange for the output to go
+ /// directly into the desired output buffer, instead of being copied on each
+ /// flush.
+ void SetBuffer(char *BufferStart, size_t Size) {
+ SetBufferAndMode(BufferStart, Size, ExternalBuffer);
+ }
+
+ /// preferred_buffer_size - Return an efficient buffer size for the
+ /// underlying output mechanism.
+ virtual size_t preferred_buffer_size();
+
+ /// error_detected - Set the flag indicating that an output error has
+ /// been encountered.
+ void error_detected() { Error = true; }
+
+ /// getBufferStart - Return the beginning of the current stream buffer, or 0
+ /// if the stream is unbuffered.
+ const char *getBufferStart() const { return OutBufStart; }
+
//===--------------------------------------------------------------------===//
// Private Interface
//===--------------------------------------------------------------------===//
private:
+ /// SetBufferAndMode - Install the given buffer and mode.
+ void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
+
/// flush_nonempty - Flush the current buffer, which is known to be
/// non-empty. This outputs the currently buffered data and resets
/// the buffer to empty.
void flush_nonempty();
+
+ /// copy_to_buffer - Copy data into the buffer. Size must not be
+ /// greater than the number of unused bytes in the buffer.
+ void copy_to_buffer(const char *Ptr, size_t Size);
};
//===----------------------------------------------------------------------===//
@@ -235,23 +321,41 @@ class raw_fd_ostream : public raw_ostream {
uint64_t pos;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, unsigned Size);
+ virtual void write_impl(const char *Ptr, size_t Size);
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
virtual uint64_t current_pos() { return pos; }
+ /// preferred_buffer_size - Determine an efficient buffer size.
+ virtual size_t preferred_buffer_size();
+
public:
- /// raw_fd_ostream - Open the specified file for writing. If an
- /// error occurs, information about the error is put into ErrorInfo,
- /// and the stream should be immediately destroyed; the string will
- /// be empty if no error occurred.
+
+ enum {
+ /// F_Excl - When opening a file, this flag makes raw_fd_ostream
+ /// report an error if the file already exists.
+ F_Excl = 1,
+
+ /// F_Append - When opening a file, if it already exists append to the
+ /// existing file instead of returning an error. This may not be specified
+ /// with F_Excl.
+ F_Append = 2,
+
+ /// F_Binary - The file should be opened in binary mode on platforms that
+ /// make this distinction.
+ F_Binary = 4
+ };
+
+ /// raw_fd_ostream - Open the specified file for writing. If an error occurs,
+ /// information about the error is put into ErrorInfo, and the stream should
+ /// be immediately destroyed; the string will be empty if no error occurred.
+ /// This allows optional flags to control how the file will be opened.
///
/// \param Filename - The file to open. If this is "-" then the
/// stream will use stdout instead.
- /// \param Binary - The file should be opened in binary mode on
- /// platforms that support this distinction.
- raw_fd_ostream(const char *Filename, bool Binary, std::string &ErrorInfo);
+ raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
+ unsigned Flags = 0);
/// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
/// ShouldClose is true, this closes the file when the stream is destroyed.
@@ -264,9 +368,6 @@ public:
/// close - Manually flush the stream and close the file.
void close();
- /// tell - Return the current offset with the file.
- uint64_t tell() { return pos + GetNumBytesInBuffer(); }
-
/// seek - Flushes the stream and repositions the underlying file descriptor
/// positition to the offset specified from the beginning of the file.
uint64_t seek(uint64_t off);
@@ -274,6 +375,8 @@ public:
virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
bool bg=false);
virtual raw_ostream &resetColor();
+
+ virtual bool is_displayed() const;
};
/// raw_stdout_ostream - This is a stream that always prints to stdout.
@@ -302,49 +405,29 @@ raw_ostream &outs();
/// Use it like: errs() << "foo" << "bar";
raw_ostream &errs();
+/// nulls() - This returns a reference to a raw_ostream which simply discards
+/// output.
+raw_ostream &nulls();
//===----------------------------------------------------------------------===//
// Output Stream Adaptors
//===----------------------------------------------------------------------===//
-/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a
-/// simple adaptor class.
-class raw_os_ostream : public raw_ostream {
- std::ostream &OS;
-
- /// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, unsigned Size);
-
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
- virtual uint64_t current_pos();
-
-public:
- raw_os_ostream(std::ostream &O) : OS(O) {}
- ~raw_os_ostream();
-
- /// tell - Return the current offset with the stream.
- uint64_t tell();
-};
-
/// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
-/// simple adaptor class.
+/// simple adaptor class. This class does not encounter output errors.
class raw_string_ostream : public raw_ostream {
std::string &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, unsigned Size);
+ virtual void write_impl(const char *Ptr, size_t Size);
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
virtual uint64_t current_pos() { return OS.size(); }
public:
- raw_string_ostream(std::string &O) : OS(O) {}
+ explicit raw_string_ostream(std::string &O) : OS(O) {}
~raw_string_ostream();
- /// tell - Return the current offset with the stream.
- uint64_t tell() { return OS.size() + GetNumBytesInBuffer(); }
-
/// str - Flushes the stream contents to the target string and returns
/// the string's reference.
std::string& str() {
@@ -354,22 +437,42 @@ public:
};
/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
-/// SmallString. This is a simple adaptor class.
+/// SmallString. This is a simple adaptor class. This class does not
+/// encounter output errors.
class raw_svector_ostream : public raw_ostream {
SmallVectorImpl<char> &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, unsigned Size);
+ virtual void write_impl(const char *Ptr, size_t Size);
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
virtual uint64_t current_pos();
public:
- raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {}
+ /// Construct a new raw_svector_ostream.
+ ///
+ /// \arg O - The vector to write to; this should generally have at least 128
+ /// bytes free to avoid any extraneous memory overhead.
+ explicit raw_svector_ostream(SmallVectorImpl<char> &O);
~raw_svector_ostream();
- /// tell - Return the current offset with the stream.
- uint64_t tell();
+ /// str - Flushes the stream contents to the target vector and return a
+ /// StringRef for the vector contents.
+ StringRef str();
+};
+
+/// raw_null_ostream - A raw_ostream that discards all output.
+class raw_null_ostream : public raw_ostream {
+ /// write_impl - See raw_ostream::write_impl.
+ virtual void write_impl(const char *Ptr, size_t size);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos();
+
+public:
+ explicit raw_null_ostream() {}
+ ~raw_null_ostream();
};
} // end llvm namespace
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index 5000a8b..5f799b8 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -35,7 +35,7 @@ namespace dont_use
// important to make the is_class<T>::value idiom zero cost. it
// evaluates to a constant 1 or 0 depending on whether the
// parameter T is a class or not (respectively).
- template<typename T> char is_class_helper(void(T::*)(void));
+ template<typename T> char is_class_helper(void(T::*)());
template<typename T> double is_class_helper(...);
}
@@ -49,6 +49,44 @@ struct is_class
enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) };
};
+/// \brief Metafunction that determines whether the two given types are
+/// equivalent.
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+// enable_if_c - Enable/disable a template based on a metafunction
+template<bool Cond, typename T = void>
+struct enable_if_c {
+ typedef T type;
+};
+
+template<typename T> struct enable_if_c<false, T> { };
+
+// enable_if - Enable/disable a template based on a metafunction
+template<typename Cond, typename T = void>
+struct enable_if : public enable_if_c<Cond::value, T> { };
+
+namespace dont_use {
+ template<typename Base> char base_of_helper(const volatile Base*);
+ template<typename Base> double base_of_helper(...);
+}
+
+/// is_base_of - Metafunction to determine whether one type is a base class of
+/// (or identical to) another type.
+template<typename Base, typename Derived>
+struct is_base_of {
+ static const bool value
+ = is_class<Base>::value && is_class<Derived>::value &&
+ sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0));
+};
+
}
#endif
OpenPOWER on IntegriCloud