Skip to content

Reland [clang] Unify SourceLocation and IdentifierInfo* pair-like data structures to IdentifierLoc #136077

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

Merged
merged 6 commits into from
Apr 17, 2025

Conversation

yronglin
Copy link
Contributor

This PR reland #135808, fixed some missed changes in LLDB.
I found this issue when I working on #107168.

Currently we have many similiar data structures like:

  • std::pair<IdentifierInfo *, SourceLocation>.
  • Element type of ModuleIdPath.
  • IdentifierLocPair.
  • IdentifierLoc.

This PR unify these data structures to IdentifierLoc, moved IdentifierLoc definition to SourceLocation.h, and deleted other similer data structures.

@yronglin yronglin requested a review from JDevlieghere as a code owner April 17, 2025 03:02
@llvmbot llvmbot added clang Clang issues not falling into any other category clang-tools-extra lldb backend:ARM backend:AArch64 clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules HLSL HLSL Language Support labels Apr 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 17, 2025

@llvm/pr-subscribers-clang-modules
@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-backend-arm

Author: None (yronglin)

Changes

This PR reland #135808, fixed some missed changes in LLDB.
I found this issue when I working on #107168.

Currently we have many similiar data structures like:

  • std::pair<IdentifierInfo *, SourceLocation>.
  • Element type of ModuleIdPath.
  • IdentifierLocPair.
  • IdentifierLoc.

This PR unify these data structures to IdentifierLoc, moved IdentifierLoc definition to SourceLocation.h, and deleted other similer data structures.


Patch is 110.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136077.diff

47 Files Affected:

  • (modified) clang-tools-extra/pp-trace/PPCallbacksTracker.cpp (+2-2)
  • (modified) clang/include/clang/AST/OpenACCClause.h (+10-10)
  • (modified) clang/include/clang/Basic/IdentifierTable.h (+23-3)
  • (modified) clang/include/clang/Lex/ModuleLoader.h (+2-1)
  • (modified) clang/include/clang/Lex/PPCallbacks.h (+1)
  • (modified) clang/include/clang/Lex/Preprocessor.h (+4-5)
  • (modified) clang/include/clang/Parse/LoopHint.h (+1-1)
  • (modified) clang/include/clang/Parse/Parser.h (+5-8)
  • (modified) clang/include/clang/Sema/ParsedAttr.h (-10)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/include/clang/Sema/SemaCodeCompletion.h (+1-2)
  • (modified) clang/include/clang/Sema/SemaObjC.h (+2-2)
  • (modified) clang/include/clang/Sema/SemaOpenACC.h (+1-1)
  • (modified) clang/lib/AST/OpenACCClause.cpp (+2-2)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+2-2)
  • (modified) clang/lib/Frontend/CompilerInstance.cpp (+28-25)
  • (modified) clang/lib/Frontend/FrontendActions.cpp (+2-2)
  • (modified) clang/lib/Lex/PPDirectives.cpp (+11-11)
  • (modified) clang/lib/Lex/PPLexerChange.cpp (+3-3)
  • (modified) clang/lib/Lex/Pragma.cpp (+35-38)
  • (modified) clang/lib/Lex/Preprocessor.cpp (+8-8)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+14-14)
  • (modified) clang/lib/Parse/ParseExpr.cpp (+4-3)
  • (modified) clang/lib/Parse/ParseHLSL.cpp (+1-1)
  • (modified) clang/lib/Parse/ParseObjc.cpp (+18-20)
  • (modified) clang/lib/Parse/ParseOpenACC.cpp (+7-5)
  • (modified) clang/lib/Parse/ParsePragma.cpp (+7-8)
  • (modified) clang/lib/Parse/ParseStmt.cpp (+3-3)
  • (modified) clang/lib/Parse/Parser.cpp (+9-10)
  • (modified) clang/lib/Sema/ParsedAttr.cpp (-8)
  • (modified) clang/lib/Sema/SemaARM.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+65-59)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+19-16)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+6-6)
  • (modified) clang/lib/Sema/SemaModule.cpp (+23-19)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+23-22)
  • (modified) clang/lib/Sema/SemaOpenACCClause.cpp (+6-5)
  • (modified) clang/lib/Sema/SemaStmtAttr.cpp (+16-13)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+12-12)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+5-5)
  • (modified) clang/lib/Sema/SemaType.cpp (+6-7)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+1-1)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+4-4)
  • (modified) clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp (+1-1)
  • (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (+4-2)
  • (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp (+8-9)
diff --git a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
index 3bb30fd15b2e1..4c916fa30685b 100644
--- a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
+++ b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
@@ -547,8 +547,8 @@ void PPCallbacksTracker::appendArgument(const char *Name, ModuleIdPath Value) {
     if (I)
       SS << ", ";
     SS << "{"
-       << "Name: " << Value[I].first->getName() << ", "
-       << "Loc: " << getSourceLocationString(PP, Value[I].second) << "}";
+       << "Name: " << Value[I].getIdentifierInfo()->getName() << ", "
+       << "Loc: " << getSourceLocationString(PP, Value[I].getLoc()) << "}";
   }
   SS << "]";
   appendArgument(Name, SS.str());
diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index 681567228cbb0..f18a6cf62f2c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -258,7 +258,7 @@ inline bool operator!=(const OpenACCBindClause &LHS,
   return !(LHS == RHS);
 }
 
-using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
+using DeviceTypeArgument = IdentifierLoc;
 /// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or
 /// an identifier. The 'asterisk' means 'the rest'.
 class OpenACCDeviceTypeClause final
@@ -280,16 +280,16 @@ class OpenACCDeviceTypeClause final
         "Invalid clause kind for device-type");
 
     assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) {
-      return Arg.second.isInvalid();
+      return Arg.getLoc().isInvalid();
     }) && "Invalid SourceLocation for an argument");
 
-    assert(
-        (Archs.size() == 1 || !llvm::any_of(Archs,
-                                            [](const DeviceTypeArgument &Arg) {
-                                              return Arg.first == nullptr;
-                                            })) &&
-        "Only a single asterisk version is permitted, and must be the "
-        "only one");
+    assert((Archs.size() == 1 ||
+            !llvm::any_of(Archs,
+                          [](const DeviceTypeArgument &Arg) {
+                            return Arg.getIdentifierInfo() == nullptr;
+                          })) &&
+           "Only a single asterisk version is permitted, and must be the "
+           "only one");
 
     std::uninitialized_copy(Archs.begin(), Archs.end(),
                             getTrailingObjects<DeviceTypeArgument>());
@@ -302,7 +302,7 @@ class OpenACCDeviceTypeClause final
   }
   bool hasAsterisk() const {
     return getArchitectures().size() > 0 &&
-           getArchitectures()[0].first == nullptr;
+           getArchitectures()[0].getIdentifierInfo() == nullptr;
   }
 
   ArrayRef<DeviceTypeArgument> getArchitectures() const {
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
index 0347880244a40..1275b056227b5 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -76,9 +77,6 @@ inline bool isReservedInAllContexts(ReservedIdentifierStatus Status) {
          Status != ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
 }
 
-/// A simple pair of identifier info and location.
-using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
-
 /// IdentifierInfo and other related classes are aligned to
 /// 8 bytes so that DeclarationName can use the lower 3 bits
 /// of a pointer to one of these classes.
@@ -1165,6 +1163,28 @@ class SelectorTable {
   static std::string getPropertyNameFromSetterSelector(Selector Sel);
 };
 
+/// A simple pair of identifier info and location.
+class IdentifierLoc {
+  SourceLocation Loc;
+  IdentifierInfo *II = nullptr;
+
+public:
+  IdentifierLoc() = default;
+  IdentifierLoc(SourceLocation L, IdentifierInfo *Ident) : Loc(L), II(Ident) {}
+
+  void setLoc(SourceLocation L) { Loc = L; }
+  void setIdentifierInfo(IdentifierInfo *Ident) { II = Ident; }
+  SourceLocation getLoc() const { return Loc; }
+  IdentifierInfo *getIdentifierInfo() const { return II; }
+
+  bool operator==(const IdentifierLoc &X) const {
+    return Loc == X.Loc && II == X.II;
+  }
+
+  bool operator!=(const IdentifierLoc &X) const {
+    return Loc != X.Loc || II != X.II;
+  }
+};
 }  // namespace clang
 
 namespace llvm {
diff --git a/clang/include/clang/Lex/ModuleLoader.h b/clang/include/clang/Lex/ModuleLoader.h
index f880a9091a2ed..a58407200c41c 100644
--- a/clang/include/clang/Lex/ModuleLoader.h
+++ b/clang/include/clang/Lex/ModuleLoader.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_LEX_MODULELOADER_H
 #define LLVM_CLANG_LEX_MODULELOADER_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
@@ -29,7 +30,7 @@ class IdentifierInfo;
 
 /// A sequence of identifier/location pairs used to describe a particular
 /// module or submodule, e.g., std.vector.
-using ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>;
+using ModuleIdPath = ArrayRef<IdentifierLoc>;
 
 /// Describes the result of attempting to load a module.
 class ModuleLoadResult {
diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h
index 46cc564086f1c..313b730afbab8 100644
--- a/clang/include/clang/Lex/PPCallbacks.h
+++ b/clang/include/clang/Lex/PPCallbacks.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_LEX_PPCALLBACKS_H
 
 #include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/ModuleLoader.h"
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 24bb524783e93..f8f2f567f9171 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -327,7 +327,7 @@ class Preprocessor {
   SourceLocation ModuleImportLoc;
 
   /// The import path for named module that we're currently processing.
-  SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> NamedModuleImportPath;
+  SmallVector<IdentifierLoc, 2> NamedModuleImportPath;
 
   llvm::DenseMap<FileID, SmallVector<const char *>> CheckPoints;
   unsigned CheckPointCounter = 0;
@@ -622,7 +622,7 @@ class Preprocessor {
 
   /// The identifier and source location of the currently-active
   /// \#pragma clang arc_cf_code_audited begin.
-  std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo;
+  IdentifierLoc PragmaARCCFCodeAuditedInfo;
 
   /// The source location of the currently-active
   /// \#pragma clang assume_nonnull begin.
@@ -1998,8 +1998,7 @@ class Preprocessor {
   /// arc_cf_code_audited begin.
   ///
   /// Returns an invalid location if there is no such pragma active.
-  std::pair<IdentifierInfo *, SourceLocation>
-  getPragmaARCCFCodeAuditedInfo() const {
+  IdentifierLoc getPragmaARCCFCodeAuditedInfo() const {
     return PragmaARCCFCodeAuditedInfo;
   }
 
@@ -2007,7 +2006,7 @@ class Preprocessor {
   /// arc_cf_code_audited begin.  An invalid location ends the pragma.
   void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident,
                                      SourceLocation Loc) {
-    PragmaARCCFCodeAuditedInfo = {Ident, Loc};
+    PragmaARCCFCodeAuditedInfo = IdentifierLoc(Loc, Ident);
   }
 
   /// The location of the currently-active \#pragma clang
diff --git a/clang/include/clang/Parse/LoopHint.h b/clang/include/clang/Parse/LoopHint.h
index cec5605ea3615..72be043d3c5a4 100644
--- a/clang/include/clang/Parse/LoopHint.h
+++ b/clang/include/clang/Parse/LoopHint.h
@@ -9,12 +9,12 @@
 #ifndef LLVM_CLANG_PARSE_LOOPHINT_H
 #define LLVM_CLANG_PARSE_LOOPHINT_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/SourceLocation.h"
 
 namespace clang {
 
 class Expr;
-struct IdentifierLoc;
 
 /// Loop optimization hint for loop and unroll pragmas.
 struct LoopHint {
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 9ebcf144ba59e..662f54d0e8d8a 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1725,8 +1725,8 @@ class Parser : public CodeCompletionHandler {
   ObjCTypeParamList *parseObjCTypeParamList();
   ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
       ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
-      SmallVectorImpl<IdentifierLocPair> &protocolIdents,
-      SourceLocation &rAngleLoc, bool mayBeProtocolList = true);
+      SmallVectorImpl<IdentifierLoc> &protocolIdents, SourceLocation &rAngleLoc,
+      bool mayBeProtocolList = true);
 
   void HelperActionsForIvarDeclarations(ObjCContainerDecl *interfaceDecl,
                                         SourceLocation atLoc,
@@ -3818,8 +3818,7 @@ class Parser : public CodeCompletionHandler {
                                SourceLocation Loc,
                                llvm::SmallVectorImpl<Expr *> &IntExprs);
   /// Parses the 'device-type-list', which is a list of identifiers.
-  bool ParseOpenACCDeviceTypeList(
-      llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>> &Archs);
+  bool ParseOpenACCDeviceTypeList(llvm::SmallVector<IdentifierLoc> &Archs);
   /// Parses the 'async-argument', which is an integral value with two
   /// 'special' values that are likely negative (but come from Macros).
   OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
@@ -3951,10 +3950,8 @@ class Parser : public CodeCompletionHandler {
     return false;
   }
 
-  bool ParseModuleName(
-      SourceLocation UseLoc,
-      SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
-      bool IsImport);
+  bool ParseModuleName(SourceLocation UseLoc,
+                       SmallVectorImpl<IdentifierLoc> &Path, bool IsImport);
 
   //===--------------------------------------------------------------------===//
   // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index b88b871dc8821..428d3111de80d 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -40,7 +40,6 @@ class LangOptions;
 class Sema;
 class Stmt;
 class TargetInfo;
-struct IdentifierLoc;
 
 /// Represents information about a change in availability for
 /// an entity, which is part of the encoding of the 'availability'
@@ -99,15 +98,6 @@ struct PropertyData {
 
 } // namespace detail
 
-/// Wraps an identifier and optional source location for the identifier.
-struct IdentifierLoc {
-  SourceLocation Loc;
-  IdentifierInfo *Ident;
-
-  static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
-                               IdentifierInfo *Ident);
-};
-
 /// A union of the various pointer types that can be passed to an
 /// ParsedAttr as an argument.
 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fe37fd7701ce3..1f23b754a69cb 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -143,7 +143,7 @@ enum class LangAS : unsigned int;
 class LocalInstantiationScope;
 class LookupResult;
 class MangleNumberingContext;
-typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath;
+typedef ArrayRef<IdentifierLoc> ModuleIdPath;
 class ModuleLoader;
 class MultiLevelTemplateArgumentList;
 struct NormalizedConstraint;
diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h b/clang/include/clang/Sema/SemaCodeCompletion.h
index 72159de3a6e72..3029e56e5cfe2 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -193,8 +193,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar);
   void CodeCompleteObjCSelector(Scope *S,
                                 ArrayRef<const IdentifierInfo *> SelIdents);
-  void
-  CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLocPair> Protocols);
+  void CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLoc> Protocols);
   void CodeCompleteObjCProtocolDecl(Scope *S);
   void CodeCompleteObjCInterfaceDecl(Scope *S);
   void CodeCompleteObjCClassForwardDecl(Scope *S);
diff --git a/clang/include/clang/Sema/SemaObjC.h b/clang/include/clang/Sema/SemaObjC.h
index 791a7f45b832f..4cda41a82b61f 100644
--- a/clang/include/clang/Sema/SemaObjC.h
+++ b/clang/include/clang/Sema/SemaObjC.h
@@ -307,11 +307,11 @@ class SemaObjC : public SemaBase {
 
   DeclGroupPtrTy
   ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
-                                  ArrayRef<IdentifierLocPair> IdentList,
+                                  ArrayRef<IdentifierLoc> IdentList,
                                   const ParsedAttributesView &attrList);
 
   void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
-                               ArrayRef<IdentifierLocPair> ProtocolId,
+                               ArrayRef<IdentifierLoc> ProtocolId,
                                SmallVectorImpl<Decl *> &Protocols);
 
   void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId,
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index 4c3a13a3b044f..8d31d46444c7e 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -212,7 +212,7 @@ class SemaOpenACC : public SemaBase {
   } LoopWithoutSeqInfo;
 
   // Redeclaration of the version in OpenACCClause.h.
-  using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
+  using DeviceTypeArgument = IdentifierLoc;
 
   /// A type to represent all the data for an OpenACC Clause that has been
   /// parsed, but not yet created/semantically analyzed. This is effectively a
diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp
index d7cbb51335359..2820d7b288658 100644
--- a/clang/lib/AST/OpenACCClause.cpp
+++ b/clang/lib/AST/OpenACCClause.cpp
@@ -891,10 +891,10 @@ void OpenACCClausePrinter::VisitDeviceTypeClause(
   OS << "(";
   llvm::interleaveComma(C.getArchitectures(), OS,
                         [&](const DeviceTypeArgument &Arch) {
-                          if (Arch.first == nullptr)
+                          if (Arch.getIdentifierInfo() == nullptr)
                             OS << "*";
                           else
-                            OS << Arch.first->getName();
+                            OS << Arch.getIdentifierInfo()->getName();
                         });
   OS << ")";
 }
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index c8b459ee78e6b..1bd94a3ac6431 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -500,10 +500,10 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
       llvm::interleaveComma(
           cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS,
           [&](const DeviceTypeArgument &Arch) {
-            if (Arch.first == nullptr)
+            if (Arch.getIdentifierInfo() == nullptr)
               OS << "*";
             else
-              OS << Arch.first->getName();
+              OS << Arch.getIdentifierInfo()->getName();
           });
       OS << ")";
       break;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 243e0a3c15b05..93e4e31c2891d 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -35,6 +35,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
@@ -2009,8 +2010,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
                              Module::NameVisibilityKind Visibility,
                              bool IsInclusionDirective) {
   // Determine what file we're searching from.
-  StringRef ModuleName = Path[0].first->getName();
-  SourceLocation ModuleNameLoc = Path[0].second;
+  StringRef ModuleName = Path[0].getIdentifierInfo()->getName();
+  SourceLocation ModuleNameLoc = Path[0].getLoc();
 
   // If we've already handled this import, just return the cached result.
   // This one-element cache is important to eliminate redundant diagnostics
@@ -2026,7 +2027,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   // If we don't already have information on this module, load the module now.
   Module *Module = nullptr;
   ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap();
-  if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
+  if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].getIdentifierInfo())) {
     // Use the cached result, which may be nullptr.
     Module = *MaybeModule;
     // Config macros are already checked before building a module, but they need
@@ -2046,7 +2047,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
     // * `Preprocessor::HandleHeaderIncludeOrImport` will never call this
     //   function as the `#include` or `#import` is textual.
 
-    MM.cacheModuleLoad(*Path[0].first, Module);
+    MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
   } else {
     ModuleLoadResult Result = findOrCompileModuleAndReadAST(
         ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
@@ -2055,7 +2056,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
     if (!Result)
       DisableGeneratingGlobalModuleIndex = true;
     Module = Result;
-    MM.cacheModuleLoad(*Path[0].first, Module);
+    MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
   }
 
   // If we never found the module, fail.  Otherwise, verify the module and link
@@ -2067,7 +2068,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   // a submodule.
   bool MapPrivateSubModToTopLevel = false;
   for (unsigned I = 1, N = Path.size(); I != N; ++I) {
-    StringRef Name = Path[I].first->getName();
+    StringRef Name = Path[I].getIdentifierInfo()->getName();
     clang::Module *Sub = Module->findSubmodule(Name);
 
     // If the user is requesting Foo.Private and it doesn't exist, try to
@@ -2078,10 +2079,10 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
       SmallString<128> PrivateModule(Module->Name);
       PrivateModule.append("_Private");
 
-      SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath;
+      SmallVector<IdentifierLoc, 2> PrivPath;
       auto &II = PP->getIdentifierTable().get(
           PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID());
-      PrivPath.push_back(std::make_pair(&II, Path[0].second));
+      PrivPath.emplace_back(Path[0].getLoc(), &II);
 
       std::string FileName;
       // If there is a modulemap module or prebuilt module, load it.
@@ -2095,11 +2096,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
         PP->markClangModuleAsAffecting(Module);
         if (!getDiagnostics().isIgnored(
                 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
-          getDiagnostics().Report(Path[I].second,
+          getDiagnostics().Report(Path[I].getLoc(),
                                   diag::warn_no_priv_submodule_use_toplevel)
-              << Path[I].first << Module->getFullModuleName() << PrivateModule
-              << SourceRange(Path[0].second, Path[I].second)
-              << FixItHint::CreateReplacement(SourceRange(Path[0].second),
+              << Path[I].getIdentifierInfo() << Module->getFullModuleName()
+              << PrivateModule
+              << SourceRange(Path[0].getLoc(), Path[I].getLoc())
+              << FixItHint::CreateReplacement(SourceRange(Path[0].getLoc()),
                                               PrivateModule);
           getDiagnostics().Report(Sub->DefinitionLoc,
                                   diag::note_private_top_level_defined);
@@ -2128,10 +2130,11 @@ Com...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Apr 17, 2025

@llvm/pr-subscribers-clang-tools-extra

Author: None (yronglin)

Changes

This PR reland #135808, fixed some missed changes in LLDB.
I found this issue when I working on #107168.

Currently we have many similiar data structures like:

  • std::pair<IdentifierInfo *, SourceLocation>.
  • Element type of ModuleIdPath.
  • IdentifierLocPair.
  • IdentifierLoc.

This PR unify these data structures to IdentifierLoc, moved IdentifierLoc definition to SourceLocation.h, and deleted other similer data structures.


Patch is 110.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136077.diff

47 Files Affected:

  • (modified) clang-tools-extra/pp-trace/PPCallbacksTracker.cpp (+2-2)
  • (modified) clang/include/clang/AST/OpenACCClause.h (+10-10)
  • (modified) clang/include/clang/Basic/IdentifierTable.h (+23-3)
  • (modified) clang/include/clang/Lex/ModuleLoader.h (+2-1)
  • (modified) clang/include/clang/Lex/PPCallbacks.h (+1)
  • (modified) clang/include/clang/Lex/Preprocessor.h (+4-5)
  • (modified) clang/include/clang/Parse/LoopHint.h (+1-1)
  • (modified) clang/include/clang/Parse/Parser.h (+5-8)
  • (modified) clang/include/clang/Sema/ParsedAttr.h (-10)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/include/clang/Sema/SemaCodeCompletion.h (+1-2)
  • (modified) clang/include/clang/Sema/SemaObjC.h (+2-2)
  • (modified) clang/include/clang/Sema/SemaOpenACC.h (+1-1)
  • (modified) clang/lib/AST/OpenACCClause.cpp (+2-2)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+2-2)
  • (modified) clang/lib/Frontend/CompilerInstance.cpp (+28-25)
  • (modified) clang/lib/Frontend/FrontendActions.cpp (+2-2)
  • (modified) clang/lib/Lex/PPDirectives.cpp (+11-11)
  • (modified) clang/lib/Lex/PPLexerChange.cpp (+3-3)
  • (modified) clang/lib/Lex/Pragma.cpp (+35-38)
  • (modified) clang/lib/Lex/Preprocessor.cpp (+8-8)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+14-14)
  • (modified) clang/lib/Parse/ParseExpr.cpp (+4-3)
  • (modified) clang/lib/Parse/ParseHLSL.cpp (+1-1)
  • (modified) clang/lib/Parse/ParseObjc.cpp (+18-20)
  • (modified) clang/lib/Parse/ParseOpenACC.cpp (+7-5)
  • (modified) clang/lib/Parse/ParsePragma.cpp (+7-8)
  • (modified) clang/lib/Parse/ParseStmt.cpp (+3-3)
  • (modified) clang/lib/Parse/Parser.cpp (+9-10)
  • (modified) clang/lib/Sema/ParsedAttr.cpp (-8)
  • (modified) clang/lib/Sema/SemaARM.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+65-59)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+19-16)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+6-6)
  • (modified) clang/lib/Sema/SemaModule.cpp (+23-19)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+23-22)
  • (modified) clang/lib/Sema/SemaOpenACCClause.cpp (+6-5)
  • (modified) clang/lib/Sema/SemaStmtAttr.cpp (+16-13)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+12-12)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+5-5)
  • (modified) clang/lib/Sema/SemaType.cpp (+6-7)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+1-1)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+4-4)
  • (modified) clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp (+1-1)
  • (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (+4-2)
  • (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp (+8-9)
diff --git a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
index 3bb30fd15b2e1..4c916fa30685b 100644
--- a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
+++ b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
@@ -547,8 +547,8 @@ void PPCallbacksTracker::appendArgument(const char *Name, ModuleIdPath Value) {
     if (I)
       SS << ", ";
     SS << "{"
-       << "Name: " << Value[I].first->getName() << ", "
-       << "Loc: " << getSourceLocationString(PP, Value[I].second) << "}";
+       << "Name: " << Value[I].getIdentifierInfo()->getName() << ", "
+       << "Loc: " << getSourceLocationString(PP, Value[I].getLoc()) << "}";
   }
   SS << "]";
   appendArgument(Name, SS.str());
diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index 681567228cbb0..f18a6cf62f2c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -258,7 +258,7 @@ inline bool operator!=(const OpenACCBindClause &LHS,
   return !(LHS == RHS);
 }
 
-using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
+using DeviceTypeArgument = IdentifierLoc;
 /// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or
 /// an identifier. The 'asterisk' means 'the rest'.
 class OpenACCDeviceTypeClause final
@@ -280,16 +280,16 @@ class OpenACCDeviceTypeClause final
         "Invalid clause kind for device-type");
 
     assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) {
-      return Arg.second.isInvalid();
+      return Arg.getLoc().isInvalid();
     }) && "Invalid SourceLocation for an argument");
 
-    assert(
-        (Archs.size() == 1 || !llvm::any_of(Archs,
-                                            [](const DeviceTypeArgument &Arg) {
-                                              return Arg.first == nullptr;
-                                            })) &&
-        "Only a single asterisk version is permitted, and must be the "
-        "only one");
+    assert((Archs.size() == 1 ||
+            !llvm::any_of(Archs,
+                          [](const DeviceTypeArgument &Arg) {
+                            return Arg.getIdentifierInfo() == nullptr;
+                          })) &&
+           "Only a single asterisk version is permitted, and must be the "
+           "only one");
 
     std::uninitialized_copy(Archs.begin(), Archs.end(),
                             getTrailingObjects<DeviceTypeArgument>());
@@ -302,7 +302,7 @@ class OpenACCDeviceTypeClause final
   }
   bool hasAsterisk() const {
     return getArchitectures().size() > 0 &&
-           getArchitectures()[0].first == nullptr;
+           getArchitectures()[0].getIdentifierInfo() == nullptr;
   }
 
   ArrayRef<DeviceTypeArgument> getArchitectures() const {
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
index 0347880244a40..1275b056227b5 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -76,9 +77,6 @@ inline bool isReservedInAllContexts(ReservedIdentifierStatus Status) {
          Status != ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
 }
 
-/// A simple pair of identifier info and location.
-using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
-
 /// IdentifierInfo and other related classes are aligned to
 /// 8 bytes so that DeclarationName can use the lower 3 bits
 /// of a pointer to one of these classes.
@@ -1165,6 +1163,28 @@ class SelectorTable {
   static std::string getPropertyNameFromSetterSelector(Selector Sel);
 };
 
+/// A simple pair of identifier info and location.
+class IdentifierLoc {
+  SourceLocation Loc;
+  IdentifierInfo *II = nullptr;
+
+public:
+  IdentifierLoc() = default;
+  IdentifierLoc(SourceLocation L, IdentifierInfo *Ident) : Loc(L), II(Ident) {}
+
+  void setLoc(SourceLocation L) { Loc = L; }
+  void setIdentifierInfo(IdentifierInfo *Ident) { II = Ident; }
+  SourceLocation getLoc() const { return Loc; }
+  IdentifierInfo *getIdentifierInfo() const { return II; }
+
+  bool operator==(const IdentifierLoc &X) const {
+    return Loc == X.Loc && II == X.II;
+  }
+
+  bool operator!=(const IdentifierLoc &X) const {
+    return Loc != X.Loc || II != X.II;
+  }
+};
 }  // namespace clang
 
 namespace llvm {
diff --git a/clang/include/clang/Lex/ModuleLoader.h b/clang/include/clang/Lex/ModuleLoader.h
index f880a9091a2ed..a58407200c41c 100644
--- a/clang/include/clang/Lex/ModuleLoader.h
+++ b/clang/include/clang/Lex/ModuleLoader.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_LEX_MODULELOADER_H
 #define LLVM_CLANG_LEX_MODULELOADER_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
@@ -29,7 +30,7 @@ class IdentifierInfo;
 
 /// A sequence of identifier/location pairs used to describe a particular
 /// module or submodule, e.g., std.vector.
-using ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>;
+using ModuleIdPath = ArrayRef<IdentifierLoc>;
 
 /// Describes the result of attempting to load a module.
 class ModuleLoadResult {
diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h
index 46cc564086f1c..313b730afbab8 100644
--- a/clang/include/clang/Lex/PPCallbacks.h
+++ b/clang/include/clang/Lex/PPCallbacks.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_LEX_PPCALLBACKS_H
 
 #include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/ModuleLoader.h"
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 24bb524783e93..f8f2f567f9171 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -327,7 +327,7 @@ class Preprocessor {
   SourceLocation ModuleImportLoc;
 
   /// The import path for named module that we're currently processing.
-  SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> NamedModuleImportPath;
+  SmallVector<IdentifierLoc, 2> NamedModuleImportPath;
 
   llvm::DenseMap<FileID, SmallVector<const char *>> CheckPoints;
   unsigned CheckPointCounter = 0;
@@ -622,7 +622,7 @@ class Preprocessor {
 
   /// The identifier and source location of the currently-active
   /// \#pragma clang arc_cf_code_audited begin.
-  std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo;
+  IdentifierLoc PragmaARCCFCodeAuditedInfo;
 
   /// The source location of the currently-active
   /// \#pragma clang assume_nonnull begin.
@@ -1998,8 +1998,7 @@ class Preprocessor {
   /// arc_cf_code_audited begin.
   ///
   /// Returns an invalid location if there is no such pragma active.
-  std::pair<IdentifierInfo *, SourceLocation>
-  getPragmaARCCFCodeAuditedInfo() const {
+  IdentifierLoc getPragmaARCCFCodeAuditedInfo() const {
     return PragmaARCCFCodeAuditedInfo;
   }
 
@@ -2007,7 +2006,7 @@ class Preprocessor {
   /// arc_cf_code_audited begin.  An invalid location ends the pragma.
   void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident,
                                      SourceLocation Loc) {
-    PragmaARCCFCodeAuditedInfo = {Ident, Loc};
+    PragmaARCCFCodeAuditedInfo = IdentifierLoc(Loc, Ident);
   }
 
   /// The location of the currently-active \#pragma clang
diff --git a/clang/include/clang/Parse/LoopHint.h b/clang/include/clang/Parse/LoopHint.h
index cec5605ea3615..72be043d3c5a4 100644
--- a/clang/include/clang/Parse/LoopHint.h
+++ b/clang/include/clang/Parse/LoopHint.h
@@ -9,12 +9,12 @@
 #ifndef LLVM_CLANG_PARSE_LOOPHINT_H
 #define LLVM_CLANG_PARSE_LOOPHINT_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/SourceLocation.h"
 
 namespace clang {
 
 class Expr;
-struct IdentifierLoc;
 
 /// Loop optimization hint for loop and unroll pragmas.
 struct LoopHint {
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 9ebcf144ba59e..662f54d0e8d8a 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1725,8 +1725,8 @@ class Parser : public CodeCompletionHandler {
   ObjCTypeParamList *parseObjCTypeParamList();
   ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
       ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
-      SmallVectorImpl<IdentifierLocPair> &protocolIdents,
-      SourceLocation &rAngleLoc, bool mayBeProtocolList = true);
+      SmallVectorImpl<IdentifierLoc> &protocolIdents, SourceLocation &rAngleLoc,
+      bool mayBeProtocolList = true);
 
   void HelperActionsForIvarDeclarations(ObjCContainerDecl *interfaceDecl,
                                         SourceLocation atLoc,
@@ -3818,8 +3818,7 @@ class Parser : public CodeCompletionHandler {
                                SourceLocation Loc,
                                llvm::SmallVectorImpl<Expr *> &IntExprs);
   /// Parses the 'device-type-list', which is a list of identifiers.
-  bool ParseOpenACCDeviceTypeList(
-      llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>> &Archs);
+  bool ParseOpenACCDeviceTypeList(llvm::SmallVector<IdentifierLoc> &Archs);
   /// Parses the 'async-argument', which is an integral value with two
   /// 'special' values that are likely negative (but come from Macros).
   OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
@@ -3951,10 +3950,8 @@ class Parser : public CodeCompletionHandler {
     return false;
   }
 
-  bool ParseModuleName(
-      SourceLocation UseLoc,
-      SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
-      bool IsImport);
+  bool ParseModuleName(SourceLocation UseLoc,
+                       SmallVectorImpl<IdentifierLoc> &Path, bool IsImport);
 
   //===--------------------------------------------------------------------===//
   // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index b88b871dc8821..428d3111de80d 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -40,7 +40,6 @@ class LangOptions;
 class Sema;
 class Stmt;
 class TargetInfo;
-struct IdentifierLoc;
 
 /// Represents information about a change in availability for
 /// an entity, which is part of the encoding of the 'availability'
@@ -99,15 +98,6 @@ struct PropertyData {
 
 } // namespace detail
 
-/// Wraps an identifier and optional source location for the identifier.
-struct IdentifierLoc {
-  SourceLocation Loc;
-  IdentifierInfo *Ident;
-
-  static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
-                               IdentifierInfo *Ident);
-};
-
 /// A union of the various pointer types that can be passed to an
 /// ParsedAttr as an argument.
 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fe37fd7701ce3..1f23b754a69cb 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -143,7 +143,7 @@ enum class LangAS : unsigned int;
 class LocalInstantiationScope;
 class LookupResult;
 class MangleNumberingContext;
-typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath;
+typedef ArrayRef<IdentifierLoc> ModuleIdPath;
 class ModuleLoader;
 class MultiLevelTemplateArgumentList;
 struct NormalizedConstraint;
diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h b/clang/include/clang/Sema/SemaCodeCompletion.h
index 72159de3a6e72..3029e56e5cfe2 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -193,8 +193,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar);
   void CodeCompleteObjCSelector(Scope *S,
                                 ArrayRef<const IdentifierInfo *> SelIdents);
-  void
-  CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLocPair> Protocols);
+  void CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLoc> Protocols);
   void CodeCompleteObjCProtocolDecl(Scope *S);
   void CodeCompleteObjCInterfaceDecl(Scope *S);
   void CodeCompleteObjCClassForwardDecl(Scope *S);
diff --git a/clang/include/clang/Sema/SemaObjC.h b/clang/include/clang/Sema/SemaObjC.h
index 791a7f45b832f..4cda41a82b61f 100644
--- a/clang/include/clang/Sema/SemaObjC.h
+++ b/clang/include/clang/Sema/SemaObjC.h
@@ -307,11 +307,11 @@ class SemaObjC : public SemaBase {
 
   DeclGroupPtrTy
   ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
-                                  ArrayRef<IdentifierLocPair> IdentList,
+                                  ArrayRef<IdentifierLoc> IdentList,
                                   const ParsedAttributesView &attrList);
 
   void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
-                               ArrayRef<IdentifierLocPair> ProtocolId,
+                               ArrayRef<IdentifierLoc> ProtocolId,
                                SmallVectorImpl<Decl *> &Protocols);
 
   void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId,
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index 4c3a13a3b044f..8d31d46444c7e 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -212,7 +212,7 @@ class SemaOpenACC : public SemaBase {
   } LoopWithoutSeqInfo;
 
   // Redeclaration of the version in OpenACCClause.h.
-  using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
+  using DeviceTypeArgument = IdentifierLoc;
 
   /// A type to represent all the data for an OpenACC Clause that has been
   /// parsed, but not yet created/semantically analyzed. This is effectively a
diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp
index d7cbb51335359..2820d7b288658 100644
--- a/clang/lib/AST/OpenACCClause.cpp
+++ b/clang/lib/AST/OpenACCClause.cpp
@@ -891,10 +891,10 @@ void OpenACCClausePrinter::VisitDeviceTypeClause(
   OS << "(";
   llvm::interleaveComma(C.getArchitectures(), OS,
                         [&](const DeviceTypeArgument &Arch) {
-                          if (Arch.first == nullptr)
+                          if (Arch.getIdentifierInfo() == nullptr)
                             OS << "*";
                           else
-                            OS << Arch.first->getName();
+                            OS << Arch.getIdentifierInfo()->getName();
                         });
   OS << ")";
 }
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index c8b459ee78e6b..1bd94a3ac6431 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -500,10 +500,10 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
       llvm::interleaveComma(
           cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS,
           [&](const DeviceTypeArgument &Arch) {
-            if (Arch.first == nullptr)
+            if (Arch.getIdentifierInfo() == nullptr)
               OS << "*";
             else
-              OS << Arch.first->getName();
+              OS << Arch.getIdentifierInfo()->getName();
           });
       OS << ")";
       break;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 243e0a3c15b05..93e4e31c2891d 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -35,6 +35,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
@@ -2009,8 +2010,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
                              Module::NameVisibilityKind Visibility,
                              bool IsInclusionDirective) {
   // Determine what file we're searching from.
-  StringRef ModuleName = Path[0].first->getName();
-  SourceLocation ModuleNameLoc = Path[0].second;
+  StringRef ModuleName = Path[0].getIdentifierInfo()->getName();
+  SourceLocation ModuleNameLoc = Path[0].getLoc();
 
   // If we've already handled this import, just return the cached result.
   // This one-element cache is important to eliminate redundant diagnostics
@@ -2026,7 +2027,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   // If we don't already have information on this module, load the module now.
   Module *Module = nullptr;
   ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap();
-  if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
+  if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].getIdentifierInfo())) {
     // Use the cached result, which may be nullptr.
     Module = *MaybeModule;
     // Config macros are already checked before building a module, but they need
@@ -2046,7 +2047,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
     // * `Preprocessor::HandleHeaderIncludeOrImport` will never call this
     //   function as the `#include` or `#import` is textual.
 
-    MM.cacheModuleLoad(*Path[0].first, Module);
+    MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
   } else {
     ModuleLoadResult Result = findOrCompileModuleAndReadAST(
         ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
@@ -2055,7 +2056,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
     if (!Result)
       DisableGeneratingGlobalModuleIndex = true;
     Module = Result;
-    MM.cacheModuleLoad(*Path[0].first, Module);
+    MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
   }
 
   // If we never found the module, fail.  Otherwise, verify the module and link
@@ -2067,7 +2068,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   // a submodule.
   bool MapPrivateSubModToTopLevel = false;
   for (unsigned I = 1, N = Path.size(); I != N; ++I) {
-    StringRef Name = Path[I].first->getName();
+    StringRef Name = Path[I].getIdentifierInfo()->getName();
     clang::Module *Sub = Module->findSubmodule(Name);
 
     // If the user is requesting Foo.Private and it doesn't exist, try to
@@ -2078,10 +2079,10 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
       SmallString<128> PrivateModule(Module->Name);
       PrivateModule.append("_Private");
 
-      SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath;
+      SmallVector<IdentifierLoc, 2> PrivPath;
       auto &II = PP->getIdentifierTable().get(
           PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID());
-      PrivPath.push_back(std::make_pair(&II, Path[0].second));
+      PrivPath.emplace_back(Path[0].getLoc(), &II);
 
       std::string FileName;
       // If there is a modulemap module or prebuilt module, load it.
@@ -2095,11 +2096,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
         PP->markClangModuleAsAffecting(Module);
         if (!getDiagnostics().isIgnored(
                 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
-          getDiagnostics().Report(Path[I].second,
+          getDiagnostics().Report(Path[I].getLoc(),
                                   diag::warn_no_priv_submodule_use_toplevel)
-              << Path[I].first << Module->getFullModuleName() << PrivateModule
-              << SourceRange(Path[0].second, Path[I].second)
-              << FixItHint::CreateReplacement(SourceRange(Path[0].second),
+              << Path[I].getIdentifierInfo() << Module->getFullModuleName()
+              << PrivateModule
+              << SourceRange(Path[0].getLoc(), Path[I].getLoc())
+              << FixItHint::CreateReplacement(SourceRange(Path[0].getLoc()),
                                               PrivateModule);
           getDiagnostics().Report(Sub->DefinitionLoc,
                                   diag::note_private_top_level_defined);
@@ -2128,10 +2130,11 @@ Com...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Apr 17, 2025

@llvm/pr-subscribers-hlsl

Author: None (yronglin)

Changes

This PR reland #135808, fixed some missed changes in LLDB.
I found this issue when I working on #107168.

Currently we have many similiar data structures like:

  • std::pair<IdentifierInfo *, SourceLocation>.
  • Element type of ModuleIdPath.
  • IdentifierLocPair.
  • IdentifierLoc.

This PR unify these data structures to IdentifierLoc, moved IdentifierLoc definition to SourceLocation.h, and deleted other similer data structures.


Patch is 110.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136077.diff

47 Files Affected:

  • (modified) clang-tools-extra/pp-trace/PPCallbacksTracker.cpp (+2-2)
  • (modified) clang/include/clang/AST/OpenACCClause.h (+10-10)
  • (modified) clang/include/clang/Basic/IdentifierTable.h (+23-3)
  • (modified) clang/include/clang/Lex/ModuleLoader.h (+2-1)
  • (modified) clang/include/clang/Lex/PPCallbacks.h (+1)
  • (modified) clang/include/clang/Lex/Preprocessor.h (+4-5)
  • (modified) clang/include/clang/Parse/LoopHint.h (+1-1)
  • (modified) clang/include/clang/Parse/Parser.h (+5-8)
  • (modified) clang/include/clang/Sema/ParsedAttr.h (-10)
  • (modified) clang/include/clang/Sema/Sema.h (+1-1)
  • (modified) clang/include/clang/Sema/SemaCodeCompletion.h (+1-2)
  • (modified) clang/include/clang/Sema/SemaObjC.h (+2-2)
  • (modified) clang/include/clang/Sema/SemaOpenACC.h (+1-1)
  • (modified) clang/lib/AST/OpenACCClause.cpp (+2-2)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+2-2)
  • (modified) clang/lib/Frontend/CompilerInstance.cpp (+28-25)
  • (modified) clang/lib/Frontend/FrontendActions.cpp (+2-2)
  • (modified) clang/lib/Lex/PPDirectives.cpp (+11-11)
  • (modified) clang/lib/Lex/PPLexerChange.cpp (+3-3)
  • (modified) clang/lib/Lex/Pragma.cpp (+35-38)
  • (modified) clang/lib/Lex/Preprocessor.cpp (+8-8)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+14-14)
  • (modified) clang/lib/Parse/ParseExpr.cpp (+4-3)
  • (modified) clang/lib/Parse/ParseHLSL.cpp (+1-1)
  • (modified) clang/lib/Parse/ParseObjc.cpp (+18-20)
  • (modified) clang/lib/Parse/ParseOpenACC.cpp (+7-5)
  • (modified) clang/lib/Parse/ParsePragma.cpp (+7-8)
  • (modified) clang/lib/Parse/ParseStmt.cpp (+3-3)
  • (modified) clang/lib/Parse/Parser.cpp (+9-10)
  • (modified) clang/lib/Sema/ParsedAttr.cpp (-8)
  • (modified) clang/lib/Sema/SemaARM.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+65-59)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+19-16)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+6-6)
  • (modified) clang/lib/Sema/SemaModule.cpp (+23-19)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+23-22)
  • (modified) clang/lib/Sema/SemaOpenACCClause.cpp (+6-5)
  • (modified) clang/lib/Sema/SemaStmtAttr.cpp (+16-13)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+12-12)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+5-5)
  • (modified) clang/lib/Sema/SemaType.cpp (+6-7)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+1-1)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+4-4)
  • (modified) clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp (+1-1)
  • (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (+4-2)
  • (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp (+8-9)
diff --git a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
index 3bb30fd15b2e1..4c916fa30685b 100644
--- a/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
+++ b/clang-tools-extra/pp-trace/PPCallbacksTracker.cpp
@@ -547,8 +547,8 @@ void PPCallbacksTracker::appendArgument(const char *Name, ModuleIdPath Value) {
     if (I)
       SS << ", ";
     SS << "{"
-       << "Name: " << Value[I].first->getName() << ", "
-       << "Loc: " << getSourceLocationString(PP, Value[I].second) << "}";
+       << "Name: " << Value[I].getIdentifierInfo()->getName() << ", "
+       << "Loc: " << getSourceLocationString(PP, Value[I].getLoc()) << "}";
   }
   SS << "]";
   appendArgument(Name, SS.str());
diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index 681567228cbb0..f18a6cf62f2c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -258,7 +258,7 @@ inline bool operator!=(const OpenACCBindClause &LHS,
   return !(LHS == RHS);
 }
 
-using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
+using DeviceTypeArgument = IdentifierLoc;
 /// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or
 /// an identifier. The 'asterisk' means 'the rest'.
 class OpenACCDeviceTypeClause final
@@ -280,16 +280,16 @@ class OpenACCDeviceTypeClause final
         "Invalid clause kind for device-type");
 
     assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) {
-      return Arg.second.isInvalid();
+      return Arg.getLoc().isInvalid();
     }) && "Invalid SourceLocation for an argument");
 
-    assert(
-        (Archs.size() == 1 || !llvm::any_of(Archs,
-                                            [](const DeviceTypeArgument &Arg) {
-                                              return Arg.first == nullptr;
-                                            })) &&
-        "Only a single asterisk version is permitted, and must be the "
-        "only one");
+    assert((Archs.size() == 1 ||
+            !llvm::any_of(Archs,
+                          [](const DeviceTypeArgument &Arg) {
+                            return Arg.getIdentifierInfo() == nullptr;
+                          })) &&
+           "Only a single asterisk version is permitted, and must be the "
+           "only one");
 
     std::uninitialized_copy(Archs.begin(), Archs.end(),
                             getTrailingObjects<DeviceTypeArgument>());
@@ -302,7 +302,7 @@ class OpenACCDeviceTypeClause final
   }
   bool hasAsterisk() const {
     return getArchitectures().size() > 0 &&
-           getArchitectures()[0].first == nullptr;
+           getArchitectures()[0].getIdentifierInfo() == nullptr;
   }
 
   ArrayRef<DeviceTypeArgument> getArchitectures() const {
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
index 0347880244a40..1275b056227b5 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -76,9 +77,6 @@ inline bool isReservedInAllContexts(ReservedIdentifierStatus Status) {
          Status != ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
 }
 
-/// A simple pair of identifier info and location.
-using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
-
 /// IdentifierInfo and other related classes are aligned to
 /// 8 bytes so that DeclarationName can use the lower 3 bits
 /// of a pointer to one of these classes.
@@ -1165,6 +1163,28 @@ class SelectorTable {
   static std::string getPropertyNameFromSetterSelector(Selector Sel);
 };
 
+/// A simple pair of identifier info and location.
+class IdentifierLoc {
+  SourceLocation Loc;
+  IdentifierInfo *II = nullptr;
+
+public:
+  IdentifierLoc() = default;
+  IdentifierLoc(SourceLocation L, IdentifierInfo *Ident) : Loc(L), II(Ident) {}
+
+  void setLoc(SourceLocation L) { Loc = L; }
+  void setIdentifierInfo(IdentifierInfo *Ident) { II = Ident; }
+  SourceLocation getLoc() const { return Loc; }
+  IdentifierInfo *getIdentifierInfo() const { return II; }
+
+  bool operator==(const IdentifierLoc &X) const {
+    return Loc == X.Loc && II == X.II;
+  }
+
+  bool operator!=(const IdentifierLoc &X) const {
+    return Loc != X.Loc || II != X.II;
+  }
+};
 }  // namespace clang
 
 namespace llvm {
diff --git a/clang/include/clang/Lex/ModuleLoader.h b/clang/include/clang/Lex/ModuleLoader.h
index f880a9091a2ed..a58407200c41c 100644
--- a/clang/include/clang/Lex/ModuleLoader.h
+++ b/clang/include/clang/Lex/ModuleLoader.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_LEX_MODULELOADER_H
 #define LLVM_CLANG_LEX_MODULELOADER_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
@@ -29,7 +30,7 @@ class IdentifierInfo;
 
 /// A sequence of identifier/location pairs used to describe a particular
 /// module or submodule, e.g., std.vector.
-using ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>;
+using ModuleIdPath = ArrayRef<IdentifierLoc>;
 
 /// Describes the result of attempting to load a module.
 class ModuleLoadResult {
diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h
index 46cc564086f1c..313b730afbab8 100644
--- a/clang/include/clang/Lex/PPCallbacks.h
+++ b/clang/include/clang/Lex/PPCallbacks.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_LEX_PPCALLBACKS_H
 
 #include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/ModuleLoader.h"
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 24bb524783e93..f8f2f567f9171 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -327,7 +327,7 @@ class Preprocessor {
   SourceLocation ModuleImportLoc;
 
   /// The import path for named module that we're currently processing.
-  SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> NamedModuleImportPath;
+  SmallVector<IdentifierLoc, 2> NamedModuleImportPath;
 
   llvm::DenseMap<FileID, SmallVector<const char *>> CheckPoints;
   unsigned CheckPointCounter = 0;
@@ -622,7 +622,7 @@ class Preprocessor {
 
   /// The identifier and source location of the currently-active
   /// \#pragma clang arc_cf_code_audited begin.
-  std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo;
+  IdentifierLoc PragmaARCCFCodeAuditedInfo;
 
   /// The source location of the currently-active
   /// \#pragma clang assume_nonnull begin.
@@ -1998,8 +1998,7 @@ class Preprocessor {
   /// arc_cf_code_audited begin.
   ///
   /// Returns an invalid location if there is no such pragma active.
-  std::pair<IdentifierInfo *, SourceLocation>
-  getPragmaARCCFCodeAuditedInfo() const {
+  IdentifierLoc getPragmaARCCFCodeAuditedInfo() const {
     return PragmaARCCFCodeAuditedInfo;
   }
 
@@ -2007,7 +2006,7 @@ class Preprocessor {
   /// arc_cf_code_audited begin.  An invalid location ends the pragma.
   void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident,
                                      SourceLocation Loc) {
-    PragmaARCCFCodeAuditedInfo = {Ident, Loc};
+    PragmaARCCFCodeAuditedInfo = IdentifierLoc(Loc, Ident);
   }
 
   /// The location of the currently-active \#pragma clang
diff --git a/clang/include/clang/Parse/LoopHint.h b/clang/include/clang/Parse/LoopHint.h
index cec5605ea3615..72be043d3c5a4 100644
--- a/clang/include/clang/Parse/LoopHint.h
+++ b/clang/include/clang/Parse/LoopHint.h
@@ -9,12 +9,12 @@
 #ifndef LLVM_CLANG_PARSE_LOOPHINT_H
 #define LLVM_CLANG_PARSE_LOOPHINT_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/SourceLocation.h"
 
 namespace clang {
 
 class Expr;
-struct IdentifierLoc;
 
 /// Loop optimization hint for loop and unroll pragmas.
 struct LoopHint {
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 9ebcf144ba59e..662f54d0e8d8a 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1725,8 +1725,8 @@ class Parser : public CodeCompletionHandler {
   ObjCTypeParamList *parseObjCTypeParamList();
   ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
       ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
-      SmallVectorImpl<IdentifierLocPair> &protocolIdents,
-      SourceLocation &rAngleLoc, bool mayBeProtocolList = true);
+      SmallVectorImpl<IdentifierLoc> &protocolIdents, SourceLocation &rAngleLoc,
+      bool mayBeProtocolList = true);
 
   void HelperActionsForIvarDeclarations(ObjCContainerDecl *interfaceDecl,
                                         SourceLocation atLoc,
@@ -3818,8 +3818,7 @@ class Parser : public CodeCompletionHandler {
                                SourceLocation Loc,
                                llvm::SmallVectorImpl<Expr *> &IntExprs);
   /// Parses the 'device-type-list', which is a list of identifiers.
-  bool ParseOpenACCDeviceTypeList(
-      llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>> &Archs);
+  bool ParseOpenACCDeviceTypeList(llvm::SmallVector<IdentifierLoc> &Archs);
   /// Parses the 'async-argument', which is an integral value with two
   /// 'special' values that are likely negative (but come from Macros).
   OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
@@ -3951,10 +3950,8 @@ class Parser : public CodeCompletionHandler {
     return false;
   }
 
-  bool ParseModuleName(
-      SourceLocation UseLoc,
-      SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
-      bool IsImport);
+  bool ParseModuleName(SourceLocation UseLoc,
+                       SmallVectorImpl<IdentifierLoc> &Path, bool IsImport);
 
   //===--------------------------------------------------------------------===//
   // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index b88b871dc8821..428d3111de80d 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -40,7 +40,6 @@ class LangOptions;
 class Sema;
 class Stmt;
 class TargetInfo;
-struct IdentifierLoc;
 
 /// Represents information about a change in availability for
 /// an entity, which is part of the encoding of the 'availability'
@@ -99,15 +98,6 @@ struct PropertyData {
 
 } // namespace detail
 
-/// Wraps an identifier and optional source location for the identifier.
-struct IdentifierLoc {
-  SourceLocation Loc;
-  IdentifierInfo *Ident;
-
-  static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
-                               IdentifierInfo *Ident);
-};
-
 /// A union of the various pointer types that can be passed to an
 /// ParsedAttr as an argument.
 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fe37fd7701ce3..1f23b754a69cb 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -143,7 +143,7 @@ enum class LangAS : unsigned int;
 class LocalInstantiationScope;
 class LookupResult;
 class MangleNumberingContext;
-typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath;
+typedef ArrayRef<IdentifierLoc> ModuleIdPath;
 class ModuleLoader;
 class MultiLevelTemplateArgumentList;
 struct NormalizedConstraint;
diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h b/clang/include/clang/Sema/SemaCodeCompletion.h
index 72159de3a6e72..3029e56e5cfe2 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -193,8 +193,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar);
   void CodeCompleteObjCSelector(Scope *S,
                                 ArrayRef<const IdentifierInfo *> SelIdents);
-  void
-  CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLocPair> Protocols);
+  void CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLoc> Protocols);
   void CodeCompleteObjCProtocolDecl(Scope *S);
   void CodeCompleteObjCInterfaceDecl(Scope *S);
   void CodeCompleteObjCClassForwardDecl(Scope *S);
diff --git a/clang/include/clang/Sema/SemaObjC.h b/clang/include/clang/Sema/SemaObjC.h
index 791a7f45b832f..4cda41a82b61f 100644
--- a/clang/include/clang/Sema/SemaObjC.h
+++ b/clang/include/clang/Sema/SemaObjC.h
@@ -307,11 +307,11 @@ class SemaObjC : public SemaBase {
 
   DeclGroupPtrTy
   ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
-                                  ArrayRef<IdentifierLocPair> IdentList,
+                                  ArrayRef<IdentifierLoc> IdentList,
                                   const ParsedAttributesView &attrList);
 
   void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
-                               ArrayRef<IdentifierLocPair> ProtocolId,
+                               ArrayRef<IdentifierLoc> ProtocolId,
                                SmallVectorImpl<Decl *> &Protocols);
 
   void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId,
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index 4c3a13a3b044f..8d31d46444c7e 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -212,7 +212,7 @@ class SemaOpenACC : public SemaBase {
   } LoopWithoutSeqInfo;
 
   // Redeclaration of the version in OpenACCClause.h.
-  using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
+  using DeviceTypeArgument = IdentifierLoc;
 
   /// A type to represent all the data for an OpenACC Clause that has been
   /// parsed, but not yet created/semantically analyzed. This is effectively a
diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp
index d7cbb51335359..2820d7b288658 100644
--- a/clang/lib/AST/OpenACCClause.cpp
+++ b/clang/lib/AST/OpenACCClause.cpp
@@ -891,10 +891,10 @@ void OpenACCClausePrinter::VisitDeviceTypeClause(
   OS << "(";
   llvm::interleaveComma(C.getArchitectures(), OS,
                         [&](const DeviceTypeArgument &Arch) {
-                          if (Arch.first == nullptr)
+                          if (Arch.getIdentifierInfo() == nullptr)
                             OS << "*";
                           else
-                            OS << Arch.first->getName();
+                            OS << Arch.getIdentifierInfo()->getName();
                         });
   OS << ")";
 }
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index c8b459ee78e6b..1bd94a3ac6431 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -500,10 +500,10 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
       llvm::interleaveComma(
           cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS,
           [&](const DeviceTypeArgument &Arch) {
-            if (Arch.first == nullptr)
+            if (Arch.getIdentifierInfo() == nullptr)
               OS << "*";
             else
-              OS << Arch.first->getName();
+              OS << Arch.getIdentifierInfo()->getName();
           });
       OS << ")";
       break;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 243e0a3c15b05..93e4e31c2891d 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -35,6 +35,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
@@ -2009,8 +2010,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
                              Module::NameVisibilityKind Visibility,
                              bool IsInclusionDirective) {
   // Determine what file we're searching from.
-  StringRef ModuleName = Path[0].first->getName();
-  SourceLocation ModuleNameLoc = Path[0].second;
+  StringRef ModuleName = Path[0].getIdentifierInfo()->getName();
+  SourceLocation ModuleNameLoc = Path[0].getLoc();
 
   // If we've already handled this import, just return the cached result.
   // This one-element cache is important to eliminate redundant diagnostics
@@ -2026,7 +2027,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   // If we don't already have information on this module, load the module now.
   Module *Module = nullptr;
   ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap();
-  if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
+  if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].getIdentifierInfo())) {
     // Use the cached result, which may be nullptr.
     Module = *MaybeModule;
     // Config macros are already checked before building a module, but they need
@@ -2046,7 +2047,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
     // * `Preprocessor::HandleHeaderIncludeOrImport` will never call this
     //   function as the `#include` or `#import` is textual.
 
-    MM.cacheModuleLoad(*Path[0].first, Module);
+    MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
   } else {
     ModuleLoadResult Result = findOrCompileModuleAndReadAST(
         ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
@@ -2055,7 +2056,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
     if (!Result)
       DisableGeneratingGlobalModuleIndex = true;
     Module = Result;
-    MM.cacheModuleLoad(*Path[0].first, Module);
+    MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
   }
 
   // If we never found the module, fail.  Otherwise, verify the module and link
@@ -2067,7 +2068,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   // a submodule.
   bool MapPrivateSubModToTopLevel = false;
   for (unsigned I = 1, N = Path.size(); I != N; ++I) {
-    StringRef Name = Path[I].first->getName();
+    StringRef Name = Path[I].getIdentifierInfo()->getName();
     clang::Module *Sub = Module->findSubmodule(Name);
 
     // If the user is requesting Foo.Private and it doesn't exist, try to
@@ -2078,10 +2079,10 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
       SmallString<128> PrivateModule(Module->Name);
       PrivateModule.append("_Private");
 
-      SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath;
+      SmallVector<IdentifierLoc, 2> PrivPath;
       auto &II = PP->getIdentifierTable().get(
           PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID());
-      PrivPath.push_back(std::make_pair(&II, Path[0].second));
+      PrivPath.emplace_back(Path[0].getLoc(), &II);
 
       std::string FileName;
       // If there is a modulemap module or prebuilt module, load it.
@@ -2095,11 +2096,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
         PP->markClangModuleAsAffecting(Module);
         if (!getDiagnostics().isIgnored(
                 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
-          getDiagnostics().Report(Path[I].second,
+          getDiagnostics().Report(Path[I].getLoc(),
                                   diag::warn_no_priv_submodule_use_toplevel)
-              << Path[I].first << Module->getFullModuleName() << PrivateModule
-              << SourceRange(Path[0].second, Path[I].second)
-              << FixItHint::CreateReplacement(SourceRange(Path[0].second),
+              << Path[I].getIdentifierInfo() << Module->getFullModuleName()
+              << PrivateModule
+              << SourceRange(Path[0].getLoc(), Path[I].getLoc())
+              << FixItHint::CreateReplacement(SourceRange(Path[0].getLoc()),
                                               PrivateModule);
           getDiagnostics().Report(Sub->DefinitionLoc,
                                   diag::note_private_top_level_defined);
@@ -2128,10 +2130,11 @@ Com...
[truncated]

@yronglin
Copy link
Contributor Author

Thanks for the review!

@yronglin yronglin merged commit d83b639 into llvm:main Apr 17, 2025
12 checks passed
@damyanp damyanp moved this to Closed in HLSL Support Apr 25, 2025
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
… data structures to `IdentifierLoc` (llvm#136077)

This PR reland llvm#135808, fixed
some missed changes in LLDB.
I found this issue when I working on
llvm#107168.

Currently we have many similiar data structures like:
- std::pair<IdentifierInfo *, SourceLocation>.
- Element type of ModuleIdPath.
- IdentifierLocPair.
- IdentifierLoc.

This PR unify these data structures to IdentifierLoc, moved
IdentifierLoc definition to SourceLocation.h, and deleted other similer
data structures.

---------

Signed-off-by: yronglin <[email protected]>
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
… data structures to `IdentifierLoc` (llvm#136077)

This PR reland llvm#135808, fixed
some missed changes in LLDB.
I found this issue when I working on
llvm#107168.

Currently we have many similiar data structures like:
- std::pair<IdentifierInfo *, SourceLocation>.
- Element type of ModuleIdPath.
- IdentifierLocPair.
- IdentifierLoc.

This PR unify these data structures to IdentifierLoc, moved
IdentifierLoc definition to SourceLocation.h, and deleted other similer
data structures.

---------

Signed-off-by: yronglin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 backend:ARM clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category clang-tools-extra HLSL HLSL Language Support lldb
Projects
Status: Closed
Development

Successfully merging this pull request may close these issues.

4 participants