Try to fix ODR violation of ErrorInfo::ID
authorReid Kleckner <rnk@google.com>
Thu, 24 Mar 2016 23:49:34 +0000 (23:49 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 24 Mar 2016 23:49:34 +0000 (23:49 +0000)
This implements my suggestion to Lang.

llvm-svn: 264360

llvm/docs/ProgrammersManual.rst
llvm/include/llvm/Support/Error.h
llvm/lib/Support/Error.cpp
llvm/unittests/Support/ErrorTest.cpp

index 3779225..3214555 100644 (file)
@@ -342,10 +342,13 @@ that inherits from the ErrorInfo utility:
   public:
     MyError(std::string Msg) : Msg(Msg) {}
     void log(OStream &OS) const override { OS << "MyError - " << Msg; }
+    static char ID;
   private:
     std::string Msg;
   };
 
+  char MyError::ID = 0; // In MyError.cpp
+
   Error bar() {
     if (checkErrorCondition)
       return make_error<MyError>("Error condition detected");
index 14d7ab0..3eb254c 100644 (file)
@@ -285,15 +285,9 @@ public:
     return ClassID == classID() || ParentErrT::isA(ClassID);
   }
 
-  static const void *classID() { return &ID; }
-
-private:
-  static char ID;
+  static const void *classID() { return &ThisErrT::ID; }
 };
 
-template <typename ThisErrT, typename ParentErrT>
-char ErrorInfo<ThisErrT, ParentErrT>::ID = 0;
-
 /// Special ErrorInfo subclass representing a list of ErrorInfos.
 /// Instances of this class are constructed by joinError.
 class ErrorList final : public ErrorInfo<ErrorList> {
@@ -317,6 +311,9 @@ public:
 
   std::error_code convertToErrorCode() const override;
 
+  // Used by ErrorInfo::classID.
+  static char ID;
+
 private:
   ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
             std::unique_ptr<ErrorInfoBase> Payload2) {
@@ -729,6 +726,9 @@ public:
   std::error_code convertToErrorCode() const override { return EC; }
   void log(raw_ostream &OS) const override { OS << EC.message(); }
 
+  // Used by ErrorInfo::classID.
+  static char ID;
+
 protected:
   std::error_code EC;
 };
index 5bda6aa..9007e69 100644 (file)
@@ -36,9 +36,8 @@ namespace {
 
 void ErrorInfoBase::anchor() {}
 char ErrorInfoBase::ID = 0;
-
-template <> char ErrorInfo<ErrorList>::ID = 0;
-template <> char ErrorInfo<ECError>::ID = 0;
+char ErrorList::ID = 0;
+char ECError::ID = 0;
 
 static ManagedStatic<ErrorErrorCategory> ErrorErrorCat;
 
index cf1c6e6..893bd68 100644 (file)
@@ -35,6 +35,9 @@ public:
     llvm_unreachable("CustomError doesn't support ECError conversion");
   }
 
+  // Used by ErrorInfo::classID.
+  static char ID;
+
 protected:
   // This error is subclassed below, but we can't use inheriting constructors
   // yet, so we can't propagate the constructors through ErrorInfo. Instead
@@ -45,6 +48,8 @@ protected:
   int Info;
 };
 
+char CustomError::ID = 0;
+
 // Custom error class with a custom base class and some additional random
 // 'info'.
 class CustomSubError : public ErrorInfo<CustomSubError, CustomError> {
@@ -66,10 +71,15 @@ public:
     llvm_unreachable("CustomSubError doesn't support ECError conversion");
   }
 
+  // Used by ErrorInfo::classID.
+  static char ID;
+
 protected:
   int ExtraInfo;
 };
 
+char CustomSubError::ID = 0;
+
 static Error handleCustomError(const CustomError &CE) { return Error(); }
 
 static void handleCustomErrorVoid(const CustomError &CE) {}
@@ -453,6 +463,3 @@ TEST(Error, ErrorCodeConversions) {
 }
 
 } // end anon namespace
-
-template <> char ErrorInfo<CustomError>::ID = 0;
-template <> char ErrorInfo<CustomSubError, CustomError>::ID = 0;