Skip to content

Commit

Permalink
Add LLVM 12 support
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexDenisov authored and AlexDenisov committed Jul 1, 2021
1 parent ce7a538 commit 3c3bb19
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: CI macOS

env:
LLVM_RELEASE: "11.0"
LLVM_RELEASE: "12.0"
CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }}

on:
Expand All @@ -18,7 +18,7 @@ jobs:
runs-on: macOS-latest
strategy:
matrix:
LLVM_VERSION: ["6.0", "7.0", "8.0", "9.0", "10.0", "11.0"]
LLVM_VERSION: ["6.0", "7.0", "8.0", "9.0", "10.0", "11.0", "12.0"]

steps:
- uses: actions/checkout@v1
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-ubuntu-20.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI Ubuntu 20.04

env:
DISTR_REPO: "ubuntu/focal"
LLVM_RELEASE: "11.0"
LLVM_RELEASE: "12.0"
CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }}

on:
Expand All @@ -20,7 +20,7 @@ jobs:
container: ubuntu:20.04
strategy:
matrix:
LLVM_VERSION: ["11.0"]
LLVM_VERSION: ["11.0", "12.0"]

steps:
- name: Install software
Expand Down
15 changes: 15 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,21 @@ if (${BUILD_AGAINST_PRECOMPILED_LLVM})
find_package(LLVM REQUIRED CONFIG PATHS ${search_paths} NO_DEFAULT_PATH)
find_package(Clang REQUIRED CONFIG PATHS ${search_paths} NO_DEFAULT_PATH)

if (APPLE)
if (LLVM_VERSION_MAJOR EQUAL 12)
# Precompiled LLVM 12 for macOS contains a hardcoded dependency on a very
# specific version of libcurses:
#
# set_target_properties(LLVMSupport PROPERTIES
# INTERFACE_LINK_LIBRARIES "m;ZLIB::ZLIB;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/lib/libcurses.tbd;LLVMDemangle"
# )
#
# So we are monkey-patching it here
set_target_properties(LLVMSupport PROPERTIES
INTERFACE_LINK_LIBRARIES "z;curses;m;LLVMDemangle")
endif()
endif()

if (TARGET clang)
get_target_property(MULL_CC clang LOCATION)
else()
Expand Down
13 changes: 13 additions & 0 deletions LLVMCompatibility/12.x.x/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set (SOURCES
LLVMCompatibility.cpp
LLVMCompatibility.h
)

add_library(LLVMCompatibility OBJECT ${SOURCES})
set_target_properties(LLVMCompatibility PROPERTIES
COMPILE_FLAGS ${MULL_CXX_FLAGS}
)
target_include_directories(LLVMCompatibility SYSTEM PUBLIC
${LLVM_INCLUDE_DIRS}
)
add_dependencies(LLVMCompatibility ${MULL_LLVM_COMPATIBILITY_LIBRARIES})
54 changes: 54 additions & 0 deletions LLVMCompatibility/12.x.x/LLVMCompatibility.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "LLVMCompatibility.h"

#include <llvm/Bitcode/BitcodeWriter.h>
#include <llvm/Demangle/Demangle.h>
#include <llvm/IR/DebugInfoMetadata.h>
#include <llvm/IR/DebugLoc.h>
#include <llvm/IR/Module.h>
#include <llvm/Object/ObjectFile.h>
#include <llvm/Target/TargetMachine.h>

using namespace llvm;

namespace llvm_compat {

StringRef getSectionContent(const object::SectionRef &section) {
Expected<StringRef> content = section.getContents();
if (!content) {
return {};
}
return content.get();
}

StringRef getSectionName(const object::SectionRef &section) {
Expected<StringRef> name = section.getName();
if (!name) {
return {};
}
return name.get();
}

DICompileUnit *getUnit(const DebugLoc &debugLocation) {
DIScope *scope = debugLocation->getScope();
while (!llvm::isa<llvm::DISubprogram>(scope) && scope != nullptr) {
scope = scope->getScope();
}
return scope ? llvm::cast<llvm::DISubprogram>(scope)->getUnit() : nullptr;
}

std::string demangle(const std::string &MangledName) {
return llvm::demangle(MangledName);
}

llvm::Value *getOrInsertFunction(llvm::Module *module, StringRef name, FunctionType *type) {
return module->getOrInsertFunction(name, type).getCallee();
}

void writeBitcodeToFile(const llvm::Module &module, llvm::raw_fd_ostream &stream) {
llvm::WriteBitcodeToFile(module, stream);
}
bool addPassesToEmitObjectFile(TargetMachine *targetMachine, legacy::PassManagerBase &passManager,
raw_pwrite_stream &out) {
return targetMachine->addPassesToEmitFile(passManager, out, nullptr, llvm::CGFT_ObjectFile);
}
} // namespace llvm_compat
36 changes: 36 additions & 0 deletions LLVMCompatibility/12.x.x/LLVMCompatibility.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <llvm/ADT/StringRef.h>

namespace llvm {

class DICompileUnit;
class DebugLoc;
class TargetMachine;
class FunctionType;
class Value;
class Module;
class raw_pwrite_stream;
class raw_fd_ostream;

namespace object {
class SectionRef;
}

namespace legacy {
class PassManagerBase;
}
} // namespace llvm

namespace llvm_compat {
llvm::StringRef getSectionContent(const llvm::object::SectionRef &section);
llvm::StringRef getSectionName(const llvm::object::SectionRef &section);
llvm::DICompileUnit *getUnit(const llvm::DebugLoc &debugLocation);
std::string demangle(const std::string &MangledName);
llvm::Value *getOrInsertFunction(llvm::Module *module, llvm::StringRef name,
llvm::FunctionType *type);
void writeBitcodeToFile(const llvm::Module &module, llvm::raw_fd_ostream &stream);
bool addPassesToEmitObjectFile(llvm::TargetMachine *targetMachine,
llvm::legacy::PassManagerBase &passManager,
llvm::raw_pwrite_stream &out);
} // namespace llvm_compat
2 changes: 1 addition & 1 deletion docs/HackingOnMull.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ LLVM
----

You need LLVM to build and debug Mull.
You can use any LLVM version between 6.0 and 11.0.
You can use any LLVM version between 6.0 and 12.0.

There are several options:

Expand Down
6 changes: 6 additions & 0 deletions infrastructure/helpers/variables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ SDKROOT: /

llvm_mapping:
macos:
12.0.0:
url: https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-apple-darwin.tar.xz
path: clang+llvm-12.0.0-x86_64-apple-darwin
11.0.0:
url: https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-apple-darwin.tar.xz
path: clang+llvm-11.0.0-x86_64-apple-darwin
Expand All @@ -31,6 +34,9 @@ llvm_mapping:
path: clang+llvm-6.0.0-x86_64-linux-gnu-debian8

ubuntu:
12.0.0:
url: https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz
path: clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-20.04
11.0.0:
url: https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz
path: clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04
Expand Down
25 changes: 11 additions & 14 deletions tests/Helpers/InMemoryCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@

using namespace mull_test;

std::unique_ptr<llvm::Module> InMemoryCompiler::compile(std::string code,
std::string inMemoryFileName,
std::unique_ptr<llvm::Module> InMemoryCompiler::compile(const std::string &code,
const std::string &inMemoryFileName,
llvm::LLVMContext &context) {
/// The following code is based on the following sources:
/// 1. http://blog.audio-tk.com/2018/09/18/compiling-c-code-in-memory-with-clang/
/// 2. https://stackoverflow.com/questions/34828480/generate-assembly-from-c-code-in-memory-using-libclang/34866053#34866053
/// 2.
/// https://stackoverflow.com/questions/34828480/generate-assembly-from-c-code-in-memory-using-libclang/34866053#34866053

llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
Expand All @@ -30,24 +31,18 @@ std::unique_ptr<llvm::Module> InMemoryCompiler::compile(std::string code,
std::vector<const char *> args;
args.push_back(inMemoryFileName.c_str());

/// Prepare DiagnosticEngine
clang::DiagnosticOptions DiagOpts;
std::unique_ptr<clang::TextDiagnosticPrinter> textDiagPrinter(new clang::TextDiagnosticPrinter(llvm::errs(), &DiagOpts));
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs;
std::unique_ptr<clang::DiagnosticsEngine> pDiagnosticsEngine(new clang::DiagnosticsEngine(pDiagIDs, &DiagOpts, textDiagPrinter.get()));

/// Create and initialize CompilerInstance
clang::CompilerInstance clangCompilerInstance;
clangCompilerInstance.createDiagnostics(textDiagPrinter.get(), false);
clangCompilerInstance.createDiagnostics();

/// Initialize CompilerInvocation
clang::CompilerInvocation &compilerInvocation = clangCompilerInstance.getInvocation();
#if LLVM_VERSION_MAJOR > 9
clang::CompilerInvocation::CreateFromArgs(
compilerInvocation, args, *pDiagnosticsEngine.release());
compilerInvocation, args, clangCompilerInstance.getDiagnostics());
#else
clang::CompilerInvocation::CreateFromArgs(
compilerInvocation, &args[0], &args[0] + args.size(), *pDiagnosticsEngine.release());
compilerInvocation, &args[0], &args[0] + args.size(), clangCompilerInstance.getDiagnostics());
#endif
/// Configure options

Expand Down Expand Up @@ -79,12 +74,14 @@ std::unique_ptr<llvm::Module> InMemoryCompiler::compile(std::string code,
std::make_shared<clang::TargetOptions>();
targetOptions->Triple = llvm::sys::getDefaultTargetTriple();
clang::TargetInfo *pTargetInfo =
clang::TargetInfo::CreateTargetInfo(*pDiagnosticsEngine, targetOptions);
clang::TargetInfo::CreateTargetInfo(clangCompilerInstance.getDiagnostics(), targetOptions);
clangCompilerInstance.setTarget(pTargetInfo);

/// Create and execute action
std::unique_ptr<clang::CodeGenAction> compilerAction(new clang::EmitLLVMOnlyAction(&context));
assert(clangCompilerInstance.ExecuteAction(*compilerAction));
bool actionResult = clangCompilerInstance.ExecuteAction(*compilerAction);
(void)actionResult;
assert(actionResult);

/// Obtain LLVM Module
std::unique_ptr<llvm::Module> module = compilerAction->takeModule();
Expand Down
4 changes: 2 additions & 2 deletions tests/Helpers/InMemoryCompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Module;
namespace mull_test {
class InMemoryCompiler {
public:
std::unique_ptr<llvm::Module> compile(std::string code, std::string inMemoryFileName,
llvm::LLVMContext &context);
std::unique_ptr<llvm::Module>
compile(const std::string &code, const std::string &inMemoryFileName, llvm::LLVMContext &context);
};
} // namespace mull_test
68 changes: 52 additions & 16 deletions tools/mull-cxx-frontend/src/ASTNodeFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <clang/AST/ASTContext.h>
#include <clang/AST/Attr.h>
#include <clang/Basic/Specifiers.h>

namespace mull {
namespace cxx {
Expand All @@ -15,18 +16,22 @@ clang::FunctionDecl *ASTNodeFactory::createFunctionDecl(std::string name,
clang::DeclarationName declarationName(&getenvFuncIdentifierInfo);

#if LLVM_VERSION_MAJOR >= 9
return clang::FunctionDecl::Create(
context,
declContext,
NULL_LOCATION,
NULL_LOCATION,
declarationName,
functionType,
context.getTrivialTypeSourceInfo(functionType),
clang::StorageClass::SC_Extern,
false, /// bool isInlineSpecified = false,
true, /// bool hasWrittenPrototype = true,
clang::CSK_unspecified /// ConstexprSpecKind ConstexprKind = CSK_unspecified
return clang::FunctionDecl::Create(context,
declContext,
NULL_LOCATION,
NULL_LOCATION,
declarationName,
functionType,
context.getTrivialTypeSourceInfo(functionType),
clang::StorageClass::SC_Extern,
false, /// bool isInlineSpecified = false,
true, /// bool hasWrittenPrototype = true,
#if LLVM_VERSION_MAJOR >= 12
clang::ConstexprSpecKind::Unspecified
#else
clang::CSK_unspecified /// ConstexprSpecKind ConstexprKind =
/// CSK_unspecified
#endif
);
#else
return clang::FunctionDecl::Create(context,
Expand Down Expand Up @@ -73,7 +78,19 @@ clang::IfStmt *ASTNodeFactory::createIfStmt(clang::Expr *condExpr, clang::Stmt *
clang::Stmt *elseStmt) {
assert(condExpr);
assert(thenStmt);
#if LLVM_VERSION_MAJOR >= 8
#if LLVM_VERSION_MAJOR >= 12
clang::IfStmt *ifStmt = clang::IfStmt::Create(context,
NULL_LOCATION,
false,
nullptr,
nullptr,
condExpr,
NULL_LOCATION,
NULL_LOCATION,
thenStmt,
NULL_LOCATION,
elseStmt);
#elif LLVM_VERSION_MAJOR >= 8
clang::IfStmt *ifStmt = clang::IfStmt::Create(
context, NULL_LOCATION, false, nullptr, nullptr, condExpr, thenStmt, NULL_LOCATION, elseStmt);
#else
Expand All @@ -95,7 +112,17 @@ clang::ImplicitCastExpr *ASTNodeFactory::createImplicitCastExpr(clang::Expr *exp
clang::QualType qualType,
clang::CastKind castKind,
clang::ExprValueKind valueKind) {
return clang::ImplicitCastExpr::Create(context, qualType, castKind, expr, nullptr, valueKind);
return clang::ImplicitCastExpr::Create(context,
qualType,
castKind,
expr,
nullptr,
valueKind
#if LLVM_VERSION_MAJOR >= 12
,
clang::FPOptionsOverride()
#endif
);
}

clang::UnaryOperator *ASTNodeFactory::createUnaryOperator(clang::UnaryOperator::Opcode opcode,
Expand Down Expand Up @@ -193,8 +220,17 @@ clang::CallExpr *ASTNodeFactory::createCallExprSingleArg(clang::Expr *function,
clang::QualType returnType,
clang::ExprValueKind valueKind) {
#if LLVM_VERSION_MAJOR >= 8
clang::CallExpr *callExpr = clang::CallExpr::Create(
context, function, { argument }, returnType, valueKind, NULL_LOCATION);
clang::CallExpr *callExpr = clang::CallExpr::Create(context,
function,
{ argument },
returnType,
valueKind,
NULL_LOCATION
#if LLVM_VERSION_MAJOR >= 12
,
clang::FPOptionsOverride()
#endif
);
#else
clang::CallExpr *callExpr = new (context)
clang::CallExpr(context, function, { argument }, returnType, valueKind, NULL_LOCATION);
Expand Down
Loading

0 comments on commit 3c3bb19

Please sign in to comment.