1 //===----------------------------------------------------------------------===// 2 // 3 // Copyright (c) 2012 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 REMOVE_NAMESPACE_H 12 #define REMOVE_NAMESPACE_H 13 14 #include <string> 15 #include "Transformation.h" 16 #include "llvm/ADT/SmallPtrSet.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "clang/AST/NestedNameSpecifier.h" 19 20 namespace clang { 21 class DeclGroupRef; 22 class ASTContext; 23 class NamespaceDecl; 24 class NamedDecl; 25 class DeclContext; 26 class UsingDirectiveDecl; 27 class UsingShadowDecl; 28 class UsingDecl; 29 class EnumDecl; 30 } 31 32 class RemoveNamespaceASTVisitor; 33 class RemoveNamespaceRewriteVisitor; 34 35 class RemoveNamespace : public Transformation { 36 friend class RemoveNamespaceASTVisitor; 37 friend class RemoveNamespaceRewriteVisitor; 38 39 public: 40 RemoveNamespace(const char * TransName,const char * Desc)41 RemoveNamespace(const char *TransName, const char *Desc) 42 : Transformation(TransName, Desc), 43 CollectionVisitor(NULL), 44 RewriteVisitor(NULL), 45 TheNamespaceDecl(NULL), 46 NamePrefix("Trans_NS_"), 47 AnonNamePrefix("Trans_Anon_NS"), 48 AnonNamespaceCounter(0), 49 isForUsingNamedDecls(false) 50 { } 51 52 ~RemoveNamespace(void); 53 54 private: 55 56 typedef llvm::SmallPtrSet<const clang::NamespaceDecl *, 15> NamespaceDeclSet; 57 58 typedef llvm::SmallPtrSet<const clang::UsingDecl *, 10> UsingDeclSet; 59 60 typedef llvm::SmallPtrSet<const clang::UsingDirectiveDecl *, 10> 61 UsingDirectiveDeclSet; 62 63 typedef llvm::DenseMap<const clang::NamedDecl *, std::string> 64 NamedDeclToNameMap; 65 66 virtual void Initialize(clang::ASTContext &context); 67 68 virtual bool HandleTopLevelDecl(clang::DeclGroupRef D); 69 70 virtual void HandleTranslationUnit(clang::ASTContext &Ctx); 71 72 void addNamedDeclsFromNamespace(const clang::NamespaceDecl *ND); 73 74 bool handleOneNamespaceDecl(clang::NamespaceDecl *ND); 75 76 void removeNamespace(const clang::NamespaceDecl *ND); 77 78 void removeUsingOrUsingDirectiveDecl(const clang::Decl *D); 79 80 void handleOneNamedDecl(const clang::NamedDecl *ND, 81 const clang::DeclContext *ParentCtx, 82 const std::string &NamespaceName); 83 84 bool hasNameConflict(const clang::NamedDecl *ND, 85 const clang::DeclContext *ParentCtx); 86 87 bool isValidNamedDeclKind(const clang::NamedDecl *ND); 88 89 void handleOneEnumDecl(const clang::EnumDecl *ED, 90 const std::string &Prefix, 91 NamedDeclToNameMap &NameMap, 92 const clang::DeclContext *ParentCtx); 93 94 void handleOneUsingShadowDecl(const clang::UsingShadowDecl *UD, 95 const clang::DeclContext *ParentCtx); 96 97 void handleOneUsingDirectiveDecl(const clang::UsingDirectiveDecl *UD, 98 const clang::DeclContext *ParentCtx); 99 100 void rewriteNamedDecls(void); 101 102 bool getNewNameFromNameMap(const clang::NamedDecl *ND, 103 std::string &Name, 104 const NamedDeclToNameMap &NameMap); 105 106 bool getNewNameByNameFromNameMap(const std::string &Name, 107 std::string &NewName, 108 const NamedDeclToNameMap &NameMap); 109 110 bool getNewNamedDeclName(const clang::NamedDecl *ND, std::string &Name); 111 112 bool getNewUsingNamedDeclName(const clang::NamedDecl *ND, std::string &Name); 113 114 bool getNewName(const clang::NamedDecl *ND, std::string &Name); 115 116 bool getNewNameByName(const std::string &Name, std::string &NewName); 117 118 bool isGlobalNamespace(clang::NestedNameSpecifierLoc Loc); 119 120 bool isTheNamespaceSpecifier(const clang::NestedNameSpecifier *NNS); 121 122 void removeLastNamespaceFromUsingDecl(const clang::UsingDirectiveDecl *D, 123 const clang::NamespaceDecl *ND); 124 125 void replaceFirstNamespaceFromUsingDecl(const clang::UsingDirectiveDecl *D, 126 const std::string &Name); 127 128 bool isSuffix(std::string &Name, std::string &SpecifierName); 129 130 NamespaceDeclSet VisitedND; 131 132 UsingDeclSet UselessUsingDecls; 133 134 UsingDirectiveDeclSet UselessUsingDirectiveDecls; 135 136 // a mapping from NamedDecls in TheNamespaceDecl used in TheNamespaceDecl 137 // to their new names after TheNamespaceDecl is removed. This map only 138 // stores those NamedDecls which need to be renamed. 139 NamedDeclToNameMap NamedDeclToNewName; 140 141 // a mapping from NamedDecl in other namespaces used in TheNamespaceDecl 142 // to their new names after TheNamespaceDecl is removed. 143 NamedDeclToNameMap UsingNamedDeclToNewName; 144 145 RemoveNamespaceASTVisitor *CollectionVisitor; 146 147 RemoveNamespaceRewriteVisitor *RewriteVisitor; 148 149 clang::NamespaceDecl *TheNamespaceDecl; 150 151 const std::string NamePrefix; 152 153 // Prefix for anonymous namespaces 154 const std::string AnonNamePrefix; 155 156 unsigned AnonNamespaceCounter; 157 158 // a flag to indicate if we are working on renaming UsingNamedDecl 159 // The purpose of this flag is to avoid double visit. 160 // The RemoveNamespaceRewriteVisitor are used twice: 161 // * one for TheNamespaceDecl. In this case, we only rename UsingNamedDecls 162 // without doing any other work 163 // * another is for NamedDecls belonging to TheNamespaceDecl 164 bool isForUsingNamedDecls; 165 166 // Unimplemented 167 RemoveNamespace(void); 168 169 RemoveNamespace(const RemoveNamespace &); 170 171 void operator=(const RemoveNamespace &); 172 }; 173 #endif 174