Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/xmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ jobs:
- name: Setup xmake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: branch@master
xmake-version: 3.0.0
actions-cache-folder: ".xmake-cache"
actions-cache-key: ${{ matrix.os }}
package-cache: true
package-cache: false
package-cache-key: ${{ matrix.os }}
build-cache: true
build-cache-key: ${{ matrix.os }}-${{ matrix.build_type }}
Expand Down Expand Up @@ -86,10 +86,10 @@ jobs:
- name: Setup xmake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: branch@master
xmake-version: 3.0.0
actions-cache-folder: ".xmake-cache"
actions-cache-key: ${{ matrix.os }}
package-cache: true
package-cache: false
package-cache-key: ${{ matrix.os }}
build-cache: true
build-cache-key: ${{ matrix.os }}-${{ matrix.build_type }}
Expand Down Expand Up @@ -127,10 +127,10 @@ jobs:
- name: Setup xmake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: branch@master
xmake-version: 3.0.0
actions-cache-folder: ".xmake-cache"
actions-cache-key: ${{ matrix.os }}
package-cache: true
package-cache: false
package-cache-key: ${{ matrix.os }}
build-cache: true
build-cache-key: ${{ matrix.os }}-${{ matrix.build_type }}
Expand Down
11 changes: 6 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,13 @@ target_link_libraries(clice PRIVATE clice-core)
install(TARGETS clice RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

message(STATUS "Copying resource directory for development build")
file(COPY
"${LLVM_INSTALL_PATH}/lib/clang/20/"
DESTINATION "${PROJECT_BINARY_DIR}/lib/clang/20"
file(
COPY "${LLVM_INSTALL_PATH}/lib/clang"
DESTINATION "${PROJECT_BINARY_DIR}/lib"
)
install(DIRECTORY "${LLVM_INSTALL_PATH}/lib/clang/20/"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/clang/20"
install(
DIRECTORY "${LLVM_INSTALL_PATH}/lib/clang"
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)

if(CLICE_ENABLE_TEST)
Expand Down
40 changes: 22 additions & 18 deletions cmake/llvm_setup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@ include_guard()
include(${CMAKE_CURRENT_LIST_DIR}/github.cmake)

# Check if LLVM version is supported
function(check_llvm_version llvm_ver OUTPUT_VAR)
if((NOT DEFINED llvm_ver) OR (llvm_ver STREQUAL ""))
function(check_llvm_version LOCAL_LLVM_VERSION LLVM_VERSION OUTPUT_VAR)
if((NOT DEFINED LOCAL_LLVM_VERSION) OR (LOCAL_LLVM_VERSION STREQUAL ""))
message(WARNING "LLVM version is not set.")
set(${OUTPUT_VAR} FALSE PARENT_SCOPE)
elseif(NOT (llvm_ver VERSION_GREATER_EQUAL "20.1" AND llvm_ver VERSION_LESS "20.2"))
message(WARNING "Unsupported LLVM version: ${llvm_ver}. Only LLVM 20.1.x is supported.")
elseif(NOT (LOCAL_LLVM_VERSION VERSION_GREATER_EQUAL LLVM_VERSION))
message(WARNING "Unsupported LLVM version: ${LOCAL_LLVM_VERSION}. Only LLVM ${LLVM_VERSION} is supported.")
set(${OUTPUT_VAR} FALSE PARENT_SCOPE)
else()
set(${OUTPUT_VAR} TRUE PARENT_SCOPE)
endif()
endfunction()

# Look up LLVM version's corresponding commit SHA
function(lookup_commit llvm_ver OUTPUT_VAR)
set(LLVM_TAG "llvmorg-${llvm_ver}")
function(lookup_commit LLVM_VERSION OUTPUT_VAR)
set(LLVM_TAG "llvmorg-${LLVM_VERSION}")
github_lookup_tag_commit("llvm" "llvm-project" ${LLVM_TAG} COMMIT_SHA)
set(${OUTPUT_VAR} ${COMMIT_SHA} PARENT_SCOPE)
endfunction()

# Fetch private Clang header files from LLVM source
function(fetch_private_clang_files llvm_ver)
function(fetch_private_clang_files LLVM_VERSION)
set(PRIVATE_CLANG_FILE_LIST
"Sema/CoroutineStmtBuilder.h"
"Sema/TypeLocBuilder.h"
Expand Down Expand Up @@ -58,13 +58,13 @@ function(fetch_private_clang_files llvm_ver)
message(WARNING "Required private clang files incomplete, fetching from llvm-project source...")

# Get the commit SHA for this LLVM version
lookup_commit(${llvm_ver} LLVM_COMMIT)
lookup_commit(${LLVM_VERSION} LLVM_COMMIT)
if(LLVM_COMMIT STREQUAL "NOTFOUND")
message(WARNING "Failed to lookup commit for LLVM ${llvm_ver}, skipping private clang files download")
message(WARNING "Failed to lookup commit for LLVM ${LLVM_VERSION}, skipping private clang files download")
return()
endif()

message(STATUS "LLVM ${llvm_ver} corresponds to commit ${LLVM_COMMIT}")
message(STATUS "LLVM ${LLVM_VERSION} corresponds to commit ${LLVM_COMMIT}")

# Download missing files
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/clang")
Expand Down Expand Up @@ -117,14 +117,14 @@ function(detect_llvm OUTPUT_VAR)
endfunction()

# Download and install prebuilt LLVM binaries with error checking
function(install_prebuilt_llvm llvm_ver)
function(install_prebuilt_llvm LLVM_VERSION)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.llvm")

# Determine platform-specific package name
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(LLVM_BUILD_TYPE "debug")
elseif(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(LLVM_BUILD_TYPE "release")
set(LLVM_BUILD_TYPE "releasedbg")
else()
set(LLVM_BUILD_TYPE "release-lto")
endif()
Expand All @@ -146,7 +146,7 @@ function(install_prebuilt_llvm llvm_ver)
# Download if file does not exist
if(NOT EXISTS "${DOWNLOAD_PATH}")
message(STATUS "Downloading prebuilt LLVM package: ${LLVM_PACKAGE}")
set(DOWNLOAD_URL "https://github.com/clice-io/llvm-binary/releases/download/${llvm_ver}/${LLVM_PACKAGE}")
set(DOWNLOAD_URL "https://github.com/clice-io/llvm-binary/releases/download/${LLVM_VERSION}/${LLVM_PACKAGE}")
file(DOWNLOAD "${DOWNLOAD_URL}"
"${DOWNLOAD_PATH}"
STATUS DOWNLOAD_STATUS
Expand Down Expand Up @@ -187,7 +187,11 @@ function(install_prebuilt_llvm llvm_ver)
endfunction()

# Main function to set up LLVM for the project
function(setup_llvm)
function(setup_llvm LLVM_VERSION)
if(NOT DEFINED LLVM_VERSION OR LLVM_VERSION STREQUAL "")
message(FATAL_ERROR "setup_llvm() requires a LLVM_VERSION argument (e.g., '21.1.4').")
endif()

# Use existing LLVM installation if path is already set
if(DEFINED LLVM_INSTALL_PATH AND NOT LLVM_INSTALL_PATH STREQUAL "")
message(STATUS "LLVM_INSTALL_PATH is set to ${LLVM_INSTALL_PATH}, using it directly.")
Expand All @@ -197,14 +201,14 @@ function(setup_llvm)
set(LLVM_VERSION_OK false)
if (CMAKE_BUILD_TYPE STREQUAL "Release")
# Try to detect system LLVM
detect_llvm(LLVM_VERSION)
check_llvm_version("${LLVM_VERSION}" LLVM_VERSION_OK)
detect_llvm(LOCAL_LLVM_VERSION)
check_llvm_version("${LOCAL_LLVM_VERSION}" "${LLVM_VERSION}" LLVM_VERSION_OK)
endif()

# Download prebuilt LLVM if system version is not suitable
if(NOT LLVM_VERSION_OK)
set(LLVM_VERSION "20.1.5")
message(WARNING "System LLVM not found, version mismatch or incompatible build type, downloading prebuilt LLVM...")
message(WARNING "System LLVM not found, version mismatch or incompatible build type.")
message(WARNING "Downloading prebuilt LLVM ${LLVM_VERSION} ...")
install_prebuilt_llvm("${LLVM_VERSION}")
endif()

Expand Down
2 changes: 1 addition & 1 deletion cmake/package.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ include_guard()

include(${CMAKE_CURRENT_LIST_DIR}/llvm_setup.cmake)

setup_llvm()
setup_llvm("21.1.4")

get_filename_component(LLVM_INSTALL_PATH "${LLVM_INSTALL_PATH}" ABSOLUTE)

Expand Down
26 changes: 13 additions & 13 deletions config/prebuilt-llvm.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"platform": "Windows",
"build_type": "Release",
"is_lto": false,
"filename": "x64-windows-msvc-release.7z",
"version": "20.1.5",
"sha256": "499b2e1e37c6dcccbc9d538cea5a222b552d599f54bb523adea8594d7837d02b"
"filename": "x64-windows-msvc-releasedbg.7z",
"version": "21.1.4",
"sha256": "324ec6b3634c32e1e999dae505f6ae83386f2a6b9ab96ac03ccfa029fb68b496"
},
{
"platform": "Windows",
Expand All @@ -20,16 +20,16 @@
"build_type": "Debug",
"is_lto": false,
"filename": "x86_64-linux-gnu-debug.tar.xz",
"version": "20.1.5",
"sha256": "c04dddbe1d43d006f1ac52db01ab1776b8686fb8d4a1d13f2e07df37ae1ed47e"
"version": "21.1.4",
"sha256": "7bd68b14f147e291c9af8c32a8e78d57cc7b0e1f9c733df67e963e7062651f10"
},
{
"platform": "Linux",
"build_type": "Release",
"is_lto": false,
"filename": "x86_64-linux-gnu-release.tar.xz",
"version": "20.1.5",
"sha256": "5ff442434e9c1fbe67c9c2bd13284ef73590aa984bb74bcdfcec4404e5074b70"
"filename": "x86_64-linux-gnu-releasedbg.tar.xz",
"version": "21.1.4",
"sha256": "d4bf7ca08b07164637595ea3988330305e36354e466832a0fe7c4406fee3ac40"
},
{
"platform": "Linux",
Expand All @@ -44,16 +44,16 @@
"build_type": "Debug",
"is_lto": false,
"filename": "arm64-macosx-apple-debug.tar.xz",
"version": "20.1.5",
"sha256": "899d15d0678c1099bccb41098355b938d3bb6dd20870763758b70db01b31a709"
"version": "21.1.4",
"sha256": "fd77af5a767ac7f4dc682602cfd6c84fbd5082021200e5cd8bd30379f4fd4a4d"
},
{
"platform": "macosx",
"build_type": "Release",
"is_lto": false,
"filename": "arm64-macosx-apple-release.tar.xz",
"version": "20.1.5",
"sha256": "47d89ed747b9946b4677ff902b5889b47d07b5cd92b0daf12db9abc6d284f955"
"filename": "arm64-macosx-apple-releasedbg.tar.xz",
"version": "21.1.4",
"sha256": "87f7667166496639ad60f02a22505296b09e458530a72d52b792ffb29d96a82b"
},
{
"platform": "macosx",
Expand Down
9 changes: 8 additions & 1 deletion include/AST/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,14 @@ class TemplateResolver {
}

lookup_result lookup(const clang::DependentTemplateSpecializationType* type) {
return lookup(type->getQualifier(), type->getIdentifier());
auto& template_name = type->getDependentTemplateName();
auto identifier = template_name.getName().getIdentifier();
if(identifier) {
return lookup(template_name.getQualifier(), identifier);
} else {
/// FIXME: Operators does't have a name.
return {};
}
}

lookup_result lookup(const clang::DependentScopeDeclRefExpr* expr) {
Expand Down
1 change: 0 additions & 1 deletion include/AST/Semantic.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,6 @@ class SemanticVisitor : public FilteredASTVisitor<SemanticVisitor<Derived>> {
}

case clang::NestedNameSpecifier::TypeSpec:
case clang::NestedNameSpecifier::TypeSpecWithTemplate:
case clang::NestedNameSpecifier::Global:
case clang::NestedNameSpecifier::Super: {
break;
Expand Down
3 changes: 2 additions & 1 deletion include/Compiler/Diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ struct Diagnostic {
/// The error message of this diagnostic.
std::string message;

static DiagnosticCollector* create(std::shared_ptr<std::vector<Diagnostic>> diagnostics);
static std::unique_ptr<DiagnosticCollector>
create(std::shared_ptr<std::vector<Diagnostic>> diagnostics);
};

} // namespace clice
8 changes: 4 additions & 4 deletions include/Support/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ using namespace llvm::sys::fs;

inline std::string resource_dir = "";

inline std::expected<void, std::error_code> init_resource_dir(llvm::StringRef execute) {
inline std::expected<void, std::string> init_resource_dir(llvm::StringRef execute) {
llvm::SmallString<128> path;
path::append(path, path::parent_path(execute), "..");
path::append(path, "lib", "clang", "20");
path::append(path, "lib", "clang", "21");
if(auto error = real_path(path, path)) {
return std::unexpected(error);
return std::unexpected(std::format("{}:{}", error, path.str()));
}
resource_dir = path.str();
return std::expected<void, std::error_code>();
return std::expected<void, std::string>();
}

inline std::expected<std::string, std::error_code> createTemporaryFile(llvm::StringRef prefix,
Expand Down
41 changes: 26 additions & 15 deletions src/AST/Resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,14 @@ class PseudoInstantiator : public clang::TreeTransform<PseudoInstantiator> {
TD = TST->getTemplateName().getAsTemplateDecl();
args = TST->template_arguments();
} else if(auto DTST = type->getAs<clang::DependentTemplateSpecializationType>()) {
if(auto decl = preferred(lookup(DTST->getQualifier(), DTST->getIdentifier()))) {
auto& template_name = DTST->getDependentTemplateName();
/// FIXME: operators does't have the name.
auto name = template_name.getName().getIdentifier();
if(!name) {
return {};
}

if(auto decl = preferred(lookup(template_name.getQualifier(), name))) {
TD = decl;
args = DTST->template_arguments();
}
Expand Down Expand Up @@ -371,9 +378,8 @@ class PseudoInstantiator : public clang::TreeTransform<PseudoInstantiator> {
return lookup(type, name);
}

case clang::NestedNameSpecifier::TypeSpec:
case clang::NestedNameSpecifier::TypeSpecWithTemplate: {
/// If the prefix is `TypeSpec` or `TypeSpecWithTemplate`, it must be a type.
case clang::NestedNameSpecifier::TypeSpec: {
/// If the prefix is `TypeSpec`, it must be a type.
return lookup(clang::QualType(NNS->getAsType(), 0), name);
}

Expand Down Expand Up @@ -597,18 +603,16 @@ class PseudoInstantiator : public clang::TreeTransform<PseudoInstantiator> {

/// Alloc::rebind<T>::other
auto prefix =
clang::NestedNameSpecifier::Create(context, nullptr, false, Alloc.getTypePtr());
clang::NestedNameSpecifier::Create(context, nullptr, Alloc.getTypePtr());

auto rebind = sema.getPreprocessor().getIdentifierInfo("rebind");

auto DTST = context.getDependentTemplateSpecializationType(
clang::ElaboratedTypeKeyword::None,
prefix,
rebind,
clang::DependentTemplateStorage(prefix, rebind, false),
arguments);

prefix =
clang::NestedNameSpecifier::Create(context, prefix, true, DTST.getTypePtr());
prefix = clang::NestedNameSpecifier::Create(context, prefix, DTST.getTypePtr());

auto other = sema.getPreprocessor().getIdentifierInfo("other");
auto DNT = context.getDependentNameType(clang::ElaboratedTypeKeyword::Typename,
Expand All @@ -624,6 +628,7 @@ class PseudoInstantiator : public clang::TreeTransform<PseudoInstantiator> {
if(auto TST = Alloc->getAs<clang::TemplateSpecializationType>()) {
llvm::SmallVector<clang::TemplateArgument, 4> replaceArguments = {T};
return context.getTemplateSpecializationType(TST->getTemplateName(),
replaceArguments,
replaceArguments);
}
}
Expand Down Expand Up @@ -721,16 +726,22 @@ class PseudoInstantiator : public clang::TreeTransform<PseudoInstantiator> {
arguments.push_back(arg.getArgument());
}

/// FIXME: operator does't have a name.
auto name = DTST->getDependentTemplateName().getName().getIdentifier();
if(!name) {
return clang::QualType();
}

/// Try resolve the hole.
if(auto result = hole(NNS, DTST->getIdentifier(), arguments); !result.isNull()) {
if(auto result = hole(NNS, name, arguments); !result.isNull()) {
resolved.try_emplace(DTST, result);
TLB.pushTrivial(context, result, {});
return result;
}

/// The `lookup` may change the instantiation stack, save the current state.
auto state = stack.state();
if(auto decl = preferred(lookup(NNS, DTST->getIdentifier()))) {
if(auto decl = preferred(lookup(NNS, name))) {
/// FIXME: Current implementation results in duplicated lookup.
/// Cache the result of `lookup` to avoid duplicated lookup.
if(auto TATD = llvm::dyn_cast<clang::TypeAliasTemplateDecl>(decl)) {
Expand All @@ -746,10 +757,10 @@ class PseudoInstantiator : public clang::TreeTransform<PseudoInstantiator> {
}

/// FIXME: figure out here.
auto result = context.getDependentTemplateSpecializationType(DTST->getKeyword(),
NNS,
DTST->getIdentifier(),
arguments);
auto result = context.getDependentTemplateSpecializationType(
DTST->getKeyword(),
clang::DependentTemplateStorage(NNS, name, false),
arguments);

return TLB.push<clang::DependentTemplateSpecializationTypeLoc>(result).getType();
}
Expand Down
Loading