<commit_before>#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Constants.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/DefaultPasses.h"
#include "ObjectiveCOpts.h"
#include <string>

using namespace GNUstep;
using namespace llvm;
using std::string;

namespace {

  class GNUNonfragileIvarPass : public FunctionPass {

    public:
    static char ID;
    GNUNonfragileIvarPass() : FunctionPass(ID) {}

    Module *M;
    size_t PointerSize;
    virtual bool doInitialization(Module &Mod) {
      M = &Mod;
      PointerSize = 8;
      if (M->getPointerSize() == Module::Pointer32) 
        PointerSize = 4;
      return false;  
    }

    std::string getSuperName(Constant *ClsStruct) {
      User *super = cast<User>(ClsStruct->getOperand(1));
      if (isa<ConstantPointerNull>(super)) return "";
      GlobalVariable *name = cast<GlobalVariable>(super->getOperand(0));
      return cast<ConstantArray>(name->getInitializer())->getAsString();
    }

    size_t sizeOfClass(const std::string &className) {
      // This is a root class
      if ("" == className) { return 0; }
      // These root classes are assumed to only have one ivar: isa
      if (className.compare(0, 8, "NSObject") == 0 || 
          className.compare(0, 6, "Object") == 0) {
        return PointerSize;
      }
      GlobalVariable *Cls = M->getGlobalVariable("_OBJC_CLASS_" + className);
      if (!Cls) return 0;
      Constant *ClsStruct = Cls->getInitializer();
      // Size is initialized to be negative.
      ConstantInt *Size = cast<ConstantInt>(ClsStruct->getOperand(5));
      return sizeOfClass(getSuperName(ClsStruct)) - Size->getSExtValue();
    }

    size_t hardCodedOffset(const StringRef &className, 
                           const StringRef &ivarName) {
      GlobalVariable *Cls = M->getGlobalVariable(("_OBJC_CLASS_" + className).str(), true);
      if (!Cls) return 0;
      Constant *ClsStruct = Cls->getInitializer();
      size_t superSize = sizeOfClass(getSuperName(ClsStruct));
      if (!superSize) return 0;
      ConstantStruct *IvarStruct = cast<ConstantStruct>(
          cast<GlobalVariable>(ClsStruct->getOperand(6))->getInitializer());
      int ivarCount = cast<ConstantInt>(IvarStruct->getOperand(0))->getSExtValue();
      Constant *ivars = IvarStruct->getOperand(1);
      for (int i=0 ; i<ivarCount ; i++) {
        Constant *ivar = cast<Constant>(ivars->getOperand(i));
        GlobalVariable *name =
          cast<GlobalVariable>(
              cast<User>(ivar->getOperand(0))->getOperand(0));
        std::string ivarNameStr = 
          cast<ConstantArray>(name->getInitializer())->getAsString();
        if (ivarNameStr.compare(0, ivarName.size(), ivarName.str()) == 0)
          return superSize +
            cast<ConstantInt>(ivar->getOperand(2))->getSExtValue();
      }
      return 0;
    }

    virtual bool runOnFunction(Function &F) {
      bool modified = false;
      typedef std::pair<Instruction*, Value*> Replacement;
      llvm::SmallVector<Replacement, 16> replacements;
      //llvm::cerr << "IvarPass: " << F.getName() << "\n";
      for (Function::iterator i=F.begin(), end=F.end() ;<commit_msg>Fix non-fragile ivar short-circuiting (i.e. hard-code the CORRECT ivar addresses, don't make foo and foobar have the same offset).<commit_after>#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Constants.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/DefaultPasses.h"
#include "ObjectiveCOpts.h"
#include <string>

using namespace GNUstep;
using namespace llvm;
using std::string;

namespace {

  class GNUNonfragileIvarPass : public FunctionPass {

    public:
    static char ID;
    GNUNonfragileIvarPass() : FunctionPass(ID) {}

    Module *M;
    size_t PointerSize;
    virtual bool doInitialization(Module &Mod) {
      M = &Mod;
      PointerSize = 8;
      if (M->getPointerSize() == Module::Pointer32) 
        PointerSize = 4;
      return false;  
    }

    std::string getSuperName(Constant *ClsStruct) {
      User *super = cast<User>(ClsStruct->getOperand(1));
      if (isa<ConstantPointerNull>(super)) return "";
      GlobalVariable *name = cast<GlobalVariable>(super->getOperand(0));
      return cast<ConstantArray>(name->getInitializer())->getAsString();
    }

    size_t sizeOfClass(const std::string &className) {
      // This is a root class
      if ("" == className) { return 0; }
      // These root classes are assumed to only have one ivar: isa
      if (className.compare(0, 8, "NSObject") == 0 || 
          className.compare(0, 6, "Object") == 0) {
        return PointerSize;
      }
      GlobalVariable *Cls = M->getGlobalVariable("_OBJC_CLASS_" + className);
      if (!Cls) return 0;
      Constant *ClsStruct = Cls->getInitializer();
      // Size is initialized to be negative for the non-fragile ABI.
      ConstantInt *Size = cast<ConstantInt>(ClsStruct->getOperand(5));
      int s = Size->getSExtValue();
      // If we find a fragile class in the hierarchy, don't perform the
      // simplification.  This means that we're the mixed ABI, so we need the
      // extra indirection.
      if (s > 0) return 0;
      return sizeOfClass(getSuperName(ClsStruct)) - Size->getSExtValue();
    }

    size_t hardCodedOffset(const StringRef &className, 
                           const StringRef &ivarName) {
      GlobalVariable *Cls = M->getGlobalVariable(("_OBJC_CLASS_" + className).str(), true);
      if (!Cls) return 0;
      Constant *ClsStruct = Cls->getInitializer();
      size_t superSize = sizeOfClass(getSuperName(ClsStruct));
      if (!superSize) return 0;
      ConstantStruct *IvarStruct = cast<ConstantStruct>(
          cast<GlobalVariable>(ClsStruct->getOperand(6))->getInitializer());
      int ivarCount = cast<ConstantInt>(IvarStruct->getOperand(0))->getSExtValue();
      Constant *ivars = IvarStruct->getOperand(1);
      for (int i=0 ; i<ivarCount ; i++) {
        Constant *ivar = cast<Constant>(ivars->getOperand(i));
        GlobalVariable *name =
          cast<GlobalVariable>(
              cast<User>(ivar->getOperand(0))->getOperand(0));
        std::string ivarNameStr = 
          cast<ConstantArray>(name->getInitializer())->getAsString();
        // Remove the NULL terminator from the metadata string
        ivarNameStr.resize(ivarNameStr.size() - 1);
        if (ivarNameStr == ivarName.str())
          return superSize +
            cast<ConstantInt>(ivar->getOperand(2))->getSExtValue();
      }
      return 0;
    }

    virtual bool runOnFunction(Function &F) {
      bool modified = false;
      typedef std::pair<Instruction*, Value*> Replacement;
      llvm::SmallVector<Replacement, 16> replacements;
      //llvm::cerr << "IvarPass: " << F.getName() << "\n";
      for (Function::iterator i=F.begin(), end=F.end() ;
{'fraction_non_alphanumeric': 0.1369453924914676, 'fraction_numerical': 0.008390216154721275, 'mean_word_length': 3.186309523809524, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5663510', 'n_tokens_mistral': 2191, 'n_tokens_neox': 2155, 'n_words': 494}