| Upstream-bug: http://code.google.com/p/include-what-you-use/issues/detail?id=110 |
| Index: tests/elaboration-struct.h |
| =================================================================== |
| --- tests/elaboration-struct.h (revision 0) |
| +++ tests/elaboration-struct.h (revision 0) |
| @@ -0,0 +1,10 @@ |
| +//===--- elaboration-struct.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. |
| +// |
| +//===----------------------------------------------------------------------===// |
| + |
| +struct ElaborationStruct {}; |
| |
| Property changes on: tests\elaboration-struct.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + native |
| |
| Index: tests/elaboration.cc |
| =================================================================== |
| --- tests/elaboration.cc (revision 0) |
| +++ tests/elaboration.cc (revision 0) |
| @@ -0,0 +1,79 @@ |
| +//===--- elaboration.cc - 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. |
| +// |
| +//===----------------------------------------------------------------------===// |
| + |
| +// Test that elaborated types are handled correctly. |
| +// |
| +// An elaborated type is a type prefixed by type kind, e.g. 'class Foo', |
| +// 'struct Bar' or 'enum Baz'. |
| +// |
| +// Clang considers namespace-qualified types elaborated as well, even if they |
| +// lack actual elaboration, e.g. 'ns::Foo'. |
| + |
| + |
| +#include "tests/elaboration-enum1.h" // for ElaborationEnum1 |
| +#include "tests/elaboration-enum2.h" // for ElaborationEnum2 |
| + |
| +// Make sure both elaborated and bare enums require the full type. |
| +void bare_enum(ElaborationEnum1 e); |
| +void elaborated_enum(enum ElaborationEnum2 e); |
| + |
| +// For C++ classes, a forward declaration should suffice for |
| +// bare type names and nothing should be necessary for elaborated ones. |
| +#include "tests/elaboration-class.h" |
| + |
| +void bare_class(ElaborationClass* c); |
| +void elaborated_class(class UnknownElaborationClass* c); |
| + |
| +// Structs should work like classes. |
| +#include "tests/elaboration-struct.h" |
| + |
| +void bare_struct(ElaborationStruct* s); |
| +void elaborated_struct(struct UnknownElaborationStruct* s); |
| + |
| +// And unions. |
| +#include "tests/elaboration-union.h" |
| + |
| +void bare_union(ElaborationUnion* u); |
| +void elaborated_union(union UnknownElaborationUnion* u); |
| + |
| +// Namespace-qualified types must be forward-declared even |
| +// if they are represented as elaborated types in Clang's AST. |
| +#include "tests/elaboration-namespace.h" |
| + |
| +void namespace_qualified(Elaboration::Class* c); |
| + |
| +// We can use elaborated types for templates, too, but |
| +// they must also be forward-declared. |
| +struct Elaboration::Template<int, float>* namespace_qualified_template; |
| + |
| +/**** IWYU_SUMMARY |
| + |
| +tests/elaboration.cc should add these lines: |
| +class ElaborationClass; |
| +namespace Elaboration { class Class; } |
| +namespace Elaboration { template <typename T, typename U> struct Template; } |
| +struct ElaborationStruct; |
| +union ElaborationUnion; |
| + |
| +tests/elaboration.cc should remove these lines: |
| +- #include "tests/elaboration-class.h" // lines XX-XX |
| +- #include "tests/elaboration-namespace.h" // lines XX-XX |
| +- #include "tests/elaboration-struct.h" // lines XX-XX |
| +- #include "tests/elaboration-union.h" // lines XX-XX |
| + |
| +The full include-list for tests/elaboration.cc: |
| +#include "tests/elaboration-enum1.h" // for ElaborationEnum1 |
| +#include "tests/elaboration-enum2.h" // for ElaborationEnum2 |
| +class ElaborationClass; |
| +namespace Elaboration { class Class; } |
| +namespace Elaboration { template <typename T, typename U> struct Template; } |
| +struct ElaborationStruct; |
| +union ElaborationUnion; |
| + |
| +***** IWYU_SUMMARY */ |
| Index: tests/elaboration-enum1.h |
| =================================================================== |
| --- tests/elaboration-enum1.h (revision 0) |
| +++ tests/elaboration-enum1.h (revision 0) |
| @@ -0,0 +1,13 @@ |
| +//===--- elaboration-enum1.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. |
| +// |
| +//===----------------------------------------------------------------------===// |
| + |
| +enum ElaborationEnum1 { |
| + EE1_First, |
| + EE1_Second |
| +}; |
| |
| Property changes on: tests\elaboration-enum1.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + native |
| |
| Index: tests/elaboration-class.h |
| =================================================================== |
| --- tests/elaboration-class.h (revision 0) |
| +++ tests/elaboration-class.h (revision 0) |
| @@ -0,0 +1,10 @@ |
| +//===--- elaboration-class.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. |
| +// |
| +//===----------------------------------------------------------------------===// |
| + |
| +class ElaborationClass {}; |
| |
| Property changes on: tests\elaboration-class.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + native |
| |
| Index: tests/badinc.cc |
| =================================================================== |
| --- tests/badinc.cc (revision 485) |
| +++ tests/badinc.cc (working copy) |
| @@ -317,17 +317,12 @@ |
| // IWYU: I2_Class is...*badinc-i2.h.*for autocast |
| // IWYU: I2_Class needs a declaration |
| const I2_Class& i2, |
| - const class I1_Class& elaborated_i1, |
| - // IWYU: I2_Class is...*badinc-i2.h.*for autocast |
| - const class I2_Class& elaborated_i2, |
| // A subtle c++ point: forward-declaring is ok for i2b, because |
| // you can't do implicit conversion to a non-const reference |
| // (implicit conversion involves creating a temporary, which |
| // doesn't bind to non-const references). |
| // IWYU: I2_Class needs a declaration |
| I2_Class& i2_nonconst, |
| - class I2_Class& elaborated_i2_nonconst, |
| - struct i3_ns1::i3_ns2::i3_ns3::I3_ForwardDeclareNamespaceStruct* i3_forward, |
| // Forward-declaring is ok because we a const reference to a *pointer*. |
| // IWYU: I2_Class needs a declaration |
| I2_Class* const & i2_ptrref, |
| @@ -897,11 +892,6 @@ |
| // IWYU: I3_ForwardDeclareNamespaceTemplateStruct needs a declaration |
| i3_ns1::i3_ns2::i3_ns3::I3_ForwardDeclareNamespaceTemplateStruct<H_Enum, 2>* |
| i3_fdtns_struct; |
| -// Even with elaboration, we still need fwd decl. |
| -// IWYU: I3_ForwardDeclareNamespaceTemplateStruct needs a declaration |
| -struct i3_ns1::i3_ns2::i3_ns3::I3_ForwardDeclareNamespaceTemplateStruct<H_Enum, |
| - 3>* |
| - i3_elaborated_fdtns_struct; |
| |
| // IWYU: I3_UnnamedNamespaceStruct needs a declaration |
| i3_ns1::I3_UnnamedNamespaceStruct* i3_unnamed_namespace_struct; |
| Index: tests/elaboration-enum2.h |
| =================================================================== |
| --- tests/elaboration-enum2.h (revision 0) |
| +++ tests/elaboration-enum2.h (revision 0) |
| @@ -0,0 +1,13 @@ |
| +//===--- elaboration-enum2.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. |
| +// |
| +//===----------------------------------------------------------------------===// |
| + |
| +enum ElaborationEnum2 { |
| + EE2_First, |
| + EE2_Second |
| +}; |
| |
| Property changes on: tests\elaboration-enum2.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + native |
| |
| Index: tests/elaboration-union.h |
| =================================================================== |
| --- tests/elaboration-union.h (revision 0) |
| +++ tests/elaboration-union.h (revision 0) |
| @@ -0,0 +1,10 @@ |
| +//===--- elaboration-union.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. |
| +// |
| +//===----------------------------------------------------------------------===// |
| + |
| +union ElaborationUnion {}; |
| |
| Property changes on: tests\elaboration-union.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + native |
| |
| Index: tests/elaboration-namespace.h |
| =================================================================== |
| --- tests/elaboration-namespace.h (revision 0) |
| +++ tests/elaboration-namespace.h (revision 0) |
| @@ -0,0 +1,18 @@ |
| +//===--- elaboration-namespace.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. |
| +// |
| +//===----------------------------------------------------------------------===// |
| + |
| +namespace Elaboration { |
| + class Class {}; |
| + |
| + template< typename T, typename U > |
| + struct Template { |
| + typedef T FirstType; |
| + typedef U SecondType; |
| + }; |
| +} |
| |
| Property changes on: tests\elaboration-namespace.h |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + native |
| |
| Index: iwyu.cc |
| =================================================================== |
| --- iwyu.cc (revision 485) |
| +++ iwyu.cc (working copy) |
| @@ -166,6 +166,7 @@ |
| using clang::DeclContext; |
| using clang::DeclRefExpr; |
| using clang::ElaboratedType; |
| +using clang::EnumType; |
| using clang::Expr; |
| using clang::FileEntry; |
| using clang::FriendDecl; |
| @@ -3454,6 +3455,7 @@ |
| preprocessor_info().FileInfoFor(CurrentFileEntry())->AddForwardDeclare( |
| decl_to_fwd_declare, definitely_keep_fwd_decl); |
| } |
| + |
| return Base::VisitTagDecl(decl); |
| } |
| |
| @@ -3562,13 +3564,17 @@ |
| // If we're forward-declarable, then no complicated checking is |
| // needed: just forward-declare. If we're already elaborated |
| // ('class Foo x') but not namespace-qualified ('class ns::Foo x') |
| - // there's no need even to forward-declare! |
| + // or an enum ('enum Foo x') there's no need even to forward-declare! |
| if (CanForwardDeclareType(current_ast_node())) { |
| current_ast_node()->set_in_forward_declare_context(true); |
| + |
| + bool is_enum_type = current_ast_node()->GetAs<EnumType>(); |
| if (!IsElaborationNode(current_ast_node()->parent()) || |
| - IsNamespaceQualifiedNode(current_ast_node()->parent())) { |
| + IsNamespaceQualifiedNode(current_ast_node()->parent()) || |
| + is_enum_type) { |
| ReportDeclForwardDeclareUse(CurrentLoc(), type->getDecl()); |
| } |
| + |
| return Base::VisitTagType(type); |
| } |
| |