Skip to content

Commit

Permalink
ImportC add Win32 OMF preprocessor #define support
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright authored and dlang-bot committed May 20, 2022
1 parent f58acb3 commit 5807f1e
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 12 deletions.
5 changes: 3 additions & 2 deletions src/dmd/cpreprocess.d
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ version (Windows) version = runPreprocessor;
* loc = The source location where preprocess is requested from
* cppswitches = array of switches to pass to C preprocessor
* ifile = set to true if an output file was written
* defines = buffer to append any `#define` and `#undef` lines encountered to
* Result:
* filename of output
*/
extern (C++)
FileName preprocess(FileName csrcfile, ref const Loc loc, ref Array!(const(char)*) cppswitches, out bool ifile)
FileName preprocess(FileName csrcfile, ref const Loc loc, ref Array!(const(char)*) cppswitches, out bool ifile, OutBuffer* defines)
{
/* Look for "importc.h" by searching along import path.
* It should be in the same place as "object.d"
Expand Down Expand Up @@ -90,7 +91,7 @@ FileName preprocess(FileName csrcfile, ref const Loc loc, ref Array!(const(char)
assert(ext);
const ifilename = FileName.addExt(name[0 .. name.length - (ext.length + 1)], i_ext);
const command = cppCommand();
auto status = runPreprocessor(command, csrcfile.toString(), importc_h, cppswitches, ifilename);
auto status = runPreprocessor(command, csrcfile.toString(), importc_h, cppswitches, ifilename, defines);
if (status)
{
error(loc, "C preprocess command %.*s failed for file %s, exit status %d\n",
Expand Down
6 changes: 4 additions & 2 deletions src/dmd/dmodule.d
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ extern (C++) final class Module : Package
int selfimports; // 0: don't know, 1: does not, 2: does
Dsymbol[void*] tagSymTab; /// ImportC: tag symbols that conflict with other symbols used as the index

private OutBuffer defines; // collect all the #define lines here


/*************************************
* Return true if module imports itself.
*/
Expand Down Expand Up @@ -677,7 +680,7 @@ extern (C++) final class Module : Package
FileName.equalsExt(srcfile.toString(), c_ext) &&
FileName.exists(srcfile.toString()))
{
filename = global.preprocess(srcfile, loc, global.params.cppswitches, ifile); // run C preprocessor
filename = global.preprocess(srcfile, loc, global.params.cppswitches, ifile, &defines); // run C preprocessor
}

if (auto result = global.fileManager.lookup(filename))
Expand Down Expand Up @@ -975,7 +978,6 @@ extern (C++) final class Module : Package
{
filetype = FileType.c;

OutBuffer defines;
scope p = new CParser!AST(this, buf, cast(bool) docfile, target.c, &defines);
p.nextToken();
checkCompiledImport();
Expand Down
60 changes: 58 additions & 2 deletions src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ class TypeFunction;
class Initializer;
struct IntRange;
struct ModuleDeclaration;
template <typename Datum>
struct FileMapping;
struct Escape;
class WithStatement;
struct AA;
Expand Down Expand Up @@ -827,7 +829,7 @@ struct Global final
FileManager* fileManager;
enum : int32_t { recursionLimit = 500 };

FileName(*preprocess)(FileName , const Loc& , Array<const char* >& cppswitches, bool& );
FileName(*preprocess)(FileName , const Loc& , Array<const char* >& cppswitches, bool& , OutBuffer* defines);
uint32_t startGagging();
bool endGagging(uint32_t oldGagged);
void increaseErrorCount();
Expand Down Expand Up @@ -1630,6 +1632,57 @@ enum class FileType : uint8_t
c = 3u,
};

struct OutBuffer final
{
private:
_d_dynamicArray< uint8_t > data;
size_t offset;
bool notlinehead;
FileMapping<uint8_t >* fileMapping;
public:
bool doindent;
bool spaces;
int32_t level;
void dtor();
~OutBuffer();
size_t length() const;
char* extractData();
void destroy();
void reserve(size_t nbytes);
void setsize(size_t size);
void reset();
void write(const void* data, size_t nbytes);
void writestring(const char* s);
void prependstring(const char* string);
void writenl();
void writeByten(int32_t b);
void writeByte(uint32_t b);
void writeUTF8(uint32_t b);
void prependbyte(uint32_t b);
void writewchar(uint32_t w);
void writeword(uint32_t w);
void writeUTF16(uint32_t w);
void write4(uint32_t w);
void write(const OutBuffer* const buf);
void fill0(size_t nbytes);
void vprintf(const char* format, va_list args);
void printf(const char* format, ...);
void print(uint64_t u);
void bracket(char left, char right);
size_t bracket(size_t i, const char* left, size_t j, const char* right);
void spread(size_t offset, size_t nbytes);
size_t insert(size_t offset, const void* p, size_t nbytes);
void remove(size_t offset, size_t nbytes);
char* peekChars();
char* extractChars();
OutBuffer() :
doindent(),
spaces(),
level()
{
}
};

template <typename K, typename V>
struct AssocArray final
{
Expand Down Expand Up @@ -5512,7 +5565,7 @@ extern const char* toCppMangleDMC(Dsymbol* s);

extern const char* cppTypeInfoMangleDMC(Dsymbol* s);

extern FileName preprocess(FileName csrcfile, const Loc& loc, Array<const char* >& cppswitches, bool& ifile);
extern FileName preprocess(FileName csrcfile, const Loc& loc, Array<const char* >& cppswitches, bool& ifile, OutBuffer* defines);

class ClassReferenceExp final : public Expression
{
Expand Down Expand Up @@ -6085,6 +6138,9 @@ class Module final : public Package
int32_t needmoduleinfo;
int32_t selfimports;
void* tagSymTab;
private:
OutBuffer defines;
public:
bool selfImports();
int32_t rootimports;
bool rootImports();
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ extern (C++) struct Global

enum recursionLimit = 500; /// number of recursive template expansions before abort

extern (C++) FileName function(FileName, ref const Loc, ref Array!(const(char)*) cppswitches, out bool) preprocess;
extern (C++) FileName function(FileName, ref const Loc, ref Array!(const(char)*) cppswitches, out bool, OutBuffer* defines) preprocess;

nothrow:

Expand Down
2 changes: 1 addition & 1 deletion src/dmd/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ struct Global

FileManager* fileManager;

FileName (*preprocess)(FileName, const Loc&, Array<const char *>& cppswitches, bool&);
FileName (*preprocess)(FileName, const Loc&, Array<const char *>& cppswitches, bool&, OutBuffer&);

/* Start gagging. Return the current number of gagged errors
*/
Expand Down
49 changes: 46 additions & 3 deletions src/dmd/link.d
Original file line number Diff line number Diff line change
Expand Up @@ -1038,10 +1038,12 @@ public int runProgram()
* importc_h = filename of importc.h
* cppswitches = array of switches to pass to C preprocessor
* output = preprocessed output file name
* defines = buffer to append any `#define` and `#undef` lines encountered to
* Returns:
* exit status.
*/
public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char)* importc_h, ref Array!(const(char)*) cppswitches, const(char)[] output)
public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char)* importc_h, ref Array!(const(char)*) cppswitches,
const(char)[] output, OutBuffer* defines)
{
//printf("runPreprocessor() cpp: %.*s filename: %.*s\n", cast(int)cpp.length, cpp.ptr, cast(int)filename.length, filename.ptr);
version (Windows)
Expand Down Expand Up @@ -1134,7 +1136,7 @@ public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char
*/
OutBuffer buf;
buf.writestring(cpp);
buf.printf(" %.*s -HI%s -o%.*s",
buf.printf(" %.*s -HI%s -ED -o%.*s",
cast(int)filename.length, filename.ptr, importc_h, cast(int)output.length, output.ptr);

/* Append preprocessor switches to command line
Expand All @@ -1153,9 +1155,50 @@ public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char

ubyte[2048] buffer = void;

/* Write lines captured from stdout to either defines[] or stdout
*/
enum S
{
start, // start of line
hash, // write to defines[]
other, // write to stdout
}

S state = S.start;

void sinkomf(ubyte[] data)
{
printf("%.*s", cast(int)data.length, data.ptr);
foreach (c; data)
{
final switch (state)
{
case S.start:
if (c == '#')
{
defines.writeByte(c);
state = S.hash;
}
else
{
fputc(c, stdout);
state = S.other;
}
break;

case S.hash:
defines.writeByte(c);
if (c == '\n')
state = S.start;
break;

case S.other:
fputc(c, stdout);
if (c == '\n')
state = S.start;
break;
}
}
//printf("%.*s", cast(int)data.length, data.ptr);
}

// Convert command to wchar
Expand Down
1 change: 1 addition & 0 deletions src/dmd/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Module : public Package
int needmoduleinfo;
int selfimports; // 0: don't know, 1: does not, 2: does
void* tagSymTab; // ImportC: tag symbols that conflict with other symbols used as the index
OutBuffer defines; // collect all the #define lines here
bool selfImports(); // returns true if module imports itself

int rootimports; // 0: don't know, 1: does not, 2: does
Expand Down
2 changes: 1 addition & 1 deletion test/compilable/testdefines.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// DISABLED: win32 win64 win32mscoff
// DISABLED: win64 win32mscoff
#define GHI 3
_Static_assert(GHI == 3, "1");

0 comments on commit 5807f1e

Please sign in to comment.