Skip to content
CodeGenModule.cpp 47.7 KiB
Newer Older
Chris Lattner's avatar
Chris Lattner committed
//===--- 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.
Chris Lattner's avatar
Chris Lattner committed
//
//===----------------------------------------------------------------------===//
//
// This coordinates the per-module state used while generating code.
//
//===----------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "CGCall.h"
#include "CGObjCRuntime.h"
Daniel Dunbar's avatar
Daniel Dunbar committed
#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/Intrinsics.h"
Chris Lattner's avatar
Chris Lattner committed
using namespace clang;
using namespace CodeGen;


CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
                             llvm::Module &M, const llvm::TargetData &TD,
                             Diagnostic &diags, bool GenerateDebugInfo)
  : BlockModule(C, M, TD, Types, *this), Context(C), Features(LO), TheModule(M),
    TheTargetData(TD), Diags(diags), Types(C, M, TD), Runtime(0),
    MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0) {
Chris Lattner's avatar
Chris Lattner committed
  if (!Features.ObjC1)
    Runtime = 0;
  else if (!Features.NeXTRuntime)
    Runtime = CreateGNUObjCRuntime(*this);
  else if (Features.ObjCNonFragileABI)
    Runtime = CreateMacNonFragileABIObjCRuntime(*this);
  else
    Runtime = CreateMacObjCRuntime(*this);

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

void CodeGenModule::Release() {
  if (Runtime)
    if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
      AddGlobalCtor(ObjCInitFunction);
  EmitCtorList(GlobalCtors, "llvm.global_ctors");
  EmitCtorList(GlobalDtors, "llvm.global_dtors");
void CodeGenModule::BindRuntimeGlobals() {
  // Deal with protecting runtime function names.
  for (unsigned i = 0, e = RuntimeGlobals.size(); i < e; ++i) {
    llvm::GlobalValue *GV = RuntimeGlobals[i].first;
    const std::string &Name = RuntimeGlobals[i].second;
    // Discard unused runtime declarations.
    if (GV->isDeclaration() && GV->use_empty()) {
      GV->eraseFromParent();
    // See if there is a conflict against a function by setting the name and
    // seeing if we got the desired name.
    GV->setName(Name);
    if (GV->isName(Name.c_str()))
      continue;  // Yep, it worked!
    
    GV->setName(""); // Zap the bogus name until we work out the conflict.
    llvm::GlobalValue *Conflict = TheModule.getNamedValue(Name);
    assert(Conflict && "Must have conflicted!");
    
    // Decide which version to take. If the conflict is a definition
    // we are forced to take that, otherwise assume the runtime
    // knows best.
    // FIXME: This will fail phenomenally when the conflict is the
    // wrong type of value. Just bail on it for now. This should
    // really reuse something inside the LLVM Linker code.
    assert(GV->getValueID() == Conflict->getValueID() &&
           "Unable to resolve conflict between globals of different types.");
    if (!Conflict->isDeclaration()) {
      llvm::Value *Casted = 
        llvm::ConstantExpr::getBitCast(Conflict, GV->getType());
      GV->replaceAllUsesWith(Casted);
      GV->eraseFromParent();
    } else {
      GV->takeName(Conflict);
      llvm::Value *Casted = 
        llvm::ConstantExpr::getBitCast(GV, Conflict->getType());
      Conflict->replaceAllUsesWith(Casted);
      Conflict->eraseFromParent();
    }
/// ErrorUnsupported - Print out an error that codegen doesn't support the
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");
  getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID)
    << Msg << S->getSourceRange();
/// ErrorUnsupported - Print out an error that codegen doesn't support the
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");
  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
/// const char* containing the mangled name.  Otherwise, returns
/// the unmangled name.
///
/// 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
Daniel Dunbar's avatar
Daniel Dunbar committed
/// 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)
///
/// FIXME: Performance here is going to be terribly until we start
/// caching mangled names. However, we should fix the problem above
/// first.
const char *CodeGenModule::getMangledName(const NamedDecl *ND) {
  // In C, functions with no attributes never need to be mangled. Fastpath them.
  if (!getLangOptions().CPlusPlus && !ND->hasAttrs()) {
    assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
Chris Lattner's avatar
Chris Lattner committed
    return ND->getNameAsCString();
  llvm::SmallString<256> Name;
  llvm::raw_svector_ostream Out(Name);
  if (!mangleName(ND, Context, Out)) {
    assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
Chris Lattner's avatar
Chris Lattner committed
    return ND->getNameAsCString();
Chris Lattner's avatar
Chris Lattner committed
  return MangledNames.GetOrCreateValue(Name.begin(), Name.end()).getKeyData();
/// AddGlobalCtor - Add a function to the list that will be called before
/// main() runs.
void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor, int Priority) {
  // FIXME: Type coercion of void()* types.
  GlobalCtors.push_back(std::make_pair(Ctor, Priority));
Loading
Loading full blame...