28 using namespace clang;
52 return Name1 == Name2;
66 if ((
bool)Prefix1 != (
bool)Prefix2)
70 if (!IsStructurallyEquivalent(Context, Prefix1, Prefix2))
74 case NestedNameSpecifier::Identifier:
77 case NestedNameSpecifier::Namespace:
80 case NestedNameSpecifier::NamespaceAlias:
83 case NestedNameSpecifier::TypeSpec:
84 case NestedNameSpecifier::TypeSpecWithTemplate:
87 case NestedNameSpecifier::Global:
89 case NestedNameSpecifier::Super:
102 case TemplateName::Template:
106 case TemplateName::OverloadedTemplate: {
110 E1 = OS1->
end(), E2 = OS2->end();
111 for (; I1 != E1 && I2 != E2; ++I1, ++I2)
112 if (!IsStructurallyEquivalent(Context, *I1, *I2))
114 return I1 == E1 && I2 == E2;
117 case TemplateName::QualifiedTemplate: {
120 return IsStructurallyEquivalent(Context, QN1->
getDecl(), QN2->getDecl()) &&
122 QN2->getQualifier());
125 case TemplateName::DependentTemplate: {
128 if (!IsStructurallyEquivalent(Context, DN1->
getQualifier(),
129 DN2->getQualifier()))
133 DN2->getIdentifier());
139 case TemplateName::SubstTemplateTemplateParm: {
142 return IsStructurallyEquivalent(Context, TS1->
getParameter(),
143 TS2->getParameter()) &&
145 TS2->getReplacement());
147 case TemplateName::SubstTemplateTemplateParmPack: {
152 P2->getArgumentPack()) &&
154 P2->getParameterPack());
168 case TemplateArgument::Null:
171 case TemplateArgument::Type:
174 case TemplateArgument::Integral:
182 case TemplateArgument::Declaration:
185 case TemplateArgument::NullPtr:
188 case TemplateArgument::Template:
189 return IsStructurallyEquivalent(Context, Arg1.
getAsTemplate(),
192 case TemplateArgument::TemplateExpansion:
193 return IsStructurallyEquivalent(Context,
197 case TemplateArgument::Expression:
198 return IsStructurallyEquivalent(Context, Arg1.
getAsExpr(),
201 case TemplateArgument::Pack:
205 for (
unsigned I = 0, N = Arg1.
pack_size(); I != N; ++I)
206 if (!IsStructurallyEquivalent(Context, Arg1.
pack_begin()[I],
213 llvm_unreachable(
"Invalid template argument kind");
255 TC = Type::FunctionNoProto;
258 TC = Type::FunctionNoProto;
266 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->
getKind())
271 if (!IsStructurallyEquivalent(Context,
272 cast<ComplexType>(T1)->getElementType(),
273 cast<ComplexType>(T2)->getElementType()))
279 if (!IsStructurallyEquivalent(Context,
280 cast<AdjustedType>(T1)->getOriginalType(),
281 cast<AdjustedType>(T2)->getOriginalType()))
286 if (!IsStructurallyEquivalent(Context,
287 cast<PointerType>(T1)->getPointeeType(),
288 cast<PointerType>(T2)->getPointeeType()))
292 case Type::BlockPointer:
293 if (!IsStructurallyEquivalent(Context,
294 cast<BlockPointerType>(T1)->getPointeeType(),
295 cast<BlockPointerType>(T2)->getPointeeType()))
299 case Type::LValueReference:
300 case Type::RValueReference: {
308 Ref2->getPointeeTypeAsWritten()))
313 case Type::MemberPointer: {
325 case Type::ConstantArray: {
328 if (!llvm::APInt::isSameValue(Array1->
getSize(), Array2->getSize()))
331 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
336 case Type::IncompleteArray:
337 if (!IsArrayStructurallyEquivalent(Context, cast<ArrayType>(T1),
338 cast<ArrayType>(T2)))
342 case Type::VariableArray: {
345 if (!IsStructurallyEquivalent(Context, Array1->
getSizeExpr(),
346 Array2->getSizeExpr()))
349 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
355 case Type::DependentSizedArray: {
358 if (!IsStructurallyEquivalent(Context, Array1->
getSizeExpr(),
359 Array2->getSizeExpr()))
362 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
368 case Type::DependentAddressSpace: {
370 cast<DependentAddressSpaceType>(T1);
372 cast<DependentAddressSpaceType>(T2);
373 if (!IsStructurallyEquivalent(Context, DepAddressSpace1->
getAddrSpaceExpr(),
374 DepAddressSpace2->getAddrSpaceExpr()))
376 if (!IsStructurallyEquivalent(Context, DepAddressSpace1->
getPointeeType(),
383 case Type::DependentSizedExtVector: {
385 cast<DependentSizedExtVectorType>(T1);
387 cast<DependentSizedExtVectorType>(T2);
388 if (!IsStructurallyEquivalent(Context, Vec1->
getSizeExpr(),
389 Vec2->getSizeExpr()))
392 Vec2->getElementType()))
398 case Type::ExtVector: {
399 const VectorType *Vec1 = cast<VectorType>(T1);
400 const VectorType *Vec2 = cast<VectorType>(T2);
402 Vec2->getElementType()))
411 case Type::FunctionProto: {
416 for (
unsigned I = 0, N = Proto1->
getNumParams(); I != N; ++I) {
417 if (!IsStructurallyEquivalent(Context, Proto1->
getParamType(I),
418 Proto2->getParamType(I)))
421 if (Proto1->
isVariadic() != Proto2->isVariadic())
430 Proto2->getExceptionType(I)))
435 Proto2->getNoexceptExpr()))
445 case Type::FunctionNoProto: {
448 if (!IsStructurallyEquivalent(Context, Function1->
getReturnType(),
449 Function2->getReturnType()))
451 if (Function1->
getExtInfo() != Function2->getExtInfo())
456 case Type::UnresolvedUsing:
457 if (!IsStructurallyEquivalent(Context,
458 cast<UnresolvedUsingType>(T1)->getDecl(),
459 cast<UnresolvedUsingType>(T2)->getDecl()))
464 case Type::Attributed:
465 if (!IsStructurallyEquivalent(Context,
466 cast<AttributedType>(T1)->getModifiedType(),
467 cast<AttributedType>(T2)->getModifiedType()))
469 if (!IsStructurallyEquivalent(
470 Context, cast<AttributedType>(T1)->getEquivalentType(),
471 cast<AttributedType>(T2)->getEquivalentType()))
476 if (!IsStructurallyEquivalent(Context, cast<ParenType>(T1)->getInnerType(),
477 cast<ParenType>(T2)->getInnerType()))
482 if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
483 cast<TypedefType>(T2)->getDecl()))
487 case Type::TypeOfExpr:
488 if (!IsStructurallyEquivalent(
489 Context, cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
490 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
495 if (!IsStructurallyEquivalent(Context,
501 case Type::UnaryTransform:
502 if (!IsStructurallyEquivalent(
509 if (!IsStructurallyEquivalent(Context,
510 cast<DecltypeType>(T1)->getUnderlyingExpr(),
511 cast<DecltypeType>(T2)->getUnderlyingExpr()))
516 if (!IsStructurallyEquivalent(Context, cast<AutoType>(T1)->getDeducedType(),
517 cast<AutoType>(T2)->getDeducedType()))
521 case Type::DeducedTemplateSpecialization: {
522 auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
523 auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
524 if (!IsStructurallyEquivalent(Context, DT1->getTemplateName(),
525 DT2->getTemplateName()))
527 if (!IsStructurallyEquivalent(Context, DT1->getDeducedType(),
528 DT2->getDeducedType()))
535 if (!IsStructurallyEquivalent(Context, cast<TagType>(T1)->getDecl(),
536 cast<TagType>(T2)->getDecl()))
540 case Type::TemplateTypeParm: {
543 if (Parm1->
getDepth() != Parm2->getDepth())
545 if (Parm1->
getIndex() != Parm2->getIndex())
554 case Type::SubstTemplateTypeParm: {
556 cast<SubstTemplateTypeParmType>(T1);
558 cast<SubstTemplateTypeParmType>(T2);
559 if (!IsStructurallyEquivalent(Context,
561 QualType(Subst2->getReplacedParameter(), 0)))
564 Subst2->getReplacementType()))
569 case Type::SubstTemplateTypeParmPack: {
571 cast<SubstTemplateTypeParmPackType>(T1);
573 cast<SubstTemplateTypeParmPackType>(T2);
574 if (!IsStructurallyEquivalent(Context,
576 QualType(Subst2->getReplacedParameter(), 0)))
579 Subst2->getArgumentPack()))
583 case Type::TemplateSpecialization: {
585 cast<TemplateSpecializationType>(T1);
587 cast<TemplateSpecializationType>(T2);
589 Spec2->getTemplateName()))
591 if (Spec1->
getNumArgs() != Spec2->getNumArgs())
593 for (
unsigned I = 0, N = Spec1->
getNumArgs(); I != N; ++I) {
594 if (!IsStructurallyEquivalent(Context, Spec1->
getArg(I),
601 case Type::Elaborated: {
605 if (Elab1->
getKeyword() != Elab2->getKeyword())
607 if (!IsStructurallyEquivalent(Context, Elab1->
getQualifier(),
608 Elab2->getQualifier()))
610 if (!IsStructurallyEquivalent(Context, Elab1->
getNamedType(),
611 Elab2->getNamedType()))
616 case Type::InjectedClassName: {
619 if (!IsStructurallyEquivalent(Context,
621 Inj2->getInjectedSpecializationType()))
626 case Type::DependentName: {
629 if (!IsStructurallyEquivalent(Context, Typename1->
getQualifier(),
630 Typename2->getQualifier()))
633 Typename2->getIdentifier()))
639 case Type::DependentTemplateSpecialization: {
641 cast<DependentTemplateSpecializationType>(T1);
643 cast<DependentTemplateSpecializationType>(T2);
644 if (!IsStructurallyEquivalent(Context, Spec1->
getQualifier(),
645 Spec2->getQualifier()))
648 Spec2->getIdentifier()))
650 if (Spec1->
getNumArgs() != Spec2->getNumArgs())
652 for (
unsigned I = 0, N = Spec1->
getNumArgs(); I != N; ++I) {
653 if (!IsStructurallyEquivalent(Context, Spec1->
getArg(I),
660 case Type::PackExpansion:
661 if (!IsStructurallyEquivalent(Context,
662 cast<PackExpansionType>(T1)->getPattern(),
663 cast<PackExpansionType>(T2)->getPattern()))
667 case Type::ObjCInterface: {
670 if (!IsStructurallyEquivalent(Context, Iface1->
getDecl(),
676 case Type::ObjCTypeParam: {
679 if (!IsStructurallyEquivalent(Context, Obj1->
getDecl(), Obj2->getDecl()))
685 if (!IsStructurallyEquivalent(Context, Obj1->
getProtocol(I),
686 Obj2->getProtocol(I)))
691 case Type::ObjCObject: {
694 if (!IsStructurallyEquivalent(Context, Obj1->
getBaseType(),
695 Obj2->getBaseType()))
700 if (!IsStructurallyEquivalent(Context, Obj1->
getProtocol(I),
701 Obj2->getProtocol(I)))
707 case Type::ObjCObjectPointer: {
717 if (!IsStructurallyEquivalent(Context, cast<AtomicType>(T1)->getValueType(),
718 cast<AtomicType>(T2)->getValueType()))
724 if (!IsStructurallyEquivalent(Context, cast<PipeType>(T1)->getElementType(),
725 cast<PipeType>(T2)->getElementType()))
747 return IsStructurallyEquivalent(Context, D1, D2);
753 if (!::IsStructurallyEquivalent(Name1, Name2)) {
757 ? diag::err_odr_tag_type_inconsistent
758 : diag::warn_odr_tag_type_inconsistent)
768 if (!IsStructurallyEquivalent(Context, Field1->
getType(),
773 ? diag::err_odr_tag_type_inconsistent
774 : diag::warn_odr_tag_type_inconsistent)
788 ? diag::err_odr_tag_type_inconsistent
789 : diag::warn_odr_tag_type_inconsistent)
813 if (Bits1 != Bits2) {
817 ? diag::err_odr_tag_type_inconsistent
818 : diag::warn_odr_tag_type_inconsistent)
839 ? diag::err_odr_tag_type_inconsistent
840 : diag::warn_odr_tag_type_inconsistent)
852 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(D1)) {
854 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
856 if (*Index1 != *Index2)
868 if (Spec1 && Spec2) {
871 Spec2->getSpecializedTemplate()))
880 Spec2->getTemplateArgs().get(I)))
885 else if (Spec1 || Spec2)
897 if (D1CXX->hasExternalLexicalStorage() &&
898 !D1CXX->isCompleteDefinition()) {
902 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
907 << D2CXX->getNumBases();
909 << D1CXX->getNumBases();
916 BaseEnd1 = D1CXX->bases_end(),
917 Base2 = D2CXX->bases_begin();
918 Base1 != BaseEnd1; ++Base1, ++Base2) {
919 if (!IsStructurallyEquivalent(Context, Base1->getType(),
923 diag::warn_odr_tag_type_inconsistent)
925 Context.
Diag2(Base2->getLocStart(), diag::note_odr_base)
926 << Base2->getType() << Base2->getSourceRange();
927 Context.
Diag1(Base1->getLocStart(), diag::note_odr_base)
928 << Base1->getType() << Base1->getSourceRange();
934 if (Base1->isVirtual() != Base2->isVirtual()) {
937 diag::warn_odr_tag_type_inconsistent)
939 Context.
Diag2(Base2->getLocStart(), diag::note_odr_virtual_base)
940 << Base2->isVirtual() << Base2->getSourceRange();
941 Context.
Diag1(Base1->getLocStart(), diag::note_odr_base)
942 << Base1->isVirtual() << Base1->getSourceRange();
947 }
else if (D1CXX->getNumBases() > 0) {
965 Field1 != Field1End; ++Field1, ++Field2) {
966 if (Field2 == Field2End) {
970 ? diag::err_odr_tag_type_inconsistent
971 : diag::warn_odr_tag_type_inconsistent)
980 if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
984 if (Field2 != Field2End) {
988 ? diag::err_odr_tag_type_inconsistent
989 : diag::warn_odr_tag_type_inconsistent)
991 Context.
Diag2(Field2->getLocation(), diag::note_odr_field)
992 << Field2->getDeclName() << Field2->getType();
1008 EC1 != EC1End; ++EC1, ++EC2) {
1009 if (EC2 == EC2End) {
1013 ? diag::err_odr_tag_type_inconsistent
1014 : diag::warn_odr_tag_type_inconsistent)
1016 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1017 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1023 llvm::APSInt Val1 = EC1->getInitVal();
1024 llvm::APSInt Val2 = EC2->getInitVal();
1025 if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1026 !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
1030 ? diag::err_odr_tag_type_inconsistent
1031 : diag::warn_odr_tag_type_inconsistent)
1033 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1034 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1035 Context.
Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1036 << EC1->getDeclName() << EC1->getInitVal().toString(10);
1042 if (EC2 != EC2End) {
1046 ? diag::err_odr_tag_type_inconsistent
1047 : diag::warn_odr_tag_type_inconsistent)
1049 Context.
Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1050 << EC2->getDeclName() << EC2->getInitVal().toString(10);
1062 if (Params1->
size() != Params2->
size()) {
1065 diag::err_odr_different_num_template_parameters)
1066 << Params1->
size() << Params2->
size();
1068 diag::note_odr_template_parameter_list);
1073 for (
unsigned I = 0, N = Params1->
size(); I != N; ++I) {
1077 diag::err_odr_different_template_parameter_kind);
1079 diag::note_odr_template_parameter_here);
1127 diag::err_odr_non_type_parameter_type_inconsistent)
1196 assert(Complain &&
"Not allowed to complain");
1198 FromCtx.getDiagnostics().notePriorDiagnosticFrom(ToCtx.getDiagnostics());
1199 LastDiagFromC2 =
false;
1200 return FromCtx.getDiagnostics().Report(Loc, DiagID);
1205 assert(Complain &&
"Not allowed to complain");
1206 if (!LastDiagFromC2)
1207 ToCtx.getDiagnostics().notePriorDiagnosticFrom(FromCtx.getDiagnostics());
1208 LastDiagFromC2 =
true;
1209 return ToCtx.getDiagnostics().Report(Loc, DiagID);
1213 StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
RecordDecl *Anon) {
1227 if (F->isAnonymousStructOrUnion()) {
1237 if (
const auto *RecType = dyn_cast<RecordType>(FieldType)) {
1238 const RecordDecl *RecDecl = RecType->getDecl();
1251 bool StructuralEquivalenceContext::IsStructurallyEquivalent(
Decl *D1,
1253 if (!::IsStructurallyEquivalent(*
this, D1, D2))
1259 bool StructuralEquivalenceContext::IsStructurallyEquivalent(
QualType T1,
1261 if (!::IsStructurallyEquivalent(*
this, T1, T2))
1267 bool StructuralEquivalenceContext::Finish() {
1268 while (!DeclsToCheck.empty()) {
1270 Decl *D1 = DeclsToCheck.front();
1271 DeclsToCheck.pop_front();
1273 Decl *D2 = TentativeEquivalences[D1];
1274 assert(D2 &&
"Unrecorded tentative equivalence?");
1276 bool Equivalent =
true;
1280 if (
RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
1281 if (
RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
1284 if (!Name1 && Record1->getTypedefNameForAnonDecl())
1285 Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
1287 if (!Name2 && Record2->getTypedefNameForAnonDecl())
1288 Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
1289 if (!::IsStructurallyEquivalent(Name1, Name2) ||
1290 !::IsStructurallyEquivalent(*
this, Record1, Record2))
1296 }
else if (
EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
1297 if (
EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
1300 if (!Name1 && Enum1->getTypedefNameForAnonDecl())
1301 Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
1303 if (!Name2 && Enum2->getTypedefNameForAnonDecl())
1304 Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
1305 if (!::IsStructurallyEquivalent(Name1, Name2) ||
1306 !::IsStructurallyEquivalent(*
this, Enum1, Enum2))
1312 }
else if (
TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
1314 if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
1315 Typedef2->getIdentifier()) ||
1316 !::IsStructurallyEquivalent(*
this, Typedef1->getUnderlyingType(),
1317 Typedef2->getUnderlyingType()))
1324 dyn_cast<ClassTemplateDecl>(D1)) {
1326 if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(),
1327 ClassTemplate2->getIdentifier()) ||
1328 !::IsStructurallyEquivalent(*
this, ClassTemplate1, ClassTemplate2))
1335 dyn_cast<TemplateTypeParmDecl>(D1)) {
1337 if (!::IsStructurallyEquivalent(*
this, TTP1, TTP2))
1344 dyn_cast<NonTypeTemplateParmDecl>(D1)) {
1346 dyn_cast<NonTypeTemplateParmDecl>(D2)) {
1347 if (!::IsStructurallyEquivalent(*
this, NTTP1, NTTP2))
1354 dyn_cast<TemplateTemplateParmDecl>(D1)) {
1356 dyn_cast<TemplateTemplateParmDecl>(D2)) {
1357 if (!::IsStructurallyEquivalent(*
this, TTP1, TTP2))
1368 NonEquivalentDecls.insert(
TemplateTemplateParmDecl * getParameterPack() const
Retrieve the template template parameter pack being substituted.
Defines the clang::ASTContext interface.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S...
enumerator_iterator enumerator_end() const
A (possibly-)qualified type.
OverloadedOperatorKind getOperator() const
Return the overloaded operator to which this template name refers.
QualType getInjectedSpecializationType() const
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
unsigned getNumExceptions() const
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Defines the SourceManager interface.
Represents a qualified type name for which the type name is dependent.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
Decl - This represents one declaration (or definition), e.g.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
NamedDecl * getParam(unsigned Idx)
ObjCProtocolDecl * getProtocol(unsigned I) const
Fetch a protocol by index.
QualType getElementType() const
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
unsigned getNumParams() const
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
ASTContext & FromCtx
AST contexts for which we are checking structural equivalence.
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.
Represents the result of substituting a type for a template type parameter.
QualType getIntegralType() const
Retrieve the type of the integral value.
bool isAnonymousStructOrUnion() const
isAnonymousStructOrUnion - Determines whether this field is a representative for an anonymous struct ...
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
RecordDecl - Represents a struct/union/class.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
DeclarationName getDeclName() const
getDeclName - 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.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Represents a class type in Objective C.
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.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
SourceLocation getLocStart() const LLVM_READONLY
bool isSpelledAsLValue() const
bool ErrorOnTagTypeMismatch
Whether warn or error on tag type mismatches.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
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.
Represents the result of substituting a set of types for a template type parameter pack...
SourceLocation getTemplateLoc() const
TemplateName getReplacement() const
unsigned getTypeQuals() 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.
TagKind getTagKind() const
QualType getExceptionType(unsigned i) const
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
const TemplateArgument & getArg(unsigned Idx) const
const Type * getClass() const
Expr * getSizeExpr() const
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.
Expr * getSizeExpr() const
QualType getPointeeTypeAsWritten() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumProtocols() const
Return the number of qualifying protocols in this type, or 0 if there are none.
QualType getElementType() const
bool isAnonymousStructOrUnion() const
isAnonymousStructOrUnion - Whether this is an anonymous struct or union.
Represents an extended vector type where either the type or size is dependent.
bool IsStructurallyEquivalent(Decl *D1, Decl *D2)
Determine whether the two declarations are structurally equivalent.
Expr * getAddrSpaceExpr() const
QualType getBaseType() const
Gets the base type of this object type.
A little helper class used to produce diagnostics.
Represents a prototype with parameter type info, e.g.
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
ObjCTypeParamDecl * getDecl() const
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Represents an array type in C++ whose size is a value-dependent expression.
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
unsigned getNumArgs() const
Retrieve the number of template arguments.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
Expr - This represents one expression.
Declaration of a template type parameter.
unsigned getIndex() const
const T * castAs() const
Member-template castAs<specific type>.
field_iterator field_end() const
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID)
DeclContext * getDeclContext()
A structure for storing the information associated with a substituted template template parameter...
const IdentifierInfo * getIdentifier() const
Retrieve the type named by the typename specifier as an identifier.
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.
enumerator_iterator enumerator_begin() const
QualType getRecordType(const RecordDecl *Decl) const
Represents a GCC generic vector type.
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.
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template.
ElaboratedTypeKeyword getKeyword() const
bool isParameterPack() const
Returns whether this is a parameter pack.
Encodes a location in the source.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
QualType getReturnType() const
Interfaces are the core concept in Objective-C for object oriented design.
A structure for storing an already-substituted template template parameter pack.
TemplateArgument getArgumentPack() const
ASTContext & getASTContext() const LLVM_READONLY
QualType getElementType() const
static QualType getUnderlyingType(const SubRegion *R)
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
bool isParameterPack() const
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.
const TemplateTypeParmType * getReplacedParameter() const
Gets the template parameter that was substituted for.
Expr * getNoexceptExpr() const
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
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.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
The injected class name of a C++ class template or class template partial specialization.
QualType getPointeeType() const
StringRef getName() const
Return the actual identifier string.
Base class for declarations which introduce a typedef-name.
Represents a template argument.
Represents a template name that was expressed as a qualified name.
Dataflow Directional Tag Classes.
ExtInfo getExtInfo() const
NestedNameSpecifier * getQualifier() const
VectorKind getVectorKind() const
EnumDecl - Represents an enum.
A pointer to member type per C++ 8.3.3 - Pointers to members.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
const TemplateTypeParmType * getReplacedParameter() const
Gets the template parameter that was substituted for.
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).
Represents a pointer to an Objective C object.
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...
unsigned getNumArgs() const
Retrieve the number of template arguments.
const TemplateArgument & getArg(unsigned Idx) const
Retrieve a specific template argument as a type.
const llvm::APInt & getSize() const
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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.
unsigned getDepth() const
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
QualType getParamType(unsigned i) const
Represents a type parameter type in Objective C.
Represents a C++ struct/union/class.
Represents a template specialization type whose template cannot be resolved, e.g. ...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNamedType() const
Retrieve the type named by the qualified-id.
A structure for storing the information associated with an overloaded template name.
QualType getReplacementType() const
Gets the type that was substituted for the template parameter.
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)
unsigned getNumElements() const
QualType getAsType() const
Retrieve the type for a type template argument.
Represents an extended address space qualifier where the input address space value is dependent...
Represents a type template specialization; the template must be a class template, a type alias templa...
TemplateDecl * getDecl() const
The template declaration that this qualified name refers to.
bool Complain
Whether to complain about failures.
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
Represents a C array with a specified size that is not an integer-constant-expression.
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.
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.
Represents the canonical version of C arrays with a specified constant size.
SourceLocation getLocation() const
QualType getPointeeType() const
const IdentifierInfo * getIdentifier() const
Expr * getSizeExpr() const
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
QualType getType() const
Retrieves the type of the base class.