Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F4819321
typeinference.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Aug 24, 2:30 AM
Size
3 KB
Mime Type
text/x-c++
Expires
Wed, Aug 26, 2:30 AM (12 h, 40 m)
Engine
blob
Format
Raw Data
Handle
286564
Attached To
rXR Xreate
typeinference.cpp
View Options
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* typeinference.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on April 16, 2017, 10:13 AM
*/
/**
* \file typeinference.h
* \brief Type inference analysis
*/
#include "typeinference.h"
#include "llvmlayer.h"
#include "transcendlayer.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/DerivedTypes.h"
using namespace std;
namespace xreate{
namespace typeinference{
//TODO type conversion:
//a) automatically expand types int -> bigger int; int -> floating
//b) detect exact type of `num` based on max used numeral / function type
//c) warning if need to truncate (allow/dissallow based on annotations)
llvm::Value*
doAutomaticTypeConversion(llvm::Value* source, llvm::Type* tyTarget, llvm::IRBuilder<>& builder) {
if(tyTarget->isIntegerTy() && source->getType()->isIntegerTy()) {
llvm::IntegerType* tyTargetInt = llvm::dyn_cast<llvm::IntegerType>(tyTarget);
llvm::IntegerType* tySourceInt = llvm::dyn_cast<llvm::IntegerType>(source->getType());
if(tyTargetInt->getBitWidth() < tySourceInt->getBitWidth()) {
return builder.CreateCast(llvm::Instruction::Trunc, source, tyTarget);
}
if(tyTargetInt->getBitWidth() > tySourceInt->getBitWidth()) {
return builder.CreateCast(llvm::Instruction::SExt, source, tyTarget);
}
}
if(source->getType()->isIntegerTy() && tyTarget->isFloatingPointTy()) {
return builder.CreateCast(llvm::Instruction::SIToFP, source, tyTarget);
}
if (source->getType()->isStructTy() && tyTarget->isIntegerTy()){
llvm::StructType* sourceST = llvm::cast<llvm::StructType>(source->getType());
if(sourceST->getNumElements() == 1) {
llvm::Value* sourceElRaw = builder.CreateExtractValue(source, llvm::ArrayRef<unsigned>({0}));
return doAutomaticTypeConversion(sourceElRaw, tyTarget, builder);
}
}
return source;
}
/**
* \brief Performs basic type inference to deduce the type of the given expression
*
* Tries several strategies in the following order:
* - Looks at expression's type if it has one.
* - Looks at Attachment<TypeInferred> if it has one. This allows assign expression's type by analyses done elsewhere.
* - For a number literal assumes i32.
*
* \param expression Infers the given expression's type.
* \param ast AST instance.
*/
ExpandedType
getType(const Expression& expression, const AST& ast) {
if(expression.type.isValid()) {
return ast.expandType(expression.type);
}
if(expression.__state == Expression::IDENT) {
Symbol s = Attachments::get<IdentifierSymbol>(expression);
return getType(CodeScope::getDefinition(s), ast);
}
if(Attachments::exists<TypeInferred>(expression)) {
return Attachments::get<TypeInferred>(expression);
}
if(expression.__state == Expression::NUMBER) {
return ExpandedType(TypeAnnotation(TypePrimitive::I32));
}
assert(false && "Type can't be determined for an expression");
}
}
} //end of namespace xreate::typeinference
Event Timeline
Log In to Comment