Esempio n. 1
0
void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
                                                  const NamedDecl *Parent,
                                                  const DeclContext *DC) {
  if (!NNS)
    return;

  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
    indexNestedNameSpecifierLoc(Prefix, Parent, DC);

  if (!DC)
    DC = Parent->getLexicalDeclContext();
  SourceLocation Loc = NNS.getSourceRange().getBegin();

  switch (NNS.getNestedNameSpecifier()->getKind()) {
  case NestedNameSpecifier::Identifier:
  case NestedNameSpecifier::Global:
  case NestedNameSpecifier::Super:
    break;

  case NestedNameSpecifier::Namespace:
    handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
                    Loc, Parent, DC, SymbolRoleSet());
    break;
  case NestedNameSpecifier::NamespaceAlias:
    handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
                    Loc, Parent, DC, SymbolRoleSet());
    break;

  case NestedNameSpecifier::TypeSpec:
  case NestedNameSpecifier::TypeSpecWithTemplate:
    indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
    break;
  }
}
Esempio n. 2
0
bool RemoveNamespaceRewriteVisitor::VisitUsingDecl(UsingDecl *D)
{
  if (ConsumerInstance->isForUsingNamedDecls)
    return true;

  if (ConsumerInstance->UselessUsingDecls.count(D)) {
    ConsumerInstance->RewriteHelper->removeDecl(D);
    return true;
  }

  // check if this UsingDecl refers to the namespaced being removed
  NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
  TransAssert(QualifierLoc && "Bad QualifierLoc!");
  NestedNameSpecifierLoc PrefixLoc = QualifierLoc.getPrefix();

  const NestedNameSpecifier *NNS = D->getQualifier();
  TransAssert(NNS && "Bad NameSpecifier!");
  if (ConsumerInstance->isTheNamespaceSpecifier(NNS) &&
      (!PrefixLoc || ConsumerInstance->isGlobalNamespace(PrefixLoc))) {
    ConsumerInstance->RewriteHelper->removeDecl(D);
    SkipTraverseNestedNameSpecifier = true;
  }

  return true;
}
SourceLocation ReplaceDependentName::getElaboratedTypeLocBegin(
                 const ElaboratedTypeLoc &TLoc)
{
  SourceLocation Loc = TLoc.getElaboratedKeywordLoc();
  if (Loc.isValid())
    return Loc;
  NestedNameSpecifierLoc SpecLoc = TLoc.getQualifierLoc();
  NestedNameSpecifierLoc Prefix = SpecLoc.getPrefix();

  while (Prefix.getBeginLoc().isValid()) {
    SpecLoc = Prefix;
    Prefix = Prefix.getPrefix();
  }
  Loc = SpecLoc.getBeginLoc();
  TransAssert(Loc.isValid() && "Failed to get ElaboratedTypeLoc!");
  return Loc;
}
Esempio n. 4
0
SourceRange NestedNameSpecifierLoc::getSourceRange() const {
  if (!Qualifier)
    return SourceRange();
  
  NestedNameSpecifierLoc First = *this;
  while (NestedNameSpecifierLoc Prefix = First.getPrefix())
    First = Prefix;
  
  return SourceRange(First.getLocalSourceRange().getBegin(), 
                     getLocalSourceRange().getEnd());
}
// fix the "B" part of names like A::B::C if B is our target
void TypeRenameTransform::processQualifierLoc(NestedNameSpecifierLoc NNSL,
                                              bool forceRewriteMacro)
{
  while (NNSL) {
    auto NNS = NNSL.getNestedNameSpecifier();
    auto NNSK = NNS->getKind();
    if (NNSK == NestedNameSpecifier::TypeSpec ||
        NNSK == NestedNameSpecifier::TypeSpecWithTemplate) {
      processTypeLoc(NNSL.getTypeLoc(), forceRewriteMacro);
    } 
    else if (NNSK == NestedNameSpecifier::Namespace) {
      std::string newName;
      if (nameMatches(NNS->getAsNamespace(), newName, true)) {
        renameLocation(NNSL.getLocalBeginLoc(), newName);
      }      
      processTypeLoc(NNSL.getTypeLoc(), forceRewriteMacro);
    }
    else if (NNSK == NestedNameSpecifier::NamespaceAlias) {
      std::string newName;
      if (nameMatches(NNS->getAsNamespaceAlias(), newName, true)) {
        renameLocation(NNSL.getLocalBeginLoc(), newName);
      }      
      processTypeLoc(NNSL.getTypeLoc(), forceRewriteMacro);
    }
    // else {
    //   auto srcrange = NNSL.getSourceRange();
    //   llvm::errs() << indent()
    //                << "==> ??? (" << ii << ") "
    //                << " range=[" << range(srcrange)
    //                << "\n";
    //   break;
    // }

    NNSL = NNSL.getPrefix();
  }
}
Esempio n. 6
0
// It handles two cases:
//   * remove the specifier if it refers to TheNamespaceDecl
//   * replace the specifier with a new name if the corresponding namespace
//     has a name conflicts, e.g.,
//   namespace NS1 { }
//   namespace NS2 {
//     namespace NS1 {
//       void foo() {}
//     }
//     namespace NS3 {
//       using NS1::foo;
//       void bar() { foo(); }
//     }
//   }
//   If we remove NS2, then the inner namespace NS1 conflicts with
//   the global NS1, but "using NS1::foo" refers to the conflicting NS1.
bool RemoveNamespaceRewriteVisitor::TraverseNestedNameSpecifierLoc(
       NestedNameSpecifierLoc QualifierLoc)
{
  SkipRewriteName = false;
  // Reset the flag
  if (SkipTraverseNestedNameSpecifier) {
    SkipTraverseNestedNameSpecifier = false;
    return true;
  }

  if (!QualifierLoc || QualifierLoc.getBeginLoc().isInvalid())
    return true;

  SmallVector<NestedNameSpecifierLoc, 8> QualifierLocs;
  for (; QualifierLoc; QualifierLoc = QualifierLoc.getPrefix())
    QualifierLocs.push_back(QualifierLoc);

  while (!QualifierLocs.empty()) {
    NestedNameSpecifierLoc Loc = QualifierLocs.pop_back_val();
    NestedNameSpecifier *NNS = Loc.getNestedNameSpecifier();
    NestedNameSpecifier::SpecifierKind Kind = NNS->getKind();
    const NamespaceDecl *ND = NULL;

    switch (Kind) {
      case NestedNameSpecifier::Namespace: {
        ND = NNS->getAsNamespace()->getCanonicalDecl();
        break;
      }
      case NestedNameSpecifier::NamespaceAlias: {
        const NamespaceAliasDecl *NAD = NNS->getAsNamespaceAlias();
        if (!NAD->getQualifier())
          ND = NAD->getNamespace()->getCanonicalDecl();
        break;
      }
      case NestedNameSpecifier::TypeSpec: // Fall-through
      case NestedNameSpecifier::TypeSpecWithTemplate:
        TraverseTypeLoc(Loc.getTypeLoc());
        break;
      default:
        break;
    }

    if (!ND)
      continue;

    if (ND == ConsumerInstance->TheNamespaceDecl) {
      ConsumerInstance->RewriteHelper->removeSpecifier(Loc);
      continue;
    }

    std::string SpecifierName;
    if (Loc.getBeginLoc().isInvalid())
      continue;

    ConsumerInstance->RewriteHelper->getSpecifierAsString(Loc, SpecifierName);
    std::string NDName = ND->getNameAsString();
    std::string Name = "";
    ConsumerInstance->getNewName(ND, Name);

    // Skip it if this specifier is the same as ND's name.
    // Note that the above case could only happen for UsingNamedDecls
    if (ConsumerInstance->isForUsingNamedDecls && (SpecifierName == NDName)) {
      // It could happen for example:
      // namespace NS1 { }
      // namespace NS2 {
      //   using namespace NS1;
      //   void bar() { NS1::foo(); }
      // }
      // If we remove NS2, then the guard below avoids renaming
      // NS1::foo to NS1::foo::foo.
      if (Name.empty()) {
        SkipRewriteName = true;
        return true;
      }

      // another case to handle:
      // namespace NS1 {
      //   namespace NS2 {
      //     void foo() {}
      //   }
      // }
      // namespace NS3 {
      //   using namespace NS1;
      //   void bar() { NS2::foo(); }
      // }
      // If we remove NS3, we do need to rename NS2::foo as NS1::NS2::foo
      if (!ConsumerInstance->isSuffix(Name, SpecifierName)) {
        SkipRewriteName = true;
        return true;
      }
    }

    if (!Name.empty()) {
      ConsumerInstance->RewriteHelper->replaceSpecifier(Loc, Name);
      SkipRewriteName = true;
      return true;
    }
  }
  return true;
}