Skip to content

Commit 7e581b3

Browse files
committed
Synchronize files with the official upstream source.
1 parent 86ffdfd commit 7e581b3

File tree

19 files changed

+484
-110
lines changed

19 files changed

+484
-110
lines changed

.github/workflows/docker_ci.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ on:
1010

1111
jobs:
1212
build-job:
13-
runs-on: ubuntu-22.04
13+
runs-on: ubuntu-24.04
1414
strategy:
1515
matrix:
16-
#image: [ "ghcr.io/uvic-frodo/clang_libs-ubuntu_24-llvm_20:latest", "ghcr.io/uvic-frodo/clang_libs-fedora_41-llvm_20:latest" ]
16+
# NOTE: The repository is assumed to have been granted access to the
17+
# package corresponding to each of the images below.
1718
image:
18-
- "ghcr.io/mdadams/clang_libs-ubuntu_24-llvm_20:latest"
19-
- "ghcr.io/mdadams/clang_libs-fedora_41-llvm_20:latest"
19+
#- "ghcr.io/uvic-aurora/clang_libs-ubuntu_24-llvm_21:latest"
20+
#- "ghcr.io/uvic-aurora/clang_libs-fedora_42-llvm_21:latest"
21+
- "ghcr.io/mdadams/clang_libs-ubuntu_24-llvm_21:latest"
22+
- "ghcr.io/mdadams/clang_libs-fedora_42-llvm_21:latest"
2023
compiler:
2124
- gcc
2225
- clang

NEWS.txt

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,54 @@ NEWS
44
This document highlights some of the more significant changes from one
55
release of the lecture slides (and companion Git repository) to the next.
66

7+
Edition 0.4.0 (2025-08-15)
8+
==========================
9+
10+
Some of the more significant changes in going from Edition 0.3.0 to Edition
11+
0.4.0 are as follows:
12+
13+
- The slides and code examples have been updated to be based on
14+
LLVM/Clang 21. Some of the code examples may work with earlier
15+
versions of LLVM/Clang, but this is not officially supported. The API
16+
differences between different versions of LLVM/Clang are handled by
17+
conditional compilation in the case of the non-slide code examples and
18+
by using multiple separate source files in the case of code examples
19+
that appear on slides (so as to avoid clutter).
20+
21+
- Made a number of improvements to the code examples and added a new
22+
code example.
23+
724
Edition 0.3.0 (2025-03-07)
825
==========================
926

1027
Some of the more significant changes in going from Edition 0.2.0 to Edition
1128
0.3.0 are as follows:
1229

13-
* The slides and code examples have been updated to be based on
30+
- The slides and code examples have been updated to be based on
1431
LLVM/Clang 20. Some of the code examples may work with earlier
1532
versions of LLVM/Clang, but this is not officially supported. The API
1633
differences between different versions of LLVM/Clang are handled by
1734
conditional compilation in the case of the non-slide code examples and
1835
by using multiple separate source files in the case of code examples
1936
that appear on slides (so as to avoid clutter).
2037

21-
* Added new content related to (amongst other things):
38+
- Added new content related to (amongst other things):
2239
- ASTUnit and AST serialization/deserialization
2340
- various node visitor classes (e.g., DeclVisitor, StmtVisitor, etc.)
2441
- ASTNodeTraverser
2542
- VFS interface
2643
- IntrusiveRefCntPtr
2744
- DynamicRecursiveASTVisitor
2845

29-
* Added several new code examples, including (but not limited to):
46+
- Added several new code examples, including (but not limited to):
3047
- a simple text-based AST dumper based on ASTNodeTraverser
3148
- a simple text-based AST dumper based on RecursiveASTVisitor
3249
- a AST serialization and deserialization example using ASTUnit
3350

34-
* Improved the way in which the Clang include directory is being determined
51+
- Improved the way in which the Clang include directory is being determined
3552
in various places in the code.
3653

37-
* Made numerous smaller improvements to the slides (e.g., revised wording,
54+
- Made numerous smaller improvements to the slides (e.g., revised wording,
3855
added clarifying comments).
3956

4057
Edition 0.2.0 (2024-01-25)
@@ -43,39 +60,39 @@ Edition 0.2.0 (2024-01-25)
4360
Some of the more significant changes in going from Edition 0.1.0 to Edition
4461
0.2.0 are as follows:
4562

46-
* The slides and code examples have been updated to be based on
63+
- The slides and code examples have been updated to be based on
4764
LLVM/Clang 17, instead of Clang 15 (as was the case with the previous
4865
edition of the slides). The code examples still continue to work with
4966
LLVM/Clang 15 and 16, however. The API differences between LLVM/Clang
5067
15, 16, and 17 are handled by conditional compilation in the case of the
5168
non-slide code examples and by using multiple separate source files in
5269
the case of code examples that appear on slides (so as to avoid clutter).
5370

54-
* Numerous smaller improvements to the slides were made, including adding
71+
- Numerous smaller improvements to the slides were made, including adding
5572
more hyperlinks to external LLVM/Clang documentation.
5673

57-
* A Dockerfile was added to the Companion Git repository in order
74+
- A Dockerfile was added to the Companion Git repository in order
5875
to provide an easy-to-use environment in which to build and run the
5976
code examples. This is expected to be helpful to beginners who do not
6077
already have a working LLVM/Clang environment.
6178

62-
* Some bugs fixes and other improvements were made to the Clang Auxiliary
79+
- Some bugs fixes and other improvements were made to the Clang Auxiliary
6380
Library (CAL), including fixing some problems in the function used to
6481
determine the Clang include directory.
6582

66-
* A new CMake find module was introduced for LLVM and Clang in an
83+
- A new CMake find module was introduced for LLVM and Clang in an
6784
attempt to reduce boilerplate needed in many CMakeLists.txt files.
6885

69-
* Build-time introspection was added to determine whether the custom
86+
- Build-time introspection was added to determine whether the custom
7087
Fmt library is needed for std::format support.
7188

72-
* Many improvements were made to the scripts used (either directly or
89+
- Many improvements were made to the scripts used (either directly or
7390
indirectly) for running the various code examples for demo purposes.
7491

75-
* Many changes were made to the scripts and configuration files used
92+
- Many changes were made to the scripts and configuration files used
7693
for the GitHub CI workflow.
7794

78-
* A formal JSON schema for compilation databases was added for reference
95+
- A formal JSON schema for compilation databases was added for reference
7996
purposes.
8097

8198
Edition 0.1.0 (2023-08-03)
@@ -84,14 +101,14 @@ Edition 0.1.0 (2023-08-03)
84101
Some of the more significant changes in going from Edition 0.0 to Edition
85102
0.1.0 are as follows:
86103

87-
* Approximately 120 new slides were added along with a number of new code
104+
- Approximately 120 new slides were added along with a number of new code
88105
examples in the Git repository.
89106

90-
* Numerous improvements were made to the old content as well.
107+
- Numerous improvements were made to the old content as well.
91108

92109
Edition 0.0 (2022-12-31)
93110
========================
94111

95-
* This was the initial release of the lecture slides.
112+
- This was the initial release of the lecture slides.
96113

97-
* This edition of the slides is based on LLVM/Clang 15.
114+
- This edition of the slides is based on LLVM/Clang 15.

README.md

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ This repository contains all of the code examples that are associated
44
with the following slide deck:
55

66
- Michael D. Adams.
7-
*Lecture Slides for the Clang Libraries [LLVM/Clang 20]*.
8-
Edition 0.3.0,
9-
Mar. 2025.
7+
*Lecture Slides for the Clang Libraries [LLVM/Clang 21]*.
8+
Edition 0.4.0,
9+
Aug. 2025.
1010

1111
## Obtaining the Slide Deck
1212

@@ -41,20 +41,16 @@ provided build script (which invokes these two CMake superbuilds).
4141
This repository employs a CI workflow based on GitHub Actions. Each time
4242
a new commit is pushed, the code examples in the repository are built
4343
and run as a basic sanity test. The workflow employs Podman/Docker
44-
container images based on Ubuntu and Fedora Linux. The Ubuntu container
45-
image is based on the Ubuntu APT packages provided by the LLVM Project
46-
(at <https://apt.llvm.org/>). The Fedora container image is based on
47-
the author's own build of LLVM (since LLVM 20 was not yet packaged
48-
in Fedora Linux at the time that the container image was generated).
49-
The code examples are built using both Clang and GCC.
44+
container images based on Ubuntu and Fedora Linux. The code examples
45+
are built using both Clang and GCC.
5046

5147
## Prerequisites to Building the Software
5248

5349
The code examples have the following software dependencies:
5450

5551
- CMake
5652
- Make
57-
- version 20 of LLVM/Clang
53+
- version 21 of LLVM/Clang
5854
- GCC (if application programs are to be built with GCC)
5955
- Boost
6056
- Python
@@ -177,7 +173,7 @@ For this reason, a prebuilt version of the Podman/Docker container
177173
image has been made available via the following repository in the GitHub
178174
Container Registry:
179175

180-
- `ghcr.io/mdadams/clang_libs-fedora_41-llvm_20`
176+
- `ghcr.io/mdadams/clang_libs-fedora_42-llvm_21`
181177

182178
Instructions are given below on how to use this containerized environment.
183179
Although these instructions use (rootless) Podman, the `podman` and `docker`
@@ -203,13 +199,13 @@ be an absolute path.
203199
- Option 1 (Use the prebuilt image).
204200
To retrieve the prebuilt image, use the following command:
205201

206-
podman pull ghcr.io/mdadams/clang_libs-fedora_41-llvm_20
202+
podman pull ghcr.io/mdadams/clang_libs-fedora_42-llvm_21
207203

208204
- Option 2 (Build the image from scratch).
209205
To build the image from scratch, use the following command:
210206

211-
podman build --tag clang_libs-fedora_41-llvm_20 \
212-
-f $TOP_DIR/podman/Dockerfile-fedora_41-llvm_20 $TOP_DIR/podman
207+
podman build --tag clang_libs-fedora_42-llvm_21 \
208+
-f $TOP_DIR/podman/Dockerfile-fedora_42-llvm_21 $TOP_DIR/podman
213209

214210
Note that building the container image from scratch involves
215211
building LLVM, which takes a considerable amount of time.
@@ -219,7 +215,7 @@ be an absolute path.
219215

220216
podman run -i -t --rm -v $TOP_DIR:$TOP_DIR:rw -w $TOP_DIR \
221217
--cap-add=SYS_PTRACE --security-opt label=disable \
222-
clang_libs-fedora_41-llvm_20 /bin/bash
218+
clang_libs-fedora_42-llvm_21 /bin/bash
223219

224220
Note that the `--cap-add` and `--security-opt` options may not be
225221
needed. The `SYS_PTRACE` capability is typically needed in order
@@ -234,6 +230,9 @@ be an absolute path.
234230

235231
./build --defaults
236232

233+
If you want to control the number of parallel jobs (used for
234+
building), you can add the `--num-jobs` option.
235+
237236
## Remarks on the Use of Address Sanitizer (ASan)
238237

239238
Sometimes the use of Address Sanitizer (ASan) can be problematic, due,

slides/examples/ast_serialization_1/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
11
cmake_minimum_required(VERSION 3.14)
2+
23
project(ast_serialization_1 LANGUAGES CXX C)
34

45
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
56
include(CheckCXXCompilerFlag)
67
include(Sanitizers)
8+
include(ParseVersion)
79

810
#set(CMAKE_VERBOSE_MAKEFILE TRUE)
911
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
1012

1113
set(CMAKE_CXX_STANDARD 20)
14+
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
1215

1316
find_package(ClangFoo REQUIRED)
17+
parse_version_string("${LLVM_VERSION}" LLVM_MAJOR_VERSION LLVM_MINOR_VERSION
18+
LLVM_PATCH_VERSION)
1419
include(CheckStdFormat)
1520
import_std_format()
1621

1722
add_executable(load_ast)
18-
target_sources(load_ast PRIVATE load_ast.cpp)
23+
if(LLVM_MAJOR_VERSION GREATER_EQUAL 21)
24+
set(load_ast_sources load_ast.cpp)
25+
else()
26+
set(load_ast_sources clang-20/load_ast.cpp)
27+
endif()
28+
target_sources(load_ast PRIVATE ${load_ast_sources})
1929

2030
add_executable(save_ast)
2131
target_sources(save_ast PRIVATE save_ast.cpp)
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include <memory>
2+
#include <string>
3+
#include <clang/AST/ASTContext.h>
4+
#include <clang/AST/RecursiveASTVisitor.h>
5+
#include <clang/Basic/Diagnostic.h>
6+
#include <clang/Basic/DiagnosticOptions.h>
7+
#include <clang/Basic/FileSystemOptions.h>
8+
#include <clang/Basic/SourceManager.h>
9+
#include <clang/Frontend/ASTUnit.h>
10+
#include <clang/Frontend/FrontendOptions.h>
11+
#include <clang/Frontend/TextDiagnosticPrinter.h>
12+
#include <clang/Lex/Lexer.h>
13+
#include <clang/Serialization/PCHContainerOperations.h>
14+
#include <llvm/ADT/IntrusiveRefCntPtr.h>
15+
#include <llvm/ADT/StringRef.h>
16+
#include <llvm/Support/CommandLine.h>
17+
#include <llvm/Support/raw_ostream.h>
18+
19+
namespace lc = llvm::cl;
20+
21+
static lc::opt<std::string> InputASTFile(lc::Positional,
22+
lc::desc("input AST file"), lc::Required);
23+
24+
std::string getSourceText(const clang::SourceManager &sourceManager,
25+
const clang::LangOptions& langOpts, clang::SourceRange sourceRange) {
26+
assert(sourceRange.isValid());
27+
clang::SourceLocation beginLoc = sourceRange.getBegin();
28+
clang::SourceLocation endLoc = sourceRange.getEnd();
29+
if (beginLoc.isMacroID() || endLoc.isMacroID()) {return "@@SOURCE::MACRO@@"; }
30+
assert(beginLoc == sourceManager.getSpellingLoc(beginLoc));
31+
assert(endLoc == sourceManager.getSpellingLoc(endLoc));
32+
endLoc = clang::Lexer::getLocForEndOfToken(endLoc, 0, sourceManager,
33+
langOpts);
34+
assert(beginLoc.isValid() && endLoc.isValid());
35+
clang::FileID beginFileId = sourceManager.getFileID(beginLoc);
36+
clang::FileID endFileId = sourceManager.getFileID(endLoc);
37+
if (beginFileId != endFileId) {return "@@SOURCE::SPANS_FILES@@";}
38+
assert(beginLoc.isValid() && endLoc.isValid());
39+
unsigned beginOffset = sourceManager.getFileOffset(beginLoc);
40+
unsigned endOffset = sourceManager.getFileOffset(endLoc);
41+
std::size_t length = endOffset - beginOffset;
42+
llvm::StringRef buffer = sourceManager.getBufferData(beginFileId);
43+
return std::string(buffer.substr(beginOffset, length));
44+
}
45+
46+
class MyASTVisitor : public clang::RecursiveASTVisitor<MyASTVisitor> {
47+
public:
48+
explicit MyASTVisitor(clang::ASTUnit &astUnit) :
49+
sourceManager_(&astUnit.getSourceManager()),
50+
langOpts_(&astUnit.getLangOpts()) {}
51+
std::string makeHeading(const std::string& title)
52+
{return std::format("{:=^80}\n{}\n", "", title);}
53+
bool VisitDecl(clang::Decl *decl) {
54+
llvm::outs() << makeHeading(std::format("Decl: {}",
55+
std::string(decl->getDeclKindName())));
56+
clang::SourceRange sourceRange = decl->getSourceRange();
57+
if (sourceRange.isValid()) {
58+
llvm::outs() << getSourceText(*sourceManager_, *langOpts_,
59+
sourceRange) << '\n';
60+
}
61+
return true;
62+
}
63+
bool VisitStmt(clang::Stmt *stmt) {
64+
llvm::outs() << makeHeading(std::format("Stmt: {}",
65+
std::string(stmt->getStmtClassName())));
66+
clang::SourceRange sourceRange = stmt->getSourceRange();
67+
if (sourceRange.isValid()) {
68+
llvm::outs() << getSourceText(*sourceManager_, *langOpts_,
69+
sourceRange) << '\n';
70+
}
71+
return true;
72+
}
73+
private:
74+
clang::SourceManager* sourceManager_;
75+
const clang::LangOptions* langOpts_;
76+
};
77+
78+
int main(int argc, const char** argv) {
79+
lc::ParseCommandLineOptions(argc, argv, "AST deserializer\n");
80+
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts(
81+
new clang::DiagnosticOptions());
82+
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(
83+
new clang::DiagnosticIDs());
84+
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagEngine(
85+
new clang::DiagnosticsEngine(diagIDs, diagOpts,
86+
new clang::TextDiagnosticPrinter(llvm::errs(), &*diagOpts), true));
87+
clang::PCHContainerOperations pchContainerOps;
88+
clang::FileSystemOptions fileSysOpts;
89+
std::unique_ptr<clang::ASTUnit> astUnit = clang::ASTUnit::LoadFromASTFile(
90+
InputASTFile, pchContainerOps.getRawReader(),
91+
clang::ASTUnit::LoadEverything, diagEngine, fileSysOpts, nullptr);
92+
if (!astUnit) {
93+
llvm::errs() << "cannot load AST file\n";
94+
return 1;
95+
}
96+
clang::ASTContext &astContext = astUnit->getASTContext();
97+
clang::TranslationUnitDecl *tuDecl = astContext.getTranslationUnitDecl();
98+
llvm::outs() << std::format("main file name: {}\n",
99+
std::string_view(astUnit->getMainFileName()));
100+
llvm::outs() << std::format("language: {}\n",
101+
astUnit->getInputKind().getLanguage() == clang::Language::CXX ? "C++" :
102+
"other");
103+
const clang::LangOptions& langOpts = astUnit->getLangOpts();
104+
llvm::outs() << std::format("language standard unspecified: {}\n",
105+
langOpts.LangStd == clang::LangStandard::Kind::lang_unspecified);
106+
MyASTVisitor visitor(*astUnit);
107+
visitor.TraverseDecl(tuDecl);
108+
return 0;
109+
}

0 commit comments

Comments
 (0)