This patch introduces spell checking to the PCBuild pass (aggregate
constant construction pass). It also adds the type name spell checking.
It also adds some missing production statements when the FORWARD keyword
is encountered during PCBuild.
gcc/m2/ChangeLog:
PR modula2/127554
* gm2-compiler/M2MetaError.mod (SpellHint): Allow error symbols to
be spell checked.
* gm2-compiler/M2Quads.mod (BuildConstructor): Generate a spelling
hint error message if the name is set and an error is seen.
(PopTntok): New procedure.
* gm2-compiler/PCBuild.bnf (CreateQualident): New procedure.
(PushQualident): Reimplement.
* gm2-compiler/PCSymBuild.mod (PCStartBuildDefModule): Push
module to spelling stack.
(PCStartBuildImpModule): Ditto.
(PCStartBuildInnerModule): Ditto.
(PCEndBuildDefModule): Pop top of spell stack.
(PCEndBuildImpModule): Ditto.
(PCEndBuildProgModule): Ditto.
(PCEndBuildInnerModule): Ditto.
(PCEndBuildProcedure): Ditto.
(PCBuildProcedureHeading): Ditto.
(PCEndBuildForward): Reimplement.
gcc/testsuite/ChangeLog:
PR modula2/127554
* gm2.dg/spell/iso/fail/constaggregate.mod: New test.
Signed-off-by: Gaius Mulley <[email protected]>
---
gcc/m2/gm2-compiler/M2MetaError.mod | 2 +-
gcc/m2/gm2-compiler/M2Quads.mod | 31 +++-
gcc/m2/gm2-compiler/PCBuild.bnf | 150 ++++++++++--------
gcc/m2/gm2-compiler/PCSymBuild.mod | 33 ++--
.../gm2.dg/spell/iso/fail/constaggregate.mod | 19 +++
5 files changed, 157 insertions(+), 78 deletions(-)
create mode 100644 gcc/testsuite/gm2.dg/spell/iso/fail/constaggregate.mod
diff --git a/gcc/m2/gm2-compiler/M2MetaError.mod
b/gcc/m2/gm2-compiler/M2MetaError.mod
index f5b5b5f13eb..b270f7ca64a 100644
--- a/gcc/m2/gm2-compiler/M2MetaError.mod
+++ b/gcc/m2/gm2-compiler/M2MetaError.mod
@@ -1964,7 +1964,7 @@ BEGIN
IF eb.filterDef AND IsDefImp (sym[bol])
THEN
JoinSentances (eb, GetDefModuleSpellHint (sym[bol]))
- ELSIF IsUnknown (sym[bol])
+ ELSIF IsUnknown (sym[bol]) OR IsError (sym[bol])
THEN
JoinSentances (eb, GetSpellHint (sym[bol]))
END
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index 8e92e52f7c0..498f1b4c319 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -12661,10 +12661,12 @@ END SilentBuildConstructor ;
PROCEDURE BuildConstructor (tokcbrpos: CARDINAL) ;
VAR
tok : CARDINAL ;
+ name : Name ;
+ errsym,
constValue,
type : CARDINAL ;
BEGIN
- PopTtok (type, tok) ;
+ PopTntok (type, name, tok) ;
constValue := MakeTemporary (tok, ImmediateValue) ;
PutVar (constValue, type) ;
PutConstructor (constValue) ;
@@ -12676,8 +12678,10 @@ BEGIN
MetaErrorT0 (tokcbrpos,
'{%E}constructor requires a type before the opening %{')
ELSE
- MetaErrorT0 (tok,
- '{%E}the constructor type before the opening %{ is
unknown')
+ (* Spellcheck. *)
+ errsym := MakeError (tok, name) ;
+ MetaErrorT1 (tok, 'constructor type {%1Ea} is undefined {%1&s}',
errsym) ;
+ UnknownReported (errsym)
END
ELSE
ChangeToConstructor (tok, type) ;
@@ -15957,6 +15961,27 @@ BEGIN
END PushTFntok ;
+(*
+ PopTntok - Pop a True/number/tok from the True/False stack.
+ True and False are assumed to contain Symbols.
+ The number is word sized.
+*)
+
+PROCEDURE PopTntok (VAR True, n: WORD; VAR tokno: CARDINAL) ;
+VAR
+ f: BoolFrame ;
+BEGIN
+ f := PopAddress (BoolStack) ;
+ WITH f^ DO
+ True := TrueExit ;
+ n := name ;
+ tokno := tokenno ;
+ Assert (NOT BooleanOp)
+ END ;
+ DISPOSE (f)
+END PopTntok ;
+
+
(*
PopTFn - Pop a True and False number from the True/False stack.
True and False are assumed to contain Symbols or Ident etc.
diff --git a/gcc/m2/gm2-compiler/PCBuild.bnf b/gcc/m2/gm2-compiler/PCBuild.bnf
index f7b5715f182..1fbee0750f7 100644
--- a/gcc/m2/gm2-compiler/PCBuild.bnf
+++ b/gcc/m2/gm2-compiler/PCBuild.bnf
@@ -47,7 +47,7 @@ IMPLEMENTATION MODULE PCBuild ;
FROM M2LexBuf IMPORT currentstring, currenttoken, GetToken, InsertToken,
InsertTokenAndRewind, GetTokenNo, MakeVirtualTok ;
-FROM M2MetaError IMPORT MetaErrorStringT0 ;
+FROM M2MetaError IMPORT MetaErrorStringT0, MetaErrorT1 ;
FROM NameKey IMPORT NulName, Name, makekey ;
FROM DynamicStrings IMPORT String, InitString, KillString, Mark, ConCat,
ConCatChar ;
FROM M2Printf IMPORT printf0 ;
@@ -120,7 +120,7 @@ FROM SymbolTable IMPORT MakeGnuAsm, PutGnuAsmVolatile,
PutGnuAsm, PutGnuAsmInput
IsRecord, IsProcType,
GetCurrentModule, IsInnerModule, IsImported,
RequestSym,
- GetSym, GetLocalSym ;
+ GetSym, GetLocalSym, MakeError, UnknownReported ;
FROM M2Batch IMPORT IsModuleKnown ;
@@ -475,6 +475,78 @@ BEGIN
END
END CheckModuleQualident ;
+
+(*
+ CreateQualident - push the qualident symbol building it
+ component at a time.
+*)
+
+PROCEDURE CreateQualident (stopset0: SetOfStop0;
+ stopset1: SetOfStop1;
+ stopset2: SetOfStop2) ;
+VAR
+ name : Name ;
+ sym,
+ init,
+ ip1 : CARDINAL ;
+ tok,
+ tokstart: CARDINAL ;
+BEGIN
+ PopTtok (name, tokstart) ;
+ tok := tokstart ;
+ init := GetSym (name) ;
+ IF init=NulSym
+ THEN
+ PushTFntok (NulSym, NulSym, name, tok)
+ ELSE
+ WHILE IsDefImp (init) OR IsModule (init) DO
+ IF currenttoken # periodtok
+ THEN
+ ErrorArrayAt ("expecting '.' after module in the construction of a
qualident", tok) ;
+ IF tok#tokstart
+ THEN
+ tok := MakeVirtualTok (tokstart, tokstart, tok)
+ END ;
+ PushTtok (init, tok) ;
+ RETURN
+ ELSE
+ Expect (periodtok, stopset0, stopset1, stopset2 +
SetOfStop2{identtok}) ;
+ StartScope (init) ;
+ Ident (stopset0, stopset1, stopset2) ;
+ PopTtok (name, tok) ;
+ ip1 := GetSym (name) ;
+ IF ip1 = NulSym
+ THEN
+ ErrorArrayAt ("unknown ident in the construction of a
qualident", tok) ;
+ EndScope ;
+ IF tok#tokstart
+ THEN
+ tok := MakeVirtualTok (tokstart, tokstart, tok)
+ END ;
+ PushTFntok (NulSym, NulSym, name, tok) ;
+ RETURN
+ ELSE
+ PutIncluded (ip1)
+ END ;
+ EndScope ;
+ CheckCanBeImported (init, ip1) ;
+ init := ip1
+ END
+ END ;
+ IF tok#tokstart
+ THEN
+ tok := MakeVirtualTok (tokstart, tokstart, tok)
+ END ;
+ IF IsProcedure (init) OR IsProcType (init)
+ THEN
+ PushTtok (init, tok)
+ ELSE
+ PushTFtok (init, GetType(init), tok)
+ END
+ END
+END CreateQualident ;
+
+
% module PCBuild end
BEGIN
BlockState := InitState ()
@@ -1002,70 +1074,18 @@ Term := Factor { MulOperator Factor } =:
Factor := Number | string | SetOrDesignatorOrFunction |
"(" Expression ")" | "NOT" ( Factor | ConstAttribute ) =:
-PushQualident := %
VAR name : Name ;
-
init, ip1 : CARDINAL ;
-
tok, tokstart: CARDINAL ; %
- %
PushAutoOn %
- Ident %
IF IsAutoPushOn()
+PushQualident := %
PushAutoOn %
+ Ident %
IF IsAutoPushOn()
THEN
-
PopTtok (name, tokstart) ;
-
tok := tokstart ;
-
init := GetSym (name) ;
-
IF init=NulSym
-
THEN
-
PushTFntok (NulSym, NulSym, name, tok)
-
ELSE
-
WHILE IsDefImp (init) OR IsModule (init) DO
-
IF currenttoken # periodtok
-
THEN
-
ErrorArrayAt ("expecting '.' after module in the construction of a
qualident", tok) ;
-
IF tok#tokstart
-
THEN
-
tok := MakeVirtualTok (tokstart, tokstart, tok)
-
END ;
-
PushTtok (init, tok) ;
-
PopAuto ;
-
RETURN
-
ELSE
-
Expect (periodtok, stopset0, stopset1, stopset2 +
SetOfStop2{identtok}) ;
-
StartScope (init) ;
-
Ident (stopset0, stopset1, stopset2) ;
-
PopTtok (name, tok) ;
-
ip1 := GetSym (name) ;
-
IF ip1 = NulSym
-
THEN
-
ErrorArrayAt ("unknown ident in the construction of a qualident",
tok) ;
-
EndScope ;
-
IF tok#tokstart
-
THEN
-
tok := MakeVirtualTok (tokstart, tokstart, tok)
-
END ;
-
PushTFntok (NulSym, NulSym, name, tok) ;
-
PopAuto ;
-
RETURN
-
ELSE
-
PutIncluded (ip1)
-
END ;
-
EndScope ;
-
CheckCanBeImported (init, ip1) ;
-
init := ip1
-
END
-
END ;
-
IF tok#tokstart
-
THEN
-
tok := MakeVirtualTok (tokstart, tokstart, tok)
-
END ;
-
IF IsProcedure (init) OR IsProcType (init)
-
THEN
-
PushTtok (init, tok)
-
ELSE
-
PushTFtok (init, GetType(init), tok)
-
END
-
END
-
ELSE %
- { "." Ident } %
END %
- %
PopAuto %
- =:
+
CreateQualident (stopset0, stopset1, stopset2)
+
ELSE
+
(* Although this code is not executed the grammar is
+
processed by pge to generate first and follow sets. *)
+ %
+ { "." Ident }
+ %
END ;
+
PopAuto %
+ =:
ConstructorOrSimpleDes := Constructor | %
PopNothing %
SimpleDes [ ActualParameters ]
diff --git a/gcc/m2/gm2-compiler/PCSymBuild.mod
b/gcc/m2/gm2-compiler/PCSymBuild.mod
index 0597a548180..f54e83a4fc3 100644
--- a/gcc/m2/gm2-compiler/PCSymBuild.mod
+++ b/gcc/m2/gm2-compiler/PCSymBuild.mod
@@ -99,6 +99,7 @@ FROM M2StackWord IMPORT StackOfWord, InitStackWord,
KillStackWord,
IsEmptyWord, NoOfItemsInStackWord ;
IMPORT M2Error ;
+IMPORT M2StackSpell ;
CONST
@@ -236,6 +237,7 @@ BEGIN
StartScope(ModuleSym) ;
Assert(IsDefImp(ModuleSym)) ;
Assert(CompilingDefinitionModule()) ;
+ M2StackSpell.Push (ModuleSym) ;
PushT(name) ;
M2Error.EnterDefinitionScope (name)
END PCStartBuildDefModule ;
@@ -265,6 +267,7 @@ BEGIN
Assert(CompilingDefinitionModule()) ;
CheckForUnknownInModule (tokno) ;
EndScope ;
+ M2StackSpell.Pop ;
PopT(NameEnd) ;
PopT(NameStart) ;
IF NameStart#NameEnd
@@ -305,7 +308,8 @@ BEGIN
Assert(IsDefImp(ModuleSym)) ;
Assert(CompilingImplementationModule()) ;
PushTtok(name, tok) ;
- M2Error.EnterImplementationScope (name)
+ M2Error.EnterImplementationScope (name) ;
+ M2StackSpell.Push (ModuleSym)
END PCStartBuildImpModule ;
@@ -333,6 +337,7 @@ BEGIN
Assert(CompilingImplementationModule()) ;
CheckForUnknownInModule (tokno) ;
EndScope ;
+ M2StackSpell.Pop ;
PopT(NameEnd) ;
PopT(NameStart) ;
IF NameStart#NameEnd
@@ -378,7 +383,8 @@ BEGIN
Assert(CompilingProgramModule()) ;
Assert(NOT IsDefImp(ModuleSym)) ;
PushTtok(name, tok) ;
- M2Error.EnterProgramScope (name)
+ M2Error.EnterProgramScope (name) ;
+ M2StackSpell.Push (ModuleSym)
END PCStartBuildProgModule ;
@@ -416,7 +422,8 @@ BEGIN
WriteFormat0('too many errors in pass 3') ;
FlushErrors
END ;
- M2Error.LeaveErrorScope
+ M2Error.LeaveErrorScope ;
+ M2StackSpell.Pop
END PCEndBuildProgModule ;
@@ -448,7 +455,8 @@ BEGIN
Assert(NOT IsDefImp(ModuleSym)) ;
SetCurrentModule(ModuleSym) ;
PushTtok(name, tok) ;
- M2Error.EnterModuleScope (name)
+ M2Error.EnterModuleScope (name) ;
+ M2StackSpell.Push (ModuleSym)
END PCStartBuildInnerModule ;
@@ -486,7 +494,8 @@ BEGIN
FlushErrors
END ;
SetCurrentModule(GetModuleScope(GetCurrentModule())) ;
- M2Error.LeaveErrorScope
+ M2Error.LeaveErrorScope ;
+ M2StackSpell.Pop
END PCEndBuildInnerModule ;
@@ -628,7 +637,8 @@ BEGIN
Assert (IsProcedure (ProcSym)) ;
PushTtok (ProcSym, tok) ;
StartScope (ProcSym) ;
- M2Error.EnterProcedureScope (name)
+ M2Error.EnterProcedureScope (name) ;
+ M2StackSpell.Push (ProcSym)
END PCStartBuildProcedure ;
@@ -672,7 +682,8 @@ BEGIN
FlushErrors
END ;
EndScope ;
- M2Error.LeaveErrorScope
+ M2Error.LeaveErrorScope ;
+ M2StackSpell.Pop
END PCEndBuildProcedure ;
@@ -694,7 +705,10 @@ END PCEndBuildProcedure ;
PROCEDURE PCEndBuildForward ;
BEGIN
- PopN (2)
+ PopN (2) ;
+ EndScope ;
+ M2Error.LeaveErrorScope ;
+ M2StackSpell.Pop
END PCEndBuildForward ;
@@ -728,7 +742,8 @@ BEGIN
THEN
PopT (ProcSym) ;
PopT (NameStart) ;
- EndScope
+ EndScope ;
+ M2StackSpell.Pop
END
END PCBuildProcedureHeading ;
diff --git a/gcc/testsuite/gm2.dg/spell/iso/fail/constaggregate.mod
b/gcc/testsuite/gm2.dg/spell/iso/fail/constaggregate.mod
new file mode 100644
index 00000000000..1f38f7b00f5
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/spell/iso/fail/constaggregate.mod
@@ -0,0 +1,19 @@
+(* { dg-do compile } *)
+(* { dg-options "-g" } *)
+
+MODULE constaggregate ;
+
+TYPE
+ callType = RECORD
+ callNick : ARRAY [0..8] OF CHAR;
+ callString: ARRAY [0..20] OF CHAR;
+ END ;
+
+CONST
+ cls = CallType {"nickname", "realname"} ;
+ (* { dg-error "constructor type 'CallType' is undefined, did you mean
callType?" "CallType" { target *-*-* } 13 } *)
+ (* { dg-error "the type of the constant declaration 'cls' cannot be
determined" "cls" { target *-*-* } 13 } *)
+
+
+BEGIN
+END constaggregate.
--
2.47.3