================
@@ -3405,6 +3405,122 @@ getReplacedTemplateParameter(Decl *D, unsigned Index);
 /// If we have an implicit instantiation, adjust 'D' to refer to template.
 const Decl &adjustDeclToTemplate(const Decl &D);
 
+/// Represents an explicit instantiation of a template entity in source code.
+///
+/// This node records source location information for an explicit instantiation
+/// statement. It does not participate in name lookup (inherits from Decl, not
+/// NamedDecl), and does not affect code generation. The underlying
+/// specialization decl (FunctionDecl, VarDecl, CXXRecordDecl, etc.) continues
+/// to handle all semantic and codegen responsibilities.
+///
+/// \code
+///   template void ns::foo<int>(int);        // function template
+///   extern template struct ns::S<int>;      // class template (extern)
+///   template int ns::bar<int>;              // variable template
+///   template void ns::S<int>::method(int);  // member function
+/// \endcode
+class ExplicitInstantiationDecl : public Decl {
+  /// The underlying specialization being explicitly instantiated.
+  NamedDecl *Specialization = nullptr;
+
+  /// The source range of the entire explicit instantiation statement.
+  SourceRange Range;
+
+  /// Location of the 'extern' keyword (invalid if not extern template).
+  SourceLocation ExternLoc;
+
+  /// Location of the struct/class/union keyword (for class template and
+  /// nested class instantiations; invalid otherwise).
+  SourceLocation TagKWLoc;
+
+  /// Nested name specifier with source locations (e.g., ns::S<int>::).
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// Template arguments as written (e.g., <int>). Null if the template
+  /// arguments were deduced.
+  const ASTTemplateArgumentListInfo *TemplateArgsAsWritten = nullptr;
+
+  /// Location of the entity name (e.g., 'foo' in 'template void
+  /// ns::foo<int>(int)').
+  SourceLocation NameLoc;
+
+  /// Type source info for the declaration type:
+  ///   - Function templates / member functions: FunctionProtoTypeLoc with
+  ///     return type location and parameter type locations.
+  ///   - Variable templates / static data members: the declared type.
+  ///   - Class templates / nested classes: null.
+  TypeSourceInfo *TypeAsWritten = nullptr;
+
+  /// Whether this is a declaration (extern template) or definition (template).
+  LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
+  unsigned TSK : 3;
+
+  ExplicitInstantiationDecl(DeclContext *DC, SourceRange Range,
+                            NamedDecl *Specialization, SourceLocation 
ExternLoc,
+                            SourceLocation TemplateLoc, SourceLocation 
TagKWLoc,
+                            NestedNameSpecifierLoc QualifierLoc,
+                            const ASTTemplateArgumentListInfo *ArgsAsWritten,
+                            SourceLocation NameLoc,
+                            TypeSourceInfo *TypeAsWritten,
+                            TemplateSpecializationKind TSK)
+      : Decl(ExplicitInstantiation, DC, TemplateLoc),
+        Specialization(Specialization), Range(Range), ExternLoc(ExternLoc),
+        TagKWLoc(TagKWLoc), QualifierLoc(QualifierLoc),
+        TemplateArgsAsWritten(ArgsAsWritten), NameLoc(NameLoc),
+        TypeAsWritten(TypeAsWritten), TSK(TSK) {
+    assert((TSK == TSK_ExplicitInstantiationDeclaration) ==
----------------
mizvekov wrote:

We could probably assert more here, if you are already doing it.

For example, we should always have a NameLoc, Range and TemplateLoc, and the 
angle brackets at least I think.

https://github.com/llvm/llvm-project/pull/191658
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to