ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
build_ast.cpp File Reference
#include <util/base/compiler_defs.h>
#include <clang/AST/ASTImporter.h>
#include <clang/AST/ASTImporterSharedState.h>
#include <clang/Basic/Version.inc>
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Driver/Options.h>
#include <clang/Frontend/ASTUnit.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Lex/PreprocessorOptions.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Option/ArgList.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/Path.h>
#include <clang-c-frontend/AST/build_ast.h>
#include <clang-c-frontend/AST/vfs_adapter.h>
#include <clang-c-frontend/AST/vfs_paths.h>
Include dependency graph for build_ast.cpp:

Functions

static clang::driver::Driver * newDriver (clang::DiagnosticsEngine *Diagnostics, const char *BinaryName, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS)
 Builds a clang driver initialized for running clang tools.
std::unique_ptr< clang::ASTUnit > buildASTs (const std::string &intrinsics, const std::vector< std::string > &compiler_args)
static void log_import_error (llvm::Error Err)
static void override_weak_var (clang::ASTImporter &Importer, clang::VarDecl &FromVar, clang::VarDecl &ToVar)
 The importer maps a variable definition onto one already in the destination and drops its initializer, so the definition merged first wins.
static void override_weak_function (clang::ASTImporter &Importer, clang::Decl *FromDecl, clang::Decl *Imported)
 As override_weak_var, for a function: its parameters map onto the merged decl's, so that the imported body refers to those.
static void override_weak (clang::ASTImporter &Importer, clang::Decl *FromDecl, clang::Decl *Imported)
 Applies the overrides to FromDecl and, since the importer brings in a namespace's members itself, to every member of a namespace.
static clang::Decl * importDecl (clang::ASTImporter &Importer, clang::Decl *FromDecl)
 Import one decl from the source context into Importer's destination.
void mergeASTs (const std::unique_ptr< clang::ASTUnit > &FromUnit, std::unique_ptr< clang::ASTUnit > &ToUnit)

Function Documentation

◆ buildASTs()

std::unique_ptr< clang::ASTUnit > buildASTs ( const std::string & intrinsics,
const std::vector< std::string > & compiler_args )

◆ importDecl()

clang::Decl * importDecl ( clang::ASTImporter & Importer,
clang::Decl * FromDecl )
static

Import one decl from the source context into Importer's destination.

Returns the imported decl, or nullptr if the import failed (the error is logged and consumed so the rest of the merge can proceed).

clang::ASTImporter::Import() imports the decl node itself but does NOT recurse into the children of a DeclContext such as a LinkageSpecDecl (extern "C" { ... }). Importing the wrapper alone yields an empty linkage-spec, so the functions inside it silently vanish from the merged AST. Every function in ESBMC's C++ operational models is declared inside an extern "C" block, which is why merging a second C++ translation unit dropped all of its symbols. C functions are direct children of the translation unit, so they import individually and were unaffected.

We therefore import each child of a LinkageSpecDecl explicitly and attach it to the imported wrapper's context.

◆ log_import_error()

void log_import_error ( llvm::Error Err)
static

◆ mergeASTs()

void mergeASTs ( const std::unique_ptr< clang::ASTUnit > & FromUnit,
std::unique_ptr< clang::ASTUnit > & ToUnit )

◆ newDriver()

clang::driver::Driver * newDriver ( clang::DiagnosticsEngine * Diagnostics,
const char * BinaryName,
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS )
static

Builds a clang driver initialized for running clang tools.

◆ override_weak()

void override_weak ( clang::ASTImporter & Importer,
clang::Decl * FromDecl,
clang::Decl * Imported )
static

Applies the overrides to FromDecl and, since the importer brings in a namespace's members itself, to every member of a namespace.

◆ override_weak_function()

void override_weak_function ( clang::ASTImporter & Importer,
clang::Decl * FromDecl,
clang::Decl * Imported )
static

As override_weak_var, for a function: its parameters map onto the merged decl's, so that the imported body refers to those.

◆ override_weak_var()

void override_weak_var ( clang::ASTImporter & Importer,
clang::VarDecl & FromVar,
clang::VarDecl & ToVar )
static

The importer maps a variable definition onto one already in the destination and drops its initializer, so the definition merged first wins.

A strong definition must override a weak one wherever it appears, as at link time (#7451).