diff --git a/clang/include/clang/Index/USRGeneration.h b/clang/include/clang/Index/USRGeneration.h index f89fc5cf49302..61d267f3545a7 100644 --- a/clang/include/clang/Index/USRGeneration.h +++ b/clang/include/clang/Index/USRGeneration.h @@ -15,6 +15,7 @@ namespace clang { class ASTContext; class Decl; +class LangOptions; class MacroDefinitionRecord; class Module; class SourceLocation; @@ -30,6 +31,8 @@ static inline StringRef getUSRSpacePrefix() { /// 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 &Buf); +bool generateUSRForDecl(const Decl *D, SmallVectorImpl &Buf, + const LangOptions &LangOpts); /// Generate a USR fragment for an Objective-C class. void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS, @@ -75,7 +78,10 @@ bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc, /// Generates a USR for a type. /// /// \return true on error, false on success. -bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl &Buf); +bool generateUSRForType(QualType T, ASTContext &Ctx, + SmallVectorImpl &Buf); +bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl &Buf, + const LangOptions &LangOpts); /// Generate a USR for a module, including the USR prefix. /// \returns true on error, false on success. diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 35d0aefaf69a6..493123459a5a4 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -62,20 +62,17 @@ namespace { class USRGenerator : public ConstDeclVisitor { SmallVectorImpl &Buf; llvm::raw_svector_ostream Out; - bool IgnoreResults; ASTContext *Context; - bool generatedLoc; + const LangOptions &LangOpts; + bool IgnoreResults = false; + bool generatedLoc = false; llvm::DenseMap TypeSubstitutions; public: - explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl &Buf) - : Buf(Buf), - Out(Buf), - IgnoreResults(false), - Context(Ctx), - generatedLoc(false) - { + USRGenerator(ASTContext *Ctx, SmallVectorImpl &Buf, + const LangOptions &LangOpts) + : Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) { // Add the USR space prefix. Out << getUSRSpacePrefix(); } @@ -246,14 +243,13 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { } else Out << "@F@"; - PrintingPolicy Policy(Context->getLangOpts()); + PrintingPolicy Policy(LangOpts); // Forward references can have different template argument names. Suppress the // template argument names in constructors to make their USR more stable. Policy.SuppressTemplateArgsInCXXConstructors = true; D->getDeclName().print(Out, Policy); - ASTContext &Ctx = *Context; - if ((!Ctx.getLangOpts().CPlusPlus || D->isExternC()) && + if ((!LangOpts.CPlusPlus || D->isExternC()) && !D->hasAttr()) return; @@ -657,9 +653,10 @@ bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) { return IgnoreResults; } -static void printQualifier(llvm::raw_ostream &Out, ASTContext &Ctx, NestedNameSpecifier *NNS) { +static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts, + NestedNameSpecifier *NNS) { // FIXME: Encode the qualifier, don't just print it. - PrintingPolicy PO(Ctx.getLangOpts()); + PrintingPolicy PO(LangOpts); PO.SuppressTagKeyword = true; PO.SuppressUnwrittenScope = true; PO.ConstantArraySizeAsWritten = false; @@ -948,7 +945,7 @@ void USRGenerator::VisitType(QualType T) { } if (const DependentNameType *DNT = T->getAs()) { Out << '^'; - printQualifier(Out, Ctx, DNT->getQualifier()); + printQualifier(Out, LangOpts, DNT->getQualifier()); Out << ':' << DNT->getIdentifier()->getName(); return; } @@ -1090,7 +1087,7 @@ void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl return; VisitDeclContext(D->getDeclContext()); Out << "@UUV@"; - printQualifier(Out, D->getASTContext(), D->getQualifier()); + printQualifier(Out, LangOpts, D->getQualifier()); EmitDeclName(D); } @@ -1099,7 +1096,7 @@ void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenam return; VisitDeclContext(D->getDeclContext()); Out << "@UUT@"; - printQualifier(Out, D->getASTContext(), D->getQualifier()); + printQualifier(Out, LangOpts, D->getQualifier()); Out << D->getName(); // Simple name. } @@ -1190,6 +1187,13 @@ bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl &Buf) { if (!D) return true; + return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts()); +} + +bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl &Buf, + const LangOptions &LangOpts) { + if (!D) + return true; // We don't ignore decls with invalid source locations. Implicit decls, like // C++'s operator new function, can have invalid locations but it is fine to // create USRs that can identify them. @@ -1203,7 +1207,7 @@ bool clang::index::generateUSRForDecl(const Decl *D, return false; } } - USRGenerator UG(&D->getASTContext(), Buf); + USRGenerator UG(&D->getASTContext(), Buf, LangOpts); UG.Visit(D); return UG.ignoreResults(); } @@ -1240,11 +1244,17 @@ bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc, bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl &Buf) { + return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts()); +} + +bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx, + SmallVectorImpl &Buf, + const LangOptions &LangOpts) { if (T.isNull()) return true; T = T.getCanonicalType(); - USRGenerator UG(&Ctx, Buf); + USRGenerator UG(&Ctx, Buf, LangOpts); UG.VisitType(T); return UG.ignoreResults(); }