1 //===----------------------------------------------------------------------===// 2 // 3 // Copyright (c) 2012, 2013, 2015, 2016, 2017, 2018 The University of Utah 4 // All rights reserved. 5 // 6 // This file is distributed under the University of Illinois Open Source 7 // License. See the file COPYING for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef REWRITE_UTILS_H 12 #define REWRITE_UTILS_H 13 14 #include <string> 15 #include "clang/Basic/SourceLocation.h" 16 #include "clang/AST/NestedNameSpecifier.h" 17 18 #ifndef ENABLE_TRANS_ASSERT 19 #define TransAssert(x) {if (!(x)) exit(-1);} 20 #else 21 #define TransAssert(x) assert(x) 22 #endif 23 24 namespace clang { 25 class ParmVarDecl; 26 class VarDecl; 27 class Decl; 28 class DeclStmt; 29 class Rewriter; 30 class SourceManager; 31 class CallExpr; 32 class Expr; 33 class FunctionDecl; 34 class TemplateDecl; 35 class Stmt; 36 class DeclGroupRef; 37 class DeclRefExpr; 38 class NamedDecl; 39 class IfStmt; 40 class Type; 41 class FieldDecl; 42 class CXXConstructExpr; 43 class RecordDecl; 44 class CXXMemberCallExpr; 45 class RecordTypeLoc; 46 class CXXDestructorDecl; 47 class CXXCtorInitializer; 48 class CXXRecordDecl; 49 class ClassTemplateDecl; 50 class CXXMethodDecl; 51 class NestedNameSpecifierLoc; 52 class ValueDecl; 53 } 54 55 class RewriteUtils { 56 public: 57 static RewriteUtils *GetInstance(clang::Rewriter *RW); 58 59 static void Finalize(void); 60 61 clang::SourceLocation getEndLocationFromBegin(clang::SourceRange Range); 62 63 bool removeParamFromFuncDecl(const clang::ParmVarDecl *PV, 64 unsigned int NumParams, 65 int ParamPos); 66 67 bool removeArgFromCallExpr(const clang::CallExpr *CallE, 68 int ParamPos); 69 70 bool removeArgFromCXXConstructExpr(const clang::CXXConstructExpr *CE, 71 int ParamPos); 72 73 bool removeVarFromDeclStmt(clang::DeclStmt *DS, 74 const clang::VarDecl *VD, 75 clang::Decl *PrevDecl, 76 bool IsFirstDecl, 77 bool *StmtRemoved); 78 79 bool getExprString(const clang::Expr *E, 80 std::string &ES); 81 82 bool getStmtString(const clang::Stmt *S, 83 std::string &Str); 84 85 bool replaceExpr(const clang::Expr *E, 86 const std::string &ES); 87 88 bool replaceExprNotInclude(const clang::Expr *E, 89 const std::string &ES); 90 91 bool addLocalVarToFunc(const std::string &VarStr, 92 clang::FunctionDecl *FD); 93 94 std::string getStmtIndentString(clang::Stmt *S, 95 clang::SourceManager *SrcManager); 96 97 bool addNewAssignStmtBefore(clang::Stmt *BeforeStmt, 98 const std::string &VarName, 99 clang::Expr *RHS, 100 bool NeedParen); 101 102 bool addStringBeforeStmt(clang::Stmt *BeforeStmt, 103 const std::string &Str, 104 bool NeedParen); 105 106 bool addStringBeforeStmtAndReplaceExpr(clang::Stmt *BeforeStmt, 107 const std::string &StmtStr, 108 const clang::Expr *E, 109 const std::string &ExprStr, 110 bool NeedParen); 111 112 bool addStringAfterStmt(clang::Stmt *AfterStmt, 113 const std::string &Str); 114 115 bool addStringAfterVarDecl(const clang::VarDecl *VD, 116 const std::string &Str); 117 118 bool addStringAfterFuncDecl(const clang::FunctionDecl *FD, 119 const std::string &Str); 120 121 bool replaceVarDeclName(clang::VarDecl *VD, 122 const std::string &NameStr); 123 124 bool replaceFunctionDeclName(const clang::FunctionDecl *FD, 125 const std::string &NameStr); 126 127 bool replaceRecordDeclName(const clang::RecordDecl *RD, 128 const std::string &NameStr); 129 130 bool replaceRecordDeclDef(const clang::RecordDecl *RD, 131 const std::string &NameStr); 132 133 bool replaceVarTypeName(const clang::VarDecl *VD, 134 const std::string &NameStr); 135 136 const char *getTmpVarNamePrefix(void); 137 138 void getStringBetweenLocs(std::string &Str, 139 clang::SourceLocation LocStart, 140 clang::SourceLocation LocEnd); 141 142 void getStringBetweenLocsAfterStart(std::string &Str, 143 clang::SourceLocation LocStart, 144 clang::SourceLocation LocEnd); 145 146 bool getDeclGroupStrAndRemove(clang::DeclGroupRef DGR, 147 std::string &Str); 148 149 bool getEntireDeclGroupStrAndRemove(clang::DeclGroupRef DGR, 150 std::string &Str); 151 152 clang::SourceLocation getDeclGroupRefEndLoc(clang::DeclGroupRef DGR); 153 154 bool getDeclStmtStrAndRemove(clang::DeclStmt *DS, 155 std::string &Str); 156 157 clang::SourceLocation getDeclStmtEndLoc(clang::DeclStmt *DS); 158 159 bool removeAStarBefore(const clang::Decl *D); 160 161 bool removeAStarAfter(const clang::Expr *E); 162 163 bool removeAnAddrOfAfter(const clang::Expr *E); 164 165 bool removeASymbolAfter(const clang::Expr *E, char Symbol); 166 167 bool insertAnAddrOfBefore(const clang::Expr *E); 168 169 bool insertAStarBefore(const clang::Expr *E); 170 171 bool removeVarInitExpr(const clang::VarDecl *VD); 172 173 bool removeVarDecl(const clang::VarDecl *VD, 174 clang::DeclGroupRef DGR); 175 176 bool removeVarDecl(const clang::VarDecl *VD); 177 178 void getTmpTransName(unsigned Postfix, std::string &Name); 179 180 bool insertStringBeforeFunc(const clang::FunctionDecl *FD, 181 const std::string &Str); 182 183 bool insertStringBeforeTemplateDecl(const clang::TemplateDecl *D, 184 const std::string &Str); 185 186 bool replaceUnionWithStruct(const clang::NamedDecl *ND); 187 188 bool removeIfAndCond(const clang::IfStmt *IS); 189 190 clang::SourceLocation getLocationUntil(clang::SourceLocation Loc, 191 char Symbol); 192 193 clang::SourceLocation getLocationAfter(clang::SourceLocation Loc, 194 char Symbol); 195 196 bool removeArraySubscriptExpr(const clang::Expr *E); 197 198 bool getFunctionDefStrAndRemove(const clang::FunctionDecl *FD, 199 std::string &Str); 200 201 bool getFunctionDeclStrAndRemove(const clang::FunctionDecl *FD, 202 std::string &Str); 203 204 bool replaceFunctionDefWithStr(const clang::FunctionDecl *FD, 205 const std::string &Str); 206 207 clang::SourceLocation getEndLocationUntil(clang::SourceRange Range, 208 char Symbol); 209 210 bool removeFieldDecl(const clang::FieldDecl *FD); 211 212 bool removeDecl(const clang::Decl *D); 213 214 bool replaceNamedDeclName(const clang::NamedDecl *ND, 215 const std::string &NameStr); 216 217 ///\brief Replaces a value decl with a given string. 218 /// 219 ///For example: \code 220 /// enum E {...}; 221 /// template <E argName> struct S { } => template <int> struct S { } 222 ///\endcode 223 /// 224 ///\param[in] VD - The decl to be replaced. 225 ///\param[in] Str - The replacement 226 ///\returns true on success. 227 /// 228 bool replaceValueDecl(const clang::ValueDecl *ValD, const std::string &Str); 229 230 bool replaceCXXDtorCallExpr(const clang::CXXMemberCallExpr *CE, 231 std::string &Name); 232 233 bool removeSpecifier(clang::NestedNameSpecifierLoc Loc); 234 235 bool replaceSpecifier(clang::NestedNameSpecifierLoc Loc, 236 const std::string &Name); 237 238 void getQualifierAsString(clang::NestedNameSpecifierLoc Loc, 239 std::string &Str); 240 241 void getSpecifierAsString(clang::NestedNameSpecifierLoc Loc, 242 std::string &Str); 243 244 bool replaceRecordType(clang::RecordTypeLoc &RTLoc, const std::string &Name); 245 246 bool isSingleDecl(const clang::VarDecl *VD); 247 248 bool isTheFirstDecl(const clang::VarDecl *VD); 249 250 bool removeTextFromLeftAt(clang::SourceRange Range, char C, 251 clang::SourceLocation EndLoc); 252 253 clang::SourceLocation getLocationFromLeftUntil(clang::SourceLocation StartLoc, 254 char C); 255 256 bool removeTextUntil(clang::SourceRange Range, char C); 257 258 bool replaceCXXDestructorDeclName(const clang::CXXDestructorDecl *DtorDecl, 259 const std::string &Name); 260 261 bool removeCXXCtorInitializer(const clang::CXXCtorInitializer *Init, 262 unsigned Index, unsigned NumInits); 263 264 bool removeClassDecls(const clang::CXXRecordDecl *CXXRD); 265 266 bool removeClassTemplateDecls(const clang::ClassTemplateDecl *TmplD); 267 268 bool replaceCXXMethodNameAfterQualifier( 269 const clang::NestedNameSpecifierLoc *QualLoc, 270 const clang::CXXMethodDecl *MD, 271 const std::string &NewName); 272 273 private: 274 275 static RewriteUtils *Instance; 276 277 static const char *TmpVarNamePrefix; 278 279 clang::Rewriter *TheRewriter; 280 281 clang::SourceManager *SrcManager; 282 RewriteUtils(void)283 RewriteUtils(void) 284 : TheRewriter(NULL), 285 SrcManager(NULL) 286 { } 287 ~RewriteUtils(void)288 ~RewriteUtils(void) { } 289 290 int getOffsetUntil(const char *Buf, char Symbol); 291 292 int getSkippingOffset(const char *Buf, char Symbol); 293 294 clang::SourceLocation getEndLocationAfter(clang::SourceRange Range, 295 char Symbol); 296 297 clang::SourceLocation getLocationAfterSkiping(clang::SourceLocation StartLoc, 298 char Symbol); 299 300 unsigned getLocationOffsetAndFileID(clang::SourceLocation Loc, 301 clang::FileID &FID, 302 clang::SourceManager *SrcManager); 303 304 clang::SourceLocation getVarDeclTypeLocEnd(const clang::VarDecl *VD); 305 306 clang::SourceLocation getVarDeclTypeLocBegin(const clang::VarDecl *VD); 307 308 clang::SourceLocation 309 getParamSubstringLocation(clang::SourceLocation StartLoc, size_t Size, 310 const std::string &Substr); 311 312 void indentAfterNewLine(llvm::StringRef Str, 313 std::string &NewStr, 314 const std::string &IndentStr); 315 316 void addOpenParenBeforeStmt(clang::Stmt *S, const std::string &IndentStr); 317 318 bool addStringBeforeStmtInternal(clang::Stmt *S, const std::string &Str, 319 const std::string &IndentStr, 320 bool NeedParen); 321 322 unsigned getOffsetBetweenLocations(clang::SourceLocation StartLoc, 323 clang::SourceLocation EndLoc, 324 clang::SourceManager *SrcManager); 325 326 clang::SourceLocation skipPossibleTypeRange(const clang::Type *Ty, 327 clang::SourceLocation OrigEndLoc, 328 clang::SourceLocation VarStartLoc); 329 330 void skipRangeByType(const std::string &BufStr, 331 const clang::Type *Ty, int &Offset); 332 333 bool removeArgFromExpr(const clang::Expr *E, int ParamPos); 334 335 const clang::Expr *getArgWrapper(const clang::Expr *E, int ParamPos); 336 337 unsigned getNumArgsWrapper(const clang::Expr *E); 338 339 clang::SourceLocation getExpansionEndLoc(clang::SourceLocation EndLoc); 340 341 clang::SourceLocation getMacroExpansionLoc(clang::SourceLocation Loc); 342 343 clang::SourceRange getFileLocSourceRange(clang::SourceRange LocRange); 344 345 // Unimplemented 346 RewriteUtils(const RewriteUtils &); 347 348 void operator=(const RewriteUtils &); 349 }; 350 351 #endif 352