void ReplaceDependentName::handleOneElaboratedTypeLoc( const ElaboratedTypeLoc &TLoc) { SourceLocation Loc = TLoc.getBeginLoc(); if (Loc.isInvalid() || isInIncludedFile(Loc)) return; const ElaboratedType *ET = TLoc.getTypePtr(); if ((ET->getKeyword() != ETK_Typename) && (ET->getKeyword() != ETK_None)) return; if (TLoc.getQualifierLoc().getBeginLoc().isInvalid()) return; std::string Str = ""; if (ValidInstanceNum == 8) TransAssert(ET); bool Typename = false; if (!getTypeString(ET->getNamedType(), Str, Typename)) return; std::string TyStr = ""; ET->getNamedType().getAsStringInternal(TyStr, Context->getPrintingPolicy()); if (TyStr == Str) return; ValidInstanceNum++; if (ValidInstanceNum == TransformationCounter) { TheTyName = Str; NeedTypenameKeyword = Typename; TheLocBegin = getElaboratedTypeLocBegin(TLoc); TheNameLocEnd = TLoc.getEndLoc(); } }
bool EmptyStructToIntRewriteVisitor::VisitElaboratedTypeLoc( ElaboratedTypeLoc Loc) { const ElaboratedType *ETy = dyn_cast<ElaboratedType>(Loc.getTypePtr()); const Type *NamedTy = ETy->getNamedType().getTypePtr(); const RecordType *RDTy = NamedTy->getAs<RecordType>(); if (!RDTy) return true; const RecordDecl *RD = RDTy->getDecl(); TransAssert(RD && "NULL RecordDecl!"); if (RD->getCanonicalDecl() != ConsumerInstance->TheRecordDecl) { return true; } SourceLocation StartLoc = Loc.getLocStart(); if (StartLoc.isInvalid()) return true; TypeLoc TyLoc = Loc.getNamedTypeLoc(); SourceLocation EndLoc = TyLoc.getLocStart(); if (EndLoc.isInvalid()) return true; EndLoc = EndLoc.getLocWithOffset(-1); const char *StartBuf = ConsumerInstance->SrcManager->getCharacterData(StartLoc); const char *EndBuf = ConsumerInstance->SrcManager->getCharacterData(EndLoc); ConsumerInstance->Rewritten = true; // It's possible, e.g., // struct S1 { // struct { } S; // }; // Clang will translate struct { } S to // struct { // }; // struct <anonymous struct ...> S; // the last declaration is injected by clang. // We need to omit it. if (StartBuf > EndBuf) { SourceLocation KeywordLoc = Loc.getElaboratedKeywordLoc(); const llvm::StringRef Keyword = TypeWithKeyword::getKeywordName(ETy->getKeyword()); ConsumerInstance->TheRewriter.ReplaceText(KeywordLoc, Keyword.size(), "int"); return true; } ConsumerInstance->TheRewriter.RemoveText(SourceRange(StartLoc, EndLoc)); return true; }
// Handle cases like: // struct S { // typedef int Int; // }; // S::Int g; // where S::Int is referred as an ElaboratedType bool ReplaceSimpleTypedefRewriteVisitor::VisitElaboratedTypeLoc( ElaboratedTypeLoc Loc) { const ElaboratedType *ETy = dyn_cast<ElaboratedType>(Loc.getTypePtr()); const Type *NamedTy = ETy->getNamedType().getTypePtr(); const TypedefType *TdefTy = NamedTy->getAs<TypedefType>(); if (!TdefTy) return true; const TypedefDecl *TdefD = dyn_cast<TypedefDecl>(TdefTy->getDecl()); if (!TdefD || (dyn_cast<TypedefDecl>(TdefD->getCanonicalDecl()) != ConsumerInstance->TheTypedefDecl)) { return true; } NestedNameSpecifierLoc QualifierLoc = Loc.getQualifierLoc(); if (QualifierLoc && ConsumerInstance->IsScalarType) { ConsumerInstance->TheRewriter.RemoveText(QualifierLoc.getSourceRange()); } return true; }