Esempio n. 1
0
    bool VisitCallExpr(CallExpr *E) {
        llvm::errs() << "I see a CallExpr\n";
        E->dump();


        Expr *callee = E->getCallee();

        if (ImplicitCastExpr *ica = llvm::dyn_cast<ImplicitCastExpr>(callee)) {
            callee = ica->getSubExpr();
        }

        if (DeclRefExpr *dref = llvm::dyn_cast<DeclRefExpr>(callee)) {
            llvm::errs() << "declref:\n";
            dref->dump();

            NamedDecl *d = dref->getFoundDecl();
            ASTContext &Context = d->getASTContext();
            SourceManager &SM = Context.getSourceManager();

            if (dref->hasQualifier()) {
                llvm::errs() << "  has qualifier in name.\n";
                NestedNameSpecifierLoc lc = dref->getQualifierLoc();

                llvm::errs() << "    begin loc: " << lc.getBeginLoc().printToString(SM)
                             << "\n";
                llvm::errs() << "    end loc: " << lc.getEndLoc().printToString(SM)
                             << "\n";
            }

            if (UsingShadowDecl *sh = llvm::dyn_cast<UsingShadowDecl>(d)) {
                NamedDecl *td = sh->getTargetDecl();
                FoundRealDecl(td);
                //d->dump();
            } else {
                FoundRealDecl(d);
                //d->dump();
            }
        } else if (UnresolvedLookupExpr *ule = dyn_cast<UnresolvedLookupExpr>(callee)) {
            llvm::errs() << "unresolved\n";
            ASTContext* Context;
            SourceManager* SM;
            for (const auto *d : ule->decls()) {
                FoundRealDecl(d);
                Context = &d->getASTContext();
                SM = &Context->getSourceManager();
            }
            llvm::errs() << "    begin loc: " << ule->getLocStart().printToString(*SM)
                         << "\n";
            llvm::errs() << "    end loc: " << ule->getLocEnd().printToString(*SM)
                         << "\n";

            NestedNameSpecifierLoc ll = ule->getQualifierLoc();
            llvm::errs() << "    nested begin loc: "
                         << ll.getBeginLoc().printToString(*SM) << "\n";
            llvm::errs() << "    nested end loc: "
                         << ll.getEndLoc().printToString(*SM) << "\n";
        }

        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. 3
0
void RewriteUtils::getQualifierAsString(NestedNameSpecifierLoc Loc,
                                        std::string &Str)
{
  SourceLocation StartLoc = Loc.getBeginLoc();
  TransAssert(StartLoc.isValid() && "Bad StartLoc for NestedNameSpecifier!");
  SourceRange Range = Loc.getSourceRange();
  int Len = TheRewriter->getRangeSize(Range);
  const char *StartBuf = SrcManager->getCharacterData(StartLoc);
  Str.assign(StartBuf, Len);
}
Esempio n. 4
0
void RewriteUtils::getSpecifierAsString(NestedNameSpecifierLoc Loc,
                                        std::string &Str)
{
  SourceLocation StartLoc = Loc.getBeginLoc();
  TransAssert(StartLoc.isValid() && "Bad StartLoc for NestedNameSpecifier!");
  const char *StartBuf = SrcManager->getCharacterData(StartLoc);
  const char *OrigBuf = StartBuf;
  unsigned int Len = 0;
  while (!isspace(*StartBuf) && (*StartBuf != ':')) {
    StartBuf++;
    Len++;
  }
  
  Str.assign(OrigBuf, Len);
}
Esempio n. 5
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;
}