
Without this patch, clang will not wrap in an ElaboratedType node types written without a keyword and nested name qualifier, which goes against the intent that we should produce an AST which retains enough details to recover how things are written. The lack of this sugar is incompatible with the intent of the type printer default policy, which is to print types as written, but to fall back and print them fully qualified when they are desugared. An ElaboratedTypeLoc without keyword / NNS uses no storage by itself, but still requires pointer alignment due to pre-existing bug in the TypeLoc buffer handling. Signed-off-by: Matheus Izvekov <mizvekov@gmail.com> Differential Revision: https://reviews.llvm.org/D112374
131 lines
3.6 KiB
C++
131 lines
3.6 KiB
C++
// Clear and create directories
|
|
// RUN: rm -rf %t
|
|
// RUN: mkdir %t
|
|
// RUN: mkdir %t/cache
|
|
// RUN: mkdir %t/Inputs
|
|
|
|
// Build first header file
|
|
// RUN: echo "#define FIRST" >> %t/Inputs/first.h
|
|
// RUN: cat %s >> %t/Inputs/first.h
|
|
|
|
// Build second header file
|
|
// RUN: echo "#define SECOND" >> %t/Inputs/second.h
|
|
// RUN: cat %s >> %t/Inputs/second.h
|
|
|
|
// Test that each header can compile
|
|
// RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %t/Inputs/first.h
|
|
// RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %t/Inputs/second.h
|
|
|
|
// Build module map file
|
|
// RUN: echo "module FirstModule {" >> %t/Inputs/module.map
|
|
// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map
|
|
// RUN: echo "}" >> %t/Inputs/module.map
|
|
// RUN: echo "module SecondModule {" >> %t/Inputs/module.map
|
|
// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map
|
|
// RUN: echo "}" >> %t/Inputs/module.map
|
|
|
|
// Run test
|
|
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=gnu++11
|
|
|
|
#if !defined(FIRST) && !defined(SECOND)
|
|
#include "first.h"
|
|
#include "second.h"
|
|
#endif
|
|
|
|
namespace Types {
|
|
namespace TypeOfExpr {
|
|
#if defined(FIRST)
|
|
struct Invalid1 {
|
|
typeof(1 + 2) x;
|
|
};
|
|
double global;
|
|
struct Invalid2 {
|
|
typeof(global) x;
|
|
};
|
|
struct Valid {
|
|
typeof(3) x;
|
|
typeof(x) y;
|
|
typeof(Valid*) self;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct Invalid1 {
|
|
typeof(3) x;
|
|
};
|
|
int global;
|
|
struct Invalid2 {
|
|
typeof(global) x;
|
|
};
|
|
struct Valid {
|
|
typeof(3) x;
|
|
typeof(x) y;
|
|
typeof(Valid*) self;
|
|
};
|
|
#else
|
|
Invalid1 i1;
|
|
// expected-error@first.h:* {{'Types::TypeOfExpr::Invalid1' has different definitions in different modules; first difference is definition in module 'FirstModule' found field 'x' with type 'typeof (1 + 2)' (aka 'int')}}
|
|
// expected-note@second.h:* {{but in 'SecondModule' found field 'x' with type 'typeof (3)' (aka 'int')}}
|
|
Invalid2 i2;
|
|
// expected-error@second.h:* {{'Types::TypeOfExpr::Invalid2::x' from module 'SecondModule' is not present in definition of 'Types::TypeOfExpr::Invalid2' in module 'FirstModule'}}
|
|
// expected-note@first.h:* {{declaration of 'x' does not match}}
|
|
Valid v;
|
|
#endif
|
|
} // namespace TypeOfExpr
|
|
|
|
namespace TypeOf {
|
|
#if defined(FIRST)
|
|
struct Invalid1 {
|
|
typeof(int) x;
|
|
};
|
|
struct Invalid2 {
|
|
typeof(int) x;
|
|
};
|
|
using T = int;
|
|
struct Invalid3 {
|
|
typeof(T) x;
|
|
};
|
|
struct Valid {
|
|
typeof(int) x;
|
|
using T = typeof(double);
|
|
typeof(T) y;
|
|
};
|
|
#elif defined(SECOND)
|
|
struct Invalid1 {
|
|
typeof(double) x;
|
|
};
|
|
using I = int;
|
|
struct Invalid2 {
|
|
typeof(I) x;
|
|
};
|
|
using T = short;
|
|
struct Invalid3 {
|
|
typeof(T) x;
|
|
};
|
|
struct Valid {
|
|
typeof(int) x;
|
|
using T = typeof(double);
|
|
typeof(T) y;
|
|
};
|
|
#else
|
|
Invalid1 i1;
|
|
// expected-error@second.h:* {{'Types::TypeOf::Invalid1::x' from module 'SecondModule' is not present in definition of 'Types::TypeOf::Invalid1' in module 'FirstModule'}}
|
|
// expected-note@first.h:* {{declaration of 'x' does not match}}
|
|
Invalid2 i2;
|
|
// expected-error@first.h:* {{'Types::TypeOf::Invalid2' has different definitions in different modules; first difference is definition in module 'FirstModule' found field 'x' with type 'typeof(int)' (aka 'int')}}
|
|
// expected-note@second.h:* {{but in 'SecondModule' found field 'x' with type 'typeof(I)' (aka 'int')}}
|
|
Invalid3 i3;
|
|
// expected-error@second.h:* {{'Types::TypeOf::Invalid3::x' from module 'SecondModule' is not present in definition of 'Types::TypeOf::Invalid3' in module 'FirstModule'}}
|
|
// expected-note@first.h:* {{declaration of 'x' does not match}}
|
|
Valid v;
|
|
#endif
|
|
} // namespace TypeOf
|
|
} // namespace Types
|
|
|
|
// Keep macros contained to one file.
|
|
#ifdef FIRST
|
|
#undef FIRST
|
|
#endif
|
|
|
|
#ifdef SECOND
|
|
#undef SECOND
|
|
#endif
|