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

#include "CodeGenModule.h"
Chris Lattner's avatar
Chris Lattner committed
#include "CodeGenFunction.h"
Dan Gohman's avatar
Dan Gohman committed
#include "CodeGenTBAA.h"
#include "CGCall.h"
#include "CGObjCRuntime.h"
#include "clang/Frontend/CodeGenOptions.h"
Daniel Dunbar's avatar
Daniel Dunbar committed
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.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"
#include "llvm/Target/Mangler.h"
#include "llvm/Support/CallSite.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;

static CGCXXABI &createCXXABI(CodeGenModule &CGM) {
  switch (CGM.getContext().Target.getCXXABI()) {
  case CXXABI_ARM: return *CreateARMCXXABI(CGM);
  case CXXABI_Itanium: return *CreateItaniumCXXABI(CGM);
  case CXXABI_Microsoft: return *CreateMicrosoftCXXABI(CGM);
  }

  llvm_unreachable("invalid C++ ABI kind");
  return *CreateItaniumCXXABI(CGM);
}

CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
                             llvm::Module &M, const llvm::TargetData &TD,
                             Diagnostic &diags)
  : Context(C), Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),
    TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
    ABI(createCXXABI(*this)), 
    Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI),
Dan Gohman's avatar
Dan Gohman committed
    TBAA(0),
    CFConstantStringClassRef(0), ConstantStringClassRef(0),
    VMContext(M.getContext()),
    NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0),
    NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
    BlockObjectAssignDecl(0), BlockObjectDisposeDecl(0),
    BlockObjectAssign(0), BlockObjectDispose(0),
    BlockDescriptorType(0), GenericBlockLiteralType(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);
Dan Gohman's avatar
Dan Gohman committed
  // Enable TBAA unless it's suppressed.
  if (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)
    TBAA = new CodeGenTBAA(Context, VMContext, getLangOptions(),
                           ABI.getMangleContext());
  // If debug info generation is enabled, create the CGDebugInfo object.
  DebugInfo = CodeGenOpts.DebugInfo ? new CGDebugInfo(*this) : 0;
John McCall's avatar
John McCall committed

  // Initialize the type cache.
  llvm::LLVMContext &LLVMContext = M.getContext();
  Int8Ty  = llvm::Type::getInt8Ty(LLVMContext);
  Int32Ty  = llvm::Type::getInt32Ty(LLVMContext);
  Int64Ty  = llvm::Type::getInt64Ty(LLVMContext);
  PointerWidthInBits = C.Target.getPointerWidth(0);
  PointerAlignInBytes =
    C.toCharUnitsFromBits(C.Target.getPointerAlign(0)).getQuantity();
John McCall's avatar
John McCall committed
  IntTy = llvm::IntegerType::get(LLVMContext, C.Target.getIntWidth());
  IntPtrTy = llvm::IntegerType::get(LLVMContext, PointerWidthInBits);
  Int8PtrTy = Int8Ty->getPointerTo(0);
  Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
Dan Gohman's avatar
Dan Gohman committed
  delete TBAA;
void CodeGenModule::createObjCRuntime() {
  if (!Features.NeXTRuntime)
    Runtime = CreateGNUObjCRuntime(*this);
  else if (Features.ObjCNonFragileABI)
    Runtime = CreateMacNonFragileABIObjCRuntime(*this);
  else
    Runtime = CreateMacObjCRuntime(*this);
}

  EmitCXXGlobalDtorFunc();
  if (Runtime)
    if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
      AddGlobalCtor(ObjCInitFunction);
  EmitCtorList(GlobalCtors, "llvm.global_ctors");
  EmitCtorList(GlobalDtors, "llvm.global_dtors");
  if (getCodeGenOpts().EmitDeclMetadata)
    EmitDeclMetadata();
Dan Gohman's avatar
Dan Gohman committed
llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) {
  if (!TBAA)
    return 0;
  return TBAA->getTBAAInfo(QTy);
}

void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,
                                        llvm::MDNode *TBAAInfo) {
  Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
}

bool CodeGenModule::isTargetDarwin() const {
  return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin;
}

/// 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;
void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
                                        const NamedDecl *D) const {
  // Internal definitions always have default visibility.
    GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
  // Set visibility for definitions.
  NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
  if (LV.visibilityExplicit() || !GV->hasAvailableExternallyLinkage())
    GV->setVisibility(GetLLVMVisibility(LV.visibility()));
/// Set the symbol visibility of type information (vtable and RTTI)
/// associated with the given type.
void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
                                      const CXXRecordDecl *RD,
Loading
Loading full blame...