Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
88cd6a0
Update clang dumper resources to manifest release
lm-sousa Jul 3, 2026
33c7c2f
Read clang dumper include entrypoints
lm-sousa Jul 3, 2026
9f62bb8
Cache clang dumper by release version
lm-sousa Jul 6, 2026
37d0b27
Throttle clang dumper include validation
lm-sousa Jul 7, 2026
9bb46c0
Restore strict clang dumper integration
lm-sousa Jul 15, 2026
b367fa9
Support testing local clang-dumper builds
lm-sousa Jul 15, 2026
5411fb4
Use canonical dumper threshold option
lm-sousa Jul 16, 2026
a1f5256
Update character literal kind for LLVM 18
lm-sousa Jul 27, 2026
04f367b
Support local clang-dumper builds from tag file
lm-sousa Jul 27, 2026
a4f50ce
Allow unresolved unary transform types
lm-sousa Jul 27, 2026
021800a
Test source locations in ClangAstParser
lm-sousa Jul 27, 2026
a8b23d7
Prevent races during stale dumper cache cleanup
lm-sousa Jul 28, 2026
7dd123c
Refactor bundled include handling
lm-sousa Jul 28, 2026
09098bd
Regenerate Clava-JS enum interfaces
lm-sousa Jul 28, 2026
9439627
Update the dumper tag
lm-sousa Jul 30, 2026
91c8dd4
Fix C++20 parenthesized list initialization
lm-sousa Jul 30, 2026
93290bc
Synchronize clang cache initialization locks
lm-sousa Jul 30, 2026
0496980
Make stale cache cleanup portable
lm-sousa Jul 30, 2026
cc2e57c
Support CUDA discovery for local clang-dumper builds
lm-sousa Jul 30, 2026
2b06418
Remove persistent clang cache lock artifacts
lm-sousa Jul 30, 2026
d0e99f9
Publish CUDA compatibility header atomically
lm-sousa Jul 30, 2026
ab0682b
Preserve JavaScript initialization style names
lm-sousa Jul 30, 2026
6b3a744
test: exercise clang dumper cache races
lm-sousa Jul 31, 2026
09861ed
test: cover stale cleanup of cached dumper paths
lm-sousa Jul 31, 2026
8cbbcfa
fix: coordinate cached clang resource heartbeat updates
lm-sousa Jul 31, 2026
fb14c49
Avoid hashing cached clang-dumper includes
lm-sousa Jul 31, 2026
b320fd4
fix: simplify clang cache coordination
lm-sousa Aug 1, 2026
4eeb794
fix: use system libc for local clang-dumper builds
lm-sousa Aug 4, 2026
d0a596e
refactor: simplify clang dumper resource setup
lm-sousa Aug 4, 2026
5a09c94
fix: preserve unevaluated string literal spelling
lm-sousa Aug 4, 2026
bbd48d1
fix: preserve unevaluated string source spelling
lm-sousa Aug 4, 2026
e4f3e21
fix: update C++ standard versions in Standard enum
lm-sousa Aug 4, 2026
2e40739
test: cover dependent unary transform types
lm-sousa Aug 4, 2026
9726acf
test: cover strict optional node resolution
lm-sousa Aug 4, 2026
c71eb7c
test: assert parenthesized initialization style
lm-sousa Aug 4, 2026
9f0f3ad
fix: restore built-in CUDA archive parsing
lm-sousa Aug 4, 2026
cf3ffa0
fix: always use built-in CUDA archive
lm-sousa Aug 4, 2026
03a4e88
fix: simplify legacy CUDA resource handling
lm-sousa Aug 4, 2026
ba928d3
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