r300001 - Revert r298824 & r298816, recommit r298742 & r298754
Greg Bedwell via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 12 08:09:44 PDT 2017
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-
> selfhost-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&
>> r2=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/
>> odr_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/f5a20b74/attachment-0001.html>
More information about the cfe-commits
mailing list