Пример #1
0
void LSLocation::getFirstLevelLSLocations(LSLocationList &Locs,
                                          SILModule *Mod) {
  SILType Ty = getType();
  llvm::SmallVector<Projection, 8> Out;
  Projection::getFirstLevelAddrProjections(Ty, *Mod, Out);
  for (auto &X : Out) {
    ProjectionPath P;
    P.append(X);
    P.append(Path.getValue());
    Locs.push_back(LSLocation(Base, P));
  }
}
Пример #2
0
MemLocation MemLocation::createMemLocation(SILValue Base, ProjectionPath &P1,
                                           ProjectionPath &P2) {
  ProjectionPath T;
  T.append(P1);
  T.append(P2);
  return MemLocation(Base, T);
}
Пример #3
0
void
ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
        ProjectionPathList &Paths,
        bool OnlyLeafNode) {
    // Perform a BFS to expand the given type into projectionpath each of
    // which contains 1 field from the type.
    ProjectionPathList Worklist;
    llvm::SmallVector<Projection, 8> Projections;

    // Push an empty projection path to get started.
    SILType Ty;
    ProjectionPath P;
    Worklist.push_back(std::move(P));
    do {
        // Get the next level projections based on current projection's type.
        Optional<ProjectionPath> PP = Worklist.pop_back_val();
        // Get the current type to process, the very first projection path will be
        // empty.
        Ty = PP.getValue().empty() ? B : PP.getValue().front().getType();

        // Get the first level projection of the current type.
        Projections.clear();
        Projection::getFirstLevelAddrProjections(Ty, *Mod, Projections);

        // Reached the end of the projection tree, this field can not be expanded
        // anymore.
        if (Projections.empty()) {
            Paths.push_back(std::move(PP.getValue()));
            continue;
        }

        // If this is a class type, we also have reached the end of the type
        // tree for this type.
        //
        // We do not push its next level projection into the worklist,
        // if we do that, we could run into an infinite loop, e.g.
        //
        //   class SelfLoop {
        //     var p : SelfLoop
        //   }
        //
        //   struct XYZ {
        //     var x : Int
        //     var y : SelfLoop
        //   }
        //
        // The worklist would never be empty in this case !.
        //
        if (Ty.getClassOrBoundGenericClass()) {
            Paths.push_back(std::move(PP.getValue()));
            continue;
        }

        // This is NOT a leaf node, keep the intermediate nodes as well.
        if (!OnlyLeafNode)
            Paths.push_back(std::move(PP.getValue()));

        // Keep expanding the location.
        for (auto &P : Projections) {
            ProjectionPath X;
            X.append(P);
            X.append(PP.getValue());
            Worklist.push_back(std::move(X));
        }
        // Keep iterating if the worklist is not empty.
    } while (!Worklist.empty());
}