codetools: parse method specifier assembler, bug #20437

git-svn-id: trunk@32762 -
This commit is contained in:
mattias 2011-10-08 07:48:31 +00:00
parent 44e4f5e830
commit 2453363069
4 changed files with 111 additions and 104 deletions

View File

@ -849,8 +849,9 @@ begin
KeyWordLists.Add(IsKeyWordMethodSpecifier);
with IsKeyWordMethodSpecifier do begin
Add('ABSTRACT' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('ASSEMBLER' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('CDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('EXTDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); // used often for macros
Add('EXTDECL' ,{$ifdef FPC}@{$endif}AllwaysTrue); // often used for macros
ADD('MWPASCAL' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('NOSTACKFRAME' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('DEPRECATED' ,{$ifdef FPC}@{$endif}AllwaysTrue);

View File

@ -1605,117 +1605,116 @@ begin
SaveRaiseException(ctsSemicolonNotFound);
repeat
if CurPos.StartPos<=SrcLen then begin
if (pphIsMethod in ParseAttr) then
if pphIsMethod in ParseAttr then
IsSpecifier:=IsKeyWordMethodSpecifier.DoIdentifier(@Src[CurPos.StartPos])
else if pphIsType in ParseAttr then
IsSpecifier:=IsKeyWordProcedureTypeSpecifier.DoIdentifier(@Src[CurPos.StartPos])
else
IsSpecifier:=IsKeyWordProcedureSpecifier.DoItCaseInsensitive(Src,
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos);
IsSpecifier:=IsKeyWordProcedureSpecifier.DoItCaseInsensitive(
Src,CurPos.StartPos,CurPos.EndPos-CurPos.StartPos);
end else
IsSpecifier:=false;
if IsSpecifier then begin
// read specifier
if UpAtomIs('MESSAGE') or UpAtomIs('DISPID') or UpAtomIs('ENUMERATOR')
or UpAtomIs('DEPRECATED')
then begin
ReadNextAtom;
if not (CurPos.Flag in [cafSemicolon,cafEND]) then
ReadConstant(true,false,[]);
end else if UpAtomIs('IS') then begin
ReadNextAtom;
if not UpAtomIs('NESTED') then
RaiseStringExpectedButAtomFound('nested');
ReadNextAtom;
end else if UpAtomIs('EXTERNAL') or UpAtomIs('WEAKEXTERNAL') or UpAtomIs('PUBLIC') then begin
HasForwardModifier:=UpAtomIs('EXTERNAL') or UpAtomIs('WEAKEXTERNAL');
ReadNextAtom;
if CurPos.Flag<>cafSemicolon then begin
if not UpAtomIs('NAME') then
ReadConstant(true,false,[]);
if UpAtomIs('NAME') or UpAtomIs('INDEX') then begin
ReadNextAtom;
ReadConstant(true,false,[]);
end;
if UpAtomIs('DELAYED') then
ReadNextAtom;
end;
end else if UpAtomIs('ALIAS') then begin
if not ReadNextAtomIsChar(':') then
RaiseCharExpectedButAtomFound(':');
ReadNextAtom;
ReadConstant(true,false,[]);
end else if CurPos.Flag=cafEdgedBracketOpen then begin
// read assembler alias [public,alias: 'alternative name'],
// internproc, internconst, external
repeat
ReadNextAtom;
if not (CurPos.Flag in AllCommonAtomWords) then
RaiseStringExpectedButAtomFound(ctsKeyword);
if not IsKeyWordProcedureBracketSpecifier.DoIdentifier(@Src[CurPos.StartPos])
then
RaiseKeyWordExampleExpected;
if UpAtomIs('INTERNPROC') then
HasForwardModifier:=true;
if UpAtomIs('INTERNCONST') then begin
ReadNextAtom;
if AtomIsChar(':') then begin
ReadNextAtom;
AtomIsIdentifier(true);
ReadNextAtom;
end;
end else if UpAtomIs('EXTERNAL') then begin
HasForwardModifier:=true;
ReadNextAtom;
if not (CurPos.Flag in [cafComma,cafEdgedBracketClose]) then begin
if not UpAtomIs('NAME') then
ReadConstant(true,false,[]);
if UpAtomIs('NAME') or UpAtomIs('INDEX') then begin
ReadNextAtom;
ReadConstant(true,false,[]);
end;
end;
end else
ReadNextAtom;
if CurPos.Flag in [cafColon,cafEdgedBracketClose] then
break;
if CurPos.Flag<>cafComma then
RaiseCharExpectedButAtomFound(']');
until false;
if CurPos.Flag=cafColon then begin
ReadNextAtom;
if (not AtomIsStringConstant) and (not AtomIsIdentifier(false)) then
RaiseStringExpectedButAtomFound(ctsStringConstant);
ReadConstant(true,false,[]);
end;
if CurPos.Flag<>cafEdgedBracketClose then
RaiseCharExpectedButAtomFound(']');
ReadNextAtom;
if CurPos.Flag=cafEND then begin
UndoReadNextAtom;
exit;
end;
end else begin
// read specifier without parameters
if UpAtomIs('FORWARD') then HasForwardModifier:=true;
ReadNextAtom;
if CurPos.Flag=cafEND then begin
UndoReadNextAtom;
exit;
end;
end;
// check semicolon
if CurPos.Flag=cafSemicolon then begin
ReadNextAtom;
end else begin
// Delphi/FPC allow procs without ending semicolon
end;
end else begin
if not IsSpecifier then begin
// current atom does not belong to procedure/method declaration
UndoReadNextAtom; // unread unknown atom
break;
end;
// read specifier
if UpAtomIs('MESSAGE') or UpAtomIs('DISPID') or UpAtomIs('ENUMERATOR')
or UpAtomIs('DEPRECATED')
then begin
ReadNextAtom;
if not (CurPos.Flag in [cafSemicolon,cafEND]) then
ReadConstant(true,false,[]);
end else if UpAtomIs('IS') then begin
ReadNextAtom;
if not UpAtomIs('NESTED') then
RaiseStringExpectedButAtomFound('nested');
ReadNextAtom;
end else if UpAtomIs('EXTERNAL') or UpAtomIs('WEAKEXTERNAL') or UpAtomIs('PUBLIC') then begin
HasForwardModifier:=UpAtomIs('EXTERNAL') or UpAtomIs('WEAKEXTERNAL');
ReadNextAtom;
if CurPos.Flag<>cafSemicolon then begin
if not UpAtomIs('NAME') then
ReadConstant(true,false,[]);
if UpAtomIs('NAME') or UpAtomIs('INDEX') then begin
ReadNextAtom;
ReadConstant(true,false,[]);
end;
if UpAtomIs('DELAYED') then
ReadNextAtom;
end;
end else if UpAtomIs('ALIAS') then begin
if not ReadNextAtomIsChar(':') then
RaiseCharExpectedButAtomFound(':');
ReadNextAtom;
ReadConstant(true,false,[]);
end else if CurPos.Flag=cafEdgedBracketOpen then begin
// read assembler alias [public,alias: 'alternative name'],
// internproc, internconst, external
repeat
ReadNextAtom;
if not (CurPos.Flag in AllCommonAtomWords) then
RaiseStringExpectedButAtomFound(ctsKeyword);
if not IsKeyWordProcedureBracketSpecifier.DoIdentifier(@Src[CurPos.StartPos])
then
RaiseKeyWordExampleExpected;
if UpAtomIs('INTERNPROC') then
HasForwardModifier:=true;
if UpAtomIs('INTERNCONST') then begin
ReadNextAtom;
if AtomIsChar(':') then begin
ReadNextAtom;
AtomIsIdentifier(true);
ReadNextAtom;
end;
end else if UpAtomIs('EXTERNAL') then begin
HasForwardModifier:=true;
ReadNextAtom;
if not (CurPos.Flag in [cafComma,cafEdgedBracketClose]) then begin
if not UpAtomIs('NAME') then
ReadConstant(true,false,[]);
if UpAtomIs('NAME') or UpAtomIs('INDEX') then begin
ReadNextAtom;
ReadConstant(true,false,[]);
end;
end;
end else
ReadNextAtom;
if CurPos.Flag in [cafColon,cafEdgedBracketClose] then
break;
if CurPos.Flag<>cafComma then
RaiseCharExpectedButAtomFound(']');
until false;
if CurPos.Flag=cafColon then begin
ReadNextAtom;
if (not AtomIsStringConstant) and (not AtomIsIdentifier(false)) then
RaiseStringExpectedButAtomFound(ctsStringConstant);
ReadConstant(true,false,[]);
end;
if CurPos.Flag<>cafEdgedBracketClose then
RaiseCharExpectedButAtomFound(']');
ReadNextAtom;
if CurPos.Flag=cafEND then begin
UndoReadNextAtom;
exit;
end;
end else begin
// read specifier without parameters
if UpAtomIs('FORWARD') then HasForwardModifier:=true;
ReadNextAtom;
if CurPos.Flag=cafEND then begin
UndoReadNextAtom;
exit;
end;
end;
// check semicolon
if CurPos.Flag=cafSemicolon then begin
ReadNextAtom;
end else begin
// Delphi/FPC allow procs without ending semicolon
end;
until false;
end;

View File

@ -3425,12 +3425,19 @@ procedure TXMLReader.ParseEndTag; // [42]
var
ErrOffset: Integer;
ElName: PHashItem;
procedure UnmatchingEndTag;
begin
FatalError('Unmatching element end tag (expected "</%s>")', [ElName^.Key], FName.Length);
end;
begin
ElName := FValidator[FNesting].FElement.NSI.QName;
CheckName;
if not BufEquals(FName, ElName^.Key) then
FatalError('Unmatching element end tag (expected "</%s>")', [ElName^.Key], FName.Length);
UnmatchingEndTag;
if FSource.FBuf^ = '>' then // this handles majority of cases
begin
ErrOffset := FName.Length+1;

View File

@ -70,7 +70,7 @@ const
'IgnoreSpaceChars',
'IgnoreTrailingSpaces'
);
implementation