Exemple #1
0
		size_t getLvalCount(const SEM::Type* type) {
			type = getDerefType(type);
			
			size_t count = 0;
			while (type->isLval()) {
				count++;
				type = getDerefType(type->lvalTarget());
			}
			return count;
		}
Exemple #2
0
		AST::Value CallValue(Context& context, AST::Value rawValue, HeapArray<AST::Value> args, const Debug::SourceLocation& location) {
			auto value = derefValue(std::move(rawValue));
			
			if (getDerefType(value.type())->isTypename()) {
				return CallValue(context, GetStaticMethod(context, std::move(value), context.getCString("create"), location), std::move(args), location);
			}
			
			if (!value.type()->isCallable()) {
				// Try to use 'call' method.
				if (TypeCapabilities(context).hasCallMethod(getDerefType(value.type()))) {
					return CallValue(context, GetMethod(context, std::move(value),
					                                    context.getCString("call"), location),
					                 std::move(args), location);
				} else {
					context.issueDiag(TypeNotCallableDiag(getDerefType(value.type())),
					                  location);
					return AST::Value::Constant(Constant::Integer(0), context.typeBuilder().getIntType());
				}
			}
			
			const auto functionType = value.type()->asFunctionType();
			const auto& typeList = functionType.parameterTypes();
			
			if (functionType.attributes().isVarArg()) {
				if (args.size() < typeList.size()) {
					context.issueDiag(VarArgTooFewArgsDiag(value.toDiagString(),
					                                       args.size(), typeList.size()),
					                  location);
				}
			} else {
				if (args.size() != typeList.size()) {
					context.issueDiag(CallIncorrectArgCountDiag(value.toDiagString(),
					                                            args.size(), typeList.size()),
					                  location);
				}
			}
			
			if (!TypeCapabilities(context).isSized(functionType.returnType())) {
				// TODO: also check that the type is not abstract.
				context.issueDiag(CallReturnTypeIsUnsizedDiag(functionType.returnType()),
				                  location);
			}
			
			if (functionType.returnType()->hasConst()) {
				context.issueDiag(CallReturnTypeIsConstDiag(functionType.returnType()),
						  location);
			}
			
			return addDebugInfo(AST::Value::Call(std::move(value), CastFunctionArguments(context, std::move(args), typeList, location),
							     functionType.returnType()->stripConst()), location);
		}
Exemple #3
0
		const SEM::Type* makeLvalType(Context& context, const bool isFinal, const SEM::Type* const valueType) {
			if (getDerefType(valueType)->isLval()) {
				return valueType;
			}
			
			if (isFinal) {
				return makeFinalLvalType(context, valueType);
			} else {
				return makeValueLvalType(context, valueType);
			}
		}
Exemple #4
0
		SEM::Value GetTemplatedMethod(Context& context, SEM::Value rawValue, const String& methodName, SEM::ValueArray templateArguments, const Debug::SourceLocation& location) {
			auto value = derefOrBindValue(context, tryDissolveValue(context, derefOrBindValue(context, std::move(rawValue)), location));
			const auto type = getDerefType(value.type())->resolveAliases();
			return GetTemplatedMethodWithoutResolution(context, std::move(value), type, methodName, std::move(templateArguments), location);
		}