diff options
| -rw-r--r-- | clang/include/clang/Basic/LangOptions.h | 2 | ||||
| -rw-r--r-- | clang/include/clang/Driver/Options.def | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 41 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 1 | ||||
| -rw-r--r-- | clang/lib/CodeGen/Mangle.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/CodeGen/Mangle.h | 1 | ||||
| -rw-r--r-- | clang/lib/Driver/Tools.cpp | 16 | ||||
| -rw-r--r-- | clang/tools/clang-cc/clang-cc.cpp | 5 | 
8 files changed, 78 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 26688bf5672..f030c285906 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -46,6 +46,7 @@ public:    unsigned LaxVectorConversions : 1;    unsigned AltiVec           : 1;  // Support AltiVec-style vector initializers.    unsigned Exceptions        : 1;  // Support exception handling. +  unsigned Rtti              : 1;  // Support rtti information.    unsigned NeXTRuntime       : 1; // Use NeXT runtime.    unsigned Freestanding      : 1; // Freestanding implementation @@ -120,6 +121,7 @@ public:      C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;      CXXOperatorNames = PascalStrings = WritableStrings = 0;      Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0; +    Rtti = 1;      LaxVectorConversions = 1;      HeinousExtensions = 0;      AltiVec = OpenCL = StackProtector = 0; diff --git a/clang/include/clang/Driver/Options.def b/clang/include/clang/Driver/Options.def index dbc4e34d975..5826d012d83 100644 --- a/clang/include/clang/Driver/Options.def +++ b/clang/include/clang/Driver/Options.def @@ -415,11 +415,13 @@ OPTION("-fno-diagnostics-fixit-info", fno_diagnostics_fixit_info, Flag, f_Group,  OPTION("-fno-diagnostics-show-option", fno_diagnostics_show_option, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-dollars-in-identifiers", fno_dollars_in_identifiers, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-eliminate-unused-debug-symbols", fno_eliminate_unused_debug_symbols, Flag, f_Group, INVALID, "", 0, 0, 0) +OPTION("-fno-exceptions", fno_exceptions, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-inline-functions", fno_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-inline", fno_inline, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-keep-inline-functions", fno_keep_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0) +OPTION("-fno-rtti", fno_rtti, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-show-column", fno_show_column, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-show-source-location", fno_show_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fno-stack-protector", fno_stack_protector, Flag, f_Group, INVALID, "", 0, 0, 0) @@ -449,6 +451,7 @@ OPTION("-fpie", fpie, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fprofile-arcs", fprofile_arcs, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fprofile-generate", fprofile_generate, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0) +OPTION("-frtti", frtti, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)  OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0) diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 62dabf77d6b..356d31829be 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -490,10 +490,42 @@ const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,    return UniqueMangledName(Name.begin(), Name.end());  } +llvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) { +  llvm::Type *Ptr8Ty; +  Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); +  llvm::Constant *rtti = llvm::Constant::getNullValue(Ptr8Ty); + +  if (!getContext().getLangOptions().Rtti) +    return rtti; + +  llvm::SmallString<256> OutName; +  llvm::raw_svector_ostream Out(OutName); +  QualType ClassTy; +  // FIXME: What is the design on getTagDeclType when it requires casting +  // away const?  mutable? +  ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD)); +  mangleCXXRtti(ClassTy, getContext(), Out); +  const char *Name = OutName.c_str(); +  llvm::GlobalVariable::LinkageTypes linktype; +  linktype = llvm::GlobalValue::WeakAnyLinkage; +  std::vector<llvm::Constant *> info; +  assert (0 && "FIXME: implement rtti descriptor"); +  // FIXME: descriptor +  info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); +  assert (0 && "FIXME: implement rtti ts"); +  // FIXME: TS +  info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); + +  llvm::Constant *C; +  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size()); +  C = llvm::ConstantArray::get(type, info); +  rtti = new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C, +                                  Name); +  rtti = llvm::ConstantExpr::getBitCast(rtti, Ptr8Ty); +  return rtti; +} +  llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { -  const llvm::FunctionType *FTy; -  FTy = llvm::FunctionType::get(llvm::Type::VoidTy, -                                std::vector<const llvm::Type*>(), false);    llvm::SmallString<256> OutName;    llvm::raw_svector_ostream Out(OutName);    QualType ClassTy; @@ -512,7 +544,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {    m = llvm::Constant::getNullValue(Ptr8Ty);    int64_t offset = 0;    methods.push_back(m); offset += LLVMPointerWidth; -  methods.push_back(m); offset += LLVMPointerWidth; +  methods.push_back(GenerateRtti(RD)); offset += LLVMPointerWidth;    for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;         ++mi) {      if (mi->isVirtual()) { @@ -526,7 +558,6 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {    C = llvm::ConstantArray::get(type, methods);    llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,                                                   linktype, C, Name); -  // CGM.CreateRuntimeFunction(FTy, Name);    vtable = Builder.CreateBitCast(vtable, Ptr8Ty);    // FIXME: finish layout for virtual bases    vtable = Builder.CreateGEP(vtable, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5661343c134..b814ed7c5c5 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -358,6 +358,7 @@ public:    /// legal to call this function even if there is no current insertion point.    void FinishFunction(SourceLocation EndLoc=SourceLocation()); +  llvm::Constant *GenerateRtti(const CXXRecordDecl *RD);    llvm::Value *GenerateVtable(const CXXRecordDecl *RD);    void EmitCtorPrologue(const CXXConstructorDecl *CD); diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index 36ee2a42222..341e230e904 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/lib/CodeGen/Mangle.cpp @@ -42,6 +42,7 @@ namespace {      void mangleGuardVariable(const VarDecl *D);      void mangleCXXVtable(QualType Type); +    void mangleCXXRtti(QualType Type);      void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type);      void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type); @@ -165,6 +166,12 @@ void CXXNameMangler::mangleCXXVtable(QualType T) {    mangleType(T);  } +void CXXNameMangler::mangleCXXRtti(QualType T) { +  // <special-name> ::= TI <type>  # typeinfo structure +  Out << "_ZTI"; +  mangleType(T); +} +  void CXXNameMangler::mangleGuardVariable(const VarDecl *D)  {    //  <special-name> ::= GV <object name>	# Guard variable for one-time  @@ -822,4 +829,12 @@ namespace clang {      os.flush();    } + +  void mangleCXXRtti(QualType Type, ASTContext &Context, +                     llvm::raw_ostream &os) { +    CXXNameMangler Mangler(Context, os); +    Mangler.mangleCXXRtti(Type); + +    os.flush(); +  }  } diff --git a/clang/lib/CodeGen/Mangle.h b/clang/lib/CodeGen/Mangle.h index 1a5ca63c50b..8f0a32da885 100644 --- a/clang/lib/CodeGen/Mangle.h +++ b/clang/lib/CodeGen/Mangle.h @@ -37,6 +37,7 @@ namespace clang {    void mangleGuardVariable(const VarDecl *D, ASTContext &Context,                             llvm::raw_ostream &os);    void mangleCXXVtable(QualType T, ASTContext &Context, llvm::raw_ostream &os); +  void mangleCXXRtti(QualType T, ASTContext &Context, llvm::raw_ostream &os);    void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,                       ASTContext &Context, llvm::raw_ostream &os);    void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index e3612c71bda..8158b72ab72 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -480,7 +480,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,    // Forward -f options which we can pass directly.    Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); -  Args.AddLastArg(CmdArgs, options::OPT_fexceptions);    Args.AddLastArg(CmdArgs, options::OPT_ffreestanding);    Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);    Args.AddLastArg(CmdArgs, options::OPT_fgnu_runtime); @@ -530,6 +529,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,        CmdArgs.push_back("-fblocks=0");    } +  // -fexceptions default varies depending on platform and language; only +  // pass if specified. + if (Arg *A = Args.getLastArg(options::OPT_fexceptions, +                               options::OPT_fno_exceptions)) { +    if (A->getOption().matches(options::OPT_fexceptions)) +      CmdArgs.push_back("-fexceptions"); +    else +      CmdArgs.push_back("-fexceptions=0"); +  } + +  // -frtti is default, only pass non-default. +  if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti)) +    CmdArgs.push_back("-frtti=0"); +    // -fsigned-char/-funsigned-char default varies depending on platform; only    // pass if specified.    if (Arg *A = Args.getLastArg(options::OPT_fsigned_char, @@ -1669,6 +1682,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,          // Derived from darwin_iphoneos_libgcc spec.          CmdArgs.push_back("-lgcc_s.10.5");        } else if (Args.hasArg(options::OPT_shared_libgcc) || +                 // FIXME: -fexceptions -fno-exceptions means no exceptions                   Args.hasArg(options::OPT_fexceptions) ||                   Args.hasArg(options::OPT_fgnu_runtime)) {          // FIXME: This is probably broken on 10.3? diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index ab4bb1eff4e..31e2df7ed82 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -592,6 +592,10 @@ Exceptions("fexceptions",             llvm::cl::desc("Enable support for exception handling"));  static llvm::cl::opt<bool> +Rtti("frtti", llvm::cl::init(true), +     llvm::cl::desc("Enable generation of rtti information")); + +static llvm::cl::opt<bool>  GNURuntime("fgnu-runtime",              llvm::cl::desc("Generate output compatible with the standard GNU "                             "Objective-C runtime")); @@ -769,6 +773,7 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,    if (NoLaxVectorConversions.getPosition())        Options.LaxVectorConversions = 0;    Options.Exceptions = Exceptions; +  Options.Rtti = Rtti;    if (EnableBlocks.getPosition())      Options.Blocks = EnableBlocks;    if (CharIsSigned.getPosition())  | 

