Exemplo n.º 1
0
void LLJIT::recordCtorDtors(Module &M) {
  CtorRunner.add(getConstructors(M));
  DtorRunner.add(getDestructors(M));
}
Exemplo n.º 2
0
	/// TODO: add trivial marker for tagtypes
	bool isTrivial(const TypePtr& type) {
		auto ttype = type.isa<TagTypePtr>();
		if(!ttype) {
			if (core::lang::isArray(type)) {
				// in case of an array, check the enclosed type for triviality
				return isTrivial(core::lang::ArrayType(type).getElementType());
			}
			// non-tag-type & non-array types are always trivial
			return true;
		}

		auto record = ttype->getRecord();

		IRBuilder builder(type->getNodeManager());

		auto containsCtor = [&](const LambdaExprPtr& ctor)->bool {
			return any(record->getConstructors(), [&](const ExpressionPtr& cur) {
				return *builder.normalize(cur) == *builder.normalize(ctor);
			});
		};

		auto containsMemberFunction = [&](const MemberFunctionPtr& member)->bool {
			return any(record->getMemberFunctions(), [&](const MemberFunctionPtr& cur) {
				return *builder.normalize(cur) == *builder.normalize(member);
			});
		};

		auto thisType = builder.refType(builder.tagTypeReference(record->getName()));

		ParentsPtr parents =
				(record.isa<StructPtr>()) ?
				record.as<StructPtr>()->getParents() :
				builder.parents();

		// check for trivial constructors
		bool trivialDefaultConstructor = containsCtor(builder.getDefaultConstructor(thisType, parents, record->getFields()));
		if (!trivialDefaultConstructor) return false;

		bool trivialCopyConstructor = containsCtor(builder.getDefaultCopyConstructor(thisType, parents, record->getFields()));
		if (!trivialCopyConstructor) return false;

		bool trivialMoveConstructor = containsCtor(builder.getDefaultMoveConstructor(thisType, parents, record->getFields()));
		if (!trivialMoveConstructor) return false;


		// check for trivial copy and move assignments
		bool trivialCopyAssignment = containsMemberFunction(builder.getDefaultCopyAssignOperator(thisType, parents, record->getFields()));
		if (!trivialCopyAssignment) return false;

		bool trivialMoveAssignment = containsMemberFunction(builder.getDefaultMoveAssignOperator(thisType, parents, record->getFields()));
		if (!trivialMoveAssignment) return false;

		// check for trivial, non-virtual destructor
		if(record->getDestructor().as<LambdaExprPtr>()->getBody().size() != 0 || record->getDestructorVirtual().getValue()) return false;

		// check for virtual member functions
		for(auto memFun : record->getMemberFunctions()) {
			if(memFun->getVirtualFlag().getValue()) return false;
		}

		if(!record->getPureVirtualMemberFunctions().empty()) return false;

		// check for virtual & non-trivial base classes
		if(ttype->isStruct()) {
			auto stype = ttype->getStruct();
			for(auto par : stype->getParents()) {
				if(par->getVirtual().getValue()) return false;
				// if our direct base class is non-trivial, we cannot be trivial per-se
				if(!isTrivial(par->getType())) return false;
			}
		}

		// check that all non-static members are trivial
		for(auto field : record->getFields()) {
			auto fieldType = field->getType();
			if(!isTrivial(fieldType)) return false;
			//check cpp_ref field types
			if(analysis::isRefType(fieldType) && lang::isCppReference(fieldType)) {
				//TODO this is an over approximation which has to be refined
				return false;
			}
		}

		return true;
	}