Add external definitions for commonly-used template specializations and add

anchor methods to others.  This eliminates the vtable/template method bloat
in .o files that defining a cl::opt used to impose (~4K per .o file for one
cp::opt<unsigned>).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29909 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2006-08-27 12:45:47 +00:00
parent 0c0cc92762
commit 7422a76100
2 changed files with 65 additions and 9 deletions

View File

@@ -22,6 +22,7 @@
#include "llvm/Support/type_traits.h" #include "llvm/Support/type_traits.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/Support/Compiler.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include <utility> #include <utility>
@@ -509,6 +510,9 @@ struct basic_parser_impl { // non-template implementation of basic_parser<t>
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "value"; } virtual const char *getValueName() const { return "value"; }
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
}; };
// basic_parser - The real basic parser is just a template wrapper that provides // basic_parser - The real basic parser is just a template wrapper that provides
@@ -519,7 +523,6 @@ struct basic_parser : public basic_parser_impl {
typedef DataType parser_data_type; typedef DataType parser_data_type;
}; };
//-------------------------------------------------- //--------------------------------------------------
// parser<bool> // parser<bool>
// //
@@ -533,10 +536,15 @@ public:
return ValueOptional; return ValueOptional;
} }
// getValueName - Do not print =<value> at all // getValueName - Do not print =<value> at all.
virtual const char *getValueName() const { return 0; } virtual const char *getValueName() const { return 0; }
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
}; };
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
//-------------------------------------------------- //--------------------------------------------------
// parser<int> // parser<int>
@@ -549,8 +557,13 @@ public:
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "int"; } virtual const char *getValueName() const { return "int"; }
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
}; };
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
//-------------------------------------------------- //--------------------------------------------------
// parser<unsigned> // parser<unsigned>
@@ -563,8 +576,12 @@ public:
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "uint"; } virtual const char *getValueName() const { return "uint"; }
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
}; };
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
//-------------------------------------------------- //--------------------------------------------------
// parser<double> // parser<double>
@@ -577,8 +594,12 @@ public:
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "number"; } virtual const char *getValueName() const { return "number"; }
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
}; };
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
//-------------------------------------------------- //--------------------------------------------------
// parser<float> // parser<float>
@@ -591,8 +612,12 @@ public:
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "number"; } virtual const char *getValueName() const { return "number"; }
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
}; };
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
//-------------------------------------------------- //--------------------------------------------------
// parser<std::string> // parser<std::string>
@@ -609,8 +634,13 @@ public:
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "string"; } virtual const char *getValueName() const { return "string"; }
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
}; };
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// applicator class - This class is used because we must use partial // applicator class - This class is used because we must use partial
// specialization to handle literal string arguments specially (const char* does // specialization to handle literal string arguments specially (const char* does
@@ -845,6 +875,11 @@ public:
} }
}; };
EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// list_storage class // list_storage class

View File

@@ -28,11 +28,36 @@
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
using namespace llvm; using namespace llvm;
using namespace cl; using namespace cl;
//===----------------------------------------------------------------------===//
// Template instantiations and anchors.
//
TEMPLATE_INSTANTIATION(class basic_parser<bool>);
TEMPLATE_INSTANTIATION(class basic_parser<int>);
TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
TEMPLATE_INSTANTIATION(class basic_parser<double>);
TEMPLATE_INSTANTIATION(class basic_parser<float>);
TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
TEMPLATE_INSTANTIATION(class opt<unsigned>);
TEMPLATE_INSTANTIATION(class opt<int>);
TEMPLATE_INSTANTIATION(class opt<std::string>);
TEMPLATE_INSTANTIATION(class opt<bool>);
void Option::anchor() {}
void basic_parser_impl::anchor() {}
void parser<bool>::anchor() {}
void parser<int>::anchor() {}
void parser<unsigned>::anchor() {}
void parser<double>::anchor() {}
void parser<float>::anchor() {}
void parser<std::string>::anchor() {}
//===----------------------------------------------------------------------===//
// Globals for name and overview of program // Globals for name and overview of program
static std::string ProgramName ( "<premain>" ); static std::string ProgramName = "<premain>";
static const char *ProgramOverview = 0; static const char *ProgramOverview = 0;
// This collects additional help to be printed. // This collects additional help to be printed.
@@ -47,7 +72,7 @@ extrahelp::extrahelp(const char* Help)
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Basic, shared command line option processing machinery... // Basic, shared command line option processing machinery.
// //
// Return the global command line option vector. Making it a function scoped // Return the global command line option vector. Making it a function scoped
@@ -596,10 +621,6 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
// Option Base class implementation // Option Base class implementation
// //
// Out of line virtual function to provide home for the class.
void Option::anchor() {
}
bool Option::error(std::string Message, const char *ArgName) { bool Option::error(std::string Message, const char *ArgName) {
if (ArgName == 0) ArgName = ArgStr; if (ArgName == 0) ArgName = ArgStr;
if (ArgName[0] == 0) if (ArgName[0] == 0)