eb9f95544ce1d8b9709341a76ce5abb579cb06e4
[lldb.git] / clang-tools-extra / loop-convert / VariableNaming.cpp
1 #include "VariableNaming.h"
2
3 namespace clang {
4 namespace loop_migrate {
5
6 std::string VariableNamer::createIndexName() {
7   // FIXME: Add in naming conventions to handle:
8   //  - Uppercase/lowercase indices
9   //  - How to handle conflicts
10   //  - An interactive process for naming
11   std::string IteratorName;
12   std::string ContainerName;
13   if (TheContainer)
14     ContainerName = TheContainer->getName().str();
15
16   size_t Len = ContainerName.length();
17   if (Len > 1 && ContainerName[Len - 1] == 's')
18     IteratorName = ContainerName.substr(0, Len - 1);
19   else
20     IteratorName = "elem";
21
22   // FIXME: Maybe create a class so that this call doesn't need 6 parameters
23   // every time?
24   if (!declarationExists(IteratorName))
25     return IteratorName;
26
27   IteratorName = ContainerName + "_" + OldIndex->getName().str();
28   if (!declarationExists(IteratorName))
29     return IteratorName;
30
31   IteratorName = ContainerName + "_elem";
32   if (!declarationExists(IteratorName))
33     return IteratorName;
34
35   IteratorName += "_elem";
36   if (!declarationExists(IteratorName))
37     return IteratorName;
38
39   IteratorName = "_elem_";
40
41   // Someone defeated my naming scheme...
42   while (declarationExists(IteratorName))
43     IteratorName += "i";
44   return IteratorName;
45 }
46
47 /// \brief Determines whether or not the the name Symbol exists in LoopContext,
48 /// any of its parent contexts, or any of its child statements.
49 ///
50 /// We also check to see if the same identifier was generated by this loop
51 /// converter in a loop nested within SourceStmt.
52 bool VariableNamer::declarationExists(const std::string& Symbol) {
53   IdentifierInfo& Identifier = Context->Idents.get(Symbol);
54   DeclarationName Name =
55       Context->DeclarationNames.getIdentifier(&Identifier);
56
57   // First, let's check the parent context.
58   // FIXME: lookup() always returns the pair (NULL, NULL) because its
59   // StoredDeclsMap is not initialized (i.e. LookupPtr.getInt() is false inside
60   // of DeclContext::lookup()). Why is this?
61   // NOTE: We work around this by checking when a shadowed declaration is
62   // referenced, rather than now.
63   for (const DeclContext *CurrContext = LoopContext; CurrContext != NULL;
64        CurrContext = CurrContext->getLookupParent()) {
65     DeclContext::lookup_const_result Result = CurrContext->lookup(Name);
66     if (Result.first != Result.second)
67         return true;
68   }
69
70   // Determine if the symbol was generated in a parent context.
71   for (const Stmt *S = SourceStmt; S != NULL; S = ReverseAST->lookup(S)) {
72     StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(S);
73     if (I != GeneratedDecls->end() && I->second == Symbol)
74       return true;
75   }
76
77   // Finally, determine if the symbol was used in the loop or a child context.
78   DeclFinderASTVisitor DeclFinder(Symbol, GeneratedDecls);
79   return DeclFinder.findUsages(SourceStmt);
80 }
81
82 } // namespace loop_migrate
83 } // namespace clang