Reduce string trashing in getQualifiedNameAsString.

llvm-svn: 102498
This commit is contained in:
Benjamin Kramer 2010-04-28 14:33:51 +00:00
parent d472c85285
commit d76b698ca6
1 changed files with 38 additions and 48 deletions

View File

@ -25,7 +25,6 @@
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/IdentifierTable.h"
#include "clang/Parse/DeclSpec.h" #include "clang/Parse/DeclSpec.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include <vector>
using namespace clang; using namespace clang;
@ -376,88 +375,79 @@ std::string NamedDecl::getQualifiedNameAsString() const {
} }
std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const { std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
// FIXME: Collect contexts, then accumulate names to avoid unnecessary
// std::string thrashing.
std::vector<std::string> Names;
std::string QualName;
const DeclContext *Ctx = getDeclContext(); const DeclContext *Ctx = getDeclContext();
if (Ctx->isFunctionOrMethod()) if (Ctx->isFunctionOrMethod())
return getNameAsString(); return getNameAsString();
while (Ctx) { typedef llvm::SmallVector<const DeclContext *, 8> ContextsTy;
ContextsTy Contexts;
// Collect contexts.
while (Ctx && isa<NamedDecl>(Ctx)) {
Contexts.push_back(Ctx);
Ctx = Ctx->getParent();
};
std::string QualName;
llvm::raw_string_ostream OS(QualName);
for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend();
I != E; ++I) {
if (const ClassTemplateSpecializationDecl *Spec if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) { = dyn_cast<ClassTemplateSpecializationDecl>(*I)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList( = TemplateSpecializationType::PrintTemplateArgumentList(
TemplateArgs.getFlatArgumentList(), TemplateArgs.getFlatArgumentList(),
TemplateArgs.flat_size(), TemplateArgs.flat_size(),
P); P);
Names.push_back(Spec->getIdentifier()->getNameStart() + TemplateArgsStr); OS << Spec->getName() << TemplateArgsStr;
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Ctx)) { } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
if (ND->isAnonymousNamespace()) if (ND->isAnonymousNamespace())
Names.push_back("<anonymous namespace>"); OS << "<anonymous namespace>";
else else
Names.push_back(ND->getNameAsString()); OS << ND;
} else if (const RecordDecl *RD = dyn_cast<RecordDecl>(Ctx)) { } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
if (!RD->getIdentifier()) { if (!RD->getIdentifier())
std::string RecordString = "<anonymous "; OS << "<anonymous " << RD->getKindName() << '>';
RecordString += RD->getKindName(); else
RecordString += ">"; OS << RD;
Names.push_back(RecordString); } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
} else {
Names.push_back(RD->getNameAsString());
}
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Ctx)) {
std::string Proto = FD->getNameAsString();
const FunctionProtoType *FT = 0; const FunctionProtoType *FT = 0;
if (FD->hasWrittenPrototype()) if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>()); FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
Proto += "("; OS << FD << '(';
if (FT) { if (FT) {
llvm::raw_string_ostream POut(Proto);
unsigned NumParams = FD->getNumParams(); unsigned NumParams = FD->getNumParams();
for (unsigned i = 0; i < NumParams; ++i) { for (unsigned i = 0; i < NumParams; ++i) {
if (i) if (i)
POut << ", "; OS << ", ";
std::string Param; std::string Param;
FD->getParamDecl(i)->getType().getAsStringInternal(Param, P); FD->getParamDecl(i)->getType().getAsStringInternal(Param, P);
POut << Param; OS << Param;
} }
if (FT->isVariadic()) { if (FT->isVariadic()) {
if (NumParams > 0) if (NumParams > 0)
POut << ", "; OS << ", ";
POut << "..."; OS << "...";
} }
} }
Proto += ")"; OS << ')';
} else {
Names.push_back(Proto); OS << cast<NamedDecl>(*I);
} else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx)) }
Names.push_back(ND->getNameAsString()); OS << "::";
else
break;
Ctx = Ctx->getParent();
} }
std::vector<std::string>::reverse_iterator
I = Names.rbegin(),
End = Names.rend();
for (; I!=End; ++I)
QualName += *I + "::";
if (getDeclName()) if (getDeclName())
QualName += getNameAsString(); OS << this;
else else
QualName += "<anonymous>"; OS << "<anonymous>";
return QualName; return OS.str();
} }
bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {