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