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