diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 54fb59e2a..c6ebe76fe 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -1073,8 +1073,6 @@ class EmitCImp : EmitCStmts { } ofp->puts("// See "+v3Global.opt.prefix()+".h for the primary calling header\n"); } - ofp->puts("\n"); - return ofp; } @@ -2536,8 +2534,7 @@ void EmitCImp::emitMTaskState() { void EmitCImp::emitInt(AstNodeModule* modp) { // Always have this first; gcc has short circuiting if #ifdef is first in a file - puts("#ifndef _"+modClassName(modp)+"_H_\n"); - puts("#define _"+modClassName(modp)+"_H_\n"); + ofp()->putsGuard(); puts("\n"); ofp()->putsIntTopInclude(); @@ -2757,12 +2754,13 @@ void EmitCImp::emitInt(AstNodeModule* modp) { } // finish up h-file - puts("#endif // guard\n"); + ofp()->putsEndGuard(); } //---------------------------------------------------------------------- void EmitCImp::emitImp(AstNodeModule* modp) { + puts("\n"); puts("#include \""+modClassName(modp)+".h\"\n"); puts("#include \""+symClassName()+".h\"\n"); @@ -2770,8 +2768,8 @@ void EmitCImp::emitImp(AstNodeModule* modp) { puts("\n"); puts("#include \"verilated_dpi.h\"\n"); } - puts("\n"); + puts("\n"); emitTextSection(AstType::atScImpHdr); if (m_slow && splitFilenum()==0) { diff --git a/src/V3EmitCInlines.cpp b/src/V3EmitCInlines.cpp index 28946e809..344d29e13 100644 --- a/src/V3EmitCInlines.cpp +++ b/src/V3EmitCInlines.cpp @@ -101,8 +101,7 @@ void EmitCInlines::emitInt() { m_ofp = &hf; ofp()->putsHeader(); - puts("#ifndef _"+topClassName()+"__Inlines_H_\n"); - puts("#define _"+topClassName()+"__Inlines_H_\n"); + ofp()->putsGuard(); puts("\n"); puts("#include \"verilated.h\"\n"); @@ -112,7 +111,7 @@ void EmitCInlines::emitInt() { // Placeholder - v3Global.needHInlines(true) currently not used puts("//======================\n\n"); - puts("#endif // guard\n"); + ofp()->putsEndGuard(); } //###################################################################### diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index dfbc62b73..5b55a02e7 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -372,12 +372,10 @@ void EmitCSyms::emitSymHdr() { puts("//\n"); puts("// Internal details; most calling programs do not need this header,\n"); puts("// unless using verilator public meta comments.\n"); - puts("\n"); - puts("#ifndef _"+symClassName()+"_H_\n"); - puts("#define _"+symClassName()+"_H_\n"); - puts("\n"); + ofp()->putsGuard(); + puts("\n"); ofp()->putsIntTopInclude(); if (v3Global.needHeavy()) { puts("#include \"verilated_heavy.h\"\n"); @@ -474,8 +472,8 @@ void EmitCSyms::emitSymHdr() { } puts("\n"); puts("} VL_ATTR_ALIGNED(64);\n"); - puts("\n"); - puts("#endif // guard\n"); + + ofp()->putsEndGuard(); } void EmitCSyms::closeSplit() { diff --git a/src/V3File.cpp b/src/V3File.cpp index cbf857e9b..46c81ded5 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -25,6 +25,7 @@ #include "V3File.h" #include "V3Os.h" #include "V3PreShell.h" +#include "V3String.h" #include "V3Ast.h" #include @@ -942,6 +943,17 @@ void V3OutFile::putsForceIncs() { } } +void V3OutCFile::putsGuard() { + UASSERT(!m_guard, "Already called putsGuard in emit file"); + m_guard = true; + string var = VString::upcase(string("_") + V3Os::filenameNonDir(filename()) + "_"); + for (string::iterator pos = var.begin(); pos != var.end(); ++pos) { + if (!isalnum(*pos)) *pos = '_'; + } + puts("\n#ifndef " + var + "\n"); + puts("#define " + var + " // guard\n"); +} + //###################################################################### // VIdProtect diff --git a/src/V3File.h b/src/V3File.h index 2c0997283..3f429ed66 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -138,6 +138,7 @@ public: V3OutFormatter(const string& filename, Language lang); virtual ~V3OutFormatter() {} // ACCESSORS + string filename() const { return m_filename; } int column() const { return m_column; } int blockIndent() const { return m_blockIndent; } void blockIndent(int flag) { m_blockIndent = flag; } @@ -186,23 +187,28 @@ private: }; class V3OutCFile : public V3OutFile { - int m_private; + int m_guard; // Created header guard + int m_private; // 1 = Most recently emitted private:, 2 = public: public: - explicit V3OutCFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_C) { + explicit V3OutCFile(const string& filename) + : V3OutFile(filename, V3OutFormatter::LA_C) + , m_guard(false) { resetPrivate(); } virtual ~V3OutCFile() {} virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); } - virtual void putsIntTopInclude() { - putsForceIncs(); + virtual void putsIntTopInclude() { putsForceIncs(); } + virtual void putsGuard(); + virtual void putsEndGuard() { + if (m_guard) puts("\n#endif // guard\n"); } // Print out public/privates void resetPrivate() { m_private = 0; } void putsPrivate(bool setPrivate) { - if (setPrivate && m_private!=1) { + if (setPrivate && m_private != 1) { puts("private:\n"); m_private = 1; - } else if (!setPrivate && m_private!=2) { + } else if (!setPrivate && m_private != 2) { puts("public:\n"); m_private = 2; } diff --git a/src/V3String.cpp b/src/V3String.cpp index 79869dbdf..9e1a5b0d6 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -88,6 +88,14 @@ string VString::downcase(const string& str) { return out; } +string VString::upcase(const string& str) { + string out = str; + for (string::iterator pos = out.begin(); pos != out.end(); ++pos) { + *pos = toupper(*pos); + } + return out; +} + string VString::quotePercent(const string& str) { string out; for (string::const_iterator pos = str.begin(); pos != str.end(); ++pos) { diff --git a/src/V3String.h b/src/V3String.h index d04629606..ace8428c3 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -65,8 +65,10 @@ public: static bool wildmatch(const char* s, const char* p); // Return {a}{dot}{b}, omitting dot if a or b are empty static string dot(const string& a, const string& dot, const string& b); - // Convert string to lowercase + // Convert string to lowercase (tolower) static string downcase(const string& str); + // Convert string to upper case (toupper) + static string upcase(const string& str); // Replace any %'s with %% static string quotePercent(const string& str); // Replace any unprintable with space