15#include "llvm/ADT/SmallString.h"
16#include "llvm/ADT/TinyPtrVector.h"
17#include "llvm/Support/SaveAndRestore.h"
29 std::vector<ObjCPropertyDecl *> &AllProps;
34 std::vector<ObjCPropertyDecl *> &AllProps)
35 : MigrateCtx(ctx), FullyMigratable(
false),
36 AllProps(AllProps) { }
52 lookForAttribute(PropD, PropD->getTypeSourceInfo());
53 AllProps.push_back(PropD);
55 lookForAttribute(DD, DD->getTypeSourceInfo());
68 if (handleAttr(
Attr,
D))
70 TL =
Attr.getModifiedLoc();
73 TL = MDTL.getInnerLoc();
75 TL = Arr.getElementLoc();
77 TL = PT.getPointeeLoc();
79 TL = RT.getPointeeLoc();
86 auto *OwnershipAttr = TL.
getAttrAs<ObjCOwnershipAttr>();
92 if (MigrateCtx.
AttrSet.count(OrigLoc))
98 Loc =
SM.getImmediateExpansionRange(
Loc).getBegin();
99 StringRef Spell = OwnershipAttr->getKind()->getName();
101 if (Spell ==
"strong")
103 else if (Spell ==
"weak")
108 MigrateCtx.
AttrSet.insert(OrigLoc);
116 Attr.FullyMigratable = FullyMigratable;
120 bool isMigratable(
Decl *
D) {
121 if (isa<TranslationUnitDecl>(
D))
128 return FD->hasBody();
131 return hasObjCImpl(ContD);
134 for (
const auto *MI : RD->methods()) {
135 if (MI->isOutOfLine())
144 static bool hasObjCImpl(
Decl *
D) {
149 return ID->getImplementation() !=
nullptr;
151 return CD->getImplementation() !=
nullptr;
152 return isa<ObjCImplDecl>(ContD);
173 return SM.isInFileID(
SM.getExpansionLoc(
Loc),
SM.getMainFileID());
182 for (
unsigned i = 0, e = MigrateCtx.
GCAttrs.size(); i != e; ++i) {
184 if (
Attr.FullyMigratable &&
Attr.Dcl) {
185 if (
Attr.ModifiedType.isNull())
187 if (!
Attr.ModifiedType->isObjCRetainableType()) {
188 TA.
reportError(
"GC managed memory will become unmanaged in ARC",
198 for (
unsigned i = 0, e = MigrateCtx.
GCAttrs.size(); i != e; ++i) {
201 if (
Attr.ModifiedType.isNull() ||
202 !
Attr.ModifiedType->isObjCRetainableType())
210 diag::err_arc_unsupported_weak_class,
222 if (IndProps.empty())
225 for (IndivPropsTy::iterator
226 PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) {
233 bool hasWeak =
false, hasStrong =
false;
235 for (IndivPropsTy::iterator
236 PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) {
245 ATLs.push_back(std::make_pair(ATL, PD));
256 if (hasWeak && hasStrong)
262 if (GCAttrsCollector::hasObjCImpl(
263 cast<Decl>(IndProps.front()->getDeclContext()))) {
268 StringRef toAttr =
"strong";
274 toAttr =
"unsafe_unretained";
282 for (
unsigned i = 0, e = ATLs.size(); i != e; ++i) {
289 TA.
clearDiagnostic(diag::err_objc_property_attr_mutually_exclusive, AtLoc);
291 ATLs[i].second->getLocation());
297 std::vector<ObjCPropertyDecl *> &AllProps) {
298 typedef llvm::TinyPtrVector<ObjCPropertyDecl *>
IndivPropsTy;
299 llvm::DenseMap<SourceLocation, IndivPropsTy> AtProps;
301 for (
unsigned i = 0, e = AllProps.size(); i != e; ++i) {
309 AtProps[AtLoc].push_back(PD);
313 for (
auto I = AtProps.begin(),
E = AtProps.end(); I !=
E; ++I) {
321 std::vector<ObjCPropertyDecl *> AllProps;
322 GCAttrsCollector(MigrateCtx, AllProps).TraverseDecl(
331 llvm::errs() <<
"\n################\n";
332 for (
unsigned i = 0, e =
GCAttrs.size(); i != e; ++i) {
334 llvm::errs() <<
"KIND: "
336 llvm::errs() <<
"\nLOC: ";
338 llvm::errs() <<
"\nTYPE: ";
339 Attr.ModifiedType.dump();
341 llvm::errs() <<
"DECL:\n";
344 llvm::errs() <<
"DECL: NONE";
346 llvm::errs() <<
"\nMIGRATABLE: " <<
Attr.FullyMigratable;
347 llvm::errs() <<
"\n----------------\n";
349 llvm::errs() <<
"\n################\n";
Defines the clang::ASTContext interface.
static bool isInMainFile(const clang::Diagnostic &D)
Defines the SourceManager interface.
static void checkAllProps(MigrationContext &MigrateCtx, std::vector< ObjCPropertyDecl * > &AllProps)
static void checkAllAtProps(MigrationContext &MigrateCtx, SourceLocation AtLoc, IndivPropsTy &IndProps)
llvm::TinyPtrVector< ObjCPropertyDecl * > IndivPropsTy
static void checkWeakGCAttrs(MigrationContext &MigrateCtx)
static void errorForGCAttrsOnNonObjC(MigrationContext &MigrateCtx)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
Wrapper for source info for arrays.
Attr - This represents one attribute.
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Represents a C++ struct/union/class.
SourceLocation getBegin() const
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
DeclContext * getDeclContext()
Represents a ValueDecl that came out of a declarator.
Represents a function declaration or definition.
ObjCCategoryDecl - Represents a category declaration.
ObjCContainerDecl - Represents a container for method declarations.
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
SourceLocation getAtLoc() const
TypeSourceInfo * getTypeSourceInfo() const
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
Wrapper for source info for pointers.
A (possibly-)qualified type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Wrapper of type source information for a type with non-trivial direct qualifiers.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
bool shouldWalkTypesOfTypeLocs() const
Return whether this visitor should recurse into the types of TypeLocs.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
Base wrapper for a particular "section" of type source info.
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
QualType getType() const
Get the type for which this source info wrapper provides information.
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
bool isObjCRetainableType() const
void traverseTU(MigrationContext &MigrateCtx) override
llvm::DenseSet< SourceLocation > AttrSet
bool addPropertyAttribute(StringRef attr, SourceLocation atLoc)
std::vector< GCAttrOccurrence > GCAttrs
llvm::DenseSet< SourceLocation > AtPropsWeak
Set of raw '@' locations for 'assign' properties group that contain GC __weak.
bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr, SourceLocation atLoc)
llvm::DenseSet< SourceLocation > RemovedAttrSet
bool canApplyWeak(ASTContext &Ctx, QualType type, bool AllowOnUnknownClass=false)
Determine whether we can add weak to the given type.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T