T->getStmtClass() <= lastExprConstant;
}
};
+// PointerLikeTypeTraits is specialized so it can be used with a forward-decl of
+// Expr. Verify that we got it right.
+static_assert(llvm::PointerLikeTypeTraits<Expr *>::NumLowBitsAvailable <=
+ llvm::detail::ConstantLog2<alignof(Expr)>::value,
+ "PointerLikeTypeTraits<Expr*> assumes too much alignment.");
//===----------------------------------------------------------------------===//
// Wrapper Expressions.
class FoldingSetNodeID;
+// Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
+// full definition of Expr, but this file only sees a forward del because of
+// the dependency.
+template <> struct PointerLikeTypeTraits<clang::Expr *> {
+ static inline void *getAsVoidPointer(clang::Expr *P) { return P; }
+ static inline clang::Expr *getFromVoidPointer(void *P) {
+ return static_cast<clang::Expr *>(P);
+ }
+ static constexpr int NumLowBitsAvailable = 2;
+};
+
} // namespace llvm
namespace clang {
/// Location information for a TemplateArgument.
struct TemplateArgumentLocInfo {
private:
- struct T {
+ struct TemplateTemplateArgLocInfo {
// FIXME: We'd like to just use the qualifier in the TemplateName,
// but template arguments get canonicalized too quickly.
NestedNameSpecifier *Qualifier;
unsigned EllipsisLoc;
};
- union {
- struct T Template;
- Expr *Expression;
- TypeSourceInfo *Declarator;
- };
-
-public:
- constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
+ llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
+ Pointer;
- TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
+ TemplateTemplateArgLocInfo *getTemplate() const {
+ return Pointer.get<TemplateTemplateArgLocInfo *>();
+ }
- TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
+public:
+ constexpr TemplateArgumentLocInfo() {}
+ TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
- TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
+ TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
+ // Ctx is used for allocation -- this case is unusually large and also rare,
+ // so we store the payload out-of-line.
+ TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
- SourceLocation EllipsisLoc) {
- Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
- Template.QualifierLocData = QualifierLoc.getOpaqueData();
- Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
- Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
- }
+ SourceLocation EllipsisLoc);
TypeSourceInfo *getAsTypeSourceInfo() const {
- return Declarator;
+ return Pointer.get<TypeSourceInfo *>();
}
- Expr *getAsExpr() const {
- return Expression;
- }
+ Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- return NestedNameSpecifierLoc(Template.Qualifier,
- Template.QualifierLocData);
+ const auto *Template = getTemplate();
+ return NestedNameSpecifierLoc(Template->Qualifier,
+ Template->QualifierLocData);
}
SourceLocation getTemplateNameLoc() const {
- return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
+ return SourceLocation::getFromRawEncoding(getTemplate()->TemplateNameLoc);
}
SourceLocation getTemplateEllipsisLoc() const {
- return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
+ return SourceLocation::getFromRawEncoding(getTemplate()->EllipsisLoc);
}
};
Argument.getKind() == TemplateArgument::Expression);
}
- TemplateArgumentLoc(const TemplateArgument &Argument,
+ TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc = SourceLocation())
: Argument(Argument),
- LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
+ LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
}
import(FromInfo.getTemplateEllipsisLoc());
if (!ToTemplateEllipsisLocOrErr)
return ToTemplateEllipsisLocOrErr.takeError();
-
ToInfo = TemplateArgumentLocInfo(
- *ToTemplateQualifierLocOrErr,
- *ToTemplateNameLocOrErr,
- *ToTemplateEllipsisLocOrErr);
+ Importer.getToContext(), *ToTemplateQualifierLocOrErr,
+ *ToTemplateNameLocOrErr, *ToTemplateEllipsisLocOrErr);
}
return TemplateArgumentLoc(Arg, ToInfo);
llvm_unreachable("Invalid TemplateArgument Kind!");
}
+clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
+ ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
+ TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
+ Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
+ Template->QualifierLocData = QualifierLoc.getOpaqueData();
+ Template->TemplateNameLoc = TemplateNameLoc.getRawEncoding();
+ Template->EllipsisLoc = EllipsisLoc.getRawEncoding();
+ Pointer = Template;
+}
+
const ASTTemplateArgumentListInfo *
ASTTemplateArgumentListInfo::Create(const ASTContext &C,
const TemplateArgumentListInfo &List) {
Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
ArgInfos[i] = TemplateArgumentLocInfo(
- Builder.getWithLocInContext(Context), Loc,
+ Context, Builder.getWithLocInContext(Context), Loc,
Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
: Loc);
break;
TArg = TemplateArgument(Template, Optional<unsigned int>());
else
TArg = Template;
- return TemplateArgumentLoc(TArg,
- Arg.getScopeSpec().getWithLocInContext(
- SemaRef.Context),
- Arg.getLocation(),
- Arg.getEllipsisLoc());
+ return TemplateArgumentLoc(
+ SemaRef.Context, TArg,
+ Arg.getScopeSpec().getWithLocInContext(SemaRef.Context),
+ Arg.getLocation(), Arg.getEllipsisLoc());
}
}
if (TName.isNull())
return TemplateArgumentLoc();
- return TemplateArgumentLoc(TemplateArgument(TName),
- TempTempParm->getDefaultArgument().getTemplateQualifierLoc(),
- TempTempParm->getDefaultArgument().getTemplateNameLoc());
+ return TemplateArgumentLoc(
+ Context, TemplateArgument(TName),
+ TempTempParm->getDefaultArgument().getTemplateQualifierLoc(),
+ TempTempParm->getDefaultArgument().getTemplateNameLoc());
}
/// Convert a template-argument that we parsed as a type into a template, if
/// possible. C++ permits injected-class-names to perform dual service as
/// template template arguments and as template type arguments.
-static TemplateArgumentLoc convertTypeTemplateArgumentToTemplate(TypeLoc TLoc) {
+static TemplateArgumentLoc
+convertTypeTemplateArgumentToTemplate(ASTContext &Context, TypeLoc TLoc) {
// Extract and step over any surrounding nested-name-specifier.
NestedNameSpecifierLoc QualLoc;
if (auto ETLoc = TLoc.getAs<ElaboratedTypeLoc>()) {
QualLoc = ETLoc.getQualifierLoc();
TLoc = ETLoc.getNamedTypeLoc();
}
-
// If this type was written as an injected-class-name, it can be used as a
// template template argument.
if (auto InjLoc = TLoc.getAs<InjectedClassNameTypeLoc>())
- return TemplateArgumentLoc(InjLoc.getTypePtr()->getTemplateName(),
+ return TemplateArgumentLoc(Context, InjLoc.getTypePtr()->getTemplateName(),
QualLoc, InjLoc.getNameLoc());
// If this type was written as an injected-class-name, it may have been
if (auto RecLoc = TLoc.getAs<RecordTypeLoc>())
if (auto *CTSD =
dyn_cast<ClassTemplateSpecializationDecl>(RecLoc.getDecl()))
- return TemplateArgumentLoc(TemplateName(CTSD->getSpecializedTemplate()),
+ return TemplateArgumentLoc(Context,
+ TemplateName(CTSD->getSpecializedTemplate()),
QualLoc, RecLoc.getNameLoc());
return TemplateArgumentLoc();
// itself.
if (Arg.getArgument().getKind() == TemplateArgument::Type) {
TemplateArgumentLoc ConvertedArg = convertTypeTemplateArgumentToTemplate(
- Arg.getTypeSourceInfo()->getTypeLoc());
+ Context, Arg.getTypeSourceInfo()->getTypeLoc());
if (!ConvertedArg.getArgument().isNull())
Arg = ConvertedArg;
}
if (Name.isNull())
return true;
- Arg = TemplateArgumentLoc(TemplateArgument(Name), QualifierLoc,
- TempParm->getDefaultArgument().getTemplateNameLoc());
+ Arg = TemplateArgumentLoc(
+ Context, TemplateArgument(Name), QualifierLoc,
+ TempParm->getDefaultArgument().getTemplateNameLoc());
}
// Introduce an instantiation record that describes where we are using
Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
if (Arg.getKind() == TemplateArgument::Template)
- return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Context),
- Loc);
+ return TemplateArgumentLoc(Context, Arg,
+ Builder.getWithLocInContext(Context), Loc);
- return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Context),
- Loc, Loc);
+ return TemplateArgumentLoc(
+ Context, Arg, Builder.getWithLocInContext(Context), Loc, Loc);
}
case TemplateArgument::Expression:
if (!TName.isNull())
Param->setDefaultArgument(
SemaRef.Context,
- TemplateArgumentLoc(TemplateArgument(TName),
+ TemplateArgumentLoc(SemaRef.Context, TemplateArgument(TName),
D->getDefaultArgument().getTemplateQualifierLoc(),
D->getDefaultArgument().getTemplateNameLoc()));
}
case TemplateArgument::TemplateExpansion:
Ellipsis = OrigLoc.getTemplateEllipsisLoc();
NumExpansions = Argument.getNumTemplateExpansions();
- return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
+ return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(),
OrigLoc.getTemplateQualifierLoc(),
OrigLoc.getTemplateNameLoc());
}
case TemplateArgument::Template:
- return TemplateArgumentLoc(TemplateArgument(
- Pattern.getArgument().getAsTemplate(),
- NumExpansions),
- Pattern.getTemplateQualifierLoc(),
- Pattern.getTemplateNameLoc(),
- EllipsisLoc);
+ return TemplateArgumentLoc(
+ SemaRef.Context,
+ TemplateArgument(Pattern.getArgument().getAsTemplate(),
+ NumExpansions),
+ Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
+ EllipsisLoc);
case TemplateArgument::Null:
case TemplateArgument::Integral:
if (Template.isNull())
return true;
- Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc,
- Input.getTemplateNameLoc());
+ Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
+ QualifierLoc, Input.getTemplateNameLoc());
return false;
}
NestedNameSpecifierLoc QualifierLoc =
readNestedNameSpecifierLoc();
SourceLocation TemplateNameLoc = readSourceLocation();
- return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
- SourceLocation());
+ return TemplateArgumentLocInfo(getASTContext(), QualifierLoc,
+ TemplateNameLoc, SourceLocation());
}
case TemplateArgument::TemplateExpansion: {
NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc();
SourceLocation TemplateNameLoc = readSourceLocation();
SourceLocation EllipsisLoc = readSourceLocation();
- return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
- EllipsisLoc);
+ return TemplateArgumentLocInfo(getASTContext(), QualifierLoc,
+ TemplateNameLoc, EllipsisLoc);
}
case TemplateArgument::Null:
case TemplateArgument::Integral: