SUGGESTED FIX
diff --git a/make/solaris/makefiles/adlc.make b/make/solaris/makefiles/adlc.make
--- a/make/solaris/makefiles/adlc.make
+++ b/make/solaris/makefiles/adlc.make
@@ -54,9 +54,11 @@ Src_Dirs_I = ${Src_Dirs} $(GENERATED)
Src_Dirs_I = ${Src_Dirs} $(GENERATED)
INCLUDES += $(Src_Dirs_I:%=-I%)
+# set flags for adlc compilation
+CPPFLAGS = $(SYSDEFS) $(INCLUDES)
+
# Force assertions on.
-SYSDEFS += -DASSERT
-CPPFLAGS = $(SYSDEFS) $(INCLUDES)
+CPPFLAGS += -DASSERT
ifndef USE_GCC
# We need libCstd.so for adlc
@@ -141,7 +143,15 @@ all: $(GENERATEDFILES)
# Note that product files are updated via "mv", which is atomic.
TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$)
-ADLCFLAGS = -q -T
+# Pass -D flags into ADLC.
+ADLCFLAGS += $(SYSDEFS)
+
+# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO.
+ADLCFLAGS += -q -T
+
+# Normally, debugging is done directly on the ad_<arch>*.cpp files.
+# But -g will put #line directives in those files pointing back to <arch>.ad.
+#ADLCFLAGS += -g
ifdef LP64
ADLCFLAGS += -D_LP64
@@ -190,7 +200,15 @@ refresh_adfiles: $(EXEC) $(SOURCE.AD)
# #########################################################################
$(SOURCE.AD): $(SOURCES.AD)
- $(QUIETLY) cat $(SOURCES.AD) > $(SOURCE.AD)
+ $(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD)
+
+#PROCESS_AD_FILES = cat
+# Pass through #line directives, in case user enables -g option above:
+PROCESS_AD_FILES = awk '{ \
+ if (NR==1) need_lineno=1; \
+ if (need_lineno && $$0 !~ /\/\//) \
+ { print "\n\n\#line " NR " \"" FILENAME "\""; need_lineno=0 }; \
+ print }'
$(OUTDIR)/%.o: %.cpp
@echo Compiling $<
diff --git a/src/share/vm/adlc/adlparse.cpp b/src/share/vm/adlc/adlparse.cpp
--- a/src/share/vm/adlc/adlparse.cpp
+++ b/src/share/vm/adlc/adlparse.cpp
@@ -108,6 +108,7 @@ void ADLParser::parse() {
else if (!strcmp(ident, "pipeline")) pipe_parse();
else if (!strcmp(ident, "definitions")) definitions_parse();
else if (!strcmp(ident, "peephole")) peep_parse();
+ else if (!strcmp(ident, "#line")) preproc_line();
else if (!strcmp(ident, "#define")) preproc_define();
else if (!strcmp(ident, "#undef")) preproc_undef();
else {
@@ -903,11 +904,7 @@ void ADLParser::enc_class_parse_block(En
skipws_no_preproc(); // Skip leading whitespace
// Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
if (_AD._adlocation_debug) {
- const char* file = _AD._ADL_file._name;
- int line = linenum();
- char* location = (char *)malloc(strlen(file) + 100);
- sprintf(location, "#line %d \"%s\"\n", line, file);
- encoding->add_code(location);
+ encoding->add_code(get_line_string());
}
// Collect the parts of the encode description
@@ -2746,7 +2743,8 @@ Predicate *ADLParser::pred_parse(void) {
char *rule = NULL; // String representation of predicate
skipws(); // Skip leading whitespace
- if ( (rule = get_paren_expr("pred expression")) == NULL ) {
+ int line = _linenum;
+ if ( (rule = get_paren_expr("pred expression", true)) == NULL ) {
parse_err(SYNERR, "incorrect or missing expression for 'predicate'\n");
return NULL;
}
@@ -3942,8 +3940,7 @@ char* ADLParser::find_cpp_block(const ch
next_char(); // Skip block delimiter
skipws_no_preproc(); // Skip leading whitespace
cppBlock = _ptr; // Point to start of expression
- const char* file = _AD._ADL_file._name;
- int line = linenum();
+ int line = _linenum;
next = _ptr + 1;
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
next_char_or_line();
@@ -3958,15 +3955,14 @@ char* ADLParser::find_cpp_block(const ch
_curchar = *_ptr; // Maintain invariant
// Prepend location descriptor, for debugging.
- char* location = (char *)malloc(strlen(file) + 100);
- *location = '\0';
- if (_AD._adlocation_debug)
- sprintf(location, "#line %d \"%s\"\n", line, file);
- char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + 1);
- strcpy(result, location);
- strcat(result, cppBlock);
- cppBlock = result;
- free(location);
+ if (_AD._adlocation_debug) {
+ char* location = get_line_string(line);
+ char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + 1);
+ strcpy(result, location);
+ strcat(result, cppBlock);
+ cppBlock = result;
+ free(location);
+ }
}
return cppBlock;
@@ -4036,13 +4032,23 @@ char* ADLParser::get_expr(const char *de
// Helper function around get_expr
// Sets _curchar to '(' so that get_paren_expr will search for a matching ')'
-char *ADLParser::get_paren_expr(const char *description) {
+char *ADLParser::get_paren_expr(const char *description, bool include_location) {
+ int line = _linenum;
if (_curchar != '(') // Escape if not valid starting position
return NULL;
next_char(); // Skip the required initial paren.
char *token2 = get_expr(description, ")");
if (_curchar == ')')
next_char(); // Skip required final paren.
+ if (include_location && _AD._adlocation_debug) {
+ // Prepend location descriptor, for debugging.
+ char* location = get_line_string(line);
+ char* result = (char *)malloc(strlen(location) + strlen(token2) + 1);
+ strcpy(result, location);
+ strcat(result, token2);
+ token2 = result;
+ free(location);
+ }
return token2;
}
@@ -4430,6 +4436,35 @@ void ADLParser::get_effectlist(FormDict
}
}
+
+//-------------------------------preproc_line----------------------------------
+// A "#line" keyword has been seen, so parse the rest of the line.
+void ADLParser::preproc_line(void) {
+ int line = get_int();
+ skipws_no_preproc();
+ const char* file = NULL;
+ if (_curchar == '"') {
+ next_char(); // Move past the initial '"'
+ file = _ptr;
+ while (true) {
+ if (_curchar == '\n') {
+ parse_err(SYNERR, "missing '\"' at end of #line directive");
+ return;
+ }
+ if (_curchar == '"') {
+ *_ptr = '\0'; // Terminate the string
+ next_char();
+ skipws_no_preproc();
+ break;
+ }
+ next_char();
+ }
+ }
+ ensure_end_of_line();
+ if (file != NULL)
+ _AD._ADL_file._name = file;
+ _linenum = line;
+}
//------------------------------preproc_define---------------------------------
// A "#define" keyword has been seen, so parse the rest of the line.
@@ -4494,6 +4529,7 @@ void ADLParser::parse_err(int flag, cons
// A preprocessor directive has been encountered. Be sure it has fallen at
// the begining of a line, or else report an error.
void ADLParser::ensure_start_of_line(void) {
+ if (_curchar == '\n') { next_line(); return; }
assert( _ptr >= _curline && _ptr < _curline+strlen(_curline),
"Must be able to find which line we are in" );
@@ -4662,6 +4698,7 @@ char ADLParser::cur_char() {
//---------------------------next_char-----------------------------------------
void ADLParser::next_char() {
+ if (_curchar == '\n') parse_err(WARN, "must call next_line!");
_curchar = *++_ptr;
// if ( _curchar == '\n' ) {
// next_line();
@@ -4682,6 +4719,18 @@ void ADLParser::next_char_or_line() {
//---------------------------next_line-----------------------------------------
void ADLParser::next_line() {
_curline = _buf.get_line();
+ _curchar = ' ';
+}
+
+//------------------------get_line_string--------------------------------------
+// Prepended location descriptor, for debugging.
+// Must return a malloced string (that can be freed if desired).
+char* ADLParser::get_line_string(int linenum) {
+ const char* file = _AD._ADL_file._name;
+ int line = linenum ? linenum : _linenum;
+ char* location = (char *)malloc(strlen(file) + 100);
+ sprintf(location, "\n#line %d \"%s\"\n", line, file);
+ return location;
}
//-------------------------is_literal_constant---------------------------------
diff --git a/src/share/vm/adlc/adlparse.hpp b/src/share/vm/adlc/adlparse.hpp
--- a/src/share/vm/adlc/adlparse.hpp
+++ b/src/share/vm/adlc/adlparse.hpp
@@ -93,6 +93,7 @@ protected:
void pipe_parse(void); // Parse pipeline section
void definitions_parse(void); // Parse definitions section
void peep_parse(void); // Parse peephole rule definitions
+ void preproc_line(void); // Parse a #line statement
void preproc_define(void); // Parse a #define statement
void preproc_undef(void); // Parse an #undef statement
@@ -226,7 +227,7 @@ protected:
void get_effectlist(FormDict &effects, FormDict &operands); // Parse effect-operand pairs
// Return the contents of a parenthesized expression.
// Requires initial '(' and consumes final ')', which is replaced by '\0'.
- char *get_paren_expr(const char *description);
+ char *get_paren_expr(const char *description, bool include_location = false);
// Return expression up to next stop-char, which terminator replaces.
// Does not require initial '('. Does not consume final stop-char.
// Final stop-char is left in _curchar, but is also is replaced by '\0'.
@@ -234,6 +235,8 @@ protected:
char *find_cpp_block(const char *description); // Parse a C++ code block
// Issue parser error message & go to EOL
void parse_err(int flag, const char *fmt, ...);
+ // Create a location marker for this file and line.
+ char *get_line_string(int linenum = 0);
// Return pointer to current character
inline char cur_char(void);
diff --git a/src/share/vm/adlc/dfa.cpp b/src/share/vm/adlc/dfa.cpp
--- a/src/share/vm/adlc/dfa.cpp
+++ b/src/share/vm/adlc/dfa.cpp
@@ -458,7 +458,7 @@ void ArchDesc::buildDFA(FILE* fp) {
class dfa_shared_preds {
- enum { count = 2 };
+ enum { count = 4 };
static bool _found[count];
static const char* _type [count];
@@ -479,11 +479,14 @@ class dfa_shared_preds {
char c = *prev;
switch( c ) {
case ' ':
+ case '\n':
return dfa_shared_preds::valid_loc(pred, prev);
case '!':
case '(':
case '<':
case '=':
+ return true;
+ case '"': // such as: #line 10 "myfile.ad"\n mypredicate
return true;
case '|':
if( prev != pred && *(prev-1) == '|' ) return true;
@@ -564,10 +567,14 @@ public:
}
};
// shared predicates, _var and _pred entry should be the same length
-bool dfa_shared_preds::_found[dfa_shared_preds::count] = { false, false };
-const char* dfa_shared_preds::_type[dfa_shared_preds::count] = { "int", "bool" };
-const char* dfa_shared_preds::_var [dfa_shared_preds::count] = { "_n_get_int__", "Compile__current____select_24_bit_instr__" };
-const char* dfa_shared_preds::_pred[dfa_shared_preds::count] = { "n->get_int()", "Compile::current()->select_24_bit_instr()" };
+bool dfa_shared_preds::_found[dfa_shared_preds::count]
+ = { false, false, false, false };
+const char* dfa_shared_preds::_type[dfa_shared_preds::count]
+ = { "int", "jlong", "intptr_t", "bool" };
+const char* dfa_shared_preds::_var [dfa_shared_preds::count]
+ = { "_n_get_int__", "_n_get_long__", "_n_get_intptr_t__", "Compile__current____select_24_bit_instr__" };
+const char* dfa_shared_preds::_pred[dfa_shared_preds::count]
+ = { "n->get_int()", "n->get_long()", "n->get_intptr_t()", "Compile::current()->select_24_bit_instr()" };
void ArchDesc::gen_dfa_state_body(FILE* fp, Dict &minimize, ProductionState &status, Dict &operands_chained_from, int i) {
|