Add beginnigs of rtti generation, wire up more of -fno-exceptions.
authorMike Stump <mrs@apple.com>
Fri, 31 Jul 2009 23:15:31 +0000 (23:15 +0000)
committerMike Stump <mrs@apple.com>
Fri, 31 Jul 2009 23:15:31 +0000 (23:15 +0000)
llvm-svn: 77751

clang/include/clang/Basic/LangOptions.h
clang/include/clang/Driver/Options.def
clang/lib/CodeGen/CGCXX.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/CodeGen/Mangle.cpp
clang/lib/CodeGen/Mangle.h
clang/lib/Driver/Tools.cpp
clang/tools/clang-cc/clang-cc.cpp

index 26688bf..f030c28 100644 (file)
@@ -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;
index dbc4e34..5826d01 100644 (file)
@@ -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)
index 62dabf7..356d318 100644 (file)
@@ -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,
index 5661343..b814ed7 100644 (file)
@@ -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);
index 36ee2a4..341e230 100644 (file)
@@ -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();
+  }
 }
index 1a5ca63..8f0a32d 100644 (file)
@@ -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,
index e3612c7..8158b72 100644 (file)
@@ -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?
index ab4bb1e..31e2df7 100644 (file)
@@ -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())