Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang][Index][USR][NFC] Allow customizing langopts for USR generation #109574

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion clang/include/clang/Index/USRGeneration.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
namespace clang {
class ASTContext;
class Decl;
class LangOptions;
class MacroDefinitionRecord;
class Module;
class SourceLocation;
Expand All @@ -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<char> &Buf);
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf,
const LangOptions &LangOpts);

/// Generate a USR fragment for an Objective-C class.
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
Expand Down Expand Up @@ -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<char> &Buf);
bool generateUSRForType(QualType T, ASTContext &Ctx,
SmallVectorImpl<char> &Buf);
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl<char> &Buf,
const LangOptions &LangOpts);

/// Generate a USR for a module, including the USR prefix.
/// \returns true on error, false on success.
Expand Down
48 changes: 29 additions & 19 deletions clang/lib/Index/USRGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,17 @@ namespace {
class USRGenerator : public ConstDeclVisitor<USRGenerator> {
SmallVectorImpl<char> &Buf;
llvm::raw_svector_ostream Out;
bool IgnoreResults;
ASTContext *Context;
bool generatedLoc;
const LangOptions &LangOpts;
bool IgnoreResults = false;
bool generatedLoc = false;

llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;

public:
explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf)
: Buf(Buf),
Out(Buf),
IgnoreResults(false),
Context(Ctx),
generatedLoc(false)
{
USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf,
const LangOptions &LangOpts)
: Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) {
// Add the USR space prefix.
Out << getUSRSpacePrefix();
}
Expand Down Expand Up @@ -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<OverloadableAttr>())
return;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -948,7 +945,7 @@ void USRGenerator::VisitType(QualType T) {
}
if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
Out << '^';
printQualifier(Out, Ctx, DNT->getQualifier());
printQualifier(Out, LangOpts, DNT->getQualifier());
Out << ':' << DNT->getIdentifier()->getName();
return;
}
Expand Down Expand Up @@ -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);
}

Expand All @@ -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.
}

Expand Down Expand Up @@ -1190,6 +1187,13 @@ bool clang::index::generateUSRForDecl(const Decl *D,
SmallVectorImpl<char> &Buf) {
if (!D)
return true;
return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts());
}

bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &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.
Expand All @@ -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();
}
Expand Down Expand Up @@ -1240,11 +1244,17 @@ bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,

bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
SmallVectorImpl<char> &Buf) {
return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts());
}

bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
SmallVectorImpl<char> &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();
}
Expand Down
Loading