balazske updated this revision to Diff 376441.
balazske added a comment.
AttrImporter owns now the result of import (until it is read),
instead of referenced error and returned pointer.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110810/new/
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,7 +8453,8 @@
};
class AttrImporter {
- Error Err = Error::success();
+ Error Err{Error::success()};
+ Attr *ToAttr = nullptr;
ASTImporter &Importer;
ASTNodeImporter NImporter;
@@ -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) {
+ void importAttr(const T *FromAttr, Arg &&...ImportedArg) {
static_assert(std::is_base_of<Attr, T>::value,
"T should be subclass of Attr.");
@@ -8497,262 +8500,171 @@
NImporter.importChecked(Err, FromAttr->getScopeLoc());
if (Err)
- return std::move(Err);
+ return;
AttributeCommonInfo ToI(ToAttrName, ToScopeName, ToAttrRange, ToScopeLoc,
FromAttr->getParsedKind(), FromAttr->getSyntax(),
FromAttr->getAttributeSpellingListIndex());
// The "SemanticSpelling" is not needed to be passed to the constructor.
// That value is recalculated from the SpellingListIndex if needed.
- T *ToAttr = T::Create(Importer.getToContext(),
- std::forward<Arg>(ImportedArg)..., ToI);
+ ToAttr = T::Create(Importer.getToContext(),
+ std::forward<Arg>(ImportedArg)..., ToI);
ToAttr->setImplicit(FromAttr->isImplicit());
ToAttr->setPackExpansion(FromAttr->isPackExpansion());
if (auto *ToInheritableAttr = dyn_cast<InheritableAttr>(ToAttr))
ToInheritableAttr->setInherited(FromAttr->isInherited());
+ }
+
+ void cloneAttr(const Attr *FromAttr) {
+ SourceRange ToRange = NImporter.importChecked(Err, FromAttr->getRange());
+ if (Err)
+ return;
+
+ ToAttr = FromAttr->clone(Importer.getToContext());
+ ToAttr->setRange(ToRange);
+ }
+ llvm::Expected<Attr *> getResult() {
+ if (Err)
+ return std::move(Err);
+ assert(ToAttr && "Attribute should be created.");
return ToAttr;
}
};
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);
+ AttrImporter AI(*this);
// 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())
+ AI.importAttr(From, true, AI.importArg(From->getAlignmentExpr()).value());
+ else
+ AI.importAttr(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;
+ AI.importAttr(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(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::AcquireCapability: {
const auto *From = cast<AcquireCapabilityAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::TryAcquireCapability: {
const auto *From = cast<TryAcquireCapabilityAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = 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();
+ AI.importAttr(From, AI.importArg(From->getSuccessValue()).value(),
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::ReleaseCapability: {
const auto *From = cast<ReleaseCapabilityAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::RequiresCapability: {
const auto *From = cast<RequiresCapabilityAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
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();
+ AI.importAttr(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();
+ AI.importAttr(From, AI.importArg(From->getArg()).value());
break;
}
case attr::AcquiredAfter: {
const auto *From = cast<AcquiredAfterAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::AcquiredBefore: {
const auto *From = cast<AcquiredBeforeAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::AssertExclusiveLock: {
const auto *From = cast<AssertExclusiveLockAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::AssertSharedLock: {
const auto *From = cast<AssertSharedLockAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::ExclusiveTrylockFunction: {
const auto *From = cast<ExclusiveTrylockFunctionAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = 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();
+ AI.importAttr(From, AI.importArg(From->getSuccessValue()).value(),
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
break;
}
case attr::SharedTrylockFunction: {
const auto *From = cast<SharedTrylockFunctionAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = 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();
+ AI.importAttr(From, AI.importArg(From->getSuccessValue()).value(),
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
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();
+ AI.importAttr(From, AI.importArg(From->getArg()).value());
break;
}
case attr::LocksExcluded: {
const auto *From = cast<LocksExcludedAttr>(FromAttr);
- AttrImporter AI(*this);
- Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
- From, AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- if (ToAttrOrErr)
- ToAttr = *ToAttrOrErr;
- else
- return ToAttrOrErr.takeError();
+ AI.importAttr(From,
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
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);
- ToAttr->setRange(ToRange);
+ default: {
+ // 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.
+ AI.cloneAttr(FromAttr);
break;
}
- assert(ToAttr && "Attribute should be created.");
-
- return ToAttr;
+ }
+
+ return AI.getResult();
}
Decl *ASTImporter::GetAlreadyImportedOrNull(const Decl *FromD) const {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits