src/share/vm/adlc/adlparse.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/adlc/adlparse.cpp Mon Dec 8 17:22:36 2008
--- new/src/share/vm/adlc/adlparse.cpp Mon Dec 8 17:22:35 2008
*** 106,115 ****
--- 106,116 ----
else if (!strcmp(ident, "frame")) frame_parse();
else if (!strcmp(ident, "encode")) encode_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 {
parse_err(SYNERR, "expected one of - instruct, operand, ins_attrib, op_attrib, source, register, pipeline, encode\n Found %s",ident);
}
*** 785,796 ****
--- 786,799 ----
if (token == NULL) {
parse_err(SYNERR, "missing identifier inside register block.\n");
return;
}
if (strcmp(token,"reg_def")==0) { reg_def_parse(); }
! else if (strcmp(token,"reg_class")==0) { reg_class_parse(); }
! if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); }
! else if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); }
+ else if (strcmp(token,"#define")==0) { preproc_define(); }
+ else { parse_err(SYNERR, "bad token %s inside register block.\n", token); break; }
skipws();
}
}
else {
parse_err(SYNERR, "Missing %c{ ... %c} block after register keyword.\n",'%','%');
*** 901,915 ****
--- 904,914 ----
void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
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
// (1) strings that are passed through to output
// (2) replacement/substitution variable, preceeded by a '$'
*** 946,955 ****
--- 945,958 ----
next_char(); // Skip '%'
next_char(); // Skip '}'
skipws();
+ if (_AD._adlocation_debug) {
+ encoding->add_code(end_line_marker());
+ }
+
// Debug Stuff
if (_AD._adl_debug > 1) fprintf(stderr,"EncodingClass Form: %s\n", ec_name);
}
//------------------------------frame_parse-----------------------------------
*** 2347,2357 ****
--- 2350,2364 ----
if (rname==NULL) {
parse_err(SYNERR, "missing identifier inside reg_class list.\n");
return;
}
RegDef *regDef = _AD._register->getRegDef(rname);
+ if (!regDef) {
+ parse_err(SEMERR, "unknown identifier %s inside reg_class list.\n", rname);
+ } else {
reg_class->addReg(regDef); // add regDef to regClass
+ }
// Check for ',' and position to next token.
skipws();
if (_curchar == ',') {
next_char(); // Skip trailing ','
*** 2744,2754 ****
--- 2751,2762 ----
Predicate *ADLParser::pred_parse(void) {
Predicate *predicate; // Predicate class for operand
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;
}
// Debug Stuff
if (_AD._adl_debug > 1) fprintf(stderr,"Predicate: %s\n", rule);
*** 3405,3415 ****
--- 3413,3428 ----
// (1)
// Check if there is a string to pass through to output
char *start = _ptr; // Record start of the next string
while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
! if (_curchar == '\\') next_char(); // superquote
! if (_curchar == '\\') {
+ next_char(); // superquote
+ if ((_curchar == '$') || (_curchar == '%'))
+ // hack to avoid % escapes and warnings about undefined \ escapes
+ *(_ptr-1) = _curchar;
+ }
if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
next_char();
}
// If a string was found, terminate it and record in FormatRule
if ( start != _ptr ) {
*** 3940,3950 ****
--- 3953,3962 ----
return NULL;
}
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();
next = _ptr + 1;
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
next_char_or_line();
next = _ptr+1; // Maintain the next pointer
*** 3956,3975 ****
--- 3968,3988 ----
*_ptr = '\0'; // Terminate string
_ptr += 2; // Skip block delimiter
_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);
+ if (_AD._adlocation_debug) {
! char* location = get_line_string(line);
+ char* end_loc = end_line_marker();
! char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1);
strcpy(result, location);
strcat(result, cppBlock);
+ strcat(result, end_loc);
cppBlock = result;
free(location);
}
+ }
return cppBlock;
}
// Move to the closing token of the expression we are currently at,
*** 4034,4050 ****
--- 4047,4076 ----
return expr;
}
// 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, 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.
+ int junk = 0;
+ if (include_location && _AD._adlocation_debug && !is_int_token(token2, junk)) {
+ // Prepend location descriptor, for debugging.
+ char* location = get_line_string(line);
+ char* end_loc = end_line_marker();
+ char* result = (char *)malloc(strlen(location) + strlen(token2) + strlen(end_loc) + 1);
+ strcpy(result, location);
+ strcat(result, token2);
+ strcat(result, end_loc);
+ token2 = result;
+ free(location);
+ }
return token2;
}
//------------------------------get_ident_common-------------------------------
// Looks for an identifier in the buffer, and turns it into a null terminated
*** 4080,4093 ****
--- 4106,4125 ----
// Make sure we do not try to use #defined identifiers. If start is
// NULL an error was already reported.
if (do_preproc && start != NULL) {
const char* def = _AD.get_preproc_def(start);
if (def != NULL && strcmp(def, start)) {
! const char* def2 = _AD.get_preproc_def(def);
if (def2 != NULL && strcmp(def2, def)) {
parse_err(SYNERR, "unimplemented: using %s defined as %s => %s",
start, def, def2);
! const char* def1 = def;
+ const char* def2 = _AD.get_preproc_def(def1);
+ // implement up to 2 levels of #define
+ if (def2 != NULL && strcmp(def2, def1)) {
+ def = def2;
+ const char* def3 = _AD.get_preproc_def(def2);
+ if (def3 != NULL && strcmp(def3, def2) && strcmp(def3, def1)) {
+ parse_err(SYNERR, "unimplemented: using %s defined as %s => %s => %s",
+ start, def1, def2, def3);
+ }
}
start = strdup(def);
}
}
*** 4429,4438 ****
--- 4461,4499 ----
next_char(); // set current character position past the close paren
}
}
+ //-------------------------------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;
+ _buf.set_linenum(line);
+ }
+
//------------------------------preproc_define---------------------------------
// A "#define" keyword has been seen, so parse the rest of the line.
void ADLParser::preproc_define(void) {
char* flag = get_ident_no_preproc();
skipws_no_preproc();
*** 4492,4501 ****
--- 4553,4563 ----
//---------------------------ensure_start_of_line------------------------------
// 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" );
for (char *s = _curline; s < _ptr; s++) {
if (*s > ' ') {
*** 4660,4669 ****
--- 4722,4732 ----
return (_curchar);
}
//---------------------------next_char-----------------------------------------
void ADLParser::next_char() {
+ if (_curchar == '\n') parse_err(WARN, "must call next_line!");
_curchar = *++_ptr;
// if ( _curchar == '\n' ) {
// next_line();
// }
}
*** 4680,4689 ****
--- 4743,4764 ----
}
//---------------------------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 : this->linenum();
+ char* location = (char *)malloc(strlen(file) + 100);
+ sprintf(location, "\n#line %d \"%s\"\n", line, file);
+ return location;
}
//-------------------------is_literal_constant---------------------------------
bool ADLParser::is_literal_constant(const char *param) {
if (param[0] == 0) return false; // null string
*** 4720,4729 ****
--- 4795,4864 ----
}
intval = atoi(token);
return true;
}
+ static const char* skip_expr_ws(const char* str) {
+ const char * cp = str;
+ while (cp[0]) {
+ if (cp[0] <= ' ') {
+ ++cp;
+ } else if (cp[0] == '#') {
+ ++cp;
+ while (cp[0] == ' ') ++cp;
+ assert(0 == strncmp(cp, "line", 4), "must be a #line directive");
+ const char* eol = strchr(cp, '\n');
+ assert(eol != NULL, "must find end of line");
+ if (eol == NULL) eol = cp + strlen(cp);
+ cp = eol;
+ } else {
+ break;
+ }
+ }
+ return cp;
+ }
+
+ //-----------------------equivalent_expressions--------------------------------
+ bool ADLParser::equivalent_expressions(const char* str1, const char* str2) {
+ if (str1 == str2)
+ return true;
+ else if (str1 == NULL || str2 == NULL)
+ return false;
+ const char* cp1 = str1;
+ const char* cp2 = str2;
+ char in_quote = '\0';
+ while (cp1[0] && cp2[0]) {
+ if (!in_quote) {
+ // skip spaces and/or cpp directives
+ const char* cp1a = skip_expr_ws(cp1);
+ const char* cp2a = skip_expr_ws(cp2);
+ if (cp1a > cp1 && cp2a > cp2) {
+ cp1 = cp1a; cp2 = cp2a;
+ continue;
+ }
+ if (cp1a > cp1 || cp2a > cp2) break; // fail
+ }
+ // match one non-space char
+ if (cp1[0] != cp2[0]) break; // fail
+ char ch = cp1[0];
+ cp1++; cp2++;
+ // watch for quotes
+ if (in_quote && ch == '\\') {
+ if (cp1[0] != cp2[0]) break; // fail
+ if (!cp1[0]) break;
+ cp1++; cp2++;
+ }
+ if (in_quote && ch == in_quote) {
+ in_quote = '\0';
+ } else if (!in_quote && (ch == '"' || ch == '\'')) {
+ in_quote = ch;
+ }
+ }
+ return (!cp1[0] && !cp2[0]);
+ }
+
+
//-------------------------------trim------------------------------------------
void ADLParser::trim(char* &token) {
while (*token <= ' ') token++;
char* end = token + strlen(token);
while (end > token && *(end-1) <= ' ') --end;
src/share/vm/adlc/adlparse.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File