Skip to content

Commit

Permalink
srcSlice now has an API-like thing similar to srcType's. It's rough, …
Browse files Browse the repository at this point in the history
…but it'll allow me to write tests for srcSlice, which was the entire point. It'll have to be improved upon someday.
  • Loading branch information
cnewman committed Oct 30, 2015
1 parent 2a61b83 commit 996caaa
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 18 deletions.
4 changes: 2 additions & 2 deletions src/cpp/srcSlice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void TestSlice(const FileFunctionVarMap& mp, srcSliceHandler handler){

void srcSliceToCsv(const srcSliceHandler& handler){
std::string str;
for(FileFunctionVarMap::const_iterator ffvmIt = handler.sysDict.dictionary.begin(); ffvmIt != handler.sysDict.dictionary.end(); ++ffvmIt){
for(FileFunctionVarMap::const_iterator ffvmIt = handler.sysDict.dictionary.ffvMap.begin(); ffvmIt != handler.sysDict.dictionary.ffvMap.end(); ++ffvmIt){
//auto fileNameIt = handler.sysDict.fileTable.find(ffvmIt->first);
//if(fileNameIt != handler.sysDict.fileTable.end())
for(FunctionVarMap::const_iterator fvmIt = ffvmIt->second.begin(); fvmIt != ffvmIt->second.end(); ++fvmIt){
Expand Down Expand Up @@ -184,7 +184,7 @@ int main(int argc, char * argv[]) {
srcSAXController control(argv[1]);
srcSliceHandler handler;
control.parse(&handler);
DoComputation(handler, handler.sysDict.dictionary);
DoComputation(handler, handler.sysDict.dictionary.ffvMap);
//t = clock() - t;
//std::cerr<<"Time is: "<<((float)t)/CLOCKS_PER_SEC<<std::endl;
//std::string filename = handler.sysDict.dictionary.find("stack.cpp.xml");
Expand Down
13 changes: 6 additions & 7 deletions src/cpp/srcSliceHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

#include <srcSliceHandler.hpp>
#include <Utility.hpp>

/**
*Find
*@param varName - Name of the variable whose slice profile we want
Expand All @@ -41,7 +40,6 @@ SliceProfile* srcSliceHandler::Find(const std::string& varName){
}
return nullptr;
}

/**
*ProcessConstructorDecl
*Processes decls of the form object(arg,arg)
Expand Down Expand Up @@ -254,8 +252,8 @@ void srcSliceHandler::ProcessDeclCtor(){
*/
void srcSliceHandler::ComputeInterprocedural(const std::string& f){

FileIt = sysDict.dictionary.find(f);
if(FileIt == sysDict.dictionary.end()){
FileIt = sysDict.dictionary.ffvMap.find(f);
if(FileIt == sysDict.dictionary.ffvMap.end()){
std::cerr<<"CAN'T FIND FILE"<<std::endl;
return;
}
Expand All @@ -265,11 +263,11 @@ void srcSliceHandler::ComputeInterprocedural(const std::string& f){

for(FunctionIt; FunctionIt != FunctionItEnd; ++FunctionIt){
for(VarMap::iterator it = FunctionIt->second.begin(); it != FunctionIt->second.end(); ++it){
if(it->second.visited == true){//std::unordered_set<NameLineNumberPair, NameLineNumberPairHash>::iterator - auto
if(it->second.visited == false){//std::unordered_set<NameLineNumberPair, NameLineNumberPairHash>::iterator - auto
for(auto itCF = it->second.cfunctions.begin(); itCF != it->second.cfunctions.end(); ++itCF ){
unsigned int argumentIndex = itCF->second;
SliceProfile Spi = ArgumentProfile(itCF->first, argumentIndex, it);
SetUnion(it->second.def, Spi.def);
//SetUnion(it->second.def, Spi.def); Also suspect this is wrong. Only want to do this if the rhs is an alias
SetUnion(it->second.use, Spi.use);
SetUnion(it->second.cfunctions, Spi.cfunctions);
SetUnion(it->second.dvars, Spi.dvars);
Expand All @@ -293,10 +291,11 @@ SliceProfile srcSliceHandler::ArgumentProfile(std::string fname, unsigned int pa
VarMap::iterator v = funcIt->second.begin();
for(VarMap::iterator it = v; it != funcIt->second.end(); ++it){
if (it->second.index == (parameterIndex)){
if(it->second.visited == true){
if(it->second.visited == false){
std::cerr<<"Variable: "<<it->second.variableName<<" "<<it->second.potentialAlias<<" END"<<std::endl;
if(it->second.potentialAlias){
it->second.aliases.insert(vIt->second.variableName);
SetUnion(vIt->second.def, it->second.def);//Only if it's an alias
}
Spi = it->second;
return Spi;
Expand Down
158 changes: 154 additions & 4 deletions src/headers/SliceProfile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,163 @@ class SliceProfile{



struct SystemDictionary{
//per file system dictionary
struct srcSlice{
struct SliceDictionary{
//context can be used to keep track of what function you're searching in. Makes searching faster because I assume you're using that function as the context
struct Context{
int ln;
std::string fileName;
std::string functionName;
FunctionVarMap::iterator currentFunc;
FileFunctionVarMap::iterator currentFile;
Context():fileName(""), functionName(""), ln(-1){}
bool IsSet() const {return (ln == -1 || functionName == "") ? false : true;}
Context(std::string file, std::string func, unsigned int line, FileFunctionVarMap::iterator fileIt, FunctionVarMap::iterator funcIt)
: fileName(file), functionName(func), ln(line), currentFile(fileIt), currentFunc(funcIt){}
};
Context currentContext;
FileFunctionVarMap ffvMap;
};
/*This is a map of file, function/method, and variables. {file, {function, {SliceProfiles}}}*/
FileFunctionVarMap dictionary;
VarMap globalMap;
SliceDictionary dictionary;

VarMap globalMap;
std::unordered_map<std::string, ClassProfile> classTable;
std::unordered_map<unsigned int, std::string> typeTable;
std::vector<std::pair<unsigned int, unsigned int>> controledges;

srcSlice(){}
srcSlice(const char*, const char*){}
srcSlice(std::string, const char*){}
srcSlice(FILE*, const char*){}
srcSlice(int, const char*){}
void ReadArchiveFile(std::string){}

int size()const {return dictionary.ffvMap.size();}

bool SetContext(std::string fle, std::string fn, int linenumber){
FileFunctionVarMap::iterator fleIt = dictionary.ffvMap.find(fle);
if(fleIt != dictionary.ffvMap.end()){
FunctionVarMap::iterator fnIt = fleIt->second.find(fn);
if(fnIt != fleIt->second.end()){
dictionary.currentContext.currentFile = fleIt;
dictionary.currentContext.currentFunc = fnIt;
dictionary.currentContext.ln = linenumber;
dictionary.currentContext.functionName = fle;
dictionary.currentContext.functionName = fn;
return true;
}
}
return false;
}

bool SetContext(std::string fn, int linenumber){
if(dictionary.currentContext.currentFile != dictionary.ffvMap.end()){
FunctionVarMap::iterator fnIt = dictionary.currentContext.currentFile->second.find(fn);
if(fnIt != dictionary.currentContext.currentFile->second.end()){
dictionary.currentContext.currentFunc = fnIt;
dictionary.currentContext.ln = linenumber;
dictionary.currentContext.functionName = fn;
return true;
}
}
return false;
}
bool SetContext(int linenumber){ //it enough to just check function? Need to check file?
if(dictionary.currentContext.currentFunc != dictionary.currentContext.currentFile->second.end()){
dictionary.currentContext.ln = linenumber;
return true;
}
return false;
}
//Definition of find that assumes the user didn't give a context (They should just give a context, though, tbh).
std::pair<bool, SliceProfile> Find(std::string flename, std::string funcname, std::string varname, int lineNumber)const{
FileFunctionVarMap::const_iterator ffvmIt = dictionary.ffvMap.find(flename);
if(ffvmIt != dictionary.ffvMap.end()){
FunctionVarMap::const_iterator fvmIt = ffvmIt->second.find(funcname);
if(fvmIt != ffvmIt->second.end()){
VarMap::const_iterator vtmIt = fvmIt->second.find(varname);
if(vtmIt != fvmIt->second.end()){
return std::make_pair(true, vtmIt->second);
}
}
}

return std::make_pair(false, SliceProfile());
}
//Definition of find that assumes the user didn't give a context (They should just give a context, though, tbh).
std::pair<bool, SliceProfile> Find(std::string funcname, std::string varname, int lineNumber)const{
FunctionVarMap::const_iterator fvmIt = dictionary.currentContext.currentFile->second.find(funcname);
if(fvmIt != dictionary.currentContext.currentFile->second.end()){
VarMap::const_iterator vtmIt = fvmIt->second.find(varname);
if(vtmIt != fvmIt->second.end()){
return std::make_pair(true, vtmIt->second);
}
}
return std::make_pair(false, SliceProfile());
}
//Definition of find that uses the context (so it doesn't need to take a function name as context)
std::pair<bool, SliceProfile> Find(std::string varname) const{
if(!dictionary.currentContext.IsSet()){
throw std::runtime_error("Context not set"); //for now, std exception
}else{
VarMap::const_iterator it = dictionary.currentContext.currentFunc->second.find(varname);
if(it != dictionary.currentContext.currentFunc->second.end()){
return std::make_pair(true, it->second);
}
return std::make_pair(false, SliceProfile());
}
}
bool Insert(std::string flename, std::string funcname, const SliceProfile& np){
FileFunctionVarMap::iterator ffvmIt = dictionary.ffvMap.find(flename);
if(ffvmIt != dictionary.ffvMap.end()){
FunctionVarMap::iterator fvmIt = ffvmIt->second.find(funcname);
if(fvmIt != ffvmIt->second.end()){
VarMap::iterator vtmIt = fvmIt->second.find(np.variableName);
if(vtmIt != fvmIt->second.end()){
vtmIt->second = np;
return true;
}else{
fvmIt->second.insert(std::make_pair(np.variableName, np));
return true;
}
}
}
return false;
}

bool Insert(std::string funcname, const SliceProfile& np){
if(dictionary.currentContext.currentFile != dictionary.ffvMap.end()){
FunctionVarMap::iterator fvmIt = dictionary.currentContext.currentFile->second.find(funcname);
if(fvmIt != dictionary.currentContext.currentFile->second.end()){
VarMap::iterator vtmIt = fvmIt->second.find(np.variableName);
if(vtmIt != fvmIt->second.end()){
vtmIt->second = np;
return true;
}else{
fvmIt->second.insert(std::make_pair(np.variableName, np));
return true;
}
}
}
return false;
}

bool Insert(const SliceProfile& np){
if(dictionary.currentContext.ln == -1){ //TODO: Make better
throw std::runtime_error("Context not set"); //for now, std exception
}else{
auto it = dictionary.currentContext.currentFunc->second.find(np.variableName);
if(it != dictionary.currentContext.currentFunc->second.end()){
it->second = np;
return true;
}else{
dictionary.currentContext.currentFunc->second.insert(std::make_pair(np.variableName, np));
return true;
}
}
return false;
}

};
#endif
10 changes: 5 additions & 5 deletions src/headers/srcSliceHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class srcSliceHandler : public srcSAXHandler {
/*keeps track of which functioni has been called. Useful for when argument slice profiles need to be updated*/
std::stack<std::string> nameOfCurrentClldFcn;
std::stack<unsigned int> controlFlowLineNum;

/*These two iterators keep track of where we are inside of the system dictionary. They're primarily so that
*there's no need to do any nasty map.finds on the dictionary (since it's a nested map of maps). These must
*be updated as the file is parsed*/
Expand Down Expand Up @@ -144,12 +145,11 @@ class srcSliceHandler : public srcSAXHandler {
void ProcessConstructorDecl();
void GetFunctionDeclData();

SliceProfile* Find(const std::string&);
SliceProfile ArgumentProfile(std::string, unsigned int, VarMap::iterator);

SliceProfile* Find(const std::string& varName);
public:
void ComputeInterprocedural(const std::string&);
SystemDictionary sysDict;
srcSlice sysDict;
unsigned int lineNum;
srcSliceHandler(){
fileNumber = 0;
Expand Down Expand Up @@ -695,7 +695,7 @@ class srcSliceHandler : public srcSAXHandler {
int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes,
const struct srcsax_attribute * attributes) {
//fileNumber = functionNameHash(attributes[1].value);
FileIt = sysDict.dictionary.insert(std::make_pair(std::string(attributes[2].value), FunctionVarMap())).first; //insert and keep track of most recent.
FileIt = sysDict.dictionary.ffvMap.insert(std::make_pair(std::string(attributes[2].value), FunctionVarMap())).first; //insert and keep track of most recent.
//std::cerr<<"val: "<<attributes[1].value<<std::endl;exit(1);
//classIt = sysDict.classTable.insert(std::make_pair("GLOBAL", ClassProfile())).first;
FunctionIt = FileIt->second.insert(std::make_pair("GLOBAL", VarMap())).first; //for globals. Makes a bad assumption about where globals are. Fix.
Expand Down Expand Up @@ -800,7 +800,7 @@ class srcSliceHandler : public srcSAXHandler {
if(!sawgeneric && (triggerField[name]) && triggerField[decl_stmt] && triggerField[argument_list] && triggerField[decl] && !(triggerField[op] || triggerField[index] || triggerField[preproc] || triggerField[type] || triggerField[macro])) {
currentDeclCtor.first.append(ch,len);
}
//This only handles expr statments of the form a = b. Anything without = in it is skipped here
//This only handles expr statments of the form a = b. Anything without = in it is skipped here -- Not entirely true anymore
if((triggerField[name] || triggerField[op]) && triggerField[expr] && triggerField[expr_stmt] && !(triggerField[index] || triggerField[preproc])){
std::string str = std::string(ch, len);
if(str.back() == '='){
Expand Down

0 comments on commit 996caaa

Please sign in to comment.