//===--- badinc.h - test input file for iwyu ------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef INCLUDE_WHAT_YOU_USE_TESTS_CXX_BADINC_H_ #define INCLUDE_WHAT_YOU_USE_TESTS_CXX_BADINC_H_ #include // used only in badinc.cc #include // used both here and in badinc.cc #include #include // used only in this .h file, not in any other file. #include #include "tests/cxx/badinc-d2.h" #include "tests/cxx/badinc-d3.h" class H_ForwardDeclareClass; class Cc_Struct; // test having the wrong 'kind' (Cc_Struct is a struct) class Cc_Class; enum H_Enum { H1, H2, H3 }; template class I2_TypedefOnly_Class; typedef I2_TypedefOnly_Class H_I1_Class_Typedef; // H_ScopedPtr and H_MakeScopedPtr mimic the implementation of // scoped_ptr but are much simplified. template class H_ScopedPtr; template H_ScopedPtr H_MakeScopedPtr(T *); template class H_ScopedPtr { public: typedef T element_type; typedef T* element_ptr; typedef std::queue element_queue; T* get() { return ptr_; } T& operator*() { return *ptr_; } T* operator->() { return ptr_; } ~H_ScopedPtr() { enum { type_must_be_complete = sizeof(T) }; delete ptr_; } private: friend H_ScopedPtr H_MakeScopedPtr(T* p); T* ptr_; }; template H_ScopedPtr H_MakeScopedPtr(T* p) { return H_ScopedPtr(p); } // This is for the implicit constructor and implicit destructor: // IWYU: I2_Class is...*badinc-i2.h // IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h class H_Pimpl { private: H_ScopedPtr cc_impl_; // IWYU: I2_Class needs a declaration H_ScopedPtr i2_impl_; }; // These are for the implicit destructor: // IWYU: I2_Class is...*badinc-i2.h // IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h // IWYU: I2_Struct is...*badinc-i2.h class H_Pimpl_ExplicitCtor { public: H_Pimpl_ExplicitCtor() : i2_impl_explicit_ctor_() { } private: H_ScopedPtr cc_impl_; // IWYU: I2_Class needs a declaration H_ScopedPtr i2_impl_; // IWYU: I2_Struct needs a declaration H_ScopedPtr i2_impl_explicit_ctor_; }; class H_Pimpl_ExplicitCtorDtor { public: H_Pimpl_ExplicitCtorDtor() : i2_impl_explicit_ctor_() { } ~H_Pimpl_ExplicitCtorDtor(); private: H_ScopedPtr cc_impl_; // IWYU: I2_Class needs a declaration H_ScopedPtr i2_impl_; // IWYU: I2_Struct needs a declaration H_ScopedPtr i2_impl_explicit_ctor_; }; template struct H_ScopedPtrHolder { H_ScopedPtr holder; }; class H_Class { public: class H_Class_Subdecl; class H_Class_UnusedSubdecl; // defined in badinc.cc class H_Class_DefinedInI1; // defined in badinc-i1.h H_Class(int a) { a_ = a; } // IWYU: I2_Enum is...*badinc-i2.h H_Class(I2_Enum i2_enum) { a_ = 1; } // IWYU: I2_MACRO is...*badinc-i2.h H_Class() { a_ = I2_MACRO; } // from badinc-i2.h int a() { return a_; } H_Enum b() const { return static_cast(a_); } // IWYU: I2_Typedef is...*badinc-i2.h // IWYU: I2_EnumForTypedefs is...*badinc-i2.h I2_Typedef c() const { return static_cast(a_); } // IWYU: I2_Struct is...*badinc-i2.h I2_Struct unused_c() const { return I2_Struct(); } // IWYU: I2_Struct is...*badinc-i2.h int unused_c2() const { return I2_Struct().a; } D3_Enum d() const { return static_cast(a_); } int e() const { std::string s("a long long string"); std::queue q; if (q.empty()) return s.length(); // IWYU: I2_Enum is...*badinc-i2.h switch (static_cast(a_)) { // IWYU: I21 is...*badinc-i2.h case I21: return 21; // IWYU: I22 is...*badinc-i2.h case I22: return 22; default: return errno; } } // IWYU: I2_Enum is...*badinc-i2.h int f(I2_Enum i2_enum); int g(H_Class_Subdecl *h_class_subdecl) { return 1; } // IWYU: TemplateForHClassTplFn needs a declaration template A TplFn(const TemplateForHClassTplFn& a) { return a.value; } // IWYU: TemplateForHClassTplFn needs a declaration int NonTplFn(const TemplateForHClassTplFn& a) { return 0; } // IWYU: I2_Enum is...*badinc-i2.h static int static_out_of_line(I2_Enum i2_enum); struct H_NestedStruct { // IWYU: I2_Enum is...*badinc-i2.h I2_Enum nested_i2_enum; // IWYU: I2_Enum is...*badinc-i2.h int nested(I2_Enum i2_enum); // IWYU: I2_Enum is...*badinc-i2.h static int static_nested(I2_Enum i2_enum); }; void DefinedInBadincCc(); void UsedInBadincH() { DefinedInBadincCc(); } H_NestedStruct h_nested_struct; ~H_Class() { // IWYU: printf is...* printf("%d/%d/%d/%d/%d\n", b(), c(), d(), e(), ee_); } // IWYU: I2_Enum is...*badinc-i2.h static I2_Enum ee_; // IWYU: I2_Enum is...*badinc-i2.h static I2_Enum ff_; private: // IWYU: I2_EnumForTypedefs is...*badinc-i2.h typedef I2_EnumForTypedefs H_Class_I2_Typedef; // IWYU: I2_Struct needs a declaration // IWYU: I2_Class needs a declaration friend I2_Struct I2_Function(I2_Class*); friend class I2_Class; template friend class TemplateForHClassTplFn; int a_; Cc_Struct* ptr_into_cc_file_type_; H_Class(const H_Class&); }; // IWYU: I2_Enum is...*badinc-i2.h // IWYU: I21 is...*badinc-i2.h I2_Enum H_Class::ee_ = I21; template class H_TemplateClass { public: H_TemplateClass(FOO a) { a_ = a; } FOO a() { return a_; } H_Enum b() const { return static_cast(a_); } // IWYU: I2_Typedef is...*badinc-i2.h // IWYU: I2_EnumForTypedefs is...*badinc-i2.h I2_Typedef c() const { return static_cast(a_); } // IWYU: I2_Struct is...*badinc-i2.h I2_Struct unused_c() const { return I2_Struct(); } // unused tpl fn not iwyu // IWYU: I2_Struct is...*badinc-i2.h int unused_c2() const { return I2_Struct().a; } int unused_c3() const { return this_is_ok_even_though_it_exists_not(FOO()); } // IWYU: I2_Enum is...*badinc-i2.h int f(I2_Enum i2_enum); void uses_i2class() { // IWYU: I2_Class is...*badinc-i2.h // IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h I2_Class i2_class; (void)i2_class; } // IWYU: I2_Enum is...*badinc-i2.h static FOO static_out_of_line(I2_Enum i2_enum); // IWYU: I2_Enum is...*badinc-i2.h static FOO static_never_defined(I2_Enum i2_enum); struct H_TplNestedStruct { // IWYU: I2_Enum is...*badinc-i2.h I2_Enum tplnested_i2_enum; // IWYU: I2_Enum is...*badinc-i2.h int tplnested(I2_Enum i2_enum); // IWYU: I2_Enum is...*badinc-i2.h static FOO static_tplnested(I2_Enum i2_enum); }; H_TplNestedStruct h_nested_struct; // IWYU: I2_Enum is...*badinc-i2.h static I2_Enum h_template_i2_static_; static FOO h_template_foo_static_; private: // IWYU: I2_EnumForTypedefs is...*badinc-i2.h typedef I2_EnumForTypedefs H_TemplateClass_I2_Typedef; // IWYU: I2_Struct needs a declaration // IWYU: I2_Class needs a declaration friend I2_Struct I2_Function(I2_Class*); FOO a_; public: H_TemplateClass(const H_TemplateClass&); }; // IWYU: I2_Enum is...*badinc-i2.h // IWYU: I21 is...*badinc-i2.h template I2_Enum H_TemplateClass::h_template_i2_static_ = I21; H_TemplateClass* h_templateclass_var; // IWYU: I2_TemplateClass is...*badinc-i2.h template class T = I2_TemplateClass> // This is from the default destructor destroying t. // TODO(csilvers): attribute this use here, not at the caller sites. // TODO(csilvers): IWYU: I2_TemplateClass::~I2_TemplateClass<.*> is...*badinc-i2-inl.h class H_TemplateTemplateClass { public: // TODO(csilvers): attribute this use here, not at the caller sites. // TODO(csilvers): IWYU: I2_TemplateClass::~I2_TemplateClass<.*> is...*badinc-i2-inl.h // IWYU: I2_Enum is...*badinc-i2.h // IWYU: I2_Enum::I21 is...*badinc-i2.h H_TemplateTemplateClass() : t(T(I21)) {} // IWYU: I2_Enum is...*badinc-i2.h T t; // IWYU: I2_Enum is...*badinc-i2.h I2_Enum e; }; // The generic OperateOn, but each specialization needs to define its own. template class OperateOn { }; // OperateOn isn't checked for IWYU violations until it's instantiated. template > class H_TemplateStructHelper { public: void a() { Functor f; (void)f; } }; // To make this example as much like hash_set<> as possible, the outer // class is really just a container around the class that does work. template > class H_TemplateStruct { private: typedef H_TemplateStructHelper _TS; _TS ts; public: void a() { return ts.a(); } }; template struct H_TypedefStruct { // Should not be an iwyu violation for T typedef T t_type; // IWYU: std::pair is...* typedef std::pair pair_type; }; // IWYU: I2_EnumForTypedefs is...*badinc-i2.h typedef I2_EnumForTypedefs H_Typedef; // IWYU: std::set is...* // IWYU: I2_Enum is...*badinc-i2.h typedef std::set H_I2Enum_Set; // We need the full definition of I2_Class because as a typedef we are // re-exporting the vector type, so it must be fully defined. // TODO(csilvers): IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h // IWYU: std::vector is...* // IWYU: I2_Class needs a declaration // IWYU: I2_Class is...*badinc-i2.h typedef std::vector H_I2Class_Vector_Unused; // IWYU: I2_TemplateClass is...*badinc-i2.h // IWYU: I2_TemplateClass::I2_TemplateClass<.*> is...*badinc-i2-inl.h // IWYU: I2_TemplateClass::~I2_TemplateClass<.*> is...*badinc-i2-inl.h // IWYU: I2_TemplateClass::InlFileTemplateClassFn is...*badinc-i2-inl.h // IWYU: I2_Enum is...*badinc-i2.h typedef I2_TemplateClass H_TemplateTypedef; // IWYU: I2_Struct needs a declaration typedef I2_Struct* H_StructPtr; // IWYU: I2_Class needs a declaration typedef int (*H_FunctionPtr)(int, I2_Class*); H_Enum H_Function(H_Class* c) { return H1; } // IWYU: I2_Class needs a declaration // IWYU: I2_Enum is...*badinc-i2.h I2_Enum H_Function_I(I2_Class*) { // IWYU: I21 is...*badinc-i2.h return I21; } // IWYU: I2_Enum is...*badinc-i2.h // IWYU: I2_Class needs a declaration I2_Enum H_Function_I2(I2_Class* c); template int H_TemplateFunction(A a) { typedef A value_type; // Should not cause an iwyu violation // IWYU: I2_Class is...*badinc-i2.h // IWYU: I2_Class::I2_Class is...*badinc-i2-inl.h // IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h // IWYU: I2_Class::InlFileFn is...*badinc-i2-inl.h // IWYU: I2_Class::InlFileTemplateFn is...*badinc-i2-inl.h // IWYU: I2_Class::InlFileStaticFn is...*badinc-i2-inl.h typedef I2_Class i2_type; // IWYU: I2_Class needs a declaration I2_Class* i2_class; // IWYU: NULL is...* i2_class = NULL; return a == A() ? 1 : 0; } // This macro is tricky because myclass_##classname involves a type // that's defined in scratch space. Make sure this doesn't result in // an IWYU violation. Nor should classname used *not* in a macro // concatenation (as the return value of Init). #define H_USE_CLASS(classname) \ struct H_Use_##classname { \ H_Use_##classname() { Init(); } \ classname* Init() { return 0; } \ }; \ static H_Use_##classname myclass_##classname #define H_CREATE_VAR(typ) typ h_create_var template T& Identity(T& t) { return t; } #define H_IDENTITY(x) Identity(x) namespace h_ns { // IWYU: I2_Struct is...*badinc-i2.h typedef I2_Struct H_NamespaceTypedef; } // The vars. Just a few. H_Enum h_h_enum; // IWYU: I2_Class is...*badinc-i2.h // IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h I2_Class h_i2_class; H_TemplateClass h_d3_template_class(D31); // IWYU: I2_Enum is...*badinc-i2.h // IWYU: I22 is...*badinc-i2.h H_TemplateClass h_i2_template_class(I22); // TODO(csilvers): this should be attributed to the .h, since it comes // via a default template argument. // IWYU: I2_TemplateClass::~I2_TemplateClass<.*> is...*badinc-i2-inl.h H_TemplateTemplateClass<> h_templatetemlpate_class; H_TemplateTemplateClass h_i2_templatetemlpate_class; #endif // INCLUDE_WHAT_YOU_USE_TESTS_CXX_BADINC_H_ /**** IWYU_SUMMARY tests/cxx/badinc.h should add these lines: #include #include #include #include #include "tests/cxx/badinc-i2-inl.h" #include "tests/cxx/badinc-i2.h" tests/cxx/badinc.h should remove these lines: - #include // lines XX-XX - #include // lines XX-XX - #include "tests/cxx/badinc-d2.h" // lines XX-XX - class H_ForwardDeclareClass; // lines XX-XX - template class I2_TypedefOnly_Class; // lines XX-XX The full include-list for tests/cxx/badinc.h: #include // for errno #include // for NULL, printf #include // for queue #include // for set #include // for string #include // for pair #include // for vector #include "tests/cxx/badinc-d3.h" // for D3_Enum, D3_Enum::D31 #include "tests/cxx/badinc-i2-inl.h" // for I2_Class::I2_Class, I2_Class::InlFileFn, I2_Class::InlFileStaticFn, I2_Class::InlFileTemplateFn, I2_Class::~I2_Class, I2_TemplateClass::I2_TemplateClass, I2_TemplateClass::InlFileTemplateClassFn, I2_TemplateClass::~I2_TemplateClass #include "tests/cxx/badinc-i2.h" // for I2_Class, I2_Enum, I2_Enum::I21, I2_Enum::I22, I2_EnumForTypedefs, I2_MACRO, I2_Struct, I2_TemplateClass, I2_Typedef, I2_TypedefOnly_Class (ptr only), TemplateForHClassTplFn (ptr only) class Cc_Class; // lines XX-XX // TODO(csilvers): this should change to struct Cc_Struct. class Cc_Struct; // lines XX-XX class H_Class::H_Class_DefinedInI1; // lines XX-XX class H_Class::H_Class_Subdecl; // lines XX-XX class H_Class::H_Class_UnusedSubdecl; // lines XX-XX template class H_ScopedPtr; // lines XX-XX ***** IWYU_SUMMARY */