예제 #1
0
void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
  switch (D->getKind()) {
    default:
      llvm_unreachable("Invalid ObjC container.");
    case Decl::ObjCInterface:
    case Decl::ObjCImplementation:
      GenObjCClass(D->getName());
      break;
    case Decl::ObjCCategory: {
      ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
      ObjCInterfaceDecl *ID = CD->getClassInterface();
      if (!ID) {
        // Handle invalid code where the @interface might not
        // have been specified.
        // FIXME: We should be able to generate this USR even if the
        // @interface isn't available.
        IgnoreResults = true;
        return;
      }
      // Specially handle class extensions, which are anonymous categories.
      // We want to mangle in the location to uniquely distinguish them.
      if (CD->IsClassExtension()) {
        Out << "objc(ext)" << ID->getName() << '@';
        GenLoc(CD);
      }
      else
        GenObjCCategory(ID->getName(), CD->getName());

      break;
    }
    case Decl::ObjCCategoryImpl: {
      ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
      ObjCInterfaceDecl *ID = CD->getClassInterface();
      if (!ID) {
        // Handle invalid code where the @interface might not
        // have been specified.
        // FIXME: We should be able to generate this USR even if the
        // @interface isn't available.
        IgnoreResults = true;
        return;
      }
      GenObjCCategory(ID->getName(), CD->getName());
      break;
    }
    case Decl::ObjCProtocol:
      GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
      break;
  }
}
예제 #2
0
bool trans::canApplyWeak(ASTContext &Ctx, QualType type,
                         bool AllowOnUnknownClass) {
  if (!Ctx.getLangOpts().ObjCARCWeak)
    return false;

  QualType T = type;
  if (T.isNull())
    return false;

  // iOS is always safe to use 'weak'.
  if (Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::IOS)
    AllowOnUnknownClass = true;

  while (const PointerType *ptr = T->getAs<PointerType>())
    T = ptr->getPointeeType();
  if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) {
    ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl();
    if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject"))
      return false; // id/NSObject is not safe for weak.
    if (!AllowOnUnknownClass && !Class->hasDefinition())
      return false; // forward classes are not verifiable, therefore not safe.
    if (Class && Class->isArcWeakrefUnavailable())
      return false;
  }

  return true;
}
예제 #3
0
void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) {
	std::string I = OID->getName();
	ObjCInterfaceDecl *SID = OID->getSuperClass();

	if (SID)
		Out << "@implementation " << I << " : " << SID->getName();
	else
		Out << "@implementation " << I;

	for (ObjCImplementationDecl::instmeth_iterator I = OID->instmeth_begin(),
		E = OID->instmeth_end(); I != E; ++I) {
			ObjCMethodDecl *OMD = *I;
			PrintObjCMethodDecl(OMD);
			if (OMD->getBody()) {
				Out << ' ';
				OMD->getBody()->printPretty(Out);
				Out << '\n';
			}
	}

	for (ObjCImplementationDecl::classmeth_iterator I = OID->classmeth_begin(),
		E = OID->classmeth_end(); I != E; ++I) {
			ObjCMethodDecl *OMD = *I;
			PrintObjCMethodDecl(OMD);
			if (OMD->getBody()) {
				Out << ' ';
				OMD->getBody()->printPretty(Out);
				Out << '\n';
			}
	}

	Out << "@end\n";
}
예제 #4
0
bool trans::canApplyWeak(ASTContext &Ctx, QualType type,
                         bool AllowOnUnknownClass) {
  if (!Ctx.getLangOptions().ObjCRuntimeHasWeak)
    return false;

  QualType T = type;
  if (T.isNull())
    return false;

  while (const PointerType *ptr = T->getAs<PointerType>())
    T = ptr->getPointeeType();
  if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) {
    ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl();
    if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject"))
      return false; // id/NSObject is not safe for weak.
    if (!AllowOnUnknownClass && Class->isForwardDecl())
      return false; // forward classes are not verifiable, therefore not safe.
    if (Class->isArcWeakrefUnavailable())
      return false;
    if (isClassInWeakBlacklist(Class))
      return false;
  }

  return true;
}
예제 #5
0
void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
  switch (D->getKind()) {
    default:
      assert(false && "Invalid ObjC container.");
    case Decl::ObjCInterface:
    case Decl::ObjCImplementation:
      GenObjCClass(D->getName());
      break;
    case Decl::ObjCCategory: {
      ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
      ObjCInterfaceDecl *ID = CD->getClassInterface();
      if (!ID) {
        // Handle invalid code where the @interface might not
        // have been specified.
        // FIXME: We should be able to generate this USR even if the
        // @interface isn't available.
        IgnoreResults = true;
        return;
      }
      GenObjCCategory(ID->getName(), CD->getName());
      break;
    }
    case Decl::ObjCCategoryImpl: {
      ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
      ObjCInterfaceDecl *ID = CD->getClassInterface();
      if (!ID) {
        // Handle invalid code where the @interface might not
        // have been specified.
        // FIXME: We should be able to generate this USR even if the
        // @interface isn't available.
        IgnoreResults = true;
        return;
      }
      GenObjCCategory(ID->getName(), CD->getName());
      break;
    }
    case Decl::ObjCProtocol:
      GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
      break;
  }
}
예제 #6
0
void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
	std::string I = OID->getName();
  ObjCInterfaceDecl *SID = OID->getSuperClass();

  if (SID)
    Out << "@interface " << I << " : " << SID->getName();
  else
    Out << "@interface " << I;
  
  // Protocols?
  const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
  if (!Protocols.empty()) {
    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
         E = Protocols.end(); I != E; ++I)
      Out << (I == Protocols.begin() ? '<' : ',') << (*I)->getName();
  }
  
  if (!Protocols.empty())
    Out << ">";
  Out << '\n';
  
  if (OID->ivar_size() > 0) {
    Out << '{';
    for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
         E = OID->ivar_end(); I != E; ++I) {
      Out << '\t' << (*I)->getType().getAsString()
          << ' '  << (*I)->getName() << ";\n";      
    }
    Out << "}\n";
  }
  
  for (ObjCInterfaceDecl::classprop_iterator I = OID->classprop_begin(),
       E = OID->classprop_end(); I != E; ++I)
    PrintObjCPropertyDecl(*I);
  bool eol_needed = false;
  for (ObjCInterfaceDecl::classmeth_iterator I = OID->classmeth_begin(),
       E = OID->classmeth_end(); I != E; ++I)
    eol_needed = true, PrintObjCMethodDecl(*I);
  
  for (ObjCInterfaceDecl::instmeth_iterator I = OID->instmeth_begin(),
       E = OID->instmeth_end(); I != E; ++I)
    eol_needed = true, PrintObjCMethodDecl(*I);
  
  Out << (eol_needed ? "\n@end\n" : "@end\n");
  // FIXME: implement the rest...
}
예제 #7
0
StringRef CodeCompletionTUInfo::getParentName(DeclContext *DC) {
  NamedDecl *ND = dyn_cast<NamedDecl>(DC);
  if (!ND)
    return StringRef();
  
  // Check whether we've already cached the parent name.
  StringRef &CachedParentName = ParentNames[DC];
  if (!CachedParentName.empty())
    return CachedParentName;

  // If we already processed this DeclContext and assigned empty to it, the
  // data pointer will be non-null.
  if (CachedParentName.data() != 0)
    return StringRef();

  // Find the interesting names.
  llvm::SmallVector<DeclContext *, 2> Contexts;
  while (DC && !DC->isFunctionOrMethod()) {
    if (NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
      if (ND->getIdentifier())
        Contexts.push_back(DC);
    }
    
    DC = DC->getParent();
  }

  {
    llvm::SmallString<128> S;
    llvm::raw_svector_ostream OS(S);
    bool First = true;
    for (unsigned I = Contexts.size(); I != 0; --I) {
      if (First)
        First = false;
      else {
        OS << "::";
      }
      
      DeclContext *CurDC = Contexts[I-1];
      if (ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
        CurDC = CatImpl->getCategoryDecl();
      
      if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
        ObjCInterfaceDecl *Interface = Cat->getClassInterface();
        if (!Interface) {
          // Assign an empty StringRef but with non-null data to distinguish
          // between empty because we didn't process the DeclContext yet.
          CachedParentName = StringRef((const char *)~0U, 0);
          return StringRef();
        }
        
        OS << Interface->getName() << '(' << Cat->getName() << ')';
      } else {
        OS << cast<NamedDecl>(CurDC)->getName();
      }
    }
    
    CachedParentName = AllocatorRef->CopyString(OS.str());
  }

  return CachedParentName;
}
예제 #8
0
void CodeCompletionBuilder::addParentContext(DeclContext *DC) {
    if (DC->isTranslationUnit()) {
        ParentKind = CXCursor_TranslationUnit;
        return;
    }

    if (DC->isFunctionOrMethod())
        return;

    NamedDecl *ND = dyn_cast<NamedDecl>(DC);
    if (!ND)
        return;

    ParentKind = getCursorKindForDecl(ND);

    // Check whether we've already cached the parent name.
    StringRef &CachedParentName = Allocator.getParentNames()[DC];
    if (!CachedParentName.empty()) {
        ParentName = CachedParentName;
        return;
    }

    // Find the interesting names.
    llvm::SmallVector<DeclContext *, 2> Contexts;
    while (DC && !DC->isFunctionOrMethod()) {
        if (NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
            if (ND->getIdentifier())
                Contexts.push_back(DC);
        }

        DC = DC->getParent();
    }

    {
        llvm::SmallString<128> S;
        llvm::raw_svector_ostream OS(S);
        bool First = true;
        for (unsigned I = Contexts.size(); I != 0; --I) {
            if (First)
                First = false;
            else {
                OS << "::";
            }

            DeclContext *CurDC = Contexts[I-1];
            if (ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
                CurDC = CatImpl->getCategoryDecl();

            if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
                ObjCInterfaceDecl *Interface = Cat->getClassInterface();
                if (!Interface)
                    return;

                OS << Interface->getName() << '(' << Cat->getName() << ')';
            } else {
                OS << cast<NamedDecl>(CurDC)->getName();
            }
        }

        ParentName = Allocator.CopyString(OS.str());
        CachedParentName = ParentName;
    }
}