Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
31deb79
Update clang dumper resources to manifest release
lm-sousa Jul 3, 2026
8ce384b
Read clang dumper include entrypoints
lm-sousa Jul 3, 2026
54e87e1
Cache clang dumper by release version
lm-sousa Jul 6, 2026
c9bb930
Throttle clang dumper include validation
lm-sousa Jul 7, 2026
5f9d8d9
Restore strict clang dumper integration
lm-sousa Jul 15, 2026
9c0a14a
Support testing local clang-dumper builds
lm-sousa Jul 15, 2026
2ed37d6
Use canonical dumper threshold option
lm-sousa Jul 16, 2026
5a7b532
Update character literal kind for LLVM 18
lm-sousa Jul 27, 2026
3687e45
Support local clang-dumper builds from tag file
lm-sousa Jul 27, 2026
8e08c25
Allow unresolved unary transform types
lm-sousa Jul 27, 2026
264098c
Test source locations across macro expansions
lm-sousa Jul 27, 2026
9fdd317
Test source locations in ClangAstParser
lm-sousa Jul 27, 2026
761523b
Prevent races during stale dumper cache cleanup
lm-sousa Jul 28, 2026
c4e6937
Refactor bundled include handling
lm-sousa Jul 28, 2026
ab48ad3
Regenerate Clava-JS enum interfaces
lm-sousa Jul 28, 2026
7a0c249
Update the dumper tag
lm-sousa Jul 30, 2026
64533b9
Fix C++20 parenthesized list initialization
lm-sousa Jul 30, 2026
1429791
Synchronize clang cache initialization locks
lm-sousa Jul 30, 2026
c1ea2e8
Make stale cache cleanup portable
lm-sousa Jul 30, 2026
5ab9ef3
Support CUDA discovery for local clang-dumper builds
lm-sousa Jul 30, 2026
13d6bca
Remove persistent clang cache lock artifacts
lm-sousa Jul 30, 2026
8c5dafa
Publish CUDA compatibility header atomically
lm-sousa Jul 30, 2026
a7fd932
Preserve JavaScript initialization style names
lm-sousa Jul 30, 2026
3565a5a
test: exercise clang dumper cache races
lm-sousa Jul 31, 2026
ba135fa
test: cover stale cleanup of cached dumper paths
lm-sousa Jul 31, 2026
7318635
fix: coordinate cached clang resource heartbeat updates
lm-sousa Jul 31, 2026
5cee6ec
Avoid hashing cached clang-dumper includes
lm-sousa Jul 31, 2026
c3e7395
fix: simplify clang cache coordination
lm-sousa Aug 1, 2026
f7a872a
fix: use system libc for local clang-dumper builds
lm-sousa Aug 4, 2026
f03fa3c
refactor: simplify clang dumper resource setup
lm-sousa Aug 4, 2026
eb5bb92
fix: preserve unevaluated string literal spelling
lm-sousa Aug 4, 2026
07e4d2a
fix: preserve unevaluated string source spelling
lm-sousa Aug 4, 2026
b3e6947
fix: update C++ standard versions in Standard enum
lm-sousa Aug 4, 2026
f24cae5
test: cover dependent unary transform types
lm-sousa Aug 4, 2026
28aa6f0
test: cover strict optional node resolution
lm-sousa Aug 4, 2026
f27b181
test: assert parenthesized initialization style
lm-sousa Aug 4, 2026
c63586e
fix: restore built-in CUDA archive parsing
lm-sousa Aug 4, 2026
82eed58
fix: always use built-in CUDA archive
lm-sousa Aug 4, 2026
5a36896
fix: simplify legacy CUDA resource handling
lm-sousa Aug 4, 2026
b273499
docs: clarify CUDA standard workaround
lm-sousa Aug 4, 2026
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
5 changes: 5 additions & 0 deletions ClangAstParser/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
implementation ":jOptions"
implementation ":SpecsUtils"

implementation 'com.google.code.gson:gson:2.12.1'
implementation 'com.google.guava:guava:33.4.0-jre'

testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
Expand Down Expand Up @@ -49,6 +50,10 @@ sourceSets {
}
}

processResources {
from('clang-dumper-release.tag')
}

// Test coverage configuration
jacocoTestReport {
reports {
Expand Down
1 change: 1 addition & 0 deletions ClangAstParser/clang-dumper-release.tag
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.1.8_1
56 changes: 0 additions & 56 deletions ClangAstParser/src/pt/up/fe/specs/clang/ClangAstFileResource.java

This file was deleted.

15 changes: 5 additions & 10 deletions ClangAstParser/src/pt/up/fe/specs/clang/ClangAstKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.suikasoft.jOptions.Datakey.DataKey;
import org.suikasoft.jOptions.Datakey.KeyFactory;
import org.suikasoft.jOptions.Interfaces.DataStore;
import pt.up.fe.specs.clang.ClangAstWebResource.LocalBuild;
import pt.up.fe.specs.clava.ClavaLog;
import pt.up.fe.specs.clava.ClavaOptions;
import pt.up.fe.specs.clava.language.Standard;
Expand All @@ -27,8 +28,6 @@

public interface ClangAstKeys {

DataKey<String> CLANGAST_VERSION = KeyFactory.string("clangast_version", "");

/**
* What libc/libcxx mode should be used.
*/
Expand All @@ -55,7 +54,6 @@ public static String getFlagIgnoreIncludes() {
static DataStore toDataStore(List<String> flags) {
DataStore config = DataStore.newInstance(ClavaOptions.STORE_DEFINITION, false);
final String stdPrefix = "-std=";
final String clangAstDumperPrefix = "-clang-dumper=";
final String cilkFlag = "-fcilkplus";

// Search options
Expand All @@ -78,13 +76,6 @@ static DataStore toDataStore(List<String> flags) {
continue;
}

// If ClangAstDumper version, parse option
if (flag.startsWith(clangAstDumperPrefix)) {
String version = flag.substring(clangAstDumperPrefix.length());
config.set(ClangAstKeys.CLANGAST_VERSION, version);
continue;
}

// If Cilk flag, add option
if (flag.equals(cilkFlag)) {
config.set(ClangAstKeys.USES_CILK);
Expand All @@ -108,6 +99,10 @@ static DataStore toDataStore(List<String> flags) {

config.add(ClavaOptions.FLAGS_LIST, parsedFlags);

if (ClangAstWebResource.getDumperSource() instanceof LocalBuild) {
config.set(ClangAstKeys.LIBC_CXX_MODE, LibcMode.SYSTEM);
}

return config;
}

Expand Down
17 changes: 0 additions & 17 deletions ClangAstParser/src/pt/up/fe/specs/clang/ClangAstResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@
*
*/
public enum ClangAstResource implements ResourceProvider {
// BUILTIN_INCLUDES_3_8(ClangAstWebResource.BUILTIN_INCLUDES_3_8),

TEST_INCLUDES_C("test_includes.c"),
TEST_INCLUDES_CPP("test_includes.cpp");

// private final WebResourceProvider webResource;
private final String resource;

private static final String basePackage = "clangast/";
Expand All @@ -35,24 +32,10 @@ public enum ClangAstResource implements ResourceProvider {
*/
private ClangAstResource(String resource) {
this.resource = basePackage + resource;
// this.webResource = null;
}

// private ClangAstResource(WebResourceProvider webResource) {
// this.resource = null;
// this.webResource = webResource;
// }

/* (non-Javadoc)
* @see org.suikasoft.SharedLibrary.Interfaces.ResourceProvider#getResource()
*/
@Override
public String getResource() {
return resource;
// if (resource != null) {
// return resource;
// }

// return webResource.getResourceUrl();
}
}
160 changes: 134 additions & 26 deletions ClangAstParser/src/pt/up/fe/specs/clang/ClangAstWebResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,148 @@

package pt.up.fe.specs.clang;

import com.google.gson.Gson;
import pt.up.fe.specs.util.SpecsIo;
import pt.up.fe.specs.util.providers.WebResourceProvider;

public interface ClangAstWebResource {
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

String ROOT_16_0_5 = "https://github.com/specs-feup/clava/releases/download/clang_ast_dumper_16.0.5/";
String ROOT_12_0_7 = "https://github.com/specs-feup/clava/releases/download/clang_ast_dumper_v12.0.7.1/";
public final class ClangAstWebResource {

WebResourceProvider LIBC_CXX_LINUX_COMPLETE = WebResourceProvider.newInstance(ROOT_16_0_5, "libc_cxx_linux_complete.zip", "v16.0.5");
WebResourceProvider LIBC_CXX_MACOS_COMPLETE = WebResourceProvider.newInstance(ROOT_16_0_5, "libc_cxx_macos_complete.zip", "v16.0.6");
WebResourceProvider LIBC_CXX_WIN32_COMPLETE = WebResourceProvider.newInstance(ROOT_16_0_5, "libc_cxx_win32_complete.zip", "v16.0.5");
private static final String RELEASE_ROOT = "https://github.com/specs-feup/clang-dumper/releases/download/";
private static final String CUDA_RELEASE_ROOT =
"https://github.com/specs-feup/clava/releases/download/clang_ast_dumper_v12.0.7.1/";
public static final String CUDA_LIB_FILENAME = "cudalib.zip";
static final WebResourceProvider CUDA_LIB =
WebResourceProvider.newInstance(CUDA_RELEASE_ROOT, CUDA_LIB_FILENAME, "v11.3.0");
private static final String RELEASE_TAG_RESOURCE = "clang-dumper-release.tag";
public static final String MANIFEST_FILENAME = "clang-dumper-release-manifest.json";

WebResourceProvider OPENMP_INCLUDES = WebResourceProvider.newInstance(ROOT_16_0_5, "openmp_includes.zip");
private static final Gson GSON = new Gson();
private static final DumperSource DUMPER_SOURCE = readDumperSource();

WebResourceProvider CUDA_LIB = WebResourceProvider.newInstance(ROOT_12_0_7, "cudalib.zip", "v11.3.0");
private ClangAstWebResource() {
}

WebResourceProvider WIN_EXE = WebResourceProvider.newInstance(ROOT_16_0_5, "clang_ast_windows.exe", "v16.0.5_1");
WebResourceProvider WIN_DLL1 = WebResourceProvider.newInstance(ROOT_12_0_7, "libwinpthread-1.dll");
WebResourceProvider WIN_DLL2 = WebResourceProvider.newInstance(ROOT_12_0_7, "zlib1.dll");
WebResourceProvider WIN_DLL3 = WebResourceProvider.newInstance(ROOT_12_0_7, "libzstd.dll");
WebResourceProvider WIN_DLL4 = WebResourceProvider.newInstance(ROOT_12_0_7, "libstdc++-6.dll");
WebResourceProvider WIN_DLL5 = WebResourceProvider.newInstance(ROOT_12_0_7, "libgcc_s_seh-1.dll");
WebResourceProvider WIN_DLL6 = WebResourceProvider.newInstance(ROOT_12_0_7, "libffi-8.dll");
WebResourceProvider WIN_DLL7 = WebResourceProvider.newInstance(ROOT_12_0_7, "libxml2-2.dll");
WebResourceProvider WIN_DLL8 = WebResourceProvider.newInstance(ROOT_12_0_7, "liblzma-5.dll");
WebResourceProvider WIN_DLL9 = WebResourceProvider.newInstance(ROOT_12_0_7, "libiconv-2.dll");
WebResourceProvider WIN_LLVM_DLL = WebResourceProvider.newInstance(ROOT_16_0_5, "libLLVM-16.dll");
WebResourceProvider WIN_CLANG_DLL = WebResourceProvider.newInstance(ROOT_16_0_5, "libclang-cpp.dll");
public static DumperSource getDumperSource() {
return DUMPER_SOURCE;
}

WebResourceProvider LINUX_EXE = WebResourceProvider.newInstance(ROOT_16_0_5, "clang_ast_linux", "v16.0.5");
WebResourceProvider LINUX_PLUGIN = WebResourceProvider.newInstance(ROOT_16_0_5, "clang-plugin.so", "v16.0.5");
WebResourceProvider LINUX_LLVM_DLL = WebResourceProvider.newInstance(ROOT_16_0_5, "libLLVM-16.so.1", "v16.0.5");
private static DumperSource readDumperSource() {
var inputStream = ClangAstWebResource.class.getClassLoader().getResourceAsStream(RELEASE_TAG_RESOURCE);

WebResourceProvider MAC_OS_EXE = WebResourceProvider.newInstance(ROOT_16_0_5, "clang_ast_macos", "v16.0.5");
WebResourceProvider MAC_OS_LLVM_DLL = WebResourceProvider.newInstance(ROOT_16_0_5, "libLLVM.dylib", "v16.0.5");
WebResourceProvider MAC_OS_DLL1 = WebResourceProvider.newInstance(ROOT_16_0_5, "libzstd.1.dylib", "v16.0.5");
if (inputStream == null) {
throw new RuntimeException("Could not find resource '" + RELEASE_TAG_RESOURCE + "'");
}

String value;
try (inputStream) {
value = SpecsIo.read(inputStream).trim();
} catch (IOException e) {
throw new UncheckedIOException("Could not read resource '" + RELEASE_TAG_RESOURCE + "'", e);
}

if (value.isBlank()) {
throw new RuntimeException("Resource '" + RELEASE_TAG_RESOURCE + "' is empty");
}

return parseDumperSource(value);
}

static DumperSource parseDumperSource(String value) {
var path = Path.of(value);
if (path.isAbsolute()) {
return new LocalBuild(path.toFile());
}

if (value.contains("/") || value.contains("\\") || value.equals(".") || value.equals("..")) {
throw new RuntimeException("Relative paths are not supported in resource '" + RELEASE_TAG_RESOURCE
+ "': '" + value + "'");
}

return new Release(value);
}

public static String getReleaseTag() {
var source = getDumperSource();
if (source instanceof Release release) {
return release.tag();
}

throw new IllegalStateException("The clang-dumper resource points to a local build");
}

public static ClangDumperManifest getManifest(File resourceFolder) {
var releaseTag = getReleaseTag();
var manifestResource = WebResourceProvider.newInstance(getReleaseBaseUrl(releaseTag), MANIFEST_FILENAME,
releaseTag);
var manifestFile = manifestResource.writeVersioned(resourceFolder, ClangAstWebResource.class).getFile();
var manifest = GSON.fromJson(SpecsIo.read(manifestFile), ClangDumperManifest.class);

if (manifest == null) {
throw new RuntimeException("Could not parse clang-dumper manifest from '" + manifestFile + "'");
}

manifest.validate();
return manifest;
}

public static WebResourceProvider getAssetResource(ClangDumperManifestAsset asset) {
var releaseTag = getReleaseTag();
return WebResourceProvider.newInstance(getReleaseBaseUrl(releaseTag), asset.filename(),
releaseTag + "-" + asset.sha256());
}

private static String getReleaseBaseUrl(String releaseTag) {
return RELEASE_ROOT + releaseTag + "/";
}

public sealed interface DumperSource permits Release, LocalBuild {
}

public record Release(String tag) implements DumperSource {
}

public record LocalBuild(File folder) implements DumperSource {
}

public record ClangDumperManifest(int schema_version, List<ClangDumperManifestAsset> assets) {

public void validate() {
if (schema_version != 1) {
throw new RuntimeException("Unsupported clang-dumper manifest schema version: " + schema_version);
}

if (assets == null || assets.isEmpty()) {
throw new RuntimeException("Clang-dumper manifest does not contain assets");
}
}

public ClangDumperManifestAsset getAsset(String platform, String arch, String kind) {
Objects.requireNonNull(platform);
Objects.requireNonNull(arch);
Objects.requireNonNull(kind);

Optional<ClangDumperManifestAsset> asset = assets.stream()
.filter(candidate -> candidate.matches(platform, arch, kind))
.findFirst();

return asset.orElseThrow(() -> new RuntimeException("Could not find clang-dumper asset for platform '"
+ platform + "', architecture '" + arch + "' and kind '" + kind + "'"));
}
}

public record ClangDumperManifestAsset(String filename, String kind, String platform, String arch, int llvm_major,
String sha256) {

public boolean matches(String platform, String arch, String kind) {
return this.platform.equals(platform) && this.arch.equals(arch) && this.kind.equals(kind);
}
}
}
Loading
Loading