# Copyright (c) Meta Platforms, Inc. and affiliates. schema pp1.1 { import src # Preprocessor #include occurences. Each occurence of a #include # Note that there may be many such facts for a given src.File predicate Include : { file : src.File, # file being included source : src.Range, # where #include statement occurs pathSpan : src.ByteSpan # span of the file path in the source } # Preprocessor macro predicate Macro : string # Preprocessor #define predicate Define : { macro : Macro, source : src.Range, } # For case insensitive, kind search. Derive lower name to decl directly predicate DefineLowerCase: { name_lowercase: string, decl: Define, } stored { prim.toLower NameStr, Define} where Define = Define { macro = Macro NameStr } # Preprocessor #undef predicate Undef : { macro : Macro, source : src.Range, } # Preprocessor macro use predicate Use : { macro : Macro, definition : maybe src.Loc, # xref to the macro definition expand : bool, # expansion or defined check? source : src.Range, # entire term including args nameSpan : src.ByteSpan # macro name at use site } # for historical reasons pp1.Define and pp1.Use/Undefs are keyed by macro # rather than a more unique pp1.Define or similar fact. All similar named # macros collide. We can disambiguate uses by definition (though this means # no nested macro uses will be found) predicate DefineUse: { define: pp1.Define, use: pp1.Use } { Def, Use } where { macro = M, source = { file = F } } = Def; Use = pp1.Use { macro = M, definition = { just = { file = F } } } }