21#include <llvm/Support/LogicalResult.h>
25#define GEN_PASS_DEF_INLINEINCLUDESPASS
33using IncludeStack = std::vector<std::pair<StringRef, Location>>;
35inline bool contains(IncludeStack &stack, StringRef &&loc) {
36 auto path_match = [loc](std::pair<StringRef, Location> &p) {
return p.first == loc; };
37 return std::find_if(stack.begin(), stack.end(), path_match) != stack.end();
41 void runOnOperation()
override {
42 std::vector<std::pair<ModuleOp, IncludeStack>> currLevel = {
43 std::make_pair(getOperation(), IncludeStack())
46 std::vector<std::pair<ModuleOp, IncludeStack>> nextLevel = {};
47 for (std::pair<ModuleOp, IncludeStack> &curr : currLevel) {
48 curr.first.walk([includeStack = std::move(curr.second),
51 if (contains(includeStack, incOp.getPath())) {
52 auto err = incOp.emitError().append(
"found cyclic include");
53 for (auto it = includeStack.rbegin(); it != includeStack.rend(); ++it) {
54 err.attachNote(it->second).append(
"included from here");
58 includeStack.push_back(std::make_pair(incOp.getPath(), incOp.getLoc()));
59 FailureOr<ModuleOp> result = incOp.inlineAndErase();
60 if (succeeded(result)) {
61 ModuleOp newMod = std::move(result.value());
62 assert(succeeded(newMod.verify()) &&
"newMod must pass verification");
63 nextLevel.push_back(make_pair(newMod, includeStack));
67 return WalkResult::advance();
70 currLevel = nextLevel;
71 }
while (!currLevel.empty());
73 if (failed(getOperation().verify())) {
77 markAllAnalysesPreserved();