[llvm] [nfc] Common utility macros for `Error` / `Expect<T>` (PR #92150)

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Tue May 14 10:26:22 PDT 2024


https://github.com/mtrofin created https://github.com/llvm/llvm-project/pull/92150

Moving commonly re-defined macros for dealing with `Error` or `Expect<T>` in `Error.h`

Issue #92054.

>From 5e92a2c017569a1e97ee6043f1c40fce2a7be829 Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Tue, 14 May 2024 08:12:30 -0700
Subject: [PATCH] [nfc] Common utility macros for `Error` / `Expect<T>`

Issue #92054.
---
 llvm/include/llvm/Support/Error.h             | 26 +++++++++++++++++
 llvm/lib/Object/COFFObjectFile.cpp            |  7 -----
 llvm/lib/Object/WindowsResource.cpp           | 29 +++++--------------
 llvm/tools/llvm-rc/ResourceScriptParser.cpp   | 12 --------
 llvm/tools/llvm-rc/ResourceScriptStmt.h       |  2 +-
 .../llvm-profdata/OutputSizeLimitTest.cpp     |  4 ---
 6 files changed, 34 insertions(+), 46 deletions(-)

diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h
index 894b6484336ae..8843ee2d3441c 100644
--- a/llvm/include/llvm/Support/Error.h
+++ b/llvm/include/llvm/Support/Error.h
@@ -1420,6 +1420,32 @@ inline Error unwrap(LLVMErrorRef ErrRef) {
       reinterpret_cast<ErrorInfoBase *>(ErrRef)));
 }
 
+/// Common scenarios macros for handling Error or Expect<T> returns
+/// Forward Error.
+#ifndef RETURN_IF_ERROR
+#define RETURN_IF_ERROR(Expr)                                                  \
+  if (auto Err = (Expr))                                                       \
+    return Err;
+#endif
+
+/// Assign Var as Expect<T>, and forward the Error. The user decides how to
+/// consume the contained value - move it, or take a reference.
+#ifndef ASSIGN_OR_RETURN
+#define ASSIGN_OR_RETURN(Var, Expr)                                            \
+  auto Var = (Expr);                                                           \
+  if (!Var)                                                                    \
+    return Var.takeError();
+#endif
+
+/// Forward the Error. Otherwise move the contained value to Var.
+#ifndef TAKE_OR_RETURN
+#define TAKE_OR_RETURN(Var, Expr)                                              \
+  auto Var##OrErr = (Expr);                                                    \
+  if (!Var##OrErr)                                                             \
+    return Var##OrErr.takeError();                                             \
+  auto Var = std::move(*Var##OrErr);
+#endif
+
 } // end namespace llvm
 
 #endif // LLVM_SUPPORT_ERROR_H
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 18506f39f6b57..af0ccba5b0970 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -1789,13 +1789,6 @@ Error BaseRelocRef::getRVA(uint32_t &Result) const {
   return Error::success();
 }
 
-#define RETURN_IF_ERROR(Expr)                                                  \
-  do {                                                                         \
-    Error E = (Expr);                                                          \
-    if (E)                                                                     \
-      return std::move(E);                                                     \
-  } while (0)
-
 Expected<ArrayRef<UTF16>>
 ResourceSectionRef::getDirStringAtOffset(uint32_t Offset) {
   BinaryStreamReader Reader = BinaryStreamReader(BBS);
diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp
index 983c8e30a9420..4f50e6a949051 100644
--- a/llvm/lib/Object/WindowsResource.cpp
+++ b/llvm/lib/Object/WindowsResource.cpp
@@ -13,6 +13,7 @@
 #include "llvm/Object/WindowsResource.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Object/WindowsMachineFlag.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/ScopedPrinter.h"
@@ -25,22 +26,6 @@ using namespace object;
 namespace llvm {
 namespace object {
 
-#define RETURN_IF_ERROR(X)                                                     \
-  if (auto EC = X)                                                             \
-    return EC;
-
-#define UNWRAP_REF_OR_RETURN(Name, Expr)                                       \
-  auto Name##OrErr = Expr;                                                     \
-  if (!Name##OrErr)                                                            \
-    return Name##OrErr.takeError();                                            \
-  const auto &Name = *Name##OrErr;
-
-#define UNWRAP_OR_RETURN(Name, Expr)                                           \
-  auto Name##OrErr = Expr;                                                     \
-  if (!Name##OrErr)                                                            \
-    return Name##OrErr.takeError();                                            \
-  auto Name = *Name##OrErr;
-
 const uint32_t MIN_HEADER_SIZE = 7 * sizeof(uint32_t) + 2 * sizeof(uint16_t);
 
 // COFF files seem to be inconsistent with alignment between sections, just use
@@ -365,7 +350,7 @@ Error WindowsResourceParser::parse(WindowsResource *WR,
 
 Error WindowsResourceParser::parse(ResourceSectionRef &RSR, StringRef Filename,
                                    std::vector<std::string> &Duplicates) {
-  UNWRAP_REF_OR_RETURN(BaseTable, RSR.getBaseTable());
+  TAKE_OR_RETURN(BaseTable, RSR.getBaseTable());
   uint32_t Origin = InputFilenames.size();
   InputFilenames.push_back(std::string(Filename));
   std::vector<StringOrID> Context;
@@ -395,14 +380,14 @@ Error WindowsResourceParser::addChildren(TreeNode &Node,
 
   for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries;
        i++) {
-    UNWRAP_REF_OR_RETURN(Entry, RSR.getTableEntry(Table, i));
+    TAKE_OR_RETURN(Entry, RSR.getTableEntry(Table, i));
     TreeNode *Child;
 
     if (Entry.Offset.isSubDir()) {
 
       // Create a new subdirectory and recurse
       if (i < Table.NumberOfNameEntries) {
-        UNWRAP_OR_RETURN(NameString, RSR.getEntryNameString(Entry));
+        TAKE_OR_RETURN(NameString, RSR.getEntryNameString(Entry));
         Child = &Node.addNameChild(NameString, StringTable);
         Context.push_back(StringOrID(NameString));
       } else {
@@ -410,7 +395,7 @@ Error WindowsResourceParser::addChildren(TreeNode &Node,
         Context.push_back(StringOrID(Entry.Identifier.ID));
       }
 
-      UNWRAP_REF_OR_RETURN(NextTable, RSR.getEntrySubDir(Entry));
+      TAKE_OR_RETURN(NextTable, RSR.getEntrySubDir(Entry));
       Error E =
           addChildren(*Child, RSR, NextTable, Origin, Context, Duplicates);
       if (E)
@@ -425,14 +410,14 @@ Error WindowsResourceParser::addChildren(TreeNode &Node,
                                  "unexpected string key for data object");
 
       // Try adding a data leaf
-      UNWRAP_REF_OR_RETURN(DataEntry, RSR.getEntryData(Entry));
+      TAKE_OR_RETURN(DataEntry, RSR.getEntryData(Entry));
       TreeNode *Child;
       Context.push_back(StringOrID(Entry.Identifier.ID));
       bool Added = Node.addDataChild(Entry.Identifier.ID, Table.MajorVersion,
                                      Table.MinorVersion, Table.Characteristics,
                                      Origin, Data.size(), Child);
       if (Added) {
-        UNWRAP_OR_RETURN(Contents, RSR.getContents(DataEntry));
+        TAKE_OR_RETURN(Contents, RSR.getContents(DataEntry));
         Data.push_back(ArrayRef<uint8_t>(
             reinterpret_cast<const uint8_t *>(Contents.data()),
             Contents.size()));
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index 69798152c1f25..977484bf6ac10 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -17,18 +17,6 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
 
-// Take an expression returning llvm::Error and forward the error if it exists.
-#define RETURN_IF_ERROR(Expr)                                                  \
-  if (auto Err = (Expr))                                                       \
-    return std::move(Err);
-
-// Take an expression returning llvm::Expected<T> and assign it to Var or
-// forward the error out of the function.
-#define ASSIGN_OR_RETURN(Var, Expr)                                            \
-  auto Var = (Expr);                                                           \
-  if (!Var)                                                                    \
-    return Var.takeError();
-
 namespace llvm {
 namespace rc {
 
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index 05865e5828592..0d8ec3e5b7875 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -145,7 +145,7 @@ class IntOrString {
   IntOrString(const RCToken &Token)
       : Data(Token), IsInt(Token.kind() == RCToken::Kind::Int) {}
 
-  bool equalsLower(const char *Str) {
+  bool equalsLower(const char *Str) const {
     return !IsInt && Data.String.equals_insensitive(Str);
   }
 
diff --git a/llvm/unittests/tools/llvm-profdata/OutputSizeLimitTest.cpp b/llvm/unittests/tools/llvm-profdata/OutputSizeLimitTest.cpp
index d21c378e8ce3b..9f049d497138e 100644
--- a/llvm/unittests/tools/llvm-profdata/OutputSizeLimitTest.cpp
+++ b/llvm/unittests/tools/llvm-profdata/OutputSizeLimitTest.cpp
@@ -65,10 +65,6 @@ template <typename T> class ExpectedErrorOr : public Expected<T> {
     return Var##OrErr;                                                         \
   Var = std::move(Var##OrErr.get())
 
-#define RETURN_IF_ERROR(Value)                                                 \
-  if (auto E = Value)                                                          \
-  return std::move(E)
-
 /// The main testing routine. After rewriting profiles with size limit, check
 /// the following:
 /// 1. The file size of the new profile is within the size limit.



More information about the llvm-commits mailing list