github.com/llir/llvm@v0.3.6/asm/specialized_metadata.go (about)

     1  package asm
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  
     7  	"github.com/llir/ll/ast"
     8  	asmenum "github.com/llir/llvm/asm/enum"
     9  	"github.com/llir/llvm/ir/enum"
    10  	"github.com/llir/llvm/ir/metadata"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  // === [ SpecializedMDNode ] ===================================================
    15  
    16  // irSpecializedMDNode returns the IR specialized metadata node corresponding to
    17  // the given AST specialized metadata node.
    18  func (gen *generator) irSpecializedMDNode(new metadata.Definition, old ast.SpecializedMDNode) (metadata.SpecializedNode, error) {
    19  	switch old := old.(type) {
    20  	case *ast.DIBasicType:
    21  		return gen.irDIBasicType(new, old)
    22  	case *ast.DICommonBlock:
    23  		return gen.irDICommonBlock(new, old)
    24  	case *ast.DICompileUnit:
    25  		return gen.irDICompileUnit(new, old)
    26  	case *ast.DICompositeType:
    27  		return gen.irDICompositeType(new, old)
    28  	case *ast.DIDerivedType:
    29  		return gen.irDIDerivedType(new, old)
    30  	case *ast.DIEnumerator:
    31  		return gen.irDIEnumerator(new, old)
    32  	case *ast.DIExpression:
    33  		return gen.irDIExpression(new, old)
    34  	case *ast.DIFile:
    35  		return gen.irDIFile(new, old)
    36  	case *ast.DIGlobalVariable:
    37  		return gen.irDIGlobalVariable(new, old)
    38  	case *ast.DIGlobalVariableExpression:
    39  		return gen.irDIGlobalVariableExpression(new, old)
    40  	case *ast.DIImportedEntity:
    41  		return gen.irDIImportedEntity(new, old)
    42  	case *ast.DILabel:
    43  		return gen.irDILabel(new, old)
    44  	case *ast.DILexicalBlock:
    45  		return gen.irDILexicalBlock(new, old)
    46  	case *ast.DILexicalBlockFile:
    47  		return gen.irDILexicalBlockFile(new, old)
    48  	case *ast.DILocalVariable:
    49  		return gen.irDILocalVariable(new, old)
    50  	case *ast.DILocation:
    51  		return gen.irDILocation(new, old)
    52  	case *ast.DIMacro:
    53  		return gen.irDIMacro(new, old)
    54  	case *ast.DIMacroFile:
    55  		return gen.irDIMacroFile(new, old)
    56  	case *ast.DIModule:
    57  		return gen.irDIModule(new, old)
    58  	case *ast.DINamespace:
    59  		return gen.irDINamespace(new, old)
    60  	case *ast.DIObjCProperty:
    61  		return gen.irDIObjCProperty(new, old)
    62  	case *ast.DIStringType:
    63  		return gen.irDIStringType(new, old)
    64  	case *ast.DISubprogram:
    65  		return gen.irDISubprogram(new, old)
    66  	case *ast.DISubrange:
    67  		return gen.irDISubrange(new, old)
    68  	case *ast.DISubroutineType:
    69  		return gen.irDISubroutineType(new, old)
    70  	case *ast.DITemplateTypeParameter:
    71  		return gen.irDITemplateTypeParameter(new, old)
    72  	case *ast.DITemplateValueParameter:
    73  		return gen.irDITemplateValueParameter(new, old)
    74  	case *ast.GenericDINode:
    75  		return gen.irGenericDINode(new, old)
    76  	default:
    77  		panic(fmt.Errorf("support for %T not yet implemented", old))
    78  	}
    79  }
    80  
    81  // --- [ DIBasicType ] ---------------------------------------------------------
    82  
    83  // irDIBasicType returns the IR specialized metadata node DIBasicType
    84  // corresponding to the given AST specialized metadata node DIBasicType. A new
    85  // IR specialized metadata node correspoding to the AST specialized metadata
    86  // node is created if new is nil, otherwise the body of new is populated.
    87  func (gen *generator) irDIBasicType(new metadata.SpecializedNode, old *ast.DIBasicType) (*metadata.DIBasicType, error) {
    88  	md, ok := new.(*metadata.DIBasicType)
    89  	if new == nil {
    90  		md = &metadata.DIBasicType{MetadataID: -1}
    91  	} else if !ok {
    92  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIBasicType, got %T", new))
    93  	}
    94  	for _, oldField := range old.Fields() {
    95  		switch oldField := oldField.(type) {
    96  		case *ast.TagField:
    97  			md.Tag = irDwarfTag(oldField.Tag())
    98  		case *ast.NameField:
    99  			md.Name = stringLit(oldField.Name())
   100  		case *ast.SizeField:
   101  			md.Size = uintLit(oldField.Size())
   102  		case *ast.AlignField:
   103  			md.Align = uintLit(oldField.Align())
   104  		case *ast.EncodingField:
   105  			md.Encoding = irDwarfAttEncodingOrUint(oldField.Encoding())
   106  		case *ast.FlagsField:
   107  			md.Flags = irDIFlags(oldField.Flags())
   108  		default:
   109  			panic(fmt.Errorf("support for DIBasicType field %T not yet implemented", old))
   110  		}
   111  	}
   112  	return md, nil
   113  }
   114  
   115  // --- [ DICommonBlock ] -------------------------------------------------------
   116  
   117  // irDICommonBlock returns the IR specialized metadata node DICommonBlock
   118  // corresponding to the given AST specialized metadata node DICommonBlock. A new
   119  // IR specialized metadata node correspoding to the AST specialized metadata
   120  // node is created if new is nil, otherwise the body of new is populated.
   121  func (gen *generator) irDICommonBlock(new metadata.SpecializedNode, old *ast.DICommonBlock) (*metadata.DICommonBlock, error) {
   122  	md, ok := new.(*metadata.DICommonBlock)
   123  	if new == nil {
   124  		md = &metadata.DICommonBlock{MetadataID: -1}
   125  	} else if !ok {
   126  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DICommonBlock, got %T", new))
   127  	}
   128  	for _, oldField := range old.Fields() {
   129  		switch oldField := oldField.(type) {
   130  		case *ast.ScopeField:
   131  			scope, err := gen.irMDField(oldField.Scope())
   132  			if err != nil {
   133  				return nil, errors.WithStack(err)
   134  			}
   135  			md.Scope = scope
   136  		case *ast.DeclarationField:
   137  			declaration, err := gen.irMDField(oldField.Declaration())
   138  			if err != nil {
   139  				return nil, errors.WithStack(err)
   140  			}
   141  			md.Declaration = declaration
   142  		case *ast.NameField:
   143  			md.Name = stringLit(oldField.Name())
   144  		case *ast.FileField:
   145  			file, err := gen.irMDField(oldField.File())
   146  			if err != nil {
   147  				return nil, errors.WithStack(err)
   148  			}
   149  			switch file := file.(type) {
   150  			case *metadata.NullLit:
   151  				// nothing to do.
   152  			case *metadata.DIFile:
   153  				md.File = file
   154  			default:
   155  				panic(fmt.Errorf("support for metadata DICommonBlock file field type %T not yet implemented", file))
   156  			}
   157  		case *ast.LineField:
   158  			md.Line = intLit(oldField.Line())
   159  		default:
   160  			panic(fmt.Errorf("support for DICommonBlock field %T not yet implemented", old))
   161  		}
   162  	}
   163  	return md, nil
   164  }
   165  
   166  // --- [ DICompileUnit ] -------------------------------------------------------
   167  
   168  // irDICompileUnit returns the IR specialized metadata node DICompileUnit
   169  // corresponding to the given AST specialized metadata node DICompileUnit. A new
   170  // IR specialized metadata node correspoding to the AST specialized metadata
   171  // node is created if new is nil, otherwise the body of new is populated.
   172  func (gen *generator) irDICompileUnit(new metadata.SpecializedNode, old *ast.DICompileUnit) (*metadata.DICompileUnit, error) {
   173  	md, ok := new.(*metadata.DICompileUnit)
   174  	if new == nil {
   175  		md = &metadata.DICompileUnit{MetadataID: -1}
   176  	} else if !ok {
   177  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DICompileUnit, got %T", new))
   178  	}
   179  	for _, oldField := range old.Fields() {
   180  		switch oldField := oldField.(type) {
   181  		case *ast.LanguageField:
   182  			md.Language = irDwarfLang(oldField.Language())
   183  		case *ast.FileField:
   184  			file, err := gen.irMDField(oldField.File())
   185  			if err != nil {
   186  				return nil, errors.WithStack(err)
   187  			}
   188  			switch file := file.(type) {
   189  			case *metadata.NullLit:
   190  				// nothing to do.
   191  			case *metadata.DIFile:
   192  				md.File = file
   193  			default:
   194  				panic(fmt.Errorf("support for metadata DICompileUnit file field type %T not yet implemented", file))
   195  			}
   196  		case *ast.ProducerField:
   197  			md.Producer = stringLit(oldField.Producer())
   198  		case *ast.IsOptimizedField:
   199  			md.IsOptimized = boolLit(oldField.IsOptimized())
   200  		case *ast.FlagsStringField:
   201  			md.Flags = stringLit(oldField.Flags())
   202  		case *ast.RuntimeVersionField:
   203  			md.RuntimeVersion = uintLit(oldField.RuntimeVersion())
   204  		case *ast.SplitDebugFilenameField:
   205  			md.SplitDebugFilename = stringLit(oldField.SplitDebugFilename())
   206  		case *ast.EmissionKindField:
   207  			md.EmissionKind = irEmissionKind(oldField.EmissionKind())
   208  		case *ast.EnumsField:
   209  			enums, err := gen.irMDField(oldField.Enums())
   210  			if err != nil {
   211  				return nil, errors.WithStack(err)
   212  			}
   213  			switch enums := enums.(type) {
   214  			case *metadata.NullLit:
   215  				// nothing to do.
   216  			case *metadata.Tuple:
   217  				md.Enums = enums
   218  			default:
   219  				panic(fmt.Errorf("support for metadata DICompileUnit enums field type %T not yet implemented", enums))
   220  			}
   221  		case *ast.RetainedTypesField:
   222  			retainedTypes, err := gen.irMDField(oldField.RetainedTypes())
   223  			if err != nil {
   224  				return nil, errors.WithStack(err)
   225  			}
   226  			switch retainedTypes := retainedTypes.(type) {
   227  			case *metadata.NullLit:
   228  				// nothing to do.
   229  			case *metadata.Tuple:
   230  				md.RetainedTypes = retainedTypes
   231  			default:
   232  				panic(fmt.Errorf("support for metadata DICompileUnit retainedTypes field type %T not yet implemented", retainedTypes))
   233  			}
   234  		case *ast.GlobalsField:
   235  			globals, err := gen.irMDField(oldField.Globals())
   236  			if err != nil {
   237  				return nil, errors.WithStack(err)
   238  			}
   239  			switch globals := globals.(type) {
   240  			case *metadata.NullLit:
   241  				// nothing to do.
   242  			case *metadata.Tuple:
   243  				md.Globals = globals
   244  			default:
   245  				panic(fmt.Errorf("support for metadata DICompileUnit globals field type %T not yet implemented", globals))
   246  			}
   247  		case *ast.ImportsField:
   248  			imports, err := gen.irMDField(oldField.Imports())
   249  			if err != nil {
   250  				return nil, errors.WithStack(err)
   251  			}
   252  			switch imports := imports.(type) {
   253  			case *metadata.NullLit:
   254  				// nothing to do.
   255  			case *metadata.Tuple:
   256  				md.Imports = imports
   257  			default:
   258  				panic(fmt.Errorf("support for metadata DICompileUnit imports field type %T not yet implemented", imports))
   259  			}
   260  		case *ast.MacrosField:
   261  			macros, err := gen.irMDField(oldField.Macros())
   262  			if err != nil {
   263  				return nil, errors.WithStack(err)
   264  			}
   265  			switch macros := macros.(type) {
   266  			case *metadata.NullLit:
   267  				// nothing to do.
   268  			case *metadata.Tuple:
   269  				md.Macros = macros
   270  			default:
   271  				panic(fmt.Errorf("support for metadata DICompileUnit macros field type %T not yet implemented", macros))
   272  			}
   273  		case *ast.DwoIdField:
   274  			md.DwoID = uintLit(oldField.DwoId())
   275  		case *ast.SplitDebugInliningField:
   276  			md.SplitDebugInlining = boolLit(oldField.SplitDebugInlining())
   277  		case *ast.DebugInfoForProfilingField:
   278  			md.DebugInfoForProfiling = boolLit(oldField.DebugInfoForProfiling())
   279  		case *ast.NameTableKindField:
   280  			md.NameTableKind = irNameTableKind(oldField.NameTableKind())
   281  		case *ast.RangesBaseAddressField:
   282  			md.RangesBaseAddress = boolLit(oldField.RangesBaseAddress())
   283  		case *ast.SysrootField:
   284  			md.Sysroot = stringLit(oldField.Sysroot())
   285  		case *ast.SDKField:
   286  			md.SDK = stringLit(oldField.SDK())
   287  		default:
   288  			panic(fmt.Errorf("support for DICompileUnit field %T not yet implemented", old))
   289  		}
   290  	}
   291  	return md, nil
   292  }
   293  
   294  // --- [ DICompositeType ] -----------------------------------------------------
   295  
   296  // irDICompositeType returns the IR specialized metadata node DICompositeType
   297  // corresponding to the given AST specialized metadata node DICompositeType. A
   298  // new IR specialized metadata node correspoding to the AST specialized metadata
   299  // node is created if new is nil, otherwise the body of new is populated.
   300  func (gen *generator) irDICompositeType(new metadata.SpecializedNode, old *ast.DICompositeType) (*metadata.DICompositeType, error) {
   301  	md, ok := new.(*metadata.DICompositeType)
   302  	if new == nil {
   303  		md = &metadata.DICompositeType{MetadataID: -1}
   304  	} else if !ok {
   305  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DICompositeType, got %T", new))
   306  	}
   307  	for _, oldField := range old.Fields() {
   308  		switch oldField := oldField.(type) {
   309  		case *ast.TagField:
   310  			md.Tag = irDwarfTag(oldField.Tag())
   311  		case *ast.NameField:
   312  			md.Name = stringLit(oldField.Name())
   313  		case *ast.ScopeField:
   314  			scope, err := gen.irMDField(oldField.Scope())
   315  			if err != nil {
   316  				return nil, errors.WithStack(err)
   317  			}
   318  			md.Scope = scope
   319  		case *ast.FileField:
   320  			file, err := gen.irMDField(oldField.File())
   321  			if err != nil {
   322  				return nil, errors.WithStack(err)
   323  			}
   324  			switch file := file.(type) {
   325  			case *metadata.NullLit:
   326  				// nothing to do.
   327  			case *metadata.DIFile:
   328  				md.File = file
   329  			default:
   330  				panic(fmt.Errorf("support for metadata DICompositeType file field type %T not yet implemented", file))
   331  			}
   332  		case *ast.LineField:
   333  			md.Line = intLit(oldField.Line())
   334  		case *ast.BaseTypeField:
   335  			baseType, err := gen.irMDField(oldField.BaseType())
   336  			if err != nil {
   337  				return nil, errors.WithStack(err)
   338  			}
   339  			md.BaseType = baseType
   340  		case *ast.SizeField:
   341  			md.Size = uintLit(oldField.Size())
   342  		case *ast.AlignField:
   343  			md.Align = uintLit(oldField.Align())
   344  		case *ast.OffsetField:
   345  			md.Offset = uintLit(oldField.OffsetField())
   346  		case *ast.FlagsField:
   347  			md.Flags = irDIFlags(oldField.Flags())
   348  		case *ast.ElementsField:
   349  			elements, err := gen.irMDField(oldField.Elements())
   350  			if err != nil {
   351  				return nil, errors.WithStack(err)
   352  			}
   353  			switch elements := elements.(type) {
   354  			case *metadata.NullLit:
   355  				// nothing to do.
   356  			case *metadata.Tuple:
   357  				md.Elements = elements
   358  			default:
   359  				panic(fmt.Errorf("support for metadata DICompositeType elements field type %T not yet implemented", elements))
   360  			}
   361  		case *ast.RuntimeLangField:
   362  			md.RuntimeLang = irDwarfLang(oldField.RuntimeLang())
   363  		case *ast.VtableHolderField:
   364  			vtableHolder, err := gen.irMDField(oldField.VtableHolder())
   365  			if err != nil {
   366  				return nil, errors.WithStack(err)
   367  			}
   368  			switch vtableHolder := vtableHolder.(type) {
   369  			case *metadata.NullLit:
   370  				// nothing to do.
   371  			case *metadata.DIBasicType:
   372  				md.VtableHolder = vtableHolder
   373  			case *metadata.DICompositeType:
   374  				md.VtableHolder = vtableHolder
   375  			default:
   376  				panic(fmt.Errorf("support for metadata DICompositeType vtableHolder field type %T not yet implemented", vtableHolder))
   377  			}
   378  		case *ast.TemplateParamsField:
   379  			templateParams, err := gen.irMDField(oldField.TemplateParams())
   380  			if err != nil {
   381  				return nil, errors.WithStack(err)
   382  			}
   383  			switch templateParams := templateParams.(type) {
   384  			case *metadata.NullLit:
   385  				// nothing to do.
   386  			case *metadata.Tuple:
   387  				md.TemplateParams = templateParams
   388  			default:
   389  				panic(fmt.Errorf("support for metadata DICompositeType templateParams field type %T not yet implemented", templateParams))
   390  			}
   391  		case *ast.IdentifierField:
   392  			md.Identifier = stringLit(oldField.Identifier())
   393  		case *ast.DiscriminatorField:
   394  			discriminator, err := gen.irMDField(oldField.Discriminator())
   395  			if err != nil {
   396  				return nil, errors.WithStack(err)
   397  			}
   398  			md.Discriminator = discriminator
   399  		case *ast.DataLocationField:
   400  			dataLocation, err := gen.irMDField(oldField.DataLocation())
   401  			if err != nil {
   402  				return nil, errors.WithStack(err)
   403  			}
   404  			md.DataLocation = dataLocation
   405  		case *ast.AssociatedField:
   406  			associated, err := gen.irMDField(oldField.Associated())
   407  			if err != nil {
   408  				return nil, errors.WithStack(err)
   409  			}
   410  			md.Associated = associated
   411  		case *ast.AllocatedField:
   412  			allocated, err := gen.irMDField(oldField.Allocated())
   413  			if err != nil {
   414  				return nil, errors.WithStack(err)
   415  			}
   416  			md.Allocated = allocated
   417  		case *ast.RankField:
   418  			rank, err := gen.irMDFieldOrInt(oldField.Rank())
   419  			if err != nil {
   420  				return nil, errors.WithStack(err)
   421  			}
   422  			md.Rank = rank
   423  		case *ast.AnnotationsField:
   424  			annotations, err := gen.irMDField(oldField.Annotations())
   425  			if err != nil {
   426  				return nil, errors.WithStack(err)
   427  			}
   428  			md.Annotations = annotations
   429  		default:
   430  			panic(fmt.Errorf("support for DICompositeType field %T not yet implemented", old))
   431  		}
   432  	}
   433  	return md, nil
   434  }
   435  
   436  // --- [ DIDerivedType ] -------------------------------------------------------
   437  
   438  // irDIDerivedType returns the IR specialized metadata node DIDerivedType
   439  // corresponding to the given AST specialized metadata node DIDerivedType. A new
   440  // IR specialized metadata node correspoding to the AST specialized metadata
   441  // node is created if new is nil, otherwise the body of new is populated.
   442  func (gen *generator) irDIDerivedType(new metadata.SpecializedNode, old *ast.DIDerivedType) (*metadata.DIDerivedType, error) {
   443  	md, ok := new.(*metadata.DIDerivedType)
   444  	if new == nil {
   445  		md = &metadata.DIDerivedType{MetadataID: -1}
   446  	} else if !ok {
   447  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIDerivedType, got %T", new))
   448  	}
   449  	for _, oldField := range old.Fields() {
   450  		switch oldField := oldField.(type) {
   451  		case *ast.TagField:
   452  			md.Tag = irDwarfTag(oldField.Tag())
   453  		case *ast.NameField:
   454  			md.Name = stringLit(oldField.Name())
   455  		case *ast.ScopeField:
   456  			scope, err := gen.irMDField(oldField.Scope())
   457  			if err != nil {
   458  				return nil, errors.WithStack(err)
   459  			}
   460  			md.Scope = scope
   461  		case *ast.FileField:
   462  			file, err := gen.irMDField(oldField.File())
   463  			if err != nil {
   464  				return nil, errors.WithStack(err)
   465  			}
   466  			switch file := file.(type) {
   467  			case *metadata.NullLit:
   468  				// nothing to do.
   469  			case *metadata.DIFile:
   470  				md.File = file
   471  			default:
   472  				panic(fmt.Errorf("support for metadata DIDerivedType file field type %T not yet implemented", file))
   473  			}
   474  		case *ast.LineField:
   475  			md.Line = intLit(oldField.Line())
   476  		case *ast.BaseTypeField:
   477  			baseType, err := gen.irMDField(oldField.BaseType())
   478  			if err != nil {
   479  				return nil, errors.WithStack(err)
   480  			}
   481  			md.BaseType = baseType
   482  		case *ast.SizeField:
   483  			md.Size = uintLit(oldField.Size())
   484  		case *ast.AlignField:
   485  			md.Align = uintLit(oldField.Align())
   486  		case *ast.OffsetField:
   487  			// TODO: rename OffsetField method to Offset once https://github.com/inspirer/textmapper/issues/13 is resolved.
   488  			md.Offset = uintLit(oldField.OffsetField())
   489  		case *ast.FlagsField:
   490  			md.Flags = irDIFlags(oldField.Flags())
   491  		case *ast.ExtraDataField:
   492  			extraData, err := gen.irMDField(oldField.ExtraData())
   493  			if err != nil {
   494  				return nil, errors.WithStack(err)
   495  			}
   496  			md.ExtraData = extraData
   497  		case *ast.DwarfAddressSpaceField:
   498  			md.DwarfAddressSpace = uintLit(oldField.DwarfAddressSpace())
   499  		case *ast.AnnotationsField:
   500  			annotations, err := gen.irMDField(oldField.Annotations())
   501  			if err != nil {
   502  				return nil, errors.WithStack(err)
   503  			}
   504  			md.Annotations = annotations
   505  		default:
   506  			panic(fmt.Errorf("support for DIDerivedType field %T not yet implemented", old))
   507  		}
   508  	}
   509  	return md, nil
   510  }
   511  
   512  // --- [ DIEnumerator ] --------------------------------------------------------
   513  
   514  // irDIEnumerator returns the IR specialized metadata node DIEnumerator
   515  // corresponding to the given AST specialized metadata node DIEnumerator. A new
   516  // IR specialized metadata node correspoding to the AST specialized metadata
   517  // node is created if new is nil, otherwise the body of new is populated.
   518  func (gen *generator) irDIEnumerator(new metadata.SpecializedNode, old *ast.DIEnumerator) (*metadata.DIEnumerator, error) {
   519  	md, ok := new.(*metadata.DIEnumerator)
   520  	if new == nil {
   521  		md = &metadata.DIEnumerator{MetadataID: -1}
   522  	} else if !ok {
   523  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIEnumerator, got %T", new))
   524  	}
   525  	isUnsigned := false
   526  	for _, oldField := range old.Fields() {
   527  		if oldField, ok := oldField.(*ast.IsUnsignedField); ok {
   528  			isUnsigned = boolLit(oldField.IsUnsigned())
   529  			break
   530  		}
   531  	}
   532  	for _, oldField := range old.Fields() {
   533  		switch oldField := oldField.(type) {
   534  		case *ast.NameField:
   535  			md.Name = stringLit(oldField.Name())
   536  		case *ast.ValueIntField:
   537  			if isUnsigned {
   538  				text := oldField.Value().Text()
   539  				x, err := strconv.ParseUint(text, 10, 64)
   540  				if err != nil {
   541  					panic(fmt.Errorf("unable to parse unsigned integer literal %q; %v", text, err))
   542  				}
   543  				md.Value = int64(x)
   544  			} else {
   545  				md.Value = intLit(oldField.Value())
   546  			}
   547  		case *ast.IsUnsignedField:
   548  			md.IsUnsigned = boolLit(oldField.IsUnsigned())
   549  		default:
   550  			panic(fmt.Errorf("support for DIEnumerator field %T not yet implemented", old))
   551  		}
   552  	}
   553  	return md, nil
   554  }
   555  
   556  // --- [ DIExpression ] --------------------------------------------------------
   557  
   558  // irDIExpression returns the IR specialized metadata node DIExpression
   559  // corresponding to the given AST specialized metadata node DIExpression. A new
   560  // IR specialized metadata node correspoding to the AST specialized metadata
   561  // node is created if new is nil, otherwise the body of new is populated.
   562  func (gen *generator) irDIExpression(new metadata.SpecializedNode, old *ast.DIExpression) (*metadata.DIExpression, error) {
   563  	md, ok := new.(*metadata.DIExpression)
   564  	if new == nil {
   565  		md = &metadata.DIExpression{MetadataID: -1}
   566  	} else if !ok {
   567  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIExpression, got %T", new))
   568  	}
   569  	for _, oldField := range old.Fields() {
   570  		field, err := gen.irDIExpressionField(oldField)
   571  		if err != nil {
   572  			return nil, errors.WithStack(err)
   573  		}
   574  		md.Fields = append(md.Fields, field)
   575  	}
   576  	return md, nil
   577  }
   578  
   579  // ~~~ [ DIExpressionField ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   580  
   581  // irDIExpressionField returns the IR DIExpression field corresponding to the
   582  // given AST DIExpression field.
   583  func (gen *generator) irDIExpressionField(old ast.DIExpressionField) (metadata.DIExpressionField, error) {
   584  	switch old := old.(type) {
   585  	case *ast.UintLit:
   586  		return metadata.UintLit(uintLit(*old)), nil
   587  	case *ast.DwarfAttEncodingEnum:
   588  		return asmenum.DwarfAttEncodingFromString(old.Text()), nil
   589  	case *ast.DwarfOp:
   590  		return asmenum.DwarfOpFromString(old.Text()), nil
   591  	default:
   592  		panic(fmt.Errorf("support for DIExpression field %T not yet implemented", old))
   593  	}
   594  }
   595  
   596  // --- [ DIFile ] --------------------------------------------------------------
   597  
   598  // irDIFile returns the IR specialized metadata node DIFile corresponding to the
   599  // given AST specialized metadata node DIFile. A new IR specialized metadata
   600  // node correspoding to the AST specialized metadata node is created if new is
   601  // nil, otherwise the body of new is populated.
   602  func (gen *generator) irDIFile(new metadata.SpecializedNode, old *ast.DIFile) (*metadata.DIFile, error) {
   603  	md, ok := new.(*metadata.DIFile)
   604  	if new == nil {
   605  		md = &metadata.DIFile{MetadataID: -1}
   606  	} else if !ok {
   607  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIFile, got %T", new))
   608  	}
   609  	for _, oldField := range old.Fields() {
   610  		switch oldField := oldField.(type) {
   611  		case *ast.FilenameField:
   612  			md.Filename = stringLit(oldField.Filename())
   613  		case *ast.DirectoryField:
   614  			md.Directory = stringLit(oldField.Directory())
   615  		case *ast.ChecksumkindField:
   616  			md.Checksumkind = asmenum.ChecksumKindFromString(oldField.Checksumkind().Text())
   617  		case *ast.ChecksumField:
   618  			md.Checksum = stringLit(oldField.Checksum())
   619  		case *ast.SourceField:
   620  			md.Source = stringLit(oldField.Source())
   621  		default:
   622  			panic(fmt.Errorf("support for DIFile field %T not yet implemented", old))
   623  		}
   624  	}
   625  	return md, nil
   626  }
   627  
   628  // --- [ DIGlobalVariable ] ----------------------------------------------------
   629  
   630  // irDIGlobalVariable returns the IR specialized metadata node DIGlobalVariable
   631  // corresponding to the given AST specialized metadata node DIGlobalVariable. A
   632  // new IR specialized metadata node correspoding to the AST specialized metadata
   633  // node is created if new is nil, otherwise the body of new is populated.
   634  func (gen *generator) irDIGlobalVariable(new metadata.SpecializedNode, old *ast.DIGlobalVariable) (*metadata.DIGlobalVariable, error) {
   635  	md, ok := new.(*metadata.DIGlobalVariable)
   636  	if new == nil {
   637  		md = &metadata.DIGlobalVariable{MetadataID: -1}
   638  	} else if !ok {
   639  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIGlobalVariable, got %T", new))
   640  	}
   641  	for _, oldField := range old.Fields() {
   642  		switch oldField := oldField.(type) {
   643  		case *ast.NameField:
   644  			md.Name = stringLit(oldField.Name())
   645  		case *ast.ScopeField:
   646  			scope, err := gen.irMDField(oldField.Scope())
   647  			if err != nil {
   648  				return nil, errors.WithStack(err)
   649  			}
   650  			md.Scope = scope
   651  		case *ast.LinkageNameField:
   652  			md.LinkageName = stringLit(oldField.LinkageName())
   653  		case *ast.FileField:
   654  			file, err := gen.irMDField(oldField.File())
   655  			if err != nil {
   656  				return nil, errors.WithStack(err)
   657  			}
   658  			switch file := file.(type) {
   659  			case *metadata.NullLit:
   660  				// nothing to do.
   661  			case *metadata.DIFile:
   662  				md.File = file
   663  			default:
   664  				panic(fmt.Errorf("support for metadata DIGlobalVariable file field type %T not yet implemented", file))
   665  			}
   666  		case *ast.LineField:
   667  			md.Line = intLit(oldField.Line())
   668  		case *ast.TypeField:
   669  			typ, err := gen.irMDField(oldField.Typ())
   670  			if err != nil {
   671  				return nil, errors.WithStack(err)
   672  			}
   673  			md.Type = typ
   674  		case *ast.IsLocalField:
   675  			md.IsLocal = boolLit(oldField.IsLocal())
   676  		case *ast.IsDefinitionField:
   677  			md.IsDefinition = boolLit(oldField.IsDefinition())
   678  		case *ast.TemplateParamsField:
   679  			templateParams, err := gen.irMDField(oldField.TemplateParams())
   680  			if err != nil {
   681  				return nil, errors.WithStack(err)
   682  			}
   683  			switch templateParams := templateParams.(type) {
   684  			case *metadata.NullLit:
   685  				// nothing to do.
   686  			case *metadata.Tuple:
   687  				md.TemplateParams = templateParams
   688  			default:
   689  				panic(fmt.Errorf("support for metadata DIGlobalVariable templateParams field type %T not yet implemented", templateParams))
   690  			}
   691  		case *ast.DeclarationField:
   692  			declaration, err := gen.irMDField(oldField.Declaration())
   693  			if err != nil {
   694  				return nil, errors.WithStack(err)
   695  			}
   696  			md.Declaration = declaration
   697  		case *ast.AlignField:
   698  			md.Align = uintLit(oldField.Align())
   699  		case *ast.AnnotationsField:
   700  			annotations, err := gen.irMDField(oldField.Annotations())
   701  			if err != nil {
   702  				return nil, errors.WithStack(err)
   703  			}
   704  			md.Annotations = annotations
   705  		default:
   706  			panic(fmt.Errorf("support for DIGlobalVariable field %T not yet implemented", old))
   707  		}
   708  	}
   709  	return md, nil
   710  }
   711  
   712  // --- [ DIGlobalVariableExpression ] ------------------------------------------
   713  
   714  // irDIGlobalVariableExpression returns the IR specialized metadata node
   715  // DIGlobalVariableExpression corresponding to the given AST specialized
   716  // metadata node DIGlobalVariableExpression. A new IR specialized metadata node
   717  // correspoding to the AST specialized metadata node is created if new is nil,
   718  // otherwise the body of new is populated.
   719  func (gen *generator) irDIGlobalVariableExpression(new metadata.SpecializedNode, old *ast.DIGlobalVariableExpression) (*metadata.DIGlobalVariableExpression, error) {
   720  	md, ok := new.(*metadata.DIGlobalVariableExpression)
   721  	if new == nil {
   722  		md = &metadata.DIGlobalVariableExpression{MetadataID: -1}
   723  	} else if !ok {
   724  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIGlobalVariableExpression, got %T", new))
   725  	}
   726  	for _, oldField := range old.Fields() {
   727  		switch oldField := oldField.(type) {
   728  		case *ast.VarField:
   729  			v, err := gen.irMDField(oldField.Var())
   730  			if err != nil {
   731  				return nil, errors.WithStack(err)
   732  			}
   733  			switch v := v.(type) {
   734  			case *metadata.NullLit:
   735  				// nothing to do.
   736  			case *metadata.DIGlobalVariable:
   737  				md.Var = v
   738  			default:
   739  				panic(fmt.Errorf("support for metadata DIGlobalVariableExpression var field type %T not yet implemented", v))
   740  			}
   741  		case *ast.ExprField:
   742  			expr, err := gen.irMDField(oldField.Expr())
   743  			if err != nil {
   744  				return nil, errors.WithStack(err)
   745  			}
   746  			switch expr := expr.(type) {
   747  			case *metadata.NullLit:
   748  				// nothing to do.
   749  			case *metadata.DIExpression:
   750  				md.Expr = expr
   751  			default:
   752  				panic(fmt.Errorf("support for metadata DIGlobalVariableExpression expr field type %T not yet implemented", expr))
   753  			}
   754  		default:
   755  			panic(fmt.Errorf("support for DIGlobalVariableExpression field %T not yet implemented", old))
   756  		}
   757  	}
   758  	return md, nil
   759  }
   760  
   761  // --- [ DIImportedEntity ] ----------------------------------------------------
   762  
   763  // irDIImportedEntity returns the IR specialized metadata node DIImportedEntity
   764  // corresponding to the given AST specialized metadata node DIImportedEntity. A
   765  // new IR specialized metadata node correspoding to the AST specialized metadata
   766  // node is created if new is nil, otherwise the body of new is populated.
   767  func (gen *generator) irDIImportedEntity(new metadata.SpecializedNode, old *ast.DIImportedEntity) (*metadata.DIImportedEntity, error) {
   768  	md, ok := new.(*metadata.DIImportedEntity)
   769  	if new == nil {
   770  		md = &metadata.DIImportedEntity{MetadataID: -1}
   771  	} else if !ok {
   772  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIImportedEntity, got %T", new))
   773  	}
   774  	for _, oldField := range old.Fields() {
   775  		switch oldField := oldField.(type) {
   776  		case *ast.TagField:
   777  			md.Tag = irDwarfTag(oldField.Tag())
   778  		case *ast.ScopeField:
   779  			scope, err := gen.irMDField(oldField.Scope())
   780  			if err != nil {
   781  				return nil, errors.WithStack(err)
   782  			}
   783  			md.Scope = scope
   784  		case *ast.EntityField:
   785  			entity, err := gen.irMDField(oldField.Entity())
   786  			if err != nil {
   787  				return nil, errors.WithStack(err)
   788  			}
   789  			md.Entity = entity
   790  		case *ast.FileField:
   791  			file, err := gen.irMDField(oldField.File())
   792  			if err != nil {
   793  				return nil, errors.WithStack(err)
   794  			}
   795  			switch file := file.(type) {
   796  			case *metadata.NullLit:
   797  				// nothing to do.
   798  			case *metadata.DIFile:
   799  				md.File = file
   800  			default:
   801  				panic(fmt.Errorf("support for metadata DIImportedEntity file field type %T not yet implemented", file))
   802  			}
   803  		case *ast.LineField:
   804  			md.Line = intLit(oldField.Line())
   805  		case *ast.NameField:
   806  			md.Name = stringLit(oldField.Name())
   807  		case *ast.ElementsField:
   808  			elements, err := gen.irMDField(oldField.Elements())
   809  			if err != nil {
   810  				return nil, errors.WithStack(err)
   811  			}
   812  			switch elements := elements.(type) {
   813  			case *metadata.NullLit:
   814  				// nothing to do.
   815  			case *metadata.Tuple:
   816  				md.Elements = elements
   817  			default:
   818  				panic(fmt.Errorf("support for metadata DIImportedEntity elements field type %T not yet implemented", elements))
   819  			}
   820  		default:
   821  			panic(fmt.Errorf("support for DIImportedEntity field %T not yet implemented", old))
   822  		}
   823  	}
   824  	return md, nil
   825  }
   826  
   827  // --- [ DILabel ] -------------------------------------------------------------
   828  
   829  // irDILabel returns the IR specialized metadata node DILabel corresponding to
   830  // the given AST specialized metadata node DILabel. A new IR specialized
   831  // metadata node correspoding to the AST specialized metadata node is created if
   832  // new is nil, otherwise the body of new is populated.
   833  func (gen *generator) irDILabel(new metadata.SpecializedNode, old *ast.DILabel) (*metadata.DILabel, error) {
   834  	md, ok := new.(*metadata.DILabel)
   835  	if new == nil {
   836  		md = &metadata.DILabel{MetadataID: -1}
   837  	} else if !ok {
   838  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DILabel, got %T", new))
   839  	}
   840  	for _, oldField := range old.Fields() {
   841  		switch oldField := oldField.(type) {
   842  		case *ast.ScopeField:
   843  			scope, err := gen.irMDField(oldField.Scope())
   844  			if err != nil {
   845  				return nil, errors.WithStack(err)
   846  			}
   847  			md.Scope = scope
   848  		case *ast.NameField:
   849  			md.Name = stringLit(oldField.Name())
   850  		case *ast.FileField:
   851  			file, err := gen.irMDField(oldField.File())
   852  			if err != nil {
   853  				return nil, errors.WithStack(err)
   854  			}
   855  			switch file := file.(type) {
   856  			case *metadata.NullLit:
   857  				// nothing to do.
   858  			case *metadata.DIFile:
   859  				md.File = file
   860  			default:
   861  				panic(fmt.Errorf("support for metadata DILabel file field type %T not yet implemented", file))
   862  			}
   863  		case *ast.LineField:
   864  			md.Line = intLit(oldField.Line())
   865  		default:
   866  			panic(fmt.Errorf("support for DILabel field %T not yet implemented", old))
   867  		}
   868  	}
   869  	return md, nil
   870  }
   871  
   872  // --- [ DILexicalBlock ] ------------------------------------------------------
   873  
   874  // irDILexicalBlock returns the IR specialized metadata node DILexicalBlock
   875  // corresponding to the given AST specialized metadata node DILexicalBlock. A
   876  // new IR specialized metadata node correspoding to the AST specialized metadata
   877  // node is created if new is nil, otherwise the body of new is populated.
   878  func (gen *generator) irDILexicalBlock(new metadata.SpecializedNode, old *ast.DILexicalBlock) (*metadata.DILexicalBlock, error) {
   879  	md, ok := new.(*metadata.DILexicalBlock)
   880  	if new == nil {
   881  		md = &metadata.DILexicalBlock{MetadataID: -1}
   882  	} else if !ok {
   883  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DILexicalBlock, got %T", new))
   884  	}
   885  	for _, oldField := range old.Fields() {
   886  		switch oldField := oldField.(type) {
   887  		case *ast.ScopeField:
   888  			scope, err := gen.irMDField(oldField.Scope())
   889  			if err != nil {
   890  				return nil, errors.WithStack(err)
   891  			}
   892  			md.Scope = scope
   893  		case *ast.FileField:
   894  			file, err := gen.irMDField(oldField.File())
   895  			if err != nil {
   896  				return nil, errors.WithStack(err)
   897  			}
   898  			switch file := file.(type) {
   899  			case *metadata.NullLit:
   900  				// nothing to do.
   901  			case *metadata.DIFile:
   902  				md.File = file
   903  			default:
   904  				panic(fmt.Errorf("support for metadata DILexicalBlock file field type %T not yet implemented", file))
   905  			}
   906  		case *ast.LineField:
   907  			md.Line = intLit(oldField.Line())
   908  		case *ast.ColumnField:
   909  			md.Column = intLit(oldField.Column())
   910  		default:
   911  			panic(fmt.Errorf("support for DILexicalBlock field %T not yet implemented", old))
   912  		}
   913  	}
   914  	return md, nil
   915  }
   916  
   917  // --- [ DILexicalBlockFile ] --------------------------------------------------
   918  
   919  // irDILexicalBlockFile returns the IR specialized metadata node
   920  // DILexicalBlockFile corresponding to the given AST specialized metadata node
   921  // DILexicalBlockFile. A new IR specialized metadata node correspoding to the
   922  // AST specialized metadata node is created if new is nil, otherwise the body of
   923  // new is populated.
   924  func (gen *generator) irDILexicalBlockFile(new metadata.SpecializedNode, old *ast.DILexicalBlockFile) (*metadata.DILexicalBlockFile, error) {
   925  	md, ok := new.(*metadata.DILexicalBlockFile)
   926  	if new == nil {
   927  		md = &metadata.DILexicalBlockFile{MetadataID: -1}
   928  	} else if !ok {
   929  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DILexicalBlockFile, got %T", new))
   930  	}
   931  	for _, oldField := range old.Fields() {
   932  		switch oldField := oldField.(type) {
   933  		case *ast.ScopeField:
   934  			scope, err := gen.irMDField(oldField.Scope())
   935  			if err != nil {
   936  				return nil, errors.WithStack(err)
   937  			}
   938  			md.Scope = scope
   939  		case *ast.FileField:
   940  			file, err := gen.irMDField(oldField.File())
   941  			if err != nil {
   942  				return nil, errors.WithStack(err)
   943  			}
   944  			switch file := file.(type) {
   945  			case *metadata.NullLit:
   946  				// nothing to do.
   947  			case *metadata.DIFile:
   948  				md.File = file
   949  			default:
   950  				panic(fmt.Errorf("support for metadata DILexicalBlockFile file field type %T not yet implemented", file))
   951  			}
   952  		case *ast.DiscriminatorIntField:
   953  			md.Discriminator = uintLit(oldField.Discriminator())
   954  		default:
   955  			panic(fmt.Errorf("support for DILexicalBlockFile field %T not yet implemented", old))
   956  		}
   957  	}
   958  	return md, nil
   959  }
   960  
   961  // --- [ DILocalVariable ] -----------------------------------------------------
   962  
   963  // irDILocalVariable returns the IR specialized metadata node DILocalVariable
   964  // corresponding to the given AST specialized metadata node DILocalVariable. A
   965  // new IR specialized metadata node correspoding to the AST specialized metadata
   966  // node is created if new is nil, otherwise the body of new is populated.
   967  func (gen *generator) irDILocalVariable(new metadata.SpecializedNode, old *ast.DILocalVariable) (*metadata.DILocalVariable, error) {
   968  	md, ok := new.(*metadata.DILocalVariable)
   969  	if new == nil {
   970  		md = &metadata.DILocalVariable{MetadataID: -1}
   971  	} else if !ok {
   972  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DILocalVariable, got %T", new))
   973  	}
   974  	for _, oldField := range old.Fields() {
   975  		switch oldField := oldField.(type) {
   976  		case *ast.NameField:
   977  			md.Name = stringLit(oldField.Name())
   978  		case *ast.ArgField:
   979  			md.Arg = uintLit(oldField.Arg())
   980  		case *ast.ScopeField:
   981  			scope, err := gen.irMDField(oldField.Scope())
   982  			if err != nil {
   983  				return nil, errors.WithStack(err)
   984  			}
   985  			md.Scope = scope
   986  		case *ast.FileField:
   987  			file, err := gen.irMDField(oldField.File())
   988  			if err != nil {
   989  				return nil, errors.WithStack(err)
   990  			}
   991  			switch file := file.(type) {
   992  			case *metadata.NullLit:
   993  				// nothing to do.
   994  			case *metadata.DIFile:
   995  				md.File = file
   996  			default:
   997  				panic(fmt.Errorf("support for metadata DILocalVariable file field type %T not yet implemented", file))
   998  			}
   999  		case *ast.LineField:
  1000  			md.Line = intLit(oldField.Line())
  1001  		case *ast.TypeField:
  1002  			typ, err := gen.irMDField(oldField.Typ())
  1003  			if err != nil {
  1004  				return nil, errors.WithStack(err)
  1005  			}
  1006  			md.Type = typ
  1007  		case *ast.FlagsField:
  1008  			md.Flags = irDIFlags(oldField.Flags())
  1009  		case *ast.AlignField:
  1010  			md.Align = uintLit(oldField.Align())
  1011  		case *ast.AnnotationsField:
  1012  			annotations, err := gen.irMDField(oldField.Annotations())
  1013  			if err != nil {
  1014  				return nil, errors.WithStack(err)
  1015  			}
  1016  			md.Annotations = annotations
  1017  		default:
  1018  			panic(fmt.Errorf("support for DILocalVariable field %T not yet implemented", old))
  1019  		}
  1020  	}
  1021  	return md, nil
  1022  }
  1023  
  1024  // --- [ DILocation ] ----------------------------------------------------------
  1025  
  1026  // irDILocation returns the IR specialized metadata node DILocation
  1027  // corresponding to the given AST specialized metadata node DILocation. A new IR
  1028  // specialized metadata node correspoding to the AST specialized metadata node
  1029  // is created if new is nil, otherwise the body of new is populated.
  1030  func (gen *generator) irDILocation(new metadata.SpecializedNode, old *ast.DILocation) (*metadata.DILocation, error) {
  1031  	md, ok := new.(*metadata.DILocation)
  1032  	if new == nil {
  1033  		md = &metadata.DILocation{MetadataID: -1}
  1034  	} else if !ok {
  1035  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DILocation, got %T", new))
  1036  	}
  1037  	for _, oldField := range old.Fields() {
  1038  		switch oldField := oldField.(type) {
  1039  		case *ast.LineField:
  1040  			md.Line = intLit(oldField.Line())
  1041  		case *ast.ColumnField:
  1042  			md.Column = intLit(oldField.Column())
  1043  		case *ast.ScopeField:
  1044  			scope, err := gen.irMDField(oldField.Scope())
  1045  			if err != nil {
  1046  				return nil, errors.WithStack(err)
  1047  			}
  1048  			md.Scope = scope
  1049  		case *ast.InlinedAtField:
  1050  			inlinedAt, err := gen.irMDField(oldField.InlinedAt())
  1051  			if err != nil {
  1052  				return nil, errors.WithStack(err)
  1053  			}
  1054  			switch inlinedAt := inlinedAt.(type) {
  1055  			case *metadata.NullLit:
  1056  				// nothing to do.
  1057  			case *metadata.DILocation:
  1058  				md.InlinedAt = inlinedAt
  1059  			default:
  1060  				panic(fmt.Errorf("support for metadata DILocation inlinedAt field type %T not yet implemented", inlinedAt))
  1061  			}
  1062  		case *ast.IsImplicitCodeField:
  1063  			md.IsImplicitCode = boolLit(oldField.IsImplicitCode())
  1064  		default:
  1065  			panic(fmt.Errorf("support for DILocation field %T not yet implemented", old))
  1066  		}
  1067  	}
  1068  	return md, nil
  1069  }
  1070  
  1071  // --- [ DIMacro ] -------------------------------------------------------------
  1072  
  1073  // irDIMacro returns the IR specialized metadata node DIMacro corresponding to
  1074  // the given AST specialized metadata node DIMacro. A new IR specialized
  1075  // metadata node correspoding to the AST specialized metadata node is created if
  1076  // new is nil, otherwise the body of new is populated.
  1077  func (gen *generator) irDIMacro(new metadata.SpecializedNode, old *ast.DIMacro) (*metadata.DIMacro, error) {
  1078  	md, ok := new.(*metadata.DIMacro)
  1079  	if new == nil {
  1080  		md = &metadata.DIMacro{MetadataID: -1}
  1081  	} else if !ok {
  1082  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIMacro, got %T", new))
  1083  	}
  1084  	for _, oldField := range old.Fields() {
  1085  		switch oldField := oldField.(type) {
  1086  		case *ast.TypeMacinfoField:
  1087  			md.Type = irDwarfMacinfo(oldField.Typ())
  1088  		case *ast.LineField:
  1089  			md.Line = intLit(oldField.Line())
  1090  		case *ast.NameField:
  1091  			md.Name = stringLit(oldField.Name())
  1092  		case *ast.ValueStringField:
  1093  			md.Value = stringLit(oldField.Value())
  1094  		default:
  1095  			panic(fmt.Errorf("support for DIMacro field %T not yet implemented", old))
  1096  		}
  1097  	}
  1098  	return md, nil
  1099  }
  1100  
  1101  // --- [ DIMacroFile ] ---------------------------------------------------------
  1102  
  1103  // irDIMacroFile returns the IR specialized metadata node DIMacroFile
  1104  // corresponding to the given AST specialized metadata node DIMacroFile. A new
  1105  // IR specialized metadata node correspoding to the AST specialized metadata
  1106  // node is created if new is nil, otherwise the body of new is populated.
  1107  func (gen *generator) irDIMacroFile(new metadata.SpecializedNode, old *ast.DIMacroFile) (*metadata.DIMacroFile, error) {
  1108  	md, ok := new.(*metadata.DIMacroFile)
  1109  	if new == nil {
  1110  		md = &metadata.DIMacroFile{MetadataID: -1}
  1111  	} else if !ok {
  1112  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIMacroFile, got %T", new))
  1113  	}
  1114  	for _, oldField := range old.Fields() {
  1115  		switch oldField := oldField.(type) {
  1116  		case *ast.TypeMacinfoField:
  1117  			md.Type = irDwarfMacinfo(oldField.Typ())
  1118  		case *ast.LineField:
  1119  			md.Line = intLit(oldField.Line())
  1120  		case *ast.FileField:
  1121  			file, err := gen.irMDField(oldField.File())
  1122  			if err != nil {
  1123  				return nil, errors.WithStack(err)
  1124  			}
  1125  			switch file := file.(type) {
  1126  			case *metadata.NullLit:
  1127  				// nothing to do.
  1128  			case *metadata.DIFile:
  1129  				md.File = file
  1130  			default:
  1131  				panic(fmt.Errorf("support for metadata DIMacroFile file field type %T not yet implemented", file))
  1132  			}
  1133  		case *ast.NodesField:
  1134  			nodes, err := gen.irMDField(oldField.Nodes())
  1135  			if err != nil {
  1136  				return nil, errors.WithStack(err)
  1137  			}
  1138  			switch nodes := nodes.(type) {
  1139  			case *metadata.NullLit:
  1140  				// nothing to do.
  1141  			case *metadata.Tuple:
  1142  				md.Nodes = nodes
  1143  			default:
  1144  				panic(fmt.Errorf("support for metadata DIMacroFile nodes field type %T not yet implemented", nodes))
  1145  			}
  1146  		default:
  1147  			panic(fmt.Errorf("support for DIMacroFile field %T not yet implemented", old))
  1148  		}
  1149  	}
  1150  	return md, nil
  1151  }
  1152  
  1153  // --- [ DIModule ] ------------------------------------------------------------
  1154  
  1155  // irDIModule returns the IR specialized metadata node DIModule corresponding to
  1156  // the given AST specialized metadata node DIModule. A new IR specialized
  1157  // metadata node correspoding to the AST specialized metadata node is created if
  1158  // new is nil, otherwise the body of new is populated.
  1159  func (gen *generator) irDIModule(new metadata.SpecializedNode, old *ast.DIModule) (*metadata.DIModule, error) {
  1160  	md, ok := new.(*metadata.DIModule)
  1161  	if new == nil {
  1162  		md = &metadata.DIModule{MetadataID: -1}
  1163  	} else if !ok {
  1164  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIModule, got %T", new))
  1165  	}
  1166  	for _, oldField := range old.Fields() {
  1167  		switch oldField := oldField.(type) {
  1168  		case *ast.ScopeField:
  1169  			scope, err := gen.irMDField(oldField.Scope())
  1170  			if err != nil {
  1171  				return nil, errors.WithStack(err)
  1172  			}
  1173  			md.Scope = scope
  1174  		case *ast.NameField:
  1175  			md.Name = stringLit(oldField.Name())
  1176  		case *ast.ConfigMacrosField:
  1177  			md.ConfigMacros = stringLit(oldField.ConfigMacros())
  1178  		case *ast.IncludePathField:
  1179  			md.IncludePath = stringLit(oldField.IncludePath())
  1180  		case *ast.APINotesField:
  1181  			md.APINotes = stringLit(oldField.APINotes())
  1182  		case *ast.FileField:
  1183  			file, err := gen.irMDField(oldField.File())
  1184  			if err != nil {
  1185  				return nil, errors.WithStack(err)
  1186  			}
  1187  			md.File = file
  1188  		case *ast.LineField:
  1189  			md.Line = intLit(oldField.Line())
  1190  		case *ast.IsDeclField:
  1191  			md.IsDecl = boolLit(oldField.IsDecl())
  1192  		default:
  1193  			panic(fmt.Errorf("support for DIModule field %T not yet implemented", old))
  1194  		}
  1195  	}
  1196  	return md, nil
  1197  }
  1198  
  1199  // --- [ DINamespace ] ---------------------------------------------------------
  1200  
  1201  // irDINamespace returns the IR specialized metadata node DINamespace
  1202  // corresponding to the given AST specialized metadata node DINamespace. A new
  1203  // IR specialized metadata node correspoding to the AST specialized metadata
  1204  // node is created if new is nil, otherwise the body of new is populated.
  1205  func (gen *generator) irDINamespace(new metadata.SpecializedNode, old *ast.DINamespace) (*metadata.DINamespace, error) {
  1206  	md, ok := new.(*metadata.DINamespace)
  1207  	if new == nil {
  1208  		md = &metadata.DINamespace{MetadataID: -1}
  1209  	} else if !ok {
  1210  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DINamespace, got %T", new))
  1211  	}
  1212  	for _, oldField := range old.Fields() {
  1213  		switch oldField := oldField.(type) {
  1214  		case *ast.ScopeField:
  1215  			scope, err := gen.irMDField(oldField.Scope())
  1216  			if err != nil {
  1217  				return nil, errors.WithStack(err)
  1218  			}
  1219  			md.Scope = scope
  1220  		case *ast.NameField:
  1221  			md.Name = stringLit(oldField.Name())
  1222  		case *ast.ExportSymbolsField:
  1223  			md.ExportSymbols = boolLit(oldField.ExportSymbols())
  1224  		default:
  1225  			panic(fmt.Errorf("support for DINamespace field %T not yet implemented", old))
  1226  		}
  1227  	}
  1228  	return md, nil
  1229  }
  1230  
  1231  // --- [ DIObjCProperty ] ------------------------------------------------------
  1232  
  1233  // irDIObjCProperty returns the IR specialized metadata node DIObjCProperty
  1234  // corresponding to the given AST specialized metadata node DIObjCProperty. A
  1235  // new IR specialized metadata node correspoding to the AST specialized metadata
  1236  // node is created if new is nil, otherwise the body of new is populated.
  1237  func (gen *generator) irDIObjCProperty(new metadata.SpecializedNode, old *ast.DIObjCProperty) (*metadata.DIObjCProperty, error) {
  1238  	md, ok := new.(*metadata.DIObjCProperty)
  1239  	if new == nil {
  1240  		md = &metadata.DIObjCProperty{MetadataID: -1}
  1241  	} else if !ok {
  1242  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIObjCProperty, got %T", new))
  1243  	}
  1244  	for _, oldField := range old.Fields() {
  1245  		switch oldField := oldField.(type) {
  1246  		case *ast.NameField:
  1247  			md.Name = stringLit(oldField.Name())
  1248  		case *ast.FileField:
  1249  			file, err := gen.irMDField(oldField.File())
  1250  			if err != nil {
  1251  				return nil, errors.WithStack(err)
  1252  			}
  1253  			switch file := file.(type) {
  1254  			case *metadata.NullLit:
  1255  				// nothing to do.
  1256  			case *metadata.DIFile:
  1257  				md.File = file
  1258  			default:
  1259  				panic(fmt.Errorf("support for metadata DIObjCProperty file field type %T not yet implemented", file))
  1260  			}
  1261  		case *ast.LineField:
  1262  			md.Line = intLit(oldField.Line())
  1263  		case *ast.SetterField:
  1264  			md.Setter = stringLit(oldField.Setter())
  1265  		case *ast.GetterField:
  1266  			md.Getter = stringLit(oldField.Getter())
  1267  		case *ast.AttributesField:
  1268  			md.Attributes = uintLit(oldField.Attributes())
  1269  		case *ast.TypeField:
  1270  			typ, err := gen.irMDField(oldField.Typ())
  1271  			if err != nil {
  1272  				return nil, errors.WithStack(err)
  1273  			}
  1274  			md.Type = typ
  1275  		default:
  1276  			panic(fmt.Errorf("support for DIObjCProperty field %T not yet implemented", old))
  1277  		}
  1278  	}
  1279  	return md, nil
  1280  }
  1281  
  1282  // --- [ DIStringType ] ---------------------------------------------------------
  1283  
  1284  // irDIStringType returns the IR specialized metadata node DIStringType
  1285  // corresponding to the given AST specialized metadata node DIStringType. A new
  1286  // IR specialized metadata node correspoding to the AST specialized metadata
  1287  // node is created if new is nil, otherwise the body of new is populated.
  1288  func (gen *generator) irDIStringType(new metadata.SpecializedNode, old *ast.DIStringType) (*metadata.DIStringType, error) {
  1289  	md, ok := new.(*metadata.DIStringType)
  1290  	if new == nil {
  1291  		md = &metadata.DIStringType{MetadataID: -1}
  1292  	} else if !ok {
  1293  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DIStringType, got %T", new))
  1294  	}
  1295  	for _, oldField := range old.Fields() {
  1296  		switch oldField := oldField.(type) {
  1297  		case *ast.TagField:
  1298  			md.Tag = irDwarfTag(oldField.Tag())
  1299  		case *ast.NameField:
  1300  			md.Name = stringLit(oldField.Name())
  1301  		case *ast.StringLengthField:
  1302  			stringLength, err := gen.irMDField(oldField.StringLength())
  1303  			if err != nil {
  1304  				return nil, errors.WithStack(err)
  1305  			}
  1306  			md.StringLength = stringLength
  1307  		case *ast.StringLengthExpressionField:
  1308  			stringLengthExpression, err := gen.irMDField(oldField.StringLengthExpression())
  1309  			if err != nil {
  1310  				return nil, errors.WithStack(err)
  1311  			}
  1312  			md.StringLengthExpression = stringLengthExpression
  1313  		case *ast.StringLocationExpressionField:
  1314  			stringLocationExpression, err := gen.irMDField(oldField.StringLocationExpression())
  1315  			if err != nil {
  1316  				return nil, errors.WithStack(err)
  1317  			}
  1318  			md.StringLocationExpression = stringLocationExpression
  1319  		case *ast.SizeField:
  1320  			md.Size = uintLit(oldField.Size())
  1321  		case *ast.AlignField:
  1322  			md.Align = uintLit(oldField.Align())
  1323  		case *ast.EncodingField:
  1324  			md.Encoding = irDwarfAttEncodingOrUint(oldField.Encoding())
  1325  		default:
  1326  			panic(fmt.Errorf("support for DIStringType field %T not yet implemented", old))
  1327  		}
  1328  	}
  1329  	return md, nil
  1330  }
  1331  
  1332  // --- [ DISubprogram ] --------------------------------------------------------
  1333  
  1334  // irDISubprogram returns the IR specialized metadata node DISubprogram
  1335  // corresponding to the given AST specialized metadata node DISubprogram. A new
  1336  // IR specialized metadata node correspoding to the AST specialized metadata
  1337  // node is created if new is nil, otherwise the body of new is populated.
  1338  func (gen *generator) irDISubprogram(new metadata.SpecializedNode, old *ast.DISubprogram) (*metadata.DISubprogram, error) {
  1339  	md, ok := new.(*metadata.DISubprogram)
  1340  	if new == nil {
  1341  		md = &metadata.DISubprogram{MetadataID: -1}
  1342  	} else if !ok {
  1343  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DISubprogram, got %T", new))
  1344  	}
  1345  	for _, oldField := range old.Fields() {
  1346  		switch oldField := oldField.(type) {
  1347  		case *ast.ScopeField:
  1348  			scope, err := gen.irMDField(oldField.Scope())
  1349  			if err != nil {
  1350  				return nil, errors.WithStack(err)
  1351  			}
  1352  			md.Scope = scope
  1353  		case *ast.NameField:
  1354  			md.Name = stringLit(oldField.Name())
  1355  		case *ast.LinkageNameField:
  1356  			md.LinkageName = stringLit(oldField.LinkageName())
  1357  		case *ast.FileField:
  1358  			file, err := gen.irMDField(oldField.File())
  1359  			if err != nil {
  1360  				return nil, errors.WithStack(err)
  1361  			}
  1362  			switch file := file.(type) {
  1363  			case *metadata.NullLit:
  1364  				// nothing to do.
  1365  			case *metadata.DIFile:
  1366  				md.File = file
  1367  			default:
  1368  				panic(fmt.Errorf("support for metadata DISubprogram file field type %T not yet implemented", file))
  1369  			}
  1370  		case *ast.LineField:
  1371  			md.Line = intLit(oldField.Line())
  1372  		case *ast.TypeField:
  1373  			typ, err := gen.irMDField(oldField.Typ())
  1374  			if err != nil {
  1375  				return nil, errors.WithStack(err)
  1376  			}
  1377  			md.Type = typ
  1378  		case *ast.IsLocalField:
  1379  			md.IsLocal = boolLit(oldField.IsLocal())
  1380  		case *ast.IsDefinitionField:
  1381  			md.IsDefinition = boolLit(oldField.IsDefinition())
  1382  		case *ast.ScopeLineField:
  1383  			md.ScopeLine = intLit(oldField.ScopeLine())
  1384  		case *ast.ContainingTypeField:
  1385  			containingType, err := gen.irMDField(oldField.ContainingType())
  1386  			if err != nil {
  1387  				return nil, errors.WithStack(err)
  1388  			}
  1389  			md.ContainingType = containingType
  1390  		case *ast.VirtualityField:
  1391  			md.Virtuality = irDwarfVirtuality(oldField.Virtuality())
  1392  		case *ast.VirtualIndexField:
  1393  			md.VirtualIndex = uintLit(oldField.VirtualIndex())
  1394  		case *ast.ThisAdjustmentField:
  1395  			md.ThisAdjustment = intLit(oldField.ThisAdjustment())
  1396  		case *ast.FlagsField:
  1397  			md.Flags = irDIFlags(oldField.Flags())
  1398  		case *ast.SPFlagsField:
  1399  			md.SPFlags = irDISPFlags(oldField.SPFlags())
  1400  		case *ast.IsOptimizedField:
  1401  			md.IsOptimized = boolLit(oldField.IsOptimized())
  1402  		case *ast.UnitField:
  1403  			unit, err := gen.irMDField(oldField.Unit())
  1404  			if err != nil {
  1405  				return nil, errors.WithStack(err)
  1406  			}
  1407  			switch unit := unit.(type) {
  1408  			case *metadata.NullLit:
  1409  				// nothing to do.
  1410  			case *metadata.DICompileUnit:
  1411  				md.Unit = unit
  1412  			default:
  1413  				panic(fmt.Errorf("support for metadata DISubprogram unit field type %T not yet implemented", unit))
  1414  			}
  1415  		case *ast.TemplateParamsField:
  1416  			templateParams, err := gen.irMDField(oldField.TemplateParams())
  1417  			if err != nil {
  1418  				return nil, errors.WithStack(err)
  1419  			}
  1420  			switch templateParams := templateParams.(type) {
  1421  			case *metadata.NullLit:
  1422  				// nothing to do.
  1423  			case *metadata.Tuple:
  1424  				md.TemplateParams = templateParams
  1425  			default:
  1426  				panic(fmt.Errorf("support for metadata DISubprogram templateParams field type %T not yet implemented", templateParams))
  1427  			}
  1428  		case *ast.DeclarationField:
  1429  			declaration, err := gen.irMDField(oldField.Declaration())
  1430  			if err != nil {
  1431  				return nil, errors.WithStack(err)
  1432  			}
  1433  			md.Declaration = declaration
  1434  		case *ast.RetainedNodesField:
  1435  			retainedNodes, err := gen.irMDField(oldField.RetainedNodes())
  1436  			if err != nil {
  1437  				return nil, errors.WithStack(err)
  1438  			}
  1439  			switch retainedNodes := retainedNodes.(type) {
  1440  			case *metadata.NullLit:
  1441  				// nothing to do.
  1442  			case *metadata.Tuple:
  1443  				md.RetainedNodes = retainedNodes
  1444  			default:
  1445  				panic(fmt.Errorf("support for metadata DISubprogram retainedNodes field type %T not yet implemented", retainedNodes))
  1446  			}
  1447  		case *ast.ThrownTypesField:
  1448  			thrownTypes, err := gen.irMDField(oldField.ThrownTypes())
  1449  			if err != nil {
  1450  				return nil, errors.WithStack(err)
  1451  			}
  1452  			switch thrownTypes := thrownTypes.(type) {
  1453  			case *metadata.NullLit:
  1454  				// nothing to do.
  1455  			case *metadata.Tuple:
  1456  				md.ThrownTypes = thrownTypes
  1457  			default:
  1458  				panic(fmt.Errorf("support for metadata DISubprogram thrownTypes field type %T not yet implemented", thrownTypes))
  1459  			}
  1460  		case *ast.AnnotationsField:
  1461  			annotations, err := gen.irMDField(oldField.Annotations())
  1462  			if err != nil {
  1463  				return nil, errors.WithStack(err)
  1464  			}
  1465  			md.Annotations = annotations
  1466  		default:
  1467  			panic(fmt.Errorf("support for DISubprogram field %T not yet implemented", old))
  1468  		}
  1469  	}
  1470  	return md, nil
  1471  }
  1472  
  1473  // --- [ DISubrange ] ----------------------------------------------------------
  1474  
  1475  // irDISubrange returns the IR specialized metadata node DISubrange
  1476  // corresponding to the given AST specialized metadata node DISubrange. A new IR
  1477  // specialized metadata node correspoding to the AST specialized metadata node
  1478  // is created if new is nil, otherwise the body of new is populated.
  1479  func (gen *generator) irDISubrange(new metadata.SpecializedNode, old *ast.DISubrange) (*metadata.DISubrange, error) {
  1480  	md, ok := new.(*metadata.DISubrange)
  1481  	if new == nil {
  1482  		md = &metadata.DISubrange{MetadataID: -1}
  1483  	} else if !ok {
  1484  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DISubrange, got %T", new))
  1485  	}
  1486  	for _, oldField := range old.Fields() {
  1487  		switch oldField := oldField.(type) {
  1488  		case *ast.CountField:
  1489  			count, err := gen.irMDFieldOrInt(oldField.Count())
  1490  			if err != nil {
  1491  				return nil, errors.WithStack(err)
  1492  			}
  1493  			md.Count = count
  1494  		case *ast.LowerBoundField:
  1495  			lowerBound, err := gen.irMDFieldOrInt(oldField.LowerBound())
  1496  			if err != nil {
  1497  				return nil, errors.WithStack(err)
  1498  			}
  1499  			md.LowerBound = lowerBound
  1500  		case *ast.UpperBoundField:
  1501  			upperBound, err := gen.irMDFieldOrInt(oldField.UpperBound())
  1502  			if err != nil {
  1503  				return nil, errors.WithStack(err)
  1504  			}
  1505  			md.UpperBound = upperBound
  1506  		case *ast.StrideField:
  1507  			stride, err := gen.irMDFieldOrInt(oldField.Stride())
  1508  			if err != nil {
  1509  				return nil, errors.WithStack(err)
  1510  			}
  1511  			md.Stride = stride
  1512  		default:
  1513  			panic(fmt.Errorf("support for DISubrange field %T not yet implemented", old))
  1514  		}
  1515  	}
  1516  	return md, nil
  1517  }
  1518  
  1519  // --- [ DISubroutineType ] ----------------------------------------------------
  1520  
  1521  // irDISubroutineType returns the IR specialized metadata node DISubroutineType
  1522  // corresponding to the given AST specialized metadata node DISubroutineType. A
  1523  // new IR specialized metadata node correspoding to the AST specialized metadata
  1524  // node is created if new is nil, otherwise the body of new is populated.
  1525  func (gen *generator) irDISubroutineType(new metadata.SpecializedNode, old *ast.DISubroutineType) (*metadata.DISubroutineType, error) {
  1526  	md, ok := new.(*metadata.DISubroutineType)
  1527  	if new == nil {
  1528  		md = &metadata.DISubroutineType{MetadataID: -1}
  1529  	} else if !ok {
  1530  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DISubroutineType, got %T", new))
  1531  	}
  1532  	for _, oldField := range old.Fields() {
  1533  		switch oldField := oldField.(type) {
  1534  		case *ast.FlagsField:
  1535  			md.Flags = irDIFlags(oldField.Flags())
  1536  		case *ast.CCField:
  1537  			md.CC = irDwarfCC(oldField.CC())
  1538  		case *ast.TypesField:
  1539  			ts, err := gen.irMDField(oldField.Types())
  1540  			if err != nil {
  1541  				return nil, errors.WithStack(err)
  1542  			}
  1543  			switch ts := ts.(type) {
  1544  			case *metadata.NullLit:
  1545  				// nothing to do.
  1546  			case *metadata.Tuple:
  1547  				md.Types = ts
  1548  			default:
  1549  				panic(fmt.Errorf("support for metadata DISubroutineType types field type %T not yet implemented", ts))
  1550  			}
  1551  		default:
  1552  			panic(fmt.Errorf("support for DISubroutineType field %T not yet implemented", old))
  1553  		}
  1554  	}
  1555  	return md, nil
  1556  }
  1557  
  1558  // --- [ DITemplateTypeParameter ] ---------------------------------------------
  1559  
  1560  // irDITemplateTypeParameter returns the IR specialized metadata node
  1561  // DITemplateTypeParameter corresponding to the given AST specialized metadata
  1562  // node DITemplateTypeParameter. A new IR specialized metadata node correspoding
  1563  // to the AST specialized metadata node is created if new is nil, otherwise the
  1564  // body of new is populated.
  1565  func (gen *generator) irDITemplateTypeParameter(new metadata.SpecializedNode, old *ast.DITemplateTypeParameter) (*metadata.DITemplateTypeParameter, error) {
  1566  	md, ok := new.(*metadata.DITemplateTypeParameter)
  1567  	if new == nil {
  1568  		md = &metadata.DITemplateTypeParameter{MetadataID: -1}
  1569  	} else if !ok {
  1570  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DITemplateTypeParameter, got %T", new))
  1571  	}
  1572  	for _, oldField := range old.Fields() {
  1573  		switch oldField := oldField.(type) {
  1574  		case *ast.NameField:
  1575  			md.Name = stringLit(oldField.Name())
  1576  		case *ast.TypeField:
  1577  			typ, err := gen.irMDField(oldField.Typ())
  1578  			if err != nil {
  1579  				return nil, errors.WithStack(err)
  1580  			}
  1581  			md.Type = typ
  1582  		case *ast.DefaultedField:
  1583  			md.Defaulted = boolLit(oldField.Name())
  1584  		default:
  1585  			panic(fmt.Errorf("support for DITemplateTypeParameter field %T not yet implemented", old))
  1586  		}
  1587  	}
  1588  	return md, nil
  1589  }
  1590  
  1591  // --- [ DITemplateValueParameter ] --------------------------------------------
  1592  
  1593  // irDITemplateValueParameter returns the IR specialized metadata node
  1594  // DITemplateValueParameter corresponding to the given AST specialized metadata
  1595  // node DITemplateValueParameter. A new IR specialized metadata node
  1596  // correspoding to the AST specialized metadata node is created if new is nil,
  1597  // otherwise the body of new is populated.
  1598  func (gen *generator) irDITemplateValueParameter(new metadata.SpecializedNode, old *ast.DITemplateValueParameter) (*metadata.DITemplateValueParameter, error) {
  1599  	md, ok := new.(*metadata.DITemplateValueParameter)
  1600  	if new == nil {
  1601  		md = &metadata.DITemplateValueParameter{MetadataID: -1}
  1602  	} else if !ok {
  1603  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.DITemplateValueParameter, got %T", new))
  1604  	}
  1605  	for _, oldField := range old.Fields() {
  1606  		switch oldField := oldField.(type) {
  1607  		case *ast.TagField:
  1608  			md.Tag = irDwarfTag(oldField.Tag())
  1609  		case *ast.NameField:
  1610  			md.Name = stringLit(oldField.Name())
  1611  		case *ast.DefaultedField:
  1612  			md.Defaulted = boolLit(oldField.Name())
  1613  		case *ast.TypeField:
  1614  			typ, err := gen.irMDField(oldField.Typ())
  1615  			if err != nil {
  1616  				return nil, errors.WithStack(err)
  1617  			}
  1618  			md.Type = typ
  1619  		case *ast.ValueField:
  1620  			value, err := gen.irMDField(oldField.Value())
  1621  			if err != nil {
  1622  				return nil, errors.WithStack(err)
  1623  			}
  1624  			md.Value = value
  1625  		default:
  1626  			panic(fmt.Errorf("support for DITemplateValueParameter field %T not yet implemented", old))
  1627  		}
  1628  	}
  1629  	return md, nil
  1630  }
  1631  
  1632  // --- [ GenericDINode ] -------------------------------------------------------
  1633  
  1634  // irGenericDINode returns the IR specialized metadata node GenericDINode
  1635  // corresponding to the given AST specialized metadata node GenericDINode. A new
  1636  // IR specialized metadata node correspoding to the AST specialized metadata
  1637  // node is created if new is nil, otherwise the body of new is populated.
  1638  func (gen *generator) irGenericDINode(new metadata.SpecializedNode, old *ast.GenericDINode) (*metadata.GenericDINode, error) {
  1639  	md, ok := new.(*metadata.GenericDINode)
  1640  	if new == nil {
  1641  		md = &metadata.GenericDINode{MetadataID: -1}
  1642  	} else if !ok {
  1643  		panic(fmt.Errorf("invalid IR specialized metadata node for AST specialized metadata node; expected *metadata.GenericDINode, got %T", new))
  1644  	}
  1645  	for _, oldField := range old.Fields() {
  1646  		switch oldField := oldField.(type) {
  1647  		case *ast.TagField:
  1648  			md.Tag = irDwarfTag(oldField.Tag())
  1649  		case *ast.HeaderField:
  1650  			md.Header = stringLit(oldField.Header())
  1651  		case *ast.OperandsField:
  1652  			for _, field := range oldField.Operands() {
  1653  				operand, err := gen.irMDField(field)
  1654  				if err != nil {
  1655  					return nil, errors.WithStack(err)
  1656  				}
  1657  				md.Operands = append(md.Operands, operand)
  1658  			}
  1659  		default:
  1660  			panic(fmt.Errorf("support for GenericDINode field %T not yet implemented", old))
  1661  		}
  1662  	}
  1663  	return md, nil
  1664  }
  1665  
  1666  // ### [ Helper functions ] ####################################################
  1667  
  1668  // irMDFieldOrInt returns the IR metadata field or integer corresponding to the
  1669  // given AST metadata field or integer.
  1670  func (gen *generator) irMDFieldOrInt(old ast.MDFieldOrInt) (metadata.FieldOrInt, error) {
  1671  	switch old := old.(type) {
  1672  	case ast.MDField:
  1673  		return gen.irMDField(old)
  1674  	case *ast.IntLit:
  1675  		return metadata.IntLit(intLit(*old)), nil
  1676  	default:
  1677  		panic(fmt.Errorf("support for metadata field %T not yet implemented", old))
  1678  	}
  1679  }
  1680  
  1681  // irDIFlags returns the IR debug info flags corresponding to the given AST
  1682  // debug info flags.
  1683  func irDIFlags(old ast.DIFlags) enum.DIFlag {
  1684  	var flags enum.DIFlag
  1685  	for _, oldFlag := range old.Flags() {
  1686  		flag := irDIFlag(oldFlag)
  1687  		flags |= flag
  1688  	}
  1689  	return flags
  1690  }
  1691  
  1692  // irDIFlag returns the IR debug info flag corresponding to the given AST debug
  1693  // info flag.
  1694  func irDIFlag(old ast.DIFlag) enum.DIFlag {
  1695  	switch old := old.(type) {
  1696  	case *ast.DIFlagEnum:
  1697  		return asmenum.DIFlagFromString(old.Text())
  1698  	case *ast.DIFlagInt:
  1699  		return enum.DIFlag(uintLit(old.UintLit()))
  1700  	default:
  1701  		panic(fmt.Errorf("support for debug info flag %T not yet implemented", old))
  1702  	}
  1703  }
  1704  
  1705  // irDISPFlags returns the IR subprogram specific flags corresponding to the
  1706  // given AST subprogram specific flags.
  1707  func irDISPFlags(old ast.DISPFlags) enum.DISPFlag {
  1708  	var flags enum.DISPFlag
  1709  	for _, oldFlag := range old.Flags() {
  1710  		flag := irDISPFlag(oldFlag)
  1711  		flags |= flag
  1712  	}
  1713  	return flags
  1714  }
  1715  
  1716  // irDISPFlag returns the IR subprogram specific flag corresponding to the given
  1717  // AST subprogram specific flag.
  1718  func irDISPFlag(old ast.DISPFlag) enum.DISPFlag {
  1719  	switch old := old.(type) {
  1720  	case *ast.DISPFlagEnum:
  1721  		return asmenum.DISPFlagFromString(old.Text())
  1722  	case *ast.DISPFlagInt:
  1723  		return enum.DISPFlag(uintLit(old.UintLit()))
  1724  	default:
  1725  		panic(fmt.Errorf("support for subprogram specific flag %T not yet implemented", old))
  1726  	}
  1727  }
  1728  
  1729  // irDwarfAttEncoding returns the IR Dwarf attribute encoding corresponding to
  1730  // the given AST Dwarf attribute encoding.
  1731  func irDwarfAttEncoding(old ast.DwarfAttEncoding) enum.DwarfAttEncoding {
  1732  	switch old := old.(type) {
  1733  	case *ast.DwarfAttEncodingEnum:
  1734  		return asmenum.DwarfAttEncodingFromString(old.Text())
  1735  	default:
  1736  		panic(fmt.Errorf("support for Dwarf attribute encoding %T not yet implemented", old))
  1737  	}
  1738  }
  1739  
  1740  // irDwarfAttEncodingOrUint returns the IR Dwarf attribute encoding
  1741  // corresponding to the given AST Dwarf attribute encoding.
  1742  func irDwarfAttEncodingOrUint(old ast.DwarfAttEncodingOrUint) enum.DwarfAttEncoding {
  1743  	switch old := old.(type) {
  1744  	case ast.DwarfAttEncoding:
  1745  		return irDwarfAttEncoding(old)
  1746  	case *ast.DwarfAttEncodingInt:
  1747  		return enum.DwarfAttEncoding(uintLit(old.UintLit()))
  1748  	default:
  1749  		panic(fmt.Errorf("support for Dwarf attribute encoding %T not yet implemented", old))
  1750  	}
  1751  }
  1752  
  1753  // irDwarfCC returns the IR Dwarf calling convention corresponding to the given
  1754  // AST Dwarf calling convention.
  1755  func irDwarfCC(old ast.DwarfCC) enum.DwarfCC {
  1756  	switch old := old.(type) {
  1757  	case *ast.DwarfCCEnum:
  1758  		return asmenum.DwarfCCFromString(old.Text())
  1759  	case *ast.DwarfCCInt:
  1760  		return enum.DwarfCC(uintLit(old.UintLit()))
  1761  	default:
  1762  		panic(fmt.Errorf("support for Dwarf calling convention %T not yet implemented", old))
  1763  	}
  1764  }
  1765  
  1766  // irDwarfLang returns the IR Dwarf language corresponding to the given AST
  1767  // Dwarf language.
  1768  func irDwarfLang(old ast.DwarfLang) enum.DwarfLang {
  1769  	switch old := old.(type) {
  1770  	case *ast.DwarfLangEnum:
  1771  		return asmenum.DwarfLangFromString(old.Text())
  1772  	case *ast.DwarfLangInt:
  1773  		return enum.DwarfLang(uintLit(old.UintLit()))
  1774  	default:
  1775  		panic(fmt.Errorf("support for Dwarf language %T not yet implemented", old))
  1776  	}
  1777  }
  1778  
  1779  // irDwarfMacinfo returns the IR Dwarf Macinfo corresponding to the given AST
  1780  // Dwarf Macinfo.
  1781  func irDwarfMacinfo(old ast.DwarfMacinfo) enum.DwarfMacinfo {
  1782  	switch old := old.(type) {
  1783  	case *ast.DwarfMacinfoEnum:
  1784  		return asmenum.DwarfMacinfoFromString(old.Text())
  1785  	case *ast.DwarfMacinfoInt:
  1786  		return enum.DwarfMacinfo(uintLit(old.UintLit()))
  1787  	default:
  1788  		panic(fmt.Errorf("support for Dwarf Macinfo %T not yet implemented", old))
  1789  	}
  1790  }
  1791  
  1792  // irDwarfTag returns the IR Dwarf tag corresponding to the given AST Dwarf tag.
  1793  func irDwarfTag(old ast.DwarfTag) enum.DwarfTag {
  1794  	switch old := old.(type) {
  1795  	case *ast.DwarfTagEnum:
  1796  		return asmenum.DwarfTagFromString(old.Text())
  1797  	case *ast.DwarfTagInt:
  1798  		return enum.DwarfTag(uintLit(old.UintLit()))
  1799  	default:
  1800  		panic(fmt.Errorf("support for Dwarf tag %T not yet implemented", old))
  1801  	}
  1802  }
  1803  
  1804  // irDwarfVirtuality returns the IR Dwarf virtuality corresponding to the given
  1805  // AST Dwarf virtuality.
  1806  func irDwarfVirtuality(old ast.DwarfVirtuality) enum.DwarfVirtuality {
  1807  	switch old := old.(type) {
  1808  	case *ast.DwarfVirtualityEnum:
  1809  		return asmenum.DwarfVirtualityFromString(old.Text())
  1810  	case *ast.DwarfVirtualityInt:
  1811  		return enum.DwarfVirtuality(uintLit(old.UintLit()))
  1812  	default:
  1813  		panic(fmt.Errorf("support for Dwarf virtuality %T not yet implemented", old))
  1814  	}
  1815  }
  1816  
  1817  // irEmissionKind returns the IR emission kind corresponding to the given AST
  1818  // emission kind.
  1819  func irEmissionKind(old ast.EmissionKind) enum.EmissionKind {
  1820  	switch old := old.(type) {
  1821  	case *ast.EmissionKindEnum:
  1822  		return asmenum.EmissionKindFromString(old.Text())
  1823  	case *ast.EmissionKindInt:
  1824  		return enum.EmissionKind(uintLit(old.UintLit()))
  1825  	default:
  1826  		panic(fmt.Errorf("support for emission kind %T not yet implemented", old))
  1827  	}
  1828  }
  1829  
  1830  // irNameTableKind returns the IR name table kind corresponding to the given AST
  1831  // name table kind.
  1832  func irNameTableKind(old ast.NameTableKind) enum.NameTableKind {
  1833  	switch old := old.(type) {
  1834  	case *ast.NameTableKindEnum:
  1835  		return asmenum.NameTableKindFromString(old.Text())
  1836  	case *ast.NameTableKindInt:
  1837  		return enum.NameTableKind(uintLit(old.UintLit()))
  1838  	default:
  1839  		panic(fmt.Errorf("support for name table kind %T not yet implemented", old))
  1840  	}
  1841  }