Skip to content
CodeGenModule.cpp 79.3 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/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/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/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;


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), TheTargetCodeGenInfo(0), Diags(diags),
    Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()),
    VTables(*this), Runtime(0), ABI(0),
    CFConstantStringClassRef(0), NSConstantStringClassRef(0),
    VMContext(M.getContext()),
    NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0),
    NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
    BlockObjectAssignDecl(0), BlockObjectDisposeDecl(0),
    BlockObjectAssign(0), BlockObjectDispose(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 (!Features.CPlusPlus)
    ABI = 0;
  else createCXXABI();

  // If debug info generation is enabled, create the CGDebugInfo object.
  DebugInfo = CodeGenOpts.DebugInfo ? new CGDebugInfo(*this) : 0;
void CodeGenModule::createObjCRuntime() {
  if (!Features.NeXTRuntime)
    Runtime = CreateGNUObjCRuntime(*this);
  else if (Features.ObjCNonFragileABI)
    Runtime = CreateMacNonFragileABIObjCRuntime(*this);
  else
    Runtime = CreateMacObjCRuntime(*this);
}

void CodeGenModule::createCXXABI() {
  if (Context.Target.getCXXABI() == "microsoft")
    ABI = CreateMicrosoftCXXABI(*this);
  else
    ABI = CreateItaniumCXXABI(*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();
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;
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;
    }
  if (getLangOptions().CPlusPlus) {
    // Entities subject to an explicit instantiation declaration get default
    // visibility.
    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
      if (Function->getTemplateSpecializationKind()
                                        == TSK_ExplicitInstantiationDeclaration)
        return LangOptions::Default;
    } else if (const ClassTemplateSpecializationDecl *ClassSpec
                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
      if (ClassSpec->getSpecializationKind()
                                        == TSK_ExplicitInstantiationDeclaration)
        return LangOptions::Default;
    } else if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
      if (Record->getTemplateSpecializationKind()
                                        == TSK_ExplicitInstantiationDeclaration)
        return LangOptions::Default;
    } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
      if (Var->isStaticDataMember() &&
          (Var->getTemplateSpecializationKind()
                                      == TSK_ExplicitInstantiationDeclaration))
        return LangOptions::Default;
    }

    // If -fvisibility-inlines-hidden was provided, then inline C++ member
    // functions get "hidden" visibility by default.
    if (getLangOptions().InlineVisibilityHidden)
      if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
        if (Method->isInlined())
          return LangOptions::Hidden;
  }
           
  // If this decl is contained in a class, it should have the same visibility
  // as the parent class.
    if (DC->isRecord())
      return getDeclVisibilityMode(cast<Decl>(DC));
  return getLangOptions().getVisibilityMode();
Loading
Loading full blame...