File indexing completed on 2026-05-10 08:37:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
0015 #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
0016
0017 #include "clang/Basic/OperatorKinds.h"
0018 #include "clang/Basic/SourceLocation.h"
0019 #include "clang/Basic/TemplateKinds.h"
0020 #include "clang/Sema/DeclSpec.h"
0021 #include "clang/Sema/Ownership.h"
0022 #include "llvm/ADT/SmallVector.h"
0023 #include <cassert>
0024 #include <cstdlib>
0025 #include <new>
0026
0027 namespace clang {
0028
0029 class ParsedTemplateArgument {
0030 public:
0031
0032 enum KindType {
0033
0034 Type,
0035
0036 NonType,
0037
0038 Template
0039 };
0040
0041
0042
0043
0044 ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
0045
0046
0047
0048
0049
0050 ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
0051 : Kind(Kind), Arg(Arg), Loc(Loc) { }
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 ParsedTemplateArgument(const CXXScopeSpec &SS,
0063 ParsedTemplateTy Template,
0064 SourceLocation TemplateLoc)
0065 : Kind(ParsedTemplateArgument::Template),
0066 Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {}
0067
0068
0069 bool isInvalid() const { return Arg == nullptr; }
0070
0071
0072 KindType getKind() const { return Kind; }
0073
0074
0075 ParsedType getAsType() const {
0076 assert(Kind == Type && "Not a template type argument");
0077 return ParsedType::getFromOpaquePtr(Arg);
0078 }
0079
0080
0081 Expr *getAsExpr() const {
0082 assert(Kind == NonType && "Not a non-type template argument");
0083 return static_cast<Expr*>(Arg);
0084 }
0085
0086
0087 ParsedTemplateTy getAsTemplate() const {
0088 assert(Kind == Template && "Not a template template argument");
0089 return ParsedTemplateTy::getFromOpaquePtr(Arg);
0090 }
0091
0092
0093 SourceLocation getLocation() const { return Loc; }
0094
0095
0096
0097 const CXXScopeSpec &getScopeSpec() const {
0098 assert(Kind == Template &&
0099 "Only template template arguments can have a scope specifier");
0100 return SS;
0101 }
0102
0103
0104
0105 SourceLocation getEllipsisLoc() const {
0106 assert(Kind == Template &&
0107 "Only template template arguments can have an ellipsis");
0108 return EllipsisLoc;
0109 }
0110
0111
0112
0113
0114
0115 ParsedTemplateArgument getTemplatePackExpansion(
0116 SourceLocation EllipsisLoc) const;
0117
0118 private:
0119 KindType Kind;
0120
0121
0122
0123
0124 void *Arg;
0125
0126
0127
0128 CXXScopeSpec SS;
0129
0130
0131 SourceLocation Loc;
0132
0133
0134
0135 SourceLocation EllipsisLoc;
0136 };
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 struct TemplateIdAnnotation final
0150 : private llvm::TrailingObjects<TemplateIdAnnotation,
0151 ParsedTemplateArgument> {
0152 friend TrailingObjects;
0153
0154
0155 SourceLocation TemplateKWLoc;
0156
0157
0158
0159 SourceLocation TemplateNameLoc;
0160
0161
0162 const IdentifierInfo *Name;
0163
0164
0165 OverloadedOperatorKind Operator;
0166
0167
0168
0169 ParsedTemplateTy Template;
0170
0171
0172
0173
0174 TemplateNameKind Kind;
0175
0176
0177
0178 SourceLocation LAngleLoc;
0179
0180
0181
0182 SourceLocation RAngleLoc;
0183
0184
0185 unsigned NumArgs;
0186
0187
0188
0189 bool ArgsInvalid;
0190
0191
0192 ParsedTemplateArgument *getTemplateArgs() {
0193 return getTrailingObjects<ParsedTemplateArgument>();
0194 }
0195
0196
0197
0198 static TemplateIdAnnotation *
0199 Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc,
0200 const IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
0201 ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
0202 SourceLocation LAngleLoc, SourceLocation RAngleLoc,
0203 ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid,
0204 SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
0205 TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
0206 totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
0207 TemplateIdAnnotation(TemplateKWLoc, TemplateNameLoc, Name,
0208 OperatorKind, OpaqueTemplateName, TemplateKind,
0209 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
0210 CleanupList.push_back(TemplateId);
0211 return TemplateId;
0212 }
0213
0214 void Destroy() {
0215 for (ParsedTemplateArgument &A :
0216 llvm::make_range(getTemplateArgs(), getTemplateArgs() + NumArgs))
0217 A.~ParsedTemplateArgument();
0218 this->~TemplateIdAnnotation();
0219 free(this);
0220 }
0221
0222
0223 bool mightBeType() const {
0224 return Kind == TNK_Non_template ||
0225 Kind == TNK_Type_template ||
0226 Kind == TNK_Dependent_template_name ||
0227 Kind == TNK_Undeclared_template;
0228 }
0229
0230 bool hasInvalidName() const { return Kind == TNK_Non_template; }
0231 bool hasInvalidArgs() const { return ArgsInvalid; }
0232
0233 bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
0234
0235 private:
0236 TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
0237
0238 TemplateIdAnnotation(SourceLocation TemplateKWLoc,
0239 SourceLocation TemplateNameLoc,
0240 const IdentifierInfo *Name,
0241 OverloadedOperatorKind OperatorKind,
0242 ParsedTemplateTy OpaqueTemplateName,
0243 TemplateNameKind TemplateKind,
0244 SourceLocation LAngleLoc, SourceLocation RAngleLoc,
0245 ArrayRef<ParsedTemplateArgument> TemplateArgs,
0246 bool ArgsInvalid) noexcept
0247 : TemplateKWLoc(TemplateKWLoc), TemplateNameLoc(TemplateNameLoc),
0248 Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
0249 Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
0250 NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
0251
0252 std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
0253 getTemplateArgs());
0254 }
0255 ~TemplateIdAnnotation() = default;
0256 };
0257
0258
0259 SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
0260 unsigned NumParams);
0261 }
0262
0263 #endif