зеркало из https://github.com/microsoft/clang-1.git
Reduce string trashing in getQualifiedNameAsString.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102498 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
8c757f9ea3
Коммит
68eebbb627
|
@ -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 {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче