Files
codeql/go/ql/lib/semmle/go/Scopes.qll
Owen Mansel-Chan 710c1ba050 Make getACallee overlay[global]
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 12:35:11 +01:00

900 lines
30 KiB
Plaintext

/**
* Provides classes for working with scopes and declared objects.
*/
overlay[local?]
module;
import go
/**
* A scope.
*/
class Scope extends @scope {
/** Gets the enclosing scope of this scope, if any. */
Scope getOuterScope() { scopenesting(this, result) }
/** Gets a scope nested inside this scope. */
Scope getAnInnerScope() { this = result.getOuterScope() }
/** Looks up the entity with the given name in this scope. */
Entity getEntity(string name) {
result.getName() = name and
result.getScope() = this
}
/** Gets a textual representation of this scope. */
string toString() { result = "scope" }
}
/** Provides helper predicates for working with scopes. */
module Scope {
/** Gets the universe scope. */
UniverseScope universe() { any() }
}
/**
* The universe scope.
*/
class UniverseScope extends @universescope, Scope {
override string toString() { result = "universe scope" }
}
/** A package scope. */
class PackageScope extends @packagescope, Scope {
/** Gets the package whose scope this is. */
Package getPackage() { this = result.getScope() }
override string toString() { result = "package scope" }
}
/** A local scope. */
class LocalScope extends @localscope, Scope, Locatable {
/** Gets the AST node inducing this scope. */
ScopeNode getNode() { this = result.getScope() }
/**
* Gets the function scope in which this scope is nested.
*
* For function scopes, this is the scope itself.
*/
FunctionScope getEnclosingFunctionScope() {
result = this.getOuterScope().(LocalScope).getEnclosingFunctionScope()
}
override string toString() { result = "local scope" }
}
/** A local scope induced by a file. */
class FileScope extends LocalScope {
FileScope() { this.getNode() instanceof File }
}
/** A local scope induced by a function definition. */
class FunctionScope extends LocalScope {
FuncDef f;
FunctionScope() { this.getNode() = f.getTypeExpr() }
/** Gets the function inducing this scope. */
FuncDef getFunction() { result = f }
override FunctionScope getEnclosingFunctionScope() { result = this }
override string toString() { result = "function scope" }
}
/**
* A declared or built-in entity (that is, package, type, constant, variable, function or label)
*/
class Entity extends @object {
/**
* Gets the name of this entity.
*
* Anonymous entities (such as the receiver variables of interface methods) have the empty string as their name.
*/
string getName() { objects(this, _, result) }
/** Gets the package in which this entity is declared, if any. */
Package getPackage() { result.getScope() = this.getScope() }
/**
* Holds if this entity is declared in a package with path `pkg` and has the given `name`.
*
* Note that for methods `pkg` is the package path followed by `.` followed
* by the name of the receiver type, for example `io.Writer`.
*/
pragma[nomagic]
predicate hasQualifiedName(string pkg, string name) {
(
pkg = this.getPackage().getPath()
or
not exists(this.getPackage()) and pkg = ""
) and
name = this.getName()
}
/** Gets the qualified name of this entity, if any. */
string getQualifiedName() {
exists(string pkg, string name | this.hasQualifiedName(pkg, name) |
if pkg = "" then result = name else result = pkg + "." + name
)
}
/**
* Gets the scope in which this entity is declared, if any.
*
* Entities corresponding to fields and methods do not have a scope.
*/
Scope getScope() { objectscopes(this, result) }
/**
* Gets the declaring identifier for this entity, if any.
*
* Note that type switch statements which declare a new variable in the guard
* actually have a new variable (of the right type) implicitly declared at
* the beginning of each case clause, and these do not have a syntactic
* declaration.
*/
Ident getDeclaration() { result.declares(this) }
/** Gets a reference to this entity. */
Name getAReference() { result.getTarget() = this }
/** Gets the type of this entity. */
Type getType() { objecttypes(this, result) }
/** Gets a textual representation of this entity. */
string toString() { result = this.getName() }
/** Gets the location of this entity. */
Location getLocation() {
result = this.getDeclaration().getLocation()
or
result = any(CaseClause cc | this = cc.getImplicitlyDeclaredVariable()).getLocation()
}
/**
* DEPRECATED: Use `getLocation()` instead.
*
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
deprecated predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
or
// otherwise fall back on dummy location
not exists(this.getLocation()) and
filepath = "" and
startline = 0 and
startcolumn = 0 and
endline = 0 and
endcolumn = 0
}
}
/** A declared entity (that is, type, constant, variable or function). */
class DeclaredEntity extends Entity, @declobject {
/** Gets the expression to which this entity is initialized, if any. */
Expr getInit() {
exists(ValueSpec spec, int i |
spec.getNameExpr(i) = this.getDeclaration() and
spec.getInit(i) = result
)
}
}
/** A built-in entity (that is, type, constant or function). */
class BuiltinEntity extends Entity, @builtinobject { }
/** An imported package. */
class PackageEntity extends Entity, @pkgobject { }
/**
* A named type: predeclared types, defined types, type parameters, and type
* aliases.
*/
class TypeEntity extends Entity, @typeobject { }
/** The parent of a type parameter type, either a declared type or a declared function. */
class TypeParamParentEntity extends Entity, @typeparamparentobject { }
/** A named type which has a declaration. */
class DeclaredTypeEntity extends TypeEntity, DeclaredEntity, TypeParamParentEntity, @decltypeobject {
/** Gets the declaration specifier declaring this type. */
TypeSpec getSpec() { result.getNameExpr() = this.getDeclaration() }
}
/** DEPRECATED: Use `DeclaredTypeEntity` instead. */
deprecated class DeclaredType = DeclaredTypeEntity;
/** A built-in type. */
class BuiltinTypeEntity extends TypeEntity, BuiltinEntity, @builtintypeobject { }
/** DEPRECATED: Use `BuiltinTypeEntity` instead. */
deprecated class BuiltinType = BuiltinTypeEntity;
/** A built-in or declared constant, variable, field, method or function. */
class ValueEntity extends Entity, @valueobject {
/** Gets a data-flow node that reads the value of this entity. */
Read getARead() { result.reads(this) }
/** Gets a control-flow node that updates the value of this entity. */
Write getAWrite() { result.writes(this, _) }
}
/** A built-in or declared constant. */
class Constant extends ValueEntity, @constobject { }
/** A declared constant. */
class DeclaredConstant extends Constant, DeclaredEntity, @declconstobject {
/** Gets the declaration specifier declaring this constant. */
ValueSpec getSpec() { result.getANameExpr() = this.getDeclaration() }
}
/** A built-in constant. */
class BuiltinConstant extends Constant, BuiltinEntity, @builtinconstobject { }
/**
* A built-in or declared variable.
*
* Note that Go currently does not have any built-in variables, so this class is effectively
* an alias for `DeclaredVariable`.
*/
class Variable extends ValueEntity, @varobject { }
/** A declared variable. */
class DeclaredVariable extends Variable, DeclaredEntity, @declvarobject {
/** Gets the declaration specifier declaring this variable. */
ValueSpec getSpec() { result.getANameExpr() = this.getDeclaration() }
}
/** A variable declared in a local scope (as opposed to a package scope or the universal scope). */
class LocalVariable extends DeclaredVariable {
LocalVariable() { this.getScope() instanceof LocalScope }
/** Gets the innermost function containing the scope of this variable, if any. */
FuncDef getDeclaringFunction() {
result = this.getScope().(LocalScope).getEnclosingFunctionScope().getFunction()
}
/** Holds if this variable is referenced inside a nested function. */
predicate isCaptured() {
this.getDeclaringFunction() != this.getAReference().getEnclosingFunction()
}
}
/**
* A (named) function parameter.
*
* Note that receiver variables are considered parameters.
*/
class Parameter extends DeclaredVariable {
FuncDef f;
int index;
Parameter() {
f.(MethodDecl).getReceiverDecl().getNameExpr() = this.getDeclaration() and
index = -1
or
exists(FuncTypeExpr tp | tp = f.getTypeExpr() |
this =
rank[index + 1](DeclaredVariable parm, int j, int k |
parm.getDeclaration() = tp.getParameterDecl(j).getNameExpr(k)
|
parm order by j, k
)
)
}
/** Gets the function to which this parameter belongs. */
FuncDef getFunction() { result = f }
/**
* Gets the index of this parameter among all parameters of the function.
*
* The receiver is considered to have index -1.
*/
int getIndex() { result = index }
/** Holds if this is the `i`th parameter of function `fd`. */
predicate isParameterOf(FuncDef fd, int i) { fd = f and i = index }
}
/** The receiver variable of a method. */
class ReceiverVariable extends Parameter {
override MethodDecl f;
ReceiverVariable() { index = -1 }
/** Holds if this is the receiver variable of method `m`. */
predicate isReceiverOf(MethodDecl m) { m = f }
}
/** A (named) function result variable. */
class ResultVariable extends DeclaredVariable {
FuncDef f;
int index;
ResultVariable() {
exists(FuncTypeExpr tp | tp = f.getTypeExpr() |
this =
rank[index + 1](DeclaredVariable parm, int j, int k |
parm.getDeclaration() = tp.getResultDecl(j).getNameExpr(k)
|
parm order by j, k
)
)
}
/** Gets the function to which this result variable belongs. */
FuncDef getFunction() { result = f }
/** Gets the index of this result among all results of the function. */
int getIndex() { result = index }
/** Holds if this is the `i`th result of function `fd`. */
predicate isResultOf(FuncDef fd, int i) { fd = f and i = index }
}
/**
* A struct field.
*
* Note that field identity is determined by type identity: if two struct types are identical in
* the sense of the Go language specification (https://golang.org/ref/spec#Type_identity), then
* any of their fields that have the same name are also identical. This, in turn, means that a
* field can have two or more declarations.
*
* For example, consider the following two type declarations:
*
* ```go
* type T1 struct { x int }
* type T2 struct { x int }
* ```
*
* Types `T1` and `T2` are different, but their underlying struct types are identical. Hence
* the two declarations of `x` refer to the same field.
*/
class Field extends Variable {
StructType declaringType;
Field() { fieldstructs(this, declaringType) }
/** Gets the struct type declaring this field. */
StructType getDeclaringType() { result = declaringType }
override Package getPackage() {
exists(Type tp | tp.getUnderlyingType() = declaringType | result = tp.getPackage())
}
/**
* Holds if this field has name `f` and it belongs to a type with qualified name `tp`.
*
* Note that due to field embedding the same field may have multiple qualified names.
*/
override predicate hasQualifiedName(string tp, string f) {
exists(Type base |
tp = base.getQualifiedName() and
this = base.getField(f)
)
}
/**
* Holds if this field has name `f` and it belongs to a type `tp` declared in package `pkg`.
*
* Note that due to field embedding the same field may belong to multiple types.
*/
predicate hasQualifiedName(string pkg, string tp, string f) {
exists(Type base |
base.hasQualifiedName(pkg, tp) and
this = base.getField(f)
)
}
/**
* Gets the tag associated with this field, or the empty string if this field has no tag.
*/
string getTag() { declaringType.hasOwnFieldWithTag(_, this.getName(), this.getType(), _, result) }
}
/**
* A field that belongs to a struct that may be embedded within another struct.
*
* When a selector addresses such a field, it is possible it is implicitly addressing a nested struct.
*/
class PromotedField extends Field {
PromotedField() { this = any(StructType t).getFieldOfEmbedded(_, _, _, _) }
}
/** A built-in or declared function. */
class Function extends ValueEntity, @functionobject {
/**
* Gets a call to this function.
*
* This includes calls that target this function indirectly, by calling an
* interface method that this function implements.
*/
overlay[global]
pragma[nomagic]
DataFlow::CallNode getACall() { this = result.getACalleeIncludingExternals().asFunction() }
/** Gets the declaration of this function, if any. */
FuncDecl getFuncDecl() { none() }
/** Holds if this function is variadic. */
predicate isVariadic() { none() }
/** Holds if this function has no observable side effects. */
predicate mayHaveSideEffects() { none() }
/**
* Holds if this function may return without panicking, exiting the process, or looping forever.
*
* This predicate is an over-approximation: it may hold for functions that can never
* return normally, but it never fails to hold for functions that can.
*
* Note this is declared here and not in `DeclaredFunction` so that library models can override this
* by extending `Function` rather than having to remember to extend `DeclaredFunction`.
*/
predicate mayReturnNormally() {
not this.mustPanic() and
(ControlFlow::mayReturnNormally(this.getFuncDecl()) or not exists(this.getBody()))
}
/**
* Holds if calling this function may cause a runtime panic.
*
* This predicate is an over-approximation: it may hold for functions that can never
* cause a runtime panic, but it never fails to hold for functions that can.
*/
predicate mayPanic() { any() }
/**
* Holds if calling this function always causes a runtime panic.
*
* This predicate is an over-approximation: it may not hold for functions that do
* cause a runtime panic, but it never holds for functions that do not.
*/
predicate mustPanic() { none() }
/** Gets the number of parameters of this function. */
int getNumParameter() { result = this.getType().(SignatureType).getNumParameter() }
/** Gets the type of the `i`th parameter of this function. */
Type getParameterType(int i) { result = this.getType().(SignatureType).getParameterType(i) }
/** Gets the number of results of this function. */
int getNumResult() { result = this.getType().(SignatureType).getNumResult() }
/** Gets the type of the `i`th result of this function. */
Type getResultType(int i) { result = this.getType().(SignatureType).getResultType(i) }
/** Gets the body of this function, if any. */
BlockStmt getBody() { result = this.getFuncDecl().getBody() }
/** Gets the `i`th parameter of this function. */
Parameter getParameter(int i) { result.isParameterOf(this.getFuncDecl(), i) }
/** Gets a parameter of this function. */
Parameter getAParameter() { result = this.getParameter(_) }
/** Gets the `i`th result variable of this function. */
ResultVariable getResult(int i) { result.isResultOf(this.getFuncDecl(), i) }
/** Gets a result variable of this function. */
ResultVariable getAResult() { result = this.getResult(_) }
}
bindingset[m]
pragma[inline_late]
private Type implementsIncludingInterfaceMethodsCand(Method m, string mname) {
result.implements(m.getReceiverType().getUnderlyingType()) and
mname = m.getName()
}
/**
* A method, that is, a function with a receiver variable, or a function declared in an interface.
*
* Note that method identity is determined by receiver type identity: if two methods have the same
* name and their receiver types are identical in the sense of the Go language specification
* (https://golang.org/ref/spec#Type_identity), then the two methods are identical as well.
*/
class Method extends Function {
Variable receiver;
Method() { methodreceivers(this, receiver) }
override Package getPackage() {
// a method doesn't have a scope, so manually associate it with its receiver's
// package.
result = this.getReceiverType().getPackage()
}
/** Holds if this method is declared in an interface. */
predicate isInterfaceMethod() {
this.getReceiverType().getUnderlyingType() instanceof InterfaceType
}
/** Gets the receiver variable of this method. */
Variable getReceiver() { result = receiver }
/** Gets the type of the receiver variable of this method. */
Type getReceiverType() { result = receiver.getType() }
/**
* Gets the receiver base type of this method, that is, either the base type of the receiver type
* if it is a pointer type, or the receiver type itself if it is not a pointer type.
*/
Type getReceiverBaseType() { result = lookThroughPointerType(this.getReceiverType()) }
/** Holds if this method has name `m` and belongs to the method set of type `tp` or `*tp`. */
private predicate isIn(DefinedType tp, string m) {
this = tp.getMethod(m) or
this = tp.getPointerType().getMethod(m)
}
/**
* Holds if this method has name `m` and belongs to the method set of a type `T` or `*T` where
* `T` has qualified name `tp`.
*
* Note that `meth.hasQualifiedName(tp, m)` is almost, but not quite, equivalent to
* `exists(Type t | tp = t.getQualifiedName() and meth = t.getMethod(m))`: the latter
* distinguishes between the method sets of `T` and `*T`, while the former does not.
*/
override predicate hasQualifiedName(string tp, string m) {
exists(DefinedType t |
this.isIn(t, m) and
tp = t.getQualifiedName()
)
}
/**
* Holds if this method has name `m` and belongs to the method set of a type `T` or `*T` where
* `T` is declared in package `pkg` and has name `tp`.
*
* Note that `meth.hasQualifiedName(pkg, tp, m)` is almost, but not quite, equivalent to
* `exists(Type t | t.hasQualifiedName(pkg, tp) and meth = t.getMethod(m))`: the latter
* distinguishes between the method sets of `T` and `*T`, while the former does not.
*/
pragma[nomagic]
predicate hasQualifiedName(string pkg, string tp, string m) {
exists(DefinedType t |
this.isIn(t, m) and
t.hasQualifiedName(pkg, tp)
)
}
/**
* Holds if this method implements the method `m`, that is, if `m` is a method
* on an interface, and this is a method with the same name on a type that
* implements that interface.
*
* Note that all methods implement themselves, and interface methods _only_
* implement themselves.
*/
predicate implements(Method m) {
if this.isInterfaceMethod() then this = m else this.implementsIncludingInterfaceMethods(m)
}
/**
* Holds if this method implements the method `m`, that is, if `m` is a method
* on an interface, and this is a method with the same name on a type that
* implements that interface.
*
* Note that all methods implement themselves, and that unlike the predicate `implements`
* this does allow interface methods to implement other interfaces.
*/
predicate implementsIncludingInterfaceMethods(Method m) {
this = m
or
exists(Type t, string mname |
t = implementsIncludingInterfaceMethodsCand(m, mname) and
this = t.getMethod(mname)
)
}
/**
* Holds if this method implements the method that has qualified name `pkg.tp.name`, that is, if
* `pkg.tp.name` is a method on an interface, and this is a method with the same name on a type
* that implements that interface.
*/
predicate implements(string pkg, string tp, string name) {
exists(Method m | m.hasQualifiedName(pkg, tp, name) | this.implements(m))
}
}
/**
* A method whose receiver may be embedded within a struct.
*
* When a selector addresses such a method, it is possible it is implicitly addressing a nested struct.
*/
class PromotedMethod extends Method {
PromotedMethod() { this = any(StructType t).getMethodOfEmbedded(_, _, _) }
}
/** A declared function. */
class DeclaredFunction extends Function, DeclaredEntity, TypeParamParentEntity, @declfunctionobject {
override FuncDecl getFuncDecl() { result.getNameExpr() = this.getDeclaration() }
override predicate mayHaveSideEffects() {
not exists(this.getBody())
or
exists(BlockStmt body | body = this.getBody() |
body.mayHaveSideEffects()
or
// functions declared in files with build constraints may be defined differently
// for different platforms, so allow them to avoid false positives
body.getFile().hasBuildConstraints()
)
}
override predicate isVariadic() { this.getType().(SignatureType).isVariadic() }
}
/** A built-in function. */
class BuiltinFunction extends Function, BuiltinEntity, @builtinfunctionobject {
override predicate mayHaveSideEffects() { builtinFunction(this.getName(), false, _, _, _) }
override predicate mayPanic() { builtinFunction(this.getName(), _, true, _, _) }
override predicate mustPanic() { builtinFunction(this.getName(), _, _, true, _) }
override predicate isVariadic() { builtinFunction(this.getName(), _, _, _, true) }
/**
* Holds if this function is pure, that is, it has no observable side effects and
* no non-determinism.
*/
predicate isPure() { not this.mayHaveSideEffects() }
}
private newtype TCallable =
TFunctionCallable(Function f) or
TFuncLitCallable(FuncLit l)
/**
* A `Function` or a `FuncLit`. We do it this way because of limitations of both
* `Function` and `FuncDef`:
* - `Function` is an entity, and therefore does not include function literals, and
* - `FuncDef` is an AST node, and so is not extracted for functions from external libraries.
*/
class Callable extends TCallable {
/** Gets a textual representation of this callable. */
string toString() { result = [this.asFunction().toString(), this.asFuncLit().toString()] }
/** Gets this callable as a function, if it is one. */
Function asFunction() { this = TFunctionCallable(result) }
/** Gets this callable as a function literal, if it is one. */
FuncLit asFuncLit() { this = TFuncLitCallable(result) }
/** Gets this function's definition, if it exists. */
FuncDef getFuncDef() { result = [this.asFuncLit().(FuncDef), this.asFunction().getFuncDecl()] }
/** Gets the type of this callable. */
SignatureType getType() {
result = this.asFunction().getType() or
result = this.asFuncLit().getType()
}
/** Gets the name of this callable. */
string getName() {
result = this.asFunction().getName() or
result = this.asFuncLit().getName()
}
/** Gets the location of this callable. */
Location getLocation() {
result = this.asFunction().getLocation() or result = this.asFuncLit().getLocation()
}
/**
* DEPRECATED: Use `getLocation()` instead.
*
* Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `fp`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
deprecated predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) {
this.getLocation().hasLocationInfo(fp, sl, sc, el, ec)
}
}
/** A statement label. */
class Label extends Entity, @labelobject { }
/**
* Holds if `name` is a built-in function, where
*
* - `pure` is true if the function has no observable side effects, and false otherwise;
* - `mayPanic` is true if calling this function may cause a panic, and false otherwise;
* - `mustPanic` is true if calling this function always causes a panic, and false otherwise;
* - `variadic` is true if this function is variadic, and false otherwise.
*
* Allocating memory is not considered an observable side effect.
*/
private predicate builtinFunction(
string name, boolean pure, boolean mayPanic, boolean mustPanic, boolean variadic
) {
name = "append" and pure = false and mayPanic = false and mustPanic = false and variadic = true
or
name = "cap" and pure = true and mayPanic = false and mustPanic = false and variadic = false
or
name = "clear" and pure = false and mayPanic = false and mustPanic = false and variadic = false
or
name = "close" and pure = false and mayPanic = true and mustPanic = false and variadic = false
or
name = "complex" and pure = true and mayPanic = true and mustPanic = false and variadic = false
or
name = "copy" and pure = false and mayPanic = true and mustPanic = false and variadic = false
or
name = "delete" and pure = false and mayPanic = false and mustPanic = false and variadic = false
or
name = "imag" and pure = true and mayPanic = false and mustPanic = false and variadic = false
or
name = "len" and pure = true and mayPanic = false and mustPanic = false and variadic = false
or
name = "make" and pure = true and mayPanic = true and mustPanic = false and variadic = true
or
name = "max" and pure = true and mayPanic = false and mustPanic = false and variadic = true
or
name = "min" and pure = true and mayPanic = false and mustPanic = false and variadic = true
or
name = "new" and pure = true and mayPanic = false and mustPanic = false and variadic = false
or
name = "panic" and pure = false and mayPanic = true and mustPanic = true and variadic = false
or
name = "print" and pure = false and mayPanic = false and mustPanic = false and variadic = true
or
name = "println" and pure = false and mayPanic = false and mustPanic = false and variadic = true
or
name = "real" and pure = true and mayPanic = false and mustPanic = false and variadic = false
or
name = "recover" and pure = false and mayPanic = false and mustPanic = false and variadic = false
}
/** Provides helper predicates for working with built-in objects from the universe scope. */
module Builtin {
// built-in types
/** Gets the built-in type `bool`. */
BuiltinTypeEntity bool() { result.getName() = "bool" }
/** Gets the built-in type `byte`. */
BuiltinTypeEntity byte() { result.getName() = "byte" }
/** Gets the built-in type `complex64`. */
BuiltinTypeEntity complex64() { result.getName() = "complex64" }
/** Gets the built-in type `complex128`. */
BuiltinTypeEntity complex128() { result.getName() = "complex128" }
/** Gets the built-in type `error`. */
BuiltinTypeEntity error() { result.getName() = "error" }
/** Gets the built-in type `float32`. */
BuiltinTypeEntity float32() { result.getName() = "float32" }
/** Gets the built-in type `float64`. */
BuiltinTypeEntity float64() { result.getName() = "float64" }
/** Gets the built-in type `int`. */
BuiltinTypeEntity int_() { result.getName() = "int" }
/** Gets the built-in type `int8`. */
BuiltinTypeEntity int8() { result.getName() = "int8" }
/** Gets the built-in type `int16`. */
BuiltinTypeEntity int16() { result.getName() = "int16" }
/** Gets the built-in type `int32`. */
BuiltinTypeEntity int32() { result.getName() = "int32" }
/** Gets the built-in type `int64`. */
BuiltinTypeEntity int64() { result.getName() = "int64" }
/** Gets the built-in type `rune`. */
BuiltinTypeEntity rune() { result.getName() = "rune" }
/** Gets the built-in type `string`. */
BuiltinTypeEntity string_() { result.getName() = "string" }
/** Gets the built-in type `uint`. */
BuiltinTypeEntity uint() { result.getName() = "uint" }
/** Gets the built-in type `uint8`. */
BuiltinTypeEntity uint8() { result.getName() = "uint8" }
/** Gets the built-in type `uint16`. */
BuiltinTypeEntity uint16() { result.getName() = "uint16" }
/** Gets the built-in type `uint32`. */
BuiltinTypeEntity uint32() { result.getName() = "uint32" }
/** Gets the built-in type `uint64`. */
BuiltinTypeEntity uint64() { result.getName() = "uint64" }
/** Gets the built-in type `uintptr`. */
BuiltinTypeEntity uintptr() { result.getName() = "uintptr" }
// built-in constants
/** Gets the built-in constant `true`. */
BuiltinConstant true_() { result.getName() = "true" }
/** Gets the built-in constant `false`. */
BuiltinConstant false_() { result.getName() = "false" }
/** Gets the built-in constant corresponding to `b`. */
BuiltinConstant bool(boolean b) {
b = true and result = true_()
or
b = false and result = false_()
}
/** Gets the built-in constant `iota`. */
BuiltinConstant iota() { result.getName() = "iota" }
// built-in zero value
/** Gets the built-in zero-value `nil`. */
BuiltinConstant nil() { result.getName() = "nil" }
/** Gets the built-in function `append`. */
BuiltinFunction append() { result.getName() = "append" }
/** Gets the built-in function `cap`. */
BuiltinFunction cap() { result.getName() = "cap" }
/** Gets the built-in function `clear`. */
BuiltinFunction clear() { result.getName() = "clear" }
/** Gets the built-in function `close`. */
BuiltinFunction close() { result.getName() = "close" }
/** Gets the built-in function `complex`. */
BuiltinFunction complex() { result.getName() = "complex" }
/** Gets the built-in function `copy`. */
BuiltinFunction copy() { result.getName() = "copy" }
/** Gets the built-in function `delete`. */
BuiltinFunction delete() { result.getName() = "delete" }
/** Gets the built-in function `imag`. */
BuiltinFunction imag() { result.getName() = "imag" }
/** Gets the built-in function `len`. */
BuiltinFunction len() { result.getName() = "len" }
/** Gets the built-in function `make`. */
BuiltinFunction make() { result.getName() = "make" }
/** Gets the built-in function `max`. */
BuiltinFunction max_() { result.getName() = "max" }
/** Gets the built-in function `min`. */
BuiltinFunction min_() { result.getName() = "min" }
/** Gets the built-in function `new`. */
BuiltinFunction new() { result.getName() = "new" }
/** Gets the built-in function `panic`. */
BuiltinFunction panic() { result.getName() = "panic" }
/** Gets the built-in function `print`. */
BuiltinFunction print() { result.getName() = "print" }
/** Gets the built-in function `println`. */
BuiltinFunction println() { result.getName() = "println" }
/** Gets the built-in function `real`. */
BuiltinFunction real() { result.getName() = "real" }
/** Gets the built-in function `recover`. */
BuiltinFunction recover() { result.getName() = "recover" }
}