blob: f3fc9bf1d2121311ac8fe041cf6b310f4425ce90 [file] [log] [blame]
Edwin Vanedde168b2013-01-04 18:25:18 +00001//===-- LoopConvert/VariableNaming.h - Gererate variable names --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file contains the definitino of the VariableNamer class, which
12/// is responsible for generating new variable names and ensuring that they do
13/// not conflict with existing ones.
14///
15//===----------------------------------------------------------------------===//
16#include "VariableNaming.h"
17
18using namespace llvm;
19using namespace clang;
20
21std::string VariableNamer::createIndexName() {
22 // FIXME: Add in naming conventions to handle:
23 // - Uppercase/lowercase indices
24 // - How to handle conflicts
25 // - An interactive process for naming
26 std::string IteratorName;
27 std::string ContainerName;
28 if (TheContainer)
29 ContainerName = TheContainer->getName().str();
30
31 size_t Len = ContainerName.length();
32 if (Len > 1 && ContainerName[Len - 1] == 's')
33 IteratorName = ContainerName.substr(0, Len - 1);
34 else
35 IteratorName = "elem";
36
37 if (!declarationExists(IteratorName))
38 return IteratorName;
39
40 IteratorName = ContainerName + "_" + OldIndex->getName().str();
41 if (!declarationExists(IteratorName))
42 return IteratorName;
43
44 IteratorName = ContainerName + "_elem";
45 if (!declarationExists(IteratorName))
46 return IteratorName;
47
48 IteratorName += "_elem";
49 if (!declarationExists(IteratorName))
50 return IteratorName;
51
52 IteratorName = "_elem_";
53
54 // Someone defeated my naming scheme...
55 while (declarationExists(IteratorName))
56 IteratorName += "i";
57 return IteratorName;
58}
59
60/// \brief Determines whether or not the the name Symbol exists in LoopContext,
61/// any of its parent contexts, or any of its child statements.
62///
63/// We also check to see if the same identifier was generated by this loop
64/// converter in a loop nested within SourceStmt.
65bool VariableNamer::declarationExists(const StringRef Symbol) {
66 // Determine if the symbol was generated in a parent context.
67 for (const Stmt *S = SourceStmt; S != NULL; S = ReverseAST->lookup(S)) {
68 StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(S);
69 if (I != GeneratedDecls->end() && I->second == Symbol)
70 return true;
71 }
72
73 // FIXME: Rather than detecting conflicts at their usages, we should check the
74 // parent context.
75 // For some reason, lookup() always returns the pair (NULL, NULL) because its
76 // StoredDeclsMap is not initialized (i.e. LookupPtr.getInt() is false inside
77 // of DeclContext::lookup()). Why is this?
78
79 // Finally, determine if the symbol was used in the loop or a child context.
80 DeclFinderASTVisitor DeclFinder(Symbol, GeneratedDecls);
81 return DeclFinder.findUsages(SourceStmt);
82}