Skip to content
Browse files

Add file/line information to entities and ports

Include the compiler infrastructure to vhdlpp for collecting the
file and line information and attaching it to entities and ports.
Make the parser store the file name during parse.

Create a libmisc library where I can put source files that are
used by multiple programs within the source tree.
  • Loading branch information...
1 parent d72f7ea commit ab8f623cea7dcba9b965f7cdc1da57c19b63c057 @steveicarus committed
View
17 Makefile.in
@@ -80,9 +80,9 @@ PS2PDF = @PS2PDF@
GIT = @GIT@
ifeq (@srcdir@,.)
-INCLUDE_PATH = -I.
+INCLUDE_PATH = -I. -Ilibmisc
else
-INCLUDE_PATH = -I. -I$(srcdir)
+INCLUDE_PATH = -I. -Ilibmisc -I$(srcdir) -I$(srcdir)/libmisc
endif
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
@@ -91,6 +91,9 @@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
+# Source files in the libmisc directory
+M = LineInfo.o StringHeap.o
+
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
@@ -104,9 +107,9 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
pform_disciplines.o pform_dump.o pform_types.o set_width.o \
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
- Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o PExpr.o PGate.o \
+ Attrib.o HName.o Module.o PDelays.o PEvent.o PExpr.o PGate.o \
PGenerate.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
- Statement.o AStatement.o StringHeap.o $(FF) $(TT)
+ Statement.o AStatement.o $M $(FF) $(TT)
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@@ -197,7 +200,7 @@ ifeq (@WIN32@,yes)
# The first step makes an ivl.exe that dlltool can use to make an
# export and import library, and the last link makes a, ivl.exe
# that really exports the things that the import library imports.
-ivl@EXEEXT@: $O $(srcdir)/ivl.def
+ivl@EXEEXT@: $O $(srcdir)/ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
dlltool --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
--output-lib libivl.a --output-exp ivl.exp
@@ -229,6 +232,10 @@ version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep/$*.d
+%.o: $(srcdir)/libmisc/%.cc
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
+ mv $*.d dep/$*.d
+
# Here are some explicit dependencies needed to get things going.
main.o: main.cc version_tag.h
View
202 StringHeap.cc
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
- *
- * This source code is free software; you can redistribute it
- * and/or modify it in source code form under the terms of the GNU
- * General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-# include "StringHeap.h"
-# include <cstdlib>
-# include <cstring>
-# include <cassert>
-# include "ivl_alloc.h"
-
-#ifdef CHECK_WITH_VALGRIND
-static char **string_pool = NULL;
-static unsigned string_pool_count = 0;
-#endif
-
-StringHeap::StringHeap()
-{
- cell_base_ = 0;
- cell_ptr_ = HEAPCELL;
- cell_count_ = 0;
-}
-
-StringHeap::~StringHeap()
-{
- // This is a planned memory leak. The string heap is intended
- // to hold permanently-allocated strings.
-}
-
-const char* StringHeap::add(const char*text)
-{
- unsigned len = strlen(text);
- assert((len+1) <= HEAPCELL);
-
- unsigned rem = HEAPCELL - cell_ptr_;
- if (rem < (len+1)) {
- cell_base_ = (char*)malloc(HEAPCELL);
-#ifdef CHECK_WITH_VALGRIND
- string_pool_count += 1;
- string_pool = (char **) realloc(string_pool,
- string_pool_count*sizeof(char **));
- string_pool[string_pool_count-1] = cell_base_;
-#endif
- cell_ptr_ = 0;
- cell_count_ += 1;
- assert(cell_base_ != 0);
- }
-
- char*res = cell_base_ + cell_ptr_;
- memcpy(res, text, len);
- cell_ptr_ += len;
- cell_base_[cell_ptr_++] = 0;
-
- assert(cell_ptr_ <= HEAPCELL);
-
- return res;
-}
-
-perm_string StringHeap::make(const char*text)
-{
- return perm_string(add(text));
-}
-
-
-StringHeapLex::StringHeapLex()
-{
- hit_count_ = 0;
- add_count_ = 0;
-
- for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1)
- hash_table_[idx] = 0;
-}
-
-StringHeapLex::~StringHeapLex()
-{
-}
-
-void StringHeapLex::cleanup()
-{
-#ifdef CHECK_WITH_VALGRIND
- for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) {
- free(string_pool[idx]);
- }
- free(string_pool);
- string_pool = NULL;
- string_pool_count = 0;
-
- for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) {
- hash_table_[idx] = 0;
- }
-#endif
-}
-
-unsigned StringHeapLex::add_hit_count() const
-{
- return hit_count_;
-}
-
-unsigned StringHeapLex::add_count() const
-{
- return add_count_;
-}
-
-static unsigned hash_string(const char*text)
-{
- unsigned h = 0;
-
- while (*text) {
- h = (h << 4) ^ (h >> 28) ^ *text;
- text += 1;
- }
- return h;
-}
-
-const char* StringHeapLex::add(const char*text)
-{
- unsigned hash_value = hash_string(text) % HASH_SIZE;
-
- /* If we easily find the string in the hash table, then return
- that and be done. */
- if (hash_table_[hash_value]
- && (strcmp(hash_table_[hash_value], text) == 0)) {
- hit_count_ += 1;
- return hash_table_[hash_value];
- }
-
- /* The existing hash entry is not a match. Replace it with the
- newly allocated value, and return the new pointer as the
- result to the add. */
- const char*res = StringHeap::add(text);
- hash_table_[hash_value] = res;
- add_count_ += 1;
-
- return res;
-}
-
-perm_string StringHeapLex::make(const char*text)
-{
- return perm_string(add(text));
-}
-
-perm_string StringHeapLex::make(const string&text)
-{
- return perm_string(add(text.c_str()));
-}
-
-bool operator == (perm_string a, const char*b)
-{
- if (a.str() == b)
- return true;
-
- if (! (a.str() && b))
- return false;
-
- if (strcmp(a.str(), b) == 0)
- return true;
-
- return false;
-}
-
-bool operator == (perm_string a, perm_string b)
-{
- return a == b.str();
-}
-
-bool operator != (perm_string a, const char*b)
-{
- return ! (a == b);
-}
-
-bool operator != (perm_string a, perm_string b)
-{
- return ! (a == b);
-}
-
-bool operator < (perm_string a, perm_string b)
-{
- if (b.str() && !a.str())
- return true;
-
- if (b.str() == a.str())
- return false;
-
- if (strcmp(a.str(), b.str()) < 0)
- return true;
-
- return false;
-}
View
121 StringHeap.h
@@ -1,121 +0,0 @@
-#ifndef __StringHeap_H
-#define __StringHeap_H
-/*
- * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
- *
- * This source code is free software; you can redistribute it
- * and/or modify it in source code form under the terms of the GNU
- * General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-# include "config.h"
-# include <string>
-
-using namespace std;
-
-class perm_string {
-
- public:
- perm_string() : text_(0) { }
- perm_string(const perm_string&that) : text_(that.text_) { }
- ~perm_string() { }
-
- perm_string& operator = (const perm_string&that)
- { text_ = that.text_; return *this; }
-
- const char*str() const { return text_; }
- operator const char* () const { return str(); }
-
- // This is an escape for making perm_string objects out of
- // literals. For example, perm_string::literal("Label"); Please
- // do *not* cheat and pass arbitrary const char* items here.
- static perm_string literal(const char*t) { return perm_string(t); }
-
- private:
- friend class StringHeap;
- friend class StringHeapLex;
- perm_string(const char*t) : text_(t) { };
-
- private:
- const char*text_;
-};
-
-extern bool operator == (perm_string a, perm_string b);
-extern bool operator == (perm_string a, const char* b);
-extern bool operator != (perm_string a, perm_string b);
-extern bool operator != (perm_string a, const char* b);
-extern bool operator > (perm_string a, perm_string b);
-extern bool operator < (perm_string a, perm_string b);
-extern bool operator >= (perm_string a, perm_string b);
-extern bool operator <= (perm_string a, perm_string b);
-
-/*
- * The string heap is a way to permanently allocate strings
- * efficiently. They only take up the space of the string characters
- * and the terminating nul, there is no malloc overhead.
- */
-class StringHeap {
-
- public:
- StringHeap();
- ~StringHeap();
-
- const char*add(const char*);
- perm_string make(const char*);
-
- private:
- enum { HEAPCELL = 0x10000 };
-
- char*cell_base_;
- unsigned cell_ptr_;
- unsigned cell_count_;
-
- private: // not implemented
- StringHeap(const StringHeap&);
- StringHeap& operator= (const StringHeap&);
-};
-
-/*
- * A lexical string heap is a string heap that makes an effort to
- * return the same pointer for identical strings. This saves further
- * space by not allocating duplicate strings, so in a system with lots
- * of identifiers, this can theoretically save more space.
- */
-class StringHeapLex : private StringHeap {
-
- public:
- StringHeapLex();
- ~StringHeapLex();
-
- const char*add(const char*);
- perm_string make(const char*);
- perm_string make(const string&);
-
- unsigned add_count() const;
- unsigned add_hit_count() const;
- void cleanup();
-
- private:
- enum { HASH_SIZE = 4096 };
- const char*hash_table_[HASH_SIZE];
-
- unsigned add_count_;
- unsigned hit_count_;
-
- private: // not implemented
- StringHeapLex(const StringHeapLex&);
- StringHeapLex& operator= (const StringHeapLex&);
-};
-
-#endif
View
4 LineInfo.cc → libmisc/LineInfo.cc
@@ -17,11 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-# include "config.h"
-
# include "LineInfo.h"
# include <sstream>
+using namespace std;
+
LineInfo::LineInfo()
: lineno_(0)
{
View
0 LineInfo.h → libmisc/LineInfo.h
File renamed without changes.
View
0 vhdlpp/StringHeap.cc → libmisc/StringHeap.cc
File renamed without changes.
View
1 vhdlpp/StringHeap.h → libmisc/StringHeap.h
@@ -19,7 +19,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-# include "config.h"
# include <string>
using namespace std;
View
11 vhdlpp/Makefile.in
@@ -40,9 +40,9 @@ LEX = @LEX@
YACC = @YACC@
ifeq (.,.)
-INCLUDE_PATH = -I. -I..
+INCLUDE_PATH = -I. -I.. -I../libmisc
else
-INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
+INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/../libmisc
endif
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
@@ -51,8 +51,10 @@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ @EXTRALIBS@
+M = StringHeap.o LineInfo.o
+
O = main.o compiler.o entity.o entity_elaborate.o \
- lexor.o lexor_keyword.o parse.o StringHeap.o
+ lexor.o lexor_keyword.o parse.o $M
all: dep vhdlpp@EXEEXT@
@@ -73,6 +75,9 @@ dep:
vhdlpp@EXEEXT@: $O
$(CXX) -o vhdlpp@EXEEXT@ $(LDFLAGS) $O $(LIBS)
+%.o: $(srcdir)/../libmisc/%.cc
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
+
%.o: %.cc vhdlpp_config.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep/$*.d
View
2 vhdlpp/compiler.cc
@@ -19,3 +19,5 @@
# include "compiler.h"
StringHeapLex lex_strings;
+
+StringHeapLex filename_strings;
View
2 vhdlpp/compiler.h
@@ -28,4 +28,6 @@ extern bool verbose_flag;
extern StringHeapLex lex_strings;
+extern StringHeapLex filename_strings;
+
#endif
View
5 vhdlpp/entity.cc
@@ -47,7 +47,7 @@ static ostream& operator << (ostream&out, port_mode_t that)
static void dump_design_entity(ostream&out, Entity*obj)
{
- out << "entity " << obj->name << endl;
+ out << "entity " << obj->name << " file=" << obj->get_fileline() << endl;
if (obj->ports.size() == 0) {
out << " No ports" << endl;
} else {
@@ -57,7 +57,8 @@ static void dump_design_entity(ostream&out, Entity*obj)
InterfacePort*item = *cur;
out << setw(6) << "" << item->name
<< " : " << item->mode
- << ", type=" << item->type_name << endl;
+ << ", type=" << item->type_name
+ << ", file=" << item->get_fileline() << endl;
}
}
}
View
5 vhdlpp/entity.h
@@ -22,10 +22,11 @@
# include <map>
# include <vector>
# include "StringHeap.h"
+# include "LineInfo.h"
typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t;
-class InterfacePort {
+class InterfacePort : public LineInfo {
public:
// Port direction from the source code.
port_mode_t mode;
@@ -35,7 +36,7 @@ class InterfacePort {
perm_string type_name;
};
-class Entity {
+class Entity : public LineInfo {
public:
int elaborate();
View
1 vhdlpp/lexor.lex
@@ -98,6 +98,7 @@ extern void yyparse_set_filepath(const char*path);
void reset_lexor(FILE*fd, const char*path)
{
+ yylloc.text = path;
yylloc.first_line = 1;
yyrestart(fd);
View
9 vhdlpp/parse.y
@@ -25,6 +25,13 @@
# include <cstdarg>
# include <list>
+inline void FILE_NAME(LineInfo*tmp, const struct yyltype&where)
+{
+ tmp->set_lineno(where.first_line);
+ tmp->set_file(filename_strings.make(where.text));
+}
+
+
static void yyerror(const char*msg);
static void errormsg(const YYLTYPE&loc, const char*msg, ...);
@@ -135,6 +142,7 @@ design_units
entity_declaration
: K_entity IDENTIFIER K_is entity_header K_end K_entity ';'
{ Entity*tmp = new Entity;
+ FILE_NAME(tmp, @1);
// Store the name
tmp->name = lex_strings.make($2);
delete[]$2;
@@ -170,6 +178,7 @@ factor : primary ;
interface_element
: IDENTIFIER ':' mode IDENTIFIER
{ InterfacePort*tmp = new InterfacePort;
+ FILE_NAME(tmp, @1);
tmp->mode = $3;
tmp->name = lex_strings.make($1);
tmp->type_name = lex_strings.make($4);

0 comments on commit ab8f623

Please sign in to comment.
Something went wrong with that request. Please try again.