forked from OSchip/llvm-project
96 lines
3.3 KiB
C++
96 lines
3.3 KiB
C++
//===-- LoopConvert/VariableNaming.cpp - Gererate variable names ----------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// \brief This file contains the definitino of the VariableNamer class, which
|
|
/// is responsible for generating new variable names and ensuring that they do
|
|
/// not conflict with existing ones.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "VariableNaming.h"
|
|
|
|
using namespace llvm;
|
|
using namespace clang;
|
|
|
|
std::string VariableNamer::createIndexName() {
|
|
// FIXME: Add in naming conventions to handle:
|
|
// - Uppercase/lowercase indices
|
|
// - How to handle conflicts
|
|
// - An interactive process for naming
|
|
std::string IteratorName;
|
|
std::string ContainerName;
|
|
if (TheContainer)
|
|
ContainerName = TheContainer->getName().str();
|
|
|
|
size_t Len = ContainerName.length();
|
|
if (Len > 1 && ContainerName[Len - 1] == 's')
|
|
IteratorName = ContainerName.substr(0, Len - 1);
|
|
else
|
|
IteratorName = "elem";
|
|
|
|
if (!declarationExists(IteratorName))
|
|
return IteratorName;
|
|
|
|
IteratorName = ContainerName + "_" + OldIndex->getName().str();
|
|
if (!declarationExists(IteratorName))
|
|
return IteratorName;
|
|
|
|
IteratorName = ContainerName + "_elem";
|
|
if (!declarationExists(IteratorName))
|
|
return IteratorName;
|
|
|
|
IteratorName += "_elem";
|
|
if (!declarationExists(IteratorName))
|
|
return IteratorName;
|
|
|
|
IteratorName = "_elem_";
|
|
|
|
// Someone defeated my naming scheme...
|
|
while (declarationExists(IteratorName))
|
|
IteratorName += "i";
|
|
return IteratorName;
|
|
}
|
|
|
|
/// \brief Determines whether or not the the name \a Symbol conflicts with
|
|
/// language keywords or defined macros. Also checks if the name exists in
|
|
/// LoopContext, any of its parent contexts, or any of its child statements.
|
|
///
|
|
/// We also check to see if the same identifier was generated by this loop
|
|
/// converter in a loop nested within SourceStmt.
|
|
bool VariableNamer::declarationExists(StringRef Symbol) {
|
|
assert(Context != nullptr && "Expected an ASTContext");
|
|
IdentifierInfo &Ident = Context->Idents.get(Symbol);
|
|
|
|
// Check if the symbol is not an identifier (ie. is a keyword or alias).
|
|
if (!isAnyIdentifier(Ident.getTokenID()))
|
|
return true;
|
|
|
|
// Check for conflicting macro definitions.
|
|
if (Ident.hasMacroDefinition())
|
|
return true;
|
|
|
|
// Determine if the symbol was generated in a parent context.
|
|
for (const Stmt *S = SourceStmt; S != nullptr; S = ReverseAST->lookup(S)) {
|
|
StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(S);
|
|
if (I != GeneratedDecls->end() && I->second == Symbol)
|
|
return true;
|
|
}
|
|
|
|
// FIXME: Rather than detecting conflicts at their usages, we should check the
|
|
// parent context.
|
|
// For some reason, lookup() always returns the pair (NULL, NULL) because its
|
|
// StoredDeclsMap is not initialized (i.e. LookupPtr.getInt() is false inside
|
|
// of DeclContext::lookup()). Why is this?
|
|
|
|
// Finally, determine if the symbol was used in the loop or a child context.
|
|
DeclFinderASTVisitor DeclFinder(Symbol, GeneratedDecls);
|
|
return DeclFinder.findUsages(SourceStmt);
|
|
}
|