From 9833d399cef1b50b973d7ca3de69f6a9518438c3 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 15 Apr 2010 21:04:25 +0000 Subject: [PATCH] Do not generate USRs for declarations with 'no linkage' except for enums, structs, typedefs. Those still need work to disambiguate them across translation units. llvm-svn: 101401 --- clang/tools/CIndex/CIndexUSRs.cpp | 35 ++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/clang/tools/CIndex/CIndexUSRs.cpp b/clang/tools/CIndex/CIndexUSRs.cpp index b049c96b482b..2c38047fef31 100644 --- a/clang/tools/CIndex/CIndexUSRs.cpp +++ b/clang/tools/CIndex/CIndexUSRs.cpp @@ -28,8 +28,10 @@ namespace { class USRGenerator : public DeclVisitor { llvm::raw_ostream &Out; bool IgnoreResults; + ASTUnit *AU; public: - USRGenerator(llvm::raw_ostream &out) : Out(out), IgnoreResults(false) {} + USRGenerator(ASTUnit *au, llvm::raw_ostream &out) + : Out(out), IgnoreResults(false), AU(au) {} bool ignoreResults() const { return IgnoreResults; } @@ -46,7 +48,6 @@ public: void VisitTagDecl(TagDecl *D); void VisitTypedefDecl(TypedefDecl *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 @@ -79,10 +80,10 @@ private: llvm::raw_svector_ostream Out; USRGenerator UG; public: - StringUSRGenerator() - : Out(StrBuf), UG(Out) { + StringUSRGenerator(const CXCursor *C = 0) + : Out(StrBuf), UG(C ? cxcursor::getCursorASTUnit(*C) : 0, Out) { // Add the USR space prefix. - Out << "c:"; + Out << "c:"; } llvm::StringRef str() { @@ -269,7 +270,27 @@ static CXString getDeclCursorUSR(const CXCursor &C) { if (!D) return createCXString(NULL); - StringUSRGenerator SUG; + // Check if the cursor has 'NoLinkage'. + if (const NamedDecl *ND = dyn_cast_or_null(D)) + switch (ND->getLinkage()) { + case ExternalLinkage: + // Generate USRs for all entities with external linkage. + break; + case NoLinkage: + // We allow enums, typedefs, and structs that have no linkage to + // have USRs that are anchored to the file they were defined in + // (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(ND)) + break; + // Fall-through. + case InternalLinkage: + case UniqueExternalLinkage: + return createCXString(""); + } + + StringUSRGenerator SUG(&C); SUG->Visit(D); if (SUG->ignoreResults()) @@ -288,7 +309,7 @@ CXString clang_getCursorUSR(CXCursor C) { return getDeclCursorUSR(C); if (K == CXCursor_MacroDefinition) { - StringUSRGenerator SUG; + StringUSRGenerator SUG(&C); SUG << "macro@" << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart(); return createCXString(SUG.str(), true); -- GitLab