0

Whenever I use pointers I get linker errors for my type.cpp. When I wasn't using pointers it compiled just fine.

type.h

#pragma once
#include "context.h"
#include <string>
#include <vector>
#include <memory>



template<typename T>
class Clone {
  public:
  T* clone_trait() const {
    T const * t = static_cast<const T*>(this);
    return const_cast<T*>(t);
  }
};


class TypePtr;
struct  IntegralType;
class Type : public Clone<Type> {
public:
  Type(const std::string &name, TypeKind tk,const unsigned int size);



  virtual Type* clone() const =0;
  virtual ~Type();
};

class TypePtr {
  public:
  TypePtr(Type* t);
  TypePtr(const TypePtr&);
  TypePtr(const TypePtr&&);
  TypePtr()=default;
  TypePtr operator=(const TypePtr&);
  Type operator*();
  Type* operator->() const;
  explicit operator bool() const;
  ~TypePtr();
  private:
  Type* t{nullptr};
};

struct IntegralType : Type {
  IntegralType(const std::string &name, Ty ty, const unsigned int size);
  llvm::Type *codegen(FusionCtx &ctx) override;
  Type* clone() const override;
};

struct StructType : Type {
  std::vector<TypedValue> members;
  StructType(const std::string &name, const std::vector<TypedValue> &members);
  llvm::Type *codegen(FusionCtx &ctx) override;
};

type.cpp

#include "type.h"
#include "error.h"



TypePtr::TypePtr(Type* t) : t(t){};
TypePtr::TypePtr(const TypePtr& o) {
  t = o.t->clone_trait();
}
TypePtr::TypePtr(const TypePtr&& o){
  t=o.t;
}

TypePtr TypePtr::operator=(const TypePtr& o){
  t=o.t->clone_trait();
}

TypePtr::~TypePtr() {
  delete t;
}
TypePtr::operator bool() const {
  return t ? true : false;
}

Type::Type(const std::string &name, TypeKind tk,const unsigned int size)
    : name(name), tk(tk), size(size) {
}





llvm::Type *IntegralType::codegen(FusionCtx &ctx) {
Type* IntegralType::clone() const {
  return new IntegralType(*this);
}

I get the following error:

/usr/bin/ld: CMakeFiles/fs.dir/src/codegen.cpp.o: in function `FnProto::codegen(FusionCtx&)':
codegen.cpp:(.text+0x383): undefined reference to `TypePtr::operator->() const'
/usr/bin/ld: CMakeFiles/fs.dir/src/codegen.cpp.o: in function `TypeExpr::codegen(FusionCtx&)':
codegen.cpp:(.text+0xdde): undefined reference to `TypePtr::operator->() const'
/usr/bin/ld: CMakeFiles/fs.dir/src/codegen.cpp.o: in function `VarDeclExpr::codegen(FusionCtx&)':
codegen.cpp:(.text+0x1bcd): undefined reference to `TypePtr::operator->() const'
/usr/bin/ld: CMakeFiles/fs.dir/src/lex.cpp.o: in function `Lexer::stringlit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
lex.cpp:(.text+0xad2): undefined reference to `TypePtr::operator->() const'
/usr/bin/ld: CMakeFiles/fs.dir/src/parser.cpp.o: in function `Parser::parse_type_expr()':
parser.cpp:(.text+0x3403): undefined reference to `TypePtr::operator->() const'
/usr/bin/ld: CMakeFiles/fs.dir/src/parser.cpp.o:parser.cpp:(.text+0x34c8): more undefined references to `TypePtr::operator->() const' follow
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `Type::Type(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Type::TypeKind, unsigned int)':
type.cpp:(.text+0x14b): undefined reference to `vtable for Type'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `Type::getI8()':
type.cpp:(.text+0x4b9): undefined reference to `IntegralType::IntegralType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, IntegralType::Ty, unsigned int)'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `Type::getI16()':
type.cpp:(.text+0x5dc): undefined reference to `IntegralType::IntegralType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, IntegralType::Ty, unsigned int)'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `Type::getI32()':
type.cpp:(.text+0x6fc): undefined reference to `IntegralType::IntegralType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, IntegralType::Ty, unsigned int)'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `Type::getI64()':
type.cpp:(.text+0x81c): undefined reference to `IntegralType::IntegralType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, IntegralType::Ty, unsigned int)'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `Type::getISize()':
type.cpp:(.text+0x93b): undefined reference to `IntegralType::IntegralType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, IntegralType::Ty, unsigned int)'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o:type.cpp:(.text+0xa5c): more undefined references to `IntegralType::IntegralType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, IntegralType::Ty, unsigned int)' follow
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `IntegralType::~IntegralType()':
type.cpp:(.text._ZN12IntegralTypeD2Ev[_ZN12IntegralTypeD2Ev]+0x14): undefined reference to `Type::~Type()'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `StructType::~StructType()':
type.cpp:(.text._ZN10StructTypeD2Ev[_ZN10StructTypeD2Ev]+0x3d): undefined reference to `Type::~Type()'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o: in function `Type::Type(Type const&)':
type.cpp:(.text._ZN4TypeC2ERKS_[_ZN4TypeC2ERKS_]+0xb): undefined reference to `vtable for Type'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o:(.data.rel.ro+0x40): undefined reference to `typeinfo for Type'
/usr/bin/ld: CMakeFiles/fs.dir/src/type.cpp.o:(.data.rel.ro+0x88): undefined reference to `typeinfo for Type'
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)

If I change the clone_trait() to clone() in TypePtr I get the same error, when I use unique_ptr insted of TypePtr I get the same error. What should I do?

  • 1
    You declared a `TypePtr::operator->() const;` but I cannot find the definition. I suppose similar for the others. Please try to reduce your code to a [mcve] – 463035818_is_not_an_ai Jun 08 '20 at 10:01
  • Not related to your question, but are you aware that the implementation of your `clone_trait() const` of the `Clone` class is a really bad idea? `clone_trait` can be called on any const instance of `Clone`, and `const_cast(t)` just casts that constness away returning the pointer to the same object, and potentially resulting in undefined behavior. And it does not do any cloning at all. – t.niese Jun 08 '20 at 11:39

0 Answers0