diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/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 - Expected createImportedAttr(const T *FromAttr, Arg &&...ImportedArg) { + Attr *createImportedAttr(const T *FromAttr, Arg &&...ImportedArg) { static_assert(std::is_base_of::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 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(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(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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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(FromAttr); - AttrImporter AI(*this); - Expected 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; }