1 //===----------------------------------------------------------------------===//
2 //
3 // Copyright (c) 2012, 2013, 2014, 2015, 2016, 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 TRANSFORMATION_H
12 #define TRANSFORMATION_H
13 
14 #include <string>
15 #include <cstdlib>
16 #include <cassert>
17 #include "llvm/ADT/SmallPtrSet.h"
18 #include "clang/AST/ASTConsumer.h"
19 #include "clang/Rewrite/Core/Rewriter.h"
20 #include "RewriteUtils.h"
21 
22 namespace clang {
23   class CompilerInstance;
24   class ASTContext;
25   class SourceManager;
26   class Decl;
27   class Expr;
28   class ArrayType;
29   class InitListExpr;
30   class ArraySubscriptExpr;
31   class MemberExpr;
32   class Type;
33   class ConstantArrayType;
34   class DeclContext;
35   class DeclarationName;
36   class NestedNameSpecifier;
37   class TemplateSpecializationType;
38   class NamedDecl;
39   class CXXConstructorDecl;
40   class TypeLoc;
41   class TemplateArgument;
42   class TemplateTypeParmType;
43   class DependentNameType;
44   class QualType;
45 }
46 
47 typedef enum {
48   TransSuccess = 0,
49   TransInternalError,
50   TransMaxInstanceError,
51   TransMaxVarsError,
52   TransMaxClassesError,
53   TransNoValidVarsError,
54   TransNoValidFunsError,
55   TransNoValidParamsError,
56   TransNoTextModificationError,
57   TransToCounterTooBigError
58 } TransformationError;
59 
60 namespace clang_delta_common_visitor {
61 
62 template<typename T> class CommonRenameClassRewriteVisitor;
63 
64 }
65 
66 class Transformation : public clang::ASTConsumer {
67 
68 template<typename T>
69 friend class clang_delta_common_visitor::CommonRenameClassRewriteVisitor;
70 
71 public:
72 
Transformation(const char * TransName,const char * Desc)73   Transformation(const char *TransName, const char *Desc)
74     : Name(TransName),
75       TransformationCounter(-1),
76       ValidInstanceNum(0),
77       QueryInstanceOnly(false),
78       Context(NULL),
79       SrcManager(NULL),
80       TransError(TransSuccess),
81       DescriptionString(Desc),
82       RewriteHelper(NULL),
83       Rewritten(false),
84       MultipleRewrites(false),
85       ToCounter(-1),
86       DoReplacement(false),
87       CheckReference(false)
88   {
89     // Nothing to do
90   }
91 
Transformation(const char * TransName,const char * Desc,bool MultipleRewritesFlag)92   Transformation(const char *TransName,
93                  const char *Desc,
94                  bool MultipleRewritesFlag)
95     : Name(TransName),
96       TransformationCounter(-1),
97       ValidInstanceNum(0),
98       QueryInstanceOnly(false),
99       Context(NULL),
100       SrcManager(NULL),
101       TransError(TransSuccess),
102       DescriptionString(Desc),
103       RewriteHelper(NULL),
104       Rewritten(false),
105       MultipleRewrites(MultipleRewritesFlag),
106       ToCounter(-1),
107       DoReplacement(false),
108       CheckReference(false)
109   {
110     // Nothing to do
111   }
112 
113 
114   virtual ~Transformation();
115 
116   void outputOriginalSource(llvm::raw_ostream &OutStream);
117 
118   void outputTransformedSource(llvm::raw_ostream &OutStream);
119 
setTransformationCounter(int Counter)120   void setTransformationCounter(int Counter) {
121     TransformationCounter = Counter;
122   }
123 
setToCounter(int Counter)124   void setToCounter(int Counter) {
125     ToCounter = Counter;
126   }
127 
isMultipleRewritesEnabled()128   bool isMultipleRewritesEnabled() {
129     return MultipleRewrites;
130   }
131 
setQueryInstanceFlag(bool Flag)132   void setQueryInstanceFlag(bool Flag) {
133     QueryInstanceOnly = Flag;
134   }
135 
setReplacement(const std::string & Str)136   void setReplacement(const std::string &Str) {
137     Replacement = Str;
138     DoReplacement = true;
139   }
140 
setReferenceValue(const std::string & Str)141   void setReferenceValue(const std::string &Str) {
142     ReferenceValue = Str;
143     CheckReference = true;
144   }
145 
transSuccess()146   bool transSuccess() {
147     return (TransError == TransSuccess);
148   }
149 
transMaxInstanceError()150   bool transMaxInstanceError() {
151     return (TransError == TransMaxInstanceError);
152   }
153 
transInternalError()154   bool transInternalError() {
155     return (TransError == TransInternalError);
156   }
157 
isInvalidCounterError()158   bool isInvalidCounterError() {
159     return ((TransError == TransMaxInstanceError) ||
160             (TransError == TransToCounterTooBigError));
161   }
162 
getDescription()163   std::string &getDescription() {
164     return DescriptionString;
165   }
166 
167   void getTransErrorMsg(std::string &ErrorMsg);
168 
getNumTransformationInstances()169   int getNumTransformationInstances() {
170     return ValidInstanceNum;
171   }
172 
skipCounter()173   virtual bool skipCounter() {
174     return false;
175   }
176 
177 protected:
178 
179   typedef llvm::SmallVector<unsigned int, 10> IndexVector;
180 
181   typedef llvm::SmallVector<const clang::ArrayType *, 10> ArraySubTypeVector;
182 
183   typedef llvm::SmallVector<const clang::Expr *, 10> ExprVector;
184 
185   typedef llvm::SmallPtrSet<const clang::DeclContext *, 20> DeclContextSet;
186 
187   unsigned int getArrayDimension(const clang::ArrayType *ArrayTy);
188 
189   unsigned int getArrayDimensionAndTypes(const clang::ArrayType *ArrayTy,
190                                          ArraySubTypeVector &TyVec);
191 
192   virtual void Initialize(clang::ASTContext &context);
193 
194   const clang::Type *
195     getArrayBaseElemType(const clang::ArrayType *ArrayTy);
196 
197   const clang::Expr *
198     getArraySubscriptElem(const clang::ArraySubscriptExpr *ASE);
199 
200   const clang::Expr *
201     ignoreSubscriptExprParenCasts(const clang::Expr *E);
202 
203   const clang::Expr *getMemberExprElem(const clang::MemberExpr *ME);
204 
205   const clang::Expr *
206     getArrayBaseExprAndIdxs(const clang::ArraySubscriptExpr *ASE,
207                             IndexVector &Idxs);
208 
209   const clang::Expr *getBaseExprAndIdxExprs(
210           const clang::ArraySubscriptExpr *ASE, ExprVector &IdxExprs);
211 
212   const clang::Expr *getInitExprByIndex(IndexVector &Idxs,
213                                         const clang::InitListExpr *ILE);
214 
215   unsigned int getConstArraySize(const clang::ConstantArrayType *CstArrayTy);
216 
217   const clang::Expr *getMemberExprBaseExprAndIdxs(const clang::MemberExpr *ME,
218                                                   IndexVector &Idx);
219 
220   const clang::Expr *getInitExprFromBase(const clang::Expr *BaseE,
221                                          IndexVector &Idxs);
222 
223   const clang::Expr *getBaseExprAndIdxs(const clang::Expr *E,
224                                         IndexVector &Idxs);
225 
226   const clang::Type *getBasePointerElemType(const clang::Type *Ty);
227 
228   const clang::Type* getBaseType(const clang::Type *T);
229 
230   int getIndexAsInteger(const clang::Expr *E);
231 
232   bool isCXXMemberExpr(const clang::MemberExpr *ME);
233 
234   const clang::FunctionDecl *lookupFunctionDecl(
235           clang::DeclarationName &DName,
236           const clang::DeclContext *Ctx,
237           DeclContextSet &VisitedCtxs);
238 
239   const clang::FunctionDecl *lookupFunctionDeclFromCtx(
240           clang::DeclarationName &DName,
241           const clang::DeclContext *Ctx,
242           DeclContextSet &VisitedCtxs);
243 
244   const clang::FunctionDecl *lookupFunctionDeclFromBases(
245           clang::DeclarationName &DName,
246           const clang::CXXRecordDecl *CXXRD,
247           DeclContextSet &VisitedCtxs);
248 
249   const clang::FunctionDecl *lookupFunctionDeclInGlobal(
250           clang::DeclarationName &DName, const clang::DeclContext *Ctx);
251 
252   const clang::DeclContext *getDeclContextFromSpecifier(
253           const clang::NestedNameSpecifier *NNS);
254 
255   bool isSpecialRecordDecl(const clang::RecordDecl *RD);
256 
257   const clang::CXXRecordDecl *getBaseDeclFromType(const clang::Type *Ty);
258 
259   const clang::CXXRecordDecl *getBaseDeclFromTemplateSpecializationType(
260           const clang::TemplateSpecializationType *TSTy);
261 
262   bool isParameterPack(const clang::NamedDecl *ND);
263 
264   unsigned getNumCtorWrittenInitializers(const clang::CXXConstructorDecl &Ctor);
265 
266   bool isBeforeColonColon(clang::TypeLoc &Loc);
267 
268   bool getTypeString(const clang::QualType &QT,
269                      std::string &Str,
270                      bool &Typename);
271 
272   bool getTypedefString(const llvm::StringRef &Name,
273                         const clang::CXXRecordDecl *CXXRD,
274                         const clang::TemplateArgument *Args,
275                         unsigned NumArgs,
276                         std::string &Str,
277                         bool &Typename);
278 
279   bool getDependentNameTypeString(const clang::DependentNameType *DNT,
280                                   std::string &Str,
281                                   bool &Typename);
282 
283   bool replaceDependentNameString(const clang::Type *Ty,
284                                   const clang::TemplateArgument *Args,
285                                   unsigned NumArgs,
286                                   std::string &Str,
287                                   bool &Typename);
288 
289   bool getTemplateTypeParmString(const clang::TemplateTypeParmType *ParmTy,
290                                 const clang::TemplateArgument *Args,
291                                 unsigned NumArgs,
292                                 std::string &Str);
293 
294   unsigned getNumExplicitDecls(const clang::CXXRecordDecl *CXXRD);
295 
296   bool isInIncludedFile(clang::SourceLocation Loc) const;
297 
298   bool isInIncludedFile(const clang::Decl *D) const;
299 
300   bool isInIncludedFile(const clang::Stmt *S) const;
301 
302   bool isDeclaringRecordDecl(const clang::RecordDecl *RD);
303 
304   const std::string Name;
305 
306   int TransformationCounter;
307 
308   int ValidInstanceNum;
309 
310   bool QueryInstanceOnly;
311 
312   clang::ASTContext *Context;
313 
314   clang::SourceManager *SrcManager;
315 
316   clang::Rewriter TheRewriter;
317 
318   TransformationError TransError;
319 
320   std::string DescriptionString;
321 
322   RewriteUtils *RewriteHelper;
323 
324   bool Rewritten;
325 
326   const bool MultipleRewrites;
327 
328   int ToCounter;
329 
330   bool DoReplacement;
331 
332   std::string Replacement;
333 
334   bool CheckReference;
335 
336   std::string ReferenceValue;
337 };
338 
339 class TransNameQueryVisitor;
340 
341 class TransNameQueryWrap {
342 friend class TransNameQueryVisitor;
343 
344 public:
345   explicit TransNameQueryWrap(const std::string &Prefix);
346 
347   ~TransNameQueryWrap();
348 
getMaxNamePostfix()349   unsigned int getMaxNamePostfix() {
350     return MaxPostfix;
351   }
352 
353   bool TraverseDecl(clang::Decl *D);
354 
355 private:
356 
357   std::string NamePrefix;
358 
359   unsigned int MaxPostfix;
360 
361   TransNameQueryVisitor *NameQueryVisitor;
362 
363   // Unimplemented
364   TransNameQueryWrap();
365 
366   TransNameQueryWrap(const TransNameQueryWrap &);
367 
368   void operator=(const TransNameQueryWrap &);
369 };
370 
371 #endif
372