balazske created this revision.
Herald added subscribers: steakhal, whisperity, martong, teemperor, gamesh411, 
Szelethus, dkrupp.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The code of `ASTImporter::Import(const Attr *)` was repetitive,
it is now simplified. (There is still room for improvement but
probably only after big changes.)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110810

Files:
  clang/lib/AST/ASTImporter.cpp

Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -8453,12 +8453,13 @@
 };
 
 class AttrImporter {
-  Error Err = Error::success();
+  Error &Err;
   ASTImporter &Importer;
   ASTNodeImporter NImporter;
 
 public:
-  AttrImporter(ASTImporter &I) : Importer(I), NImporter(I) {}
+  AttrImporter(ASTImporter &I, Error &Err)
+      : Err(Err), Importer(I), NImporter(I) {}
 
   // Create an "importer" for an attribute parameter.
   // Result of the 'value()' of that object is to be passed to the function
@@ -8483,8 +8484,10 @@
   // (The 'Create' with 'ASTContext' first and 'AttributeCommonInfo' last is
   // used here.) As much data is copied or imported from the old attribute
   // as possible. The passed arguments should be already imported.
+  // If any import error happens, nullptr is returned and the internal error
+  // is set to the error. From now on any further import attempt is ignored.
   template <typename T, typename... Arg>
-  Expected<Attr *> createImportedAttr(const T *FromAttr, Arg &&...ImportedArg) {
+  Attr *createImportedAttr(const T *FromAttr, Arg &&...ImportedArg) {
     static_assert(std::is_base_of<Attr, T>::value,
                   "T should be subclass of Attr.");
 
@@ -8497,7 +8500,7 @@
         NImporter.importChecked(Err, FromAttr->getScopeLoc());
 
     if (Err)
-      return std::move(Err);
+      return nullptr;
 
     AttributeCommonInfo ToI(ToAttrName, ToScopeName, ToAttrRange, ToScopeLoc,
                             FromAttr->getParsedKind(), FromAttr->getSyntax(),
@@ -8517,241 +8520,151 @@
 };
 
 Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
-  Attr *ToAttr = nullptr;
-  // FIXME: Use AttrImporter as much as possible, try to remove the import
-  // of range from here.
-  SourceRange ToRange;
-  if (Error Err = importInto(ToRange, FromAttr->getRange()))
-    return std::move(Err);
+  Attr *ToAttr{nullptr};
+  Error Err{Error::success()};
+  AttrImporter AI(*this, Err);
 
   // FIXME: Is there some kind of AttrVisitor to use here?
   switch (FromAttr->getKind()) {
   case attr::Aligned: {
     auto *From = cast<AlignedAttr>(FromAttr);
-    AlignedAttr *To;
-    auto CreateAlign = [&](bool IsAlignmentExpr, void *Alignment) {
-      return AlignedAttr::Create(ToContext, IsAlignmentExpr, Alignment, ToRange,
-                                 From->getSyntax(),
-                                 From->getSemanticSpelling());
-    };
-    if (From->isAlignmentExpr()) {
-      if (auto ToEOrErr = Import(From->getAlignmentExpr()))
-        To = CreateAlign(true, *ToEOrErr);
-      else
-        return ToEOrErr.takeError();
-    } else {
-      if (auto ToTOrErr = Import(From->getAlignmentType()))
-        To = CreateAlign(false, *ToTOrErr);
-      else
-        return ToTOrErr.takeError();
-    }
-    To->setInherited(From->isInherited());
-    To->setPackExpansion(From->isPackExpansion());
-    To->setImplicit(From->isImplicit());
-    ToAttr = To;
+    if (From->isAlignmentExpr())
+      ToAttr = AI.createImportedAttr(
+          From, true, AI.importArg(From->getAlignmentExpr()).value());
+    else
+      ToAttr = AI.createImportedAttr(
+          From, false, AI.importArg(From->getAlignmentType()).value());
     break;
   }
+
   case attr::Format: {
     const auto *From = cast<FormatAttr>(FromAttr);
-    FormatAttr *To;
-    IdentifierInfo *ToAttrType = Import(From->getType());
-    To = FormatAttr::Create(ToContext, ToAttrType, From->getFormatIdx(),
-                            From->getFirstArg(), ToRange, From->getSyntax());
-    To->setInherited(From->isInherited());
-    ToAttr = To;
+    ToAttr = AI.createImportedAttr(From, Import(From->getType()),
+                                   From->getFormatIdx(), From->getFirstArg());
     break;
   }
 
   case attr::AssertCapability: {
     const auto *From = cast<AssertCapabilityAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::AcquireCapability: {
     const auto *From = cast<AcquireCapabilityAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::TryAcquireCapability: {
     const auto *From = cast<TryAcquireCapabilityAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArg(From->getSuccessValue()).value(),
         AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::ReleaseCapability: {
     const auto *From = cast<ReleaseCapabilityAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::RequiresCapability: {
     const auto *From = cast<RequiresCapabilityAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::GuardedBy: {
     const auto *From = cast<GuardedByAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr =
-        AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
+    ToAttr = AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
     break;
   }
   case attr::PtGuardedBy: {
     const auto *From = cast<PtGuardedByAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr =
-        AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
+    ToAttr = AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
     break;
   }
   case attr::AcquiredAfter: {
     const auto *From = cast<AcquiredAfterAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::AcquiredBefore: {
     const auto *From = cast<AcquiredBeforeAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::AssertExclusiveLock: {
     const auto *From = cast<AssertExclusiveLockAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::AssertSharedLock: {
     const auto *From = cast<AssertSharedLockAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::ExclusiveTrylockFunction: {
     const auto *From = cast<ExclusiveTrylockFunctionAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArg(From->getSuccessValue()).value(),
         AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::SharedTrylockFunction: {
     const auto *From = cast<SharedTrylockFunctionAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArg(From->getSuccessValue()).value(),
         AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
   case attr::LockReturned: {
     const auto *From = cast<LockReturnedAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr =
-        AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
+    ToAttr = AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
     break;
   }
   case attr::LocksExcluded: {
     const auto *From = cast<LocksExcludedAttr>(FromAttr);
-    AttrImporter AI(*this);
-    Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+    ToAttr = AI.createImportedAttr(
         From, AI.importArrayArg(From->args(), From->args_size()).value(),
         From->args_size());
-    if (ToAttrOrErr)
-      ToAttr = *ToAttrOrErr;
-    else
-      return ToAttrOrErr.takeError();
     break;
   }
 
-  default:
-    // FIXME: 'clone' copies every member but some of them should be imported.
-    // Handle other Attrs that have parameters that should be imported.
-    ToAttr = FromAttr->clone(ToContext);
+  default: {
+    llvm::consumeError(std::move(Err)); // This error object is not used here.
+    // The default branch works for attributes that have no arguments to import.
+    // FIXME: Handle every attribute type that has arguments of type to import
+    // (most often Expr* or Decl* or type) in the switch above.
+    SourceRange ToRange;
+    if (Error Err = importInto(ToRange, FromAttr->getRange()))
+      return std::move(Err);
+    Attr *ToAttr = FromAttr->clone(ToContext);
     ToAttr->setRange(ToRange);
-    break;
+    return ToAttr;
+  }
   }
+
+  if (Err)
+    return std::move(Err);
+
   assert(ToAttr && "Attribute should be created.");
-  
   return ToAttr;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D110810: [clang][AST... Balázs Kéri via Phabricator via cfe-commits

Reply via email to