Skip to content
CodeGenModule.cpp 63.1 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.
//
//===----------------------------------------------------------------------===//

#include "CodeGenModule.h"
Chris Lattner's avatar
Chris Lattner committed
#include "CodeGenFunction.h"
#include "CGCall.h"
#include "CGObjCRuntime.h"
#include "clang/CodeGen/CodeGenOptions.h"
Daniel Dunbar's avatar
Daniel Dunbar committed
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/ConvertUTF.h"
#include "llvm/Intrinsics.h"
Chris Lattner's avatar
Chris Lattner committed
#include "llvm/Support/ErrorHandling.h"
Chris Lattner's avatar
Chris Lattner committed
using namespace clang;
using namespace CodeGen;


CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
                             llvm::Module &M, const llvm::TargetData &TD,
                             Diagnostic &diags)
  : BlockModule(C, M, TD, Types, *this), Context(C),
    Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),
    TheTargetData(TD), Diags(diags), Types(C, M, TD), MangleCtx(C), 
    VtableInfo(*this), Runtime(0),
    MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0),
    VMContext(M.getContext()) {
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 = CodeGenOpts.DebugInfo ? new CGDebugInfo(this) : 0;
  delete Runtime;
  delete DebugInfo;
}

void CodeGenModule::Release() {
  // We need to call this first because it can add deferred declarations.
  EmitCXXGlobalInitFunc();

  if (Runtime)
    if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
      AddGlobalCtor(ObjCInitFunction);
  EmitCtorList(GlobalCtors, "llvm.global_ctors");
  EmitCtorList(GlobalDtors, "llvm.global_dtors");
/// 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;
LangOptions::VisibilityMode
CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
  if (const VarDecl *VD = dyn_cast<VarDecl>(D))
    if (VD->getStorageClass() == VarDecl::PrivateExtern)
      return LangOptions::Hidden;

  if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
    switch (attr->getVisibility()) {
    default: assert(0 && "Unknown visibility!");
    case VisibilityAttr::DefaultVisibility:
      return LangOptions::Default;
    case VisibilityAttr::HiddenVisibility:
      return LangOptions::Hidden;
    case VisibilityAttr::ProtectedVisibility:
      return LangOptions::Protected;
    }
  return getLangOptions().getVisibilityMode();
void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
                                        const Decl *D) const {
  // Internal definitions always have default visibility.
    GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
  switch (getDeclVisibilityMode(D)) {
  default: assert(0 && "Unknown visibility!");
  case LangOptions::Default:
    return GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
  case LangOptions::Hidden:
    return GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
  case LangOptions::Protected:
    return GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
const char *CodeGenModule::getMangledName(const GlobalDecl &GD) {
  const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
  if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
    return getMangledCXXCtorName(D, GD.getCtorType());
  if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
    return getMangledCXXDtorName(D, GD.getDtorType());
/// \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.
const char *CodeGenModule::getMangledName(const NamedDecl *ND) {
  if (!getMangleContext().shouldMangleDeclName(ND)) {
    assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
Chris Lattner's avatar
Chris Lattner committed
    return ND->getNameAsCString();
  llvm::SmallString<256> Name;
  getMangleContext().mangleName(ND, Name);
  return UniqueMangledName(Name.begin(), Name.end());
}

const char *CodeGenModule::UniqueMangledName(const char *NameStart,
                                             const char *NameEnd) {
  assert(*(NameEnd - 1) == '\0' && "Mangled name must be null terminated!");
  return MangledNames.GetOrCreateValue(NameStart, NameEnd).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));
/// AddGlobalDtor - Add a function to the list that will be called
/// when the module is unloaded.
void CodeGenModule::AddGlobalDtor(llvm::Function * Dtor, int Priority) {
  // FIXME: Type coercion of void()* types.
  GlobalDtors.push_back(std::make_pair(Dtor, Priority));
}

void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
  // Ctor function type is void()*.
  llvm::FunctionType* CtorFTy =
    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
                            std::vector<const llvm::Type*>(),
                            false);
Loading
Loading full blame...