417 lines
14 KiB
C++
417 lines
14 KiB
C++
//===--- 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 <ctype.h> // used only in badinc.cc
|
|
#include <errno.h> // used both here and in badinc.cc
|
|
#include <math.h>
|
|
#include <queue> // used only in this .h file, not in any other file.
|
|
#include <string>
|
|
#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<typename T> class I2_TypedefOnly_Class;
|
|
typedef I2_TypedefOnly_Class<int> H_I1_Class_Typedef;
|
|
|
|
// H_ScopedPtr and H_MakeScopedPtr mimic the implementation of
|
|
// scoped_ptr but are much simplified.
|
|
|
|
template <typename T> class H_ScopedPtr;
|
|
template <typename T> H_ScopedPtr<T> H_MakeScopedPtr(T *);
|
|
|
|
template <typename T>
|
|
class H_ScopedPtr {
|
|
public:
|
|
typedef T element_type;
|
|
typedef T* element_ptr;
|
|
typedef std::queue<T> 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<T> H_MakeScopedPtr<T>(T* p);
|
|
|
|
T* ptr_;
|
|
};
|
|
|
|
template <typename T> H_ScopedPtr<T> H_MakeScopedPtr(T* p) {
|
|
return H_ScopedPtr<T>(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_Class> cc_impl_;
|
|
// IWYU: I2_Class needs a declaration
|
|
H_ScopedPtr<I2_Class> 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_Class> cc_impl_;
|
|
// IWYU: I2_Class needs a declaration
|
|
H_ScopedPtr<I2_Class> i2_impl_;
|
|
// IWYU: I2_Struct needs a declaration
|
|
H_ScopedPtr<I2_Struct> i2_impl_explicit_ctor_;
|
|
};
|
|
|
|
class H_Pimpl_ExplicitCtorDtor {
|
|
public:
|
|
H_Pimpl_ExplicitCtorDtor() : i2_impl_explicit_ctor_() { }
|
|
~H_Pimpl_ExplicitCtorDtor();
|
|
private:
|
|
H_ScopedPtr<Cc_Class> cc_impl_;
|
|
// IWYU: I2_Class needs a declaration
|
|
H_ScopedPtr<I2_Class> i2_impl_;
|
|
// IWYU: I2_Struct needs a declaration
|
|
H_ScopedPtr<I2_Struct> i2_impl_explicit_ctor_;
|
|
};
|
|
|
|
template <typename T> struct H_ScopedPtrHolder {
|
|
H_ScopedPtr<T> 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<H_Enum>(a_); }
|
|
// IWYU: I2_Typedef is...*badinc-i2.h
|
|
// IWYU: I2_EnumForTypedefs is...*badinc-i2.h
|
|
I2_Typedef c() const { return static_cast<I2_EnumForTypedefs>(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<D3_Enum>(a_); }
|
|
int e() const {
|
|
std::string s("a long long string");
|
|
std::queue<int> q;
|
|
if (q.empty()) return s.length();
|
|
// IWYU: I2_Enum is...*badinc-i2.h
|
|
switch (static_cast<I2_Enum>(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<typename A> A TplFn(const TemplateForHClassTplFn<A>& a) {
|
|
return a.value;
|
|
}
|
|
// IWYU: TemplateForHClassTplFn needs a declaration
|
|
int NonTplFn(const TemplateForHClassTplFn<int>& 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...*<stdio.h>
|
|
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<typename FOO> 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<typename FOO>
|
|
class H_TemplateClass {
|
|
public:
|
|
H_TemplateClass(FOO a) { a_ = a; }
|
|
FOO a() { return a_; }
|
|
H_Enum b() const { return static_cast<H_Enum>(a_); }
|
|
// IWYU: I2_Typedef is...*badinc-i2.h
|
|
// IWYU: I2_EnumForTypedefs is...*badinc-i2.h
|
|
I2_Typedef c() const { return static_cast<I2_EnumForTypedefs>(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<typename FOO> I2_Enum H_TemplateClass<FOO>::h_template_i2_static_ = I21;
|
|
H_TemplateClass<int>* h_templateclass_var;
|
|
|
|
// IWYU: I2_TemplateClass is...*badinc-i2.h
|
|
template<template<typename A> 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<I2_Enum>(I21)) {}
|
|
// IWYU: I2_Enum is...*badinc-i2.h
|
|
T<I2_Enum> t;
|
|
// IWYU: I2_Enum is...*badinc-i2.h
|
|
I2_Enum e;
|
|
};
|
|
|
|
// The generic OperateOn, but each specialization needs to define its own.
|
|
template<class T> class OperateOn { };
|
|
|
|
// OperateOn isn't checked for IWYU violations until it's instantiated.
|
|
template<class T, class Functor = OperateOn<T> > 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 T, class Functor = OperateOn<T> > class H_TemplateStruct {
|
|
private:
|
|
typedef H_TemplateStructHelper<T, Functor> _TS;
|
|
_TS ts;
|
|
public:
|
|
void a() { return ts.a(); }
|
|
};
|
|
|
|
template<class T> struct H_TypedefStruct {
|
|
// Should not be an iwyu violation for T
|
|
typedef T t_type;
|
|
// IWYU: std::pair is...*<utility>
|
|
typedef std::pair<T, T> pair_type;
|
|
};
|
|
|
|
// IWYU: I2_EnumForTypedefs is...*badinc-i2.h
|
|
typedef I2_EnumForTypedefs H_Typedef;
|
|
// IWYU: std::set is...*<set>
|
|
// IWYU: I2_Enum is...*badinc-i2.h
|
|
typedef std::set<I2_Enum> H_I2Enum_Set;
|
|
// We need the full definition of I2_Class because as a typedef we are
|
|
// re-exporting the vector<I2_Class> type, so it must be fully defined.
|
|
// TODO(csilvers): IWYU: I2_Class::~I2_Class is...*badinc-i2-inl.h
|
|
// IWYU: std::vector is...*<vector>
|
|
// IWYU: I2_Class needs a declaration
|
|
// IWYU: I2_Class is...*badinc-i2.h
|
|
typedef std::vector<I2_Class> 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<I2_Enum> 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<typename A> 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...*<stdio.h>
|
|
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<typename T> 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<D3_Enum> h_d3_template_class(D31);
|
|
// IWYU: I2_Enum is...*badinc-i2.h
|
|
// IWYU: I22 is...*badinc-i2.h
|
|
H_TemplateClass<I2_Enum> 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_TemplateClass> h_i2_templatetemlpate_class;
|
|
|
|
#endif // INCLUDE_WHAT_YOU_USE_TESTS_CXX_BADINC_H_
|
|
|
|
|
|
/**** IWYU_SUMMARY
|
|
|
|
tests/cxx/badinc.h should add these lines:
|
|
#include <stdio.h>
|
|
#include <set>
|
|
#include <utility>
|
|
#include <vector>
|
|
#include "tests/cxx/badinc-i2-inl.h"
|
|
#include "tests/cxx/badinc-i2.h"
|
|
|
|
tests/cxx/badinc.h should remove these lines:
|
|
- #include <ctype.h> // lines XX-XX
|
|
- #include <math.h> // lines XX-XX
|
|
- #include "tests/cxx/badinc-d2.h" // lines XX-XX
|
|
- class H_ForwardDeclareClass; // lines XX-XX
|
|
- template <typename T> class I2_TypedefOnly_Class; // lines XX-XX
|
|
|
|
The full include-list for tests/cxx/badinc.h:
|
|
#include <errno.h> // for errno
|
|
#include <stdio.h> // for NULL, printf
|
|
#include <queue> // for queue
|
|
#include <set> // for set
|
|
#include <string> // for string
|
|
#include <utility> // for pair
|
|
#include <vector> // 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<FOO>, I2_TemplateClass::InlFileTemplateClassFn, I2_TemplateClass::~I2_TemplateClass<FOO>
|
|
#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 <typename T> class H_ScopedPtr; // lines XX-XX
|
|
|
|
***** IWYU_SUMMARY */
|