location tracking is enabled). Allow profiling option. Add some comments and clean-ups to types/*.go.
		
			
				
	
	
		
			420 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			420 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package ast
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"path/filepath"
 | |
| 
 | |
| 	"github.com/elliotchance/c2go/util"
 | |
| )
 | |
| 
 | |
| // Position is type of position in source code
 | |
| type Position struct {
 | |
| 	File      string // The relative or absolute file path.
 | |
| 	Line      int    // Start line
 | |
| 	LineEnd   int    // End line
 | |
| 	Column    int    // Start column
 | |
| 	ColumnEnd int    // End column
 | |
| 
 | |
| 	// This is the original string that was converted. This is used for
 | |
| 	// debugging. We could derive this value from the other properties to save
 | |
| 	// on a bit of memory, but let worry about that later.
 | |
| 	StringValue string
 | |
| }
 | |
| 
 | |
| // GetSimpleLocation - return a string like : "file:line" in
 | |
| // according to position
 | |
| // Example : " /tmp/1.c:200 "
 | |
| func (p Position) GetSimpleLocation() (loc string) {
 | |
| 	file := p.File
 | |
| 	if f, err := filepath.Abs(p.File); err != nil {
 | |
| 		file = f
 | |
| 	}
 | |
| 	return fmt.Sprintf(" %s:%d ", file, p.Line)
 | |
| }
 | |
| 
 | |
| func NewPositionFromString(s string) Position {
 | |
| 	if !TrackPositions {
 | |
| 		return Position{}
 | |
| 	}
 | |
| 	re := util.GetRegex(`<invalid sloc>|<scratch space>|<built-in>`)
 | |
| 	if re.MatchString(s) || s == "" {
 | |
| 		return Position{}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^col:(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Column:      util.Atoi(groups[1]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^col:(\d+), col:(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Column:      util.Atoi(groups[1]),
 | |
| 			ColumnEnd:   util.Atoi(groups[2]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^line:(\d+), line:(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Line:        util.Atoi(groups[1]),
 | |
| 			LineEnd:     util.Atoi(groups[2]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^col:(\d+), line:(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Column:      util.Atoi(groups[1]),
 | |
| 			Line:        util.Atoi(groups[2]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^line:(\d+):(\d+), line:(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Line:        util.Atoi(groups[1]),
 | |
| 			Column:      util.Atoi(groups[2]),
 | |
| 			LineEnd:     util.Atoi(groups[3]),
 | |
| 			ColumnEnd:   util.Atoi(groups[4]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^col:(\d+), line:(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Column:      util.Atoi(groups[1]),
 | |
| 			LineEnd:     util.Atoi(groups[2]),
 | |
| 			ColumnEnd:   util.Atoi(groups[3]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^line:(\d+):(\d+), col:(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Line:        util.Atoi(groups[1]),
 | |
| 			Column:      util.Atoi(groups[2]),
 | |
| 			ColumnEnd:   util.Atoi(groups[3]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^line:(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Line:        util.Atoi(groups[1]),
 | |
| 			Column:      util.Atoi(groups[2]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// This must be below all of the others.
 | |
| 	re = util.GetRegex(`^([^:]+):(\d+):(\d+), col:(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			File:        groups[1],
 | |
| 			Line:        util.Atoi(groups[2]),
 | |
| 			Column:      util.Atoi(groups[3]),
 | |
| 			ColumnEnd:   util.Atoi(groups[4]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^([^:]+):(\d+):(\d+), line:(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			File:        groups[1],
 | |
| 			Line:        util.Atoi(groups[2]),
 | |
| 			Column:      util.Atoi(groups[3]),
 | |
| 			LineEnd:     util.Atoi(groups[4]),
 | |
| 			ColumnEnd:   util.Atoi(groups[5]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^([^:]+):(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			File:        groups[1],
 | |
| 			Line:        util.Atoi(groups[2]),
 | |
| 			Column:      util.Atoi(groups[3]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^([^:]+):(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			File:        groups[1],
 | |
| 			Line:        util.Atoi(groups[2]),
 | |
| 			Column:      util.Atoi(groups[3]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^col:(\d+), ([^:]+):(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			Column:      util.Atoi(groups[1]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	re = util.GetRegex(`^([^:]+):(\d+):(\d+), ([^:]+):(\d+):(\d+)$`)
 | |
| 	if groups := re.FindStringSubmatch(s); len(groups) > 0 {
 | |
| 		return Position{
 | |
| 			StringValue: s,
 | |
| 			File:        groups[1],
 | |
| 			Line:        util.Atoi(groups[2]),
 | |
| 			Column:      util.Atoi(groups[3]),
 | |
| 			LineEnd:     util.Atoi(groups[5]),
 | |
| 			ColumnEnd:   util.Atoi(groups[6]),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	panic("unable to understand position '" + s + "'")
 | |
| }
 | |
| 
 | |
| func mergePositions(p1, p2 Position) Position {
 | |
| 	if p2.File != "" {
 | |
| 		p1.File = p2.File
 | |
| 		p1.Line = 0
 | |
| 		p1.LineEnd = 0
 | |
| 		p1.Column = 0
 | |
| 		p1.ColumnEnd = 0
 | |
| 	}
 | |
| 
 | |
| 	if p2.Line != 0 {
 | |
| 		p1.Line = p2.Line
 | |
| 		p1.LineEnd = 0
 | |
| 	}
 | |
| 
 | |
| 	if p2.LineEnd != 0 {
 | |
| 		p1.LineEnd = p2.LineEnd
 | |
| 	}
 | |
| 
 | |
| 	if p2.Column != 0 {
 | |
| 		p1.Column = p2.Column
 | |
| 		p1.ColumnEnd = 0
 | |
| 	}
 | |
| 
 | |
| 	if p2.ColumnEnd != 0 {
 | |
| 		p1.ColumnEnd = p2.ColumnEnd
 | |
| 	}
 | |
| 
 | |
| 	return p1
 | |
| }
 | |
| 
 | |
| var pos Position
 | |
| 
 | |
| // PositionBuiltIn - default value for fix position
 | |
| var PositionBuiltIn = "<built-in>"
 | |
| 
 | |
| func FixPositions(nodes []Node) {
 | |
| 	pos = Position{File: PositionBuiltIn}
 | |
| 	fixPositions(nodes)
 | |
| }
 | |
| 
 | |
| func fixPositions(nodes []Node) {
 | |
| 	for _, node := range nodes {
 | |
| 		if node != nil {
 | |
| 			pos = mergePositions(pos, node.Position())
 | |
| 			setPosition(node, pos)
 | |
| 			fixPositions(node.Children())
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func setPosition(node Node, position Position) {
 | |
| 	switch n := node.(type) {
 | |
| 	case *AlignedAttr:
 | |
| 		n.Pos = position
 | |
| 	case *AllocSizeAttr:
 | |
| 		n.Pos = position
 | |
| 	case *AlwaysInlineAttr:
 | |
| 		n.Pos = position
 | |
| 	case *ArraySubscriptExpr:
 | |
| 		n.Pos = position
 | |
| 	case *AsmLabelAttr:
 | |
| 		n.Pos = position
 | |
| 	case *AvailabilityAttr:
 | |
| 		n.Pos = position
 | |
| 	case *BinaryOperator:
 | |
| 		n.Pos = position
 | |
| 	case *BlockCommandComment:
 | |
| 		n.Pos = position
 | |
| 	case *BreakStmt:
 | |
| 		n.Pos = position
 | |
| 	case *CallExpr:
 | |
| 		n.Pos = position
 | |
| 	case *CaseStmt:
 | |
| 		n.Pos = position
 | |
| 	case *CharacterLiteral:
 | |
| 		n.Pos = position
 | |
| 	case *CompoundStmt:
 | |
| 		n.Pos = position
 | |
| 	case *ConditionalOperator:
 | |
| 		n.Pos = position
 | |
| 	case *ConstAttr:
 | |
| 		n.Pos = position
 | |
| 	case *ContinueStmt:
 | |
| 		n.Pos = position
 | |
| 	case *CompoundAssignOperator:
 | |
| 		n.Pos = position
 | |
| 	case *CompoundLiteralExpr:
 | |
| 		n.Pos = position
 | |
| 	case *CStyleCastExpr:
 | |
| 		n.Pos = position
 | |
| 	case *DeclRefExpr:
 | |
| 		n.Pos = position
 | |
| 	case *DeclStmt:
 | |
| 		n.Pos = position
 | |
| 	case *DefaultStmt:
 | |
| 		n.Pos = position
 | |
| 	case *DeprecatedAttr:
 | |
| 		n.Pos = position
 | |
| 	case *DisableTailCallsAttr:
 | |
| 		n.Pos = position
 | |
| 	case *DoStmt:
 | |
| 		n.Pos = position
 | |
| 	case *EmptyDecl:
 | |
| 		n.Pos = position
 | |
| 	case *EnumConstantDecl:
 | |
| 		n.Pos = position
 | |
| 	case *EnumDecl:
 | |
| 		n.Pos = position
 | |
| 	case *FieldDecl:
 | |
| 		n.Pos = position
 | |
| 	case *FloatingLiteral:
 | |
| 		n.Pos = position
 | |
| 	case *FormatAttr:
 | |
| 		n.Pos = position
 | |
| 	case *FormatArgAttr:
 | |
| 		n.Pos = position
 | |
| 	case *FullComment:
 | |
| 		n.Pos = position
 | |
| 	case *FunctionDecl:
 | |
| 		n.Pos = position
 | |
| 	case *ForStmt:
 | |
| 		n.Pos = position
 | |
| 	case *GCCAsmStmt:
 | |
| 		n.Pos = position
 | |
| 	case *HTMLStartTagComment:
 | |
| 		n.Pos = position
 | |
| 	case *HTMLEndTagComment:
 | |
| 		n.Pos = position
 | |
| 	case *GotoStmt:
 | |
| 		n.Pos = position
 | |
| 	case *IfStmt:
 | |
| 		n.Pos = position
 | |
| 	case *ImplicitCastExpr:
 | |
| 		n.Pos = position
 | |
| 	case *ImplicitValueInitExpr:
 | |
| 		n.Pos = position
 | |
| 	case *IndirectFieldDecl:
 | |
| 		n.Pos = position
 | |
| 	case *InitListExpr:
 | |
| 		n.Pos = position
 | |
| 	case *InlineCommandComment:
 | |
| 		n.Pos = position
 | |
| 	case *IntegerLiteral:
 | |
| 		n.Pos = position
 | |
| 	case *LabelStmt:
 | |
| 		n.Pos = position
 | |
| 	case *MallocAttr:
 | |
| 		n.Pos = position
 | |
| 	case *MaxFieldAlignmentAttr:
 | |
| 		n.Pos = position
 | |
| 	case *MemberExpr:
 | |
| 		n.Pos = position
 | |
| 	case *ModeAttr:
 | |
| 		n.Pos = position
 | |
| 	case *NoInlineAttr:
 | |
| 		n.Pos = position
 | |
| 	case *NoThrowAttr:
 | |
| 		n.Pos = position
 | |
| 	case *NotTailCalledAttr:
 | |
| 		n.Pos = position
 | |
| 	case *NonNullAttr:
 | |
| 		n.Pos = position
 | |
| 	case *OffsetOfExpr:
 | |
| 		n.Pos = position
 | |
| 	case *PackedAttr:
 | |
| 		n.Pos = position
 | |
| 	case *ParagraphComment:
 | |
| 		n.Pos = position
 | |
| 	case *ParamCommandComment:
 | |
| 		n.Pos = position
 | |
| 	case *ParenExpr:
 | |
| 		n.Pos = position
 | |
| 	case *ParmVarDecl:
 | |
| 		n.Pos = position
 | |
| 	case *PredefinedExpr:
 | |
| 		n.Pos = position
 | |
| 	case *PureAttr:
 | |
| 		n.Pos = position
 | |
| 	case *RecordDecl:
 | |
| 		n.Pos = position
 | |
| 	case *RestrictAttr:
 | |
| 		n.Pos = position
 | |
| 	case *ReturnStmt:
 | |
| 		n.Pos = position
 | |
| 	case *ReturnsTwiceAttr:
 | |
| 		n.Pos = position
 | |
| 	case *SentinelAttr:
 | |
| 		n.Pos = position
 | |
| 	case *StmtExpr:
 | |
| 		n.Pos = position
 | |
| 	case *StringLiteral:
 | |
| 		n.Pos = position
 | |
| 	case *SwitchStmt:
 | |
| 		n.Pos = position
 | |
| 	case *TextComment:
 | |
| 		n.Pos = position
 | |
| 	case *TransparentUnionAttr:
 | |
| 		n.Pos = position
 | |
| 	case *TypedefDecl:
 | |
| 		n.Pos = position
 | |
| 	case *UnaryExprOrTypeTraitExpr:
 | |
| 		n.Pos = position
 | |
| 	case *UnaryOperator:
 | |
| 		n.Pos = position
 | |
| 	case *UnusedAttr:
 | |
| 		n.Pos = position
 | |
| 	case *VAArgExpr:
 | |
| 		n.Pos = position
 | |
| 	case *VarDecl:
 | |
| 		n.Pos = position
 | |
| 	case *VerbatimBlockComment:
 | |
| 		n.Pos = position
 | |
| 	case *VerbatimBlockLineComment:
 | |
| 		n.Pos = position
 | |
| 	case *VerbatimLineComment:
 | |
| 		n.Pos = position
 | |
| 	case *VisibilityAttr:
 | |
| 		n.Pos = position
 | |
| 	case *WarnUnusedResultAttr:
 | |
| 		n.Pos = position
 | |
| 	case *WeakAttr:
 | |
| 		n.Pos = position
 | |
| 	case *WhileStmt:
 | |
| 		n.Pos = position
 | |
| 	case *TypedefType, *Typedef, *TranslationUnitDecl, *RecordType, *Record,
 | |
| 		*QualType, *PointerType, *DecayedType, *ParenType,
 | |
| 		*IncompleteArrayType, *FunctionProtoType, *EnumType, *Enum,
 | |
| 		*ElaboratedType, *ConstantArrayType, *BuiltinType, *ArrayFiller,
 | |
| 		*Field:
 | |
| 		// These do not have positions so they can be ignored.
 | |
| 	default:
 | |
| 		panic(fmt.Sprintf("unknown node type: %+#v", node))
 | |
| 	}
 | |
| }
 |