packages feed

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;


}