aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/DeclObjC.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/DeclObjC.cpp155
1 files changed, 127 insertions, 28 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp b/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp
index 5f82fcec90e3..962f503306a0 100644
--- a/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp
+++ b/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/ODRHash.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
@@ -23,7 +24,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
@@ -232,6 +232,18 @@ ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
return &Ctx.Idents.get(ivarName.str());
}
+ObjCPropertyDecl *ObjCContainerDecl::getProperty(const IdentifierInfo *Id,
+ bool IsInstance) const {
+ for (auto *LookupResult : lookup(Id)) {
+ if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) {
+ if (Prop->isInstanceProperty() == IsInstance) {
+ return Prop;
+ }
+ }
+ }
+ return nullptr;
+}
+
/// FindPropertyDeclaration - Finds declaration of the property given its name
/// in 'PropertyId' and returns it. It returns 0, if not found.
ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
@@ -391,21 +403,18 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
return nullptr;
}
-void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const {
+void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM) const {
for (auto *Prop : properties()) {
PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
- PO.push_back(Prop);
}
for (const auto *Ext : known_extensions()) {
const ObjCCategoryDecl *ClassExt = Ext;
for (auto *Prop : ClassExt->properties()) {
PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
- PO.push_back(Prop);
}
}
for (const auto *PI : all_referenced_protocols())
- PI->collectPropertiesToImplement(PM, PO);
+ PI->collectPropertiesToImplement(PM);
// Note, the properties declared only in class extensions are still copied
// into the main @interface's property list, and therefore we don't
// explicitly, have to search class extension properties.
@@ -603,10 +612,6 @@ void ObjCInterfaceDecl::allocateDefinitionData() {
assert(!hasDefinition() && "ObjC class already has a definition");
Data.setPointer(new (getASTContext()) DefinitionData());
Data.getPointer()->Definition = this;
-
- // Make the type point at the definition, now that we have one.
- if (TypeForDecl)
- cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
}
void ObjCInterfaceDecl::startDefinition() {
@@ -619,6 +624,17 @@ void ObjCInterfaceDecl::startDefinition() {
}
}
+void ObjCInterfaceDecl::startDuplicateDefinitionForComparison() {
+ Data.setPointer(nullptr);
+ allocateDefinitionData();
+ // Don't propagate data to other redeclarations.
+}
+
+void ObjCInterfaceDecl::mergeDuplicateDefinitionWithCommon(
+ const ObjCInterfaceDecl *Definition) {
+ Data = Definition->Data;
+}
+
ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
ObjCInterfaceDecl *&clsDeclared) {
// FIXME: Should make sure no callers ever do this.
@@ -773,6 +789,33 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
return Method;
}
+unsigned ObjCInterfaceDecl::getODRHash() {
+ assert(hasDefinition() && "ODRHash only for records with definitions");
+
+ // Previously calculated hash is stored in DefinitionData.
+ if (hasODRHash())
+ return data().ODRHash;
+
+ // Only calculate hash on first call of getODRHash per record.
+ ODRHash Hasher;
+ Hasher.AddObjCInterfaceDecl(getDefinition());
+ data().ODRHash = Hasher.CalculateHash();
+ setHasODRHash(true);
+
+ return data().ODRHash;
+}
+
+bool ObjCInterfaceDecl::hasODRHash() const {
+ if (!hasDefinition())
+ return false;
+ return data().HasODRHash;
+}
+
+void ObjCInterfaceDecl::setHasODRHash(bool HasHash) {
+ assert(hasDefinition() && "Cannot set ODRHash without definition");
+ data().HasODRHash = HasHash;
+}
+
//===----------------------------------------------------------------------===//
// ObjCMethodDecl
//===----------------------------------------------------------------------===//
@@ -782,7 +825,7 @@ ObjCMethodDecl::ObjCMethodDecl(
QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl,
bool isInstance, bool isVariadic, bool isPropertyAccessor,
bool isSynthesizedAccessorStub, bool isImplicitlyDeclared, bool isDefined,
- ImplementationControl impControl, bool HasRelatedResultType)
+ ObjCImplementationControl impControl, bool HasRelatedResultType)
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),
DeclEndLoc(endLoc) {
@@ -812,8 +855,8 @@ ObjCMethodDecl *ObjCMethodDecl::Create(
Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
DeclContext *contextDecl, bool isInstance, bool isVariadic,
bool isPropertyAccessor, bool isSynthesizedAccessorStub,
- bool isImplicitlyDeclared, bool isDefined, ImplementationControl impControl,
- bool HasRelatedResultType) {
+ bool isImplicitlyDeclared, bool isDefined,
+ ObjCImplementationControl impControl, bool HasRelatedResultType) {
return new (C, contextDecl) ObjCMethodDecl(
beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
isVariadic, isPropertyAccessor, isSynthesizedAccessorStub,
@@ -826,7 +869,8 @@ ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
}
bool ObjCMethodDecl::isDirectMethod() const {
- return hasAttr<ObjCDirectAttr>();
+ return hasAttr<ObjCDirectAttr>() &&
+ !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
}
bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
@@ -854,6 +898,14 @@ bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
return false;
}
+bool ObjCMethodDecl::hasParamDestroyedInCallee() const {
+ for (auto *param : parameters()) {
+ if (param->isDestroyedInCallee())
+ return true;
+ }
+ return false;
+}
+
Stmt *ObjCMethodDecl::getBody() const {
return Body.get(getASTContext().getExternalSource());
}
@@ -879,8 +931,8 @@ void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
unsigned Size = sizeof(ParmVarDecl *) * NumParams +
sizeof(SourceLocation) * SelLocs.size();
ParamsAndSelLocs = C.Allocate(Size);
- std::copy(Params.begin(), Params.end(), getParams());
- std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
+ std::uninitialized_copy(Params.begin(), Params.end(), getParams());
+ std::uninitialized_copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
}
void ObjCMethodDecl::getSelectorLocs(
@@ -895,12 +947,12 @@ void ObjCMethodDecl::setMethodParams(ASTContext &C,
assert((!SelLocs.empty() || isImplicit()) &&
"No selector locs for non-implicit method");
if (isImplicit())
- return setParamsAndSelLocs(C, Params, llvm::None);
+ return setParamsAndSelLocs(C, Params, std::nullopt);
setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params,
DeclEndLoc));
if (getSelLocsKind() != SelLoc_NonStandard)
- return setParamsAndSelLocs(C, Params, llvm::None);
+ return setParamsAndSelLocs(C, Params, std::nullopt);
setParamsAndSelLocs(C, Params, SelLocs);
}
@@ -1142,7 +1194,7 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),
&Context.Idents.get("self"), selfTy,
- ImplicitParamDecl::ObjCSelf);
+ ImplicitParamKind::ObjCSelf);
setSelfDecl(Self);
if (selfIsConsumed)
@@ -1153,7 +1205,7 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
setCmdDecl(ImplicitParamDecl::Create(
Context, this, SourceLocation(), &Context.Idents.get("_cmd"),
- Context.getObjCSelType(), ImplicitParamDecl::ObjCCmd));
+ Context.getObjCSelType(), ImplicitParamKind::ObjCCmd));
}
ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
@@ -1479,7 +1531,7 @@ ObjCTypeParamList *ObjCTypeParamList::create(
void ObjCTypeParamList::gatherDefaultTypeArgs(
SmallVectorImpl<QualType> &typeArgs) const {
typeArgs.reserve(size());
- for (auto typeParam : *this)
+ for (auto *typeParam : *this)
typeArgs.push_back(typeParam->getUnderlyingType());
}
@@ -1630,6 +1682,11 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
ObjCIvarDecl *curIvar = nullptr;
if (!data().IvarList) {
+ // Force ivar deserialization upfront, before building IvarList.
+ (void)ivar_empty();
+ for (const auto *Ext : known_extensions()) {
+ (void)Ext->ivar_empty();
+ }
if (!ivar_empty()) {
ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
data().IvarList = *I; ++I;
@@ -1821,8 +1878,8 @@ ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
ObjCIvarDecl::None, nullptr, false);
}
-const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
- const auto *DC = cast<ObjCContainerDecl>(getDeclContext());
+ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() {
+ auto *DC = cast<ObjCContainerDecl>(getDeclContext());
switch (DC->getKind()) {
default:
@@ -1832,7 +1889,7 @@ const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
// Ivars can only appear in class extension categories.
case ObjCCategory: {
- const auto *CD = cast<ObjCCategoryDecl>(DC);
+ auto *CD = cast<ObjCCategoryDecl>(DC);
assert(CD->IsClassExtension() && "invalid container for ivar!");
return CD->getClassInterface();
}
@@ -1966,6 +2023,7 @@ void ObjCProtocolDecl::allocateDefinitionData() {
assert(!Data.getPointer() && "Protocol already has a definition!");
Data.setPointer(new (getASTContext()) DefinitionData);
Data.getPointer()->Definition = this;
+ Data.getPointer()->HasODRHash = false;
}
void ObjCProtocolDecl::startDefinition() {
@@ -1976,19 +2034,28 @@ void ObjCProtocolDecl::startDefinition() {
RD->Data = this->Data;
}
-void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const {
+void ObjCProtocolDecl::startDuplicateDefinitionForComparison() {
+ Data.setPointer(nullptr);
+ allocateDefinitionData();
+ // Don't propagate data to other redeclarations.
+}
+
+void ObjCProtocolDecl::mergeDuplicateDefinitionWithCommon(
+ const ObjCProtocolDecl *Definition) {
+ Data = Definition->Data;
+}
+
+void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM) const {
if (const ObjCProtocolDecl *PDecl = getDefinition()) {
for (auto *Prop : PDecl->properties()) {
// Insert into PM if not there already.
PM.insert(std::make_pair(
std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
Prop));
- PO.push_back(Prop);
}
// Scan through protocol's protocols.
for (const auto *PI : PDecl->protocols())
- PI->collectPropertiesToImplement(PM, PO);
+ PI->collectPropertiesToImplement(PM);
}
}
@@ -2020,6 +2087,33 @@ ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
return getName();
}
+unsigned ObjCProtocolDecl::getODRHash() {
+ assert(hasDefinition() && "ODRHash only for records with definitions");
+
+ // Previously calculated hash is stored in DefinitionData.
+ if (hasODRHash())
+ return data().ODRHash;
+
+ // Only calculate hash on first call of getODRHash per record.
+ ODRHash Hasher;
+ Hasher.AddObjCProtocolDecl(getDefinition());
+ data().ODRHash = Hasher.CalculateHash();
+ setHasODRHash(true);
+
+ return data().ODRHash;
+}
+
+bool ObjCProtocolDecl::hasODRHash() const {
+ if (!hasDefinition())
+ return false;
+ return data().HasODRHash;
+}
+
+void ObjCProtocolDecl::setHasODRHash(bool HasHash) {
+ assert(hasDefinition() && "Cannot set ODRHash without definition");
+ data().HasODRHash = HasHash;
+}
+
//===----------------------------------------------------------------------===//
// ObjCCategoryDecl
//===----------------------------------------------------------------------===//
@@ -2295,6 +2389,11 @@ QualType ObjCPropertyDecl::getUsageType(QualType objectType) const {
ObjCSubstitutionContext::Property);
}
+bool ObjCPropertyDecl::isDirectProperty() const {
+ return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
+ !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
+}
+
//===----------------------------------------------------------------------===//
// ObjCPropertyImplDecl
//===----------------------------------------------------------------------===//