glean-0.1.0.0: glean/schema/source/codemarkup.pp.angle
# Copyright (c) Meta Platforms, Inc. and affiliates.
schema codemarkup.pp.3 {
import src
import code.pp
import codemarkup.types
import cxx1
import pp1
#
# Finding entities' locations
#
predicate PPEntityLocation:
{
entity: code.pp.Entity,
location: codemarkup.types.Location,
}
{ Entity, Location } where
# the pp Entity might be a #define, find by name
( { define = Define } = Entity;
{ pp1.Macro Name, Range } = Define;
{ file = File } = Range;
{ Name, File, { range = Range }, nothing } = Location) |
# or it could be a #include, but, subtly, only if mentioned in pp.Include
( { include_ = File } = Entity;
!(!pp1.Include { file = File }); # perf-sensitive existence check
src.File Name = File;
{ Name, File, { span = {0,0} }, nothing } = Location;
);
predicate PpResolveLocation:
{
location: codemarkup.types.Location,
entity: code.pp.Entity,
}
{ { Str, File, Range, Destination }, Entity } where
Trace = cxx1.Trace { file = File };
PpResolveTraceLocation { Trace, { Str, File, Range, Destination }, Entity };
# Keyed by trace, find all locations and entities tied to that (file) trace
# just #defines definitions at the moment
predicate PpResolveTraceLocation:
{
trace : cxx1.Trace,
location: codemarkup.types.Location,
entity: code.pp.Entity,
}
{ Trace, Location, Entity } where
Trace = cxx1.Trace { File, _, { events = PPDecls } };
## preprocessor #defines
{ define = Define } = PPDecls[..];
cxx1.PPDefineLocation { Define, Str, _, Range };
Location = codemarkup.types.Location { Str, File, { range = Range }, nothing };
{ define = Define } = Entity;
# C preprocessor uses of #defines as xrefs
# (deprecated)
predicate PpFileEntityXRefLocations:
{
file: src.File,
xref: codemarkup.types.XRefLocation,
entity: code.pp.Entity,
}
{ File, XRef, Entity } where
Trace = cxx1.Trace { file = File };
PpEntityTraceXRefLocations { Trace, XRef, Entity }
# C preprocessor uses of #defines and #includes.
# N.B. uses are keyed by traces, not xmaps, for PP
predicate PpEntityTraceXRefLocations:
{
trace: cxx1.Trace,
xref: codemarkup.types.XRefLocation,
entity: code.pp.Entity,
}
{ Trace, XRef, Entity } where
{ file = File } = Trace;
cxx1.FilePPTraceXRefs { File, Trace, SrcRange, Entity, SrcSpan };
PPEntityLocation { Entity, Location };
( { Location, { span = SrcSpan } } = XRef;
{ define = _ } = Entity ) |
( { Location, { range = SrcRange } } = XRef;
{ include_ = _ } = Entity ) |
( { Location, { range = SrcRange } } = XRef;
{ undef = _ } = Entity; )
#
# Language-specific symbol info
#
predicate PpEntityKind:
{
entity: code.pp.Entity,
kind: codemarkup.types.SymbolKind,
}
{ Decl, Kind } where
({ define = _ } = Decl; Macro = Kind ) |
({ undef = _ } = Decl; Macro = Kind ) |
({ include_ = _ } = Decl; File = Kind )
# For backward compatibility:
predicate PpEntityInfo:
{
entity: code.pp.Entity,
info: codemarkup.types.SymbolInfo,
}
{ E, { kind = K, isAbstract = false } } where
PpEntityKind { E, K }
#
# Use a cxx1.Trace to resolve #include xref target files efficiently
# We use this as a global cache of #includes to their target for clangd
#
predicate PpIncludeXRefLocations:
{
trace : cxx1.PPTrace, # source file traces to consider
range : src.Range, # at this source line/col span
target : src.File, # has a #include to this file
}
{ Trace, Range, Target } where
{ events = Events } = Trace;
{ include_ = { include_ = Include } } = Events[..];
{ file = Target, source = Range } = Include;
#
# Uses
#
predicate PpEntityUses:
{
entity: code.pp.Entity,
file: src.File,
span: src.ByteSpan
}
{ Entity, File, Span } where
{ define = D } = Entity;
pp1.DefineUse { D, Use };
{ source = { file = File }, nameSpan = Span } = Use;
}