Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
Move LLVM FileCheck interface to slang-llvm (#64)
Browse files Browse the repository at this point in the history
* Move LLVM FileCheck interface to slang-llvm

* Add missing 'override'

* Emit --end-group to match --start-group linker option

* Bump ubuntu version in github actions to 20.04

* Remove use of CharSlice in FileCheck

* Make createLLVMFileCheck_V1 return a void* rather than specifically an IFileCheck
  • Loading branch information
expipiplus1 authored Apr 7, 2023
1 parent 7586799 commit 36a237a
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 24 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
branches: [ master ]

jobs:
build:
name: Linux Build CI
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04

strategy:
matrix:
# Might want debug once release works
configuration: ['release'] # , 'debug']
steps:

steps:
- uses: actions/checkout@v3
with:
submodules: 'true'
Expand All @@ -27,7 +27,7 @@ jobs:
run: |
PREMAKE=external/slang-binaries/premake/premake-5.0.0-alpha16/bin/linux-64/premake5
chmod u+x ${PREMAKE}
${PREMAKE} gmake --deps=true --no-progress=true
${PREMAKE} gmake --deps=true --no-progress=true
- name: Build
run: |
Expand Down
24 changes: 12 additions & 12 deletions .github/workflows/release-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ on:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

jobs:
build:
name: Upload Asset - Linux
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
# runs-on: ubuntu-latest
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04

strategy:
matrix:
# Might want debug once release works
configuration: ['release'] # , 'debug']
steps:

steps:
- uses: actions/checkout@v3
with:
submodules: 'true'
Expand All @@ -28,31 +28,31 @@ jobs:
run: |
PREMAKE=external/slang-binaries/premake/premake-5.0.0-alpha16/bin/linux-64/premake5
chmod u+x ${PREMAKE}
${PREMAKE} gmake --deps=true --no-progress=true
${PREMAKE} gmake --deps=true --no-progress=true
- name: Build
run: |
make config=${{matrix.configuration}}_x64 -j`nproc`
- name: archive
id: archive
run: |
echo "achiving files..."
ARCH_NAME=`uname -p`
PLATFORM_NAME="linux-x86_64"
TAG_NAME=`git describe --tags`
SLANG_LLVM_VERSION=${TAG_NAME#"v"}
echo "tag:$TAG_NAME"
echo "slang-llvm-version:$LLVM_VERSION"
BIN_ARCHIVE="slang-llvm-$TAG_NAME-$PLATFORM_NAME-${{matrix.configuration}}.zip"
zip "$BIN_ARCHIVE" README.md
zip "$BIN_ARCHIVE" LICENSE
zip "$BIN_ARCHIVE" -r bin/*/*/*.so
echo "name=BINARY_ARCHIVE::$BIN_ARCHIVE"
echo "::set-output name=BINARY_ARCHIVE::$BIN_ARCHIVE"
Expand All @@ -62,4 +62,4 @@ jobs:
files: |
${{ steps.archive.outputs.BINARY_ARCHIVE }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion external/slang
Submodule slang updated 306 files
7 changes: 4 additions & 3 deletions premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,7 @@ workspace "slang-llvm"
-- and configuration options, e.g. `bin/windows-x64/debug/`
targetdir("bin/" .. targetInfo.tokenName .. "/%{cfg.buildcfg:lower()}")

-- C++14
cppdialect "C++14"
cppdialect "C++17"

-- Exceptions have to be turned off for linking against LLVM
exceptionhandling("Off")
Expand Down Expand Up @@ -293,7 +292,9 @@ workspace "slang-llvm"
-- z is for zlib support
-- Note that tinfo is not currently required (as is disabled for linux in llvm-project)
links { "pthread", "stdc++", "dl", "rt", "z" }
linkoptions{ "-Wl,-rpath,'$$ORIGIN',--no-as-needed,--no-undefined,--start-group" }
linkoptions{ "-Wl,-rpath,'$$ORIGIN',--no-as-needed,--no-undefined" }
-- Allow libraries to be listed in any order (adds opening and closing --start-group --end-group)
linkgroups "On"


filter { "system:macosx" }
Expand Down
189 changes: 189 additions & 0 deletions source/slang-llvm/slang-llvm-filecheck.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// This file contains a definition of LLVMFileCheck, an implementaion for
// IFileCheck.

#include <llvm/ADT/SmallString.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/FileCheck/FileCheck.h>

#include <slang.h>
#include <slang-com-helper.h>
#include <slang-com-ptr.h>
#include <core/slang-com-object.h>
#include <tools/slang-test/filecheck.h>

namespace slang_llvm
{

using namespace llvm;
using namespace Slang;

class LLVMFileCheck : IFileCheck, ComBaseObject
{
public:
// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) override;

// IUnknown
SLANG_COM_BASE_IUNKNOWN_ALL
void* getInterface(const Guid& guid);
void* getObject(const Guid& guid);

// IFileCheck
virtual TestResult SLANG_MCALL performTest(
const char* programName,
const char* rulesFilePath,
const char* fileCheckPrefix,
const char* stringToCheck,
const char* stringToCheckName,
ReportDiagnostic testReporter,
void* reporterData,
bool colorDiagnosticOutput) noexcept override;

private:
// Everything we need to pass through LLVM back to our diagnostic handler
struct ReporterData
{
ReportDiagnostic reportFun;
// User data from the caller of performTest
void* data;
bool colorDiagnosticOutput;
const char* programName;
TestMessageType testMessageType;
};

static void fileCheckDiagHandler(const SMDiagnostic & diag, void *reporterData);
};

class DisplayedStringOStream : public raw_string_ostream
{
public:
DisplayedStringOStream(std::string& s): raw_string_ostream(s){}
virtual bool is_displayed() const override { return true; };
};

void LLVMFileCheck::fileCheckDiagHandler(const SMDiagnostic & diag, void *dataPtr)
{
const ReporterData& reporterData = *reinterpret_cast<ReporterData*>(dataPtr);
std::string s;
DisplayedStringOStream o(s);
o.enable_colors(reporterData.colorDiagnosticOutput);
diag.print(reporterData.programName, o);
reporterData.reportFun(reporterData.data, TestMessageType::TestFailure, s.c_str());

}

TestResult LLVMFileCheck::performTest(
const char* const programName,
const char* const rulesFilePath,
const char* const fileCheckPrefix,
const char* const stringToCheck,
const char* const stringToCheckName,
const ReportDiagnostic testReporter,
void* const userReporterData,
const bool colorDiagnosticOutput) noexcept
{
//
// Set up our FileCheck session
//
FileCheckRequest fcReq;
fcReq.CheckPrefixes = {fileCheckPrefix};
FileCheck fc(fcReq);

//
// Set up the LLVM source manager for diagnostic output from our input buffers
//
SourceMgr sourceManager;
auto rulesTextOrError = MemoryBuffer::getFile(rulesFilePath, true);
if(std::error_code err = rulesTextOrError.getError())
{
const std::string message = "Unable to load FileCheck rules file: " + err.message();
testReporter(userReporterData, TestMessageType::RunError, message.c_str());
return TestResult::Fail;
}
SmallString<4096> rulesBuffer;
StringRef rulesStringRef = fc.CanonicalizeFile(*rulesTextOrError.get(), rulesBuffer);
sourceManager.AddNewSourceBuffer(
MemoryBuffer::getMemBuffer(rulesStringRef, rulesFilePath),
SMLoc());

SmallString<4096> inputBuffer;
const auto inputStringMB = MemoryBuffer::getMemBuffer(
StringRef(stringToCheck),
stringToCheckName,
false);
const StringRef inputStringRef = fc.CanonicalizeFile(*inputStringMB.get(), inputBuffer);
sourceManager.AddNewSourceBuffer(
MemoryBuffer::getMemBuffer(inputStringRef, stringToCheckName),
SMLoc());

// Initialize this with a 'RunError' failure type. We'll "downgrade" this to
// 'TestFailure' once we've done the FileCheck setup.
ReporterData reporterData{
testReporter,
userReporterData,
colorDiagnosticOutput,
programName,
TestMessageType::RunError};
sourceManager.setDiagHandler(fileCheckDiagHandler, static_cast<void*>(&reporterData));

auto checkPrefix = fc.buildCheckPrefixRegex();
if(fc.readCheckFile(sourceManager, rulesStringRef, checkPrefix))
{
// FileCheck failed to find or understand any FileCheck rules in
// the input file, automatic fail, and reported to the diag handler .
return TestResult::Fail;
}

// We've done the FileCheck setup, so make sure that any diagnostics
// reported on from here are just a regular test failure.
reporterData.testMessageType = TestMessageType::TestFailure;
if(!fc.checkInput(sourceManager, inputStringRef))
{
// An ordinary failure, the FileCheck rules didn't match
return TestResult::Fail;
}

return TestResult::Pass;
}

void* LLVMFileCheck::castAs(const Guid& guid)
{
if (auto ptr = getInterface(guid))
{
return ptr;
}
return getObject(guid);
}

void* LLVMFileCheck::getInterface(const Guid& guid)
{
if (guid == ISlangUnknown::getTypeGuid() ||
guid == ICastable::getTypeGuid() ||
guid == IFileCheck::getTypeGuid())
{
return this;
}
return nullptr;
}

void* LLVMFileCheck::getObject(const Guid& guid)
{
SLANG_UNUSED(guid);
return nullptr;
}

} // namespace slang_llvm

extern "C" SLANG_DLL_EXPORT SlangResult createLLVMFileCheck_V1(const SlangUUID& intfGuid, void** out)
{
Slang::ComPtr<slang_llvm::LLVMFileCheck> fileCheck(new slang_llvm::LLVMFileCheck);

if (auto ptr = fileCheck->castAs(intfGuid))
{
fileCheck.detach();
*out = ptr;
return SLANG_OK;
}

return SLANG_E_NO_INTERFACE;
}
2 changes: 1 addition & 1 deletion source/slang-llvm/slang-llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class LLVMJITSharedLibrary : public ISlangSharedLibrary, public ComBaseObject
SLANG_COM_BASE_IUNKNOWN_ALL

/// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid);
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;

// ISlangSharedLibrary impl
virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE;
Expand Down

0 comments on commit 36a237a

Please sign in to comment.