# 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; }