コード例 #1
0
SourceLocation TypeLoc::getBeginLoc() const {
  TypeLoc Cur = *this;
  TypeLoc LeftMost = Cur;
  while (true) {
    switch (Cur.getTypeLocClass()) {
    case Elaborated:
      LeftMost = Cur;
      break;
    case FunctionProto:
      if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn()) {
        LeftMost = Cur;
        break;
      }
      /* Fall through */
    case FunctionNoProto:
    case ConstantArray:
    case DependentSizedArray:
    case IncompleteArray:
    case VariableArray:
      // FIXME: Currently QualifiedTypeLoc does not have a source range
    case Qualified:
      Cur = Cur.getNextTypeLoc();
      continue;
    default:
      if (!Cur.getLocalSourceRange().getBegin().isInvalid())
        LeftMost = Cur;
      Cur = Cur.getNextTypeLoc();
      if (Cur.isNull())
        break;
      continue;
    } // switch
    break;
  } // while
  return LeftMost.getLocalSourceRange().getBegin();
}
コード例 #2
0
ファイル: TypeLoc.cpp プロジェクト: avakar/clang
SourceLocation TypeLoc::getEndLoc() const {
  TypeLoc Cur = *this;
  TypeLoc Last;
  while (true) {
    switch (Cur.getTypeLocClass()) {
    default:
      if (!Last)
	Last = Cur;
      return Last.getLocalSourceRange().getEnd();
    case Paren:
    case ConstantArray:
    case DependentSizedArray:
    case IncompleteArray:
    case VariableArray:
    case FunctionProto:
    case FunctionNoProto:
      Last = Cur;
      break;
    case Pointer:
    case BlockPointer:
    case MemberPointer:
    case LValueReference:
    case RValueReference:
    case PackExpansion:
      if (!Last)
	Last = Cur;
      break;
    case Qualified:
    case Elaborated:
      break;
    }
    Cur = Cur.getNextTypeLoc();
  }
}
コード例 #3
0
ファイル: TypeLoc.cpp プロジェクト: colgur/clang
SourceLocation TypeLoc::getEndLoc() const {
  TypeLoc Cur = *this;
  while (true) {
    switch (Cur.getTypeLocClass()) {
    default:
      break;
    case Qualified:
    case Elaborated:
      Cur = Cur.getNextTypeLoc();
      continue;
    }
    break;
  }
  return Cur.getLocalSourceRange().getEnd();
}
コード例 #4
0
ファイル: TypeLoc.cpp プロジェクト: dfsutherland/clang
/// \brief Initializes a type location, and all of its children
/// recursively, as if the entire tree had been written in the
/// given location.
void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL, 
                             SourceLocation Loc) {
  while (true) {
    switch (TL.getTypeLocClass()) {
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT)        \
    case CLASS: {                     \
      CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
      TLCasted.initializeLocal(Context, Loc);  \
      TL = TLCasted.getNextTypeLoc(); \
      if (!TL) return;                \
      continue;                       \
    }
#include "clang/AST/TypeLocNodes.def"
    }
  }
}
コード例 #5
0
ファイル: TypeLoc.cpp プロジェクト: colgur/clang
SourceLocation TypeLoc::getBeginLoc() const {
  TypeLoc Cur = *this;
  while (true) {
    switch (Cur.getTypeLocClass()) {
    // FIXME: Currently QualifiedTypeLoc does not have a source range
    // case Qualified:
    case Elaborated:
      break;
    default:
      TypeLoc Next = Cur.getNextTypeLoc();
      if (Next.isNull()) break;
      Cur = Next;
      continue;
    }
    break;
  }
  return Cur.getLocalSourceRange().getBegin();
}
コード例 #6
0
// I didn't factor out the common part of this function
// into RewriteUtils, because the common part has implicit
// dependency on VisitTemplateSpecializationTypeLoc. If in another
// transformation we use this utility without implementing
// VisitTemplateSpecializationTypeLoc, we will be in trouble.
bool RemoveNamespaceRewriteVisitor::VisitCXXDestructorDecl(
       CXXDestructorDecl *DtorDecl)
{
  if (ConsumerInstance->isForUsingNamedDecls)
    return true;

  const DeclContext *Ctx = DtorDecl->getDeclContext();
  const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(Ctx);
  TransAssert(CXXRD && "Invalid CXXRecordDecl");

  std::string Name;
  if (!ConsumerInstance->getNewNamedDeclName(CXXRD, Name))
    return true;

  // Avoid duplicated VisitDtor.
  // For example, in the code below:
  // template<typename T>
  // class SomeClass {
  // public:
  //   ~SomeClass<T>() {}
  // };
  // ~SomeClass<T>'s TypeLoc is represented as TemplateSpecializationTypeLoc
  // In this case, ~SomeClass will be renamed from
  // VisitTemplateSpecializationTypeLoc.
  DeclarationNameInfo NameInfo = DtorDecl->getNameInfo();
  if ( TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) {
    TypeLoc DtorLoc = TSInfo->getTypeLoc();
    if (!DtorLoc.isNull() &&
        (DtorLoc.getTypeLocClass() == TypeLoc::TemplateSpecialization))
      return true;
  }

  ConsumerInstance->RewriteHelper->replaceCXXDestructorDeclName(DtorDecl, Name);

  return true;
}
コード例 #7
0
SourceLocation TypeLoc::getBeginLoc() const {
  TypeLoc Cur = *this;
  SourceLocation SavedParenLoc;
  while (true) {
    switch (Cur.getTypeLocClass()) {
    // FIXME: Currently QualifiedTypeLoc does not have a source range
    // case Qualified:
    case Elaborated:
    case DependentName:
    case DependentTemplateSpecialization:
      break;

    case Paren:
      // Save local source begin, if still unset.
      if (SavedParenLoc.isInvalid())
        SavedParenLoc = Cur.getLocalSourceRange().getBegin();
      Cur = Cur.getNextTypeLoc();
      assert(!Cur.isNull());
      continue;
      break;

    case Pointer:
    case BlockPointer:
    case MemberPointer:
    case ObjCObjectPointer:
    case LValueReference:
    case RValueReference:
    case ConstantArray:
    case DependentSizedArray:
    case IncompleteArray:
    case VariableArray:
    case FunctionNoProto:
      // Discard previously saved paren loc, if any.
      SavedParenLoc = SourceLocation();
      Cur = Cur.getNextTypeLoc();
      assert(!Cur.isNull());
      continue;
      break;

    case FunctionProto:
      // Discard previously saved paren loc, if any.
      SavedParenLoc = SourceLocation();
      if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn())
        return Cur.getLocalSourceRange().getBegin();
      Cur = Cur.getNextTypeLoc();
      assert(!Cur.isNull());
      continue;
      break;

    default:
      TypeLoc Next = Cur.getNextTypeLoc();
      if (Next.isNull()) break;
      Cur = Next;
      continue;
    }
    break;
  }
  return SavedParenLoc.isValid()
    ? SavedParenLoc
    : Cur.getLocalSourceRange().getBegin();
}
コード例 #8
0
void TypeRenameTransform::processTypeLoc(TypeLoc TL, bool forceRewriteMacro)
{
  if (TL.isNull()) {
    return;
  }
  
  auto BL = TL.getBeginLoc();
  
  // ignore system headers
  if (shouldIgnore(BL)) {
    return;
  }
  
  // is a result from macro expansion? sorry...
  if (BL.isMacroID() && !forceRewriteMacro) {
    llvm::errs() << "Cannot rename type from macro expansion at: " << loc(BL) << "\n";
    return;
  }
  
  // TODO: Take care of spelling loc finesses
  // BL = sema->getSourceManager().getSpellingLoc(BL);

  pushIndent();
  auto QT = TL.getType();

  // llvm::errs() << indent()
  //   << "TypeLoc"
  //   << ", typeLocClass: " << typeLocClassName(TL.getTypeLocClass())
  //   << "\n" << indent() << "qualType as str: " << QT.getAsString()
  //   << "\n" << indent() << "beginLoc: " << loc(TL.getBeginLoc())
  //   << "\n";
    
  switch(TL.getTypeLocClass()) {    
    case TypeLoc::FunctionProto:
    {
      if (auto FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
        for (unsigned I = 0, E = FTL->getNumArgs(); I != E; ++I) {
          processParmVarDecl(FTL->getArg(I));
        }
      }
      break;
    }    
    // an elaborated type loc captures the "prefix" of a type
    // for example, the elaborated type loc of "A::B::C" is A::B
    // we need to know if A::B and A are types we are renaming
    // (so that we can handle nested classes, in-class typedefs, etc.)
    case TypeLoc::Elaborated:
    {
      if (auto ETL = dyn_cast<ElaboratedTypeLoc>(&TL)) {
        processQualifierLoc(ETL->getQualifierLoc(), forceRewriteMacro);
      }
      break;
    }
    
    case TypeLoc::ObjCObject:
    {
      if (auto OT = dyn_cast<ObjCObjectTypeLoc>(&TL)) {
        for (unsigned I = 0, E = OT->getNumProtocols(); I != E; ++I) {
          if (auto P = OT->getProtocol(I)) {
            std::string newName;
            if (nameMatches(P, newName, true)) {
              renameLocation(OT->getProtocolLoc(I), newName);
            }
          }
        }
      }
      break;
    }
    
    case TypeLoc::InjectedClassName:
    {
      if (auto TSTL = dyn_cast<InjectedClassNameTypeLoc>(&TL)) {
        auto CD = TSTL->getDecl();
        std::string newName;
        if (nameMatches(CD, newName, true)) {
          renameLocation(BL, newName);          
        }      
      }
      break;
    }
    
    case TypeLoc::TemplateSpecialization:
    {
      if (auto TSTL = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
        
        // See if it's the template name that needs renaming
        auto T = TL.getTypePtr();
        
        if (auto TT = dyn_cast<TemplateSpecializationType>(T)) {
          auto TN = TT->getTemplateName();
          auto TD = TN.getAsTemplateDecl();
          auto TTD = TD->getTemplatedDecl();

          std::string newName;
          if (nameMatches(TTD, newName, true)) {
            renameLocation(TSTL->getTemplateNameLoc(), newName);
          }
        }

        // iterate through the args
        for (unsigned I = 0, E = TSTL->getNumArgs(); I != E; ++I) {
          
          // need to see if the template argument is also a type
          // (we skip things like Foo<1> )
          auto AL = TSTL->getArgLoc(I);
          auto A = AL.getArgument();
          if (A.getKind() != TemplateArgument::Type) {
            continue;
          }
          
          if (auto TSI = AL.getTypeSourceInfo()) {
            processTypeLoc(TSI->getTypeLoc(), forceRewriteMacro);
          }
        }
      }
      break;
    }
    
    // typedef is tricky
    case TypeLoc::Typedef:
    {
      auto T = TL.getTypePtr();
      if (auto TDT = dyn_cast<TypedefType>(T)) {
        auto TDD = TDT->getDecl();
        std::string newName;
        if (nameMatches(TDD, newName, true)) {
          renameLocation(BL, newName);
        }
      }
      
      break;
    }
    
    // leaf types
    // TODO: verify correctness, need test cases for each    
    // TODO: Check if Builtin works
    case TypeLoc::Builtin:
    case TypeLoc::Enum:    
    case TypeLoc::Record:
    case TypeLoc::ObjCInterface:
    case TypeLoc::TemplateTypeParm:
    {
      // skip if it's an anonymous type
      // read Clang`s definition (in RecordDecl) -- not exactly what you think
      // so we use the length of name

      std::string newName;      
      if (auto TT = dyn_cast<TagType>(TL.getTypePtr())) {
        auto TD = TT->getDecl();
        if (nameMatches(TD, newName, true)) {
          renameLocation(BL, newName);          
        }
      }
      else {
        if (stringMatches(QT.getAsString(), newName)) {
          renameLocation(BL, newName);
        }
      }
      break;
    }
      
      
    default: 
      break;
  }
  
  processTypeLoc(TL.getNextTypeLoc(), forceRewriteMacro);
  popIndent();
}