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