Introducing boost::ptr_vector and boost::ptr_unordered_set.

This is an easy way to increase the uniformity of the API.
This commit is contained in:
Stefano Sanfilippo 2015-03-08 21:03:23 +01:00
parent 19a0c656f2
commit b2e7a11b7a
5 changed files with 69 additions and 76 deletions

View File

@ -254,8 +254,8 @@ bool BitcodeEmitter::emit(Loop const& node) {
d->builder.SetInsertPoint(body); d->builder.SetInsertPoint(body);
d->scope.enter(); d->scope.enter();
for (Statement const* statement: node.getBody()) { for (Statement const& statement: node.getBody()) {
GUARDED(statement->emit(this)); GUARDED(statement.emit(this));
} }
d->scope.leave(); d->scope.leave();
@ -424,8 +424,8 @@ bool BitcodeEmitter::emit(FunctionCall const& node) {
auto param = callee->getArgumentList().begin(); auto param = callee->getArgumentList().begin();
std::vector<llvm::Value*> callargs; std::vector<llvm::Value*> callargs;
for (Expression const* arg: node.getArgs()) { for (Expression const& arg: node.getArgs()) {
GUARDED(arg->emit(this)); GUARDED(arg.emit(this));
callargs.push_back(coerce(d, d->retval, param->getType())); callargs.push_back(coerce(d, d->retval, param->getType()));
++param; ++param;
} }
@ -449,17 +449,17 @@ bool BitcodeEmitter::emit(Branch const& node) {
getGlobalContext(), "endif" getGlobalContext(), "endif"
); );
BranchCase const* last = body.getCases().back(); BranchCase const& last = body.getCases().back();
for (BranchCase const* cas: body.getCases()) { for (BranchCase const& cas: body.getCases()) {
emitSemiExpression(node.getVar(), cas->getCondition()); emitSemiExpression(node.getVar(), cas.getCondition());
d->builder.CreateCondBr( d->builder.CreateCondBr(
isTrue(d->builder, d->retval, "condition"), thenbb, elsebb isTrue(d->builder, d->retval, "condition"), thenbb, elsebb
); );
d->builder.SetInsertPoint(thenbb); d->builder.SetInsertPoint(thenbb);
d->scope.enter(); d->scope.enter();
for (Statement const* statement: cas->getBody()) { for (Statement const& statement: cas.getBody()) {
GUARDED(statement->emit(this)); GUARDED(statement.emit(this));
} }
d->scope.leave(); d->scope.leave();
d->builder.CreateBr(mergebb); d->builder.CreateBr(mergebb);
@ -467,7 +467,7 @@ bool BitcodeEmitter::emit(Branch const& node) {
func->getBasicBlockList().push_back(elsebb); func->getBasicBlockList().push_back(elsebb);
d->builder.SetInsertPoint(elsebb); d->builder.SetInsertPoint(elsebb);
if (cas != last) { if (&cas != &last) {
thenbb = llvm::BasicBlock::Create(getGlobalContext(), "then", func); thenbb = llvm::BasicBlock::Create(getGlobalContext(), "then", func);
elsebb = llvm::BasicBlock::Create(getGlobalContext(), "else"); elsebb = llvm::BasicBlock::Create(getGlobalContext(), "else");
} }
@ -475,8 +475,8 @@ bool BitcodeEmitter::emit(Branch const& node) {
if (body.getElse()) { if (body.getElse()) {
d->scope.enter(); d->scope.enter();
for (Statement const* statement: *body.getElse()) { for (Statement const& statement: *body.getElse()) {
GUARDED(statement->emit(this)); GUARDED(statement.emit(this));
} }
d->scope.leave(); d->scope.leave();
d->builder.CreateBr(mergebb); d->builder.CreateBr(mergebb);
@ -491,13 +491,13 @@ bool BitcodeEmitter::emit(Branch const& node) {
bool BitcodeEmitter::emit(FunctionPrototype const& node) { bool BitcodeEmitter::emit(FunctionPrototype const& node) {
std::vector<llvm::Type*> argTypes; std::vector<llvm::Type*> argTypes;
for (FunArg const* arg: node.getArgs()) { for (FunArg const& arg: node.getArgs()) {
argTypes.emplace_back(LLVMType(arg->getType())); argTypes.emplace_back(LLVMType(arg.getType()));
} }
std::unordered_set<std::string> argsSet; std::unordered_set<std::string> argsSet;
for (FunArg const* arg: node.getArgs()) { for (FunArg const& arg: node.getArgs()) {
std::string const& name = arg->getName().getValue(); std::string const& name = arg.getName().getValue();
if (argsSet.find(name) != argsSet.end()) { if (argsSet.find(name) != argsSet.end()) {
return reportError({ return reportError({
"Two arguments with same name to function", "Two arguments with same name to function",
@ -536,8 +536,8 @@ bool BitcodeEmitter::emit(FunctionPrototype const& node) {
} }
auto argToEmit = func->arg_begin(); auto argToEmit = func->arg_begin();
for (FunArg const* arg: node.getArgs()) { for (FunArg const& arg: node.getArgs()) {
argToEmit->setName(arg->getName().getValue()); argToEmit->setName(arg.getName().getValue());
++argToEmit; ++argToEmit;
} }
@ -558,16 +558,16 @@ bool BitcodeEmitter::emit(Function const& node) {
d->builder.SetInsertPoint(bb); d->builder.SetInsertPoint(bb);
auto argToAlloc = func->arg_begin(); auto argToAlloc = func->arg_begin();
for (FunArg const* arg: node.getPrototype().getArgs()) { for (FunArg const& arg: node.getPrototype().getArgs()) {
llvm::AllocaInst *alloc = allocateVar( llvm::AllocaInst *alloc = allocateVar(
func, arg->getName(), LLVMType(arg->getType()) func, arg.getName(), LLVMType(arg.getType())
); );
d->builder.CreateStore(argToAlloc, alloc); d->builder.CreateStore(argToAlloc, alloc);
d->scope.push(arg->getName().getValue(), alloc); d->scope.push(arg.getName().getValue(), alloc);
} }
for (Statement const* stat: node.getBody()) { for (Statement const& stat: node.getBody()) {
GUARDED(stat->emit(this)); GUARDED(stat.emit(this));
} }
verifyFunction(*func); verifyFunction(*func);
@ -583,12 +583,12 @@ bool BitcodeEmitter::emit(Module const& node) {
bool BitcodeEmitter::emit(Program const& program) { bool BitcodeEmitter::emit(Program const& program) {
auto const& externals = getModuleRegistry().getRegisteredFunctions(); auto const& externals = getModuleRegistry().getRegisteredFunctions();
for (FunctionPrototype const* proto: externals) { for (FunctionPrototype const& proto: externals) {
GUARDED(proto->emit(this)); GUARDED(proto.emit(this));
} }
for (Function const* function: program.getFunctions()) { for (Function const& function: program.getFunctions()) {
GUARDED(function->emit(this)); GUARDED(function.emit(this));
} }
if (program.getMain()) { if (program.getMain()) {

View File

@ -58,8 +58,8 @@ bool CppEmitter::emit(Program const& program) {
stream << "\n"; stream << "\n";
} }
for (Function *function: program.getFunctions()) { for (Function const& function: program.getFunctions()) {
emit(function->getPrototype()); emit(function.getPrototype());
stream << ";\n"; stream << ";\n";
} }
@ -67,8 +67,8 @@ bool CppEmitter::emit(Program const& program) {
stream << "\n"; stream << "\n";
} }
for (Function *function: program.getFunctions()) { for (Function const& function: program.getFunctions()) {
GUARDED(function->emit(this)); GUARDED(function.emit(this));
} }
if (program.getMain()) { if (program.getMain()) {
@ -79,9 +79,9 @@ bool CppEmitter::emit(Program const& program) {
} }
bool CppEmitter::emitStatements(PointerList<Statement> const& node) { bool CppEmitter::emitStatements(PointerList<Statement> const& node) {
for (Statement *s: node) { for (Statement const& s: node) {
emitIndent(); emitIndent();
GUARDED(s->emit(this)); GUARDED(s.emit(this));
stream << STATEMENT_TERMINATOR; stream << STATEMENT_TERMINATOR;
} }
return stream; return stream;
@ -202,10 +202,10 @@ bool CppEmitter::emit(Branch const& branch) {
GUARDED(var.emit(this)); GUARDED(var.emit(this));
if (body.getCases().size() > 0) { if (body.getCases().size() > 0) {
BranchCase *last = body.getCases().back(); BranchCase const& last = body.getCases().back();
for (BranchCase *cas: body.getCases()) { for (BranchCase const& cas: body.getCases()) {
emitBranchCase(*cas); emitBranchCase(cas);
if (cas != last) { if (&cas != &last) {
stream << " else if ("; stream << " else if (";
GUARDED(var.emit(this)); GUARDED(var.emit(this));
} }
@ -236,10 +236,10 @@ bool CppEmitter::emit(Assignment const& assignment) {
bool CppEmitter::emitFunctionArglist(PointerList<Expression> const& args) { bool CppEmitter::emitFunctionArglist(PointerList<Expression> const& args) {
Expression *last = args.back(); Expression const& last = args.back();
for (Expression const* arg: args) { for (Expression const& arg: args) {
GUARDED(arg->emit(this)); GUARDED(arg.emit(this));
if (arg != last) { if (&arg != &last) {
stream << ", "; stream << ", ";
} }
} }
@ -297,12 +297,12 @@ std::ostream& operator<<(std::ostream &stream, Type const& type) {
} }
bool CppEmitter::emitFunctionParams(PointerList<FunArg> const& funargs) { bool CppEmitter::emitFunctionParams(PointerList<FunArg> const& funargs) {
FunArg *last = funargs.back(); FunArg const& last = funargs.back();
for (FunArg const* funarg: funargs) { for (FunArg const& funarg: funargs) {
stream << funarg->getType() << (funarg->isPointer()? "* ": " "); stream << funarg.getType() << (funarg.isPointer()? "* ": " ");
GUARDED(funarg->getName().emit(this)); GUARDED(funarg.getName().emit(this));
if (funarg != last) { if (&funarg != &last) {
stream << ", "; stream << ", ";
} }
} }

View File

@ -18,9 +18,9 @@
*/ */
#include "ModuleRegistry.hpp" #include "ModuleRegistry.hpp"
#include "Pointers.hpp"
#include "Nodes.hpp" #include "Nodes.hpp"
#include <vector>
using namespace monicelli; using namespace monicelli;
@ -31,7 +31,7 @@ ModuleRegistry& monicelli::getModuleRegistry() {
} }
struct ModuleRegistry::Private { struct ModuleRegistry::Private {
PointerList<FunctionPrototype> prototypes; boost::ptr_unordered_set<FunctionPrototype> prototypes;
}; };
ModuleRegistry::ModuleRegistry() { ModuleRegistry::ModuleRegistry() {
@ -42,20 +42,20 @@ ModuleRegistry::~ModuleRegistry() {
delete d; delete d;
} }
PointerList<FunctionPrototype> const& ModuleRegistry::getRegisteredFunctions() const { PointerSet<FunctionPrototype> const& ModuleRegistry::getRegisteredFunctions() const {
return d->prototypes; return d->prototypes;
} }
void ModuleRegistry::registerFunction(FunctionPrototype *proto) { void ModuleRegistry::registerFunction(FunctionPrototype *proto) {
d->prototypes.push_back(proto); d->prototypes.insert(proto);
} }
#define PUT(type, funcname) \ #define PUT(type, funcname) \
new FunctionPrototype { \ new FunctionPrototype { \
new Id {#funcname}, Type::VOID, \ new Id {#funcname}, Type::VOID, \
new PointerList<FunArg> { \ plist({ \
new FunArg {new Id {"value"}, type, false} \ new FunArg {new Id {"value"}, type, false} \
}, \ }), \
} }
#define GET(type, funcname) \ #define GET(type, funcname) \
@ -77,14 +77,15 @@ void monicelli::registerStdLib(ModuleRegistry &r) {
r.registerFunction(GET(Type::INT, __Monicelli_getInt)); r.registerFunction(GET(Type::INT, __Monicelli_getInt));
r.registerFunction(new FunctionPrototype { r.registerFunction(new FunctionPrototype {
new Id("__Monicelli_assert"), Type::VOID, new Id("__Monicelli_assert"), Type::VOID,
new PointerList<FunArg> { plist({
new FunArg {new Id("condition"), Type::CHAR, false} new FunArg {new Id("condition"), Type::CHAR, false}
} })
}); });
r.registerFunction(new FunctionPrototype { r.registerFunction(new FunctionPrototype {
new Id("__Monicelli_abort"), Type::VOID, new Id("__Monicelli_abort"), Type::VOID,
new PointerList<FunArg> {} new PointerList<FunArg> {}
}); });
} }
#undef PUT #undef PUT

View File

@ -32,7 +32,7 @@ public:
ModuleRegistry(ModuleRegistry&) = delete; ModuleRegistry(ModuleRegistry&) = delete;
virtual ~ModuleRegistry(); virtual ~ModuleRegistry();
PointerList<FunctionPrototype> const& getRegisteredFunctions() const; PointerSet<FunctionPrototype> const& getRegisteredFunctions() const;
void registerFunction(FunctionPrototype *proto); void registerFunction(FunctionPrototype *proto);
private: private:

View File

@ -21,33 +21,25 @@
*/ */
#include <memory> #include <memory>
#include <vector> #include <initializer_list>
#include <boost/optional.hpp> #include <boost/ptr_container/ptr_unordered_set.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
namespace monicelli { namespace monicelli {
// We need these instead of an using decl for compatibility template<typename T> using Pointer = std::unique_ptr<T>;
template <class T> template<typename T> using PointerList = boost::ptr_vector<T>;
class Pointer: public std::unique_ptr<T> { template<typename T> using PointerSet = boost::ptr_unordered_set<T>;
public:
Pointer(T *p = nullptr): std::unique_ptr<T>(p) {}
};
template<typename T>
template<class T> PointerList<T>* plist(std::initializer_list<T*> elements) {
class PointerList: public std::vector<T*> { PointerList<T> *result = new PointerList<T>(elements.size());
public: for (T *el: elements) {
using std::vector<T*>::vector; result->push_back(el);
PointerList() {}
PointerList(PointerList&) = delete;
virtual ~PointerList() {
for (T *element: *this) {
delete element;
}
} }
}; return result;
}
} }