<commit_before>//===--- CodeGenModule.cpp - Emit LLVM Code from ASTs for a Module --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This coordinates the per-module state used while generating code.
//
//===----------------------------------------------------------------------===//

#include "CGDebugInfo.h"
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "CGCall.h"
#include "CGObjCRuntime.h"
#include "Mangle.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/CallingConv.h"
#include "llvm/Module.h"
#include "llvm/Intrinsics.h"
#include "llvm/Target/TargetData.h"
using namespace clang;
using namespace CodeGen;


CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
                             llvm::Module &M, const llvm::TargetData &TD,
                             Diagnostic &diags, bool GenerateDebugInfo)
  : Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags),
    Types(C, M, TD), Runtime(0), MemCpyFn(0), MemMoveFn(0), MemSetFn(0),
    CFConstantStringClassRef(0), NSConcreteGlobalBlock(0),
    BlockDescriptorType(0), GenericBlockLiteralType(0) {

  if (Features.ObjC1) {
    if (Features.NeXTRuntime) {
      Runtime = Features.ObjCNonFragileABI ? CreateMacNonFragileABIObjCRuntime(*this) 
                                       : CreateMacObjCRuntime(*this);
    } else {
      Runtime = CreateGNUObjCRuntime(*this);
    }
  }

  // If debug info generation is enabled, create the CGDebugInfo object.
  DebugInfo = GenerateDebugInfo ? new CGDebugInfo(this) : 0;

  Block.GlobalUniqueCount = 0;
}

CodeGenModule::~CodeGenModule() {
  delete Runtime;
  delete DebugInfo;
}

void CodeGenModule::Release() {
  EmitDeferred();
  EmitAliases();
  if (Runtime)
    if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
      AddGlobalCtor(ObjCInitFunction);
  EmitCtorList(GlobalCtors, "llvm.global_ctors");
  EmitCtorList(GlobalDtors, "llvm.global_dtors");
  EmitAnnotations();
  EmitLLVMUsed();
  BindRuntimeFunctions();
}

void CodeGenModule::BindRuntimeFunctions() {
  // Deal with protecting runtime function names.
  for (unsigned i = 0, e = RuntimeFunctions.size(); i < e; ++i) {
    llvm::Function *Fn = RuntimeFunctions[i].first;
    const std::string &Name = RuntimeFunctions[i].second;
    
    // Discard unused runtime functions.
    if (Fn->use_empty()) {
      Fn->eraseFromParent();
      continue;
    }
      
    // See if there is a conflict against a function.
    llvm::Function *Conflict = TheModule.getFunction(Name);
    if (Conflict) {
      // Decide which version to take. If the conflict is a definition
      // we are forced to take that, otherwise assume the runtime
      // knows best.
      if (!Conflict->isDeclaration()) {
        llvm::Value *Casted = 
          llvm::ConstantExpr::getBitCast(Conflict, Fn->getType());
        Fn->replaceAllUsesWith(Casted);
        Fn->eraseFromParent();
      } else {
        Fn->takeName(Conflict);
        llvm::Value *Casted = 
          llvm::ConstantExpr::getBitCast(Fn, Conflict->getType());
        Conflict->replaceAllUsesWith(Casted);
        Conflict->eraseFromParent();
      }
    } else {
      // FIXME: There still may be conflicts with aliases and
      // variables. 
      Fn->setName(Name);
    }
  }
}

/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified stmt yet.
void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
                                     bool OmitOnError) {
  if (OmitOnError && getDiags().hasErrorOccurred())
    return;
  unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, 
                                               "cannot compile this %0 yet");
  std::string Msg = Type;
  getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID)
    << Msg << S->getSourceRange();
}

/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified decl yet.
void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type,
                                     bool OmitOnError) {
  if (OmitOnError && getDiags().hasErrorOccurred())
    return;
  unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, 
                                               "cannot compile this %0 yet");
  std::string Msg = Type;
  getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
}

/// setGlobalVisibility - Set the visibility for the given LLVM
/// GlobalValue according to the given clang AST visibility value.
static void setGlobalVisibility(llvm::GlobalValue *GV,
                                VisibilityAttr::VisibilityTypes Vis) {
  switch (Vis) {
  default: assert(0 && "Unknown visibility!");
  case VisibilityAttr::DefaultVisibility:
    GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
    break;
  case VisibilityAttr::HiddenVisibility:
    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
    break;
  case VisibilityAttr::ProtectedVisibility:
    GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
    break;
  }
}

/// \brief Retrieves the mangled name for the given declaration.
///
/// If the given declaration requires a mangled name, returns an
/// IdentifierInfo* containing the mangled name. Otherwise, returns
/// the name of the declaration as an identifier.
///
/// FIXME: Returning an IdentifierInfo* here is a total hack. We
/// really need some kind of string abstraction that either stores a
/// mangled name or stores an IdentifierInfo*. This will require
/// changes to the GlobalDeclMap, too.<commit_msg>Add anti-FIXME.<commit_after>//===--- CodeGenModule.cpp - Emit LLVM Code from ASTs for a Module --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This coordinates the per-module state used while generating code.
//
//===----------------------------------------------------------------------===//

#include "CGDebugInfo.h"
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "CGCall.h"
#include "CGObjCRuntime.h"
#include "Mangle.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/CallingConv.h"
#include "llvm/Module.h"
#include "llvm/Intrinsics.h"
#include "llvm/Target/TargetData.h"
using namespace clang;
using namespace CodeGen;


CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
                             llvm::Module &M, const llvm::TargetData &TD,
                             Diagnostic &diags, bool GenerateDebugInfo)
  : Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags),
    Types(C, M, TD), Runtime(0), MemCpyFn(0), MemMoveFn(0), MemSetFn(0),
    CFConstantStringClassRef(0), NSConcreteGlobalBlock(0),
    BlockDescriptorType(0), GenericBlockLiteralType(0) {

  if (Features.ObjC1) {
    if (Features.NeXTRuntime) {
      Runtime = Features.ObjCNonFragileABI ? CreateMacNonFragileABIObjCRuntime(*this) 
                                       : CreateMacObjCRuntime(*this);
    } else {
      Runtime = CreateGNUObjCRuntime(*this);
    }
  }

  // If debug info generation is enabled, create the CGDebugInfo object.
  DebugInfo = GenerateDebugInfo ? new CGDebugInfo(this) : 0;

  Block.GlobalUniqueCount = 0;
}

CodeGenModule::~CodeGenModule() {
  delete Runtime;
  delete DebugInfo;
}

void CodeGenModule::Release() {
  EmitDeferred();
  EmitAliases();
  if (Runtime)
    if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
      AddGlobalCtor(ObjCInitFunction);
  EmitCtorList(GlobalCtors, "llvm.global_ctors");
  EmitCtorList(GlobalDtors, "llvm.global_dtors");
  EmitAnnotations();
  EmitLLVMUsed();
  BindRuntimeFunctions();
}

void CodeGenModule::BindRuntimeFunctions() {
  // Deal with protecting runtime function names.
  for (unsigned i = 0, e = RuntimeFunctions.size(); i < e; ++i) {
    llvm::Function *Fn = RuntimeFunctions[i].first;
    const std::string &Name = RuntimeFunctions[i].second;
    
    // Discard unused runtime functions.
    if (Fn->use_empty()) {
      Fn->eraseFromParent();
      continue;
    }
      
    // See if there is a conflict against a function.
    llvm::Function *Conflict = TheModule.getFunction(Name);
    if (Conflict) {
      // Decide which version to take. If the conflict is a definition
      // we are forced to take that, otherwise assume the runtime
      // knows best.
      if (!Conflict->isDeclaration()) {
        llvm::Value *Casted = 
          llvm::ConstantExpr::getBitCast(Conflict, Fn->getType());
        Fn->replaceAllUsesWith(Casted);
        Fn->eraseFromParent();
      } else {
        Fn->takeName(Conflict);
        llvm::Value *Casted = 
          llvm::ConstantExpr::getBitCast(Fn, Conflict->getType());
        Conflict->replaceAllUsesWith(Casted);
        Conflict->eraseFromParent();
      }
    } else {
      // FIXME: There still may be conflicts with aliases and
      // variables. 
      Fn->setName(Name);
    }
  }
}

/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified stmt yet.
void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
                                     bool OmitOnError) {
  if (OmitOnError && getDiags().hasErrorOccurred())
    return;
  unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, 
                                               "cannot compile this %0 yet");
  std::string Msg = Type;
  getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID)
    << Msg << S->getSourceRange();
}

/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified decl yet.
void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type,
                                     bool OmitOnError) {
  if (OmitOnError && getDiags().hasErrorOccurred())
    return;
  unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, 
                                               "cannot compile this %0 yet");
  std::string Msg = Type;
  getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
}

/// setGlobalVisibility - Set the visibility for the given LLVM
/// GlobalValue according to the given clang AST visibility value.
static void setGlobalVisibility(llvm::GlobalValue *GV,
                                VisibilityAttr::VisibilityTypes Vis) {
  switch (Vis) {
  default: assert(0 && "Unknown visibility!");
  case VisibilityAttr::DefaultVisibility:
    GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
    break;
  case VisibilityAttr::HiddenVisibility:
    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
    break;
  case VisibilityAttr::ProtectedVisibility:
    GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
    break;
  }
}

/// \brief Retrieves the mangled name for the given declaration.
///
/// If the given declaration requires a mangled name, returns an
/// IdentifierInfo* containing the mangled name. Otherwise, returns
/// the name of the declaration as an identifier.
///
/// FIXME: Returning an IdentifierInfo* here is a total hack. We
/// really need some kind of string abstraction that either stores a
/// mangled name or stores an IdentifierInfo*. This will require
/// changes to the GlobalDeclMap, too. (I disagree, I think what we
/// actually need is for Sema to provide some notion of which Decls
/// refer to the same semantic decl. We shouldn't need to mangle the
/// names and see what comes out the same to figure this out. - DWD)
{'fraction_non_alphanumeric': 0.1432683608849412, 'fraction_numerical': 0.002467308166790032, 'mean_word_length': 2.7988128709778195, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5190573', 'n_tokens_mistral': 3526, 'n_tokens_neox': 3439, 'n_words': 939}