codetools: started parsing union

git-svn-id: trunk@29566 -
This commit is contained in:
mattias 2011-02-15 21:37:44 +00:00
parent ca93fe85e5
commit 117f3f55fa
4 changed files with 150 additions and 83 deletions

View File

@ -30,6 +30,7 @@
__TIME__ current time "hh:mm:ss" __TIME__ current time "hh:mm:ss"
__STDC__ 1 __STDC__ 1
} }
// Predefined gcc macros: // Predefined gcc macros:
// __attribute__((packed)) // __attribute__((packed))
@ -41,6 +42,16 @@
// typeof(*(ptr)) __v; // typeof(*(ptr)) __v;
// } *__p = (void *) (ptr); // } *__p = (void *) (ptr);
//union _GFloatIEEE754
//{
// gfloat v_float;
// struct {
// guint mantissa : 23;
// guint biased_exponent : 8;
// guint sign : 1;
// } mpn;
//};
//ToDo: //ToDo:
// void * __strong _reserved0; // void * __strong _reserved0;
@ -92,7 +103,7 @@ interface
{$I codetools.inc} {$I codetools.inc}
{off $DEFINE VerboseCCodeParser} {$DEFINE VerboseCCodeParser}
{off $DEFINE VerboseCDirectives} {off $DEFINE VerboseCDirectives}
uses uses
@ -119,14 +130,15 @@ const
ccnConstant = 6+ccnBase;// e.g. 1 ccnConstant = 6+ccnBase;// e.g. 1
ccnTypedef = 7+ccnBase;// e.g. typedef int TInt; ccnTypedef = 7+ccnBase;// e.g. typedef int TInt;
ccnStruct = 8+ccnBase;// e.g. struct{} ccnStruct = 8+ccnBase;// e.g. struct{}
ccnStructAlias = 9+ccnBase;// e.g. struct name ccnStructAlias = 9+ccnBase;// e.g. struct alias name;
ccnUnion = 10+ccnBase;// e.g. union{} ccnUnion = 10+ccnBase;// e.g. union{}
ccnVariable = 11+ccnBase;// e.g. int i ccnUnionAlias = 11+ccnBase;// e.g. union alias name;
ccnFunction = 12+ccnBase;// e.g. int i() ccnVariable = 12+ccnBase;// e.g. int i
ccnName = 13+ccnBase;// e.g. i ccnFunction = 13+ccnBase;// e.g. int i()
ccnFuncParamList = 14+ccnBase;// e.g. () ccnName = 14+ccnBase;// e.g. i
ccnFuncParameter = 15+ccnBase;// e.g. () ccnFuncParamList = 15+ccnBase;// e.g. ()
ccnStatementBlock = 16+ccnBase;// e.g. {} ccnFuncParameter = 16+ccnBase;// e.g. ()
ccnStatementBlock = 17+ccnBase;// e.g. {}
// values for Node.SubDesc // values for Node.SubDesc
ccnsNone = 0; ccnsNone = 0;
@ -653,7 +665,11 @@ begin
if LinkIndex<0 then exit(false); if LinkIndex<0 then exit(false);
Link:=@Links[LinkIndex]; Link:=@Links[LinkIndex];
Code:=Link^.Code; Code:=Link^.Code;
CodePos:=MergedPos-Link^.MergedPos; //dbgout(['TCHeaderFileMerger.MergedPosToOriginal LinkIndex=',LinkIndex,
// ' SearchPos=',MergedPos,' LinkMergePos=',Link^.MergedPos,' LinkSrcPos=',Link^.SrcPos]);
//if Code<>nil then dbgout(' File=',ExtractFileName(Code.Filename));
CodePos:=MergedPos-Link^.MergedPos+Link^.SrcPos;
//debugln([' CodePos=',CodePos]);
Result:=true; Result:=true;
end; end;
@ -664,8 +680,11 @@ var
CodePos: integer; CodePos: integer;
begin begin
Result:=false; Result:=false;
Code:=nil;
X:=0;
Y:=0;
CombinedSource.LineColToPosition(MergedY,MergedX,MergedPos); CombinedSource.LineColToPosition(MergedY,MergedX,MergedPos);
//debugln(['TCHeaderFileMerger.MergedPosToOriginal MergedX=',MergedX,' MergedY=',MergedY,' MergedPos=',MergedPos,' ',dbgstr(copy(CombinedSource.Source,MergedPos-10,10)),'|',dbgstr(copy(CombinedSource.Source,MergedPos,10))]); //debugln(['TCHeaderFileMerger.MergedPosToOriginal MergedX=',MergedX,' MergedY=',MergedY,' MergedPos=',MergedPos,' ',dbgstr(copy(CombinedSource.Source,MergedPos-20,20)),'|',dbgstr(copy(CombinedSource.Source,MergedPos,20))]);
if not MergedPosToOriginal(MergedPos,Code,CodePos) then exit; if not MergedPosToOriginal(MergedPos,Code,CodePos) then exit;
Code.AbsoluteToLineCol(CodePos,Y,X); Code.AbsoluteToLineCol(CodePos,Y,X);
Result:=Y>=1; Result:=Y>=1;
@ -717,13 +736,14 @@ var
l: LongInt; l: LongInt;
begin begin
debugln(['TCHeaderFileMerger.WriteDebugReport LinkCount=',LinkCount]); debugln(['TCHeaderFileMerger.WriteDebugReport LinkCount=',LinkCount]);
debugln(' # MergePos Line');
for i:=0 to LinkCount-1 do begin for i:=0 to LinkCount-1 do begin
Link:=@Links[i]; Link:=@Links[i];
CombinedSource.AbsoluteToLineCol(Link^.MergedPos,Line,Column); CombinedSource.AbsoluteToLineCol(Link^.MergedPos,Line,Column);
dbgout(' Line=',dbgs(Line)); dbgout([' ',i,' ',Link^.MergedPos,' y=',Line]);
if Link^.Code<>nil then begin if Link^.Code<>nil then begin
Link^.Code.AbsoluteToLineCol(Link^.SrcPos,Line,Column); Link^.Code.AbsoluteToLineCol(Link^.SrcPos,Line,Column);
DbgOut(' ',ExtractFilename(Link^.Code.Filename),' Y=',dbgs(Line),' X=',dbgs(Column)); DbgOut([' ',ExtractFilename(Link^.Code.Filename),' Y=',Line,' X=',Column,' SrcPos=',Link^.SrcPos]);
end else begin end else begin
DbgOut(' no source'); DbgOut(' no source');
end; end;
@ -1012,6 +1032,13 @@ end;
procedure TCCodeParserTool.ReadStruct; procedure TCCodeParserTool.ReadStruct;
(* Examples: (* Examples:
union sign /* A definition and a declaration */
{
int svar;
unsigned uvar;
} number;
As typedef: As typedef:
typedef struct { typedef struct {
uint8_t b[6]; // implicit type uint8_t b[6]; // implicit type
@ -1099,12 +1126,32 @@ procedure TCCodeParserTool.ReadUnion;
uint128_t uuid128; uint128_t uuid128;
} value; } value;
union _GFloatIEEE754
{
gfloat v_float;
struct {
guint mantissa : 23;
guint biased_exponent : 8;
guint sign : 1;
} mpn;
};
typedef union _GDoubleIEEE754 GDoubleIEEE754;
*) *)
begin begin
CreateChildNode(ccnUnion); CreateChildNode(ccnUnion);
ReadNextAtom; ReadNextAtom;
debugln(['TCCodeParserTool.ReadUnion AAA1 ',GetAtom]);
if AtomIsIdentifier then begin
// read type name
CreateChildNode(ccnName);
EndChildNode;
ReadNextAtom;
debugln(['TCCodeParserTool.ReadUnion AAA2 ',GetAtom]);
end;
if AtomIsChar('{') then begin if AtomIsChar('{') then begin
// read block {} // read block {}
repeat repeat
@ -1126,8 +1173,14 @@ begin
until false; until false;
end else if AtomIsIdentifier then begin end else if AtomIsIdentifier then begin
// using another union // using another union
// for example: typedef union _GDoubleIEEE754 GDoubleIEEE754;
CreateChildNode(ccnUnionAlias);
EndChildNode;
end else if AtomIsChar(';') then begin
// union without content
end else end else
RaiseExpectedButAtomFound('{'); RaiseExpectedButAtomFound('{');
debugln(['TCCodeParserTool.ReadUnion AAA3 ',GetAtom]);
// close node // close node
EndChildNode; EndChildNode;
@ -1330,50 +1383,53 @@ begin
MainNode:=CurNode; MainNode:=CurNode;
IsFunction:=false; IsFunction:=false;
if AtomIs('const') then ReadNextAtom; if AtomIs('const') then ReadNextAtom;
if AtomIs('struct') then begin if AtomIs('struct') then begin
// for example: struct structname varname // for example: struct structname varname
ReadNextAtom; ReadNextAtom;
end else if AtomIs('union') then begin end
else if AtomIs('union') then begin
ReadUnion; ReadUnion;
end else if IsCCodeFunctionModifier.DoItCaseSensitive(Src,AtomStart,SrcPos-AtomStart) end else begin
then begin if IsCCodeFunctionModifier.DoItCaseSensitive(Src,AtomStart,SrcPos-AtomStart)
// read function modifiers then begin
while IsCCodeFunctionModifier.DoItCaseSensitive(Src,AtomStart,SrcPos-AtomStart) // read function modifiers
do begin
if AsParameter then if AsParameter then
RaiseException('function modifier not allowed in parameter'); RaiseException('function modifier not allowed in parameter');
IsFunction:=true; repeat
MainNode.Desc:=ccnFunction; IsFunction:=true;
ReadNextAtom; MainNode.Desc:=ccnFunction;
if not AtomIsIdentifier then ReadNextAtom;
RaiseExpectedButAtomFound('identifier'); if not AtomIsIdentifier then
RaiseExpectedButAtomFound('identifier');
until not IsCCodeFunctionModifier.DoItCaseSensitive(Src,AtomStart,SrcPos-AtomStart);
end; end;
if AtomIs('const') then ReadNextAtom;
// prefixes: signed, unsigned
// prefixes and/or names long, short
// int, short int, short signed int
// char, signed char, unsigned char
// singed short, unsigned short, short
// long, long long, signed long, signed long long, unsigned long, unsigned long long
LastIsName:=false;
repeat
if AtomIs('signed') or AtomIs('unsigned') then begin
LastIsName:=false;
ReadNextAtom;
end else if AtomIs('short') or AtomIs('long') then begin
LastIsName:=true;
ReadNextAtom;
end else
break;
until false;
if LastIsName then
UndoReadNextAtom;
// read type name
ReadNextAtom;
end; end;
if AtomIs('const') then ReadNextAtom;
// prefixes: signed, unsigned
// prefixes and/or names long, short
// int, short int, short signed int
// char, signed char, unsigned char
// singed short, unsigned short, short
// long, long long, signed long, signed long long, unsigned long, unsigned long long
LastIsName:=false;
repeat
if AtomIs('signed') or AtomIs('unsigned') then begin
LastIsName:=false;
ReadNextAtom;
end else if AtomIs('short') or AtomIs('long') then begin
LastIsName:=true;
ReadNextAtom;
end else
break;
until false;
if LastIsName then
UndoReadNextAtom;
// read name
ReadNextAtom;
while AtomIsChar('*') or AtomIs('const') do begin while AtomIsChar('*') or AtomIs('const') do begin
// pointer or const // pointer or const
ReadNextAtom; ReadNextAtom;
@ -1421,8 +1477,6 @@ begin
CreateChildNode(ccnName); CreateChildNode(ccnName);
CurNode.StartPos:=AtomStart; CurNode.StartPos:=AtomStart;
CurNode.EndPos:=SrcPos; CurNode.EndPos:=SrcPos;
end else if not AsParameter then begin
RaiseExpectedButAtomFound('identifier');
end else begin end else begin
UndoReadNextAtom; UndoReadNextAtom;
end; end;
@ -1531,6 +1585,9 @@ begin
if ReportPos>0 then if ReportPos>0 then
LastErrorReportPos:=ReportPos; LastErrorReportPos:=ReportPos;
CloseNodes; CloseNodes;
{$IFDEF VerboseCCodeParser}
CTDumpStack;
{$ENDIF}
raise ECCodeParserException.Create(Self,AMessage); raise ECCodeParserException.Create(Self,AMessage);
end; end;

View File

@ -33,7 +33,7 @@
<PackageName Value="CodeTools"/> <PackageName Value="CodeTools"/>
</Item2> </Item2>
</RequiredPackages> </RequiredPackages>
<Units Count="2"> <Units Count="3">
<Unit0> <Unit0>
<Filename Value="h2pastest.lpr"/> <Filename Value="h2pastest.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -43,6 +43,10 @@
<Filename Value="scanexamples/test.h"/> <Filename Value="scanexamples/test.h"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
</Unit1> </Unit1>
<Unit2>
<Filename Value="convert_glib.sh"/>
<IsPartOfProject Value="True"/>
</Unit2>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -166,8 +166,8 @@ begin
CCodeTool.CleanPosToCaret(CCodeTool.LastErrorReportPos,Caret); CCodeTool.CleanPosToCaret(CCodeTool.LastErrorReportPos,Caret);
writeln('Combined source: ', writeln('Combined source: ',
Caret.Code.Filename+'('+IntToStr(Caret.Y)+','+IntToStr(Caret.X)+')', Caret.Code.Filename+'('+IntToStr(Caret.Y)+','+IntToStr(Caret.X)+')',
' ',dbgstr(copy(CCodeTool.Src,CCodeTool.LastErrorReportPos-20,20)),'|', ' ',dbgstr(copy(CCodeTool.Src,CCodeTool.LastErrorReportPos-40,40)),'|',
dbgstr(copy(CCodeTool.Src,CCodeTool.LastErrorReportPos,20))); dbgstr(copy(CCodeTool.Src,CCodeTool.LastErrorReportPos,40)));
if Merger<>nil then begin if Merger<>nil then begin
Merger.MergedPosToOriginal(Caret.X,Caret.Y,Caret.Code,Caret.X,Caret.Y); Merger.MergedPosToOriginal(Caret.X,Caret.Y,Caret.Code,Caret.X,Caret.Y);
end; end;

View File

@ -348,6 +348,7 @@ procedure DebugLn(const s1,s2,s3,s4,s5,s6,s7,s8,s9,s10: string);
procedure DebugLn(const s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11: string); procedure DebugLn(const s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11: string);
procedure DebugLn(const s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12: string); procedure DebugLn(const s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12: string);
procedure DbgOut(Args: array of const);
procedure DbgOut(const s: string); procedure DbgOut(const s: string);
procedure DbgOut(const s1,s2: string); procedure DbgOut(const s1,s2: string);
procedure DbgOut(const s1,s2,s3: string); procedure DbgOut(const s1,s2,s3: string);
@ -2615,38 +2616,8 @@ begin
end; end;
procedure DebugLn(Args: array of const); procedure DebugLn(Args: array of const);
var
i: Integer;
begin begin
for i:=Low(Args) to High(Args) do begin DbgOut(Args);
case Args[i].VType of
vtInteger: DbgOut(dbgs(Args[i].vinteger));
vtInt64: DbgOut(dbgs(Args[i].VInt64^));
vtQWord: DbgOut(dbgs(Args[i].VQWord^));
vtBoolean: DbgOut(dbgs(Args[i].vboolean));
vtExtended: DbgOut(dbgs(Args[i].VExtended^));
{$ifdef FPC_CURRENCY_IS_INT64}
// MWE:
// fpc 2.x has troubles in choosing the right dbgs()
// so we convert here
vtCurrency: DbgOut(dbgs(int64(Args[i].vCurrency^)/10000 , 4));
{$else}
vtCurrency: DbgOut(dbgs(Args[i].vCurrency^));
{$endif}
vtString: DbgOut(Args[i].VString^);
vtAnsiString: DbgOut(AnsiString(Args[i].VAnsiString));
vtChar: DbgOut(Args[i].VChar);
vtPChar: DbgOut(Args[i].VPChar);
vtPWideChar: DbgOut(Args[i].VPWideChar);
vtWideChar: DbgOut(Args[i].VWideChar);
vtWidestring: DbgOut(WideString(Args[i].VWideString));
vtObject: DbgOut(DbgSName(Args[i].VObject));
vtClass: DbgOut(DbgSName(Args[i].VClass));
vtPointer: DbgOut(Dbgs(Args[i].VPointer));
else
DbgOut('?unknown variant?');
end;
end;
DebugLn; DebugLn;
end; end;
@ -2722,6 +2693,41 @@ begin
DebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12); DebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12);
end; end;
procedure DbgOut(Args: array of const);
var
i: Integer;
begin
for i:=Low(Args) to High(Args) do begin
case Args[i].VType of
vtInteger: DbgOut(dbgs(Args[i].vinteger));
vtInt64: DbgOut(dbgs(Args[i].VInt64^));
vtQWord: DbgOut(dbgs(Args[i].VQWord^));
vtBoolean: DbgOut(dbgs(Args[i].vboolean));
vtExtended: DbgOut(dbgs(Args[i].VExtended^));
{$ifdef FPC_CURRENCY_IS_INT64}
// MWE:
// fpc 2.x has troubles in choosing the right dbgs()
// so we convert here
vtCurrency: DbgOut(dbgs(int64(Args[i].vCurrency^)/10000 , 4));
{$else}
vtCurrency: DbgOut(dbgs(Args[i].vCurrency^));
{$endif}
vtString: DbgOut(Args[i].VString^);
vtAnsiString: DbgOut(AnsiString(Args[i].VAnsiString));
vtChar: DbgOut(Args[i].VChar);
vtPChar: DbgOut(Args[i].VPChar);
vtPWideChar: DbgOut(Args[i].VPWideChar);
vtWideChar: DbgOut(Args[i].VWideChar);
vtWidestring: DbgOut(WideString(Args[i].VWideString));
vtObject: DbgOut(DbgSName(Args[i].VObject));
vtClass: DbgOut(DbgSName(Args[i].VClass));
vtPointer: DbgOut(Dbgs(Args[i].VPointer));
else
DbgOut('?unknown variant?');
end;
end;
end;
procedure DBGOut(const s: string); procedure DBGOut(const s: string);
begin begin
if Assigned(CTDbgOutEvent) then if Assigned(CTDbgOutEvent) then