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

View File

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

View File

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

View File

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

View File

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