From 738f8c278da5950d0d4607de2debe0bdfad64185 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Fri, 31 Jul 2009 23:15:31 +0000 Subject: [PATCH] Add beginnigs of rtti generation, wire up more of -fno-exceptions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77751 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/LangOptions.h | 2 ++ include/clang/Driver/Options.def | 3 +++ lib/CodeGen/CGCXX.cpp | 41 +++++++++++++++++++++++++++---- lib/CodeGen/CodeGenFunction.h | 1 + lib/CodeGen/Mangle.cpp | 15 +++++++++++ lib/CodeGen/Mangle.h | 1 + lib/Driver/Tools.cpp | 16 +++++++++++- tools/clang-cc/clang-cc.cpp | 5 ++++ 8 files changed, 78 insertions(+), 6 deletions(-) diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 26688bf567..f030c28590 100644 --- a/include/clang/Basic/LangOptions.h +++ b/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/include/clang/Driver/Options.def b/include/clang/Driver/Options.def index dbc4e34d97..5826d012d8 100644 --- a/include/clang/Driver/Options.def +++ b/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/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 62dabf77d6..356d31829b 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/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(RD)); + mangleCXXRtti(ClassTy, getContext(), Out); + const char *Name = OutName.c_str(); + llvm::GlobalVariable::LinkageTypes linktype; + linktype = llvm::GlobalValue::WeakAnyLinkage; + std::vector 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(), 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/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 5661343c13..b814ed7c5c 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/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/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 36ee2a4222..341e230e90 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/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) { + // ::= TI # typeinfo structure + Out << "_ZTI"; + mangleType(T); +} + void CXXNameMangler::mangleGuardVariable(const VarDecl *D) { // ::= GV # 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/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h index 1a5ca63c50..8f0a32da88 100644 --- a/lib/CodeGen/Mangle.h +++ b/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/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index e3612c71bd..8158b72ab7 100644 --- a/lib/Driver/Tools.cpp +++ b/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/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index ab4bb1eff4..31e2df7ed8 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -591,6 +591,10 @@ static llvm::cl::opt Exceptions("fexceptions", llvm::cl::desc("Enable support for exception handling")); +static llvm::cl::opt +Rtti("frtti", llvm::cl::init(true), + llvm::cl::desc("Enable generation of rtti information")); + static llvm::cl::opt GNURuntime("fgnu-runtime", llvm::cl::desc("Generate output compatible with the standard GNU " @@ -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()) -- 2.40.0