summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang')
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/Sema.h20
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp1367
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/Address.h20
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp17
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp226
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp19
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp290
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp134
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp25
12 files changed, 1126 insertions, 1002 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h
index ffe1ff3..29aa642 100644
--- a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h
+++ b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h
@@ -2229,7 +2229,8 @@ public:
bool CheckPointerConversion(Expr *From, QualType ToType,
CastKind &Kind,
CXXCastPath& BasePath,
- bool IgnoreBaseAccess);
+ bool IgnoreBaseAccess,
+ bool Diagnose = true);
bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
bool InOverloadResolution,
QualType &ConvertedType);
@@ -5388,7 +5389,8 @@ public:
unsigned AmbigiousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name,
- CXXCastPath *BasePath);
+ CXXCastPath *BasePath,
+ bool IgnoreAccess = false);
std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
@@ -7514,14 +7516,15 @@ public:
ObjCMethodDecl *&ClassMethod,
ObjCMethodDecl *&InstanceMethod,
TypedefNameDecl *&TDNDecl,
- bool CfToNs);
-
+ bool CfToNs, bool Diagnose = true);
+
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
QualType DestType, QualType SrcType,
- Expr *&SrcExpr);
-
- bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
-
+ Expr *&SrcExpr, bool Diagnose = true);
+
+ bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr,
+ bool Diagnose = true);
+
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
/// \brief Check whether the given new method is a valid override of the
@@ -8613,6 +8616,7 @@ public:
ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
QualType castType, Expr *&op,
CheckedConversionKind CCK,
+ bool Diagnose = true,
bool DiagnoseCFAudited = false,
BinaryOperatorKind Opc = BO_PtrMemD
);
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
index 0ab1fa7..2ab5a32 100644
--- a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
@@ -473,14 +473,14 @@ class TemplateDiff {
/// ShowColor - Diagnostics support color, so bolding will be used.
bool ShowColor;
- /// FromType - When single type printing is selected, this is the type to be
- /// be printed. When tree printing is selected, this type will show up first
- /// in the tree.
- QualType FromType;
+ /// FromTemplateType - When single type printing is selected, this is the
+ /// type to be be printed. When tree printing is selected, this type will
+ /// show up first in the tree.
+ QualType FromTemplateType;
- /// ToType - The type that FromType is compared to. Only in tree printing
- /// will this type be outputed.
- QualType ToType;
+ /// ToTemplateType - The type that FromType is compared to. Only in tree
+ /// printing will this type be outputed.
+ QualType ToTemplateType;
/// OS - The stream used to construct the output strings.
raw_ostream &OS;
@@ -491,82 +491,70 @@ class TemplateDiff {
/// DiffTree - A tree representation the differences between two types.
class DiffTree {
public:
- /// DiffKind - The difference in a DiffNode and which fields are used.
+ /// DiffKind - The difference in a DiffNode. Fields of
+ /// TemplateArgumentInfo needed by each difference can be found in the
+ /// Set* and Get* functions.
enum DiffKind {
/// Incomplete or invalid node.
Invalid,
- /// Another level of templates, uses TemplateDecl and Qualifiers
+ /// Another level of templates, requires that
Template,
- /// Type difference, uses QualType
+ /// Type difference, all type differences except those falling under
+ /// the Template difference.
Type,
- /// Expression difference, uses Expr
+ /// Expression difference, this is only when both arguments are
+ /// expressions. If one argument is an expression and the other is
+ /// Integer or Declaration, then use that diff type instead.
Expression,
- /// Template argument difference, uses TemplateDecl
+ /// Template argument difference
TemplateTemplate,
- /// Integer difference, uses APSInt and Expr
+ /// Integer difference
Integer,
- /// Declaration difference, uses ValueDecl
- Declaration
+ /// Declaration difference, nullptr arguments are included here
+ Declaration,
+ /// One argument being integer and the other being declaration
+ FromIntegerAndToDeclaration,
+ FromDeclarationAndToInteger
};
+
private:
+ /// TemplateArgumentInfo - All the information needed to pretty print
+ /// a template argument. See the Set* and Get* functions to see which
+ /// fields are used for each DiffKind.
+ struct TemplateArgumentInfo {
+ QualType ArgType;
+ Qualifiers Qual;
+ llvm::APSInt Val;
+ bool IsValidInt = false;
+ Expr *ArgExpr = nullptr;
+ TemplateDecl *TD = nullptr;
+ ValueDecl *VD = nullptr;
+ bool NeedAddressOf = false;
+ bool IsNullPtr = false;
+ bool IsDefault = false;
+ };
+
/// DiffNode - The root node stores the original type. Each child node
/// stores template arguments of their parents. For templated types, the
/// template decl is also stored.
struct DiffNode {
- DiffKind Kind;
+ DiffKind Kind = Invalid;
/// NextNode - The index of the next sibling node or 0.
- unsigned NextNode;
+ unsigned NextNode = 0;
/// ChildNode - The index of the first child node or 0.
- unsigned ChildNode;
+ unsigned ChildNode = 0;
/// ParentNode - The index of the parent node.
- unsigned ParentNode;
-
- /// FromType, ToType - The type arguments.
- QualType FromType, ToType;
-
- /// FromExpr, ToExpr - The expression arguments.
- Expr *FromExpr, *ToExpr;
-
- /// FromNullPtr, ToNullPtr - If the template argument is a nullptr
- bool FromNullPtr, ToNullPtr;
-
- /// FromTD, ToTD - The template decl for template template
- /// arguments or the type arguments that are templates.
- TemplateDecl *FromTD, *ToTD;
-
- /// FromQual, ToQual - Qualifiers for template types.
- Qualifiers FromQual, ToQual;
+ unsigned ParentNode = 0;
- /// FromInt, ToInt - APSInt's for integral arguments.
- llvm::APSInt FromInt, ToInt;
-
- /// IsValidFromInt, IsValidToInt - Whether the APSInt's are valid.
- bool IsValidFromInt, IsValidToInt;
-
- /// FromValueDecl, ToValueDecl - Whether the argument is a decl.
- ValueDecl *FromValueDecl, *ToValueDecl;
-
- /// FromAddressOf, ToAddressOf - Whether the ValueDecl needs an address of
- /// operator before it.
- bool FromAddressOf, ToAddressOf;
-
- /// FromDefault, ToDefault - Whether the argument is a default argument.
- bool FromDefault, ToDefault;
+ TemplateArgumentInfo FromArgInfo, ToArgInfo;
/// Same - Whether the two arguments evaluate to the same value.
- bool Same;
-
- DiffNode(unsigned ParentNode = 0)
- : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),
- FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),
- FromNullPtr(false), ToNullPtr(false),
- FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false),
- IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr),
- FromAddressOf(false), ToAddressOf(false), FromDefault(false),
- ToDefault(false), Same(false) {}
+ bool Same = false;
+
+ DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {}
};
/// FlatTree - A flattened tree used to store the DiffNodes.
@@ -581,54 +569,127 @@ class TemplateDiff {
/// ReadNode - The index of the current node being read.
unsigned ReadNode;
-
+
public:
DiffTree() :
CurrentNode(0), NextFreeNode(1) {
FlatTree.push_back(DiffNode());
}
- // Node writing functions.
- /// SetNode - Sets FromTD and ToTD of the current node.
- void SetNode(TemplateDecl *FromTD, TemplateDecl *ToTD) {
- FlatTree[CurrentNode].FromTD = FromTD;
- FlatTree[CurrentNode].ToTD = ToTD;
+ // Node writing functions, one for each valid DiffKind element.
+ void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
+ Qualifiers FromQual, Qualifiers ToQual,
+ bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Template;
+ FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
+ FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
+ FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
+ FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault,
+ bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Type;
+ FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
+ FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault,
+ bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Expression;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
+ bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = TemplateTemplate;
+ FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
+ FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetIntegerDiff(llvm::APSInt FromInt, llvm::APSInt ToInt,
+ bool IsValidFromInt, bool IsValidToInt,
+ QualType FromIntType, QualType ToIntType,
+ Expr *FromExpr, Expr *ToExpr, bool FromDefault,
+ bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Integer;
+ FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
+ FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
+ FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
+ FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
+ FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
+ FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
+ bool FromAddressOf, bool ToAddressOf,
+ bool FromNullPtr, bool ToNullPtr, Expr *FromExpr,
+ Expr *ToExpr, bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Declaration;
+ FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
+ FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
+ FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
+ FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
+ FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
+ FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetFromDeclarationAndToIntegerDiff(
+ ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr,
+ Expr *FromExpr, llvm::APSInt ToInt, bool IsValidToInt,
+ QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
+ FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
+ FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
+ FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
+ FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
+ FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetFromIntegerAndToDeclarationDiff(
+ llvm::APSInt FromInt, bool IsValidFromInt, QualType FromIntType,
+ Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf,
+ bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
+ FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
+ FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
+ FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
+ FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
+ FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
}
- /// SetNode - Sets FromType and ToType of the current node.
- void SetNode(QualType FromType, QualType ToType) {
- FlatTree[CurrentNode].FromType = FromType;
- FlatTree[CurrentNode].ToType = ToType;
- }
-
- /// SetNode - Set FromExpr and ToExpr of the current node.
- void SetNode(Expr *FromExpr, Expr *ToExpr) {
- FlatTree[CurrentNode].FromExpr = FromExpr;
- FlatTree[CurrentNode].ToExpr = ToExpr;
- }
-
- /// SetNode - Set FromInt and ToInt of the current node.
- void SetNode(llvm::APSInt FromInt, llvm::APSInt ToInt,
- bool IsValidFromInt, bool IsValidToInt) {
- FlatTree[CurrentNode].FromInt = FromInt;
- FlatTree[CurrentNode].ToInt = ToInt;
- FlatTree[CurrentNode].IsValidFromInt = IsValidFromInt;
- FlatTree[CurrentNode].IsValidToInt = IsValidToInt;
- }
-
- /// SetNode - Set FromQual and ToQual of the current node.
- void SetNode(Qualifiers FromQual, Qualifiers ToQual) {
- FlatTree[CurrentNode].FromQual = FromQual;
- FlatTree[CurrentNode].ToQual = ToQual;
- }
-
- /// SetNode - Set FromValueDecl and ToValueDecl of the current node.
- void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
- bool FromAddressOf, bool ToAddressOf) {
- FlatTree[CurrentNode].FromValueDecl = FromValueDecl;
- FlatTree[CurrentNode].ToValueDecl = ToValueDecl;
- FlatTree[CurrentNode].FromAddressOf = FromAddressOf;
- FlatTree[CurrentNode].ToAddressOf = ToAddressOf;
+ /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
+ void SetDefault(bool FromDefault, bool ToDefault) {
+ assert((!FromDefault || !ToDefault) && "Both arguments cannot be default.");
+ FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
+ FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
}
/// SetSame - Sets the same flag of the current node.
@@ -636,18 +697,6 @@ class TemplateDiff {
FlatTree[CurrentNode].Same = Same;
}
- /// SetNullPtr - Sets the NullPtr flags of the current node.
- void SetNullPtr(bool FromNullPtr, bool ToNullPtr) {
- FlatTree[CurrentNode].FromNullPtr = FromNullPtr;
- FlatTree[CurrentNode].ToNullPtr = ToNullPtr;
- }
-
- /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
- void SetDefault(bool FromDefault, bool ToDefault) {
- FlatTree[CurrentNode].FromDefault = FromDefault;
- FlatTree[CurrentNode].ToDefault = ToDefault;
- }
-
/// SetKind - Sets the current node's type.
void SetKind(DiffKind Kind) {
FlatTree[CurrentNode].Kind = Kind;
@@ -655,12 +704,16 @@ class TemplateDiff {
/// Up - Changes the node to the parent of the current node.
void Up() {
+ assert(FlatTree[CurrentNode].Kind != Invalid &&
+ "Cannot exit node before setting node information.");
CurrentNode = FlatTree[CurrentNode].ParentNode;
}
/// AddNode - Adds a child node to the current node, then sets that node
/// node as the current node.
void AddNode() {
+ assert(FlatTree[CurrentNode].Kind == Template &&
+ "Only Template nodes can have children nodes.");
FlatTree.push_back(DiffNode(CurrentNode));
DiffNode &Node = FlatTree[CurrentNode];
if (Node.ChildNode == 0) {
@@ -692,46 +745,103 @@ class TemplateDiff {
ReadNode = FlatTree[ReadNode].ParentNode;
}
- /// GetNode - Gets the FromType and ToType.
- void GetNode(QualType &FromType, QualType &ToType) {
- FromType = FlatTree[ReadNode].FromType;
- ToType = FlatTree[ReadNode].ToType;
+ void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,
+ Qualifiers &FromQual, Qualifiers &ToQual) {
+ assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind.");
+ FromTD = FlatTree[ReadNode].FromArgInfo.TD;
+ ToTD = FlatTree[ReadNode].ToArgInfo.TD;
+ FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
+ ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
+ }
+
+ void GetTypeDiff(QualType &FromType, QualType &ToType) {
+ assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind");
+ FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
+ ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
+ }
+
+ void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind");
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
+ assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind.");
+ FromTD = FlatTree[ReadNode].FromArgInfo.TD;
+ ToTD = FlatTree[ReadNode].ToArgInfo.TD;
+ }
+
+ void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
+ bool &IsValidFromInt, bool &IsValidToInt,
+ QualType &FromIntType, QualType &ToIntType,
+ Expr *&FromExpr, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind.");
+ FromInt = FlatTree[ReadNode].FromArgInfo.Val;
+ ToInt = FlatTree[ReadNode].ToArgInfo.Val;
+ IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
+ IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
+ FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
+ ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
+ bool &FromAddressOf, bool &ToAddressOf,
+ bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr,
+ Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind.");
+ FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
+ ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
+ FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
+ ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
+ FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
+ ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetFromDeclarationAndToIntegerDiff(
+ ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr,
+ Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt,
+ QualType &ToIntType, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
+ "Unexpected kind.");
+ FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
+ FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
+ FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToInt = FlatTree[ReadNode].ToArgInfo.Val;
+ IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
+ ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetFromIntegerAndToDeclarationDiff(
+ llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType,
+ Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf,
+ bool &ToNullPtr, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
+ "Unexpected kind.");
+ FromInt = FlatTree[ReadNode].FromArgInfo.Val;
+ IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
+ FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
+ ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
+ ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
}
- /// GetNode - Gets the FromExpr and ToExpr.
- void GetNode(Expr *&FromExpr, Expr *&ToExpr) {
- FromExpr = FlatTree[ReadNode].FromExpr;
- ToExpr = FlatTree[ReadNode].ToExpr;
- }
-
- /// GetNode - Gets the FromTD and ToTD.
- void GetNode(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
- FromTD = FlatTree[ReadNode].FromTD;
- ToTD = FlatTree[ReadNode].ToTD;
- }
-
- /// GetNode - Gets the FromInt and ToInt.
- void GetNode(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
- bool &IsValidFromInt, bool &IsValidToInt) {
- FromInt = FlatTree[ReadNode].FromInt;
- ToInt = FlatTree[ReadNode].ToInt;
- IsValidFromInt = FlatTree[ReadNode].IsValidFromInt;
- IsValidToInt = FlatTree[ReadNode].IsValidToInt;
- }
-
- /// GetNode - Gets the FromQual and ToQual.
- void GetNode(Qualifiers &FromQual, Qualifiers &ToQual) {
- FromQual = FlatTree[ReadNode].FromQual;
- ToQual = FlatTree[ReadNode].ToQual;
+ /// FromDefault - Return true if the from argument is the default.
+ bool FromDefault() {
+ return FlatTree[ReadNode].FromArgInfo.IsDefault;
}
- /// GetNode - Gets the FromValueDecl and ToValueDecl.
- void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
- bool &FromAddressOf, bool &ToAddressOf) {
- FromValueDecl = FlatTree[ReadNode].FromValueDecl;
- ToValueDecl = FlatTree[ReadNode].ToValueDecl;
- FromAddressOf = FlatTree[ReadNode].FromAddressOf;
- ToAddressOf = FlatTree[ReadNode].ToAddressOf;
+ /// ToDefault - Return true if the to argument is the default.
+ bool ToDefault() {
+ return FlatTree[ReadNode].ToArgInfo.IsDefault;
}
/// NodeIsSame - Returns true the arguments are the same.
@@ -764,26 +874,6 @@ class TemplateDiff {
return FlatTree[ReadNode].NextNode != 0;
}
- /// FromNullPtr - Returns true if the from argument is null.
- bool FromNullPtr() {
- return FlatTree[ReadNode].FromNullPtr;
- }
-
- /// ToNullPtr - Returns true if the to argument is null.
- bool ToNullPtr() {
- return FlatTree[ReadNode].ToNullPtr;
- }
-
- /// FromDefault - Return true if the from argument is the default.
- bool FromDefault() {
- return FlatTree[ReadNode].FromDefault;
- }
-
- /// ToDefault - Return true if the to argument is the default.
- bool ToDefault() {
- return FlatTree[ReadNode].ToDefault;
- }
-
/// Empty - Returns true if the tree has no information.
bool Empty() {
return GetKind() == Invalid;
@@ -797,102 +887,128 @@ class TemplateDiff {
DiffTree Tree;
- /// TSTiterator - an iterator that is used to enter a
- /// TemplateSpecializationType and read TemplateArguments inside template
- /// parameter packs in order with the rest of the TemplateArguments.
- struct TSTiterator {
+ /// TSTiterator - a pair of iterators that walks the
+ /// TemplateSpecializationType and the desugared TemplateSpecializationType.
+ /// The deseguared TemplateArgument should provide the canonical argument
+ /// for comparisons.
+ class TSTiterator {
typedef const TemplateArgument& reference;
typedef const TemplateArgument* pointer;
- /// TST - the template specialization whose arguments this iterator
- /// traverse over.
- const TemplateSpecializationType *TST;
+ /// InternalIterator - an iterator that is used to enter a
+ /// TemplateSpecializationType and read TemplateArguments inside template
+ /// parameter packs in order with the rest of the TemplateArguments.
+ struct InternalIterator {
+ /// TST - the template specialization whose arguments this iterator
+ /// traverse over.
+ const TemplateSpecializationType *TST;
- /// DesugarTST - desugared template specialization used to extract
- /// default argument information
- const TemplateSpecializationType *DesugarTST;
+ /// Index - the index of the template argument in TST.
+ unsigned Index;
- /// Index - the index of the template argument in TST.
- unsigned Index;
+ /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA
+ /// points to a TemplateArgument within a parameter pack.
+ TemplateArgument::pack_iterator CurrentTA;
- /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA
- /// points to a TemplateArgument within a parameter pack.
- TemplateArgument::pack_iterator CurrentTA;
+ /// EndTA - the end iterator of a parameter pack
+ TemplateArgument::pack_iterator EndTA;
- /// EndTA - the end iterator of a parameter pack
- TemplateArgument::pack_iterator EndTA;
+ /// InternalIterator - Constructs an iterator and sets it to the first
+ /// template argument.
+ InternalIterator(const TemplateSpecializationType *TST)
+ : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
+ if (isEnd()) return;
- /// TSTiterator - Constructs an iterator and sets it to the first template
- /// argument.
- TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
- : TST(TST),
- DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())),
- Index(0), CurrentTA(nullptr), EndTA(nullptr) {
- if (isEnd()) return;
+ // Set to first template argument. If not a parameter pack, done.
+ TemplateArgument TA = TST->getArg(0);
+ if (TA.getKind() != TemplateArgument::Pack) return;
- // Set to first template argument. If not a parameter pack, done.
- TemplateArgument TA = TST->getArg(0);
- if (TA.getKind() != TemplateArgument::Pack) return;
+ // Start looking into the parameter pack.
+ CurrentTA = TA.pack_begin();
+ EndTA = TA.pack_end();
- // Start looking into the parameter pack.
- CurrentTA = TA.pack_begin();
- EndTA = TA.pack_end();
+ // Found a valid template argument.
+ if (CurrentTA != EndTA) return;
- // Found a valid template argument.
- if (CurrentTA != EndTA) return;
+ // Parameter pack is empty, use the increment to get to a valid
+ // template argument.
+ ++(*this);
+ }
- // Parameter pack is empty, use the increment to get to a valid
- // template argument.
- ++(*this);
- }
+ /// isEnd - Returns true if the iterator is one past the end.
+ bool isEnd() const {
+ return Index >= TST->getNumArgs();
+ }
- /// isEnd - Returns true if the iterator is one past the end.
- bool isEnd() const {
- return Index >= TST->getNumArgs();
- }
+ /// &operator++ - Increment the iterator to the next template argument.
+ InternalIterator &operator++() {
+ if (isEnd()) {
+ return *this;
+ }
- /// &operator++ - Increment the iterator to the next template argument.
- TSTiterator &operator++() {
- // After the end, Index should be the default argument position in
- // DesugarTST, if it exists.
- if (isEnd()) {
- ++Index;
+ // If in a parameter pack, advance in the parameter pack.
+ if (CurrentTA != EndTA) {
+ ++CurrentTA;
+ if (CurrentTA != EndTA)
+ return *this;
+ }
+
+ // Loop until a template argument is found, or the end is reached.
+ while (true) {
+ // Advance to the next template argument. Break if reached the end.
+ if (++Index == TST->getNumArgs())
+ break;
+
+ // If the TemplateArgument is not a parameter pack, done.
+ TemplateArgument TA = TST->getArg(Index);
+ if (TA.getKind() != TemplateArgument::Pack)
+ break;
+
+ // Handle parameter packs.
+ CurrentTA = TA.pack_begin();
+ EndTA = TA.pack_end();
+
+ // If the parameter pack is empty, try to advance again.
+ if (CurrentTA != EndTA)
+ break;
+ }
return *this;
}
- // If in a parameter pack, advance in the parameter pack.
- if (CurrentTA != EndTA) {
- ++CurrentTA;
- if (CurrentTA != EndTA)
- return *this;
+ /// operator* - Returns the appropriate TemplateArgument.
+ reference operator*() const {
+ assert(!isEnd() && "Index exceeds number of arguments.");
+ if (CurrentTA == EndTA)
+ return TST->getArg(Index);
+ else
+ return *CurrentTA;
}
- // Loop until a template argument is found, or the end is reached.
- while (true) {
- // Advance to the next template argument. Break if reached the end.
- if (++Index == TST->getNumArgs()) break;
+ /// operator-> - Allow access to the underlying TemplateArgument.
+ pointer operator->() const {
+ return &operator*();
+ }
+ };
- // If the TemplateArgument is not a parameter pack, done.
- TemplateArgument TA = TST->getArg(Index);
- if (TA.getKind() != TemplateArgument::Pack) break;
+ InternalIterator SugaredIterator;
+ InternalIterator DesugaredIterator;
- // Handle parameter packs.
- CurrentTA = TA.pack_begin();
- EndTA = TA.pack_end();
+ public:
+ TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
+ : SugaredIterator(TST),
+ DesugaredIterator(
+ GetTemplateSpecializationType(Context, TST->desugar())) {}
- // If the parameter pack is empty, try to advance again.
- if (CurrentTA != EndTA) break;
- }
+ /// &operator++ - Increment the iterator to the next template argument.
+ TSTiterator &operator++() {
+ ++SugaredIterator;
+ ++DesugaredIterator;
return *this;
}
/// operator* - Returns the appropriate TemplateArgument.
reference operator*() const {
- assert(!isEnd() && "Index exceeds number of arguments.");
- if (CurrentTA == EndTA)
- return TST->getArg(Index);
- else
- return *CurrentTA;
+ return *SugaredIterator;
}
/// operator-> - Allow access to the underlying TemplateArgument.
@@ -900,16 +1016,27 @@ class TemplateDiff {
return &operator*();
}
- /// getDesugar - Returns the deduced template argument from DesguarTST
- reference getDesugar() const {
- return DesugarTST->getArg(Index);
+ /// isEnd - Returns true if no more TemplateArguments are available.
+ bool isEnd() const {
+ return SugaredIterator.isEnd();
+ }
+
+ /// hasDesugaredTA - Returns true if there is another TemplateArgument
+ /// available.
+ bool hasDesugaredTA() const {
+ return !DesugaredIterator.isEnd();
+ }
+
+ /// getDesugaredTA - Returns the desugared TemplateArgument.
+ reference getDesugaredTA() const {
+ return *DesugaredIterator;
}
};
// These functions build up the template diff tree, including functions to
- // retrieve and compare template arguments.
+ // retrieve and compare template arguments.
- static const TemplateSpecializationType * GetTemplateSpecializationType(
+ static const TemplateSpecializationType *GetTemplateSpecializationType(
ASTContext &Context, QualType Ty) {
if (const TemplateSpecializationType *TST =
Ty->getAs<TemplateSpecializationType>())
@@ -935,108 +1062,136 @@ class TemplateDiff {
return Ty->getAs<TemplateSpecializationType>();
}
- /// DiffTypes - Fills a DiffNode with information about a type difference.
- void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter,
- TemplateTypeParmDecl *FromDefaultTypeDecl,
- TemplateTypeParmDecl *ToDefaultTypeDecl) {
- QualType FromType = GetType(FromIter, FromDefaultTypeDecl);
- QualType ToType = GetType(ToIter, ToDefaultTypeDecl);
-
- Tree.SetNode(FromType, ToType);
- Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(),
- ToIter.isEnd() && !ToType.isNull());
- Tree.SetKind(DiffTree::Type);
+ /// Returns true if the DiffType is Type and false for Template.
+ static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,
+ QualType ToType,
+ const TemplateSpecializationType *&FromArgTST,
+ const TemplateSpecializationType *&ToArgTST) {
if (FromType.isNull() || ToType.isNull())
- return;
+ return true;
- if (Context.hasSameType(FromType, ToType)) {
- Tree.SetSame(true);
- return;
- }
+ if (Context.hasSameType(FromType, ToType))
+ return true;
- const TemplateSpecializationType *FromArgTST =
- GetTemplateSpecializationType(Context, FromType);
- if (!FromArgTST)
- return;
+ FromArgTST = GetTemplateSpecializationType(Context, FromType);
+ ToArgTST = GetTemplateSpecializationType(Context, ToType);
- const TemplateSpecializationType *ToArgTST =
- GetTemplateSpecializationType(Context, ToType);
- if (!ToArgTST)
- return;
+ if (!FromArgTST || !ToArgTST)
+ return true;
if (!hasSameTemplate(FromArgTST, ToArgTST))
- return;
+ return true;
- Qualifiers FromQual = FromType.getQualifiers(),
- ToQual = ToType.getQualifiers();
- FromQual -= QualType(FromArgTST, 0).getQualifiers();
- ToQual -= QualType(ToArgTST, 0).getQualifiers();
- Tree.SetNode(FromArgTST->getTemplateName().getAsTemplateDecl(),
- ToArgTST->getTemplateName().getAsTemplateDecl());
- Tree.SetNode(FromQual, ToQual);
- Tree.SetKind(DiffTree::Template);
- DiffTemplate(FromArgTST, ToArgTST);
+ return false;
+ }
+
+ /// DiffTypes - Fills a DiffNode with information about a type difference.
+ void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) {
+ QualType FromType = GetType(FromIter);
+ QualType ToType = GetType(ToIter);
+
+ bool FromDefault = FromIter.isEnd() && !FromType.isNull();
+ bool ToDefault = ToIter.isEnd() && !ToType.isNull();
+
+ const TemplateSpecializationType *FromArgTST = nullptr;
+ const TemplateSpecializationType *ToArgTST = nullptr;
+ if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
+ Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
+ Tree.SetSame(!FromType.isNull() && !ToType.isNull() &&
+ Context.hasSameType(FromType, ToType));
+ } else {
+ assert(FromArgTST && ToArgTST &&
+ "Both template specializations need to be valid.");
+ Qualifiers FromQual = FromType.getQualifiers(),
+ ToQual = ToType.getQualifiers();
+ FromQual -= QualType(FromArgTST, 0).getQualifiers();
+ ToQual -= QualType(ToArgTST, 0).getQualifiers();
+ Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),
+ ToArgTST->getTemplateName().getAsTemplateDecl(),
+ FromQual, ToQual, FromDefault, ToDefault);
+ DiffTemplate(FromArgTST, ToArgTST);
+ }
}
/// DiffTemplateTemplates - Fills a DiffNode with information about a
/// template template difference.
void DiffTemplateTemplates(const TSTiterator &FromIter,
- const TSTiterator &ToIter,
- TemplateTemplateParmDecl *FromDefaultTemplateDecl,
- TemplateTemplateParmDecl *ToDefaultTemplateDecl) {
- TemplateDecl *FromDecl = GetTemplateDecl(FromIter, FromDefaultTemplateDecl);
- TemplateDecl *ToDecl = GetTemplateDecl(ToIter, ToDefaultTemplateDecl);
- Tree.SetNode(FromDecl, ToDecl);
+ const TSTiterator &ToIter) {
+ TemplateDecl *FromDecl = GetTemplateDecl(FromIter);
+ TemplateDecl *ToDecl = GetTemplateDecl(ToIter);
+ Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,
+ ToIter.isEnd() && ToDecl);
Tree.SetSame(FromDecl && ToDecl &&
FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());
- Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl);
- Tree.SetKind(DiffTree::TemplateTemplate);
}
/// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes
- static void InitializeNonTypeDiffVariables(
- ASTContext &Context, const TSTiterator &Iter,
- NonTypeTemplateParmDecl *Default, bool &HasInt, bool &HasValueDecl,
- bool &IsNullPtr, Expr *&E, llvm::APSInt &Value, ValueDecl *&VD) {
- HasInt = !Iter.isEnd() && Iter->getKind() == TemplateArgument::Integral;
-
- HasValueDecl =
- !Iter.isEnd() && Iter->getKind() == TemplateArgument::Declaration;
-
- IsNullPtr = !Iter.isEnd() && Iter->getKind() == TemplateArgument::NullPtr;
-
- if (HasInt)
- Value = Iter->getAsIntegral();
- else if (HasValueDecl)
- VD = Iter->getAsDecl();
- else if (!IsNullPtr)
- E = GetExpr(Iter, Default);
-
- if (E && Default->getType()->isPointerType())
- IsNullPtr = CheckForNullPtr(Context, E);
- }
-
- /// NeedsAddressOf - Helper function for DiffNonTypes. Returns true if the
- /// ValueDecl needs a '&' when printed.
- static bool NeedsAddressOf(ValueDecl *VD, Expr *E,
- NonTypeTemplateParmDecl *Default) {
- if (!VD)
- return false;
-
- if (E) {
- if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParens())) {
- if (UO->getOpcode() == UO_AddrOf) {
- return true;
+ static void InitializeNonTypeDiffVariables(ASTContext &Context,
+ const TSTiterator &Iter,
+ NonTypeTemplateParmDecl *Default,
+ llvm::APSInt &Value, bool &HasInt,
+ QualType &IntType, bool &IsNullPtr,
+ Expr *&E, ValueDecl *&VD,
+ bool &NeedAddressOf) {
+ if (!Iter.isEnd()) {
+ switch (Iter->getKind()) {
+ default:
+ llvm_unreachable("unknown ArgumentKind");
+ case TemplateArgument::Integral:
+ Value = Iter->getAsIntegral();
+ HasInt = true;
+ IntType = Iter->getIntegralType();
+ return;
+ case TemplateArgument::Declaration: {
+ VD = Iter->getAsDecl();
+ QualType ArgType = Iter->getParamTypeForDecl();
+ QualType VDType = VD->getType();
+ if (ArgType->isPointerType() &&
+ Context.hasSameType(ArgType->getPointeeType(), VDType))
+ NeedAddressOf = true;
+ return;
}
+ case TemplateArgument::NullPtr:
+ IsNullPtr = true;
+ return;
+ case TemplateArgument::Expression:
+ E = Iter->getAsExpr();
}
- return false;
+ } else if (!Default->isParameterPack()) {
+ E = Default->getDefaultArgument();
}
- if (!Default->getType()->isReferenceType()) {
- return true;
- }
+ if (!Iter.hasDesugaredTA()) return;
- return false;
+ const TemplateArgument& TA = Iter.getDesugaredTA();
+ switch (TA.getKind()) {
+ default:
+ llvm_unreachable("unknown ArgumentKind");
+ case TemplateArgument::Integral:
+ Value = TA.getAsIntegral();
+ HasInt = true;
+ IntType = TA.getIntegralType();
+ return;
+ case TemplateArgument::Declaration: {
+ VD = TA.getAsDecl();
+ QualType ArgType = TA.getParamTypeForDecl();
+ QualType VDType = VD->getType();
+ if (ArgType->isPointerType() &&
+ Context.hasSameType(ArgType->getPointeeType(), VDType))
+ NeedAddressOf = true;
+ return;
+ }
+ case TemplateArgument::NullPtr:
+ IsNullPtr = true;
+ return;
+ case TemplateArgument::Expression:
+ // TODO: Sometimes, the desugared template argument Expr differs from
+ // the sugared template argument Expr. It may be useful in the future
+ // but for now, it is just discarded.
+ if (!E)
+ E = TA.getAsExpr();
+ return;
+ }
}
/// DiffNonTypes - Handles any template parameters not handled by DiffTypes
@@ -1046,85 +1201,68 @@ class TemplateDiff {
NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) {
Expr *FromExpr = nullptr, *ToExpr = nullptr;
llvm::APSInt FromInt, ToInt;
+ QualType FromIntType, ToIntType;
ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;
- bool HasFromInt = false, HasToInt = false, HasFromValueDecl = false,
- HasToValueDecl = false, FromNullPtr = false, ToNullPtr = false;
- InitializeNonTypeDiffVariables(Context, FromIter, FromDefaultNonTypeDecl,
- HasFromInt, HasFromValueDecl, FromNullPtr,
- FromExpr, FromInt, FromValueDecl);
- InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl,
- HasToInt, HasToValueDecl, ToNullPtr,
- ToExpr, ToInt, ToValueDecl);
-
- assert(((!HasFromInt && !HasToInt) ||
- (!HasFromValueDecl && !HasToValueDecl)) &&
- "Template argument cannot be both integer and declaration");
-
- if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
- Tree.SetNode(FromExpr, ToExpr);
- Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr);
- if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) {
- if (FromExpr)
- HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt,
- FromDefaultNonTypeDecl->getType());
- if (ToExpr)
- HasToInt = GetInt(Context, ToIter, ToExpr, ToInt,
- ToDefaultNonTypeDecl->getType());
- }
- if (HasFromInt && HasToInt) {
- Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
- Tree.SetSame(FromInt == ToInt);
- Tree.SetKind(DiffTree::Integer);
- } else if (HasFromInt || HasToInt) {
- Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
- Tree.SetSame(false);
- Tree.SetKind(DiffTree::Integer);
- } else {
- Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr) ||
- (FromNullPtr && ToNullPtr));
- Tree.SetNullPtr(FromNullPtr, ToNullPtr);
- Tree.SetKind(DiffTree::Expression);
- }
+ bool HasFromInt = false, HasToInt = false, FromNullPtr = false,
+ ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false;
+ InitializeNonTypeDiffVariables(
+ Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
+ FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
+ InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
+ HasToInt, ToIntType, ToNullPtr, ToExpr,
+ ToValueDecl, NeedToAddressOf);
+
+ bool FromDefault = FromIter.isEnd() &&
+ (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
+ bool ToDefault = ToIter.isEnd() &&
+ (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
+
+ bool FromDeclaration = FromValueDecl || FromNullPtr;
+ bool ToDeclaration = ToValueDecl || ToNullPtr;
+
+ if (FromDeclaration && HasToInt) {
+ Tree.SetFromDeclarationAndToIntegerDiff(
+ FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
+ HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
+ Tree.SetSame(false);
+ return;
+
+ }
+
+ if (HasFromInt && ToDeclaration) {
+ Tree.SetFromIntegerAndToDeclarationDiff(
+ FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
+ NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
+ Tree.SetSame(false);
return;
}
if (HasFromInt || HasToInt) {
- if (!HasFromInt && FromExpr)
- HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt,
- FromDefaultNonTypeDecl->getType());
- if (!HasToInt && ToExpr)
- HasToInt = GetInt(Context, ToIter, ToExpr, ToInt,
- ToDefaultNonTypeDecl->getType());
- Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+ Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
+ ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
if (HasFromInt && HasToInt) {
- Tree.SetSame(FromInt == ToInt);
- } else {
- Tree.SetSame(false);
+ Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) &&
+ FromInt == ToInt);
}
- Tree.SetDefault(FromIter.isEnd() && HasFromInt,
- ToIter.isEnd() && HasToInt);
- Tree.SetKind(DiffTree::Integer);
return;
}
- if (!HasFromValueDecl && FromExpr)
- FromValueDecl = GetValueDecl(FromIter, FromExpr);
- if (!HasToValueDecl && ToExpr)
- ToValueDecl = GetValueDecl(ToIter, ToExpr);
-
- bool FromAddressOf =
- NeedsAddressOf(FromValueDecl, FromExpr, FromDefaultNonTypeDecl);
- bool ToAddressOf =
- NeedsAddressOf(ToValueDecl, ToExpr, ToDefaultNonTypeDecl);
-
- Tree.SetNullPtr(FromNullPtr, ToNullPtr);
- Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
- Tree.SetSame(FromValueDecl && ToValueDecl &&
- FromValueDecl->getCanonicalDecl() ==
- ToValueDecl->getCanonicalDecl());
- Tree.SetDefault(FromIter.isEnd() && FromValueDecl,
- ToIter.isEnd() && ToValueDecl);
- Tree.SetKind(DiffTree::Declaration);
+ if (FromDeclaration || ToDeclaration) {
+ Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
+ NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
+ ToExpr, FromDefault, ToDefault);
+ bool BothNull = FromNullPtr && ToNullPtr;
+ bool SameValueDecl =
+ FromValueDecl && ToValueDecl &&
+ NeedFromAddressOf == NeedToAddressOf &&
+ FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl();
+ Tree.SetSame(BothNull || SameValueDecl);
+ return;
+ }
+
+ assert((FromExpr || ToExpr) && "Both template arguments cannot be empty.");
+ Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
+ Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
}
/// DiffTemplate - recursively visits template arguments and stores the
@@ -1149,28 +1287,23 @@ class TemplateDiff {
NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex);
NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex);
- TemplateTypeParmDecl *FromDefaultTypeDecl =
- dyn_cast<TemplateTypeParmDecl>(FromParamND);
- TemplateTypeParmDecl *ToDefaultTypeDecl =
- dyn_cast<TemplateTypeParmDecl>(ToParamND);
- if (FromDefaultTypeDecl && ToDefaultTypeDecl)
- DiffTypes(FromIter, ToIter, FromDefaultTypeDecl, ToDefaultTypeDecl);
-
- TemplateTemplateParmDecl *FromDefaultTemplateDecl =
- dyn_cast<TemplateTemplateParmDecl>(FromParamND);
- TemplateTemplateParmDecl *ToDefaultTemplateDecl =
- dyn_cast<TemplateTemplateParmDecl>(ToParamND);
- if (FromDefaultTemplateDecl && ToDefaultTemplateDecl)
- DiffTemplateTemplates(FromIter, ToIter, FromDefaultTemplateDecl,
- ToDefaultTemplateDecl);
-
- NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
- dyn_cast<NonTypeTemplateParmDecl>(FromParamND);
- NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
- dyn_cast<NonTypeTemplateParmDecl>(ToParamND);
- if (FromDefaultNonTypeDecl && ToDefaultNonTypeDecl)
+ assert(FromParamND->getKind() == ToParamND->getKind() &&
+ "Parameter Decl are not the same kind.");
+
+ if (isa<TemplateTypeParmDecl>(FromParamND)) {
+ DiffTypes(FromIter, ToIter);
+ } else if (isa<TemplateTemplateParmDecl>(FromParamND)) {
+ DiffTemplateTemplates(FromIter, ToIter);
+ } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) {
+ NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
+ cast<NonTypeTemplateParmDecl>(FromParamND);
+ NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
+ cast<NonTypeTemplateParmDecl>(ToParamND);
DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
ToDefaultNonTypeDecl);
+ } else {
+ llvm_unreachable("Unexpected Decl type.");
+ }
++FromIter;
++ToIter;
@@ -1239,140 +1372,27 @@ class TemplateDiff {
/// GetType - Retrieves the template type arguments, including default
/// arguments.
- static QualType GetType(const TSTiterator &Iter,
- TemplateTypeParmDecl *DefaultTTPD) {
- bool isVariadic = DefaultTTPD->isParameterPack();
-
+ static QualType GetType(const TSTiterator &Iter) {
if (!Iter.isEnd())
return Iter->getAsType();
- if (isVariadic)
- return QualType();
-
- QualType ArgType = DefaultTTPD->getDefaultArgument();
- if (ArgType->isDependentType())
- return Iter.getDesugar().getAsType();
-
- return ArgType;
- }
-
- /// GetExpr - Retrieves the template expression argument, including default
- /// arguments.
- static Expr *GetExpr(const TSTiterator &Iter,
- NonTypeTemplateParmDecl *DefaultNTTPD) {
- Expr *ArgExpr = nullptr;
- bool isVariadic = DefaultNTTPD->isParameterPack();
-
- if (!Iter.isEnd())
- ArgExpr = Iter->getAsExpr();
- else if (!isVariadic)
- ArgExpr = DefaultNTTPD->getDefaultArgument();
-
- if (ArgExpr)
- while (SubstNonTypeTemplateParmExpr *SNTTPE =
- dyn_cast<SubstNonTypeTemplateParmExpr>(ArgExpr))
- ArgExpr = SNTTPE->getReplacement();
-
- return ArgExpr;
- }
-
- /// GetInt - Retrieves the template integer argument, including evaluating
- /// default arguments. If the value comes from an expression, extend the
- /// APSInt to size of IntegerType to match the behavior in
- /// Sema::CheckTemplateArgument
- static bool GetInt(ASTContext &Context, const TSTiterator &Iter,
- Expr *ArgExpr, llvm::APSInt &Int, QualType IntegerType) {
- // Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument, otherwise expression needs to
- // be evaluatable.
- if (Iter.isEnd() && ArgExpr->isValueDependent()) {
- switch (Iter.getDesugar().getKind()) {
- case TemplateArgument::Integral:
- Int = Iter.getDesugar().getAsIntegral();
- return true;
- case TemplateArgument::Expression:
- ArgExpr = Iter.getDesugar().getAsExpr();
- Int = ArgExpr->EvaluateKnownConstInt(Context);
- Int = Int.extOrTrunc(Context.getTypeSize(IntegerType));
- return true;
- default:
- llvm_unreachable("Unexpected template argument kind");
- }
- } else if (ArgExpr->isEvaluatable(Context)) {
- Int = ArgExpr->EvaluateKnownConstInt(Context);
- Int = Int.extOrTrunc(Context.getTypeSize(IntegerType));
- return true;
- }
-
- return false;
- }
-
- /// GetValueDecl - Retrieves the template Decl argument, including
- /// default expression argument.
- static ValueDecl *GetValueDecl(const TSTiterator &Iter, Expr *ArgExpr) {
- // Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument
- if (Iter.isEnd() && ArgExpr->isValueDependent())
- switch (Iter.getDesugar().getKind()) {
- case TemplateArgument::Declaration:
- return Iter.getDesugar().getAsDecl();
- case TemplateArgument::Expression:
- ArgExpr = Iter.getDesugar().getAsExpr();
- return cast<DeclRefExpr>(ArgExpr)->getDecl();
- default:
- llvm_unreachable("Unexpected template argument kind");
- }
- DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
- if (!DRE) {
- UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens());
- if (!UO)
- return nullptr;
- DRE = cast<DeclRefExpr>(UO->getSubExpr());
- }
-
- return DRE->getDecl();
- }
-
- /// CheckForNullPtr - returns true if the expression can be evaluated as
- /// a null pointer
- static bool CheckForNullPtr(ASTContext &Context, Expr *E) {
- assert(E && "Expected expression");
-
- E = E->IgnoreParenCasts();
- if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
- return true;
-
- DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
- if (!DRE)
- return false;
-
- VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
- if (!VD || !VD->hasInit())
- return false;
-
- return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant(
- Context, Expr::NPC_ValueDependentIsNull);
+ if (Iter.hasDesugaredTA())
+ return Iter.getDesugaredTA().getAsType();
+ return QualType();
}
/// GetTemplateDecl - Retrieves the template template arguments, including
/// default arguments.
- static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter,
- TemplateTemplateParmDecl *DefaultTTPD) {
- bool isVariadic = DefaultTTPD->isParameterPack();
-
- TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument();
- TemplateDecl *DefaultTD = nullptr;
- if (TA.getKind() != TemplateArgument::Null)
- DefaultTD = TA.getAsTemplate().getAsTemplateDecl();
-
+ static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) {
if (!Iter.isEnd())
return Iter->getAsTemplate().getAsTemplateDecl();
- if (!isVariadic)
- return DefaultTD;
-
+ if (Iter.hasDesugaredTA())
+ return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
return nullptr;
}
- /// IsEqualExpr - Returns true if the expressions evaluate to the same value.
+ /// IsEqualExpr - Returns true if the expressions are the same in regards to
+ /// template arguments. These expressions are dependent, so profile them
+ /// instead of trying to evaluate them.
static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {
if (FromExpr == ToExpr)
return true;
@@ -1380,47 +1400,10 @@ class TemplateDiff {
if (!FromExpr || !ToExpr)
return false;
- DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()),
- *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->IgnoreParens());
-
- if (FromDRE || ToDRE) {
- if (!FromDRE || !ToDRE)
- return false;
- return FromDRE->getDecl() == ToDRE->getDecl();
- }
-
- Expr::EvalResult FromResult, ToResult;
- if (!FromExpr->EvaluateAsRValue(FromResult, Context) ||
- !ToExpr->EvaluateAsRValue(ToResult, Context)) {
- llvm::FoldingSetNodeID FromID, ToID;
- FromExpr->Profile(FromID, Context, true);
- ToExpr->Profile(ToID, Context, true);
- return FromID == ToID;
- }
-
- APValue &FromVal = FromResult.Val;
- APValue &ToVal = ToResult.Val;
-
- if (FromVal.getKind() != ToVal.getKind()) return false;
-
- switch (FromVal.getKind()) {
- case APValue::Int:
- return FromVal.getInt() == ToVal.getInt();
- case APValue::LValue: {
- APValue::LValueBase FromBase = FromVal.getLValueBase();
- APValue::LValueBase ToBase = ToVal.getLValueBase();
- if (FromBase.isNull() && ToBase.isNull())
- return true;
- if (FromBase.isNull() || ToBase.isNull())
- return false;
- return FromBase.get<const ValueDecl*>() ==
- ToBase.get<const ValueDecl*>();
- }
- case APValue::MemberPointer:
- return FromVal.getMemberPointerDecl() == ToVal.getMemberPointerDecl();
- default:
- llvm_unreachable("Unknown template argument expression.");
- }
+ llvm::FoldingSetNodeID FromID, ToID;
+ FromExpr->Profile(FromID, Context, true);
+ ToExpr->Profile(ToID, Context, true);
+ return FromID == ToID;
}
// These functions converts the tree representation of the template
@@ -1442,21 +1425,21 @@ class TemplateDiff {
llvm_unreachable("Template diffing failed with bad DiffNode");
case DiffTree::Type: {
QualType FromType, ToType;
- Tree.GetNode(FromType, ToType);
+ Tree.GetTypeDiff(FromType, ToType);
PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),
Tree.NodeIsSame());
return;
}
case DiffTree::Expression: {
Expr *FromExpr, *ToExpr;
- Tree.GetNode(FromExpr, ToExpr);
- PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),
- Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+ Tree.GetExpressionDiff(FromExpr, ToExpr);
+ PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
+ Tree.NodeIsSame());
return;
}
case DiffTree::TemplateTemplate: {
TemplateDecl *FromTD, *ToTD;
- Tree.GetNode(FromTD, ToTD);
+ Tree.GetTemplateTemplateDiff(FromTD, ToTD);
PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),
Tree.ToDefault(), Tree.NodeIsSame());
return;
@@ -1465,26 +1448,70 @@ class TemplateDiff {
llvm::APSInt FromInt, ToInt;
Expr *FromExpr, *ToExpr;
bool IsValidFromInt, IsValidToInt;
- Tree.GetNode(FromExpr, ToExpr);
- Tree.GetNode(FromInt, ToInt, IsValidFromInt, IsValidToInt);
- PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt,
- FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
- Tree.NodeIsSame());
+ QualType FromIntType, ToIntType;
+ Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
+ FromIntType, ToIntType, FromExpr, ToExpr);
+ PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
+ ToIntType, FromExpr, ToExpr, Tree.FromDefault(),
+ Tree.ToDefault(), Tree.NodeIsSame());
return;
}
case DiffTree::Declaration: {
ValueDecl *FromValueDecl, *ToValueDecl;
bool FromAddressOf, ToAddressOf;
- Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
+ bool FromNullPtr, ToNullPtr;
+ Expr *FromExpr, *ToExpr;
+ Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
+ ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
+ ToExpr);
PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
- Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),
- Tree.ToDefault(), Tree.NodeIsSame());
+ FromNullPtr, ToNullPtr, FromExpr, ToExpr,
+ Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+ return;
+ }
+ case DiffTree::FromDeclarationAndToInteger: {
+ ValueDecl *FromValueDecl;
+ bool FromAddressOf;
+ bool FromNullPtr;
+ Expr *FromExpr;
+ llvm::APSInt ToInt;
+ bool IsValidToInt;
+ QualType ToIntType;
+ Expr *ToExpr;
+ Tree.GetFromDeclarationAndToIntegerDiff(
+ FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
+ IsValidToInt, ToIntType, ToExpr);
+ assert((FromValueDecl || FromNullPtr) && IsValidToInt);
+ PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
+ FromExpr, Tree.FromDefault(), ToInt, ToIntType,
+ ToExpr, Tree.ToDefault());
+ return;
+ }
+ case DiffTree::FromIntegerAndToDeclaration: {
+ llvm::APSInt FromInt;
+ bool IsValidFromInt;
+ QualType FromIntType;
+ Expr *FromExpr;
+ ValueDecl *ToValueDecl;
+ bool ToAddressOf;
+ bool ToNullPtr;
+ Expr *ToExpr;
+ Tree.GetFromIntegerAndToDeclarationDiff(
+ FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
+ ToAddressOf, ToNullPtr, ToExpr);
+ assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
+ PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
+ Tree.FromDefault(), ToValueDecl, ToAddressOf,
+ ToNullPtr, ToExpr, Tree.ToDefault());
return;
}
case DiffTree::Template: {
// Node is root of template. Recurse on children.
TemplateDecl *FromTD, *ToTD;
- Tree.GetNode(FromTD, ToTD);
+ Qualifiers FromQual, ToQual;
+ Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
+
+ PrintQualifiers(FromQual, ToQual);
if (!Tree.HasChildren()) {
// If we're dealing with a template specialization with zero
@@ -1493,11 +1520,7 @@ class TemplateDiff {
return;
}
- Qualifiers FromQual, ToQual;
- Tree.GetNode(FromQual, ToQual);
- PrintQualifiers(FromQual, ToQual);
-
- OS << FromTD->getNameAsString() << '<';
+ OS << FromTD->getNameAsString() << '<';
Tree.MoveToChild();
unsigned NumElideArgs = 0;
do {
@@ -1604,40 +1627,36 @@ class TemplateDiff {
/// PrintExpr - Prints out the expr template arguments, highlighting argument
/// differences.
- void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr,
- bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) {
+ void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault,
+ bool ToDefault, bool Same) {
assert((FromExpr || ToExpr) &&
"Only one template argument may be missing.");
if (Same) {
- PrintExpr(FromExpr, FromNullPtr);
+ PrintExpr(FromExpr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- PrintExpr(FromExpr, FromNullPtr);
+ PrintExpr(FromExpr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- PrintExpr(FromExpr, FromNullPtr);
+ PrintExpr(FromExpr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- PrintExpr(ToExpr, ToNullPtr);
+ PrintExpr(ToExpr);
Unbold();
OS << ']';
}
}
/// PrintExpr - Actual formatting and printing of expressions.
- void PrintExpr(const Expr *E, bool NullPtr = false) {
+ void PrintExpr(const Expr *E) {
if (E) {
E->printPretty(OS, nullptr, Policy);
return;
}
- if (NullPtr) {
- OS << "nullptr";
- return;
- }
OS << "(no argument)";
}
@@ -1677,28 +1696,40 @@ class TemplateDiff {
/// PrintAPSInt - Handles printing of integral arguments, highlighting
/// argument differences.
void PrintAPSInt(llvm::APSInt FromInt, llvm::APSInt ToInt,
- bool IsValidFromInt, bool IsValidToInt, Expr *FromExpr,
- Expr *ToExpr, bool FromDefault, bool ToDefault, bool Same) {
+ bool IsValidFromInt, bool IsValidToInt, QualType FromIntType,
+ QualType ToIntType, Expr *FromExpr, Expr *ToExpr,
+ bool FromDefault, bool ToDefault, bool Same) {
assert((IsValidFromInt || IsValidToInt) &&
"Only one integral argument may be missing.");
if (Same) {
- OS << FromInt.toString(10);
- } else if (!PrintTree) {
+ if (FromIntType->isBooleanType()) {
+ OS << ((FromInt == 0) ? "false" : "true");
+ } else {
+ OS << FromInt.toString(10);
+ }
+ return;
+ }
+
+ bool PrintType = IsValidFromInt && IsValidToInt &&
+ !Context.hasSameType(FromIntType, ToIntType);
+
+ if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
- PrintAPSInt(FromInt, FromExpr, IsValidFromInt);
+ PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
} else {
OS << (FromDefault ? "[(default) " : "[");
- PrintAPSInt(FromInt, FromExpr, IsValidFromInt);
+ PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
OS << " != " << (ToDefault ? "(default) " : "");
- PrintAPSInt(ToInt, ToExpr, IsValidToInt);
+ PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
OS << ']';
}
}
/// PrintAPSInt - If valid, print the APSInt. If the expression is
/// gives more information, print it too.
- void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid) {
+ void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid, QualType IntType,
+ bool PrintType) {
Bold();
if (Valid) {
if (HasExtraInfo(E)) {
@@ -1707,7 +1738,20 @@ class TemplateDiff {
OS << " aka ";
Bold();
}
- OS << Val.toString(10);
+ if (PrintType) {
+ Unbold();
+ OS << "(";
+ Bold();
+ IntType.print(OS, Context.getPrintingPolicy());
+ Unbold();
+ OS << ") ";
+ Bold();
+ }
+ if (IntType->isBooleanType()) {
+ OS << ((Val == 0) ? "false" : "true");
+ } else {
+ OS << Val.toString(10);
+ }
} else if (E) {
PrintExpr(E);
} else {
@@ -1716,8 +1760,8 @@ class TemplateDiff {
Unbold();
}
- /// HasExtraInfo - Returns true if E is not an integer literal or the
- /// negation of an integer literal
+ /// HasExtraInfo - Returns true if E is not an integer literal, the
+ /// negation of an integer literal, or a boolean literal.
bool HasExtraInfo(Expr *E) {
if (!E) return false;
@@ -1730,10 +1774,13 @@ class TemplateDiff {
if (isa<IntegerLiteral>(UO->getSubExpr()))
return false;
+ if (isa<CXXBoolLiteralExpr>(E))
+ return false;
+
return true;
}
- void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) {
+ void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) {
if (VD) {
if (AddressOf)
OS << "&";
@@ -1742,6 +1789,17 @@ class TemplateDiff {
}
if (NullPtr) {
+ if (E && !isa<CXXNullPtrLiteralExpr>(E)) {
+ PrintExpr(E);
+ if (IsBold) {
+ Unbold();
+ OS << " aka ";
+ Bold();
+ } else {
+ OS << " aka ";
+ }
+ }
+
OS << "nullptr";
return;
}
@@ -1753,30 +1811,72 @@ class TemplateDiff {
/// argument differences.
void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
- bool ToNullPtr, bool FromDefault, bool ToDefault,
- bool Same) {
+ bool ToNullPtr, Expr *FromExpr, Expr *ToExpr,
+ bool FromDefault, bool ToDefault, bool Same) {
assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
"Only one Decl argument may be NULL");
if (Same) {
- PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr);
+ PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
+ Unbold();
+ OS << ']';
+ }
+
+ }
+
+ /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and
+ /// APSInt to print a mixed difference.
+ void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf,
+ bool IsNullPtr, Expr *VDExpr, bool DefaultDecl,
+ llvm::APSInt Val, QualType IntType,
+ Expr *IntExpr, bool DefaultInt) {
+ if (!PrintTree) {
+ OS << (DefaultDecl ? "(default) " : "");
+ Bold();
+ PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
Unbold();
+ } else {
+ OS << (DefaultDecl ? "[(default) " : "[");
+ Bold();
+ PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
+ Unbold();
+ OS << " != " << (DefaultInt ? "(default) " : "");
+ PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
OS << ']';
}
+ }
+ /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and
+ /// ValueDecl to print a mixed difference.
+ void PrintIntegerAndValueDecl(llvm::APSInt Val, QualType IntType,
+ Expr *IntExpr, bool DefaultInt, ValueDecl *VD,
+ bool NeedAddressOf, bool IsNullPtr,
+ Expr *VDExpr, bool DefaultDecl) {
+ if (!PrintTree) {
+ OS << (DefaultInt ? "(default) " : "");
+ PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
+ } else {
+ OS << (DefaultInt ? "[(default) " : "[");
+ PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
+ OS << " != " << (DefaultDecl ? "(default) " : "");
+ Bold();
+ PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
+ Unbold();
+ OS << ']';
+ }
}
// Prints the appropriate placeholder for elided template arguments.
@@ -1866,21 +1966,21 @@ public:
PrintTree(PrintTree),
ShowColor(ShowColor),
// When printing a single type, the FromType is the one printed.
- FromType(PrintFromType ? FromType : ToType),
- ToType(PrintFromType ? ToType : FromType),
+ FromTemplateType(PrintFromType ? FromType : ToType),
+ ToTemplateType(PrintFromType ? ToType : FromType),
OS(OS),
IsBold(false) {
}
/// DiffTemplate - Start the template type diffing.
void DiffTemplate() {
- Qualifiers FromQual = FromType.getQualifiers(),
- ToQual = ToType.getQualifiers();
+ Qualifiers FromQual = FromTemplateType.getQualifiers(),
+ ToQual = ToTemplateType.getQualifiers();
const TemplateSpecializationType *FromOrigTST =
- GetTemplateSpecializationType(Context, FromType);
+ GetTemplateSpecializationType(Context, FromTemplateType);
const TemplateSpecializationType *ToOrigTST =
- GetTemplateSpecializationType(Context, ToType);
+ GetTemplateSpecializationType(Context, ToTemplateType);
// Only checking templates.
if (!FromOrigTST || !ToOrigTST)
@@ -1893,13 +1993,12 @@ public:
FromQual -= QualType(FromOrigTST, 0).getQualifiers();
ToQual -= QualType(ToOrigTST, 0).getQualifiers();
- Tree.SetNode(FromType, ToType);
- Tree.SetNode(FromQual, ToQual);
- Tree.SetKind(DiffTree::Template);
// Same base template, but different arguments.
- Tree.SetNode(FromOrigTST->getTemplateName().getAsTemplateDecl(),
- ToOrigTST->getTemplateName().getAsTemplateDecl());
+ Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(),
+ ToOrigTST->getTemplateName().getAsTemplateDecl(),
+ FromQual, ToQual, false /*FromDefault*/,
+ false /*ToDefault*/);
DiffTemplate(FromOrigTST, ToOrigTST);
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 1bc6c51..4f0b124 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -6151,6 +6151,12 @@ public:
Builder.defineMacro("__s390x__");
Builder.defineMacro("__zarch__");
Builder.defineMacro("__LONG_DOUBLE_128__");
+
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+
if (HasTransactionalExecution)
Builder.defineMacro("__HTM__");
if (Opts.ZVector)
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/Address.h b/contrib/llvm/tools/clang/lib/CodeGen/Address.h
index 9d145fa..3343080 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/Address.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/Address.h
@@ -104,23 +104,15 @@ public:
};
}
-}
-namespace llvm {
- // Present a minimal LLVM-like casting interface.
- template <class U> inline U cast(clang::CodeGen::Address addr) {
- return U::castImpl(addr);
- }
- template <class U> inline bool isa(clang::CodeGen::Address addr) {
- return U::isaImpl(addr);
- }
+// Present a minimal LLVM-like casting interface.
+template <class U> inline U cast(CodeGen::Address addr) {
+ return U::castImpl(addr);
+}
+template <class U> inline bool isa(CodeGen::Address addr) {
+ return U::isaImpl(addr);
}
-namespace clang {
- // Make our custom isa and cast available in namespace clang, to mirror
- // what we do for LLVM's versions in Basic/LLVM.h.
- using llvm::isa;
- using llvm::cast;
}
#endif
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 015a739..5cfacac 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -483,7 +483,7 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
if (ThreadID != nullptr)
return ThreadID;
}
- if (auto OMPRegionInfo =
+ if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
if (OMPRegionInfo->getThreadIDVariable()) {
// Check if this an outlined function with thread id passed as argument.
@@ -1356,7 +1356,7 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
// return the address of that temp.
Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
SourceLocation Loc) {
- if (auto OMPRegionInfo =
+ if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
if (OMPRegionInfo->getThreadIDVariable())
return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
@@ -1717,15 +1717,10 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
}
// Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
// thread_id);
- auto *OMPRegionInfo =
- dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo);
- // Do not emit barrier call in the single directive emitted in some rare cases
- // for sections directives.
- if (OMPRegionInfo && OMPRegionInfo->getDirectiveKind() == OMPD_single)
- return;
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
getThreadID(CGF, Loc)};
- if (OMPRegionInfo) {
+ if (auto *OMPRegionInfo =
+ dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
auto *Result = CGF.EmitRuntimeCall(
createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
@@ -3649,8 +3644,6 @@ void CGOpenMPRuntime::emitCancellationPointCall(
// global_tid, kmp_int32 cncl_kind);
if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
- if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
- return;
if (OMPRegionInfo->hasCancel()) {
llvm::Value *Args[] = {
emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
@@ -3687,8 +3680,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
// kmp_int32 cncl_kind);
if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
- if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
- return;
auto &&ThenGen = [this, Loc, CancelRegion,
OMPRegionInfo](CodeGenFunction &CGF) {
llvm::Value *Args[] = {
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 6855512..59821a8 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1657,50 +1657,51 @@ OpenMPDirectiveKind
CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
auto *CS = dyn_cast<CompoundStmt>(Stmt);
- if (CS && CS->size() > 1) {
- bool HasLastprivates = false;
- auto &&CodeGen = [&S, CS, &HasLastprivates](CodeGenFunction &CGF) {
- auto &C = CGF.CGM.getContext();
- auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
- // Emit helper vars inits.
- LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
- CGF.Builder.getInt32(0));
- auto *GlobalUBVal = CGF.Builder.getInt32(CS->size() - 1);
- LValue UB =
- createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
- LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
- CGF.Builder.getInt32(1));
- LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
- CGF.Builder.getInt32(0));
- // Loop counter.
- LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
- OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
- CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
- OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
- CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
- // Generate condition for loop.
- BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
- OK_Ordinary, S.getLocStart(),
- /*fpContractable=*/false);
- // Increment for loop counter.
- UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue,
- OK_Ordinary, S.getLocStart());
- auto BodyGen = [CS, &S, &IV](CodeGenFunction &CGF) {
- // Iterate through all sections and emit a switch construct:
- // switch (IV) {
- // case 0:
- // <SectionStmt[0]>;
- // break;
- // ...
- // case <NumSection> - 1:
- // <SectionStmt[<NumSection> - 1]>;
- // break;
- // }
- // .omp.sections.exit:
- auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
- auto *SwitchStmt = CGF.Builder.CreateSwitch(
- CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
- CS->size());
+ bool HasLastprivates = false;
+ auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF) {
+ auto &C = CGF.CGM.getContext();
+ auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
+ // Emit helper vars inits.
+ LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
+ CGF.Builder.getInt32(0));
+ auto *GlobalUBVal = CS != nullptr ? CGF.Builder.getInt32(CS->size() - 1)
+ : CGF.Builder.getInt32(0);
+ LValue UB =
+ createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
+ LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
+ CGF.Builder.getInt32(1));
+ LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
+ CGF.Builder.getInt32(0));
+ // Loop counter.
+ LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
+ OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
+ CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
+ OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
+ CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
+ // Generate condition for loop.
+ BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
+ OK_Ordinary, S.getLocStart(),
+ /*fpContractable=*/false);
+ // Increment for loop counter.
+ UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
+ S.getLocStart());
+ auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) {
+ // Iterate through all sections and emit a switch construct:
+ // switch (IV) {
+ // case 0:
+ // <SectionStmt[0]>;
+ // break;
+ // ...
+ // case <NumSection> - 1:
+ // <SectionStmt[<NumSection> - 1]>;
+ // break;
+ // }
+ // .omp.sections.exit:
+ auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
+ auto *SwitchStmt = CGF.Builder.CreateSwitch(
+ CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
+ CS == nullptr ? 1 : CS->size());
+ if (CS) {
unsigned CaseNumber = 0;
for (auto *SubStmt : CS->children()) {
auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
@@ -1710,99 +1711,72 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
CGF.EmitBranch(ExitBB);
++CaseNumber;
}
- CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
- };
-
- CodeGenFunction::OMPPrivateScope LoopScope(CGF);
- if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
- // Emit implicit barrier to synchronize threads and avoid data races on
- // initialization of firstprivate variables.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(
- CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
- /*ForceSimpleCall=*/true);
+ } else {
+ auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
+ CGF.EmitBlock(CaseBB);
+ SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
+ CGF.EmitStmt(Stmt);
+ CGF.EmitBranch(ExitBB);
}
- CGF.EmitOMPPrivateClause(S, LoopScope);
- HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
- CGF.EmitOMPReductionClauseInit(S, LoopScope);
- (void)LoopScope.Privatize();
-
- // Emit static non-chunked loop.
- CGF.CGM.getOpenMPRuntime().emitForStaticInit(
- CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
- /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(),
- LB.getAddress(), UB.getAddress(), ST.getAddress());
- // UB = min(UB, GlobalUB);
- auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
- auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
- CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
- CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
- // IV = LB;
- CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
- // while (idx <= UB) { BODY; ++idx; }
- CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
- [](CodeGenFunction &) {});
- // Tell the runtime we are done.
- CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
- CGF.EmitOMPReductionClauseFinal(S);
-
- // Emit final copy of the lastprivate variables if IsLastIter != 0.
- if (HasLastprivates)
- CGF.EmitOMPLastprivateClauseFinal(
- S, CGF.Builder.CreateIsNotNull(
- CGF.EmitLoadOfScalar(IL, S.getLocStart())));
+ CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
};
- bool HasCancel = false;
- if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
- HasCancel = OSD->hasCancel();
- else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
- HasCancel = OPSD->hasCancel();
- CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
- HasCancel);
- // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
- // clause. Otherwise the barrier will be generated by the codegen for the
- // directive.
- if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
+ CodeGenFunction::OMPPrivateScope LoopScope(CGF);
+ if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
- OMPD_unknown);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
}
- return OMPD_sections;
- }
- // If only one section is found - no need to generate loop, emit as a single
- // region.
- bool HasFirstprivates;
- // No need to generate reductions for sections with single section region, we
- // can use original shared variables for all operations.
- bool HasReductions = S.hasClausesOfKind<OMPReductionClause>();
- // No need to generate lastprivates for sections with single section region,
- // we can use original shared variable for all calculations with barrier at
- // the end of the sections.
- bool HasLastprivates = S.hasClausesOfKind<OMPLastprivateClause>();
- auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) {
- CodeGenFunction::OMPPrivateScope SingleScope(CGF);
- HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope);
- CGF.EmitOMPPrivateClause(S, SingleScope);
- (void)SingleScope.Privatize();
+ CGF.EmitOMPPrivateClause(S, LoopScope);
+ HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
+ CGF.EmitOMPReductionClauseInit(S, LoopScope);
+ (void)LoopScope.Privatize();
+
+ // Emit static non-chunked loop.
+ CGF.CGM.getOpenMPRuntime().emitForStaticInit(
+ CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
+ /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(),
+ UB.getAddress(), ST.getAddress());
+ // UB = min(UB, GlobalUB);
+ auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
+ auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
+ CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
+ CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
+ // IV = LB;
+ CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
+ // while (idx <= UB) { BODY; ++idx; }
+ CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
+ [](CodeGenFunction &) {});
+ // Tell the runtime we are done.
+ CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
+ CGF.EmitOMPReductionClauseFinal(S);
- CGF.EmitStmt(Stmt);
+ // Emit final copy of the lastprivate variables if IsLastIter != 0.
+ if (HasLastprivates)
+ CGF.EmitOMPLastprivateClauseFinal(
+ S, CGF.Builder.CreateIsNotNull(
+ CGF.EmitLoadOfScalar(IL, S.getLocStart())));
};
- CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
- llvm::None, llvm::None, llvm::None,
- llvm::None);
- // Emit barrier for firstprivates, lastprivates or reductions only if
- // 'sections' directive has 'nowait' clause. Otherwise the barrier will be
- // generated by the codegen for the directive.
- if ((HasFirstprivates || HasLastprivates || HasReductions) &&
- S.getSingleClause<OMPNowaitClause>()) {
+
+ bool HasCancel = false;
+ if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
+ HasCancel = OSD->hasCancel();
+ else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
+ HasCancel = OPSD->hasCancel();
+ CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
+ HasCancel);
+ // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
+ // clause. Otherwise the barrier will be generated by the codegen for the
+ // directive.
+ if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown,
- /*EmitChecks=*/false,
- /*ForceSimpleCall=*/true);
+ CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
+ OMPD_unknown);
}
- return OMPD_single;
+ return OMPD_sections;
}
void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index beede2e..b669353 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
@@ -3233,6 +3233,8 @@ ToolChain::CXXStdlibType NetBSD::GetCXXStdlibType(const ArgList &Args) const {
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
return ToolChain::CST_Libcxx;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
index 5a2dbd3..b7ac24f 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
@@ -8317,6 +8317,8 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
useLibgcc = false;
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
index 11f2329..82d81a8 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1742,13 +1742,18 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
/// otherwise. Loc is the location where this routine should point to
/// if there is an error, and Range is the source range to highlight
/// if there is an error.
+///
+/// If either InaccessibleBaseID or AmbigiousBaseConvID are 0, then the
+/// diagnostic for the respective type of error will be suppressed, but the
+/// check for ill-formed code will still be performed.
bool
Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
unsigned InaccessibleBaseID,
unsigned AmbigiousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name,
- CXXCastPath *BasePath) {
+ CXXCastPath *BasePath,
+ bool IgnoreAccess) {
// First, determine whether the path from Derived to Base is
// ambiguous. This is slightly more expensive than checking whether
// the Derived to Base conversion exists, because here we need to
@@ -1761,7 +1766,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
(void)DerivationOkay;
if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) {
- if (InaccessibleBaseID) {
+ if (!IgnoreAccess) {
// Check that the base class can be accessed.
switch (CheckBaseClassAccess(Loc, Base, Derived, Paths.front(),
InaccessibleBaseID)) {
@@ -1810,12 +1815,10 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
SourceLocation Loc, SourceRange Range,
CXXCastPath *BasePath,
bool IgnoreAccess) {
- return CheckDerivedToBaseConversion(Derived, Base,
- IgnoreAccess ? 0
- : diag::err_upcast_to_inaccessible_base,
- diag::err_ambiguous_derived_to_base_conv,
- Loc, Range, DeclarationName(),
- BasePath);
+ return CheckDerivedToBaseConversion(
+ Derived, Base, diag::err_upcast_to_inaccessible_base,
+ diag::err_ambiguous_derived_to_base_conv, Loc, Range, DeclarationName(),
+ BasePath, IgnoreAccess);
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
index 3e89af6..ebf7981 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
@@ -3748,6 +3748,128 @@ bool Sema::CheckVecStepExpr(Expr *E) {
return CheckUnaryExprOrTypeTraitOperand(E, UETT_VecStep);
}
+static void captureVariablyModifiedType(ASTContext &Context, QualType T,
+ CapturingScopeInfo *CSI) {
+ assert(T->isVariablyModifiedType());
+ assert(CSI != nullptr);
+
+ // We're going to walk down into the type and look for VLA expressions.
+ do {
+ const Type *Ty = T.getTypePtr();
+ switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+ T = QualType();
+ break;
+ // These types are never variably-modified.
+ case Type::Builtin:
+ case Type::Complex:
+ case Type::Vector:
+ case Type::ExtVector:
+ case Type::Record:
+ case Type::Enum:
+ case Type::Elaborated:
+ case Type::TemplateSpecialization:
+ case Type::ObjCObject:
+ case Type::ObjCInterface:
+ case Type::ObjCObjectPointer:
+ case Type::Pipe:
+ llvm_unreachable("type class is never variably-modified!");
+ case Type::Adjusted:
+ T = cast<AdjustedType>(Ty)->getOriginalType();
+ break;
+ case Type::Decayed:
+ T = cast<DecayedType>(Ty)->getPointeeType();
+ break;
+ case Type::Pointer:
+ T = cast<PointerType>(Ty)->getPointeeType();
+ break;
+ case Type::BlockPointer:
+ T = cast<BlockPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::LValueReference:
+ case Type::RValueReference:
+ T = cast<ReferenceType>(Ty)->getPointeeType();
+ break;
+ case Type::MemberPointer:
+ T = cast<MemberPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ // Losing element qualification here is fine.
+ T = cast<ArrayType>(Ty)->getElementType();
+ break;
+ case Type::VariableArray: {
+ // Losing element qualification here is fine.
+ const VariableArrayType *VAT = cast<VariableArrayType>(Ty);
+
+ // Unknown size indication requires no size computation.
+ // Otherwise, evaluate and record it.
+ if (auto Size = VAT->getSizeExpr()) {
+ if (!CSI->isVLATypeCaptured(VAT)) {
+ RecordDecl *CapRecord = nullptr;
+ if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+ CapRecord = LSI->Lambda;
+ } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
+ CapRecord = CRSI->TheRecordDecl;
+ }
+ if (CapRecord) {
+ auto ExprLoc = Size->getExprLoc();
+ auto SizeType = Context.getSizeType();
+ // Build the non-static data member.
+ auto Field =
+ FieldDecl::Create(Context, CapRecord, ExprLoc, ExprLoc,
+ /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr,
+ /*BW*/ nullptr, /*Mutable*/ false,
+ /*InitStyle*/ ICIS_NoInit);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ Field->setCapturedVLAType(VAT);
+ CapRecord->addDecl(Field);
+
+ CSI->addVLATypeCapture(ExprLoc, SizeType);
+ }
+ }
+ }
+ T = VAT->getElementType();
+ break;
+ }
+ case Type::FunctionProto:
+ case Type::FunctionNoProto:
+ T = cast<FunctionType>(Ty)->getReturnType();
+ break;
+ case Type::Paren:
+ case Type::TypeOf:
+ case Type::UnaryTransform:
+ case Type::Attributed:
+ case Type::SubstTemplateTypeParm:
+ case Type::PackExpansion:
+ // Keep walking after single level desugaring.
+ T = T.getSingleStepDesugaredType(Context);
+ break;
+ case Type::Typedef:
+ T = cast<TypedefType>(Ty)->desugar();
+ break;
+ case Type::Decltype:
+ T = cast<DecltypeType>(Ty)->desugar();
+ break;
+ case Type::Auto:
+ T = cast<AutoType>(Ty)->getDeducedType();
+ break;
+ case Type::TypeOfExpr:
+ T = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
+ break;
+ case Type::Atomic:
+ T = cast<AtomicType>(Ty)->getValueType();
+ break;
+ }
+ } while (!T.isNull() && T->isVariablyModifiedType());
+}
+
/// \brief Build a sizeof or alignof expression given a type operand.
ExprResult
Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
@@ -3763,6 +3885,20 @@ Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
CheckUnaryExprOrTypeTraitOperand(T, OpLoc, R, ExprKind))
return ExprError();
+ if (T->isVariablyModifiedType() && FunctionScopes.size() > 1) {
+ if (auto *TT = T->getAs<TypedefType>()) {
+ if (auto *CSI = dyn_cast<CapturingScopeInfo>(FunctionScopes.back())) {
+ DeclContext *DC = nullptr;
+ if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI))
+ DC = LSI->CallOperator;
+ else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI))
+ DC = CRSI->TheCapturedDecl;
+ if (DC && TT->getDecl()->getDeclContext() != DC)
+ captureVariablyModifiedType(Context, T, CSI);
+ }
+ }
+ }
+
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
@@ -7354,11 +7490,14 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
LHSType->isBlockPointerType()) &&
RHS.get()->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull)) {
- CastKind Kind;
- CXXCastPath Path;
- CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false);
- if (ConvertRHS)
- RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
+ if (Diagnose || ConvertRHS) {
+ CastKind Kind;
+ CXXCastPath Path;
+ CheckPointerConversion(RHS.get(), LHSType, Kind, Path,
+ /*IgnoreBaseAccess=*/false, Diagnose);
+ if (ConvertRHS)
+ RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
+ }
return Compatible;
}
@@ -7376,8 +7515,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
}
Expr *PRE = RHS.get()->IgnoreParenCasts();
- if (ObjCProtocolExpr *OPE = dyn_cast<ObjCProtocolExpr>(PRE)) {
- ObjCProtocolDecl *PDecl = OPE->getProtocol();
+ if (Diagnose && isa<ObjCProtocolExpr>(PRE)) {
+ ObjCProtocolDecl *PDecl = cast<ObjCProtocolExpr>(PRE)->getProtocol();
if (PDecl && !PDecl->hasDefinition()) {
Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl->getName();
Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
@@ -7399,11 +7538,11 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
Expr *E = RHS.get();
if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
- DiagnoseCFAudited);
+ Diagnose, DiagnoseCFAudited);
if (getLangOpts().ObjC1 &&
- (CheckObjCBridgeRelatedConversions(E->getLocStart(),
- LHSType, E->getType(), E) ||
- ConversionToObjCStringLiteralCheck(LHSType, E))) {
+ (CheckObjCBridgeRelatedConversions(E->getLocStart(), LHSType,
+ E->getType(), E, Diagnose) ||
+ ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) {
RHS = E;
return Compatible;
}
@@ -8961,8 +9100,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
else {
Expr *E = RHS.get();
if (getLangOpts().ObjCAutoRefCount)
- CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion, false,
- Opc);
+ CheckObjCARCConversion(SourceRange(), LHSType, E,
+ CCK_ImplicitConversion, /*Diagnose=*/true,
+ /*DiagnoseCFAudited=*/false, Opc);
RHS = ImpCastExprToType(E, LHSType,
LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
}
@@ -11830,8 +11970,8 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
return new (Context) GNUNullExpr(Ty, TokenLoc);
}
-bool
-Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
+bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp,
+ bool Diagnose) {
if (!getLangOpts().ObjC1)
return false;
@@ -11857,8 +11997,9 @@ Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
if (!SL || !SL->isAscii())
return false;
- Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
- << FixItHint::CreateInsertion(SL->getLocStart(), "@");
+ if (Diagnose)
+ Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
+ << FixItHint::CreateInsertion(SL->getLocStart(), "@");
Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
return true;
}
@@ -13139,120 +13280,7 @@ bool Sema::tryCaptureVariable(
QualType QTy = Var->getType();
if (ParmVarDecl *PVD = dyn_cast_or_null<ParmVarDecl>(Var))
QTy = PVD->getOriginalType();
- do {
- const Type *Ty = QTy.getTypePtr();
- switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_TYPE(Class, Base)
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- QTy = QualType();
- break;
- // These types are never variably-modified.
- case Type::Builtin:
- case Type::Complex:
- case Type::Vector:
- case Type::ExtVector:
- case Type::Record:
- case Type::Enum:
- case Type::Elaborated:
- case Type::TemplateSpecialization:
- case Type::ObjCObject:
- case Type::ObjCInterface:
- case Type::ObjCObjectPointer:
- case Type::Pipe:
- llvm_unreachable("type class is never variably-modified!");
- case Type::Adjusted:
- QTy = cast<AdjustedType>(Ty)->getOriginalType();
- break;
- case Type::Decayed:
- QTy = cast<DecayedType>(Ty)->getPointeeType();
- break;
- case Type::Pointer:
- QTy = cast<PointerType>(Ty)->getPointeeType();
- break;
- case Type::BlockPointer:
- QTy = cast<BlockPointerType>(Ty)->getPointeeType();
- break;
- case Type::LValueReference:
- case Type::RValueReference:
- QTy = cast<ReferenceType>(Ty)->getPointeeType();
- break;
- case Type::MemberPointer:
- QTy = cast<MemberPointerType>(Ty)->getPointeeType();
- break;
- case Type::ConstantArray:
- case Type::IncompleteArray:
- // Losing element qualification here is fine.
- QTy = cast<ArrayType>(Ty)->getElementType();
- break;
- case Type::VariableArray: {
- // Losing element qualification here is fine.
- const VariableArrayType *VAT = cast<VariableArrayType>(Ty);
-
- // Unknown size indication requires no size computation.
- // Otherwise, evaluate and record it.
- if (auto Size = VAT->getSizeExpr()) {
- if (!CSI->isVLATypeCaptured(VAT)) {
- RecordDecl *CapRecord = nullptr;
- if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
- CapRecord = LSI->Lambda;
- } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
- CapRecord = CRSI->TheRecordDecl;
- }
- if (CapRecord) {
- auto ExprLoc = Size->getExprLoc();
- auto SizeType = Context.getSizeType();
- // Build the non-static data member.
- auto Field = FieldDecl::Create(
- Context, CapRecord, ExprLoc, ExprLoc,
- /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr,
- /*BW*/ nullptr, /*Mutable*/ false,
- /*InitStyle*/ ICIS_NoInit);
- Field->setImplicit(true);
- Field->setAccess(AS_private);
- Field->setCapturedVLAType(VAT);
- CapRecord->addDecl(Field);
-
- CSI->addVLATypeCapture(ExprLoc, SizeType);
- }
- }
- }
- QTy = VAT->getElementType();
- break;
- }
- case Type::FunctionProto:
- case Type::FunctionNoProto:
- QTy = cast<FunctionType>(Ty)->getReturnType();
- break;
- case Type::Paren:
- case Type::TypeOf:
- case Type::UnaryTransform:
- case Type::Attributed:
- case Type::SubstTemplateTypeParm:
- case Type::PackExpansion:
- // Keep walking after single level desugaring.
- QTy = QTy.getSingleStepDesugaredType(getASTContext());
- break;
- case Type::Typedef:
- QTy = cast<TypedefType>(Ty)->desugar();
- break;
- case Type::Decltype:
- QTy = cast<DecltypeType>(Ty)->desugar();
- break;
- case Type::Auto:
- QTy = cast<AutoType>(Ty)->getDeducedType();
- break;
- case Type::TypeOfExpr:
- QTy = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
- break;
- case Type::Atomic:
- QTy = cast<AtomicType>(Ty)->getValueType();
- break;
- }
- } while (!QTy.isNull() && QTy->isVariablyModifiedType());
+ captureVariablyModifiedType(Context, QTy, CSI);
}
if (getLangOpts().OpenMP) {
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
index 1d86ca3..c1fb906 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
@@ -3816,7 +3816,7 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
ObjCMethodDecl *&ClassMethod,
ObjCMethodDecl *&InstanceMethod,
TypedefNameDecl *&TDNDecl,
- bool CfToNs) {
+ bool CfToNs, bool Diagnose) {
QualType T = CfToNs ? SrcType : DestType;
ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
if (!ObjCBAttr)
@@ -3832,20 +3832,24 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
LookupResult R(*this, DeclarationName(RCId), SourceLocation(),
Sema::LookupOrdinaryName);
if (!LookupName(R, TUScope)) {
- Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
- << SrcType << DestType;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
+ << SrcType << DestType;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
return false;
}
Target = R.getFoundDecl();
if (Target && isa<ObjCInterfaceDecl>(Target))
RelatedClass = cast<ObjCInterfaceDecl>(Target);
else {
- Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
- << SrcType << DestType;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- if (Target)
- Diag(Target->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
+ << SrcType << DestType;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Target)
+ Diag(Target->getLocStart(), diag::note_declared_at);
+ }
return false;
}
@@ -3854,9 +3858,11 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
Selector Sel = Context.Selectors.getUnarySelector(CMId);
ClassMethod = RelatedClass->lookupMethod(Sel, false);
if (!ClassMethod) {
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << Sel << false;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << Sel << false;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
return false;
}
}
@@ -3866,9 +3872,11 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
Selector Sel = Context.Selectors.getNullarySelector(IMId);
InstanceMethod = RelatedClass->lookupMethod(Sel, true);
if (!InstanceMethod) {
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << Sel << true;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << Sel << true;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
return false;
}
}
@@ -3878,7 +3886,7 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
bool
Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
QualType DestType, QualType SrcType,
- Expr *&SrcExpr) {
+ Expr *&SrcExpr, bool Diagnose) {
ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
@@ -3891,27 +3899,29 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
ObjCMethodDecl *InstanceMethod = nullptr;
TypedefNameDecl *TDNDecl = nullptr;
if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
- ClassMethod, InstanceMethod, TDNDecl, CfToNs))
+ ClassMethod, InstanceMethod, TDNDecl,
+ CfToNs, Diagnose))
return false;
if (CfToNs) {
// Implicit conversion from CF to ObjC object is needed.
if (ClassMethod) {
- std::string ExpressionString = "[";
- ExpressionString += RelatedClass->getNameAsString();
- ExpressionString += " ";
- ExpressionString += ClassMethod->getSelector().getAsString();
- SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
- // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << ClassMethod->getSelector() << false
- << FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
- << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
- Diag(RelatedClass->getLocStart(), diag::note_declared_at);
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ std::string ExpressionString = "[";
+ ExpressionString += RelatedClass->getNameAsString();
+ ExpressionString += " ";
+ ExpressionString += ClassMethod->getSelector().getAsString();
+ SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
+ // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << ClassMethod->getSelector() << false
+ << FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
+ << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
+ Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
- QualType receiverType =
- Context.getObjCInterfaceType(RelatedClass);
+ QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
// Argument.
Expr *args[] = { SrcExpr };
ExprResult msg = BuildClassMessageImplicit(receiverType, false,
@@ -3925,30 +3935,34 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
else {
// Implicit conversion from ObjC type to CF object is needed.
if (InstanceMethod) {
- std::string ExpressionString;
- SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
- if (InstanceMethod->isPropertyAccessor())
- if (const ObjCPropertyDecl *PDecl = InstanceMethod->findPropertyDecl()) {
- // fixit: ObjectExpr.propertyname when it is aproperty accessor.
- ExpressionString = ".";
- ExpressionString += PDecl->getNameAsString();
+ if (Diagnose) {
+ std::string ExpressionString;
+ SourceLocation SrcExprEndLoc =
+ getLocForEndOfToken(SrcExpr->getLocEnd());
+ if (InstanceMethod->isPropertyAccessor())
+ if (const ObjCPropertyDecl *PDecl =
+ InstanceMethod->findPropertyDecl()) {
+ // fixit: ObjectExpr.propertyname when it is aproperty accessor.
+ ExpressionString = ".";
+ ExpressionString += PDecl->getNameAsString();
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << InstanceMethod->getSelector() << true
+ << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+ }
+ if (ExpressionString.empty()) {
+ // Provide a fixit: [ObjectExpr InstanceMethod]
+ ExpressionString = " ";
+ ExpressionString += InstanceMethod->getSelector().getAsString();
+ ExpressionString += "]";
+
Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << InstanceMethod->getSelector() << true
- << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+ << SrcType << DestType << InstanceMethod->getSelector() << true
+ << FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
+ << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
}
- if (ExpressionString.empty()) {
- // Provide a fixit: [ObjectExpr InstanceMethod]
- ExpressionString = " ";
- ExpressionString += InstanceMethod->getSelector().getAsString();
- ExpressionString += "]";
-
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << InstanceMethod->getSelector() << true
- << FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
- << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+ Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
}
- Diag(RelatedClass->getLocStart(), diag::note_declared_at);
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
ExprResult msg =
BuildInstanceMessageImplicit(SrcExpr, SrcType,
@@ -3965,6 +3979,7 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
Sema::ARCConversionResult
Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
Expr *&castExpr, CheckedConversionKind CCK,
+ bool Diagnose,
bool DiagnoseCFAudited,
BinaryOperatorKind Opc) {
QualType castExprType = castExpr->getType();
@@ -3980,9 +3995,9 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
if (exprACTC == castACTC) {
// check for viablity and report error if casting an rvalue to a
// life-time qualifier.
- if ((castACTC == ACTC_retainable) &&
+ if (Diagnose && castACTC == ACTC_retainable &&
(CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
- (castType != castExprType)) {
+ castType != castExprType) {
const Type *DT = castType.getTypePtr();
QualType QDT = castType;
// We desugar some types but not others. We ignore those
@@ -4051,19 +4066,20 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
// to 'NSString *'. Let caller issue a normal mismatched diagnostic with
// suitable fix-it.
if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
- ConversionToObjCStringLiteralCheck(castType, castExpr))
+ ConversionToObjCStringLiteralCheck(castType, castExpr, Diagnose))
return ACR_okay;
// Do not issue "bridge cast" diagnostic when implicit casting
// a retainable object to a CF type parameter belonging to an audited
// CF API function. Let caller issue a normal type mismatched diagnostic
// instead.
- if (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
- castACTC != ACTC_coreFoundation)
+ if (Diagnose &&
+ (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
+ castACTC != ACTC_coreFoundation))
if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
(Opc == BO_NE || Opc == BO_EQ)))
- diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
- castExpr, castExpr, exprACTC, CCK);
+ diagnoseObjCARCConversion(*this, castRange, castType, castACTC, castExpr,
+ castExpr, exprACTC, CCK);
return ACR_okay;
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
index 663da0c..d6a0ff7 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
@@ -2687,15 +2687,16 @@ bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
CastKind &Kind,
CXXCastPath& BasePath,
- bool IgnoreBaseAccess) {
+ bool IgnoreBaseAccess,
+ bool Diagnose) {
QualType FromType = From->getType();
bool IsCStyleOrFunctionalCast = IgnoreBaseAccess;
Kind = CK_BitCast;
- if (!IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() &&
+ if (Diagnose && !IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() &&
From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) ==
- Expr::NPCK_ZeroExpression) {
+ Expr::NPCK_ZeroExpression) {
if (Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy))
DiagRuntimeBehavior(From->getExprLoc(), From,
PDiag(diag::warn_impcast_bool_to_null_pointer)
@@ -2713,18 +2714,24 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
!Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) {
// We must have a derived-to-base conversion. Check an
// ambiguous or inaccessible conversion.
- if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
- From->getExprLoc(),
- From->getSourceRange(), &BasePath,
- IgnoreBaseAccess))
+ unsigned InaccessibleID = 0;
+ unsigned AmbigiousID = 0;
+ if (Diagnose) {
+ InaccessibleID = diag::err_upcast_to_inaccessible_base;
+ AmbigiousID = diag::err_ambiguous_derived_to_base_conv;
+ }
+ if (CheckDerivedToBaseConversion(
+ FromPointeeType, ToPointeeType, InaccessibleID, AmbigiousID,
+ From->getExprLoc(), From->getSourceRange(), DeclarationName(),
+ &BasePath, IgnoreBaseAccess))
return true;
// The conversion was successful.
Kind = CK_DerivedToBase;
}
- if (!IsCStyleOrFunctionalCast && FromPointeeType->isFunctionType() &&
- ToPointeeType->isVoidType()) {
+ if (Diagnose && !IsCStyleOrFunctionalCast &&
+ FromPointeeType->isFunctionType() && ToPointeeType->isVoidType()) {
assert(getLangOpts().MSVCCompat &&
"this should only be possible with MSVCCompat!");
Diag(From->getExprLoc(), diag::ext_ms_impcast_fn_obj)
OpenPOWER on IntegriCloud