summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp142
1 files changed, 84 insertions, 58 deletions
diff --git a/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp b/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp
index 16d89f8..e08b85e 100644
--- a/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp
+++ b/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp
@@ -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;
@@ -80,10 +105,16 @@ public:
void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
IgnoreResults = true;
}
-
+
+ bool ShouldGenerateLocation(const NamedDecl *D);
+
+ bool isLocal(const NamedDecl *D) {
+ return D->getParentFunctionOrMethod() != nullptr;
+ }
+
/// Generate the string component containing the location of the
/// declaration.
- bool GenLoc(const Decl *D);
+ bool GenLoc(const Decl *D, bool IncludeOffset);
/// String generation methods used both by the visitation methods
/// and from other clients that want to directly generate USRs. These
@@ -99,16 +130,6 @@ public:
void GenObjCCategory(StringRef cls, StringRef cat) {
generateUSRForObjCCategory(cls, cat, Out);
}
- /// Generate a USR fragment for an Objective-C instance variable. The
- /// complete USR can be created by concatenating the USR for the
- /// encompassing class with this USR fragment.
- void GenObjCIvar(StringRef ivar) {
- generateUSRForObjCIvar(ivar, Out);
- }
- /// Generate a USR fragment for an Objective-C method.
- void GenObjCMethod(StringRef sel, bool isInstanceMethod) {
- generateUSRForObjCMethod(sel, isInstanceMethod, Out);
- }
/// Generate a USR fragment for an Objective-C property.
void GenObjCProperty(StringRef prop) {
generateUSRForObjCProperty(prop, Out);
@@ -143,8 +164,13 @@ bool USRGenerator::EmitDeclName(const NamedDecl *D) {
return startSize == endSize;
}
-static inline bool ShouldGenerateLocation(const NamedDecl *D) {
- return !D->isExternallyVisible();
+bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
+ if (D->isExternallyVisible())
+ return false;
+ if (D->getParentFunctionOrMethod())
+ return true;
+ const SourceManager &SM = Context->getSourceManager();
+ return !SM.isInSystemHeader(D->getLocation());
}
void USRGenerator::VisitDeclContext(const DeclContext *DC) {
@@ -168,7 +194,7 @@ void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
}
void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
- if (ShouldGenerateLocation(D) && GenLoc(D))
+ if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
return;
VisitDeclContext(D->getDeclContext());
@@ -194,12 +220,9 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
}
// Mangle in type information for the arguments.
- for (FunctionDecl::param_const_iterator I = D->param_begin(),
- E = D->param_end();
- I != E; ++I) {
+ for (auto PD : D->params()) {
Out << '#';
- if (ParmVarDecl *PD = *I)
- VisitType(PD->getType());
+ VisitType(PD->getType());
}
if (D->isVariadic())
Out << '.';
@@ -229,7 +252,7 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) {
// VarDecls can be declared 'extern' within a function or method body,
// but their enclosing DeclContext is the function, not the TU. We need
// to check the storage class to correctly generate the USR.
- if (ShouldGenerateLocation(D) && GenLoc(D))
+ if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
return;
VisitDeclContext(D->getDeclContext());
@@ -249,13 +272,13 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) {
void USRGenerator::VisitNonTypeTemplateParmDecl(
const NonTypeTemplateParmDecl *D) {
- GenLoc(D);
+ GenLoc(D, /*IncludeOffset=*/true);
return;
}
void USRGenerator::VisitTemplateTemplateParmDecl(
const TemplateTemplateParmDecl *D) {
- GenLoc(D);
+ GenLoc(D, /*IncludeOffset=*/true);
return;
}
@@ -329,7 +352,7 @@ void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) {
// We want to mangle in the location to uniquely distinguish them.
if (CD->IsClassExtension()) {
Out << "objc(ext)" << ID->getName() << '@';
- GenLoc(CD);
+ GenLoc(CD, /*IncludeOffset=*/true);
}
else
GenObjCCategory(ID->getName(), CD->getName());
@@ -378,7 +401,7 @@ void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
void USRGenerator::VisitTagDecl(const TagDecl *D) {
// Add the location of the tag decl to handle resolution across
// translation units.
- if (ShouldGenerateLocation(D) && GenLoc(D))
+ if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
return;
D = D->getCanonicalDecl();
@@ -449,7 +472,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
}
void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
- if (ShouldGenerateLocation(D) && GenLoc(D))
+ if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
return;
const DeclContext *DC = D->getDeclContext();
if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
@@ -459,15 +482,15 @@ void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
}
void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
- GenLoc(D);
+ GenLoc(D, /*IncludeOffset=*/true);
return;
}
-bool USRGenerator::GenLoc(const Decl *D) {
+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;
@@ -477,27 +500,10 @@ bool USRGenerator::GenLoc(const Decl *D) {
// 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;
- }
- // 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;
}
@@ -627,11 +633,9 @@ void USRGenerator::VisitType(QualType T) {
}
if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
Out << 'F';
- VisitType(FT->getResultType());
- for (FunctionProtoType::arg_type_iterator
- I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) {
- VisitType(*I);
- }
+ VisitType(FT->getReturnType());
+ for (const auto &I : FT->param_types())
+ VisitType(I);
if (FT->isVariadic())
Out << '.';
return;
@@ -743,9 +747,8 @@ void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
case TemplateArgument::Pack:
Out << 'p' << Arg.pack_size();
- for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end();
- P != PEnd; ++P)
- VisitTemplateArgument(*P);
+ for (const auto &P : Arg.pack_elements())
+ VisitTemplateArgument(P);
break;
case TemplateArgument::Type:
@@ -801,3 +804,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()->getName();
+ return false;
+}
+
OpenPOWER on IntegriCloud