r300001 - Revert r298824 & r298816, recommit r298742 & r298754
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 12 13:38:27 PDT 2017
Yup, that looks like my fault, again.
Thanks, Greg, for the test case. It's very similar to the final test in
odr_hash.cc, which I thought I had fixed.
On Wed, Apr 12, 2017 at 8:09 AM, Greg Bedwell <gregbedwell at gmail.com> wrote:
> We're seeing the same assertion failing in our internal testing (I've not
> bisected to a specific change yet though, but it seems likely it's the same
> thing as in the log from the modules bot). Here's a reduced example that
> triggers it:
>
> $ cat 2.h
> // ============================================
> template <typename alpha> struct Bravo {
> void charlie(bool delta = false) {}
> };
> typedef Bravo<char> echo;
> echo foxtrot;
> // ============================================
>
> $ clang.exe -x c++-header 2.h
> Assertion failed: !hasUninstantiatedDefaultArg() && "Default argument is
> not yet instantiated!", file C:\llvm\tools\clang\lib\AST\Decl.cpp, line
> 2424
>
> -Greg
>
>
>
> On 12 April 2017 at 02:52, Richard Smith via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Either this or your other ODR hash change seems to have broken the
>> modules buildbot:
>>
>> http://lab.llvm.org:8011/builders/clang-x86_64-linux-selfhos
>> t-modules-2/builds/6274/steps/compile.llvm.stage2/logs/stdio
>>
>> On 11 April 2017 at 15:32, Richard Trieu via cfe-commits <
>> cfe-commits at lists.llvm.org> wrote:
>>
>>> Author: rtrieu
>>> Date: Tue Apr 11 17:32:03 2017
>>> New Revision: 300001
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=300001&view=rev
>>> Log:
>>> Revert r298824 & r298816, recommit r298742 & r298754
>>>
>>> r299989 fixes the underlying issue by waiting long enough to late parsed
>>> arguments to be processed before doing an calculating the hash.
>>>
>>> r298742
>>> [ODRHash] Add error messages for mismatched parameters in methods.
>>>
>>> r298754
>>> [ODRHash] Add support for array and decayed types.
>>>
>>> Modified:
>>> cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
>>> cfe/trunk/lib/AST/ODRHash.cpp
>>> cfe/trunk/lib/Serialization/ASTReader.cpp
>>> cfe/trunk/test/Modules/odr_hash.cpp
>>>
>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>>> Basic/DiagnosticSerializationKinds.td?rev=300001&r1=300000&r
>>> 2=300001&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
>>> (original)
>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Tue
>>> Apr 11 17:32:03 2017
>>> @@ -146,7 +146,12 @@ def err_module_odr_violation_mismatch_de
>>> "method %4 is %select{not static|static}5|"
>>> "method %4 is %select{not volatile|volatile}5|"
>>> "method %4 is %select{not const|const}5|"
>>> - "method %4 is %select{not inline|inline}5}3">;
>>> + "method %4 is %select{not inline|inline}5|"
>>> + "method %4 that has %5 parameter%s5|"
>>> + "method %4 with %ordinal5 parameter of type %6%select{| decayed from
>>> %8}7|"
>>> + "method %4 with %ordinal5 parameter named %6|"
>>> + "method %4 with %ordinal5 parameter with %select{no |}6default
>>> argument|"
>>> + "method %4 with %ordinal5 parameter with default argument}3">;
>>>
>>> def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0'
>>> found "
>>> "%select{"
>>> @@ -166,7 +171,12 @@ def note_module_odr_violation_mismatch_d
>>> "method %2 is %select{not static|static}3|"
>>> "method %2 is %select{not volatile|volatile}3|"
>>> "method %2 is %select{not const|const}3|"
>>> - "method %2 is %select{not inline|inline}3}1">;
>>> + "method %2 is %select{not inline|inline}3|"
>>> + "method %2 that has %3 parameter%s3|"
>>> + "method %2 with %ordinal3 parameter of type %4%select{| decayed from
>>> %6}5|"
>>> + "method %2 with %ordinal3 parameter named %4|"
>>> + "method %2 with %ordinal3 parameter with %select{no |}4default
>>> argument|"
>>> + "method %2 with %ordinal3 parameter with different default
>>> argument}1">;
>>>
>>> def warn_module_uses_date_time : Warning<
>>> "%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
>>>
>>> Modified: cfe/trunk/lib/AST/ODRHash.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHas
>>> h.cpp?rev=300001&r1=300000&r2=300001&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/lib/AST/ODRHash.cpp (original)
>>> +++ cfe/trunk/lib/AST/ODRHash.cpp Tue Apr 11 17:32:03 2017
>>> @@ -169,6 +169,11 @@ public:
>>> Inherited::VisitValueDecl(D);
>>> }
>>>
>>> + void VisitParmVarDecl(const ParmVarDecl *D) {
>>> + AddStmt(D->getDefaultArg());
>>> + Inherited::VisitParmVarDecl(D);
>>> + }
>>> +
>>> void VisitAccessSpecDecl(const AccessSpecDecl *D) {
>>> ID.AddInteger(D->getAccess());
>>> Inherited::VisitAccessSpecDecl(D);
>>> @@ -202,6 +207,12 @@ public:
>>> Hash.AddBoolean(D->isPure());
>>> Hash.AddBoolean(D->isDeletedAsWritten());
>>>
>>> + ID.AddInteger(D->param_size());
>>> +
>>> + for (auto *Param : D->parameters()) {
>>> + Hash.AddSubDecl(Param);
>>> + }
>>> +
>>> Inherited::VisitFunctionDecl(D);
>>> }
>>>
>>> @@ -315,6 +326,14 @@ public:
>>> }
>>> }
>>>
>>> + void AddQualType(QualType T) {
>>> + Hash.AddQualType(T);
>>> + }
>>> +
>>> + void VisitQualifiers(Qualifiers Quals) {
>>> + ID.AddInteger(Quals.getAsOpaqueValue());
>>> + }
>>> +
>>> void Visit(const Type *T) {
>>> ID.AddInteger(T->getTypeClass());
>>> Inherited::Visit(T);
>>> @@ -322,11 +341,92 @@ public:
>>>
>>> void VisitType(const Type *T) {}
>>>
>>> + void VisitAdjustedType(const AdjustedType *T) {
>>> + AddQualType(T->getOriginalType());
>>> + AddQualType(T->getAdjustedType());
>>> + VisitType(T);
>>> + }
>>> +
>>> + void VisitDecayedType(const DecayedType *T) {
>>> + AddQualType(T->getDecayedType());
>>> + AddQualType(T->getPointeeType());
>>> + VisitAdjustedType(T);
>>> + }
>>> +
>>> + void VisitArrayType(const ArrayType *T) {
>>> + AddQualType(T->getElementType());
>>> + ID.AddInteger(T->getSizeModifier());
>>> + VisitQualifiers(T->getIndexTypeQualifiers());
>>> + VisitType(T);
>>> + }
>>> + void VisitConstantArrayType(const ConstantArrayType *T) {
>>> + T->getSize().Profile(ID);
>>> + VisitArrayType(T);
>>> + }
>>> +
>>> + void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
>>> + AddStmt(T->getSizeExpr());
>>> + VisitArrayType(T);
>>> + }
>>> +
>>> + void VisitIncompleteArrayType(const IncompleteArrayType *T) {
>>> + VisitArrayType(T);
>>> + }
>>> +
>>> + void VisitVariableArrayType(const VariableArrayType *T) {
>>> + AddStmt(T->getSizeExpr());
>>> + VisitArrayType(T);
>>> + }
>>> +
>>> void VisitBuiltinType(const BuiltinType *T) {
>>> ID.AddInteger(T->getKind());
>>> VisitType(T);
>>> }
>>>
>>> + void VisitFunctionType(const FunctionType *T) {
>>> + AddQualType(T->getReturnType());
>>> + T->getExtInfo().Profile(ID);
>>> + Hash.AddBoolean(T->isConst());
>>> + Hash.AddBoolean(T->isVolatile());
>>> + Hash.AddBoolean(T->isRestrict());
>>> + VisitType(T);
>>> + }
>>> +
>>> + void VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
>>> + VisitFunctionType(T);
>>> + }
>>> +
>>> + void VisitFunctionProtoType(const FunctionProtoType *T) {
>>> + ID.AddInteger(T->getNumParams());
>>> + for (auto ParamType : T->getParamTypes())
>>> + AddQualType(ParamType);
>>> +
>>> + const auto &epi = T->getExtProtoInfo();
>>> + ID.AddInteger(epi.Variadic);
>>> + ID.AddInteger(epi.TypeQuals);
>>> + ID.AddInteger(epi.RefQualifier);
>>> + ID.AddInteger(epi.ExceptionSpec.Type);
>>> +
>>> + if (epi.ExceptionSpec.Type == EST_Dynamic) {
>>> + for (QualType Ex : epi.ExceptionSpec.Exceptions)
>>> + AddQualType(Ex);
>>> + } else if (epi.ExceptionSpec.Type == EST_ComputedNoexcept &&
>>> + epi.ExceptionSpec.NoexceptExpr) {
>>> + AddStmt(epi.ExceptionSpec.NoexceptExpr);
>>> + } else if (epi.ExceptionSpec.Type == EST_Uninstantiated ||
>>> + epi.ExceptionSpec.Type == EST_Unevaluated) {
>>> + AddDecl(epi.ExceptionSpec.SourceDecl->getCanonicalDecl());
>>> + }
>>> + if (epi.ExtParameterInfos) {
>>> + for (unsigned i = 0; i != T->getNumParams(); ++i)
>>> + ID.AddInteger(epi.ExtParameterInfos[i].getOpaqueValue());
>>> + }
>>> + epi.ExtInfo.Profile(ID);
>>> + Hash.AddBoolean(epi.HasTrailingReturn);
>>> +
>>> + VisitFunctionType(T);
>>> + }
>>> +
>>> void VisitTypedefType(const TypedefType *T) {
>>> AddDecl(T->getDecl());
>>> Hash.AddQualType(T->getDecl()->getUnderlyingType());
>>>
>>> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serializat
>>> ion/ASTReader.cpp?rev=300001&r1=300000&r2=300001&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
>>> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Apr 11 17:32:03 2017
>>> @@ -9282,6 +9282,11 @@ void ASTReader::diagnoseOdrViolations()
>>> MethodVolatile,
>>> MethodConst,
>>> MethodInline,
>>> + MethodNumberParameters,
>>> + MethodParameterType,
>>> + MethodParameterName,
>>> + MethodParameterSingleDefaultArgument,
>>> + MethodParameterDifferentDefaultArguments,
>>> };
>>>
>>> // These lambdas have the common portions of the ODR
>>> diagnostics. This
>>> @@ -9605,6 +9610,104 @@ void ASTReader::diagnoseOdrViolations()
>>> Diagnosed = true;
>>> break;
>>> }
>>> +
>>> + const unsigned FirstNumParameters = FirstMethod->param_size();
>>> + const unsigned SecondNumParameters = SecondMethod->param_size();
>>> + if (FirstNumParameters != SecondNumParameters) {
>>> + ODRDiagError(FirstMethod->getLocation(),
>>> + FirstMethod->getSourceRange(),
>>> MethodNumberParameters)
>>> + << FirstName << FirstNumParameters;
>>> + ODRDiagNote(SecondMethod->getLocation(),
>>> + SecondMethod->getSourceRange(),
>>> MethodNumberParameters)
>>> + << SecondName << SecondNumParameters;
>>> + Diagnosed = true;
>>> + break;
>>> + }
>>> +
>>> + // Need this status boolean to know when break out of the
>>> switch.
>>> + bool ParameterMismatch = false;
>>> + for (unsigned I = 0; I < FirstNumParameters; ++I) {
>>> + const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
>>> + const ParmVarDecl *SecondParam =
>>> SecondMethod->getParamDecl(I);
>>> +
>>> + QualType FirstParamType = FirstParam->getType();
>>> + QualType SecondParamType = SecondParam->getType();
>>> + if (FirstParamType != SecondParamType) {
>>> + if (const DecayedType *ParamDecayedType =
>>> + FirstParamType->getAs<DecayedType>()) {
>>> + ODRDiagError(FirstMethod->getLocation(),
>>> + FirstMethod->getSourceRange(),
>>> MethodParameterType)
>>> + << FirstName << (I + 1) << FirstParamType << true
>>> + << ParamDecayedType->getOriginalType();
>>> + } else {
>>> + ODRDiagError(FirstMethod->getLocation(),
>>> + FirstMethod->getSourceRange(),
>>> MethodParameterType)
>>> + << FirstName << (I + 1) << FirstParamType << false;
>>> + }
>>> +
>>> + if (const DecayedType *ParamDecayedType =
>>> + SecondParamType->getAs<DecayedType>()) {
>>> + ODRDiagNote(SecondMethod->getLocation(),
>>> + SecondMethod->getSourceRange(),
>>> MethodParameterType)
>>> + << SecondName << (I + 1) << SecondParamType << true
>>> + << ParamDecayedType->getOriginalType();
>>> + } else {
>>> + ODRDiagNote(SecondMethod->getLocation(),
>>> + SecondMethod->getSourceRange(),
>>> MethodParameterType)
>>> + << SecondName << (I + 1) << SecondParamType << false;
>>> + }
>>> + ParameterMismatch = true;
>>> + break;
>>> + }
>>> +
>>> + DeclarationName FirstParamName = FirstParam->getDeclName();
>>> + DeclarationName SecondParamName = SecondParam->getDeclName();
>>> + if (FirstParamName != SecondParamName) {
>>> + ODRDiagError(FirstMethod->getLocation(),
>>> + FirstMethod->getSourceRange(),
>>> MethodParameterName)
>>> + << FirstName << (I + 1) << FirstParamName;
>>> + ODRDiagNote(SecondMethod->getLocation(),
>>> + SecondMethod->getSourceRange(),
>>> MethodParameterName)
>>> + << SecondName << (I + 1) << SecondParamName;
>>> + ParameterMismatch = true;
>>> + break;
>>> + }
>>> +
>>> + const Expr* FirstDefaultArg = FirstParam->getDefaultArg();
>>> + const Expr* SecondDefaultArg = SecondParam->getDefaultArg();
>>> + if ((!FirstDefaultArg && SecondDefaultArg) ||
>>> + (FirstDefaultArg && !SecondDefaultArg)) {
>>> + ODRDiagError(FirstMethod->getLocation(),
>>> + FirstMethod->getSourceRange(),
>>> + MethodParameterSingleDefaultArgument)
>>> + << FirstName << (I + 1) << (FirstDefaultArg != nullptr);
>>> + ODRDiagNote(SecondMethod->getLocation(),
>>> + SecondMethod->getSourceRange(),
>>> + MethodParameterSingleDefaultArgument)
>>> + << SecondName << (I + 1) << (SecondDefaultArg !=
>>> nullptr);
>>> + ParameterMismatch = true;
>>> + break;
>>> + }
>>> +
>>> + if (ComputeODRHash(FirstDefaultArg) !=
>>> + ComputeODRHash(SecondDefaultArg)) {
>>> + ODRDiagError(FirstMethod->getLocation(),
>>> + FirstMethod->getSourceRange(),
>>> + MethodParameterDifferentDefaultArguments)
>>> + << FirstName << (I + 1);
>>> + ODRDiagNote(SecondMethod->getLocation(),
>>> + SecondMethod->getSourceRange(),
>>> + MethodParameterDifferentDefaultArguments)
>>> + << SecondName << (I + 1);
>>> + ParameterMismatch = true;
>>> + break;
>>> + }
>>> + }
>>> +
>>> + if (ParameterMismatch) {
>>> + Diagnosed = true;
>>> + break;
>>> + }
>>>
>>> break;
>>> }
>>>
>>> Modified: cfe/trunk/test/Modules/odr_hash.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/o
>>> dr_hash.cpp?rev=300001&r1=300000&r2=300001&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/test/Modules/odr_hash.cpp (original)
>>> +++ cfe/trunk/test/Modules/odr_hash.cpp Tue Apr 11 17:32:03 2017
>>> @@ -275,6 +275,33 @@ S11 s11;
>>> // expected-note at first.h:* {{but in 'FirstModule' found field 'x' with
>>> a different initializer}}
>>> #endif
>>>
>>> +#if defined(FIRST)
>>> +struct S12 {
>>> + unsigned x[5];
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S12 {
>>> + unsigned x[7];
>>> +};
>>> +#else
>>> +S12 s12;
>>> +// expected-error at first.h:* {{'Field::S12::x' from module
>>> 'FirstModule' is not present in definition of 'Field::S12' in module
>>> 'SecondModule'}}
>>> +// expected-note at second.h:* {{declaration of 'x' does not match}}
>>> +#endif
>>> +
>>> +#if defined(FIRST)
>>> +struct S13 {
>>> + unsigned x[7];
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S13 {
>>> + double x[7];
>>> +};
>>> +#else
>>> +S13 s13;
>>> +// expected-error at first.h:* {{'Field::S13::x' from module
>>> 'FirstModule' is not present in definition of 'Field::S13' in module
>>> 'SecondModule'}}
>>> +// expected-note at second.h:* {{declaration of 'x' does not match}}
>>> +#endif
>>> } // namespace Field
>>>
>>> namespace Method {
>>> @@ -403,6 +430,93 @@ S8 s8;
>>> // expected-note at first.h:* {{but in 'FirstModule' found method 'A' is
>>> const}}
>>> #endif
>>>
>>> +#if defined(FIRST)
>>> +struct S9 {
>>> + void A(int x) {}
>>> + void A(int x, int y) {}
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S9 {
>>> + void A(int x, int y) {}
>>> + void A(int x) {}
>>> +};
>>> +#else
>>> +S9 s9;
>>> +// expected-error at second.h:* {{'Method::S9' has different definitions
>>> in different modules; first difference is definition in module
>>> 'SecondModule' found method 'A' that has 2 parameters}}
>>> +// expected-note at first.h:* {{but in 'FirstModule' found method 'A'
>>> that has 1 parameter}}
>>> +#endif
>>> +
>>> +#if defined(FIRST)
>>> +struct S10 {
>>> + void A(int x) {}
>>> + void A(float x) {}
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S10 {
>>> + void A(float x) {}
>>> + void A(int x) {}
>>> +};
>>> +#else
>>> +S10 s10;
>>> +// expected-error at second.h:* {{'Method::S10' has different definitions
>>> in different modules; first difference is definition in module
>>> 'SecondModule' found method 'A' with 1st parameter of type 'float'}}
>>> +// expected-note at first.h:* {{but in 'FirstModule' found method 'A'
>>> with 1st parameter of type 'int'}}
>>> +#endif
>>> +
>>> +#if defined(FIRST)
>>> +struct S11 {
>>> + void A(int x) {}
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S11 {
>>> + void A(int y) {}
>>> +};
>>> +#else
>>> +S11 s11;
>>> +// expected-error at second.h:* {{'Method::S11' has different definitions
>>> in different modules; first difference is definition in module
>>> 'SecondModule' found method 'A' with 1st parameter named 'y'}}
>>> +// expected-note at first.h:* {{but in 'FirstModule' found method 'A'
>>> with 1st parameter named 'x'}}
>>> +#endif
>>> +
>>> +#if defined(FIRST)
>>> +struct S12 {
>>> + void A(int x) {}
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S12 {
>>> + void A(int x = 1) {}
>>> +};
>>> +#else
>>> +S12 s12;
>>> +// expected-error at second.h:* {{'Method::S12' has different definitions
>>> in different modules; first difference is definition in module
>>> 'SecondModule' found method 'A' with 1st parameter with default argument}}
>>> +// expected-note at first.h:* {{but in 'FirstModule' found method 'A'
>>> with 1st parameter with no default argument}}
>>> +#endif
>>> +
>>> +#if defined(FIRST)
>>> +struct S13 {
>>> + void A(int x = 1 + 0) {}
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S13 {
>>> + void A(int x = 1) {}
>>> +};
>>> +#else
>>> +S13 s13;
>>> +// expected-error at second.h:* {{'Method::S13' has different definitions
>>> in different modules; first difference is definition in module
>>> 'SecondModule' found method 'A' with 1st parameter with default argument}}
>>> +// expected-note at first.h:* {{but in 'FirstModule' found method 'A'
>>> with 1st parameter with different default argument}}
>>> +#endif
>>> +
>>> +#if defined(FIRST)
>>> +struct S14 {
>>> + void A(int x[2]) {}
>>> +};
>>> +#elif defined(SECOND)
>>> +struct S14 {
>>> + void A(int x[3]) {}
>>> +};
>>> +#else
>>> +S14 s14;
>>> +// expected-error at second.h:* {{'Method::S14' has different definitions
>>> in different modules; first difference is definition in module
>>> 'SecondModule' found method 'A' with 1st parameter of type 'int *' decayed
>>> from 'int [3]'}}
>>> +// expected-note at first.h:* {{but in 'FirstModule' found method 'A'
>>> with 1st parameter of type 'int *' decayed from 'int [2]'}}
>>> +#endif
>>> } // namespace Method
>>>
>>> // Naive parsing of AST can lead to cycles in processing. Ensure
>>> @@ -522,71 +636,54 @@ S3 s3;
>>> #endif
>>> } // namespace Using
>>>
>>> -
>>> // Interesting cases that should not cause errors. struct S should not
>>> error
>>> // while struct T should error at the access specifier mismatch at the
>>> end.
>>> +#define ALL_DECLS \
>>> +public: \
>>> +private: \
>>> +protected: \
>>> + static_assert(1 == 1, "Message"); \
>>> + static_assert(2 == 2); \
>>> + \
>>> + int x; \
>>> + double y; \
>>> + \
>>> + INT z; \
>>> + \
>>> + unsigned a : 1; \
>>> + unsigned b : 2 * 2 + 5 / 2; \
>>> + \
>>> + mutable int c = sizeof(x + y); \
>>> + \
>>> + void method() {} \
>>> + static void static_method() {} \
>>> + virtual void virtual_method() {} \
>>> + virtual void pure_virtual_method() = 0; \
>>> + inline void inline_method() {} \
>>> + void volatile_method() volatile {} \
>>> + void const_method() const {} \
>>> + \
>>> + typedef int typedef_int; \
>>> + using using_int = int; \
>>> + \
>>> + void method_one_arg(int x) {} \
>>> + void method_one_arg_default_argument(int x = 5 + 5) {} \
>>> + void method_decayed_type(int x[5]) {} \
>>> + \
>>> + int constant_arr[5]; \
>>> + \
>>> + double last_decl;
>>> +
>>> namespace AllDecls {
>>> #if defined(FIRST)
>>> typedef int INT;
>>> struct S {
>>> - public:
>>> - private:
>>> - protected:
>>> -
>>> - static_assert(1 == 1, "Message");
>>> - static_assert(2 == 2);
>>> -
>>> - int x;
>>> - double y;
>>> -
>>> - INT z;
>>> -
>>> - unsigned a : 1;
>>> - unsigned b : 2*2 + 5/2;
>>> -
>>> - mutable int c = sizeof(x + y);
>>> -
>>> - void method() {}
>>> - static void static_method() {}
>>> - virtual void virtual_method() {}
>>> - virtual void pure_virtual_method() = 0;
>>> - inline void inline_method() {}
>>> - void volatile_method() volatile {}
>>> - void const_method() const {}
>>> -
>>> - typedef int typedef_int;
>>> - using using_int = int;
>>> + ALL_DECLS
>>> };
>>> #elif defined(SECOND)
>>> typedef int INT;
>>> struct S {
>>> - public:
>>> - private:
>>> - protected:
>>> -
>>> - static_assert(1 == 1, "Message");
>>> - static_assert(2 == 2);
>>> -
>>> - int x;
>>> - double y;
>>> -
>>> - INT z;
>>> -
>>> - unsigned a : 1;
>>> - unsigned b : 2 * 2 + 5 / 2;
>>> -
>>> - mutable int c = sizeof(x + y);
>>> -
>>> - void method() {}
>>> - static void static_method() {}
>>> - virtual void virtual_method() {}
>>> - virtual void pure_virtual_method() = 0;
>>> - inline void inline_method() {}
>>> - void volatile_method() volatile {}
>>> - void const_method() const {}
>>> -
>>> - typedef int typedef_int;
>>> - using using_int = int;
>>> + ALL_DECLS
>>> };
>>> #else
>>> S *s;
>>> @@ -595,66 +692,14 @@ S *s;
>>> #if defined(FIRST)
>>> typedef int INT;
>>> struct T {
>>> - public:
>>> - private:
>>> - protected:
>>> -
>>> - static_assert(1 == 1, "Message");
>>> - static_assert(2 == 2);
>>> -
>>> - int x;
>>> - double y;
>>> -
>>> - INT z;
>>> -
>>> - unsigned a : 1;
>>> - unsigned b : 2 * 2 + 5 / 2;
>>> -
>>> - mutable int c = sizeof(x + y);
>>> -
>>> - void method() {}
>>> - static void static_method() {}
>>> - virtual void virtual_method() {}
>>> - virtual void pure_virtual_method() = 0;
>>> - inline void inline_method() {}
>>> - void volatile_method() volatile {}
>>> - void const_method() const {}
>>> -
>>> - typedef int typedef_int;
>>> - using using_int = int;
>>> + ALL_DECLS
>>>
>>> private:
>>> };
>>> #elif defined(SECOND)
>>> typedef int INT;
>>> struct T {
>>> - public:
>>> - private:
>>> - protected:
>>> -
>>> - static_assert(1 == 1, "Message");
>>> - static_assert(2 == 2);
>>> -
>>> - int x;
>>> - double y;
>>> -
>>> - INT z;
>>> -
>>> - unsigned a : 1;
>>> - unsigned b : 2 * 2 + 5 / 2;
>>> -
>>> - mutable int c = sizeof(x + y);
>>> -
>>> - void method() {}
>>> - static void static_method() {}
>>> - virtual void virtual_method() {}
>>> - virtual void pure_virtual_method() = 0;
>>> - inline void inline_method() {}
>>> - void volatile_method() volatile {}
>>> - void const_method() const {}
>>> -
>>> - typedef int typedef_int;
>>> - using using_int = int;
>>> + ALL_DECLS
>>>
>>> public:
>>> };
>>> @@ -944,6 +989,22 @@ T t;
>>> #endif
>>> } // namespace StructWithForwardDeclarationNoDefinition
>>>
>>> +namespace LateParsedDefaultArgument {
>>> +#if defined(FIRST)
>>> +template <typename T>
>>> +struct S {
>>> + struct R {
>>> + void foo(T x = 0) {}
>>> + };
>>> +};
>>> +#elif defined(SECOND)
>>> +#else
>>> +void run() {
>>> + S<int>::R().foo();
>>> +}
>>> +#endif
>>> +}
>>> +
>>> // Keep macros contained to one file.
>>> #ifdef FIRST
>>> #undef FIRST
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170412/9c692377/attachment-0001.html>
More information about the cfe-commits
mailing list