85 #include "llvm/ADT/APInt.h" 86 #include "llvm/ADT/APSInt.h" 87 #include "llvm/ADT/None.h" 88 #include "llvm/ADT/Optional.h" 89 #include "llvm/Support/Casting.h" 90 #include "llvm/Support/Compiler.h" 91 #include "llvm/Support/ErrorHandling.h" 95 using namespace clang;
118 if (!Name1 || !Name2)
119 return Name1 == Name2;
133 if ((
bool)Prefix1 != (
bool)Prefix2)
177 E1 = OS1->
end(), E2 = OS2->end();
178 for (; I1 != E1 && I2 != E2; ++I1, ++I2)
181 return I1 == E1 && I2 == E2;
189 QN2->getQualifier());
196 DN2->getQualifier()))
200 DN2->getIdentifier());
210 TS2->getParameter()) &&
212 TS2->getReplacement());
220 P2->getArgumentPack()) &&
222 P2->getParameterPack());
273 for (
unsigned I = 0, N = Arg1.
pack_size(); I != N; ++I)
281 llvm_unreachable(
"Invalid template argument kind");
326 TC = Type::FunctionNoProto;
329 TC = Type::FunctionNoProto;
337 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->
getKind())
343 cast<ComplexType>(T1)->getElementType(),
344 cast<ComplexType>(T2)->getElementType()))
351 cast<AdjustedType>(T1)->getOriginalType(),
352 cast<AdjustedType>(T2)->getOriginalType()))
358 cast<PointerType>(T1)->getPointeeType(),
359 cast<PointerType>(T2)->getPointeeType()))
363 case Type::BlockPointer:
365 cast<BlockPointerType>(T1)->getPointeeType(),
366 cast<BlockPointerType>(T2)->getPointeeType()))
370 case Type::LValueReference:
371 case Type::RValueReference: {
372 const auto *Ref1 = cast<ReferenceType>(T1);
373 const auto *Ref2 = cast<ReferenceType>(T2);
374 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
376 if (Ref1->isInnerRef() != Ref2->isInnerRef())
379 Ref2->getPointeeTypeAsWritten()))
384 case Type::MemberPointer: {
385 const auto *MemPtr1 = cast<MemberPointerType>(T1);
386 const auto *MemPtr2 = cast<MemberPointerType>(T2);
388 MemPtr2->getPointeeType()))
396 case Type::ConstantArray: {
397 const auto *Array1 = cast<ConstantArrayType>(T1);
398 const auto *Array2 = cast<ConstantArrayType>(T2);
399 if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
407 case Type::IncompleteArray:
409 cast<ArrayType>(T2)))
413 case Type::VariableArray: {
414 const auto *Array1 = cast<VariableArrayType>(T1);
415 const auto *Array2 = cast<VariableArrayType>(T2);
417 Array2->getSizeExpr()))
426 case Type::DependentSizedArray: {
427 const auto *Array1 = cast<DependentSizedArrayType>(T1);
428 const auto *Array2 = cast<DependentSizedArrayType>(T2);
430 Array2->getSizeExpr()))
439 case Type::DependentAddressSpace: {
440 const auto *DepAddressSpace1 = cast<DependentAddressSpaceType>(T1);
441 const auto *DepAddressSpace2 = cast<DependentAddressSpaceType>(T2);
443 DepAddressSpace2->getAddrSpaceExpr()))
446 DepAddressSpace2->getPointeeType()))
452 case Type::DependentSizedExtVector: {
453 const auto *Vec1 = cast<DependentSizedExtVectorType>(T1);
454 const auto *Vec2 = cast<DependentSizedExtVectorType>(T2);
456 Vec2->getSizeExpr()))
459 Vec2->getElementType()))
464 case Type::DependentVector: {
465 const auto *Vec1 = cast<DependentVectorType>(T1);
466 const auto *Vec2 = cast<DependentVectorType>(T2);
467 if (Vec1->getVectorKind() != Vec2->getVectorKind())
470 Vec2->getSizeExpr()))
473 Vec2->getElementType()))
479 case Type::ExtVector: {
480 const auto *Vec1 = cast<VectorType>(T1);
481 const auto *Vec2 = cast<VectorType>(T2);
483 Vec2->getElementType()))
485 if (Vec1->getNumElements() != Vec2->getNumElements())
487 if (Vec1->getVectorKind() != Vec2->getVectorKind())
492 case Type::FunctionProto: {
493 const auto *Proto1 = cast<FunctionProtoType>(T1);
494 const auto *Proto2 = cast<FunctionProtoType>(T2);
496 if (Proto1->getNumParams() != Proto2->getNumParams())
498 for (
unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
500 Proto2->getParamType(I)))
503 if (Proto1->isVariadic() != Proto2->isVariadic())
506 if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
510 const auto *OrigProto1 =
512 const auto *OrigProto2 =
514 auto Spec1 = OrigProto1->getExceptionSpecType();
515 auto Spec2 = OrigProto2->getExceptionSpecType();
520 if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
522 for (
unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
524 OrigProto2->getExceptionType(I)))
529 OrigProto2->getNoexceptExpr()))
537 case Type::FunctionNoProto: {
538 const auto *Function1 = cast<FunctionType>(T1);
539 const auto *Function2 = cast<FunctionType>(T2);
541 Function2->getReturnType()))
543 if (Function1->getExtInfo() != Function2->getExtInfo())
548 case Type::UnresolvedUsing:
550 cast<UnresolvedUsingType>(T1)->getDecl(),
551 cast<UnresolvedUsingType>(T2)->getDecl()))
555 case Type::Attributed:
557 cast<AttributedType>(T1)->getModifiedType(),
558 cast<AttributedType>(T2)->getModifiedType()))
561 Context, cast<AttributedType>(T1)->getEquivalentType(),
562 cast<AttributedType>(T2)->getEquivalentType()))
568 cast<ParenType>(T2)->getInnerType()))
574 cast<TypedefType>(T2)->getDecl()))
578 case Type::TypeOfExpr:
580 Context, cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
581 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
592 case Type::UnaryTransform:
601 cast<DecltypeType>(T1)->getUnderlyingExpr(),
602 cast<DecltypeType>(T2)->getUnderlyingExpr()))
608 cast<AutoType>(T2)->getDeducedType()))
612 case Type::DeducedTemplateSpecialization: {
613 const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
614 const auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
616 DT2->getTemplateName()))
619 DT2->getDeducedType()))
627 cast<TagType>(T2)->getDecl()))
631 case Type::TemplateTypeParm: {
632 const auto *Parm1 = cast<TemplateTypeParmType>(T1);
633 const auto *Parm2 = cast<TemplateTypeParmType>(T2);
634 if (Parm1->getDepth() != Parm2->getDepth())
636 if (Parm1->getIndex() != Parm2->getIndex())
638 if (Parm1->isParameterPack() != Parm2->isParameterPack())
645 case Type::SubstTemplateTypeParm: {
646 const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
647 const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
649 QualType(Subst1->getReplacedParameter(), 0),
650 QualType(Subst2->getReplacedParameter(), 0)))
653 Subst2->getReplacementType()))
658 case Type::SubstTemplateTypeParmPack: {
659 const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
660 const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
662 QualType(Subst1->getReplacedParameter(), 0),
663 QualType(Subst2->getReplacedParameter(), 0)))
666 Subst2->getArgumentPack()))
671 case Type::TemplateSpecialization: {
672 const auto *Spec1 = cast<TemplateSpecializationType>(T1);
673 const auto *Spec2 = cast<TemplateSpecializationType>(T2);
675 Spec2->getTemplateName()))
677 if (Spec1->getNumArgs() != Spec2->getNumArgs())
679 for (
unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
687 case Type::Elaborated: {
688 const auto *Elab1 = cast<ElaboratedType>(T1);
689 const auto *Elab2 = cast<ElaboratedType>(T2);
691 if (Elab1->getKeyword() != Elab2->getKeyword())
694 Elab2->getQualifier()))
697 Elab2->getNamedType()))
702 case Type::InjectedClassName: {
703 const auto *Inj1 = cast<InjectedClassNameType>(T1);
704 const auto *Inj2 = cast<InjectedClassNameType>(T2);
706 Inj1->getInjectedSpecializationType(),
707 Inj2->getInjectedSpecializationType()))
712 case Type::DependentName: {
713 const auto *Typename1 = cast<DependentNameType>(T1);
714 const auto *Typename2 = cast<DependentNameType>(T2);
716 Typename2->getQualifier()))
719 Typename2->getIdentifier()))
725 case Type::DependentTemplateSpecialization: {
726 const auto *Spec1 = cast<DependentTemplateSpecializationType>(T1);
727 const auto *Spec2 = cast<DependentTemplateSpecializationType>(T2);
729 Spec2->getQualifier()))
732 Spec2->getIdentifier()))
734 if (Spec1->getNumArgs() != Spec2->getNumArgs())
736 for (
unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
744 case Type::PackExpansion:
746 cast<PackExpansionType>(T1)->getPattern(),
747 cast<PackExpansionType>(T2)->getPattern()))
751 case Type::ObjCInterface: {
752 const auto *Iface1 = cast<ObjCInterfaceType>(T1);
753 const auto *Iface2 = cast<ObjCInterfaceType>(T2);
760 case Type::ObjCTypeParam: {
761 const auto *Obj1 = cast<ObjCTypeParamType>(T1);
762 const auto *Obj2 = cast<ObjCTypeParamType>(T2);
766 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
768 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
770 Obj2->getProtocol(I)))
776 case Type::ObjCObject: {
777 const auto *Obj1 = cast<ObjCObjectType>(T1);
778 const auto *Obj2 = cast<ObjCObjectType>(T2);
780 Obj2->getBaseType()))
782 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
784 for (
unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
786 Obj2->getProtocol(I)))
792 case Type::ObjCObjectPointer: {
793 const auto *Ptr1 = cast<ObjCObjectPointerType>(T1);
794 const auto *Ptr2 = cast<ObjCObjectPointerType>(T2);
796 Ptr2->getPointeeType()))
803 cast<AtomicType>(T2)->getValueType()))
809 cast<PipeType>(T2)->getElementType()))
837 Context.
Diag2(Owner2->getLocation(),
839 ? diag::err_odr_tag_type_inconsistent
840 : diag::warn_odr_tag_type_inconsistent)
853 Context.
Diag2(Owner2->getLocation(),
855 ? diag::err_odr_tag_type_inconsistent
856 : diag::warn_odr_tag_type_inconsistent)
868 Context.
Diag2(Owner2->getLocation(),
870 ? diag::err_odr_tag_type_inconsistent
871 : diag::warn_odr_tag_type_inconsistent)
895 if (Bits1 != Bits2) {
897 Context.
Diag2(Owner2->getLocation(),
899 ? diag::err_odr_tag_type_inconsistent
900 : diag::warn_odr_tag_type_inconsistent)
918 bool PropertiesEqual =
930 if (!PropertiesEqual)
934 if (
auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
935 auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
936 if (Constructor1->isExplicit() != Constructor2->isExplicit())
940 if (
auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
941 auto *Conversion2 = cast<CXXConversionDecl>(Method2);
942 if (Conversion1->isExplicit() != Conversion2->isExplicit())
945 Conversion2->getConversionType()))
971 ? diag::err_odr_tag_type_inconsistent
972 : diag::warn_odr_tag_type_inconsistent)
988 if (*Index1 != *Index2)
998 if (Spec1 && Spec2) {
1001 Spec2->getSpecializedTemplate()))
1005 if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
1008 for (
unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
1010 Spec2->getTemplateArgs().get(I)))
1015 else if (Spec1 || Spec2)
1034 if (
auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1035 if (
auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1036 if (D1CXX->hasExternalLexicalStorage() &&
1037 !D1CXX->isCompleteDefinition()) {
1041 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1046 << D2CXX->getNumBases();
1048 << D1CXX->getNumBases();
1055 BaseEnd1 = D1CXX->bases_end(),
1056 Base2 = D2CXX->bases_begin();
1057 Base1 != BaseEnd1; ++Base1, ++Base2) {
1059 Base2->getType())) {
1062 diag::warn_odr_tag_type_inconsistent)
1064 Context.
Diag2(Base2->getLocStart(), diag::note_odr_base)
1065 << Base2->getType() << Base2->getSourceRange();
1066 Context.
Diag1(Base1->getLocStart(), diag::note_odr_base)
1067 << Base1->getType() << Base1->getSourceRange();
1073 if (Base1->isVirtual() != Base2->isVirtual()) {
1076 diag::warn_odr_tag_type_inconsistent)
1078 Context.
Diag2(Base2->getLocStart(), diag::note_odr_virtual_base)
1079 << Base2->isVirtual() << Base2->getSourceRange();
1080 Context.
Diag1(Base1->getLocStart(), diag::note_odr_base)
1081 << Base1->isVirtual() << Base1->getSourceRange();
1089 Friend2End = D2CXX->friend_end();
1091 Friend1End = D1CXX->friend_end();
1092 Friend1 != Friend1End; ++Friend1, ++Friend2) {
1093 if (Friend2 == Friend2End) {
1096 diag::warn_odr_tag_type_inconsistent)
1098 Context.
Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1108 Context.
Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1109 Context.
Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1115 if (Friend2 != Friend2End) {
1119 Context.
Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1124 }
else if (D1CXX->getNumBases() > 0) {
1142 Field1 != Field1End; ++Field1, ++Field2) {
1143 if (Field2 == Field2End) {
1147 ? diag::err_odr_tag_type_inconsistent
1148 : diag::warn_odr_tag_type_inconsistent)
1150 Context.
Diag1(Field1->getLocation(), diag::note_odr_field)
1151 << Field1->getDeclName() << Field1->getType();
1161 if (Field2 != Field2End) {
1165 ? diag::err_odr_tag_type_inconsistent
1166 : diag::warn_odr_tag_type_inconsistent)
1168 Context.
Diag2(Field2->getLocation(), diag::note_odr_field)
1169 << Field2->getDeclName() << Field2->getType();
1185 EC1 != EC1End; ++EC1, ++EC2) {
1186 if (EC2 == EC2End) {
1190 ? diag::err_odr_tag_type_inconsistent
1191 : diag::warn_odr_tag_type_inconsistent)
1193 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1194 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1200 llvm::APSInt Val1 = EC1->getInitVal();
1201 llvm::APSInt Val2 = EC2->getInitVal();
1202 if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1207 ? diag::err_odr_tag_type_inconsistent
1208 : diag::warn_odr_tag_type_inconsistent)
1210 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1211 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1212 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1213 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1219 if (EC2 != EC2End) {
1223 ? diag::err_odr_tag_type_inconsistent
1224 : diag::warn_odr_tag_type_inconsistent)
1226 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1227 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1239 if (Params1->
size() != Params2->
size()) {
1242 diag::err_odr_different_num_template_parameters)
1243 << Params1->
size() << Params2->
size();
1245 diag::note_odr_template_parameter_list);
1250 for (
unsigned I = 0, N = Params1->
size(); I != N; ++I) {
1254 diag::err_odr_different_template_parameter_kind);
1256 diag::note_odr_template_parameter_here);
1302 diag::err_odr_non_type_parameter_type_inconsistent)
1415 assert(
Complain &&
"Not allowed to complain");
1424 assert(
Complain &&
"Not allowed to complain");
1441 for (
const auto *D : Owner->noload_decls()) {
1446 if (F->isAnonymousStructOrUnion()) {
1457 while (
const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
1458 FieldType = ElabType->getNamedType();
1460 if (
const auto *RecType = dyn_cast<RecordType>(FieldType)) {
1461 const RecordDecl *RecDecl = RecType->getDecl();
1500 bool StructuralEquivalenceContext::Finish() {
1507 assert(D2 &&
"Unrecorded tentative equivalence?");
1513 if (
auto *Record1 = dyn_cast<RecordDecl>(D1)) {
1514 if (
auto *Record2 = dyn_cast<RecordDecl>(D2)) {
1517 if (!Name1 && Record1->getTypedefNameForAnonDecl())
1518 Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
1520 if (!Name2 && Record2->getTypedefNameForAnonDecl())
1521 Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
1529 }
else if (
auto *Enum1 = dyn_cast<EnumDecl>(D1)) {
1530 if (
auto *Enum2 = dyn_cast<EnumDecl>(D2)) {
1533 if (!Name1 && Enum1->getTypedefNameForAnonDecl())
1534 Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
1536 if (!Name2 && Enum2->getTypedefNameForAnonDecl())
1537 Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
1545 }
else if (
const auto *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
1546 if (
const auto *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
1548 Typedef2->getIdentifier()) ||
1550 Typedef2->getUnderlyingType()))
1556 }
else if (
auto *ClassTemplate1 = dyn_cast<ClassTemplateDecl>(D1)) {
1557 if (
auto *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
1565 }
else if (
auto *FunctionTemplate1 = dyn_cast<FunctionTemplateDecl>(D1)) {
1566 if (
auto *FunctionTemplate2 = dyn_cast<FunctionTemplateDecl>(D2)) {
1574 }
else if (
auto *TTP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
1575 if (
auto *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
1582 }
else if (
auto *NTTP1 = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
1583 if (
auto *NTTP2 = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
1590 }
else if (
auto *TTP1 = dyn_cast<TemplateTemplateParmDecl>(D1)) {
1591 if (
auto *TTP2 = dyn_cast<TemplateTemplateParmDecl>(D2)) {
1598 }
else if (
auto *MD1 = dyn_cast<CXXMethodDecl>(D1)) {
1599 if (
auto *MD2 = dyn_cast<CXXMethodDecl>(D2)) {
1606 }
else if (
FunctionDecl *FD1 = dyn_cast<FunctionDecl>(D1)) {
1609 FD2->getIdentifier()))
1617 }
else if (
FriendDecl *FrD1 = dyn_cast<FriendDecl>(D1)) {
1618 if (
FriendDecl *FrD2 = dyn_cast<FriendDecl>(D2)) {
TemplateTemplateParmDecl * getParameterPack() const
Retrieve the template template parameter pack being substituted.
Defines the clang::ASTContext interface.
enumerator_iterator enumerator_end() const
Represents a function declaration or definition.
A (possibly-)qualified type.
static llvm::Optional< unsigned > findUntaggedStructOrUnionIndex(RecordDecl *Anon)
Find the index of the given anonymous struct/union within its context.
OverloadedOperatorKind getOperator() const
Return the overloaded operator to which this template name refers.
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
C Language Family Type Representation.
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in...
The template argument is an expression, and we've not resolved it to one of the other forms yet...
Decl - This represents one declaration (or definition), e.g.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Defines the C++ template declaration subclasses.
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
The template argument is a declaration that was provided for a pointer, reference, or pointer to member non-type template parameter.
NamedDecl * getParam(unsigned Idx)
A template template parameter that has been substituted for some other template name.
QualType getElementType() const
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
An identifier, stored as an IdentifierInfo*.
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
Represents an empty template argument, e.g., one that has not been deduced.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
ASTContext & FromCtx
AST contexts for which we are checking structural equivalence.
A namespace, stored as a NamespaceDecl*.
Stores a list of template parameters for a TemplateDecl and its derived classes.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
QualType getIntegralType() const
Retrieve the type of the integral value.
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID)
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
An iterator over the friend declarations of a class.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a class template specialization, which refers to a class template with a given set of temp...
One of these records is kept for each identifier that is lexed.
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a dependent template name that cannot be resolved prior to template instantiation.
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
SourceLocation getLocStart() const LLVM_READONLY
bool ErrorOnTagTypeMismatch
Whether warn or error on tag type mismatches.
Represents a member of a struct/union/class.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Defines the ExceptionSpecificationType enumeration and various utility functions. ...
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID)
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
SourceLocation getTemplateLoc() const
TemplateName getReplacement() const
bool StrictTypeSpelling
Whether we're being strict about the spelling of types when unifying two types.
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
bool isBitField() const
Determines whether this field is a bitfield.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
A qualified template name, where the qualification is kept to describe the source code as written...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
TagKind getTagKind() const
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
field_iterator field_begin() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
TemplateTemplateParmDecl * getParameter() const
NamedDecl *const * iterator
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
StructuralEquivalenceKind EqKind
A little helper class used to produce diagnostics.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any...
A dependent template name that has not been resolved to a template (or set of templates).
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
static bool IsTemplateDeclCommonStructurallyEquivalent(StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
Expr - This represents one expression.
bool isDefaulted() const
Whether this function is defaulted per C++0x.
Declaration of a template type parameter.
bool LastDiagFromC2
true if the last diagnostic came from ToCtx.
const T * castAs() const
Member-template castAs<specific type>.
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
field_iterator field_end() const
DeclContext * getDeclContext()
A structure for storing the information associated with a substituted template template parameter...
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a C++ template name within the type system.
bool isIdentifier() const
Determine whether this template name refers to an identifier.
A namespace alias, stored as a NamespaceAliasDecl*.
static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context, const ArrayType *Array1, const ArrayType *Array2)
Determine structural equivalence for the common part of array types.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
enumerator_iterator enumerator_begin() const
QualType getRecordType(const RecordDecl *Decl) const
ArraySizeModifier getSizeModifier() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
A type, stored as a Type*.
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
A template template parameter pack that has been substituted for a template template argument pack...
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
Decl::Kind getDeclKind() const
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template.
bool isParameterPack() const
Returns whether this is a parameter pack.
Encodes a location in the source.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
bool isPure() const
Whether this virtual function is pure, i.e.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, QualType T1, QualType T2)
Determine structural equivalence of two types.
A structure for storing an already-substituted template template parameter pack.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
ASTContext & getASTContext() const LLVM_READONLY
static QualType getUnderlyingType(const SubRegion *R)
Represents a static or instance method of a struct/union/class.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
bool isOverloadedOperator() const
Determine whether this template name refers to an overloaded operator.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Qualifiers getIndexTypeQualifiers() const
TypeClass getTypeClass() const
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
StringRef getName() const
Return the actual identifier string.
Represents a template argument.
Represents a template name that was expressed as a qualified name.
Dataflow Directional Tag Classes.
The base class of all kinds of template declarations (e.g., class, function, etc.).
The template argument is a pack expansion of a template name that was provided for a template templat...
AccessSpecifier getAccess() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
A type that was preceded by the 'template' keyword, stored as a Type*.
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
bool IsEquivalent(Decl *D1, Decl *D2)
Determine whether the two declarations are structurally equivalent.
llvm::DenseSet< std::pair< Decl *, Decl * > > & NonEquivalentDecls
Declaration (from, to) pairs that are known not to be equivalent (which we have already complained ab...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
The template argument is a type.
The template argument is actually a parameter pack.
Represents a base class of a C++ class.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
llvm::DenseMap< Decl *, Decl * > TentativeEquivalences
The set of "tentative" equivalences between two canonical declarations, mapping from a declaration in...
ArgKind getKind() const
Return the kind of stored template argument.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Defines the clang::SourceLocation class and associated facilities.
The template argument is a template name that was provided for a template template parameter...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
A structure for storing the information associated with an overloaded template name.
std::deque< Decl * > DeclsToCheck
Queue of declarations in the first context whose equivalence with a declaration in the second context...
Declaration of a class template.
static Decl::Kind getKind(const Decl *D)
QualType getAsType() const
Retrieve the type for a type template argument.
TemplateDecl * getDecl() const
The template declaration that this qualified name refers to.
bool isDeleted() const
Whether this function has been deleted.
bool Complain
Whether to complain about failures.
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
A set of overloaded template declarations.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
The global specifier '::'. There is no stored value.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion, return the pattern as a template name.
Declaration of a template function.
SourceLocation getLocation() const
QualType getType() const
Return the type wrapped by this type source info.
A single template declaration.
QualType getType() const
Retrieves the type of the base class.
void notePriorDiagnosticFrom(const DiagnosticsEngine &Other)
Note that the prior diagnostic was emitted by some other DiagnosticsEngine, and we may be attaching a...