diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
commit | 071b4126c613881f4cb25b4e5c39032964827f88 (patch) | |
tree | 7ed805786566918630d1d617b1ed8f7310f5fd8e /gcc/m2 | |
parent | 845d23f3ea08ba873197c275a8857eee7edad996 (diff) | |
parent | caa1c2f42691d68af4d894a5c3e700ecd2dba080 (diff) | |
download | gcc-devel/gfortran-test.zip gcc-devel/gfortran-test.tar.gz gcc-devel/gfortran-test.tar.bz2 |
Merge branch 'master' into gfortran-testdevel/gfortran-test
Diffstat (limited to 'gcc/m2')
-rw-r--r-- | gcc/m2/ChangeLog | 94 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2GenGCC.mod | 56 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Range.mod | 2 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Students.def | 2 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/M2Students.mod | 16 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/P2SymBuild.mod | 2 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/PathName.mod | 21 | ||||
-rw-r--r-- | gcc/m2/gm2-lang.cc | 336 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-iso/LowLong.mod | 10 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-iso/LowReal.mod | 14 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-iso/LowShort.mod | 14 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-iso/Processes.mod | 8 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-iso/RndFile.mod | 10 | ||||
-rw-r--r-- | gcc/m2/gm2-libs/SCmdArgs.mod | 36 | ||||
-rw-r--r-- | gcc/m2/gm2spec.cc | 31 | ||||
-rw-r--r-- | gcc/m2/lang.opt | 10 | ||||
-rw-r--r-- | gcc/m2/mc-boot/GFormatStrings.cc | 4 | ||||
-rw-r--r-- | gcc/m2/mc-boot/GM2EXCEPTION.cc | 6 | ||||
-rw-r--r-- | gcc/m2/mc-boot/GSFIO.cc | 20 | ||||
-rw-r--r-- | gcc/m2/mc-boot/GSFIO.h | 7 | ||||
-rw-r--r-- | gcc/m2/mc-boot/Gdecl.cc | 71 | ||||
-rw-r--r-- | gcc/m2/mc-boot/GmcFileName.h | 2 | ||||
-rw-r--r-- | gcc/m2/mc/decl.mod | 47 |
23 files changed, 648 insertions, 171 deletions
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index 6babeb9..f63381d 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,97 @@ +2025-08-29 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/121709 + * gm2-lang.cc (concat_component): New function. + (find_cpp_entry): Ditto. + (lookup_cpp_default): Ditto. + (add_default_include_paths): Rewrite. + (m2_pathname_root): Remove. + +2025-08-28 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/121629 + * gm2-compiler/PathName.mod: Add copyright notice. + * gm2-lang.cc (named_path): Add field lib_root. + (push_back_Ipath): Set lib_root false. + (push_back_lib_root): New function. + (get_dir_sep_size): Ditto. + (add_path_component): Ditto. + (add_one_import_path): Ditto. + (add_non_dialect_specific_path): Ditto. + (foreach_lib_gen_import_path): Ditto. + (get_module_source_dir): Ditto. + (add_default_include_paths): Ditto. + (assign_flibs): Ditto. + (m2_pathname_root): Ditto. + (add_m2_import_paths): Remove function. + (gm2_langhook_post_options): Call assign_flibs. + Check np.lib_root and call foreach_lib_gen_import_path. + Replace call to add_m2_import_paths with a call to + add_default_include_paths. + (gm2_langhook_handle_option): Add case OPT_fm2_pathname_rootI_. + * gm2spec.cc (named_path): Add field lib_root. + (push_back_Ipath): Set lib_root false. + (push_back_lib_root): New function. + (add_m2_I_path): Add OPT_fm2_pathname_rootI_ option + if np.lib_root. + (lang_specific_driver): Add case OPT_fm2_pathname_root_. + * lang.opt (fm2-pathname-root=): New option. + (fm2-pathname-rootI=): Ditto. + +2025-08-01 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/121354 + * gm2-compiler/M2GenGCC.mod (FoldHigh): Rewrite. + (IsUnboundedArray): New procedure function. + +2025-07-31 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/121314 + * mc-boot/GFormatStrings.cc (PerformFormatString): Rebuilt. + * mc-boot/GM2EXCEPTION.cc (M2EXCEPTION_M2Exception): Rebuilt. + * mc-boot/GSFIO.cc (SFIO_GetFileName): Rebuilt. + * mc-boot/GSFIO.h (SFIO_GetFileName): Rebuilt. + * mc-boot/Gdecl.cc: Rebuilt. + * mc-boot/GmcFileName.h: Rebuilt. + * mc/decl.mod (getStringChar): New procedure function. + (getStringContents): Call getStringChar. + (addQuotes): New procedure function. + (foldBinary): Call addQuotes to add delimiting quotes + to the new string. + +2025-07-29 Gaius Mulley <gaiusmod2@gmail.com> + + * gm2-compiler/M2GenGCC.mod (FoldBecomes): Remove all + local variables. + (CodeIndrX): Remove length. + Remove newstr. + * gm2-compiler/M2Range.mod (FoldTypeIndrX): Remove desType. + +2025-07-29 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/121289 + * gm2-compiler/M2Students.def (CheckVariableAgainstKeyword): New + parameter tok. + * gm2-compiler/M2Students.mod (CheckVariableAgainstKeyword): New + parameter tok. + Pass tok to PerformVariableKeywordCheck. + (PerformVariableKeywordCheck): New parameter tok. + Pass tok to MetaErrorStringT0. + * gm2-compiler/P2SymBuild.mod (BuildVariable): Pass tok to + CheckVariableAgainstKeyword. + * gm2-libs-iso/LowLong.mod (except): Replace with ... + (exceptSrc): ... this. + * gm2-libs-iso/LowReal.mod (except): Replace with ... + (exceptSrc): ... this. + * gm2-libs-iso/LowShort.mod (except): Replace with ... + (exceptSrc): ... this. + * gm2-libs-iso/Processes.mod (Wait): Replace from with fromCor. + * gm2-libs-iso/RndFile.mod (EndPos): Replace end with endP. + * gm2-libs/SCmdArgs.mod (GetArg): Replace start with startPos. + Replace end with endPos. + (NArg): Replace start with startPos. + Replace end with endPos. + 2025-07-25 David Malcolm <dmalcolm@redhat.com> * gm2-gcc/m2linemap.cc: Update usage of "diagnostic_info" to diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod index 4a9ced3..2440b2a 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.mod +++ b/gcc/m2/gm2-compiler/M2GenGCC.mod @@ -2903,9 +2903,6 @@ END CheckStop ; *) PROCEDURE FoldBecomes (p: WalkAction; bb: BasicBlock; quad: CARDINAL) ; -VAR - op : QuadOperator ; - des, op2, expr: CARDINAL ; BEGIN IF DeclaredOperandsBecomes (p, quad) THEN @@ -6442,37 +6439,52 @@ END ResolveHigh ; (* + IsUnboundedArray - return TRUE if symbol is an unbounded array. +*) + +PROCEDURE IsUnboundedArray (sym: CARDINAL) : BOOLEAN ; +BEGIN + IF IsParameter (sym) OR IsVar (sym) + THEN + RETURN IsUnbounded (GetType (sym)) + END ; + RETURN FALSE +END IsUnboundedArray ; + + +(* FoldHigh - if the array is not dynamic then we should be able to remove the HighOp quadruple and assign op1 with - the known compile time HIGH(op3). + the known compile time HIGH(array). *) PROCEDURE FoldHigh (tokenno: CARDINAL; p: WalkAction; - quad: CARDINAL; op1, dim, op3: CARDINAL) ; + quad: CARDINAL; op1, dim, array: CARDINAL) ; VAR t : tree ; location: location_t ; BEGIN - (* firstly ensure that any constant literal is declared *) - TryDeclareConstant(tokenno, op3) ; - location := TokenToLocation(tokenno) ; - IF GccKnowsAbout(op3) AND CompletelyResolved(op3) + (* Firstly ensure that any constant literal is declared. *) + TryDeclareConstant (tokenno, array) ; + location := TokenToLocation (tokenno) ; + IF (NOT IsUnboundedArray (array)) AND + GccKnowsAbout (array) AND CompletelyResolved (array) THEN - t := ResolveHigh(tokenno, dim, op3) ; - (* fine, we can take advantage of this and fold constants *) - IF IsConst(op1) AND (t#tree(NIL)) + t := ResolveHigh (tokenno, dim, array) ; + (* We can take advantage of this and fold constants. *) + IF IsConst (op1) AND (t # tree (NIL)) THEN - PutConst(op1, Cardinal) ; - AddModGcc(op1, - DeclareKnownConstant(location, GetCardinalType(), - ToCardinal(location, t))) ; - p(op1) ; + PutConst (op1, Cardinal) ; + AddModGcc (op1, + DeclareKnownConstant (location, GetCardinalType (), + ToCardinal (location, t))) ; + p (op1) ; NoChange := FALSE ; - SubQuad(quad) + SubQuad (quad) ELSE - (* we can still fold the expression, but not the assignment, however, we will - not do this here but in CodeHigh - *) + (* We can still fold the expression but not the assignment, + we will not do this here but in CodeHigh when the result + can be stored. *) END END END FoldHigh ; @@ -8154,8 +8166,6 @@ VAR rightpos, typepos, indrxpos : CARDINAL ; - length, - newstr : tree ; location : location_t ; BEGIN GetQuadOtok (quad, indrxpos, op, left, type, right, diff --git a/gcc/m2/gm2-compiler/M2Range.mod b/gcc/m2/gm2-compiler/M2Range.mod index dcac2ba..f1516d3 100644 --- a/gcc/m2/gm2-compiler/M2Range.mod +++ b/gcc/m2/gm2-compiler/M2Range.mod @@ -1869,14 +1869,12 @@ END FoldTypeAssign ; PROCEDURE FoldTypeIndrX (q: CARDINAL; tokenNo: CARDINAL; des, expr: CARDINAL; r: CARDINAL) ; VAR - desType, exprType: CARDINAL ; BEGIN (* Need to skip over a variable or temporary in des and expr so long as expr is not a procedure. In the case of des = *expr, both expr and des will be variables due to the property of indirection. *) - desType := GetType (des) ; IF IsProcedure (expr) THEN (* Must not GetType for a procedure as it gives the return type. *) diff --git a/gcc/m2/gm2-compiler/M2Students.def b/gcc/m2/gm2-compiler/M2Students.def index 7d67a0a..a3ecdcd 100644 --- a/gcc/m2/gm2-compiler/M2Students.def +++ b/gcc/m2/gm2-compiler/M2Students.def @@ -39,7 +39,7 @@ EXPORT QUALIFIED StudentVariableCheck, CheckVariableAgainstKeyword ; as a keyword except for its case. *) -PROCEDURE CheckVariableAgainstKeyword (name: Name) ; +PROCEDURE CheckVariableAgainstKeyword (tok: CARDINAL; name: Name) ; (* diff --git a/gcc/m2/gm2-compiler/M2Students.mod b/gcc/m2/gm2-compiler/M2Students.mod index e539eb0..3df160a 100644 --- a/gcc/m2/gm2-compiler/M2Students.mod +++ b/gcc/m2/gm2-compiler/M2Students.mod @@ -25,7 +25,7 @@ IMPLEMENTATION MODULE M2Students ; FROM SymbolTable IMPORT FinalSymbol, IsVar, IsProcedure, IsModule, GetMainModule, IsType, NulSym, IsRecord, GetSymName, GetNth, GetNthProcedure, GetDeclaredMod, NoOfParam ; FROM NameKey IMPORT GetKey, WriteKey, MakeKey, IsSameExcludingCase, NulName, makekey, KeyToCharStar ; -FROM M2MetaError IMPORT MetaErrorString0, MetaError2 ; +FROM M2MetaError IMPORT MetaErrorStringT0, MetaError2 ; FROM Lists IMPORT List, InitList, IsItemInList, IncludeItemIntoList ; FROM M2Reserved IMPORT IsReserved, toktype ; FROM DynamicStrings IMPORT String, InitString, KillString, ToUpper, InitStringCharStar, string, Mark, ToUpper, Dup ; @@ -78,11 +78,11 @@ END IsNotADuplicateName ; as a keyword except for its case. *) -PROCEDURE CheckVariableAgainstKeyword (name: Name) ; +PROCEDURE CheckVariableAgainstKeyword (tok: CARDINAL; name: Name) ; BEGIN IF StyleChecking THEN - PerformVariableKeywordCheck (name) + PerformVariableKeywordCheck (tok, name) END END CheckVariableAgainstKeyword ; @@ -91,7 +91,7 @@ END CheckVariableAgainstKeyword ; PerformVariableKeywordCheck - performs the check and constructs the metaerror notes if appropriate. *) -PROCEDURE PerformVariableKeywordCheck (name: Name) ; +PROCEDURE PerformVariableKeywordCheck (tok: CARDINAL; name: Name) ; VAR upper : Name ; token : toktype ; @@ -105,9 +105,11 @@ BEGIN THEN IF IsNotADuplicateName (name) THEN - MetaErrorString0 (Sprintf2 (Mark (InitString ('either the identifier has the same name as a keyword or alternatively a keyword has the wrong case ({%%K%s} and {!%%O:{%%K%s}})')), - upperS, orig)) ; - MetaErrorString0 (Sprintf1 (Mark (InitString ('the symbol name {!%%O:{%%K%s}} is legal as an identifier, however as such it might cause confusion and is considered bad programming practice')), orig)) + MetaErrorStringT0 (tok, + Sprintf2 (Mark (InitString ('either the identifier has the same name as a keyword or alternatively a keyword has the wrong case ({%%K%s} and {!%%O:{%%K%s}})')), + upperS, orig)) ; + MetaErrorStringT0 (tok, + Sprintf1 (Mark (InitString ('the symbol name {!%%O:{%%K%s}} is legal as an identifier, however as such it might cause confusion and is considered bad programming practice')), orig)) END END ; upperS := KillString (upperS) ; diff --git a/gcc/m2/gm2-compiler/P2SymBuild.mod b/gcc/m2/gm2-compiler/P2SymBuild.mod index 3bb3e47..54e624f 100644 --- a/gcc/m2/gm2-compiler/P2SymBuild.mod +++ b/gcc/m2/gm2-compiler/P2SymBuild.mod @@ -1179,8 +1179,8 @@ BEGIN PopT (n) ; i := 1 ; WHILE i <= n DO - CheckVariableAgainstKeyword (OperandT (n+1-i)) ; tok := OperandTok (n+1-i) ; + CheckVariableAgainstKeyword (tok, OperandT (n+1-i)) ; Var := MakeVar (tok, OperandT (n+1-i)) ; AtAddress := OperandA (n+1-i) ; IF AtAddress # NulSym diff --git a/gcc/m2/gm2-compiler/PathName.mod b/gcc/m2/gm2-compiler/PathName.mod index 6fc7612..0ba9024 100644 --- a/gcc/m2/gm2-compiler/PathName.mod +++ b/gcc/m2/gm2-compiler/PathName.mod @@ -1,3 +1,24 @@ +(* M2PathName.mod maintain a dictionary of named paths. + +Copyright (C) 2023-2025 Free Software Foundation, Inc. +Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. + +This file is part of GNU Modula-2. + +GNU Modula-2 is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GNU Modula-2 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 GNU Modula-2; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. *) + IMPLEMENTATION MODULE PathName ; FROM Storage IMPORT ALLOCATE, DEALLOCATE ; diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc index 31a2e46..cc074d5 100644 --- a/gcc/m2/gm2-lang.cc +++ b/gcc/m2/gm2-lang.cc @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "m2-tree.h" #include "convert.h" #include "rtegraph.h" +#include "cppdefault.h" static void write_globals (void); @@ -51,6 +52,7 @@ static bool iso = false; typedef struct named_path_s { std::vector<const char*>path; const char *name; + bool lib_root; } named_path; @@ -59,6 +61,7 @@ static bool allow_libraries = true; static const char *flibs = nullptr; static const char *iprefix = nullptr; static const char *imultilib = nullptr; +static const char *target_system_root = nullptr; static std::vector<named_path>Ipaths; static std::vector<const char*>isystem; static std::vector<const char*>iquote; @@ -372,6 +375,7 @@ push_back_Ipath (const char *arg) named_path np; np.path.push_back (arg); np.name = xstrdup (M2Options_GetM2PathName ()); + np.lib_root = false; Ipaths.push_back (np); } else @@ -384,11 +388,254 @@ push_back_Ipath (const char *arg) named_path np; np.path.push_back (arg); np.name = xstrdup (M2Options_GetM2PathName ()); + np.lib_root = false; Ipaths.push_back (np); } } } +/* push_back_lib_root pushes a lib_root onto the Ipaths vector. + The ordering of the -fm2_add_lib_root=, -I and named paths + must be preserved. */ + +static void +push_back_lib_root (const char *arg) +{ + named_path np; + np.name = arg; + np.lib_root = true; + Ipaths.push_back (np); +} + +/* get_dir_sep_size return the length of the DIR_SEPARATOR string. */ + +static size_t +get_dir_sep_size (void) +{ + const char dir_sep[] = {DIR_SEPARATOR, (char)0}; + size_t dir_sep_size = strlen (dir_sep); + return dir_sep_size; +} + +/* add_path_component strcats src into dest and adds a directory seperator + if necessary. */ + +static void +add_path_component (char *dest, const char *src) +{ + size_t len = strlen (dest); + const char dir_sep[] = {DIR_SEPARATOR, (char)0}; + size_t dir_sep_size = strlen (dir_sep); + + if (len > 0) + { + /* Only add a seperator if dest is not empty and does not end + with a seperator. */ + if (len >= dir_sep_size + && (strcmp (&dest[len-dir_sep_size], dir_sep) != 0)) + strcat (dest, dir_sep); + } + strcat (dest, src); +} + +/* This prefixes LIBNAME with the current compiler prefix (if it has been + relocated) or the LIBSUBDIR, if not. */ + +static void +add_one_import_path (const char *libpath, const char *libname) +{ + size_t dir_sep_size = get_dir_sep_size (); + size_t mlib_len = 0; + + if (imultilib) + { + mlib_len = strlen (imultilib); + mlib_len += dir_sep_size; + } + + char *lib = (char *)alloca (strlen (libpath) + dir_sep_size + + strlen ("m2") + dir_sep_size + + strlen (libname) + 1 + + mlib_len + 1); + strcpy (lib, libpath); + if (imultilib) + add_path_component (lib, imultilib); + add_path_component (lib, "m2"); + add_path_component (lib, libname); + M2Options_SetM2PathName (libname); + M2Options_SetSearchPath (lib); +} + +/* add_non_dialect_specific_path add non dialect specific includes + given a base libpath. */ + +static void +add_non_dialect_specific_path (const char *libpath) +{ + char *incpath = (char *)alloca (strlen (libpath) + + strlen ("m2") + + get_dir_sep_size () + + 1); + strcpy (incpath, libpath); + add_path_component (incpath, "m2"); + M2Options_SetM2PathName (""); /* No pathname for non dialect specific libs. */ + M2Options_SetSearchPath (incpath); +} + +/* For each comma-separated standard library name in LIBLIST, add the + corresponding include path. */ + +static void +foreach_lib_gen_import_path (const char *liblist, const char *libpath) +{ + while (*liblist != 0 && *liblist != '-') + { + const char *comma = strstr (liblist, ","); + size_t len; + if (comma) + len = comma - liblist; + else + len = strlen (liblist); + char *libname = (char *) alloca (len+1); + strncpy (libname, liblist, len); + libname[len] = 0; + add_one_import_path (libpath, libname); + liblist += len; + if (*liblist == ',') + liblist++; + } + add_non_dialect_specific_path (libpath); +} + +/* get_module_source_dir return the libpath/{multilib/} as a malloc'd + string. */ + +static const char * +get_module_source_dir (void) +{ + const char *libpath = iprefix ? iprefix : LIBSUBDIR; + const char dir_sep[] = {DIR_SEPARATOR, (char)0}; + size_t dir_sep_size = strlen (dir_sep); + unsigned int mlib_len = 0; + + if (imultilib) + { + mlib_len = strlen (imultilib); + mlib_len += strlen (dir_sep); + } + char *lib = (char *) xmalloc (strlen (libpath) + + dir_sep_size + + mlib_len + 1); + strcpy (lib, libpath); + /* iprefix has a trailing dir separator, LIBSUBDIR does not. */ + if (!iprefix) + strcat (lib, dir_sep); + + if (imultilib) + { + strcat (lib, imultilib); + strcat (lib, dir_sep); + } + return lib; +} + +/* concat_component returns a string containing the path left/right. + Pre-requisite, left and right are null terminated strings. The contents of + left and right are held on the heap. Post-requisite, left and right are + freed and a new combined string is malloced. */ + +static char * +concat_component (char *left, char *right) +{ + size_t len = strlen (left) + + strlen (right) + + get_dir_sep_size () + + 1; + char *new_str = (char *) xmalloc (len); + strcpy (new_str, left); + add_path_component (new_str, right); + free (left); + free (right); + return new_str; +} + +/* find_cpp_entry return the element of the cpp_include_defaults array + whose fname matches name. */ + +static const struct default_include * +find_cpp_entry (const char *name) +{ + const struct default_include *p; + + for (p = cpp_include_defaults; p->fname; p++) + if (strcmp (p->fname, name) == 0) + return p; + return NULL; +} + +/* lookup_cpp_default lookup the entry in cppdefault then add the directory to + the m2 search path. It also honours sysroot, imultilib and imultiarch. */ + +static void +lookup_cpp_default (const char *sysroot, const char *flibs, const char *name) +{ + const struct default_include *p = find_cpp_entry (name); + + if (p != NULL) + { + char *full_str = xstrdup (p->fname); + + /* Should this directory start with the sysroot? */ + if (sysroot && p->add_sysroot) + full_str = concat_component (xstrdup (sysroot), full_str); + /* Should we append the imultilib component? */ + if (p->multilib == 1 && imultilib) + full_str = concat_component (full_str, xstrdup (imultilib)); + /* Or append the imultiarch component? */ + else if (p->multilib == 2 && imultiarch) + full_str = concat_component (full_str, xstrdup (imultiarch)); + else + full_str = xstrdup (p->fname); + foreach_lib_gen_import_path (flibs, full_str); + free (full_str); + } +} + +/* add_default_include_paths add include paths for site wide definition modules + and also gcc version specific definition modules. */ + +static void +add_default_include_paths (const char *flibs) +{ + /* Follow the order found in cppdefaults.cc. */ +#ifdef LOCAL_INCLUDE_DIR + lookup_cpp_default (target_system_root, flibs, LOCAL_INCLUDE_DIR); +#endif +#ifdef PREFIX_INCLUDE_DIR + lookup_cpp_default (target_system_root, flibs, PREFIX_INCLUDE_DIR); +#endif + /* Add the gcc version specific include path. */ + foreach_lib_gen_import_path (flibs, get_module_source_dir ()); +#ifdef NATIVE_SYSTEM_HEADER_DIR + lookup_cpp_default (target_system_root, flibs, NATIVE_SYSTEM_HEADER_DIR); +#endif +} + +/* assign_flibs assign flibs to a default providing that allow_libraries + is true and flibs has not been set. */ + +static void +assign_flibs (void) +{ + if (allow_libraries && (flibs == NULL)) + { + if (iso) + flibs = "m2iso,m2cor,m2pim,m2log"; + else + flibs = "m2pim,m2iso,m2cor,m2log"; + } +} + /* Handle gm2 specific options. Return 0 if we didn't do anything. */ bool @@ -435,6 +682,9 @@ gm2_langhook_handle_option ( case OPT_fpositive_mod_floor_div: M2Options_SetPositiveModFloor (value); return 1; + case OPT_fm2_pathname_rootI_: + push_back_lib_root (arg); + return 1; case OPT_flibs_: allow_libraries = value; flibs = arg; @@ -659,7 +909,7 @@ gm2_langhook_handle_option ( return 1; break; case OPT_isysroot: - /* Otherwise, ignored, at least for now. */ + target_system_root = arg; return 1; break; case OPT_fm2_whole_program: @@ -710,66 +960,6 @@ gm2_langhook_handle_option ( return 0; } -/* This prefixes LIBNAME with the current compiler prefix (if it has been - relocated) or the LIBSUBDIR, if not. */ -static void -add_one_import_path (const char *libname) -{ - const char *libpath = iprefix ? iprefix : LIBSUBDIR; - const char dir_sep[] = {DIR_SEPARATOR, (char)0}; - size_t dir_sep_size = strlen (dir_sep); - unsigned int mlib_len = 0; - - if (imultilib) - { - mlib_len = strlen (imultilib); - mlib_len += strlen (dir_sep); - } - - char *lib = (char *)alloca (strlen (libpath) + dir_sep_size - + strlen ("m2") + dir_sep_size - + strlen (libname) + 1 - + mlib_len + 1); - strcpy (lib, libpath); - /* iprefix has a trailing dir separator, LIBSUBDIR does not. */ - if (!iprefix) - strcat (lib, dir_sep); - - if (imultilib) - { - strcat (lib, imultilib); - strcat (lib, dir_sep); - } - strcat (lib, "m2"); - strcat (lib, dir_sep); - strcat (lib, libname); - M2Options_SetM2PathName (libname); - M2Options_SetSearchPath (lib); -} - -/* For each comma-separated standard library name in LIBLIST, add the - corresponding include path. */ -static void -add_m2_import_paths (const char *liblist) -{ - while (*liblist != 0 && *liblist != '-') - { - const char *comma = strstr (liblist, ","); - size_t len; - if (comma) - len = comma - liblist; - else - len = strlen (liblist); - char *libname = (char *) alloca (len+1); - strncpy (libname, liblist, len); - libname[len] = 0; - add_one_import_path (libname); - liblist += len; - if (*liblist == ',') - liblist++; - } -} - /* Run after parsing options. */ static bool @@ -784,16 +974,7 @@ gm2_langhook_post_options (const char **pfilename) /* Add the include paths as per the libraries specified. NOTE: This assumes that the driver has validated the input and makes no attempt to be defensive of nonsense input in flibs=. */ - if (allow_libraries) - { - if (!flibs) - { - if (iso) - flibs = "m2iso,m2cor,m2pim,m2log"; - else - flibs = "m2pim,m2iso,m2cor,m2log"; - } - } + assign_flibs (); /* Add search paths. We are not handling all of the cases yet (e.g idirafter). @@ -807,9 +988,14 @@ gm2_langhook_post_options (const char **pfilename) iquote.clear(); for (auto np : Ipaths) { - M2Options_SetM2PathName (np.name); - for (auto *s : np.path) - M2Options_SetSearchPath (s); + if (np.lib_root) + foreach_lib_gen_import_path (flibs, np.name); + else + { + M2Options_SetM2PathName (np.name); + for (auto *s : np.path) + M2Options_SetSearchPath (s); + } } Ipaths.clear(); for (auto *s : isystem) @@ -818,7 +1004,7 @@ gm2_langhook_post_options (const char **pfilename) /* FIXME: this is not a good way to suppress the addition of the import paths. */ if (allow_libraries) - add_m2_import_paths (flibs); + add_default_include_paths (flibs); /* Returning false means that the backend should be used. */ return M2Options_GetPPOnly (); diff --git a/gcc/m2/gm2-libs-iso/LowLong.mod b/gcc/m2/gm2-libs-iso/LowLong.mod index 92c7d91..f611923 100644 --- a/gcc/m2/gm2-libs-iso/LowLong.mod +++ b/gcc/m2/gm2-libs-iso/LowLong.mod @@ -182,7 +182,7 @@ BEGIN IF n<0 THEN (* exception raised *) - RAISE(except, ORD(badparam), + RAISE(exceptSrc, ORD(badparam), 'LowLong.trunc: cannot truncate to a negative number of digits') ; RETURN x ELSE @@ -230,7 +230,7 @@ BEGIN IF n<0 THEN (* exception raised *) - RAISE(except, ORD(badparam), + RAISE(exceptSrc, ORD(badparam), 'LowLong.round: cannot round to a negative number of digits') ; RETURN x ELSE @@ -287,12 +287,12 @@ END currentMode ; PROCEDURE IsLowException () : BOOLEAN ; BEGIN - RETURN( IsExceptionalExecution() AND IsCurrentSource(except) ) + RETURN( IsExceptionalExecution () AND IsCurrentSource (exceptSrc) ) END IsLowException ; VAR - except: ExceptionSource ; + exceptSrc: ExceptionSource ; BEGIN - AllocateSource(except) + AllocateSource (exceptSrc) END LowLong. diff --git a/gcc/m2/gm2-libs-iso/LowReal.mod b/gcc/m2/gm2-libs-iso/LowReal.mod index 580f36b..6d9ea00 100644 --- a/gcc/m2/gm2-libs-iso/LowReal.mod +++ b/gcc/m2/gm2-libs-iso/LowReal.mod @@ -183,8 +183,8 @@ BEGIN IF n<0 THEN (* exception raised *) - RAISE(except, ORD(badparam), - 'LowReal.trunc: cannot truncate to a negative number of digits') ; + RAISE (exceptSrc, ORD(badparam), + 'LowReal.trunc: cannot truncate to a negative number of digits') ; RETURN x ELSE r := dtoa(x, maxsignificant, 100, point, sign) ; @@ -231,8 +231,8 @@ BEGIN IF n<0 THEN (* exception raised *) - RAISE(except, ORD(badparam), - 'LowReal.round: cannot round to a negative number of digits') ; + RAISE (exceptSrc, ORD(badparam), + 'LowReal.round: cannot round to a negative number of digits') ; RETURN x ELSE s := RealToFloatString(x, n) ; @@ -288,12 +288,12 @@ END currentMode ; PROCEDURE IsLowException () : BOOLEAN ; BEGIN - RETURN( IsExceptionalExecution() AND IsCurrentSource(except) ) + RETURN( IsExceptionalExecution () AND IsCurrentSource (exceptSrc) ) END IsLowException ; VAR - except: ExceptionSource ; + exceptSrc: ExceptionSource ; BEGIN - AllocateSource(except) + AllocateSource (exceptSrc) END LowReal. diff --git a/gcc/m2/gm2-libs-iso/LowShort.mod b/gcc/m2/gm2-libs-iso/LowShort.mod index 8531a88..62e4887 100644 --- a/gcc/m2/gm2-libs-iso/LowShort.mod +++ b/gcc/m2/gm2-libs-iso/LowShort.mod @@ -183,8 +183,8 @@ BEGIN IF n<0 THEN (* exception raised *) - RAISE(except, ORD(badparam), - 'LowLong.trunc: cannot truncate to a negative number of digits') ; + RAISE (exceptSrc, ORD(badparam), + 'LowLong.trunc: cannot truncate to a negative number of digits') ; RETURN x ELSE r := dtoa(x, maxsignificant, 100, point, sign) ; @@ -231,8 +231,8 @@ BEGIN IF n<0 THEN (* exception raised *) - RAISE(except, ORD(badparam), - 'LowLong.round: cannot round to a negative number of digits') ; + RAISE (exceptSrc, ORD(badparam), + 'LowLong.round: cannot round to a negative number of digits') ; RETURN x ELSE s := RealToFloatString(x, n) ; @@ -288,12 +288,12 @@ END currentMode ; PROCEDURE IsLowException () : BOOLEAN ; BEGIN - RETURN( IsExceptionalExecution() AND IsCurrentSource(except) ) + RETURN( IsExceptionalExecution () AND IsCurrentSource (exceptSrc) ) END IsLowException ; VAR - except: ExceptionSource ; + exceptSrc: ExceptionSource ; BEGIN - AllocateSource(except) + AllocateSource (exceptSrc) END LowShort. diff --git a/gcc/m2/gm2-libs-iso/Processes.mod b/gcc/m2/gm2-libs-iso/Processes.mod index 8ef22c0..b0c1b69 100644 --- a/gcc/m2/gm2-libs-iso/Processes.mod +++ b/gcc/m2/gm2-libs-iso/Processes.mod @@ -441,7 +441,7 @@ PROCEDURE Wait ; VAR calling, best : ProcessId ; - from : COROUTINE ; + fromCor: COROUTINE ; BEGIN IF debugging THEN @@ -451,17 +451,17 @@ BEGIN OnWaitingQueue (calling) ; best := chooseProcess () ; currentId := best ; - from := calling^.context ; + fromCor := calling^.context ; IF debugging THEN displayProcesses ("Wait about to perform IOTRANSFER") END ; - IOTRANSFER (from, currentId^.context) ; + IOTRANSFER (fromCor, currentId^.context) ; IF debugging THEN displayProcesses ("Wait after IOTRANSFER") END ; - currentId^.context := from ; + currentId^.context := fromCor ; currentId := calling ; OnReadyQueue (calling) ; IF debugging diff --git a/gcc/m2/gm2-libs-iso/RndFile.mod b/gcc/m2/gm2-libs-iso/RndFile.mod index e04cd8f..0a2264a 100644 --- a/gcc/m2/gm2-libs-iso/RndFile.mod +++ b/gcc/m2/gm2-libs-iso/RndFile.mod @@ -398,9 +398,9 @@ PROCEDURE EndPos (cid: ChanId): FilePos; position after which there have been no writes. *) VAR - d : DeviceTablePtr ; - end, - old: FilePos ; + d : DeviceTablePtr ; + endP, + old : FilePos ; BEGIN IF IsRndFile(cid) THEN @@ -410,9 +410,9 @@ BEGIN old := CurrentPos(cid) ; FIO.SetPositionFromEnd(RTio.GetFile(cid), 0) ; checkErrno(dev, d) ; - end := CurrentPos(cid) ; + endP := CurrentPos(cid) ; FIO.SetPositionFromBeginning(RTio.GetFile(cid), old) ; - RETURN( end ) + RETURN( endP ) END ELSE RAISEdevException(cid, did, IOChan.wrongDevice, diff --git a/gcc/m2/gm2-libs/SCmdArgs.mod b/gcc/m2/gm2-libs/SCmdArgs.mod index ed76fc4..8443d5f 100644 --- a/gcc/m2/gm2-libs/SCmdArgs.mod +++ b/gcc/m2/gm2-libs/SCmdArgs.mod @@ -132,26 +132,27 @@ PROCEDURE GetArg (CmdLine: String; VAR i : CARDINAL ; sn, - start, end: INTEGER ; + startPos, + endPos : INTEGER ; ch : CHAR ; BEGIN i := 0 ; - start := 0 ; - end := Length(CmdLine) ; + startPos := 0 ; + endPos := Length(CmdLine) ; WHILE i<n DO - start := skipWhite(CmdLine, start, end) ; - sn := skipNextArg(CmdLine, start, end) ; - IF sn<end + startPos := skipWhite(CmdLine, startPos, endPos) ; + sn := skipNextArg(CmdLine, startPos, endPos) ; + IF sn<endPos THEN - start := sn ; + startPos := sn ; INC(i) ELSE RETURN( FALSE ) END END ; - start := skipWhite(CmdLine, start, end) ; - sn := skipNextArg(CmdLine, start, end) ; - Argi := Slice(CmdLine, start, sn) ; + startPos := skipWhite(CmdLine, startPos, endPos) ; + sn := skipNextArg(CmdLine, startPos, endPos) ; + Argi := Slice(CmdLine, startPos, sn) ; RETURN( TRUE ) END GetArg ; @@ -165,17 +166,18 @@ PROCEDURE Narg (CmdLine: String) : CARDINAL ; VAR n : CARDINAL ; s, - start, end: INTEGER ; + startPos, + endPos : INTEGER ; BEGIN n := 0 ; - start := 0 ; - end := Length(CmdLine) ; + startPos := 0 ; + endPos := Length(CmdLine) ; LOOP - start := skipWhite(CmdLine, start, end) ; - s := skipNextArg(CmdLine, start, end) ; - IF s<end + startPos := skipWhite(CmdLine, startPos, endPos) ; + s := skipNextArg(CmdLine, startPos, endPos) ; + IF s<endPos THEN - start := s ; + startPos := s ; INC(n) ELSE RETURN( n ) diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc index 868e5c5..18d9ce7 100644 --- a/gcc/m2/gm2spec.cc +++ b/gcc/m2/gm2spec.cc @@ -158,10 +158,12 @@ static const char *m2_path_name = ""; typedef struct named_path_s { std::vector<const char*>path; const char *name; + bool lib_root; } named_path; static std::vector<named_path>Ipaths; +/* push_back_Ipath pushes a named path to the Ipaths global variable. */ static void push_back_Ipath (const char *arg) @@ -171,6 +173,7 @@ push_back_Ipath (const char *arg) named_path np; np.path.push_back (arg); np.name = m2_path_name; + np.lib_root = false; Ipaths.push_back (np); } else @@ -183,11 +186,25 @@ push_back_Ipath (const char *arg) named_path np; np.path.push_back (arg); np.name = m2_path_name; + np.lib_root = false; Ipaths.push_back (np); } } } +/* push_back_lib_root pushes a lib_root onto the Ipaths vector. + The ordering of the -fm2_add_lib_root=, -I and named paths + must be preserved. */ + +static void +push_back_lib_root (const char *arg) +{ + named_path np; + np.name = arg; + np.lib_root = true; + Ipaths.push_back (np); +} + /* Return whether strings S1 and S2 are both NULL or both the same string. */ @@ -379,15 +396,18 @@ convert_abbreviations (const char *libraries) return full_libraries; } -/* add_m2_I_path appends -fm2-pathname and -fm2-pathnameI options to - the command line which are contructed in the saved Ipaths. */ +/* add_m2_I_path appends -fm2-pathname, -fm2-pathnameI and -fm2-add-lib-root + options to the command line which are contructed in the saved Ipaths. + The order of these options must be maintained. */ static void add_m2_I_path (void) { for (auto np : Ipaths) { - if (strcmp (np.name, "") == 0) + if (np.lib_root) + append_option (OPT_fm2_pathname_rootI_, safe_strdup (np.name), 1); + else if (strcmp (np.name, "") == 0) append_option (OPT_fm2_pathname_, safe_strdup ("-"), 1); else append_option (OPT_fm2_pathname_, safe_strdup (np.name), 1); @@ -576,6 +596,10 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, args[i] |= SKIPOPT; /* We will add the option if it is needed. */ m2_path_name = decoded_options[i].arg; break; + case OPT_fm2_pathname_root_: + args[i] |= SKIPOPT; /* We will add the option if it is needed. */ + push_back_lib_root (decoded_options[i].arg); + break; case OPT__help: case OPT__help_: /* Let gcc.cc handle this, as it has a really @@ -739,7 +763,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, "-fgen-module-list=", "-fuse-list="); } - /* There's no point adding -shared-libgcc if we don't have a shared libgcc. */ #ifndef ENABLE_SHARED_LIBGCC diff --git a/gcc/m2/lang.opt b/gcc/m2/lang.opt index 48c2380..2aea4cc 100644 --- a/gcc/m2/lang.opt +++ b/gcc/m2/lang.opt @@ -172,7 +172,15 @@ specify the module mangled prefix name for all modules in the following include fm2-pathnameI Modula-2 Joined -; For internal use only: used by the driver to copy the user facing -I option +; For internal use only: used by the driver to copy the user facing -I option in order + +fm2-pathname-root= +Modula-2 Joined +add include paths for all the library names in -flibs= to this directory root + +fm2-pathname-rootI= +Modula-2 Joined +; For internal use only: used by the driver to copy the user facing -I option in order fm2-plugin Modula-2 diff --git a/gcc/m2/mc-boot/GFormatStrings.cc b/gcc/m2/mc-boot/GFormatStrings.cc index f4c4fd6..ad7e7d8 100644 --- a/gcc/m2/mc-boot/GFormatStrings.cc +++ b/gcc/m2/mc-boot/GFormatStrings.cc @@ -464,7 +464,7 @@ static DynamicStrings_String PerformFormatString (DynamicStrings_String fmt, int /* avoid dangling else. */ afterperc += 1; Cast ((unsigned char *) &u, (sizeof (u)-1), (const unsigned char *) w, _w_high); - in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc)); + in = Copy (fmt, in, (*startpos), nextperc); in = DynamicStrings_ConCat (in, StringConvert_CardinalToString (u, static_cast<unsigned int> (width), leader, 16, true)); (*startpos) = afterperc; DSdbExit (static_cast<DynamicStrings_String> (NULL)); @@ -475,7 +475,7 @@ static DynamicStrings_String PerformFormatString (DynamicStrings_String fmt, int /* avoid dangling else. */ afterperc += 1; Cast ((unsigned char *) &u, (sizeof (u)-1), (const unsigned char *) w, _w_high); - in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc)); + in = Copy (fmt, in, (*startpos), nextperc); in = DynamicStrings_ConCat (in, StringConvert_CardinalToString (u, static_cast<unsigned int> (width), leader, 10, false)); (*startpos) = afterperc; DSdbExit (static_cast<DynamicStrings_String> (NULL)); diff --git a/gcc/m2/mc-boot/GM2EXCEPTION.cc b/gcc/m2/mc-boot/GM2EXCEPTION.cc index 62d47f0..6baff3c 100644 --- a/gcc/m2/mc-boot/GM2EXCEPTION.cc +++ b/gcc/m2/mc-boot/GM2EXCEPTION.cc @@ -34,7 +34,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see typedef struct { PROC_t proc; } PROC; # endif -# include "Gmcrts.h" #define _M2EXCEPTION_C #include "GM2EXCEPTION.h" @@ -51,18 +50,19 @@ extern "C" M2EXCEPTION_M2Exceptions M2EXCEPTION_M2Exception (void) /* If the program or coroutine is in the exception state then return the enumeration value representing the exception cause. If it is not in the exception state then - raises and exception (exException). */ + raises an exException exception. */ e = RTExceptions_GetExceptionBlock (); n = RTExceptions_GetNumber (e); if (n == (UINT_MAX)) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_exException)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/M2EXCEPTION.mod")), 47, 6, const_cast<void*> (static_cast<const void*>("M2Exception")), const_cast<void*> (static_cast<const void*>("current coroutine is not in the exceptional execution state"))); + return M2EXCEPTION_exException; } else { return (M2EXCEPTION_M2Exceptions) (n); } - ReturnException ("../../gcc/m2/gm2-libs/M2EXCEPTION.def", 25, 1); + /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } diff --git a/gcc/m2/mc-boot/GSFIO.cc b/gcc/m2/mc-boot/GSFIO.cc index 6ae0d5e..f8c13d3 100644 --- a/gcc/m2/mc-boot/GSFIO.cc +++ b/gcc/m2/mc-boot/GSFIO.cc @@ -99,6 +99,13 @@ extern "C" DynamicStrings_String SFIO_WriteS (FIO_File file, DynamicStrings_Stri extern "C" DynamicStrings_String SFIO_ReadS (FIO_File file); +/* + GetFileName - return a new string containing the name of the file. + The string should be killed by the caller. +*/ + +extern "C" DynamicStrings_String SFIO_GetFileName (FIO_File file); + /* Exists - returns TRUE if a file named, fname exists for reading. @@ -207,6 +214,19 @@ extern "C" DynamicStrings_String SFIO_ReadS (FIO_File file) __builtin_unreachable (); } + +/* + GetFileName - return a new string containing the name of the file. + The string should be killed by the caller. +*/ + +extern "C" DynamicStrings_String SFIO_GetFileName (FIO_File file) +{ + return DynamicStrings_InitStringCharStar (FIO_getFileName (file)); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + extern "C" void _M2_SFIO_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) { } diff --git a/gcc/m2/mc-boot/GSFIO.h b/gcc/m2/mc-boot/GSFIO.h index 42ffc48..93c8099 100644 --- a/gcc/m2/mc-boot/GSFIO.h +++ b/gcc/m2/mc-boot/GSFIO.h @@ -103,6 +103,13 @@ EXTERN DynamicStrings_String SFIO_WriteS (FIO_File file, DynamicStrings_String s */ EXTERN DynamicStrings_String SFIO_ReadS (FIO_File file); + +/* + GetFileName - return a new string containing the name of the file. + The string should be killed by the caller. +*/ + +EXTERN DynamicStrings_String SFIO_GetFileName (FIO_File file); # ifdef __cplusplus } # endif diff --git a/gcc/m2/mc-boot/Gdecl.cc b/gcc/m2/mc-boot/Gdecl.cc index ae03483..94ea098 100644 --- a/gcc/m2/mc-boot/Gdecl.cc +++ b/gcc/m2/mc-boot/Gdecl.cc @@ -2550,6 +2550,14 @@ static bool isLeafString (decl_node__opaque n); static DynamicStrings_String getLiteralStringContents (decl_node__opaque n); /* + getStringChar - if the string is delimited by single + or double quotes then strip both + quotes from the string. +*/ + +static DynamicStrings_String getStringChar (decl_node__opaque n); + +/* getStringContents - return the string contents of a constant, literal, string or a constexp node. */ @@ -2569,7 +2577,13 @@ static nameKey_Name addNames (decl_node__opaque a, decl_node__opaque b); static decl_node__opaque resolveString (decl_node__opaque n); /* - foldBinary - + addQuotes - adds delimiter quote char to string. +*/ + +static DynamicStrings_String addQuotes (DynamicStrings_String s, char quote); + +/* + foldBinary - attempt to fold binary + for string constants. */ static decl_node__opaque foldBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque res); @@ -7590,6 +7604,32 @@ static DynamicStrings_String getLiteralStringContents (decl_node__opaque n) /* + getStringChar - if the string is delimited by single + or double quotes then strip both + quotes from the string. +*/ + +static DynamicStrings_String getStringChar (decl_node__opaque n) +{ + DynamicStrings_String s; + + s = getString (n); + if (((DynamicStrings_char (s, 0)) == '\'') && ((DynamicStrings_char (s, -1)) == '\'')) + { + s = DynamicStrings_Slice (s, 1, -1); + } + else if (((DynamicStrings_char (s, 0)) == '"') && ((DynamicStrings_char (s, -1)) == '"')) + { + /* avoid dangling else. */ + s = DynamicStrings_Slice (s, 1, -1); + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* getStringContents - return the string contents of a constant, literal, string or a constexp node. */ @@ -7608,7 +7648,7 @@ static DynamicStrings_String getStringContents (decl_node__opaque n) else if (isString (n)) { /* avoid dangling else. */ - return getString (n); + return getStringChar (n); } else if (isConstExp (n)) { @@ -7672,11 +7712,29 @@ static decl_node__opaque resolveString (decl_node__opaque n) /* - foldBinary - + addQuotes - adds delimiter quote char to string. +*/ + +static DynamicStrings_String addQuotes (DynamicStrings_String s, char quote) +{ + DynamicStrings_String qs; + + s = DynamicStrings_ConCatChar (s, quote); + qs = DynamicStrings_InitStringChar (quote); + qs = DynamicStrings_ConCat (qs, DynamicStrings_Mark (s)); + return qs; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + foldBinary - attempt to fold binary + for string constants. */ static decl_node__opaque foldBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque res) { + char qc; decl_node__opaque n; DynamicStrings_String ls; DynamicStrings_String rs; @@ -7686,7 +7744,12 @@ static decl_node__opaque foldBinary (decl_nodeT k, decl_node__opaque l, decl_nod { ls = getStringContents (l); rs = getStringContents (r); + qc = '\''; + /* Add unquoted contents. */ ls = DynamicStrings_Add (ls, rs); + /* Add quote. */ + ls = addQuotes (ls, qc); + /* Build new string. */ n = static_cast<decl_node__opaque> (decl_makeString (nameKey_makekey (DynamicStrings_string (ls)))); ls = DynamicStrings_KillString (ls); rs = DynamicStrings_KillString (rs); @@ -22789,7 +22852,7 @@ static decl_node__opaque doDupExpr (decl_node__opaque n) break; case decl_length: - M2RTS_HALT (-1); + M2RTS_HALT (-1); /* length should have been converted into unary. */ __builtin_unreachable (); break; diff --git a/gcc/m2/mc-boot/GmcFileName.h b/gcc/m2/mc-boot/GmcFileName.h index 11f1512..6c7ec75 100644 --- a/gcc/m2/mc-boot/GmcFileName.h +++ b/gcc/m2/mc-boot/GmcFileName.h @@ -50,7 +50,7 @@ extern "C" { given a module and an extension. This file name length will be operating system specific. String, Extension, is concatenated onto - Module and thus it is safe to `Mark' the extension + Module and thus it is safe to Mark the extension for garbage collection. */ diff --git a/gcc/m2/mc/decl.mod b/gcc/m2/mc/decl.mod index 342487e..197ca5e 100644 --- a/gcc/m2/mc/decl.mod +++ b/gcc/m2/mc/decl.mod @@ -4643,6 +4643,28 @@ END getLiteralStringContents ; (* + getStringChar - if the string is delimited by single + or double quotes then strip both + quotes from the string. +*) + +PROCEDURE getStringChar (n: node) : String ; +VAR + s: String ; +BEGIN + s := getString (n) ; + IF (DynamicStrings.char (s, 0) = "'") AND (DynamicStrings.char (s, -1) = "'") + THEN + s := DynamicStrings.Slice (s, 1, -1) + ELSIF (DynamicStrings.char (s, 0) = '"') AND (DynamicStrings.char (s, -1) = '"') + THEN + s := DynamicStrings.Slice (s, 1, -1) + END ; + RETURN s +END getStringChar ; + + +(* getStringContents - return the string contents of a constant, literal, string or a constexp node. *) @@ -4657,7 +4679,7 @@ BEGIN RETURN getLiteralStringContents (n) ELSIF isString (n) THEN - RETURN getString (n) + RETURN getStringChar (n) ELSIF isConstExp (n) THEN RETURN getStringContents (n^.unaryF.arg) @@ -4709,11 +4731,27 @@ END resolveString ; (* - foldBinary - + addQuotes - adds delimiter quote char to string. +*) + +PROCEDURE addQuotes (s: String; quote: CHAR) : String ; +VAR + qs: String ; +BEGIN + s := DynamicStrings.ConCatChar (s, quote) ; + qs := DynamicStrings.InitStringChar (quote) ; + qs := DynamicStrings.ConCat (qs, DynamicStrings.Mark (s)) ; + RETURN qs +END addQuotes ; + + +(* + foldBinary - attempt to fold binary + for string constants. *) PROCEDURE foldBinary (k: nodeT; l, r: node; res: node) : node ; VAR + qc: CHAR ; n : node ; ls, rs: String ; @@ -4723,7 +4761,12 @@ BEGIN THEN ls := getStringContents (l) ; rs := getStringContents (r) ; + qc := "'" ; + (* Add unquoted contents. *) ls := DynamicStrings.Add (ls, rs) ; + (* Add quote. *) + ls := addQuotes (ls, qc) ; + (* Build new string. *) n := makeString (makekey (DynamicStrings.string (ls))) ; ls := DynamicStrings.KillString (ls) ; rs := DynamicStrings.KillString (rs) |