mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-03 16:13:44 +00:00
libclang/libIndex: USR generation: mangle source location into USRs for macros,
unless the macro comes from a system header llvm-svn: 205064
This commit is contained in:
parent
57ba0b228d
commit
237769ede5
@ -14,7 +14,9 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace clang {
|
||||
class Decl;
|
||||
class Decl;
|
||||
class MacroDefinition;
|
||||
class SourceManager;
|
||||
|
||||
namespace index {
|
||||
|
||||
@ -22,7 +24,7 @@ static inline StringRef getUSRSpacePrefix() {
|
||||
return "c:";
|
||||
}
|
||||
|
||||
/// \brief Generate a USR for a Decl, including the prefix.
|
||||
/// \brief Generate a USR for a Decl, including the USR prefix.
|
||||
/// \returns true if the results should be ignored, false otherwise.
|
||||
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
|
||||
|
||||
@ -47,6 +49,12 @@ void generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS);
|
||||
/// \brief Generate a USR fragment for an Objective-C protocol.
|
||||
void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
|
||||
|
||||
/// \brief Generate a USR for a macro, including the USR prefix.
|
||||
///
|
||||
/// \returns true on error, false on success.
|
||||
bool generateUSRForMacro(const MacroDefinition *MD, const SourceManager &SM,
|
||||
SmallVectorImpl<char> &Buf);
|
||||
|
||||
} // namespace index
|
||||
} // namespace clang
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/DeclVisitor.h"
|
||||
#include "clang/Lex/PreprocessingRecord.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -22,6 +23,30 @@ using namespace clang::index;
|
||||
// USR generation.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// \returns true on error.
|
||||
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
|
||||
const SourceManager &SM, bool IncludeOffset) {
|
||||
if (Loc.isInvalid()) {
|
||||
return true;
|
||||
}
|
||||
Loc = SM.getExpansionLoc(Loc);
|
||||
const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
|
||||
const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
|
||||
if (FE) {
|
||||
OS << llvm::sys::path::filename(FE->getName());
|
||||
} else {
|
||||
// This case really isn't interesting.
|
||||
return true;
|
||||
}
|
||||
if (IncludeOffset) {
|
||||
// Use the offest into the FileID to represent the location. Using
|
||||
// a line/column can cause us to look back at the original source file,
|
||||
// which is expensive.
|
||||
OS << '@' << Decomposed.second;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class USRGenerator : public ConstDeclVisitor<USRGenerator> {
|
||||
SmallVectorImpl<char> &Buf;
|
||||
@ -465,7 +490,7 @@ bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
|
||||
if (generatedLoc)
|
||||
return IgnoreResults;
|
||||
generatedLoc = true;
|
||||
|
||||
|
||||
// Guard against null declarations in invalid code.
|
||||
if (!D) {
|
||||
IgnoreResults = true;
|
||||
@ -475,29 +500,10 @@ bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
|
||||
// Use the location of canonical decl.
|
||||
D = D->getCanonicalDecl();
|
||||
|
||||
const SourceManager &SM = Context->getSourceManager();
|
||||
SourceLocation L = D->getLocStart();
|
||||
if (L.isInvalid()) {
|
||||
IgnoreResults = true;
|
||||
return true;
|
||||
}
|
||||
L = SM.getExpansionLoc(L);
|
||||
const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
|
||||
const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
|
||||
if (FE) {
|
||||
Out << llvm::sys::path::filename(FE->getName());
|
||||
}
|
||||
else {
|
||||
// This case really isn't interesting.
|
||||
IgnoreResults = true;
|
||||
return true;
|
||||
}
|
||||
if (IncludeOffset) {
|
||||
// Use the offest into the FileID to represent the location. Using
|
||||
// a line/column can cause us to look back at the original source file,
|
||||
// which is expensive.
|
||||
Out << '@' << Decomposed.second;
|
||||
}
|
||||
IgnoreResults =
|
||||
IgnoreResults || printLoc(Out, D->getLocStart(),
|
||||
Context->getSourceManager(), IncludeOffset);
|
||||
|
||||
return IgnoreResults;
|
||||
}
|
||||
|
||||
@ -799,3 +805,26 @@ bool clang::index::generateUSRForDecl(const Decl *D,
|
||||
UG.Visit(D);
|
||||
return UG.ignoreResults();
|
||||
}
|
||||
|
||||
bool clang::index::generateUSRForMacro(const MacroDefinition *MD,
|
||||
const SourceManager &SM,
|
||||
SmallVectorImpl<char> &Buf) {
|
||||
// Don't generate USRs for things with invalid locations.
|
||||
if (!MD || MD->getLocation().isInvalid())
|
||||
return true;
|
||||
|
||||
llvm::raw_svector_ostream Out(Buf);
|
||||
|
||||
// Assume that system headers are sane. Don't put source location
|
||||
// information into the USR if the macro comes from a system header.
|
||||
SourceLocation Loc = MD->getLocation();
|
||||
bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);
|
||||
|
||||
Out << getUSRSpacePrefix();
|
||||
if (ShouldGenerateLocation)
|
||||
printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
|
||||
Out << "@macro@";
|
||||
Out << MD->getName()->getNameStart();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
1
clang/test/Index/Inputs/usrs-system.h
Normal file
1
clang/test/Index/Inputs/usrs-system.h
Normal file
@ -0,0 +1 @@
|
||||
#define MACRO_FROM_SYSTEM_HEADER_1 meow
|
@ -89,7 +89,24 @@ int test_multi_declaration(void) {
|
||||
-(int)methodWithFn:(void (*)(int *p))fn;
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s | FileCheck %s
|
||||
#include <usrs-system.h>
|
||||
|
||||
#define MACRO1 123
|
||||
|
||||
#define MACRO2 123
|
||||
#undef MACRO2
|
||||
#define MACRO2 789
|
||||
|
||||
#define MACRO3(X) 123, X
|
||||
#define MACRO3(X) 789, X
|
||||
|
||||
// RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s -isystem %S/Inputs | FileCheck %s
|
||||
// CHECK: usrs-system.h c:@macro@MACRO_FROM_SYSTEM_HEADER_1 Extent=[1:9 - 1:40]
|
||||
// CHECK: usrs.m c:usrs.m@1265@macro@MACRO1 Extent=[94:9 - 94:19]
|
||||
// CHECK: usrs.m c:usrs.m@1285@macro@MACRO2 Extent=[96:9 - 96:19]
|
||||
// CHECK: usrs.m c:usrs.m@1318@macro@MACRO2 Extent=[98:9 - 98:19]
|
||||
// CHECK: usrs.m c:usrs.m@1338@macro@MACRO3 Extent=[100:9 - 100:25]
|
||||
// CHECK: usrs.m c:usrs.m@1363@macro@MACRO3 Extent=[101:9 - 101:25]
|
||||
// CHECK: usrs.m c:usrs.m@F@my_helper Extent=[3:1 - 3:60]
|
||||
// CHECK: usrs.m c:usrs.m@95@F@my_helper@x Extent=[3:29 - 3:34]
|
||||
// CHECK: usrs.m c:usrs.m@102@F@my_helper@y Extent=[3:36 - 3:41]
|
||||
@ -153,7 +170,13 @@ int test_multi_declaration(void) {
|
||||
// CHECK: usrs.m c:objc(cs)CWithExt2(im)pro_ext Extent=[88:23 - 88:30]
|
||||
// CHECK: usrs.m c:objc(cs)CWithExt2(im)setPro_ext: Extent=[88:23 - 88:30]
|
||||
|
||||
// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-source %s
|
||||
// RUN: c-index-test -test-load-source all %s -isystem %S/Inputs | FileCheck -check-prefix=CHECK-source %s
|
||||
// CHECK-source: usrs-system.h:1:9: macro definition=MACRO_FROM_SYSTEM_HEADER_1 Extent=[1:9 - 1:40]
|
||||
// CHECK-source: usrs.m:94:9: macro definition=MACRO1 Extent=[94:9 - 94:19]
|
||||
// CHECK-source: usrs.m:96:9: macro definition=MACRO2 Extent=[96:9 - 96:19]
|
||||
// CHECK-source: usrs.m:98:9: macro definition=MACRO2 Extent=[98:9 - 98:19]
|
||||
// CHECK-source: usrs.m:100:9: macro definition=MACRO3 Extent=[100:9 - 100:25]
|
||||
// CHECK-source: usrs.m:101:9: macro definition=MACRO3 Extent=[101:9 - 101:25]
|
||||
// CHECK-source: usrs.m:3:19: FunctionDecl=my_helper:3:19 (Definition) Extent=[3:1 - 3:60]
|
||||
// CHECK-source: usrs.m:3:33: ParmDecl=x:3:33 (Definition) Extent=[3:29 - 3:34]
|
||||
// CHECK-source: usrs.m:3:40: ParmDecl=y:3:40 (Definition) Extent=[3:36 - 3:41]
|
||||
|
@ -14,8 +14,10 @@
|
||||
#include "CIndexer.h"
|
||||
#include "CXCursor.h"
|
||||
#include "CXString.h"
|
||||
#include "CXTranslationUnit.h"
|
||||
#include "clang/Index/USRGeneration.h"
|
||||
#include "clang/Lex/PreprocessingRecord.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
@ -73,10 +75,16 @@ CXString clang_getCursorUSR(CXCursor C) {
|
||||
if (!buf)
|
||||
return cxstring::createEmpty();
|
||||
|
||||
buf->Data += getUSRSpacePrefix();
|
||||
buf->Data += "macro@";
|
||||
buf->Data +=
|
||||
cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
|
||||
bool Ignore = generateUSRForMacro(cxcursor::getCursorMacroDefinition(C),
|
||||
cxtu::getASTUnit(TU)->getSourceManager(),
|
||||
buf->Data);
|
||||
if (Ignore) {
|
||||
buf->dispose();
|
||||
return cxstring::createEmpty();
|
||||
}
|
||||
|
||||
// Return the C-string, but don't make a copy since it is already in
|
||||
// the string buffer.
|
||||
buf->Data.push_back('\0');
|
||||
return createCXString(buf);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user