mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 09:31:03 +03:00
Run C preprocessor
This commit is contained in:
parent
f21241b662
commit
5b137768a0
17 changed files with 112 additions and 24 deletions
|
@ -378,6 +378,7 @@ set(DRV_SRC
|
||||||
driver/cl_options-llvm.cpp
|
driver/cl_options-llvm.cpp
|
||||||
driver/codegenerator.cpp
|
driver/codegenerator.cpp
|
||||||
driver/configfile.cpp
|
driver/configfile.cpp
|
||||||
|
driver/cpreprocessor.cpp
|
||||||
driver/dcomputecodegenerator.cpp
|
driver/dcomputecodegenerator.cpp
|
||||||
driver/exe_path.cpp
|
driver/exe_path.cpp
|
||||||
driver/targetmachine.cpp
|
driver/targetmachine.cpp
|
||||||
|
|
|
@ -352,7 +352,7 @@ int createStaticLibrary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoke external archiver
|
// invoke external archiver
|
||||||
return executeToolAndWait(tool, args, global.params.verbose);
|
return executeToolAndWait(Loc(), tool, args, global.params.verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getPathToProducedStaticLibrary() {
|
const char *getPathToProducedStaticLibrary() {
|
||||||
|
|
84
driver/cpreprocessor.cpp
Normal file
84
driver/cpreprocessor.cpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#include "driver/cpreprocessor.h"
|
||||||
|
|
||||||
|
#include "dmd/errors.h"
|
||||||
|
#include "driver/cl_options.h"
|
||||||
|
#include "driver/tool.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const char *getPathToImportc_h(const Loc &loc) {
|
||||||
|
// importc.h should be next to object.d
|
||||||
|
static const char *cached = nullptr;
|
||||||
|
if (!cached) {
|
||||||
|
cached = FileName::searchPath(global.path, "importc.h", false);
|
||||||
|
if (!cached) {
|
||||||
|
error(loc, "cannot find \"importc.h\" along import path");
|
||||||
|
fatal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
FileName runCPreprocessor(FileName csrcfile, const Loc &loc, bool &ifile,
|
||||||
|
OutBuffer &defines) {
|
||||||
|
const char *importc_h = getPathToImportc_h(loc);
|
||||||
|
const char *ifilename = FileName::forceExt(csrcfile.toChars(), i_ext.ptr);
|
||||||
|
|
||||||
|
const auto &triple = *global.params.targetTriple;
|
||||||
|
const bool isMSVC = triple.isWindowsMSVCEnvironment();
|
||||||
|
|
||||||
|
#if 0 //ifdef _WIN32
|
||||||
|
// TODO: INCLUDE env var etc.?
|
||||||
|
windows::MsvcEnvironmentScope msvcEnv;
|
||||||
|
if (isMSVC)
|
||||||
|
msvcEnv.setup();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const std::string cc = getGcc(isMSVC ? "cl.exe" : "cc");
|
||||||
|
std::vector<std::string> args;
|
||||||
|
|
||||||
|
if (!isMSVC)
|
||||||
|
appendTargetArgsForGcc(args);
|
||||||
|
|
||||||
|
if (triple.isOSDarwin())
|
||||||
|
args.push_back("-fno-blocks"); // disable blocks extension
|
||||||
|
|
||||||
|
for (const auto &ccSwitch : opts::ccSwitches) {
|
||||||
|
args.push_back(ccSwitch);
|
||||||
|
}
|
||||||
|
// TODO: -Xcpp switches?
|
||||||
|
|
||||||
|
if (isMSVC) {
|
||||||
|
args.push_back("/P"); // run preprocessor
|
||||||
|
args.push_back("/Zc:preprocessor"); // use the new conforming preprocessor
|
||||||
|
args.push_back("/PD"); // undocumented: print all macro definitions
|
||||||
|
args.push_back("/nologo");
|
||||||
|
args.push_back(csrcfile.toChars());
|
||||||
|
args.push_back((llvm::Twine("/FI") + importc_h).str());
|
||||||
|
// preprocessed output file
|
||||||
|
args.push_back((llvm::Twine("/Fi") + ifilename).str());
|
||||||
|
} else { // Posix
|
||||||
|
// merge #define's with output:
|
||||||
|
// https://gcc.gnu.org/onlinedocs/cpp/Invocation.html#index-dD
|
||||||
|
args.push_back("-dD");
|
||||||
|
|
||||||
|
// need to redefine some macros in importc.h
|
||||||
|
args.push_back("-Wno-builtin-macro-redefined");
|
||||||
|
|
||||||
|
args.push_back("-E"); // run preprocessor only
|
||||||
|
args.push_back("-include");
|
||||||
|
args.push_back(importc_h);
|
||||||
|
args.push_back(csrcfile.toChars());
|
||||||
|
args.push_back("-o");
|
||||||
|
args.push_back(ifilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int status = executeToolAndWait(loc, cc, args, global.params.verbose);
|
||||||
|
if (status) {
|
||||||
|
errorSupplemental(loc, "C preprocessor failed for file '%s'", csrcfile.toChars());
|
||||||
|
fatal();
|
||||||
|
}
|
||||||
|
|
||||||
|
ifile = true;
|
||||||
|
return FileName::create(ifilename);
|
||||||
|
}
|
8
driver/cpreprocessor.h
Normal file
8
driver/cpreprocessor.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dmd/common/outbuffer.h"
|
||||||
|
#include "dmd/globals.h"
|
||||||
|
#include "dmd/root/filename.h"
|
||||||
|
|
||||||
|
FileName runCPreprocessor(FileName csrcfile, const Loc &loc, bool &ifile,
|
||||||
|
OutBuffer &defines);
|
|
@ -858,5 +858,6 @@ int linkObjToBinaryGcc(llvm::StringRef outputPath,
|
||||||
logstr << "\n"; // FIXME where's flush ?
|
logstr << "\n"; // FIXME where's flush ?
|
||||||
|
|
||||||
// try to call linker
|
// try to call linker
|
||||||
return executeToolAndWait(tool, argsBuilder->args, global.params.verbose);
|
return executeToolAndWait(Loc(), tool, argsBuilder->args,
|
||||||
|
global.params.verbose);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,11 +88,6 @@ void addSanitizerLibs(std::vector<std::string> &args) {
|
||||||
|
|
||||||
int linkObjToBinaryMSVC(llvm::StringRef outputPath,
|
int linkObjToBinaryMSVC(llvm::StringRef outputPath,
|
||||||
const std::vector<std::string> &defaultLibNames) {
|
const std::vector<std::string> &defaultLibNames) {
|
||||||
if (!opts::ccSwitches.empty()) {
|
|
||||||
error(Loc(), "-Xcc is not supported for MSVC");
|
|
||||||
fatal();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
windows::MsvcEnvironmentScope msvcEnv;
|
windows::MsvcEnvironmentScope msvcEnv;
|
||||||
|
|
||||||
|
@ -309,5 +304,5 @@ int linkObjToBinaryMSVC(llvm::StringRef outputPath,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return executeToolAndWait(linker, args, global.params.verbose);
|
return executeToolAndWait(Loc(), linker, args, global.params.verbose);
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,7 +323,7 @@ int runProgram() {
|
||||||
|
|
||||||
// Run executable
|
// Run executable
|
||||||
int status =
|
int status =
|
||||||
executeToolAndWait(gExePath, opts::runargs, global.params.verbose);
|
executeToolAndWait(Loc(), gExePath, opts::runargs, global.params.verbose);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
error(Loc(), "program received signal %d", -status);
|
error(Loc(), "program received signal %d", -status);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "driver/cl_options_sanitizers.h"
|
#include "driver/cl_options_sanitizers.h"
|
||||||
#include "driver/codegenerator.h"
|
#include "driver/codegenerator.h"
|
||||||
#include "driver/configfile.h"
|
#include "driver/configfile.h"
|
||||||
|
#include "driver/cpreprocessor.h"
|
||||||
#include "driver/dcomputecodegenerator.h"
|
#include "driver/dcomputecodegenerator.h"
|
||||||
#include "driver/exe_path.h"
|
#include "driver/exe_path.h"
|
||||||
#include "driver/ldc-version.h"
|
#include "driver/ldc-version.h"
|
||||||
|
@ -1183,6 +1184,8 @@ int cppmain() {
|
||||||
global.params.dllimport = DLLImport::none;
|
global.params.dllimport = DLLImport::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global.preprocess = &runCPreprocessor;
|
||||||
|
|
||||||
// allocate the target abi
|
// allocate the target abi
|
||||||
gABI = TargetABI::getTarget();
|
gABI = TargetABI::getTarget();
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ static void assemble(const std::string &asmpath, const std::string &objpath) {
|
||||||
appendTargetArgsForGcc(args);
|
appendTargetArgsForGcc(args);
|
||||||
|
|
||||||
// Run the compiler to assembly the program.
|
// Run the compiler to assembly the program.
|
||||||
int R = executeToolAndWait(getGcc(), args, global.params.verbose);
|
int R = executeToolAndWait(Loc(), getGcc(), args, global.params.verbose);
|
||||||
if (R) {
|
if (R) {
|
||||||
error(Loc(), "Error while invoking external assembler.");
|
error(Loc(), "Error while invoking external assembler.");
|
||||||
fatal();
|
fatal();
|
||||||
|
|
|
@ -76,7 +76,7 @@ std::string getProgram(const char *fallbackName,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string getGcc() { return getProgram("cc", &gcc, "CC"); }
|
std::string getGcc(const char *fallback) { return getProgram(fallback, &gcc, "CC"); }
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -223,11 +223,11 @@ std::vector<const char *> getFullArgs(const char *tool,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int executeToolAndWait(const std::string &tool_,
|
int executeToolAndWait(const Loc &loc, const std::string &tool_,
|
||||||
const std::vector<std::string> &args, bool verbose) {
|
const std::vector<std::string> &args, bool verbose) {
|
||||||
const auto tool = findProgramByName(tool_);
|
const auto tool = findProgramByName(tool_);
|
||||||
if (tool.empty()) {
|
if (tool.empty()) {
|
||||||
error(Loc(), "cannot find program `%s`", tool_.c_str());
|
error(loc, "cannot find program `%s`", tool_.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,9 +249,9 @@ int executeToolAndWait(const std::string &tool_,
|
||||||
args::executeAndWait(std::move(fullArgs), rspEncoding, &errorMsg);
|
args::executeAndWait(std::move(fullArgs), rspEncoding, &errorMsg);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
error(Loc(), "%s failed with status: %d", tool.c_str(), status);
|
error(loc, "%s failed with status: %d", tool.c_str(), status);
|
||||||
if (!errorMsg.empty()) {
|
if (!errorMsg.empty()) {
|
||||||
errorSupplemental(Loc(), "message: %s", errorMsg.c_str());
|
errorSupplemental(loc, "message: %s", errorMsg.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,13 @@
|
||||||
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
|
||||||
|
struct Loc;
|
||||||
|
|
||||||
namespace opts {
|
namespace opts {
|
||||||
extern llvm::cl::opt<std::string> linker;
|
extern llvm::cl::opt<std::string> linker;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getGcc();
|
std::string getGcc(const char *fallback = "cc");
|
||||||
void appendTargetArgsForGcc(std::vector<std::string> &args);
|
void appendTargetArgsForGcc(std::vector<std::string> &args);
|
||||||
|
|
||||||
std::string getProgram(const char *fallbackName,
|
std::string getProgram(const char *fallbackName,
|
||||||
|
@ -37,7 +39,7 @@ std::vector<const char *> getFullArgs(const char *tool,
|
||||||
const std::vector<std::string> &args,
|
const std::vector<std::string> &args,
|
||||||
bool printVerbose);
|
bool printVerbose);
|
||||||
|
|
||||||
int executeToolAndWait(const std::string &tool,
|
int executeToolAndWait(const Loc &loc, const std::string &tool,
|
||||||
const std::vector<std::string> &args,
|
const std::vector<std::string> &args,
|
||||||
bool verbose = false);
|
bool verbose = false);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* Do a smoke test of the C Standard headers.
|
/* Do a smoke test of the C Standard headers.
|
||||||
* Many platforms do not support all the C Standard headers.
|
* Many platforms do not support all the C Standard headers.
|
||||||
* DISABLED: LDC // FIXME: needs preprocessor
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
|
@ -15,7 +15,6 @@ int y = ((size_t)((char *)&((struct Foo *)1)->x - (char *)1));
|
||||||
_Static_assert(((size_t)((char *)&((struct Foo *)0)->y - (char *)0))==4, "");
|
_Static_assert(((size_t)((char *)&((struct Foo *)0)->y - (char *)0))==4, "");
|
||||||
|
|
||||||
|
|
||||||
/* LDC FIXME: needs preprocessor (for including importc.h)
|
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=23584
|
// https://issues.dlang.org/show_bug.cgi?id=23584
|
||||||
|
|
||||||
int foo(float bar)
|
int foo(float bar)
|
||||||
|
@ -28,4 +27,3 @@ void test23584()
|
||||||
int i = foo(3.5);
|
int i = foo(3.5);
|
||||||
_Static_assert(foo(3.5) == 0x40600000, "1");
|
_Static_assert(foo(3.5) == 0x40600000, "1");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=23214
|
// https://issues.dlang.org/show_bug.cgi?id=23214
|
||||||
// DISABLED: LDC // FIXME - need to invoke C pre-processor
|
|
||||||
|
|
||||||
typedef unsigned __int64 uintptr_t;
|
typedef unsigned __int64 uintptr_t;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// DISABLED: LDC // FIXME: needs preprocessor
|
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=23580
|
// https://issues.dlang.org/show_bug.cgi?id=23580
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=23581
|
// https://issues.dlang.org/show_bug.cgi?id=23581
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=23582
|
// https://issues.dlang.org/show_bug.cgi?id=23582
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// DISABLED: LDC // FIXME: needs preprocessor
|
|
||||||
// https://issues.dlang.org/show_bug.cgi?id=23616
|
// https://issues.dlang.org/show_bug.cgi?id=23616
|
||||||
|
|
||||||
#if __has_extension(gnu_asm)
|
#if __has_extension(gnu_asm)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// DISABLED: LDC // FIXME: needs preprocessor for __LINE__
|
// DISABLED: LDC // FIXME: needs support for importC special cases
|
||||||
|
|
||||||
/* Test initializers */
|
/* Test initializers */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue