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; }
CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) { if (cursor.kind != CXCursor_CallExpr) return cursor; if (cursor.xdata == 0) return cursor; const Expr *E = getCursorExpr(cursor); TypeSourceInfo *Type = 0; if (const CXXUnresolvedConstructExpr * UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) { Type = UnCtor->getTypeSourceInfo(); } else if (const CXXTemporaryObjectExpr *Tmp = dyn_cast<CXXTemporaryObjectExpr>(E)) { Type = Tmp->getTypeSourceInfo(); } if (!Type) return cursor; CXTranslationUnit TU = getCursorTU(cursor); QualType Ty = Type->getType(); TypeLoc TL = Type->getTypeLoc(); SourceLocation Loc = TL.getBeginLoc(); if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) { Ty = ElabT->getNamedType(); ElaboratedTypeLoc ElabTL = TL.castAs<ElaboratedTypeLoc>(); Loc = ElabTL.getNamedTypeLoc().getBeginLoc(); } if (const TypedefType *Typedef = Ty->getAs<TypedefType>()) return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU); if (const TagType *Tag = Ty->getAs<TagType>()) return MakeCursorTypeRef(Tag->getDecl(), Loc, TU); if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>()) return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU); return cursor; }