зеркало из https://github.com/microsoft/clang-1.git
Better support USRs for anonymous enums, structs, by including the location where
the tag was declared. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101403 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2ba6c81baa
Коммит
6f15395615
|
@ -14,9 +14,11 @@
|
|||
#include "CIndexer.h"
|
||||
#include "CXCursor.h"
|
||||
#include "clang/AST/DeclVisitor.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Lex/PreprocessingRecord.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::cxstring;
|
||||
|
||||
|
@ -48,6 +50,10 @@ public:
|
|||
void VisitTagDecl(TagDecl *D);
|
||||
void VisitTypedefDecl(TypedefDecl *D);
|
||||
|
||||
/// Generate the string component containing the location of the
|
||||
/// declaration.
|
||||
void GenLoc(const Decl *D);
|
||||
|
||||
/// String generation methods used both by the visitation methods
|
||||
/// and from other clients that want to directly generate USRs. These
|
||||
/// methods do not construct complete USRs (which incorporate the parents
|
||||
|
@ -198,6 +204,7 @@ void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
|
|||
}
|
||||
|
||||
void USRGenerator::VisitTagDecl(TagDecl *D) {
|
||||
D = D->getCanonicalDecl();
|
||||
VisitDeclContext(D->getDeclContext());
|
||||
switch (D->getTagKind()) {
|
||||
case TagDecl::TK_struct: Out << "@S^"; break;
|
||||
|
@ -206,7 +213,14 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
|
|||
case TagDecl::TK_enum: Out << "@E^"; break;
|
||||
}
|
||||
|
||||
// FIXME: Better support for anonymous structures and enums.
|
||||
// Add the location of the tag decl to handle resolution across
|
||||
// translation units.
|
||||
if (D->getLinkage() == NoLinkage) {
|
||||
GenLoc(D);
|
||||
if (IgnoreResults)
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string &s = D->getNameAsString();
|
||||
if (s.empty()) {
|
||||
if (TypedefDecl *TD = D->getTypedefForAnonDecl())
|
||||
|
@ -222,7 +236,31 @@ void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
|
|||
DeclContext *DC = D->getDeclContext();
|
||||
if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
|
||||
Visit(DCN);
|
||||
Out << "typedef@" << D->getName();
|
||||
Out << "typedef@";
|
||||
GenLoc(D);
|
||||
Out << D->getName();
|
||||
}
|
||||
|
||||
void USRGenerator::GenLoc(const Decl *D) {
|
||||
const SourceManager &SM = AU->getSourceManager();
|
||||
SourceLocation L = D->getLocStart();
|
||||
if (L.isInvalid()) {
|
||||
IgnoreResults = true;
|
||||
return;
|
||||
}
|
||||
L = SM.getInstantiationLoc(L);
|
||||
const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
|
||||
const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
|
||||
if (FE)
|
||||
Out << FE->getName();
|
||||
else {
|
||||
// This case really isn't interesting.
|
||||
IgnoreResults = true;
|
||||
return;
|
||||
}
|
||||
Out << SM.getLineNumber(Decomposed.first, Decomposed.second) << ':'
|
||||
<< SM.getColumnNumber(Decomposed.first, Decomposed.second)
|
||||
<< '^';
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -282,7 +320,8 @@ static CXString getDeclCursorUSR(const CXCursor &C) {
|
|||
// (e.g., the header). This is a little gross, but in principal
|
||||
// enums/anonymous structs/etc. defined in a common header file
|
||||
// are referred to across multiple translation units.
|
||||
if (isa<TagDecl>(ND))
|
||||
if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) ||
|
||||
isa<EnumConstantDecl>(ND))
|
||||
break;
|
||||
// Fall-through.
|
||||
case InternalLinkage:
|
||||
|
|
Загрузка…
Ссылка в новой задаче