Skip to content

Commit 4ba623f

Browse files
authored
[clang][Index][USR][NFC] Allow customizing langopts for USR generation (#109574)
This helps to produce USRs for custom LangOpts - that differ from the one associated with the given Decl. This can unlock usecases in tooling opportunities that we have downstream. This is NFC because existing calls will still result in the right overload, thus using the LangOpts associated with the ASTContext of the Decls and Types.
1 parent d693e7c commit 4ba623f

File tree

2 files changed

+36
-20
lines changed

2 files changed

+36
-20
lines changed

clang/include/clang/Index/USRGeneration.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
namespace clang {
1616
class ASTContext;
1717
class Decl;
18+
class LangOptions;
1819
class MacroDefinitionRecord;
1920
class Module;
2021
class SourceLocation;
@@ -30,6 +31,8 @@ static inline StringRef getUSRSpacePrefix() {
3031
/// Generate a USR for a Decl, including the USR prefix.
3132
/// \returns true if the results should be ignored, false otherwise.
3233
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
34+
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf,
35+
const LangOptions &LangOpts);
3336

3437
/// Generate a USR fragment for an Objective-C class.
3538
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
@@ -75,7 +78,10 @@ bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
7578
/// Generates a USR for a type.
7679
///
7780
/// \return true on error, false on success.
78-
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl<char> &Buf);
81+
bool generateUSRForType(QualType T, ASTContext &Ctx,
82+
SmallVectorImpl<char> &Buf);
83+
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl<char> &Buf,
84+
const LangOptions &LangOpts);
7985

8086
/// Generate a USR for a module, including the USR prefix.
8187
/// \returns true on error, false on success.

clang/lib/Index/USRGeneration.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,17 @@ namespace {
6262
class USRGenerator : public ConstDeclVisitor<USRGenerator> {
6363
SmallVectorImpl<char> &Buf;
6464
llvm::raw_svector_ostream Out;
65-
bool IgnoreResults;
6665
ASTContext *Context;
67-
bool generatedLoc;
66+
const LangOptions &LangOpts;
67+
bool IgnoreResults = false;
68+
bool generatedLoc = false;
6869

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

7172
public:
72-
explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf)
73-
: Buf(Buf),
74-
Out(Buf),
75-
IgnoreResults(false),
76-
Context(Ctx),
77-
generatedLoc(false)
78-
{
73+
USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf,
74+
const LangOptions &LangOpts)
75+
: Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) {
7976
// Add the USR space prefix.
8077
Out << getUSRSpacePrefix();
8178
}
@@ -246,14 +243,13 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
246243
} else
247244
Out << "@F@";
248245

249-
PrintingPolicy Policy(Context->getLangOpts());
246+
PrintingPolicy Policy(LangOpts);
250247
// Forward references can have different template argument names. Suppress the
251248
// template argument names in constructors to make their USR more stable.
252249
Policy.SuppressTemplateArgsInCXXConstructors = true;
253250
D->getDeclName().print(Out, Policy);
254251

255-
ASTContext &Ctx = *Context;
256-
if ((!Ctx.getLangOpts().CPlusPlus || D->isExternC()) &&
252+
if ((!LangOpts.CPlusPlus || D->isExternC()) &&
257253
!D->hasAttr<OverloadableAttr>())
258254
return;
259255

@@ -657,9 +653,10 @@ bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
657653
return IgnoreResults;
658654
}
659655

660-
static void printQualifier(llvm::raw_ostream &Out, ASTContext &Ctx, NestedNameSpecifier *NNS) {
656+
static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts,
657+
NestedNameSpecifier *NNS) {
661658
// FIXME: Encode the qualifier, don't just print it.
662-
PrintingPolicy PO(Ctx.getLangOpts());
659+
PrintingPolicy PO(LangOpts);
663660
PO.SuppressTagKeyword = true;
664661
PO.SuppressUnwrittenScope = true;
665662
PO.ConstantArraySizeAsWritten = false;
@@ -948,7 +945,7 @@ void USRGenerator::VisitType(QualType T) {
948945
}
949946
if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
950947
Out << '^';
951-
printQualifier(Out, Ctx, DNT->getQualifier());
948+
printQualifier(Out, LangOpts, DNT->getQualifier());
952949
Out << ':' << DNT->getIdentifier()->getName();
953950
return;
954951
}
@@ -1090,7 +1087,7 @@ void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl
10901087
return;
10911088
VisitDeclContext(D->getDeclContext());
10921089
Out << "@UUV@";
1093-
printQualifier(Out, D->getASTContext(), D->getQualifier());
1090+
printQualifier(Out, LangOpts, D->getQualifier());
10941091
EmitDeclName(D);
10951092
}
10961093

@@ -1099,7 +1096,7 @@ void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenam
10991096
return;
11001097
VisitDeclContext(D->getDeclContext());
11011098
Out << "@UUT@";
1102-
printQualifier(Out, D->getASTContext(), D->getQualifier());
1099+
printQualifier(Out, LangOpts, D->getQualifier());
11031100
Out << D->getName(); // Simple name.
11041101
}
11051102

@@ -1190,6 +1187,13 @@ bool clang::index::generateUSRForDecl(const Decl *D,
11901187
SmallVectorImpl<char> &Buf) {
11911188
if (!D)
11921189
return true;
1190+
return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts());
1191+
}
1192+
1193+
bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf,
1194+
const LangOptions &LangOpts) {
1195+
if (!D)
1196+
return true;
11931197
// We don't ignore decls with invalid source locations. Implicit decls, like
11941198
// C++'s operator new function, can have invalid locations but it is fine to
11951199
// create USRs that can identify them.
@@ -1203,7 +1207,7 @@ bool clang::index::generateUSRForDecl(const Decl *D,
12031207
return false;
12041208
}
12051209
}
1206-
USRGenerator UG(&D->getASTContext(), Buf);
1210+
USRGenerator UG(&D->getASTContext(), Buf, LangOpts);
12071211
UG.Visit(D);
12081212
return UG.ignoreResults();
12091213
}
@@ -1240,11 +1244,17 @@ bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
12401244

12411245
bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
12421246
SmallVectorImpl<char> &Buf) {
1247+
return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts());
1248+
}
1249+
1250+
bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
1251+
SmallVectorImpl<char> &Buf,
1252+
const LangOptions &LangOpts) {
12431253
if (T.isNull())
12441254
return true;
12451255
T = T.getCanonicalType();
12461256

1247-
USRGenerator UG(&Ctx, Buf);
1257+
USRGenerator UG(&Ctx, Buf, LangOpts);
12481258
UG.VisitType(T);
12491259
return UG.ignoreResults();
12501260
}

0 commit comments

Comments
 (0)