Skip to content

Commit

Permalink
0.6 Compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno committed Feb 4, 2017
1 parent 0ad2a18 commit d15557b
Show file tree
Hide file tree
Showing 14 changed files with 193 additions and 140 deletions.
2 changes: 1 addition & 1 deletion deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ println("Tuning for julia installation at $BASE_JULIA_BIN with sources possibly
llvm_path = is_apple() ? "libLLVM" : "libLLVM-$(Base.libllvm_version)"

llvm_lib_path = Libdl.dlpath(llvm_path)
old_cxx_abi = searchindex(open(read, llvm_lib_path),"_ZN4llvm3sys16getProcessTripleEv".data,0) != 0
old_cxx_abi = searchindex(open(read, llvm_lib_path),Vector{UInt8}("_ZN4llvm3sys16getProcessTripleEv"),0) != 0
old_cxx_abi && (ENV["OLD_CXX_ABI"] = "1")

llvm_config_path = joinpath(BASE_JULIA_BIN,"..","tools","llvm-config")
Expand Down
3 changes: 3 additions & 0 deletions src/Cxx.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ include(pathfile)
using Base.Meta
using Core: svec

import Compat
using Compat.TypeUtils

export cast,
@cxx_str, @cxx_mstr, @icxx_str, @icxx_mstr, @cxxt_str,
@cxx, @cxxnew, @jpcpp_str, @exception, @cxxm,
Expand Down
2 changes: 1 addition & 1 deletion src/CxxREPL/replpane.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ module CxxREPL
end

function isTopLevelExpression(C,data)
@assert data[end] == '\0'
@assert Int(data[end]) == 0
if contains(data,":=")
return false
end
Expand Down
17 changes: 10 additions & 7 deletions src/bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,8 @@ static Function *CloneFunctionAndAdjust(C, Function *F, FunctionType *FTy,
const clang::CodeGen::CGFunctionInfo &FI,
clang::FunctionDecl *FD,
bool specsig, bool firstIsEnv,
bool *needsbox, void **juliatypes) {
bool *needsbox, void *jl_retty,
void **juliatypes) {
std::vector<Type*> ArgTypes;
llvm::ValueToValueMapTy VMap;

Expand Down Expand Up @@ -686,8 +687,10 @@ static Function *CloneFunctionAndAdjust(C, Function *F, FunctionType *FTy,

Cxx->CGF->Builder.SetInsertPoint(builder.GetInsertBlock(),
builder.GetInsertPoint());
if (Call->getType()->isPointerTy() &&
cast<PointerType>(Call->getType())->getElementType()->isAggregateType()) {
bool isboxed = false;
Type *retty = f_julia_type_to_llvm(jl_retty, &isboxed);
if (isboxed || (Call->getType()->isPointerTy() &&
cast<PointerType>(Call->getType())->getElementType()->isAggregateType())) {
Cxx->CGF->EmitAggregateCopy(Cxx->CGF->ReturnValue,
#ifdef LLVM38
clang::CodeGen::Address(Call,clang::CharUnits::fromQuantity(sizeof(void*))),
Expand Down Expand Up @@ -803,7 +806,7 @@ JL_DLLEXPORT void *DeleteUnusedArguments(llvm::Function *F, uint64_t *dtodelete,
}


JL_DLLEXPORT void ReplaceFunctionForDecl(C,clang::FunctionDecl *D, llvm::Function *F, bool DoInline, bool specsig, bool firstIsEnv, bool *needsbox, void **juliatypes)
JL_DLLEXPORT void ReplaceFunctionForDecl(C,clang::FunctionDecl *D, llvm::Function *F, bool DoInline, bool specsig, bool firstIsEnv, bool *needsbox, void *retty, void **juliatypes)
{
const clang::CodeGen::CGFunctionInfo &FI = Cxx->CGM->getTypes().arrangeGlobalDeclaration(D);
llvm::FunctionType *Ty = Cxx->CGM->getTypes().GetFunctionType(FI);
Expand All @@ -815,7 +818,7 @@ JL_DLLEXPORT void ReplaceFunctionForDecl(C,clang::FunctionDecl *D, llvm::Functio
llvm::ValueToValueMapTy VMap;
llvm::ClonedCodeInfo CCI;

llvm::Function *NF = CloneFunctionAndAdjust(Cxx,F,Ty,true,&CCI,FI,D,specsig,firstIsEnv,needsbox,juliatypes);
llvm::Function *NF = CloneFunctionAndAdjust(Cxx,F,Ty,true,&CCI,FI,D,specsig,firstIsEnv,needsbox,retty,juliatypes);
// TODO: Ideally we would delete the cloned function
// once we're done with the inlineing, but clang delays
// emitting some functions (e.g. constructors) until
Expand Down Expand Up @@ -1316,8 +1319,8 @@ static void set_default_clang_options(C, bool CCompiler, const char *Triple, con
Cxx->CI->getLangOpts().CPlusPlus = 1;
Cxx->CI->getLangOpts().CPlusPlus11 = 1;
Cxx->CI->getLangOpts().CPlusPlus14 = 1;
Cxx->CI->getLangOpts().RTTI = 0;
Cxx->CI->getLangOpts().RTTIData = 0;
Cxx->CI->getLangOpts().RTTI = 1;
Cxx->CI->getLangOpts().RTTIData = 1;
Cxx->CI->getLangOpts().Exceptions = 1; // exception handling
Cxx->CI->getLangOpts().ObjCExceptions = 1; // Objective-C exceptions
Cxx->CI->getLangOpts().CXXExceptions = 1; // C++ exceptions
Expand Down
11 changes: 6 additions & 5 deletions src/clangwrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,12 @@ AddDeclToDeclCtx(DC::pcpp"clang::DeclContext",D::pcpp"clang::Decl") =
ccall((:AddDeclToDeclCtx,libcxxffi),Void,(Ptr{Void},Ptr{Void}),DC,D)

function ReplaceFunctionForDecl(C,sv::pcpp"clang::FunctionDecl",f::pcpp"llvm::Function";
DoInline = true, specsig = false, FirstIsEnv = false, NeedsBoxed = C_NULL, jts = C_NULL)
DoInline = true, specsig = false, FirstIsEnv = false, NeedsBoxed = C_NULL,
retty = Any, jts = C_NULL)
@assert sv != C_NULL
ccall((:ReplaceFunctionForDecl,libcxxffi),Void,
(Ptr{ClangCompiler},Ptr{Void},Ptr{Void},Bool,Bool,Bool,Ptr{Bool},Ptr{Void}),
&C,sv,f,DoInline,specsig,FirstIsEnv,NeedsBoxed,jts)
(Ptr{ClangCompiler},Ptr{Void},Ptr{Void},Bool,Bool,Bool,Ptr{Bool},Any,Ptr{Void}),
&C,sv,f,DoInline,specsig,FirstIsEnv,NeedsBoxed,retty,jts)
end

function ReplaceFunctionForDecl(C,sv::pcpp"clang::CXXMethodDecl",f::pcpp"llvm::Function"; kwargs...)
Expand Down Expand Up @@ -535,7 +536,7 @@ CreateFunctionTemplateDecl(C, DC::pcpp"clang::DeclContext", Params, FD) =
function getSpecializations(FTD::pcpp"clang::FunctionTemplateDecl")
v = ccall((:newFDVector,libcxxffi),Ptr{Void},())
ccall((:getSpecializations,libcxxffi),Void,(Ptr{Void},Ptr{Void}),FTD,v)
ret = Array(pcpp"clang::FunctionDecl",ccall((:getFDVectorSize,libcxxffi),Csize_t,(Ptr{Void},),v))
ret = Array{pcpp"clang::FunctionDecl"}(ccall((:getFDVectorSize,libcxxffi),Csize_t,(Ptr{Void},),v))
ccall((:copyFDVector,libcxxffi),Void,(Ptr{Void},Ptr{Void}),ret,v);
ccall((:deleteFDVector,libcxxffi),Void,(Ptr{Void},),v)
ret
Expand Down Expand Up @@ -678,7 +679,7 @@ getParent(CxxMD::pcpp"clang::CXXMethodDecl") = pcpp"clang::CXXRecordDecl"(ccall(
decouple_pch(C) = ccall((:decouple_pch,libcxxffi),Void,(Ptr{ClangCompiler},),&C)

function ParseParameterList(C,nparams)
params = Array(Ptr{Void},nparams)
params = Array{Ptr{Void}}(nparams)
ccall((:ParseParameterList,Cxx.libcxxffi),Void,
(Ptr{Cxx.ClangCompiler},Ptr{Void},Csize_t),&C,params,length(params))
[pcpp"clang::ParmVarDecl"(p) for p in params]
Expand Down
144 changes: 72 additions & 72 deletions src/codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ end
#
# Returns the list of processed arguments
function llvmargs(C, builder, f, argt)
args = Array(pcpp"llvm::Value", length(argt))
args = Array{pcpp"llvm::Value"}(length(argt))
for i in 1:length(argt)
t = argt[i]
args[i] = pcpp"llvm::Value"(ccall(
Expand All @@ -373,7 +373,8 @@ function llvmargs(C, builder, f, argt)
args
end

cxxtransform(T,ex) = (T,ex)
cxxtransform(T,ex) = (T, ex)
cxxtransform(::Type{String},ex) = (Ptr{UInt8},:(pointer($ex)))

function buildargexprs(C, argt; derefval = true)
callargs = pcpp"clang::Expr"[]
Expand Down Expand Up @@ -439,74 +440,6 @@ function check_args(argt,f)
end
end


#
# Code generation for value references (basically everything that's not a call).
# Syntactically, these are of the form
#
# - @cxx foo
# - @cxx foo::bar
# - @cxx foo->bar
#

# Handle member references, i.e. syntax of the form `@cxx foo->bar`
@generated function cxxmemref(CT::CxxInstance, expr, args...)
C = instance(CT)
this = args[1]
check_args([this], expr)
isaddrof = false
if expr <: CppAddr
expr = expr.parameters[1]
isaddrof = true
end
exprs, pvds = buildargexprs(C,[this])
me = BuildMemberReference(C, exprs[1], cpptype(C, this), this <: CppPtr,
expr.parameters[1])
isaddrof && (me = CreateAddrOfExpr(C,me))
emitRefExpr(C, me, pvds[1], this)
end

# Handle all other references. This is more complicated than the above for two
# reasons.
# a) We can reference types (e.g. `@cxx int`)
# b) Clang cares about how the reference was qualified, so we need to deal with
# cxxscopes.
@generated function cxxref(CT,expr)
C = instance(CT)
isaddrof = false
if expr <: CppAddr
expr = expr.parameters[1]
isaddrof = true
end

cxxscope = newCXXScopeSpec(C)
d = declfornns(C,expr,cxxscope)
@assert d != C_NULL

# If this is a typedef or something we'll try to get the primary one
primary_decl = to_decl(primary_ctx(toctx(d)))
if primary_decl != C_NULL
d = primary_decl
end

if isaValueDecl(d)
expr = dre = CreateDeclRefExpr(C, d;
islvalue = isaVarDecl(d) ||
(isaFunctionDecl(d) && !isaCXXMethodDecl(d)),
cxxscope=cxxscope)

deleteCXXScopeSpec(cxxscope)

if isaddrof
expr = CreateAddrOfExpr(C,dre)
end

return emitRefExpr(C, expr)
else
return :( $(juliatype(QualType(typeForDecl(d)))) )
end
end

function emitRefExpr(C, expr, pvd = nothing, ct = nothing)
# Ask clang what the type is we're expecting
rt = BuildDecltypeType(C,expr)
Expand Down Expand Up @@ -688,10 +621,10 @@ end
function EmitExpr(C,ce,nE,ctce, argt, pvds, rett = Void; kwargs...)
builder = irbuilder(C)
argt = Type[argt...]
map!(argt) do x
map!(argt, argt) do x
(isCxxEquivalentType(x) || x <: CxxBuiltinTs) ? x : Ref{x}
end
llvmargt = [argt...]
llvmargt = Type[argt...]
issret = false
rslot = C_NULL
rt = C_NULL
Expand Down Expand Up @@ -825,6 +758,73 @@ function createReturn(C,builder,f,argt,llvmargt,llvmrt,rett,rt,ret,state; argidx
end
end

#
# Code generation for value references (basically everything that's not a call).
# Syntactically, these are of the form
#
# - @cxx foo
# - @cxx foo::bar
# - @cxx foo->bar
#

# Handle member references, i.e. syntax of the form `@cxx foo->bar`
@generated function cxxmemref(CT::CxxInstance, expr, args...)
C = instance(CT)
this = args[1]
check_args([this], expr)
isaddrof = false
if expr <: CppAddr
expr = expr.parameters[1]
isaddrof = true
end
exprs, pvds = buildargexprs(C,[this])
me = BuildMemberReference(C, exprs[1], cpptype(C, this), this <: CppPtr,
expr.parameters[1])
isaddrof && (me = CreateAddrOfExpr(C,me))
emitRefExpr(C, me, pvds[1], this)
end

# Handle all other references. This is more complicated than the above for two
# reasons.
# a) We can reference types (e.g. `@cxx int`)
# b) Clang cares about how the reference was qualified, so we need to deal with
# cxxscopes.
@generated function cxxref(CT,expr)
C = instance(CT)
isaddrof = false
if expr <: CppAddr
expr = expr.parameters[1]
isaddrof = true
end

cxxscope = newCXXScopeSpec(C)
d = declfornns(C,expr,cxxscope)
@assert d != C_NULL

# If this is a typedef or something we'll try to get the primary one
primary_decl = to_decl(primary_ctx(toctx(d)))
if primary_decl != C_NULL
d = primary_decl
end

if isaValueDecl(d)
expr = dre = CreateDeclRefExpr(C, d;
islvalue = isaVarDecl(d) ||
(isaFunctionDecl(d) && !isaCXXMethodDecl(d)),
cxxscope=cxxscope)

deleteCXXScopeSpec(cxxscope)

if isaddrof
expr = CreateAddrOfExpr(C,dre)
end

return emitRefExpr(C, expr)
else
return :( $(juliatype(QualType(typeForDecl(d)))) )
end
end

# And finally the staged functions to drive the call logic above
@generated function cppcall(CT::CxxInstance, expr, args...)
_cppcall(CT, expr, false, false, args)
Expand Down
5 changes: 3 additions & 2 deletions src/cxxmacro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ function get_llvmf_for_FD(C,jf,FD)
TT = Tuple{typeof(jf), map(x->x[2],extract_params(C,FD))...}
needsboxed = Bool[!isbits(x) for x in TT.parameters]
specsig = length(needsboxed) == 0 || !reduce(&,needsboxed)
f = pcpp"llvm::Function"(ccall(:jl_get_llvmf, Ptr{Void}, (Any,Bool,Bool), TT, false,true))
f = get_llvmf_decl(TT)
@assert f != C_NULL
needsboxed, specsig, Tuple{TT.parameters[2:end]...}, f
end
Expand All @@ -234,6 +234,7 @@ macro cxxm(str,expr)
NeedsBoxed, specsig, TT, llvmf = Cxx.get_llvmf_for_FD(Cxx.instance(__current_compiler__),$f,$FD)
Cxx.ReplaceFunctionForDecl(Cxx.instance(__current_compiler__),
$FD,llvmf,
DoInline = false, specsig = specsig, NeedsBoxed = NeedsBoxed, jts = Any[TT.parameters...])
DoInline = false, specsig = specsig, NeedsBoxed = NeedsBoxed,
retty = $RT, jts = Any[TT.parameters...])
end)
end
Loading

0 comments on commit d15557b

Please sign in to comment.