- Fixed name mangling conditions to handle 'linkonce' linkage type. In

particular, name mangling for GlobalValues only occurs when the linkage type is
internal or when the name must be mangled to avoid a collision.  See comments in
CWriter::getValueName for more information.

- 'inline' keyword is now emitted for functions with 'linkonce' linkage type.

- Fixed typos.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6898 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Joel Stanley 2003-06-25 04:52:09 +00:00
parent 898e0e42e3
commit 54f6032dae
2 changed files with 88 additions and 60 deletions

View File

@ -165,11 +165,22 @@ static std::string makeNameProper(std::string x) {
std::string CWriter::getValueName(const Value *V) {
if (V->hasName()) { // Print out the label if it exists...
if (isa<GlobalValue>(V) && // Do not mangle globals...
(cast<GlobalValue>(V)->hasExternalLinkage() &&// Unless it's internal or
!MangledGlobals.count(V))) // Unless the name would collide if we don't
return makeNameProper(V->getName());
// Name mangling occurs as follows:
// - If V is not a global, mangling always occurs.
// - Otherwise, mangling occurs when any of the following are true:
// 1) V has internal linkage
// 2) V's name would collide if it is not mangled.
//
if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
// No internal linkage, name will not collide -> no mangling.
return makeNameProper(gv->getName());
}
}
// Non-global, or global with internal linkage / colliding name -> mangle.
return "l" + utostr(V->getType()->getUniqueID()) + "_" +
makeNameProper(V->getName());
}
@ -220,23 +231,23 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
switch (Ty->getPrimitiveID()) {
case Type::FunctionTyID: {
const FunctionType *MTy = cast<FunctionType>(Ty);
std::stringstream FunctionInards;
FunctionInards << " (" << NameSoFar << ") (";
std::stringstream FunctionInnards;
FunctionInnards << " (" << NameSoFar << ") (";
for (FunctionType::ParamTypes::const_iterator
I = MTy->getParamTypes().begin(),
E = MTy->getParamTypes().end(); I != E; ++I) {
if (I != MTy->getParamTypes().begin())
FunctionInards << ", ";
printType(FunctionInards, *I, "");
FunctionInnards << ", ";
printType(FunctionInnards, *I, "");
}
if (MTy->isVarArg()) {
if (!MTy->getParamTypes().empty())
FunctionInards << ", ...";
FunctionInnards << ", ...";
} else if (MTy->getParamTypes().empty()) {
FunctionInards << "void";
FunctionInnards << "void";
}
FunctionInards << ")";
std::string tstr = FunctionInards.str();
FunctionInnards << ")";
std::string tstr = FunctionInnards.str();
printType(Out, MTy->getReturnType(), tstr);
return Out;
}
@ -650,9 +661,9 @@ void CWriter::printModule(Module *M) {
Out << "extern void * malloc(size_t);\n\n";
}
// Output the global variable declerations
// Output the global variable declarations
if (!M->gempty()) {
Out << "\n\n/* Global Variable Declerations */\n";
Out << "\n\n/* Global Variable Declarations */\n";
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
if (!I->isExternal()) {
Out << "extern ";
@ -768,33 +779,36 @@ void CWriter::printContainedStructs(const Type *Ty,
void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// If the program provides it's own malloc prototype we don't need
// If the program provides its own malloc prototype we don't need
// to include the general one.
if (getValueName(F) == "malloc")
needsMalloc = false;
if (F->hasInternalLinkage()) Out << "static ";
if (F->hasLinkOnceLinkage()) Out << "inline ";
// Loop over the arguments, printing them...
const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
std::stringstream FunctionInards;
std::stringstream FunctionInnards;
// Print out the name...
FunctionInards << getValueName(F) << "(";
FunctionInnards << getValueName(F) << "(";
if (!F->isExternal()) {
if (!F->aempty()) {
std::string ArgName;
if (F->abegin()->hasName() || !Prototype)
ArgName = getValueName(F->abegin());
printType(FunctionInards, F->afront().getType(), ArgName);
printType(FunctionInnards, F->afront().getType(), ArgName);
for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
I != E; ++I) {
FunctionInards << ", ";
FunctionInnards << ", ";
if (I->hasName() || !Prototype)
ArgName = getValueName(I);
else
ArgName = "";
printType(FunctionInards, I->getType(), ArgName);
printType(FunctionInnards, I->getType(), ArgName);
}
}
} else {
@ -802,8 +816,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
for (FunctionType::ParamTypes::const_iterator I =
FT->getParamTypes().begin(),
E = FT->getParamTypes().end(); I != E; ++I) {
if (I != FT->getParamTypes().begin()) FunctionInards << ", ";
printType(FunctionInards, *I);
if (I != FT->getParamTypes().begin()) FunctionInnards << ", ";
printType(FunctionInnards, *I);
}
}
@ -811,12 +825,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// unless there are no known types, in which case, we just emit ().
//
if (FT->isVarArg() && !FT->getParamTypes().empty()) {
if (FT->getParamTypes().size()) FunctionInards << ", ";
FunctionInards << "..."; // Output varargs portion of signature!
if (FT->getParamTypes().size()) FunctionInnards << ", ";
FunctionInnards << "..."; // Output varargs portion of signature!
}
FunctionInards << ")";
FunctionInnards << ")";
// Print out the return type and the entire signature for that matter
printType(Out, F->getReturnType(), FunctionInards.str());
printType(Out, F->getReturnType(), FunctionInnards.str());
}

View File

@ -165,11 +165,22 @@ static std::string makeNameProper(std::string x) {
std::string CWriter::getValueName(const Value *V) {
if (V->hasName()) { // Print out the label if it exists...
if (isa<GlobalValue>(V) && // Do not mangle globals...
(cast<GlobalValue>(V)->hasExternalLinkage() &&// Unless it's internal or
!MangledGlobals.count(V))) // Unless the name would collide if we don't
return makeNameProper(V->getName());
// Name mangling occurs as follows:
// - If V is not a global, mangling always occurs.
// - Otherwise, mangling occurs when any of the following are true:
// 1) V has internal linkage
// 2) V's name would collide if it is not mangled.
//
if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
// No internal linkage, name will not collide -> no mangling.
return makeNameProper(gv->getName());
}
}
// Non-global, or global with internal linkage / colliding name -> mangle.
return "l" + utostr(V->getType()->getUniqueID()) + "_" +
makeNameProper(V->getName());
}
@ -220,23 +231,23 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
switch (Ty->getPrimitiveID()) {
case Type::FunctionTyID: {
const FunctionType *MTy = cast<FunctionType>(Ty);
std::stringstream FunctionInards;
FunctionInards << " (" << NameSoFar << ") (";
std::stringstream FunctionInnards;
FunctionInnards << " (" << NameSoFar << ") (";
for (FunctionType::ParamTypes::const_iterator
I = MTy->getParamTypes().begin(),
E = MTy->getParamTypes().end(); I != E; ++I) {
if (I != MTy->getParamTypes().begin())
FunctionInards << ", ";
printType(FunctionInards, *I, "");
FunctionInnards << ", ";
printType(FunctionInnards, *I, "");
}
if (MTy->isVarArg()) {
if (!MTy->getParamTypes().empty())
FunctionInards << ", ...";
FunctionInnards << ", ...";
} else if (MTy->getParamTypes().empty()) {
FunctionInards << "void";
FunctionInnards << "void";
}
FunctionInards << ")";
std::string tstr = FunctionInards.str();
FunctionInnards << ")";
std::string tstr = FunctionInnards.str();
printType(Out, MTy->getReturnType(), tstr);
return Out;
}
@ -650,9 +661,9 @@ void CWriter::printModule(Module *M) {
Out << "extern void * malloc(size_t);\n\n";
}
// Output the global variable declerations
// Output the global variable declarations
if (!M->gempty()) {
Out << "\n\n/* Global Variable Declerations */\n";
Out << "\n\n/* Global Variable Declarations */\n";
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
if (!I->isExternal()) {
Out << "extern ";
@ -768,33 +779,36 @@ void CWriter::printContainedStructs(const Type *Ty,
void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// If the program provides it's own malloc prototype we don't need
// If the program provides its own malloc prototype we don't need
// to include the general one.
if (getValueName(F) == "malloc")
needsMalloc = false;
if (F->hasInternalLinkage()) Out << "static ";
if (F->hasLinkOnceLinkage()) Out << "inline ";
// Loop over the arguments, printing them...
const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
std::stringstream FunctionInards;
std::stringstream FunctionInnards;
// Print out the name...
FunctionInards << getValueName(F) << "(";
FunctionInnards << getValueName(F) << "(";
if (!F->isExternal()) {
if (!F->aempty()) {
std::string ArgName;
if (F->abegin()->hasName() || !Prototype)
ArgName = getValueName(F->abegin());
printType(FunctionInards, F->afront().getType(), ArgName);
printType(FunctionInnards, F->afront().getType(), ArgName);
for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
I != E; ++I) {
FunctionInards << ", ";
FunctionInnards << ", ";
if (I->hasName() || !Prototype)
ArgName = getValueName(I);
else
ArgName = "";
printType(FunctionInards, I->getType(), ArgName);
printType(FunctionInnards, I->getType(), ArgName);
}
}
} else {
@ -802,8 +816,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
for (FunctionType::ParamTypes::const_iterator I =
FT->getParamTypes().begin(),
E = FT->getParamTypes().end(); I != E; ++I) {
if (I != FT->getParamTypes().begin()) FunctionInards << ", ";
printType(FunctionInards, *I);
if (I != FT->getParamTypes().begin()) FunctionInnards << ", ";
printType(FunctionInnards, *I);
}
}
@ -811,12 +825,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// unless there are no known types, in which case, we just emit ().
//
if (FT->isVarArg() && !FT->getParamTypes().empty()) {
if (FT->getParamTypes().size()) FunctionInards << ", ";
FunctionInards << "..."; // Output varargs portion of signature!
if (FT->getParamTypes().size()) FunctionInnards << ", ";
FunctionInnards << "..."; // Output varargs portion of signature!
}
FunctionInards << ")";
FunctionInnards << ")";
// Print out the return type and the entire signature for that matter
printType(Out, F->getReturnType(), FunctionInards.str());
printType(Out, F->getReturnType(), FunctionInnards.str());
}