aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-01-03 23:43:55 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-01-03 23:43:55 +0000
commite8fc2f97ccb7606822503e6d551e39b1529c8cdf (patch)
tree3a7dd41309d4cc4bf3cfac259f6770e1da9a0de3
parentfcf17a30961ac3dfee893c323f7b9ae5fe012957 (diff)
Finish implementation of variable renaming to handle collapsed type planes
by correctly handling up references and enumerated types. Previously there was some confusion of these two. Thanks to Chris Lattner for demistifying llvm up references. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32846 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--tools/llvm-upgrade/UpgradeParser.y106
1 files changed, 71 insertions, 35 deletions
diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y
index 09642661fd..f5e119da49 100644
--- a/tools/llvm-upgrade/UpgradeParser.y
+++ b/tools/llvm-upgrade/UpgradeParser.y
@@ -78,24 +78,26 @@ void UpgradeAssembly(const std::string &infile, std::istream& in,
TypeInfo* ResolveType(TypeInfo*& Ty) {
if (Ty->isUnresolved()) {
- TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
- if (I != NamedTypes.end()) {
- Ty = I->second.clone();
- return Ty;
- } else {
- std::string msg("Cannot resolve type: ");
- msg += Ty->getNewTy();
- yyerror(msg.c_str());
- }
- } else if (Ty->isNumeric()) {
- unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // Skip the '\\'
- if (ref < EnumeratedTypes.size()) {
- Ty = EnumeratedTypes[ref].clone();
- return Ty;
+ if (Ty->getNewTy()[0] == '%' && isdigit(Ty->getNewTy()[1])) {
+ unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the %
+ if (ref < EnumeratedTypes.size()) {
+ Ty = &EnumeratedTypes[ref];
+ return Ty;
+ } else {
+ std::string msg("Can't resolve numbered type: ");
+ msg += Ty->getNewTy();
+ yyerror(msg.c_str());
+ }
} else {
- std::string msg("Can't resolve type: ");
- msg += Ty->getNewTy();
- yyerror(msg.c_str());
+ TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
+ if (I != NamedTypes.end()) {
+ Ty = &I->second;
+ return Ty;
+ } else {
+ std::string msg("Cannot resolve type: ");
+ msg += Ty->getNewTy();
+ yyerror(msg.c_str());
+ }
}
}
// otherwise its already resolved.
@@ -293,18 +295,35 @@ static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) {
return PFTy->clone();
}
+typedef std::vector<TypeInfo*> UpRefStack;
+static TypeInfo* ResolveUpReference(TypeInfo* Ty, UpRefStack* stack) {
+ assert(Ty->isUpReference() && "Can't resolve a non-upreference");
+ unsigned upref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the slash
+ assert(upref < stack->size() && "Invalid up reference");
+ return (*stack)[upref - stack->size() - 1];
+}
+
static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) {
- ResolveType(PTy);
+ TypeInfo* Result = ResolveType(PTy);
assert(PTy->isPointer() && "GEP Operand is not a pointer?");
- TypeInfo* Result = PTy->getElementType(); // just skip first index
- ResolveType(Result);
- for (unsigned i = 1; i < idxs->size(); ++i) {
+ UpRefStack stack;
+ for (unsigned i = 0; i < idxs->size(); ++i) {
if (Result->isComposite()) {
Result = Result->getIndexedType((*idxs)[i]);
ResolveType(Result);
+ stack.push_back(Result);
} else
yyerror("Invalid type for index");
}
+ // Resolve upreferences so we can return a more natural type
+ if (Result->isPointer()) {
+ if (Result->getElementType()->isUpReference()) {
+ stack.push_back(Result);
+ Result = ResolveUpReference(Result->getElementType(), &stack);
+ }
+ } else if (Result->isUpReference()) {
+ Result = ResolveUpReference(Result->getElementType(), &stack);
+ }
return Result->getPointerType();
}
@@ -335,17 +354,41 @@ static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) {
// Resolve the type
ResolveType(Ty);
+ // Remove as many levels of pointer nesting that we have.
+ if (Ty->isPointer()) {
+ // Avoid infinite loops in recursive types
+ TypeInfo* Last = 0;
+ while (Ty->isPointer() && Last != Ty) {
+ Last = Ty;
+ Ty = Ty->getElementType();
+ ResolveType(Ty);
+ }
+ }
+
// Default the result to the current name
std::string Result = *Name;
+ // Now deal with the underlying type
if (Ty->isInteger()) {
// If its an integer type, make the name unique
Result = makeUniqueName(Name, Ty->isSigned());
- } else if (Ty->isPointer()) {
- while (Ty->isPointer())
- Ty = Ty->getElementType();
+ } else if (Ty->isArray() || Ty->isPacked()) {
+ Ty = Ty->getElementType();
if (Ty->isInteger())
Result = makeUniqueName(Name, Ty->isSigned());
+ } else if (Ty->isStruct()) {
+ // Scan the fields and count the signed and unsigned fields
+ int isSigned = 0;
+ for (unsigned i = 0; i < Ty->getNumStructElements(); ++i) {
+ TypeInfo* Tmp = Ty->getElement(i);
+ if (Tmp->isInteger())
+ if (Tmp->isSigned())
+ isSigned++;
+ else
+ isSigned--;
+ }
+ if (isSigned != 0)
+ Result = makeUniqueName(Name, isSigned > 0);
}
return Result;
}
@@ -536,7 +579,7 @@ UpRTypes
}
| '\\' EUINT64VAL { // Type UpReference
$2->insert(0, "\\");
- $$ = new TypeInfo($2, NumericTy);
+ $$ = new TypeInfo($2, UpRefTy);
}
| UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
std::string newTy( $1->getNewTy() + "(");
@@ -550,21 +593,18 @@ UpRTypes
}
newTy += ")";
$$ = new TypeInfo(new std::string(newTy), $1, $3);
- EnumeratedTypes.push_back(*$$);
}
| '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
$2->insert(0,"[ ");
*$2 += " x " + $4->getNewTy() + " ]";
uint64_t elems = atoi($2->c_str());
$$ = new TypeInfo($2, ArrayTy, $4, elems);
- EnumeratedTypes.push_back(*$$);
}
| '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
$2->insert(0,"< ");
*$2 += " x " + $4->getNewTy() + " >";
uint64_t elems = atoi($2->c_str());
$$ = new TypeInfo($2, PackedTy, $4, elems);
- EnumeratedTypes.push_back(*$$);
}
| '{' TypeListI '}' { // Structure type?
std::string newTy("{");
@@ -575,11 +615,9 @@ UpRTypes
}
newTy += "}";
$$ = new TypeInfo(new std::string(newTy), StructTy, $2);
- EnumeratedTypes.push_back(*$$);
}
| '{' '}' { // Empty structure type?
$$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList());
- EnumeratedTypes.push_back(*$$);
}
| '<' '{' TypeListI '}' '>' { // Packed Structure type?
std::string newTy("<{");
@@ -590,15 +628,12 @@ UpRTypes
}
newTy += "}>";
$$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3);
- EnumeratedTypes.push_back(*$$);
}
| '<' '{' '}' '>' { // Empty packed structure type?
$$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList());
- EnumeratedTypes.push_back(*$$);
}
| UpRTypes '*' { // Pointer type?
$$ = $1->getPointerType();
- EnumeratedTypes.push_back(*$$);
};
// TypeList - Used for struct declarations and as a basis for function type
@@ -745,7 +780,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
$$ = new std::string(*$1);
*$$ += "( " + source + " to " + $5->getNewTy() + ")";
}
- delete $1; $3.destroy(); delete $4; delete $5;
+ delete $1; $3.destroy(); delete $4;
}
| GETELEMENTPTR '(' ConstVal IndexList ')' {
*$1 += "(" + *$3.cnst;
@@ -1129,6 +1164,7 @@ ValueRef
// type immediately preceeds the value reference, and allows complex constant
// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
ResolvedVal : Types ValueRef {
+ ResolveType($1);
std::string Name = getUniqueName($2.val, $1);
$$ = $2;
delete $$.val;
@@ -1414,7 +1450,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
*$1 += " " + *$2.val + ", " + *$4.val;
$$.val = $1;
ResolveType($2.type);
- $$.type = $2.type->getElementType()->clone();
+ $$.type = $2.type->getElementType();
delete $2.val; $4.destroy();
}
| INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {