aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-22 19:43:45 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-22 19:43:45 +0000
commitaa803409c3bd3930126db630c29f63d42f255153 (patch)
tree042106605c08352895ba4383ef97eae88b6b31aa
parent1ce08792766261dcaa25d8215f9d1c2f70d7b7e9 (diff)
downloadsrc-aa803409c3bd3930126db630c29f63d42f255153.tar.gz
src-aa803409c3bd3930126db630c29f63d42f255153.zip
Vendor import of clang trunk r303571:vendor/clang/clang-trunk-r303571
Notes
Notes: svn path=/vendor/clang/dist/; revision=318665 svn path=/vendor/clang/clang-trunk-r303571/; revision=318666; tag=vendor/clang/clang-trunk-r303571
-rw-r--r--include/clang/AST/ASTContext.h5
-rw-r--r--include/clang/AST/CXXInheritance.h6
-rw-r--r--include/clang/AST/DeclBase.h24
-rw-r--r--include/clang/AST/Type.h16
-rw-r--r--include/clang/Basic/AddressSpaces.h5
-rw-r--r--include/clang/Basic/Attr.td12
-rw-r--r--include/clang/Basic/AttrDocs.td13
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--include/clang/Basic/LangOptions.h2
-rw-r--r--include/clang/Format/Format.h5
-rw-r--r--include/clang/Lex/ModuleMap.h10
-rw-r--r--include/clang/Lex/Preprocessor.h6
-rw-r--r--include/clang/Parse/Parser.h18
-rw-r--r--include/clang/Sema/DeclSpec.h35
-rw-r--r--include/clang/Sema/Sema.h31
-rw-r--r--include/clang/Serialization/ASTReader.h14
-rw-r--r--include/clang/Serialization/ASTWriter.h4
-rw-r--r--lib/AST/ASTContext.cpp13
-rw-r--r--lib/AST/CXXInheritance.cpp12
-rw-r--r--lib/AST/DeclBase.cpp21
-rw-r--r--lib/AST/ExprConstant.cpp33
-rw-r--r--lib/AST/Type.cpp16
-rw-r--r--lib/AST/TypePrinter.cpp4
-rw-r--r--lib/Basic/Targets.cpp64
-rw-r--r--lib/CodeGen/CGAtomic.cpp28
-rw-r--r--lib/CodeGen/CGBlocks.cpp3
-rw-r--r--lib/CodeGen/CGBuiltin.cpp3
-rw-r--r--lib/CodeGen/CGClass.cpp4
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp2
-rw-r--r--lib/CodeGen/CGDecl.cpp18
-rw-r--r--lib/CodeGen/CGExpr.cpp248
-rw-r--r--lib/CodeGen/CGExprCXX.cpp9
-rw-r--r--lib/CodeGen/CGExprScalar.cpp7
-rw-r--r--lib/CodeGen/CGObjC.cpp6
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp3
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp6
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp7
-rw-r--r--lib/CodeGen/CGValue.h51
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp24
-rw-r--r--lib/CodeGen/CodeGenFunction.h65
-rw-r--r--lib/CodeGen/CodeGenModule.cpp20
-rw-r--r--lib/CodeGen/CodeGenTypeCache.h4
-rw-r--r--lib/CodeGen/TargetInfo.cpp17
-rw-r--r--lib/CodeGen/TargetInfo.h15
-rw-r--r--lib/Format/BreakableToken.cpp28
-rw-r--r--lib/Format/ContinuationIndenter.cpp6
-rw-r--r--lib/Format/Format.cpp3
-rw-r--r--lib/Format/TokenAnnotator.cpp64
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp3
-rw-r--r--lib/Format/UnwrappedLineParser.cpp65
-rw-r--r--lib/Index/IndexBody.cpp3
-rw-r--r--lib/Index/IndexDecl.cpp68
-rw-r--r--lib/Index/IndexSymbol.cpp13
-rw-r--r--lib/Index/USRGeneration.cpp2
-rw-r--r--lib/Lex/ModuleMap.cpp33
-rw-r--r--lib/Lex/PPDirectives.cpp13
-rw-r--r--lib/Lex/PPLexerChange.cpp20
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp15
-rw-r--r--lib/Parse/ParseDecl.cpp46
-rw-r--r--lib/Parse/ParseDeclCXX.cpp61
-rw-r--r--lib/Parse/ParseExpr.cpp19
-rw-r--r--lib/Parse/ParseExprCXX.cpp23
-rw-r--r--lib/Parse/ParseOpenMP.cpp14
-rw-r--r--lib/Parse/ParsePragma.cpp44
-rw-r--r--lib/Parse/ParseStmt.cpp4
-rw-r--r--lib/Parse/ParseTemplate.cpp18
-rw-r--r--lib/Parse/ParseTentative.cpp44
-rw-r--r--lib/Parse/Parser.cpp22
-rw-r--r--lib/Sema/SemaDecl.cpp90
-rw-r--r--lib/Sema/SemaDeclAttr.cpp19
-rw-r--r--lib/Sema/SemaLookup.cpp108
-rw-r--r--lib/Sema/SemaTemplate.cpp4
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp73
-rw-r--r--lib/Sema/SemaType.cpp20
-rw-r--r--lib/Serialization/ASTReader.cpp8
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp17
-rw-r--r--lib/Serialization/ASTWriter.cpp19
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp6
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp6
-rw-r--r--test/CodeGen/address-space.c8
-rw-r--r--test/CodeGen/micromips-attr.c12
-rw-r--r--test/CodeGen/wchar-size.c8
-rw-r--r--test/CodeGenCUDA/flush-denormals.cu4
-rw-r--r--test/CodeGenCXX/amdgcn-automatic-variable.cpp72
-rw-r--r--test/CodeGenCXX/strict-vtable-pointers.cpp2
-rw-r--r--test/CodeGenOpenCL/amdgcn-automatic-variable.cl60
-rw-r--r--test/CodeGenOpenCL/amdgpu-alignment.cl2
-rw-r--r--test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl2
-rw-r--r--test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl2
-rw-r--r--test/CodeGenOpenCL/amdgpu-nullptr.cl4
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn.cl2
-rw-r--r--test/CodeGenOpenCL/byval.cl2
-rw-r--r--test/CodeGenOpenCL/size_t.cl2
-rw-r--r--test/Index/Core/external-source-symbol-attr.m4
-rw-r--r--test/Index/Core/index-dependent-source.cpp17
-rw-r--r--test/Index/Core/index-source.cpp96
-rw-r--r--test/Index/Core/index-source.m19
-rw-r--r--test/Misc/pragma-attribute-supported-attributes-list.test4
-rw-r--r--test/Modules/extern_cxx.cpp25
-rw-r--r--test/Modules/macro-redefinition.cpp27
-rw-r--r--test/Modules/preprocess-module.cpp14
-rw-r--r--test/Parser/cxx-template-argument.cpp2
-rw-r--r--test/Parser/cxx0x-ambig.cpp26
-rw-r--r--test/Parser/cxx0x-decl.cpp19
-rw-r--r--test/Sema/attr-micromips.c17
-rw-r--r--test/Sema/block-args.c2
-rw-r--r--test/Sema/integer-overflow.c8
-rw-r--r--test/Sema/sizeof-struct-non-zero-as-member.cl2
-rw-r--r--test/SemaCXX/Inputs/nullability-completeness.h4
-rw-r--r--test/SemaCXX/lambda-expressions.cpp14
-rw-r--r--test/SemaCXX/local-classes.cpp12
-rw-r--r--test/SemaCXX/modules-ts.cppm3
-rw-r--r--test/SemaCXX/nullability.cpp8
-rw-r--r--test/SemaCXX/warn-shadow.cpp7
-rw-r--r--test/SemaObjC/unguarded-availability.m20
-rw-r--r--test/SemaOpenCL/storageclass-cl20.cl4
-rw-r--r--test/SemaOpenCL/storageclass.cl42
-rw-r--r--tools/libclang/CIndex.cpp11
-rw-r--r--unittests/Format/FormatTest.cpp14
-rw-r--r--unittests/Format/FormatTestComments.cpp109
-rw-r--r--unittests/Format/FormatTestJS.cpp10
-rw-r--r--unittests/Format/FormatTestSelective.cpp8
123 files changed, 1748 insertions, 896 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 474cf2c0e3f3..4c379620ab2d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -935,7 +935,7 @@ public:
/// \brief Get the additional modules in which the definition \p Def has
/// been merged.
- ArrayRef<Module*> getModulesWithMergedDefinition(NamedDecl *Def) {
+ ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) {
auto MergedIt = MergedDefModules.find(Def);
if (MergedIt == MergedDefModules.end())
return None;
@@ -2324,8 +2324,7 @@ public:
uint64_t getTargetNullPointerValue(QualType QT) const;
bool addressSpaceMapManglingFor(unsigned AS) const {
- return AddrSpaceMapMangling ||
- AS >= LangAS::Count;
+ return AddrSpaceMapMangling || AS >= LangAS::FirstTargetAddressSpace;
}
private:
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index a7961ebe8ce6..980608570fd6 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -127,7 +127,11 @@ class CXXBasePaths {
/// class subobjects for that class type. The key of the map is
/// the cv-unqualified canonical type of the base class subobject.
llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
-
+
+ /// VisitedDependentRecords - Records the dependent records that have been
+ /// already visited.
+ llvm::SmallDenseSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
+
/// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
/// ambiguous paths while it is looking for a path from a derived
/// type to a base type.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 08879b36cce5..c26e2d7bde95 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -34,6 +34,7 @@ class DeclarationName;
class DependentDiagnostic;
class EnumDecl;
class ExportDecl;
+class ExternalSourceSymbolAttr;
class FunctionDecl;
class FunctionType;
enum Linkage : unsigned char;
@@ -332,15 +333,15 @@ private:
bool AccessDeclContextSanity() const;
protected:
-
Decl(Kind DK, DeclContext *DC, SourceLocation L)
- : NextInContextAndBits(), DeclCtx(DC),
- Loc(L), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false), Implicit(false), Used(false), Referenced(false),
- Access(AS_none), FromASTFile(0), Hidden(DC && cast<Decl>(DC)->Hidden),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0)
- {
+ : NextInContextAndBits(), DeclCtx(DC), Loc(L), DeclKind(DK),
+ InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false),
+ Referenced(false), Access(AS_none), FromASTFile(0),
+ Hidden(DC && cast<Decl>(DC)->Hidden &&
+ (!cast<Decl>(DC)->isFromASTFile() ||
+ hasLocalOwningModuleStorage())),
+ IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
+ CacheValidAndLinkage(0) {
if (StatisticsEnabled) add(DK);
}
@@ -562,6 +563,10 @@ public:
NextInContextAndBits.setInt(Bits);
}
+ /// \brief Looks on this and related declarations for an applicable
+ /// external source symbol attribute.
+ ExternalSourceSymbolAttr *getExternalSourceSymbolAttr() const;
+
/// \brief Whether this declaration was marked as being private to the
/// module in which it was defined.
bool isModulePrivate() const {
@@ -698,6 +703,9 @@ public:
Module *getLocalOwningModule() const {
if (isFromASTFile() || !Hidden)
return nullptr;
+
+ assert(hasLocalOwningModuleStorage() &&
+ "hidden local decl but no local module storage");
return reinterpret_cast<Module *const *>(this)[-1];
}
void setLocalOwningModule(Module *M) {
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index b1c2503c32e3..9eb6d81296d8 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -333,15 +333,18 @@ public:
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
+ bool hasTargetSpecificAddressSpace() const {
+ return getAddressSpace() >= LangAS::FirstTargetAddressSpace;
+ }
/// Get the address space attribute value to be printed by diagnostics.
unsigned getAddressSpaceAttributePrintValue() const {
auto Addr = getAddressSpace();
// This function is not supposed to be used with language specific
// address spaces. If that happens, the diagnostic message should consider
// printing the QualType instead of the address space value.
- assert(Addr == 0 || Addr >= LangAS::Count);
+ assert(Addr == 0 || hasTargetSpecificAddressSpace());
if (Addr)
- return Addr - LangAS::Count;
+ return Addr - LangAS::FirstTargetAddressSpace;
// TODO: The diagnostic messages where Addr may be 0 should be fixed
// since it cannot differentiate the situation where 0 denotes the default
// address space or user specified __attribute__((address_space(0))).
@@ -2008,10 +2011,11 @@ public:
Optional<NullabilityKind> getNullability(const ASTContext &context) const;
/// Determine whether the given type can have a nullability
- /// specifier applied to it, i.e., if it is any kind of pointer type
- /// or a dependent type that could instantiate to any kind of
- /// pointer type.
- bool canHaveNullability() const;
+ /// specifier applied to it, i.e., if it is any kind of pointer type.
+ ///
+ /// \param ResultIfUnknown The value to return if we don't yet know whether
+ /// this type can have nullability because it is dependent.
+ bool canHaveNullability(bool ResultIfUnknown = true) const;
/// Retrieve the set of substitutions required when accessing a member
/// of the Objective-C receiver type that is declared in the given context.
diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h
index 0ec5aafd64b6..95b9b9c7d0b3 100644
--- a/include/clang/Basic/AddressSpaces.h
+++ b/include/clang/Basic/AddressSpaces.h
@@ -45,13 +45,12 @@ enum ID {
// This denotes the count of language-specific address spaces and also
// the offset added to the target-specific address spaces, which are usually
// specified by address space attributes __attribute__(address_space(n))).
- Count
+ FirstTargetAddressSpace
};
/// The type of a lookup table which maps from language-specific address spaces
/// to target-specific ones.
-typedef unsigned Map[Count];
-
+typedef unsigned Map[FirstTargetAddressSpace];
}
}
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 4eb958e3f4d5..a885ede8df12 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1179,6 +1179,12 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> {
let Documentation = [MipsInterruptDocs];
}
+def MicroMips : InheritableAttr, TargetSpecificAttr<TargetMips> {
+ let Spellings = [GCC<"micromips">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [MicroMipsDocs];
+}
+
def Mode : Attr {
let Spellings = [GCC<"mode">];
let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag,
@@ -1261,6 +1267,12 @@ def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
let Documentation = [Undocumented];
}
+def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips> {
+ let Spellings = [GCC<"nomicromips">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [MicroMipsDocs];
+}
+
// This is not a TargetSpecificAttr so that is silently accepted and
// ignored on other targets as encouraged by the OpenCL spec.
//
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 9e2fdf4834aa..65dd7445ba26 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -1269,6 +1269,19 @@ The semantics are as follows:
}];
}
+def MicroMipsDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the GNU style ``__attribute__((micromips))`` and
+``__attribute__((nomicromips))`` attributes on MIPS targets. These attributes
+may be attached to a function definition and instructs the backend to generate
+or not to generate microMIPS code for that function.
+
+These attributes override the `-mmicromips` and `-mno-micromips` options
+on the command line.
+ }];
+}
+
def AVRInterruptDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 1db6704f6d1f..463d057d8fd0 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2490,7 +2490,7 @@ def err_attribute_address_multiple_qualifiers : Error<
def err_attribute_address_function_type : Error<
"function type may not be qualified with an address space">;
def err_as_qualified_auto_decl : Error<
- "automatic variable qualified with an address space">;
+ "automatic variable qualified with an%select{| invalid}0 address space">;
def err_arg_with_address_space : Error<
"parameter may not be qualified with an address space">;
def err_field_with_address_space : Error<
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index ceaedf58574f..2513de70e721 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -168,7 +168,7 @@ public:
/// Do we need to track the owning module for a local declaration?
bool trackLocalOwningModule() const {
- return ModulesLocalVisibility;
+ return isCompilingModule() || ModulesLocalVisibility || ModulesTS;
}
bool isSignedOverflowDefined() const {
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index a963c6369aa9..2405f8319c61 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -1133,6 +1133,9 @@ struct FormatStyle {
/// ``Foo <Protocol>`` instead of ``Foo<Protocol>``.
bool ObjCSpaceBeforeProtocolList;
+ /// \brief The penalty for breaking around an assignment operator.
+ unsigned PenaltyBreakAssignment;
+
/// \brief The penalty for breaking a function call after ``call(``.
unsigned PenaltyBreakBeforeFirstCallParameter;
@@ -1420,6 +1423,8 @@ struct FormatStyle {
ObjCBlockIndentWidth == R.ObjCBlockIndentWidth &&
ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
+ PenaltyBreakAssignment ==
+ R.PenaltyBreakAssignment &&
PenaltyBreakBeforeFirstCallParameter ==
R.PenaltyBreakBeforeFirstCallParameter &&
PenaltyBreakComment == R.PenaltyBreakComment &&
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 0fd6abe2f7d0..b6eed23f4d32 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -507,16 +507,6 @@ public:
/// false otherwise.
bool resolveConflicts(Module *Mod, bool Complain);
- /// \brief Infers the (sub)module based on the given source location and
- /// source manager.
- ///
- /// \param Loc The location within the source that we are querying, along
- /// with its source manager.
- ///
- /// \returns The module that owns this source location, or null if no
- /// module owns this source location.
- Module *inferModuleFromLocation(FullSourceLoc Loc);
-
/// \brief Sets the umbrella header of the given module to the given
/// header.
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 114bf70ad59a..9f015eaa230b 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1917,14 +1917,11 @@ public:
/// into a module, or is outside any module, returns nullptr.
Module *getModuleForLocation(SourceLocation Loc);
- /// \brief Find the module that contains the specified location, either
- /// directly or indirectly.
- Module *getModuleContainingLocation(SourceLocation Loc);
-
/// \brief We want to produce a diagnostic at location IncLoc concerning a
/// missing module import.
///
/// \param IncLoc The location at which the missing import was detected.
+ /// \param M The desired module.
/// \param MLoc A location within the desired module at which some desired
/// effect occurred (eg, where a desired entity was declared).
///
@@ -1932,6 +1929,7 @@ public:
/// Null if no such file could be determined or if a #include is not
/// appropriate.
const FileEntry *getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ Module *M,
SourceLocation MLoc);
private:
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index f5a7e02941a7..537796fa6465 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -304,8 +304,9 @@ public:
}
/// ConsumeToken - Consume the current 'peek token' and lex the next one.
- /// This does not work with special tokens: string literals, code completion
- /// and balanced tokens must be handled using the specific consume methods.
+ /// This does not work with special tokens: string literals, code completion,
+ /// annotation tokens and balanced tokens must be handled using the specific
+ /// consume methods.
/// Returns the location of the consumed token.
SourceLocation ConsumeToken() {
assert(!isTokenSpecial() &&
@@ -366,7 +367,7 @@ private:
/// isTokenSpecial - True if this token requires special consumption methods.
bool isTokenSpecial() const {
return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
- isTokenBrace() || Tok.is(tok::code_completion);
+ isTokenBrace() || Tok.is(tok::code_completion) || Tok.isAnnotation();
}
/// \brief Returns true if the current token is '=' or is a type of '='.
@@ -397,9 +398,19 @@ private:
if (Tok.is(tok::code_completion))
return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
: handleUnexpectedCodeCompletionToken();
+ if (Tok.isAnnotation())
+ return ConsumeAnnotationToken();
return ConsumeToken();
}
+ SourceLocation ConsumeAnnotationToken() {
+ assert(Tok.isAnnotation() && "wrong consume method");
+ SourceLocation Loc = Tok.getLocation();
+ PrevTokLocation = Tok.getAnnotationEndLoc();
+ PP.Lex(Tok);
+ return Loc;
+ }
+
/// ConsumeParen - This consume method keeps the paren count up-to-date.
///
SourceLocation ConsumeParen() {
@@ -1449,6 +1460,7 @@ public:
};
ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
+ ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast);
ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast);
ExprResult ParseConstraintExpression();
// Expr that doesn't include commas.
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index df5e1050367e..bc817150ab82 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -1999,41 +1999,6 @@ public:
llvm_unreachable("unknown context kind!");
}
- /// diagnoseIdentifier - Return true if the identifier is prohibited and
- /// should be diagnosed (because it cannot be anything else).
- bool diagnoseIdentifier() const {
- switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case InitStmtContext:
- case ConditionContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case TemplateParamContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case TypeNameContext:
- case FunctionalCastContext:
- case ConversionIdContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case BlockLiteralContext:
- case CXXNewContext:
- case LambdaExprContext:
- return false;
-
- case AliasDeclContext:
- case AliasTemplateContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
- return true;
- }
- llvm_unreachable("unknown context kind!");
- }
-
/// Return true if the context permits a C++17 decomposition declarator.
bool mayHaveDecompositionDeclarator() const {
switch (Context) {
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index ba2da92c5be1..fcd3ee714fae 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1507,6 +1507,12 @@ public:
hasVisibleDefaultArgument(const NamedDecl *D,
llvm::SmallVectorImpl<Module *> *Modules = nullptr);
+ /// Determine if there is a visible declaration of \p D that is an explicit
+ /// specialization declaration for a specialization of a template. (For a
+ /// member specialization, use hasVisibleMemberSpecialization.)
+ bool hasVisibleExplicitSpecialization(
+ const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
+
/// Determine if there is a visible declaration of \p D that is a member
/// specialization declaration (as opposed to an instantiated declaration).
bool hasVisibleMemberSpecialization(
@@ -2360,7 +2366,7 @@ public:
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn);
- void notePreviousDefinition(SourceLocation Old, SourceLocation New);
+ void notePreviousDefinition(const NamedDecl *Old, SourceLocation New);
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
// AssignmentAction - This is used by all the assignment diagnostic functions
@@ -7377,9 +7383,9 @@ public:
/// but have not yet been performed.
std::deque<PendingImplicitInstantiation> PendingInstantiations;
- class SavePendingInstantiationsAndVTableUsesRAII {
+ class GlobalEagerInstantiationScope {
public:
- SavePendingInstantiationsAndVTableUsesRAII(Sema &S, bool Enabled)
+ GlobalEagerInstantiationScope(Sema &S, bool Enabled)
: S(S), Enabled(Enabled) {
if (!Enabled) return;
@@ -7387,7 +7393,14 @@ public:
SavedVTableUses.swap(S.VTableUses);
}
- ~SavePendingInstantiationsAndVTableUsesRAII() {
+ void perform() {
+ if (Enabled) {
+ S.DefineUsedVTables();
+ S.PerformPendingInstantiations();
+ }
+ }
+
+ ~GlobalEagerInstantiationScope() {
if (!Enabled) return;
// Restore the set of pending vtables.
@@ -7417,14 +7430,16 @@ public:
/// types, static variables, enumerators, etc.
std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
- class SavePendingLocalImplicitInstantiationsRAII {
+ class LocalEagerInstantiationScope {
public:
- SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) {
+ LocalEagerInstantiationScope(Sema &S) : S(S) {
SavedPendingLocalImplicitInstantiations.swap(
S.PendingLocalImplicitInstantiations);
}
- ~SavePendingLocalImplicitInstantiationsRAII() {
+ void perform() { S.PerformPendingInstantiations(/*LocalOnly=*/true); }
+
+ ~LocalEagerInstantiationScope() {
assert(S.PendingLocalImplicitInstantiations.empty() &&
"there shouldn't be any pending local implicit instantiations");
SavedPendingLocalImplicitInstantiations.swap(
@@ -7434,7 +7449,7 @@ public:
private:
Sema &S;
std::deque<PendingImplicitInstantiation>
- SavedPendingLocalImplicitInstantiations;
+ SavedPendingLocalImplicitInstantiations;
};
/// A helper class for building up ExtParameterInfos.
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 63ccb2461616..737f6fb3d413 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -478,10 +478,18 @@ private:
/// in the chain.
DeclUpdateOffsetsMap DeclUpdateOffsets;
+ struct PendingUpdateRecord {
+ Decl *D;
+ serialization::GlobalDeclID ID;
+ // Whether the declaration was just deserialized.
+ bool JustLoaded;
+ PendingUpdateRecord(serialization::GlobalDeclID ID, Decl *D,
+ bool JustLoaded)
+ : D(D), ID(ID), JustLoaded(JustLoaded) {}
+ };
/// \brief Declaration updates for already-loaded declarations that we need
/// to apply once we finish processing an import.
- llvm::SmallVector<std::pair<serialization::GlobalDeclID, Decl*>, 16>
- PendingUpdateRecords;
+ llvm::SmallVector<PendingUpdateRecord, 16> PendingUpdateRecords;
enum class PendingFakeDefinitionKind { NotFake, Fake, FakeLoaded };
@@ -1279,7 +1287,7 @@ private:
RecordLocation DeclCursorForID(serialization::DeclID ID,
SourceLocation &Location);
- void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D);
+ void loadDeclUpdateRecords(PendingUpdateRecord &Record);
void loadPendingDeclChain(Decl *D, uint64_t LocalOffset);
void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D,
unsigned PreviousGeneration = 0);
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 17cf726e4d6b..f14dfc73baa9 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -627,10 +627,6 @@ public:
/// \brief Add a version tuple to the given record
void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
- /// \brief Infer the submodule ID that contains an entity at the given
- /// source location.
- serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
-
/// \brief Retrieve or create a submodule ID for this module, or return 0 if
/// the submodule is neither local (a submodle of the currently-written module)
/// nor from an imported module.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 3b526a23edd9..29d970e66d71 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -8730,8 +8730,8 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
char *End;
unsigned AddrSpace = strtoul(Str, &End, 10);
if (End != Str && AddrSpace != 0) {
- Type = Context.getAddrSpaceQualType(Type, AddrSpace +
- LangAS::Count);
+ Type = Context.getAddrSpaceQualType(
+ Type, AddrSpace + LangAS::FirstTargetAddressSpace);
Str = End;
}
if (c == '*')
@@ -9546,13 +9546,8 @@ uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const {
}
unsigned ASTContext::getTargetAddressSpace(unsigned AS) const {
- // For OpenCL, only function local variables are not explicitly marked with
- // an address space in the AST, and these need to be the address space of
- // alloca.
- if (!AS && LangOpts.OpenCL)
- return getTargetInfo().getDataLayout().getAllocaAddrSpace();
- if (AS >= LangAS::Count)
- return AS - LangAS::Count;
+ if (AS >= LangAS::FirstTargetAddressSpace)
+ return AS - LangAS::FirstTargetAddressSpace;
else
return (*AddrSpaceMap)[AS];
}
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 746602d47be5..fc4d8b137337 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -57,6 +57,7 @@ bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
void CXXBasePaths::clear() {
Paths.clear();
ClassSubobjects.clear();
+ VisitedDependentRecords.clear();
ScratchPath.clear();
DetectedVirtual = nullptr;
}
@@ -67,6 +68,7 @@ void CXXBasePaths::swap(CXXBasePaths &Other) {
std::swap(Origin, Other.Origin);
Paths.swap(Other.Paths);
ClassSubobjects.swap(Other.ClassSubobjects);
+ VisitedDependentRecords.swap(Other.VisitedDependentRecords);
std::swap(FindAmbiguities, Other.FindAmbiguities);
std::swap(RecordPaths, Other.RecordPaths);
std::swap(DetectVirtual, Other.DetectVirtual);
@@ -278,8 +280,14 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()))
BaseRecord = TD->getTemplatedDecl();
}
- if (BaseRecord && !BaseRecord->hasDefinition())
- BaseRecord = nullptr;
+ if (BaseRecord) {
+ if (!BaseRecord->hasDefinition() ||
+ VisitedDependentRecords.count(BaseRecord)) {
+ BaseRecord = nullptr;
+ } else {
+ VisitedDependentRecords.insert(BaseRecord);
+ }
+ }
} else {
BaseRecord = cast<CXXRecordDecl>(
BaseSpec.getType()->castAs<RecordType>()->getDecl());
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index f6f81692611d..81cd1cc42658 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -407,6 +407,27 @@ bool Decl::isExported() const {
return false;
}
+ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
+ const Decl *Definition = nullptr;
+ if (auto ID = dyn_cast<ObjCInterfaceDecl>(this)) {
+ Definition = ID->getDefinition();
+ } else if (auto PD = dyn_cast<ObjCProtocolDecl>(this)) {
+ Definition = PD->getDefinition();
+ } else if (auto TD = dyn_cast<TagDecl>(this)) {
+ Definition = TD->getDefinition();
+ }
+ if (!Definition)
+ Definition = this;
+
+ if (auto *attr = Definition->getAttr<ExternalSourceSymbolAttr>())
+ return attr;
+ if (auto *dcd = dyn_cast<Decl>(getDeclContext())) {
+ return dcd->getAttr<ExternalSourceSymbolAttr>();
+ }
+
+ return nullptr;
+}
+
bool Decl::hasDefiningAttr() const {
return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
}
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 75bb0cac51b8..bd8b3abd9275 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -4579,7 +4579,7 @@ public:
}
bool handleCallExpr(const CallExpr *E, APValue &Result,
- const LValue *ResultSlot) {
+ const LValue *ResultSlot) {
const Expr *Callee = E->getCallee()->IgnoreParens();
QualType CalleeType = Callee->getType();
@@ -4588,6 +4588,23 @@ public:
auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs());
bool HasQualifier = false;
+ struct EvaluateIgnoredRAII {
+ public:
+ EvaluateIgnoredRAII(EvalInfo &Info, llvm::ArrayRef<const Expr*> ToEval)
+ : Info(Info), ToEval(ToEval) {}
+ ~EvaluateIgnoredRAII() {
+ if (Info.noteFailure()) {
+ for (auto E : ToEval)
+ EvaluateIgnoredValue(Info, E);
+ }
+ }
+ void cancel() { ToEval = {}; }
+ void drop_front() { ToEval = ToEval.drop_front(); }
+ private:
+ EvalInfo &Info;
+ llvm::ArrayRef<const Expr*> ToEval;
+ } EvalArguments(Info, Args);
+
// Extract function decl and 'this' pointer from the callee.
if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
const ValueDecl *Member = nullptr;
@@ -4637,10 +4654,12 @@ public:
if (Args.empty())
return Error(E);
- if (!EvaluateObjectArgument(Info, Args[0], ThisVal))
+ const Expr *FirstArg = Args[0];
+ Args = Args.drop_front();
+ EvalArguments.drop_front();
+ if (!EvaluateObjectArgument(Info, FirstArg, ThisVal))
return false;
This = &ThisVal;
- Args = Args.slice(1);
} else if (MD && MD->isLambdaStaticInvoker()) {
// Map the static invoker for the lambda back to the call operator.
// Conveniently, we don't have to slice out the 'this' argument (as is
@@ -4692,8 +4711,12 @@ public:
const FunctionDecl *Definition = nullptr;
Stmt *Body = FD->getBody(Definition);
- if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) ||
- !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info,
+ if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body))
+ return false;
+
+ EvalArguments.cancel();
+
+ if (!HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info,
Result, ResultSlot))
return false;
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 22d52bcd3f31..1e10094aeeea 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -3531,7 +3531,7 @@ Optional<NullabilityKind> Type::getNullability(const ASTContext &context) const
} while (true);
}
-bool Type::canHaveNullability() const {
+bool Type::canHaveNullability(bool ResultIfUnknown) const {
QualType type = getCanonicalTypeInternal();
switch (type->getTypeClass()) {
@@ -3559,7 +3559,8 @@ bool Type::canHaveNullability() const {
case Type::SubstTemplateTypeParmPack:
case Type::DependentName:
case Type::DependentTemplateSpecialization:
- return true;
+ case Type::Auto:
+ return ResultIfUnknown;
// Dependent template specializations can instantiate to pointer
// types unless they're known to be specializations of a class
@@ -3571,12 +3572,7 @@ bool Type::canHaveNullability() const {
if (isa<ClassTemplateDecl>(templateDecl))
return false;
}
- return true;
-
- // auto is considered dependent when it isn't deduced.
- case Type::Auto:
- case Type::DeducedTemplateSpecialization:
- return !cast<DeducedType>(type.getTypePtr())->isDeduced();
+ return ResultIfUnknown;
case Type::Builtin:
switch (cast<BuiltinType>(type.getTypePtr())->getKind()) {
@@ -3595,7 +3591,7 @@ bool Type::canHaveNullability() const {
case BuiltinType::PseudoObject:
case BuiltinType::UnknownAny:
case BuiltinType::ARCUnbridgedCast:
- return true;
+ return ResultIfUnknown;
case BuiltinType::Void:
case BuiltinType::ObjCId:
@@ -3614,6 +3610,7 @@ bool Type::canHaveNullability() const {
case BuiltinType::OMPArraySection:
return false;
}
+ llvm_unreachable("unknown builtin type");
// Non-pointer types.
case Type::Complex:
@@ -3629,6 +3626,7 @@ bool Type::canHaveNullability() const {
case Type::FunctionProto:
case Type::FunctionNoProto:
case Type::Record:
+ case Type::DeducedTemplateSpecialization:
case Type::Enum:
case Type::InjectedClassName:
case Type::PackExpansion:
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 2be14ab62123..0551340c37a1 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -1668,9 +1668,9 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
OS << "__shared";
break;
default:
- assert(addrspace >= LangAS::Count);
+ assert(addrspace >= LangAS::FirstTargetAddressSpace);
OS << "__attribute__((address_space(";
- OS << addrspace - LangAS::Count;
+ OS << addrspace - LangAS::FirstTargetAddressSpace;
OS << ")))";
}
}
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 92c561aa9413..1b9fbed17731 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -2034,25 +2034,45 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
return llvm::makeArrayRef(GCCRegNames);
}
-static const LangAS::Map AMDGPUPrivateIsZeroMap = {
- 4, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 4, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
+static const LangAS::Map AMDGPUNonOpenCLPrivateIsZeroMap = {
+ 4, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 4, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
+};
+static const LangAS::Map AMDGPUNonOpenCLGenericIsZeroMap = {
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
};
-static const LangAS::Map AMDGPUGenericIsZeroMap = {
- 0, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 0, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
+static const LangAS::Map AMDGPUOpenCLPrivateIsZeroMap = {
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 4, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
+};
+static const LangAS::Map AMDGPUOpenCLGenericIsZeroMap = {
+ 5, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_generic
+ 1, // cuda_device
+ 2, // cuda_constant
+ 3 // cuda_shared
};
// If you edit the description strings, make sure you update
@@ -2149,8 +2169,12 @@ public:
: DataLayoutStringR600);
assert(DataLayout->getAllocaAddrSpace() == AS.Private);
- AddrSpaceMap = IsGenericZero ? &AMDGPUGenericIsZeroMap :
- &AMDGPUPrivateIsZeroMap;
+ AddrSpaceMap =
+ llvm::StringSwitch<const LangAS::Map *>(Triple.getEnvironmentName())
+ .Case("opencl", &AMDGPUOpenCLPrivateIsZeroMap)
+ .Case("amdgiz", &AMDGPUNonOpenCLGenericIsZeroMap)
+ .Case("amdgizcl", &AMDGPUOpenCLGenericIsZeroMap)
+ .Default(&AMDGPUNonOpenCLPrivateIsZeroMap);
UseAddrSpaceMapMangling = true;
}
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index 28e20b53d656..a6e6fec206d5 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -95,7 +95,7 @@ namespace {
BFI.StorageOffset += OffsetInChars;
LVal = LValue::MakeBitfield(Address(Addr, lvalue.getAlignment()),
BFI, lvalue.getType(),
- lvalue.getAlignmentSource());
+ lvalue.getBaseInfo());
LVal.setTBAAInfo(lvalue.getTBAAInfo());
AtomicTy = C.getIntTypeForBitwidth(AtomicSizeInBits, OrigBFI.IsSigned);
if (AtomicTy.isNull()) {
@@ -203,7 +203,7 @@ namespace {
addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits());
return LValue::MakeAddr(addr, getValueType(), CGF.getContext(),
- LVal.getAlignmentSource(), LVal.getTBAAInfo());
+ LVal.getBaseInfo(), LVal.getTBAAInfo());
}
/// \brief Emits atomic load.
@@ -1181,15 +1181,15 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr,
if (LVal.isBitField())
return CGF.EmitLoadOfBitfieldLValue(
LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(),
- LVal.getAlignmentSource()), loc);
+ LVal.getBaseInfo()), loc);
if (LVal.isVectorElt())
return CGF.EmitLoadOfLValue(
LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(),
- LVal.getAlignmentSource()), loc);
+ LVal.getBaseInfo()), loc);
assert(LVal.isExtVectorElt());
return CGF.EmitLoadOfExtVectorElementLValue(LValue::MakeExtVectorElt(
addr, LVal.getExtVectorElts(), LVal.getType(),
- LVal.getAlignmentSource()));
+ LVal.getBaseInfo()));
}
RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal,
@@ -1506,26 +1506,26 @@ EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, RValue OldRVal,
UpdateLVal =
LValue::MakeBitfield(Ptr, AtomicLVal.getBitFieldInfo(),
AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
DesiredLVal =
LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(),
AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
} else if (AtomicLVal.isVectorElt()) {
UpdateLVal = LValue::MakeVectorElt(Ptr, AtomicLVal.getVectorIdx(),
AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
DesiredLVal = LValue::MakeVectorElt(
DesiredAddr, AtomicLVal.getVectorIdx(), AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
} else {
assert(AtomicLVal.isExtVectorElt());
UpdateLVal = LValue::MakeExtVectorElt(Ptr, AtomicLVal.getExtVectorElts(),
AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
DesiredLVal = LValue::MakeExtVectorElt(
DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
}
UpdateLVal.setTBAAInfo(AtomicLVal.getTBAAInfo());
DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo());
@@ -1612,17 +1612,17 @@ static void EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics,
DesiredLVal =
LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(),
AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
} else if (AtomicLVal.isVectorElt()) {
DesiredLVal =
LValue::MakeVectorElt(DesiredAddr, AtomicLVal.getVectorIdx(),
AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
} else {
assert(AtomicLVal.isExtVectorElt());
DesiredLVal = LValue::MakeExtVectorElt(
DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(),
- AtomicLVal.getAlignmentSource());
+ AtomicLVal.getBaseInfo());
}
DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo());
// Store new value in the corresponding memory area
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index f1c20e9df1f3..2e423b25f0fb 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -918,8 +918,9 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// FIXME: Pass a specific location for the expr init so that the store is
// attributed to a reasonable location - otherwise it may be attributed to
// locations of subexpressions in the initialization.
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
EmitExprAsInit(&l2r, &blockFieldPseudoVar,
- MakeAddrLValue(blockField, type, AlignmentSource::Decl),
+ MakeAddrLValue(blockField, type, BaseInfo),
/*captured by init*/ false);
}
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 50c9e22801c7..e2d5f8f870de 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -8842,9 +8842,8 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
auto MakeLdg = [&](unsigned IntrinsicID) {
Value *Ptr = EmitScalarExpr(E->getArg(0));
- AlignmentSource AlignSource;
clang::CharUnits Align =
- getNaturalPointeeTypeAlignment(E->getArg(0)->getType(), &AlignSource);
+ getNaturalPointeeTypeAlignment(E->getArg(0)->getType());
return Builder.CreateCall(
CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
Ptr->getType()}),
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 7ba03a0d42dd..5b4dc5ff0ab3 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -129,14 +129,14 @@ Address
CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
llvm::Value *memberPtr,
const MemberPointerType *memberPtrType,
- AlignmentSource *alignSource) {
+ LValueBaseInfo *BaseInfo) {
// Ask the ABI to compute the actual address.
llvm::Value *ptr =
CGM.getCXXABI().EmitMemberDataPointerAddress(*this, E, base,
memberPtr, memberPtrType);
QualType memberType = memberPtrType->getPointeeType();
- CharUnits memberAlign = getNaturalTypeAlignment(memberType, alignSource);
+ CharUnits memberAlign = getNaturalTypeAlignment(memberType, BaseInfo);
memberAlign =
CGM.getDynamicOffsetAlignment(base.getAlignment(),
memberPtrType->getClass()->getAsCXXRecordDecl(),
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index bf178dd7fd80..0a1dc09211c2 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -2613,7 +2613,7 @@ llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) {
// best to make this behavior a command line or debugger tuning
// option.
FullSourceLoc Loc(D->getLocation(), CGM.getContext().getSourceManager());
- if (Module *M = ClangModuleMap->inferModuleFromLocation(Loc)) {
+ if (Module *M = D->getOwningModule()) {
// This is a (sub-)module.
auto Info = ExternalASTSource::ASTSourceDescriptor(*M);
return getOrCreateModuleRef(Info, /*SkeletonCU=*/false);
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 0fa8eeb1c3e1..d6abfa15e541 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -11,14 +11,15 @@
//
//===----------------------------------------------------------------------===//
-#include "CodeGenFunction.h"
#include "CGBlocks.h"
#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGDebugInfo.h"
#include "CGOpenCLRuntime.h"
#include "CGOpenMPRuntime.h"
+#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
@@ -1105,6 +1106,21 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
address = Address(vla, alignment);
}
+ // Alloca always returns a pointer in alloca address space, which may
+ // be different from the type defined by the language. For example,
+ // in C++ the auto variables are in the default address space. Therefore
+ // cast alloca to the expected address space when necessary.
+ auto T = D.getType();
+ assert(T.getAddressSpace() == LangAS::Default);
+ if (getASTAllocaAddressSpace() != LangAS::Default) {
+ auto *Addr = getTargetHooks().performAddrSpaceCast(
+ *this, address.getPointer(), getASTAllocaAddressSpace(),
+ T.getAddressSpace(),
+ address.getElementType()->getPointerTo(
+ getContext().getTargetAddressSpace(T.getAddressSpace())),
+ /*non-null*/ true);
+ address = Address(Addr, address.getAlignment());
+ }
setAddrOfLocalVar(&D, address);
emission.Addr = address;
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index cef6292c0e4d..a6d5dd85c234 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -374,12 +374,14 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
// dynamic initialization or a cleanup and we can just return the address
// of the temporary.
if (Var->hasInitializer())
- return MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl);
+ return MakeAddrLValue(Object, M->getType(),
+ LValueBaseInfo(AlignmentSource::Decl, false));
Var->setInitializer(CGM.EmitNullConstant(E->getType()));
}
LValue RefTempDst = MakeAddrLValue(Object, M->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl,
+ false));
switch (getEvaluationKind(E->getType())) {
default: llvm_unreachable("expected scalar or aggregate expression");
@@ -465,7 +467,7 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
case SubobjectAdjustment::FieldAdjustment: {
LValue LV = MakeAddrLValue(Object, E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
LV = EmitLValueForField(LV, Adjustment.Field);
assert(LV.isSimple() &&
"materialized temporary field is not a simple lvalue");
@@ -482,7 +484,8 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
}
}
- return MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl);
+ return MakeAddrLValue(Object, M->getType(),
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
RValue
@@ -847,7 +850,7 @@ void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E,
/// EmitPointerWithAlignment - Given an expression of pointer type, try to
/// derive a more accurate bound on the alignment of the pointer.
Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
- AlignmentSource *Source) {
+ LValueBaseInfo *BaseInfo) {
// We allow this with ObjC object pointers because of fragile ABIs.
assert(E->getType()->isPointerType() ||
E->getType()->isObjCObjectPointerType());
@@ -866,16 +869,20 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
if (PtrTy->getPointeeType()->isVoidType())
break;
- AlignmentSource InnerSource;
- Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), &InnerSource);
- if (Source) *Source = InnerSource;
+ LValueBaseInfo InnerInfo;
+ Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), &InnerInfo);
+ if (BaseInfo) *BaseInfo = InnerInfo;
// If this is an explicit bitcast, and the source l-value is
// opaque, honor the alignment of the casted-to type.
if (isa<ExplicitCastExpr>(CE) &&
- InnerSource != AlignmentSource::Decl) {
- Addr = Address(Addr.getPointer(),
- getNaturalPointeeTypeAlignment(E->getType(), Source));
+ InnerInfo.getAlignmentSource() != AlignmentSource::Decl) {
+ LValueBaseInfo ExpInfo;
+ CharUnits Align = getNaturalPointeeTypeAlignment(E->getType(),
+ &ExpInfo);
+ if (BaseInfo)
+ BaseInfo->mergeForCast(ExpInfo);
+ Addr = Address(Addr.getPointer(), Align);
}
if (SanOpts.has(SanitizerKind::CFIUnrelatedCast) &&
@@ -893,12 +900,12 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
// Array-to-pointer decay.
case CK_ArrayToPointerDecay:
- return EmitArrayToPointerDecay(CE->getSubExpr(), Source);
+ return EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo);
// Derived-to-base conversions.
case CK_UncheckedDerivedToBase:
case CK_DerivedToBase: {
- Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), Source);
+ Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo);
auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl();
return GetAddressOfBaseClass(Addr, Derived,
CE->path_begin(), CE->path_end(),
@@ -917,7 +924,7 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
if (UO->getOpcode() == UO_AddrOf) {
LValue LV = EmitLValue(UO->getSubExpr());
- if (Source) *Source = LV.getAlignmentSource();
+ if (BaseInfo) *BaseInfo = LV.getBaseInfo();
return LV.getAddress();
}
}
@@ -925,7 +932,7 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
// TODO: conditional operators, comma.
// Otherwise, use the alignment of the type.
- CharUnits Align = getNaturalPointeeTypeAlignment(E->getType(), Source);
+ CharUnits Align = getNaturalPointeeTypeAlignment(E->getType(), BaseInfo);
return Address(EmitScalarExpr(E), Align);
}
@@ -1094,7 +1101,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
llvm::Value *V = LV.getPointer();
Scope.ForceCleanup({&V});
return LValue::MakeAddr(Address(V, LV.getAlignment()), LV.getType(),
- getContext(), LV.getAlignmentSource(),
+ getContext(), LV.getBaseInfo(),
LV.getTBAAInfo());
}
// FIXME: Is it possible to create an ExprWithCleanups that produces a
@@ -1269,7 +1276,7 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue,
SourceLocation Loc) {
return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
- lvalue.getType(), Loc, lvalue.getAlignmentSource(),
+ lvalue.getType(), Loc, lvalue.getBaseInfo(),
lvalue.getTBAAInfo(),
lvalue.getTBAABaseType(), lvalue.getTBAAOffset(),
lvalue.isNontemporal());
@@ -1381,7 +1388,7 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
QualType Ty,
SourceLocation Loc,
- AlignmentSource AlignSource,
+ LValueBaseInfo BaseInfo,
llvm::MDNode *TBAAInfo,
QualType TBAABaseType,
uint64_t TBAAOffset,
@@ -1413,7 +1420,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
// Atomic operations have to be done on integral types.
LValue AtomicLValue =
- LValue::MakeAddr(Addr, Ty, getContext(), AlignSource, TBAAInfo);
+ LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo);
if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) {
return EmitAtomicLoad(AtomicLValue, Loc).getScalarVal();
}
@@ -1469,7 +1476,7 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
bool Volatile, QualType Ty,
- AlignmentSource AlignSource,
+ LValueBaseInfo BaseInfo,
llvm::MDNode *TBAAInfo,
bool isInit, QualType TBAABaseType,
uint64_t TBAAOffset,
@@ -1500,7 +1507,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
Value = EmitToMemory(Value, Ty);
LValue AtomicLValue =
- LValue::MakeAddr(Addr, Ty, getContext(), AlignSource, TBAAInfo);
+ LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo);
if (Ty->isAtomicType() ||
(!isInit && LValueIsSuitableForInlineAtomic(AtomicLValue))) {
EmitAtomicStore(RValue::get(Value), AtomicLValue, isInit);
@@ -1526,7 +1533,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
bool isInit) {
EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
- lvalue.getType(), lvalue.getAlignmentSource(),
+ lvalue.getType(), lvalue.getBaseInfo(),
lvalue.getTBAAInfo(), isInit, lvalue.getTBAABaseType(),
lvalue.getTBAAOffset(), lvalue.isNontemporal());
}
@@ -2058,38 +2065,39 @@ static LValue EmitThreadPrivateVarDeclLValue(
llvm::Type *RealVarTy, SourceLocation Loc) {
Addr = CGF.CGM.getOpenMPRuntime().getAddrOfThreadPrivate(CGF, VD, Addr, Loc);
Addr = CGF.Builder.CreateElementBitCast(Addr, RealVarTy);
- return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
+ return CGF.MakeAddrLValue(Addr, T, BaseInfo);
}
Address CodeGenFunction::EmitLoadOfReference(Address Addr,
const ReferenceType *RefTy,
- AlignmentSource *Source) {
+ LValueBaseInfo *BaseInfo) {
llvm::Value *Ptr = Builder.CreateLoad(Addr);
return Address(Ptr, getNaturalTypeAlignment(RefTy->getPointeeType(),
- Source, /*forPointee*/ true));
-
+ BaseInfo, /*forPointee*/ true));
}
LValue CodeGenFunction::EmitLoadOfReferenceLValue(Address RefAddr,
const ReferenceType *RefTy) {
- AlignmentSource Source;
- Address Addr = EmitLoadOfReference(RefAddr, RefTy, &Source);
- return MakeAddrLValue(Addr, RefTy->getPointeeType(), Source);
+ LValueBaseInfo BaseInfo;
+ Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo);
+ return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo);
}
Address CodeGenFunction::EmitLoadOfPointer(Address Ptr,
const PointerType *PtrTy,
- AlignmentSource *Source) {
+ LValueBaseInfo *BaseInfo) {
llvm::Value *Addr = Builder.CreateLoad(Ptr);
- return Address(Addr, getNaturalTypeAlignment(PtrTy->getPointeeType(), Source,
+ return Address(Addr, getNaturalTypeAlignment(PtrTy->getPointeeType(),
+ BaseInfo,
/*forPointeeType=*/true));
}
LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr,
const PointerType *PtrTy) {
- AlignmentSource Source;
- Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &Source);
- return MakeAddrLValue(Addr, PtrTy->getPointeeType(), Source);
+ LValueBaseInfo BaseInfo;
+ Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &BaseInfo);
+ return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo);
}
static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
@@ -2115,7 +2123,8 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
if (auto RefTy = VD->getType()->getAs<ReferenceType>()) {
LV = CGF.EmitLoadOfReferenceLValue(Addr, RefTy);
} else {
- LV = CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
+ LV = CGF.MakeAddrLValue(Addr, T, BaseInfo);
}
setObjCGCLValueClass(CGF.getContext(), E, LV);
return LV;
@@ -2149,7 +2158,8 @@ static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
const Expr *E, const FunctionDecl *FD) {
llvm::Value *V = EmitFunctionDeclPointer(CGF.CGM, FD);
CharUnits Alignment = CGF.getContext().getDeclAlign(FD);
- return CGF.MakeAddrLValue(V, E->getType(), Alignment, AlignmentSource::Decl);
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
+ return CGF.MakeAddrLValue(V, E->getType(), Alignment, BaseInfo);
}
static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD,
@@ -2214,8 +2224,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// Should we be using the alignment of the constant pointer we emitted?
CharUnits Alignment = getNaturalTypeAlignment(E->getType(), nullptr,
/*pointee*/ true);
-
- return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl);
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
+ return MakeAddrLValue(Address(Val, Alignment), T, BaseInfo);
}
// Check for captured variables.
@@ -2232,14 +2242,16 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
LValue CapLVal =
EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD),
CapturedStmtInfo->getContextValue());
+ bool MayAlias = CapLVal.getBaseInfo().getMayAlias();
return MakeAddrLValue(
Address(CapLVal.getPointer(), getContext().getDeclAlign(VD)),
- CapLVal.getType(), AlignmentSource::Decl);
+ CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl, MayAlias));
}
assert(isa<BlockDecl>(CurCodeDecl));
Address addr = GetAddrOfBlockDecl(VD, VD->hasAttr<BlocksAttr>());
- return MakeAddrLValue(addr, T, AlignmentSource::Decl);
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
+ return MakeAddrLValue(addr, T, BaseInfo);
}
}
@@ -2253,7 +2265,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
if (ND->hasAttr<WeakRefAttr>()) {
const auto *VD = cast<ValueDecl>(ND);
ConstantAddress Aliasee = CGM.GetWeakRefReference(VD);
- return MakeAddrLValue(Aliasee, T, AlignmentSource::Decl);
+ return MakeAddrLValue(Aliasee, T,
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
if (const auto *VD = dyn_cast<VarDecl>(ND)) {
@@ -2299,7 +2312,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
if (auto RefTy = VD->getType()->getAs<ReferenceType>()) {
LV = EmitLoadOfReferenceLValue(addr, RefTy);
} else {
- LV = MakeAddrLValue(addr, T, AlignmentSource::Decl);
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
+ LV = MakeAddrLValue(addr, T, BaseInfo);
}
bool isLocalStorage = VD->hasLocalStorage();
@@ -2344,9 +2358,9 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
QualType T = E->getSubExpr()->getType()->getPointeeType();
assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
- AlignmentSource AlignSource;
- Address Addr = EmitPointerWithAlignment(E->getSubExpr(), &AlignSource);
- LValue LV = MakeAddrLValue(Addr, T, AlignSource);
+ LValueBaseInfo BaseInfo;
+ Address Addr = EmitPointerWithAlignment(E->getSubExpr(), &BaseInfo);
+ LValue LV = MakeAddrLValue(Addr, T, BaseInfo);
LV.getQuals().setAddressSpace(ExprTy.getAddressSpace());
// We should not generate __weak write barrier on indirect reference
@@ -2378,7 +2392,7 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
(E->getOpcode() == UO_Real
? emitAddrOfRealComponent(LV.getAddress(), LV.getType())
: emitAddrOfImagComponent(LV.getAddress(), LV.getType()));
- LValue ElemLV = MakeAddrLValue(Component, T, LV.getAlignmentSource());
+ LValue ElemLV = MakeAddrLValue(Component, T, LV.getBaseInfo());
ElemLV.getQuals().addQualifiers(LV.getQuals());
return ElemLV;
}
@@ -2398,12 +2412,14 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
return MakeAddrLValue(CGM.GetAddrOfConstantStringFromLiteral(E),
- E->getType(), AlignmentSource::Decl);
+ E->getType(),
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
return MakeAddrLValue(CGM.GetAddrOfConstantStringFromObjCEncode(E),
- E->getType(), AlignmentSource::Decl);
+ E->getType(),
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
@@ -2415,6 +2431,7 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
StringRef NameItems[] = {
PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName};
std::string GVName = llvm::join(NameItems, NameItems + 2, ".");
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
if (auto *BD = dyn_cast<BlockDecl>(CurCodeDecl)) {
std::string Name = SL->getString();
if (!Name.empty()) {
@@ -2423,14 +2440,14 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
if (Discriminator)
Name += "_" + Twine(Discriminator + 1).str();
auto C = CGM.GetAddrOfConstantCString(Name, GVName.c_str());
- return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl);
+ return MakeAddrLValue(C, E->getType(), BaseInfo);
} else {
auto C = CGM.GetAddrOfConstantCString(FnName, GVName.c_str());
- return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl);
+ return MakeAddrLValue(C, E->getType(), BaseInfo);
}
}
auto C = CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
- return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl);
+ return MakeAddrLValue(C, E->getType(), BaseInfo);
}
/// Emit a type description suitable for use by a runtime sanitizer library. The
@@ -2937,14 +2954,14 @@ llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
}
Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E,
- AlignmentSource *AlignSource) {
+ LValueBaseInfo *BaseInfo) {
assert(E->getType()->isArrayType() &&
"Array to pointer decay must have array source type!");
// Expressions of array type can't be bitfields or vector elements.
LValue LV = EmitLValue(E);
Address Addr = LV.getAddress();
- if (AlignSource) *AlignSource = LV.getAlignmentSource();
+ if (BaseInfo) *BaseInfo = LV.getBaseInfo();
// If the array type was an incomplete type, we need to make sure
// the decay ends up being the right type.
@@ -3079,7 +3096,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
return LValue::MakeVectorElt(LHS.getAddress(), Idx,
E->getBase()->getType(),
- LHS.getAlignmentSource());
+ LHS.getBaseInfo());
}
// All the other cases basically behave like simple offsetting.
@@ -3092,17 +3109,17 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
QualType EltType = LV.getType()->castAs<VectorType>()->getElementType();
Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true);
- return MakeAddrLValue(Addr, EltType, LV.getAlignmentSource());
+ return MakeAddrLValue(Addr, EltType, LV.getBaseInfo());
}
- AlignmentSource AlignSource;
+ LValueBaseInfo BaseInfo;
Address Addr = Address::invalid();
if (const VariableArrayType *vla =
getContext().getAsVariableArrayType(E->getType())) {
// The base must be a pointer, which is not an aggregate. Emit
// it. It needs to be emitted first in case it's what captures
// the VLA bounds.
- Addr = EmitPointerWithAlignment(E->getBase(), &AlignSource);
+ Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo);
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
// The element count here is the total number of non-VLA elements.
@@ -3125,7 +3142,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
// Indexing over an interface, as in "NSString *P; P[4];"
// Emit the base pointer.
- Addr = EmitPointerWithAlignment(E->getBase(), &AlignSource);
+ Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo);
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
CharUnits InterfaceSize = getContext().getTypeSizeInChars(OIT);
@@ -3171,16 +3188,16 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
{CGM.getSize(CharUnits::Zero()), Idx},
E->getType(),
!getLangOpts().isSignedOverflowDefined());
- AlignSource = ArrayLV.getAlignmentSource();
+ BaseInfo = ArrayLV.getBaseInfo();
} else {
// The base must be a pointer; emit it with an estimate of its alignment.
- Addr = EmitPointerWithAlignment(E->getBase(), &AlignSource);
+ Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo);
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
!getLangOpts().isSignedOverflowDefined());
}
- LValue LV = MakeAddrLValue(Addr, E->getType(), AlignSource);
+ LValue LV = MakeAddrLValue(Addr, E->getType(), BaseInfo);
// TODO: Preserve/extend path TBAA metadata?
@@ -3193,7 +3210,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
}
static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
- AlignmentSource &AlignSource,
+ LValueBaseInfo &BaseInfo,
QualType BaseTy, QualType ElTy,
bool IsLowerBound) {
LValue BaseLVal;
@@ -3201,7 +3218,7 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound);
if (BaseTy->isArrayType()) {
Address Addr = BaseLVal.getAddress();
- AlignSource = BaseLVal.getAlignmentSource();
+ BaseInfo = BaseLVal.getBaseInfo();
// If the array type was an incomplete type, we need to make sure
// the decay ends up being the right type.
@@ -3220,10 +3237,12 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
return CGF.Builder.CreateElementBitCast(Addr,
CGF.ConvertTypeForMem(ElTy));
}
- CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &AlignSource);
+ LValueBaseInfo TypeInfo;
+ CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &TypeInfo);
+ BaseInfo.mergeForCast(TypeInfo);
return Address(CGF.Builder.CreateLoad(BaseLVal.getAddress()), Align);
}
- return CGF.EmitPointerWithAlignment(Base, &AlignSource);
+ return CGF.EmitPointerWithAlignment(Base, &BaseInfo);
}
LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
@@ -3327,13 +3346,13 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
assert(Idx);
Address EltPtr = Address::invalid();
- AlignmentSource AlignSource;
+ LValueBaseInfo BaseInfo;
if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) {
// The base must be a pointer, which is not an aggregate. Emit
// it. It needs to be emitted first in case it's what captures
// the VLA bounds.
Address Base =
- emitOMPArraySectionBase(*this, E->getBase(), AlignSource, BaseTy,
+ emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, BaseTy,
VLA->getElementType(), IsLowerBound);
// The element count here is the total number of non-VLA elements.
llvm::Value *NumElements = getVLASize(VLA).first;
@@ -3367,15 +3386,15 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
EltPtr = emitArraySubscriptGEP(
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
ResultExprTy, !getLangOpts().isSignedOverflowDefined());
- AlignSource = ArrayLV.getAlignmentSource();
+ BaseInfo = ArrayLV.getBaseInfo();
} else {
- Address Base = emitOMPArraySectionBase(*this, E->getBase(), AlignSource,
+ Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo,
BaseTy, ResultExprTy, IsLowerBound);
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
!getLangOpts().isSignedOverflowDefined());
}
- return MakeAddrLValue(EltPtr, ResultExprTy, AlignSource);
+ return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo);
}
LValue CodeGenFunction::
@@ -3387,10 +3406,10 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
if (E->isArrow()) {
// If it is a pointer to a vector, emit the address and form an lvalue with
// it.
- AlignmentSource AlignSource;
- Address Ptr = EmitPointerWithAlignment(E->getBase(), &AlignSource);
+ LValueBaseInfo BaseInfo;
+ Address Ptr = EmitPointerWithAlignment(E->getBase(), &BaseInfo);
const PointerType *PT = E->getBase()->getType()->getAs<PointerType>();
- Base = MakeAddrLValue(Ptr, PT->getPointeeType(), AlignSource);
+ Base = MakeAddrLValue(Ptr, PT->getPointeeType(), BaseInfo);
Base.getQuals().removeObjCGCAttr();
} else if (E->getBase()->isGLValue()) {
// Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
@@ -3407,7 +3426,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
Address VecMem = CreateMemTemp(E->getBase()->getType());
Builder.CreateStore(Vec, VecMem);
Base = MakeAddrLValue(VecMem, E->getBase()->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
QualType type =
@@ -3421,7 +3440,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
llvm::Constant *CV =
llvm::ConstantDataVector::get(getLLVMContext(), Indices);
return LValue::MakeExtVectorElt(Base.getAddress(), CV, type,
- Base.getAlignmentSource());
+ Base.getBaseInfo());
}
assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
@@ -3432,17 +3451,16 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
CElts.push_back(BaseElts->getAggregateElement(Indices[i]));
llvm::Constant *CV = llvm::ConstantVector::get(CElts);
return LValue::MakeExtVectorElt(Base.getExtVectorAddress(), CV, type,
- Base.getAlignmentSource());
+ Base.getBaseInfo());
}
LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
Expr *BaseExpr = E->getBase();
-
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
LValue BaseLV;
if (E->isArrow()) {
- AlignmentSource AlignSource;
- Address Addr = EmitPointerWithAlignment(BaseExpr, &AlignSource);
+ LValueBaseInfo BaseInfo;
+ Address Addr = EmitPointerWithAlignment(BaseExpr, &BaseInfo);
QualType PtrTy = BaseExpr->getType()->getPointeeType();
SanitizerSet SkippedChecks;
bool IsBaseCXXThis = IsWrappedCXXThis(BaseExpr);
@@ -3452,7 +3470,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
SkippedChecks.set(SanitizerKind::Null, true);
EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy,
/*Alignment=*/CharUnits::Zero(), SkippedChecks);
- BaseLV = MakeAddrLValue(Addr, PtrTy, AlignSource);
+ BaseLV = MakeAddrLValue(Addr, PtrTy, BaseInfo);
} else
BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);
@@ -3512,8 +3530,10 @@ static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
LValue CodeGenFunction::EmitLValueForField(LValue base,
const FieldDecl *field) {
+ LValueBaseInfo BaseInfo = base.getBaseInfo();
AlignmentSource fieldAlignSource =
- getFieldAlignmentSource(base.getAlignmentSource());
+ getFieldAlignmentSource(BaseInfo.getAlignmentSource());
+ LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias());
if (field->isBitField()) {
const CGRecordLayout &RL =
@@ -3533,7 +3553,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
QualType fieldType =
field->getType().withCVRQualifiers(base.getVRQualifiers());
- return LValue::MakeBitfield(Addr, Info, fieldType, fieldAlignSource);
+ return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo);
}
const RecordDecl *rec = field->getParent();
@@ -3574,7 +3594,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
type = refType->getPointeeType();
CharUnits alignment =
- getNaturalTypeAlignment(type, &fieldAlignSource, /*pointee*/ true);
+ getNaturalTypeAlignment(type, &FieldBaseInfo, /*pointee*/ true);
+ FieldBaseInfo.setMayAlias(false);
addr = Address(load, alignment);
// Qualifiers on the struct don't apply to the referencee, and
@@ -3595,7 +3616,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
if (field->hasAttr<AnnotateAttr>())
addr = EmitFieldAnnotations(field, addr);
- LValue LV = MakeAddrLValue(addr, type, fieldAlignSource);
+ LValue LV = MakeAddrLValue(addr, type, FieldBaseInfo);
LV.getQuals().addCVRQualifiers(cvr);
if (TBAAPath) {
const ASTRecordLayout &Layout =
@@ -3636,14 +3657,18 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
V = Builder.CreateElementBitCast(V, llvmType, Field->getName());
// TODO: access-path TBAA?
- auto FieldAlignSource = getFieldAlignmentSource(Base.getAlignmentSource());
- return MakeAddrLValue(V, FieldType, FieldAlignSource);
+ LValueBaseInfo BaseInfo = Base.getBaseInfo();
+ LValueBaseInfo FieldBaseInfo(
+ getFieldAlignmentSource(BaseInfo.getAlignmentSource()),
+ BaseInfo.getMayAlias());
+ return MakeAddrLValue(V, FieldType, FieldBaseInfo);
}
LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
if (E->isFileScope()) {
ConstantAddress GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E);
- return MakeAddrLValue(GlobalPtr, E->getType(), AlignmentSource::Decl);
+ return MakeAddrLValue(GlobalPtr, E->getType(), BaseInfo);
}
if (E->getType()->isVariablyModifiedType())
// make sure to emit the VLA size.
@@ -3651,7 +3676,7 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
Address DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");
const Expr *InitExpr = E->getInitializer();
- LValue Result = MakeAddrLValue(DeclPtr, E->getType(), AlignmentSource::Decl);
+ LValue Result = MakeAddrLValue(DeclPtr, E->getType(), BaseInfo);
EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers(),
/*Init*/ true);
@@ -3748,8 +3773,12 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
phi->addIncoming(rhs->getPointer(), rhsBlock);
Address result(phi, std::min(lhs->getAlignment(), rhs->getAlignment()));
AlignmentSource alignSource =
- std::max(lhs->getAlignmentSource(), rhs->getAlignmentSource());
- return MakeAddrLValue(result, expr->getType(), alignSource);
+ std::max(lhs->getBaseInfo().getAlignmentSource(),
+ rhs->getBaseInfo().getAlignmentSource());
+ bool MayAlias = lhs->getBaseInfo().getMayAlias() ||
+ rhs->getBaseInfo().getMayAlias();
+ return MakeAddrLValue(result, expr->getType(),
+ LValueBaseInfo(alignSource, MayAlias));
} else {
assert((lhs || rhs) &&
"both operands of glvalue conditional are throw-expressions?");
@@ -3847,7 +3876,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
This, DerivedClassDecl, E->path_begin(), E->path_end(),
/*NullCheckValue=*/false, E->getExprLoc());
- return MakeAddrLValue(Base, E->getType(), LV.getAlignmentSource());
+ return MakeAddrLValue(Base, E->getType(), LV.getBaseInfo());
}
case CK_ToUnion:
return EmitAggExprToLValue(E);
@@ -3874,7 +3903,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
/*MayBeNull=*/false,
CFITCK_DerivedCast, E->getLocStart());
- return MakeAddrLValue(Derived, E->getType(), LV.getAlignmentSource());
+ return MakeAddrLValue(Derived, E->getType(), LV.getBaseInfo());
}
case CK_LValueBitCast: {
// This must be a reinterpret_cast (or c-style equivalent).
@@ -3890,13 +3919,13 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
/*MayBeNull=*/false,
CFITCK_UnrelatedCast, E->getLocStart());
- return MakeAddrLValue(V, E->getType(), LV.getAlignmentSource());
+ return MakeAddrLValue(V, E->getType(), LV.getBaseInfo());
}
case CK_ObjCObjectLValueCast: {
LValue LV = EmitLValue(E->getSubExpr());
Address V = Builder.CreateElementBitCast(LV.getAddress(),
ConvertType(E->getType()));
- return MakeAddrLValue(V, E->getType(), LV.getAlignmentSource());
+ return MakeAddrLValue(V, E->getType(), LV.getBaseInfo());
}
case CK_ZeroToOCLQueue:
llvm_unreachable("NULL to OpenCL queue lvalue cast is not valid");
@@ -4085,7 +4114,7 @@ LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
if (!RV.isScalar())
return MakeAddrLValue(RV.getAggregateAddress(), E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
assert(E->getCallReturnType(getContext())->isReferenceType() &&
"Can't have a scalar return unless the return type is a "
@@ -4105,7 +4134,7 @@ LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
AggValueSlot Slot = CreateAggTemp(E->getType());
EmitCXXConstructExpr(E, Slot);
return MakeAddrLValue(Slot.getAddress(), E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
LValue
@@ -4120,7 +4149,7 @@ Address CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) {
LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) {
return MakeAddrLValue(EmitCXXUuidofExpr(E), E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
LValue
@@ -4130,7 +4159,7 @@ CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
EmitAggExpr(E->getSubExpr(), Slot);
EmitCXXTemporary(E->getTemporary(), E->getType(), Slot.getAddress());
return MakeAddrLValue(Slot.getAddress(), E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
LValue
@@ -4138,7 +4167,7 @@ CodeGenFunction::EmitLambdaLValue(const LambdaExpr *E) {
AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue");
EmitLambdaExpr(E, Slot);
return MakeAddrLValue(Slot.getAddress(), E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
@@ -4146,7 +4175,7 @@ LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
if (!RV.isScalar())
return MakeAddrLValue(RV.getAggregateAddress(), E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
assert(E->getMethodDecl()->getReturnType()->isReferenceType() &&
"Can't have a scalar return unless the return type is a "
@@ -4158,7 +4187,8 @@ LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) {
Address V =
CGM.getObjCRuntime().GetAddrOfSelector(*this, E->getSelector());
- return MakeAddrLValue(V, E->getType(), AlignmentSource::Decl);
+ return MakeAddrLValue(V, E->getType(),
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
@@ -4202,7 +4232,7 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
// Can only get l-value for message expression returning aggregate type
RValue RV = EmitAnyExprToTemp(E);
return MakeAddrLValue(RV.getAggregateAddress(), E->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee,
@@ -4394,12 +4424,11 @@ EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
const MemberPointerType *MPT
= E->getRHS()->getType()->getAs<MemberPointerType>();
- AlignmentSource AlignSource;
+ LValueBaseInfo BaseInfo;
Address MemberAddr =
- EmitCXXMemberDataPointerAddress(E, BaseAddr, OffsetV, MPT,
- &AlignSource);
+ EmitCXXMemberDataPointerAddress(E, BaseAddr, OffsetV, MPT, &BaseInfo);
- return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), AlignSource);
+ return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo);
}
/// Given the address of a temporary variable, produce an r-value of
@@ -4407,7 +4436,8 @@ EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
RValue CodeGenFunction::convertTempToRValue(Address addr,
QualType type,
SourceLocation loc) {
- LValue lvalue = MakeAddrLValue(addr, type, AlignmentSource::Decl);
+ LValue lvalue = MakeAddrLValue(addr, type,
+ LValueBaseInfo(AlignmentSource::Decl, false));
switch (getEvaluationKind(type)) {
case TEK_Complex:
return RValue::getComplex(EmitLoadOfComplex(lvalue, loc));
@@ -4462,9 +4492,9 @@ static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF,
if (ov == resultExpr && ov->isRValue() && !forLValue &&
CodeGenFunction::hasAggregateEvaluationKind(ov->getType())) {
CGF.EmitAggExpr(ov->getSourceExpr(), slot);
-
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
LValue LV = CGF.MakeAddrLValue(slot.getAddress(), ov->getType(),
- AlignmentSource::Decl);
+ BaseInfo);
opaqueData = OVMA::bind(CGF, ov, LV);
result.RV = slot.asRValue();
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index d02f074dd605..a9865f3703d4 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -1531,13 +1531,13 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
assert(E->getNumPlacementArgs() == 1);
const Expr *arg = *E->placement_arguments().begin();
- AlignmentSource alignSource;
- allocation = EmitPointerWithAlignment(arg, &alignSource);
+ LValueBaseInfo BaseInfo;
+ allocation = EmitPointerWithAlignment(arg, &BaseInfo);
// The pointer expression will, in many cases, be an opaque void*.
// In these cases, discard the computed alignment and use the
// formal alignment of the allocated type.
- if (alignSource != AlignmentSource::Decl)
+ if (BaseInfo.getAlignmentSource() != AlignmentSource::Decl)
allocation = Address(allocation.getPointer(), allocAlign);
// Set up allocatorArgs for the call to operator delete if it's not
@@ -1658,8 +1658,9 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
// Passing pointer through invariant.group.barrier to avoid propagation of
// vptrs information which may be included in previous type.
+ // To not break LTO with different optimizations levels, we do it regardless
+ // of optimization level.
if (CGM.getCodeGenOpts().StrictVTablePointers &&
- CGM.getCodeGenOpts().OptimizationLevel > 0 &&
allocator->isReservedGlobalPlacementOperator())
result = Address(Builder.CreateInvariantGroupBarrier(result.getPointer()),
result.getAlignment());
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index b8d830ee9f3f..048b50d8261d 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1579,10 +1579,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
}
// Since target may map different address spaces in AST to the same address
// space, an address space conversion may end up as a bitcast.
- auto *Src = Visit(E);
- return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(CGF, Src,
- E->getType(),
- DestTy);
+ return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
+ CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
+ DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
}
case CK_AtomicToNonAtomic:
case CK_NonAtomicToAtomic:
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index f4fbab3c2b83..820520121763 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -162,7 +162,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
const Expr *Rhs = ALE->getElement(i);
LValue LV = MakeAddrLValue(
Builder.CreateConstArrayGEP(Objects, i, getPointerSize()),
- ElementType, AlignmentSource::Decl);
+ ElementType, LValueBaseInfo(AlignmentSource::Decl, false));
llvm::Value *value = EmitScalarExpr(Rhs);
EmitStoreThroughLValue(RValue::get(value), LV, true);
@@ -174,7 +174,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
const Expr *Key = DLE->getKeyValueElement(i).Key;
LValue KeyLV = MakeAddrLValue(
Builder.CreateConstArrayGEP(Keys, i, getPointerSize()),
- ElementType, AlignmentSource::Decl);
+ ElementType, LValueBaseInfo(AlignmentSource::Decl, false));
llvm::Value *keyValue = EmitScalarExpr(Key);
EmitStoreThroughLValue(RValue::get(keyValue), KeyLV, /*isInit=*/true);
@@ -182,7 +182,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
const Expr *Value = DLE->getKeyValueElement(i).Value;
LValue ValueLV = MakeAddrLValue(
Builder.CreateConstArrayGEP(Objects, i, getPointerSize()),
- ElementType, AlignmentSource::Decl);
+ ElementType, LValueBaseInfo(AlignmentSource::Decl, false));
llvm::Value *valueValue = EmitScalarExpr(Value);
EmitStoreThroughLValue(RValue::get(valueValue), ValueLV, /*isInit=*/true);
if (TrackNeededObjects) {
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index 3da7ed230edd..3e3d04672357 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -138,7 +138,8 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
Addr = CGF.Builder.CreateElementBitCast(Addr,
llvm::Type::getIntNTy(CGF.getLLVMContext(),
Info->StorageSize));
- return LValue::MakeBitfield(Addr, *Info, IvarTy, AlignmentSource::Decl);
+ return LValue::MakeBitfield(Addr, *Info, IvarTy,
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
namespace {
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index b256a88c47ad..601d662e55e6 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -720,7 +720,7 @@ LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
CodeGenFunction &CGF) {
return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()),
getThreadIDVariable()->getType(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
}
CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
@@ -3565,7 +3565,9 @@ static void emitPrivatesInit(CodeGenFunction &CGF,
auto SharedRefLValue = CGF.EmitLValueForField(SrcBase, SharedField);
SharedRefLValue = CGF.MakeAddrLValue(
Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)),
- SharedRefLValue.getType(), AlignmentSource::Decl);
+ SharedRefLValue.getType(),
+ LValueBaseInfo(AlignmentSource::Decl,
+ SharedRefLValue.getBaseInfo().getMayAlias()));
QualType Type = OriginalVD->getType();
if (Type->isArrayType()) {
// Initialize firstprivate array.
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 19b6cbab66c9..c8c71dd83e97 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -327,14 +327,15 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
continue;
}
+ LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
LValue ArgLVal =
MakeAddrLValue(GetAddrOfLocalVar(Args[Cnt]), Args[Cnt]->getType(),
- AlignmentSource::Decl);
+ BaseInfo);
if (FD->hasCapturedVLAType()) {
LValue CastedArgLVal =
MakeAddrLValue(castValueFromUintptr(*this, FD->getType(),
Args[Cnt]->getName(), ArgLVal),
- FD->getType(), AlignmentSource::Decl);
+ FD->getType(), BaseInfo);
auto *ExprArg =
EmitLoadOfLValue(CastedArgLVal, SourceLocation()).getScalarVal();
auto VAT = FD->getCapturedVLAType();
@@ -991,7 +992,7 @@ static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
BaseLV.getPointer(), CGF.ConvertTypeForMem(ElTy)->getPointerTo()),
BaseLV.getAlignment()),
- BaseLV.getType(), BaseLV.getAlignmentSource());
+ BaseLV.getType(), BaseLV.getBaseInfo());
}
void CodeGenFunction::EmitOMPReductionClauseInit(
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index 53a376df6457..b768eb86367b 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -146,6 +146,25 @@ static inline AlignmentSource getFieldAlignmentSource(AlignmentSource Source) {
return AlignmentSource::Decl;
}
+class LValueBaseInfo {
+ AlignmentSource AlignSource;
+ bool MayAlias;
+
+public:
+ explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type,
+ bool Alias = false)
+ : AlignSource(Source), MayAlias(Alias) {}
+ AlignmentSource getAlignmentSource() const { return AlignSource; }
+ void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; }
+ bool getMayAlias() const { return MayAlias; }
+ void setMayAlias(bool Alias) { MayAlias = Alias; }
+
+ void mergeForCast(const LValueBaseInfo &Info) {
+ setAlignmentSource(Info.getAlignmentSource());
+ setMayAlias(getMayAlias() || Info.getMayAlias());
+ }
+};
+
/// LValue - This represents an lvalue references. Because C/C++ allow
/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
/// bitrange.
@@ -200,7 +219,7 @@ class LValue {
// to make the default bitfield pattern all-zeroes.
bool ImpreciseLifetime : 1;
- unsigned AlignSource : 2;
+ LValueBaseInfo BaseInfo;
// This flag shows if a nontemporal load/stores should be used when accessing
// this lvalue.
@@ -218,7 +237,7 @@ class LValue {
private:
void Initialize(QualType Type, Qualifiers Quals,
- CharUnits Alignment, AlignmentSource AlignSource,
+ CharUnits Alignment, LValueBaseInfo BaseInfo,
llvm::MDNode *TBAAInfo = nullptr) {
assert((!Alignment.isZero() || Type->isIncompleteType()) &&
"initializing l-value with zero alignment!");
@@ -227,7 +246,7 @@ private:
this->Alignment = Alignment.getQuantity();
assert(this->Alignment == Alignment.getQuantity() &&
"Alignment exceeds allowed max!");
- this->AlignSource = unsigned(AlignSource);
+ this->BaseInfo = BaseInfo;
// Initialize Objective-C flags.
this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
@@ -316,12 +335,8 @@ public:
CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); }
void setAlignment(CharUnits A) { Alignment = A.getQuantity(); }
- AlignmentSource getAlignmentSource() const {
- return AlignmentSource(AlignSource);
- }
- void setAlignmentSource(AlignmentSource Source) {
- AlignSource = unsigned(Source);
- }
+ LValueBaseInfo getBaseInfo() const { return BaseInfo; }
+ void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }
// simple lvalue
llvm::Value *getPointer() const {
@@ -370,7 +385,7 @@ public:
static LValue MakeAddr(Address address, QualType type,
ASTContext &Context,
- AlignmentSource alignSource,
+ LValueBaseInfo BaseInfo,
llvm::MDNode *TBAAInfo = nullptr) {
Qualifiers qs = type.getQualifiers();
qs.setObjCGCAttr(Context.getObjCGCAttrKind(type));
@@ -379,29 +394,29 @@ public:
R.LVType = Simple;
assert(address.getPointer()->getType()->isPointerTy());
R.V = address.getPointer();
- R.Initialize(type, qs, address.getAlignment(), alignSource, TBAAInfo);
+ R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo);
return R;
}
static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx,
- QualType type, AlignmentSource alignSource) {
+ QualType type, LValueBaseInfo BaseInfo) {
LValue R;
R.LVType = VectorElt;
R.V = vecAddress.getPointer();
R.VectorIdx = Idx;
R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
- alignSource);
+ BaseInfo);
return R;
}
static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts,
- QualType type, AlignmentSource alignSource) {
+ QualType type, LValueBaseInfo BaseInfo) {
LValue R;
R.LVType = ExtVectorElt;
R.V = vecAddress.getPointer();
R.VectorElts = Elts;
R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
- alignSource);
+ BaseInfo);
return R;
}
@@ -414,12 +429,12 @@ public:
static LValue MakeBitfield(Address Addr,
const CGBitFieldInfo &Info,
QualType type,
- AlignmentSource alignSource) {
+ LValueBaseInfo BaseInfo) {
LValue R;
R.LVType = BitField;
R.V = Addr.getPointer();
R.BitFieldInfo = &Info;
- R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), alignSource);
+ R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo);
return R;
}
@@ -428,7 +443,7 @@ public:
R.LVType = GlobalReg;
R.V = Reg.getPointer();
R.Initialize(type, type.getQualifiers(), Reg.getAlignment(),
- AlignmentSource::Decl);
+ LValueBaseInfo(AlignmentSource::Decl, false));
return R;
}
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 7b42850df968..85da3ae47db0 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -117,25 +117,27 @@ CodeGenFunction::~CodeGenFunction() {
}
CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T,
- AlignmentSource *Source) {
- return getNaturalTypeAlignment(T->getPointeeType(), Source,
+ LValueBaseInfo *BaseInfo) {
+ return getNaturalTypeAlignment(T->getPointeeType(), BaseInfo,
/*forPointee*/ true);
}
CharUnits CodeGenFunction::getNaturalTypeAlignment(QualType T,
- AlignmentSource *Source,
+ LValueBaseInfo *BaseInfo,
bool forPointeeType) {
// Honor alignment typedef attributes even on incomplete types.
// We also honor them straight for C++ class types, even as pointees;
// there's an expressivity gap here.
if (auto TT = T->getAs<TypedefType>()) {
if (auto Align = TT->getDecl()->getMaxAlignment()) {
- if (Source) *Source = AlignmentSource::AttributedType;
+ if (BaseInfo)
+ *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType, false);
return getContext().toCharUnitsFromBits(Align);
}
}
- if (Source) *Source = AlignmentSource::Type;
+ if (BaseInfo)
+ *BaseInfo = LValueBaseInfo(AlignmentSource::Type, false);
CharUnits Alignment;
if (T->isIncompleteType()) {
@@ -165,9 +167,9 @@ CharUnits CodeGenFunction::getNaturalTypeAlignment(QualType T,
}
LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
- AlignmentSource AlignSource;
- CharUnits Alignment = getNaturalTypeAlignment(T, &AlignSource);
- return LValue::MakeAddr(Address(V, Alignment), T, getContext(), AlignSource,
+ LValueBaseInfo BaseInfo;
+ CharUnits Alignment = getNaturalTypeAlignment(T, &BaseInfo);
+ return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo,
CGM.getTBAAInfo(T));
}
@@ -175,9 +177,9 @@ LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
/// construct an l-value with the natural pointee alignment of T.
LValue
CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) {
- AlignmentSource AlignSource;
- CharUnits Align = getNaturalTypeAlignment(T, &AlignSource, /*pointee*/ true);
- return MakeAddrLValue(Address(V, Align), T, AlignSource);
+ LValueBaseInfo BaseInfo;
+ CharUnits Align = getNaturalTypeAlignment(T, &BaseInfo, /*pointee*/ true);
+ return MakeAddrLValue(Address(V, Align), T, BaseInfo);
}
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 459841aee5a2..526ef9a1e579 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1886,31 +1886,33 @@ public:
//===--------------------------------------------------------------------===//
LValue MakeAddrLValue(Address Addr, QualType T,
- AlignmentSource AlignSource = AlignmentSource::Type) {
- return LValue::MakeAddr(Addr, T, getContext(), AlignSource,
+ LValueBaseInfo BaseInfo =
+ LValueBaseInfo(AlignmentSource::Type)) {
+ return LValue::MakeAddr(Addr, T, getContext(), BaseInfo,
CGM.getTBAAInfo(T));
}
LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
- AlignmentSource AlignSource = AlignmentSource::Type) {
+ LValueBaseInfo BaseInfo =
+ LValueBaseInfo(AlignmentSource::Type)) {
return LValue::MakeAddr(Address(V, Alignment), T, getContext(),
- AlignSource, CGM.getTBAAInfo(T));
+ BaseInfo, CGM.getTBAAInfo(T));
}
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T);
CharUnits getNaturalTypeAlignment(QualType T,
- AlignmentSource *Source = nullptr,
+ LValueBaseInfo *BaseInfo = nullptr,
bool forPointeeType = false);
CharUnits getNaturalPointeeTypeAlignment(QualType T,
- AlignmentSource *Source = nullptr);
+ LValueBaseInfo *BaseInfo = nullptr);
Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy,
- AlignmentSource *Source = nullptr);
+ LValueBaseInfo *BaseInfo = nullptr);
LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy);
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy,
- AlignmentSource *Source = nullptr);
+ LValueBaseInfo *BaseInfo = nullptr);
LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy);
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
@@ -2992,8 +2994,8 @@ public:
/// the LLVM value representation.
llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,
SourceLocation Loc,
- AlignmentSource AlignSource =
- AlignmentSource::Type,
+ LValueBaseInfo BaseInfo =
+ LValueBaseInfo(AlignmentSource::Type),
llvm::MDNode *TBAAInfo = nullptr,
QualType TBAABaseTy = QualType(),
uint64_t TBAAOffset = 0,
@@ -3010,7 +3012,8 @@ public:
/// the LLVM value representation.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr,
bool Volatile, QualType Ty,
- AlignmentSource AlignSource = AlignmentSource::Type,
+ LValueBaseInfo BaseInfo =
+ LValueBaseInfo(AlignmentSource::Type),
llvm::MDNode *TBAAInfo = nullptr, bool isInit = false,
QualType TBAABaseTy = QualType(),
uint64_t TBAAOffset = 0, bool isNontemporal = false);
@@ -3083,7 +3086,7 @@ public:
RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc);
Address EmitArrayToPointerDecay(const Expr *Array,
- AlignmentSource *AlignSource = nullptr);
+ LValueBaseInfo *BaseInfo = nullptr);
class ConstantEmission {
llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
@@ -3224,7 +3227,7 @@ public:
Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
llvm::Value *memberPtr,
const MemberPointerType *memberPtrType,
- AlignmentSource *AlignSource = nullptr);
+ LValueBaseInfo *BaseInfo = nullptr);
RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
ReturnValueSlot ReturnValue);
@@ -3743,29 +3746,25 @@ public:
unsigned ParamsToSkip = 0,
EvaluationOrder Order = EvaluationOrder::Default);
- /// EmitPointerWithAlignment - Given an expression with a pointer
- /// type, emit the value and compute our best estimate of the
- /// alignment of the pointee.
+ /// EmitPointerWithAlignment - Given an expression with a pointer type,
+ /// emit the value and compute our best estimate of the alignment of the
+ /// pointee.
///
- /// Note that this function will conservatively fall back on the type
- /// when it doesn't
+ /// \param BaseInfo - If non-null, this will be initialized with
+ /// information about the source of the alignment and the may-alias
+ /// attribute. Note that this function will conservatively fall back on
+ /// the type when it doesn't recognize the expression and may-alias will
+ /// be set to false.
///
- /// \param Source - If non-null, this will be initialized with
- /// information about the source of the alignment. Note that this
- /// function will conservatively fall back on the type when it
- /// doesn't recognize the expression, which means that sometimes
- ///
- /// a worst-case One
- /// reasonable way to use this information is when there's a
- /// language guarantee that the pointer must be aligned to some
- /// stricter value, and we're simply trying to ensure that
- /// sufficiently obvious uses of under-aligned objects don't get
- /// miscompiled; for example, a placement new into the address of
- /// a local variable. In such a case, it's quite reasonable to
- /// just ignore the returned alignment when it isn't from an
- /// explicit source.
+ /// One reasonable way to use this information is when there's a language
+ /// guarantee that the pointer must be aligned to some stricter value, and
+ /// we're simply trying to ensure that sufficiently obvious uses of under-
+ /// aligned objects don't get miscompiled; for example, a placement new
+ /// into the address of a local variable. In such a case, it's quite
+ /// reasonable to just ignore the returned alignment when it isn't from an
+ /// explicit source.
Address EmitPointerWithAlignment(const Expr *Addr,
- AlignmentSource *Source = nullptr);
+ LValueBaseInfo *BaseInfo = nullptr);
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index a0254797ea43..9d0f802ece07 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -45,6 +45,7 @@
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
@@ -113,6 +114,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
AllocaInt8PtrTy = Int8Ty->getPointerTo(
M.getDataLayout().getAllocaAddrSpace());
+ ASTAllocaAddressSpace = getTargetCodeGenInfo().getASTAllocaAddressSpace();
RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC();
BuiltinCC = getTargetCodeGenInfo().getABIInfo().getBuiltinCC();
@@ -464,18 +466,24 @@ void CodeGenModule::Release() {
getModule().addModuleFlag(llvm::Module::Warning, "Debug Info Version",
llvm::DEBUG_METADATA_VERSION);
+ // Width of wchar_t in bytes
+ uint64_t WCharWidth =
+ Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity();
+ assert(LangOpts.ShortWChar ||
+ llvm::TargetLibraryInfoImpl::getTargetWCharSize(Target.getTriple()) ==
+ Target.getWCharWidth() / 8 &&
+ "LLVM wchar_t size out of sync");
+
// We need to record the widths of enums and wchar_t, so that we can generate
- // the correct build attributes in the ARM backend.
+ // the correct build attributes in the ARM backend. wchar_size is also used by
+ // TargetLibraryInfo.
+ getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth);
+
llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
if ( Arch == llvm::Triple::arm
|| Arch == llvm::Triple::armeb
|| Arch == llvm::Triple::thumb
|| Arch == llvm::Triple::thumbeb) {
- // Width of wchar_t in bytes
- uint64_t WCharWidth =
- Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity();
- getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth);
-
// The minimum width of an enum in bytes
uint64_t EnumWidth = Context.getLangOpts().ShortEnums ? 1 : 4;
getModule().addModuleFlag(llvm::Module::Error, "min_enum_size", EnumWidth);
diff --git a/lib/CodeGen/CodeGenTypeCache.h b/lib/CodeGen/CodeGenTypeCache.h
index 8ce9860cc638..450eab48a3b4 100644
--- a/lib/CodeGen/CodeGenTypeCache.h
+++ b/lib/CodeGen/CodeGenTypeCache.h
@@ -94,6 +94,8 @@ struct CodeGenTypeCache {
unsigned char SizeAlignInBytes;
};
+ unsigned ASTAllocaAddressSpace;
+
CharUnits getSizeSize() const {
return CharUnits::fromQuantity(SizeSizeInBytes);
}
@@ -111,6 +113,8 @@ struct CodeGenTypeCache {
llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; }
llvm::CallingConv::ID BuiltinCC;
llvm::CallingConv::ID getBuiltinCC() const { return BuiltinCC; }
+
+ unsigned getASTAllocaAddressSpace() const { return ASTAllocaAddressSpace; }
};
} // end namespace CodeGen
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 18367d1602ba..83aa1fdf5722 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -407,12 +407,11 @@ llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &
}
llvm::Value *TargetCodeGenInfo::performAddrSpaceCast(
- CodeGen::CodeGenFunction &CGF, llvm::Value *Src, QualType SrcTy,
- QualType DestTy) const {
+ CodeGen::CodeGenFunction &CGF, llvm::Value *Src, unsigned SrcAddr,
+ unsigned DestAddr, llvm::Type *DestTy, bool isNonNull) const {
// Since target may map different address spaces in AST to the same address
// space, an address space conversion may end up as a bitcast.
- return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Src,
- CGF.ConvertType(DestTy));
+ return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DestTy);
}
static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
@@ -6558,6 +6557,11 @@ public:
Fn->addFnAttr("nomips16");
}
+ if (FD->hasAttr<MicroMipsAttr>())
+ Fn->addFnAttr("micromips");
+ else if (FD->hasAttr<NoMicroMipsAttr>())
+ Fn->addFnAttr("nomicromips");
+
const MipsInterruptAttr *Attr = FD->getAttr<MipsInterruptAttr>();
if (!Attr)
return;
@@ -7292,6 +7296,11 @@ public:
llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
llvm::PointerType *T, QualType QT) const override;
+
+ unsigned getASTAllocaAddressSpace() const override {
+ return LangAS::FirstTargetAddressSpace +
+ getABIInfo().getDataLayout().getAllocaAddrSpace();
+ }
};
}
diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h
index 223d6d047af7..247d01dcb086 100644
--- a/lib/CodeGen/TargetInfo.h
+++ b/lib/CodeGen/TargetInfo.h
@@ -229,13 +229,20 @@ public:
virtual llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
llvm::PointerType *T, QualType QT) const;
+ /// Get the AST address space for alloca.
+ virtual unsigned getASTAllocaAddressSpace() const { return LangAS::Default; }
+
/// Perform address space cast of an expression of pointer type.
/// \param V is the LLVM value to be casted to another address space.
- /// \param SrcTy is the QualType of \p V.
- /// \param DestTy is the destination QualType.
+ /// \param SrcAddr is the language address space of \p V.
+ /// \param DestAddr is the targeted language address space.
+ /// \param DestTy is the destination LLVM pointer type.
+ /// \param IsNonNull is the flag indicating \p V is known to be non null.
virtual llvm::Value *performAddrSpaceCast(CodeGen::CodeGenFunction &CGF,
- llvm::Value *V, QualType SrcTy, QualType DestTy) const;
-
+ llvm::Value *V, unsigned SrcAddr,
+ unsigned DestAddr,
+ llvm::Type *DestTy,
+ bool IsNonNull = false) const;
};
} // namespace CodeGen
diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp
index c97486e4e4a7..3c9df62f80dc 100644
--- a/lib/Format/BreakableToken.cpp
+++ b/lib/Format/BreakableToken.cpp
@@ -41,7 +41,8 @@ static bool IsBlank(char C) {
}
static StringRef getLineCommentIndentPrefix(StringRef Comment) {
- static const char *const KnownPrefixes[] = {"///", "//", "//!"};
+ static const char *const KnownPrefixes[] = {
+ "///<", "//!<", "///", "//", "//!"};
StringRef LongestPrefix;
for (StringRef KnownPrefix : KnownPrefixes) {
if (Comment.startswith(KnownPrefix)) {
@@ -77,6 +78,14 @@ static BreakableToken::Split getCommentSplit(StringRef Text,
}
StringRef::size_type SpaceOffset = Text.find_last_of(Blanks, MaxSplitBytes);
+
+ // Do not split before a number followed by a dot: this would be interpreted
+ // as a numbered list, which would prevent re-flowing in subsequent passes.
+ static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\.");
+ if (SpaceOffset != StringRef::npos &&
+ kNumberedListRegexp.match(Text.substr(SpaceOffset).ltrim(Blanks)))
+ SpaceOffset = Text.find_last_of(Blanks, SpaceOffset);
+
if (SpaceOffset == StringRef::npos ||
// Don't break at leading whitespace.
Text.find_last_not_of(Blanks, SpaceOffset) == StringRef::npos) {
@@ -298,8 +307,9 @@ const FormatToken &BreakableComment::tokenAt(unsigned LineIndex) const {
static bool mayReflowContent(StringRef Content) {
Content = Content.trim(Blanks);
// Lines starting with '@' commonly have special meaning.
- static const SmallVector<StringRef, 4> kSpecialMeaningPrefixes = {
- "@", "TODO", "FIXME", "XXX"};
+ // Lines starting with '-', '-#', '+' or '*' are bulleted/numbered lists.
+ static const SmallVector<StringRef, 8> kSpecialMeaningPrefixes = {
+ "@", "TODO", "FIXME", "XXX", "-# ", "- ", "+ ", "* " };
bool hasSpecialMeaningPrefix = false;
for (StringRef Prefix : kSpecialMeaningPrefixes) {
if (Content.startswith(Prefix)) {
@@ -307,6 +317,14 @@ static bool mayReflowContent(StringRef Content) {
break;
}
}
+
+ // Numbered lists may also start with a number followed by '.'
+ // To avoid issues if a line starts with a number which is actually the end
+ // of a previous line, we only consider numbers with up to 2 digits.
+ static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\. ");
+ hasSpecialMeaningPrefix = hasSpecialMeaningPrefix ||
+ kNumberedListRegexp.match(Content);
+
// Simple heuristic for what to reflow: content should contain at least two
// characters and either the first or second character must be
// non-punctuation.
@@ -692,6 +710,10 @@ BreakableLineCommentSection::BreakableLineCommentSection(
Prefix[i] = "/// ";
else if (Prefix[i] == "//!")
Prefix[i] = "//! ";
+ else if (Prefix[i] == "///<")
+ Prefix[i] = "///< ";
+ else if (Prefix[i] == "//!<")
+ Prefix[i] = "//!< ";
}
Tokens[i] = LineTok;
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 488f9dd582f9..006a9710148f 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -207,7 +207,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
// ...
// }.bind(...));
// FIXME: We should find a more generic solution to this problem.
- !(State.Column <= NewLineColumn &&
+ !(State.Column <= NewLineColumn && Previous.isNot(tok::r_paren) &&
Style.Language == FormatStyle::LK_JavaScript))
return true;
@@ -587,8 +587,10 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
if (!DryRun) {
unsigned Newlines = std::max(
1u, std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1));
+ bool ContinuePPDirective =
+ State.Line->InPPDirective && State.Line->Type != LT_ImportStatement;
Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
- State.Line->InPPDirective);
+ ContinuePPDirective);
}
if (!Current.isTrailingComment())
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index c8677e805179..ac83379e6b15 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -343,6 +343,8 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
IO.mapOptional("ObjCSpaceBeforeProtocolList",
Style.ObjCSpaceBeforeProtocolList);
+ IO.mapOptional("PenaltyBreakAssignment",
+ Style.PenaltyBreakAssignment);
IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
Style.PenaltyBreakBeforeFirstCallParameter);
IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
@@ -582,6 +584,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.SpaceBeforeAssignmentOperators = true;
LLVMStyle.SpacesInAngles = false;
+ LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
LLVMStyle.PenaltyBreakComment = 300;
LLVMStyle.PenaltyBreakFirstLessLess = 120;
LLVMStyle.PenaltyBreakString = 1000;
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 387768a6ee56..79f438eb0f88 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -576,12 +576,13 @@ private:
}
break;
case tok::kw_for:
- if (Style.Language == FormatStyle::LK_JavaScript)
+ if (Style.Language == FormatStyle::LK_JavaScript) {
if (Tok->Previous && Tok->Previous->is(tok::period))
break;
- // JS' for async ( ...
- if (CurrentToken->is(Keywords.kw_async))
+ // JS' for await ( ...
+ if (CurrentToken && CurrentToken->is(Keywords.kw_await))
next();
+ }
Contexts.back().ColonIsForRangeExpr = true;
next();
if (!parseParens())
@@ -703,9 +704,12 @@ private:
void parseIncludeDirective() {
if (CurrentToken && CurrentToken->is(tok::less)) {
- next();
- while (CurrentToken) {
- if (CurrentToken->isNot(tok::comment) || CurrentToken->Next)
+ next();
+ while (CurrentToken) {
+ // Mark tokens up to the trailing line comments as implicit string
+ // literals.
+ if (CurrentToken->isNot(tok::comment) &&
+ !CurrentToken->TokenText.startswith("//"))
CurrentToken->Type = TT_ImplicitStringLiteral;
next();
}
@@ -2089,9 +2093,10 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
if (Left.is(TT_ConditionalExpr))
return prec::Conditional;
prec::Level Level = Left.getPrecedence();
- if (Level != prec::Unknown)
- return Level;
- Level = Right.getPrecedence();
+ if (Level == prec::Unknown)
+ Level = Right.getPrecedence();
+ if (Level == prec::Assignment)
+ return Style.PenaltyBreakAssignment;
if (Level != prec::Unknown)
return Level;
@@ -2252,8 +2257,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
} else if (Style.Language == FormatStyle::LK_JavaScript) {
if (Left.is(TT_JsFatArrow))
return true;
- // for async ( ...
- if (Right.is(tok::l_paren) && Left.is(Keywords.kw_async) &&
+ // for await ( ...
+ if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) &&
Left.Previous && Left.Previous->is(tok::kw_for))
return true;
if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
@@ -2472,22 +2477,25 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// If the last token before a '}', ']', or ')' is a comma or a trailing
// comment, the intention is to insert a line break after it in order to make
- // shuffling around entries easier.
- const FormatToken *BeforeClosingBrace = nullptr;
- if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
- (Style.Language == FormatStyle::LK_JavaScript &&
- Left.is(tok::l_paren))) &&
- Left.BlockKind != BK_Block && Left.MatchingParen)
- BeforeClosingBrace = Left.MatchingParen->Previous;
- else if (Right.MatchingParen &&
- (Right.MatchingParen->isOneOf(tok::l_brace,
- TT_ArrayInitializerLSquare) ||
- (Style.Language == FormatStyle::LK_JavaScript &&
- Right.MatchingParen->is(tok::l_paren))))
- BeforeClosingBrace = &Left;
- if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
- BeforeClosingBrace->isTrailingComment()))
- return true;
+ // shuffling around entries easier. Import statements, especially in
+ // JavaScript, can be an exception to this rule.
+ if (Style.JavaScriptWrapImports || Line.Type != LT_ImportStatement) {
+ const FormatToken *BeforeClosingBrace = nullptr;
+ if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
+ (Style.Language == FormatStyle::LK_JavaScript &&
+ Left.is(tok::l_paren))) &&
+ Left.BlockKind != BK_Block && Left.MatchingParen)
+ BeforeClosingBrace = Left.MatchingParen->Previous;
+ else if (Right.MatchingParen &&
+ (Right.MatchingParen->isOneOf(tok::l_brace,
+ TT_ArrayInitializerLSquare) ||
+ (Style.Language == FormatStyle::LK_JavaScript &&
+ Right.MatchingParen->is(tok::l_paren))))
+ BeforeClosingBrace = &Left;
+ if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
+ BeforeClosingBrace->isTrailingComment()))
+ return true;
+ }
if (Right.is(tok::comment))
return Left.BlockKind != BK_BracedInit &&
@@ -2562,7 +2570,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
Keywords.kw_interface, Keywords.kw_type, tok::kw_static,
tok::kw_public, tok::kw_private, tok::kw_protected,
Keywords.kw_abstract, Keywords.kw_get, Keywords.kw_set))
- return false; // Otherwise a semicolon is inserted.
+ return false; // Otherwise automatic semicolon insertion would trigger.
if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
return false;
if (Left.is(TT_JsTypeColon))
diff --git a/lib/Format/UnwrappedLineFormatter.cpp b/lib/Format/UnwrappedLineFormatter.cpp
index 8ff893426e25..01504da0a29b 100644
--- a/lib/Format/UnwrappedLineFormatter.cpp
+++ b/lib/Format/UnwrappedLineFormatter.cpp
@@ -611,7 +611,8 @@ public:
LineState State = Indenter->getInitialState(FirstIndent, &Line, DryRun);
while (State.NextToken) {
formatChildren(State, /*Newline=*/false, DryRun, Penalty);
- Indenter->addTokenToState(State, /*Newline=*/false, DryRun);
+ Indenter->addTokenToState(
+ State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun);
}
return Penalty;
}
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 31c66ffb00a1..ae79ea5d8a66 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -55,13 +55,33 @@ private:
std::vector<bool> &Stack;
};
+static bool isLineComment(const FormatToken &FormatTok) {
+ return FormatTok.is(tok::comment) &&
+ FormatTok.TokenText.startswith("//");
+}
+
+// Checks if \p FormatTok is a line comment that continues the line comment
+// \p Previous. The original column of \p MinColumnToken is used to determine
+// whether \p FormatTok is indented enough to the right to continue \p Previous.
+static bool continuesLineComment(const FormatToken &FormatTok,
+ const FormatToken *Previous,
+ const FormatToken *MinColumnToken) {
+ if (!Previous || !MinColumnToken)
+ return false;
+ unsigned MinContinueColumn =
+ MinColumnToken->OriginalColumn + (isLineComment(*MinColumnToken) ? 0 : 1);
+ return isLineComment(FormatTok) && FormatTok.NewlinesBefore == 1 &&
+ isLineComment(*Previous) &&
+ FormatTok.OriginalColumn >= MinContinueColumn;
+}
+
class ScopedMacroState : public FormatTokenSource {
public:
ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
FormatToken *&ResetToken)
: Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
- Token(nullptr) {
+ Token(nullptr), PreviousToken(nullptr) {
TokenSource = this;
Line.Level = 0;
Line.InPPDirective = true;
@@ -78,6 +98,7 @@ public:
// The \c UnwrappedLineParser guards against this by never calling
// \c getNextToken() after it has encountered the first eof token.
assert(!eof());
+ PreviousToken = Token;
Token = PreviousTokenSource->getNextToken();
if (eof())
return getFakeEOF();
@@ -87,12 +108,17 @@ public:
unsigned getPosition() override { return PreviousTokenSource->getPosition(); }
FormatToken *setPosition(unsigned Position) override {
+ PreviousToken = nullptr;
Token = PreviousTokenSource->setPosition(Position);
return Token;
}
private:
- bool eof() { return Token && Token->HasUnescapedNewline; }
+ bool eof() {
+ return Token && Token->HasUnescapedNewline &&
+ !continuesLineComment(*Token, PreviousToken,
+ /*MinColumnToken=*/PreviousToken);
+ }
FormatToken *getFakeEOF() {
static bool EOFInitialized = false;
@@ -112,6 +138,7 @@ private:
FormatTokenSource *PreviousTokenSource;
FormatToken *Token;
+ FormatToken *PreviousToken;
};
} // end anonymous namespace
@@ -429,8 +456,9 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
parseParens();
addUnwrappedLine();
- size_t OpeningLineIndex =
- Lines.empty() ? (UnwrappedLine::kInvalidIndex) : (Lines.size() - 1);
+ size_t OpeningLineIndex = CurrentLines->empty()
+ ? (UnwrappedLine::kInvalidIndex)
+ : (CurrentLines->size() - 1);
ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
MustBeDeclaration);
@@ -1635,9 +1663,9 @@ void UnwrappedLineParser::parseForOrWhileLoop() {
assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
"'for', 'while' or foreach macro expected");
nextToken();
- // JS' for async ( ...
+ // JS' for await ( ...
if (Style.Language == FormatStyle::LK_JavaScript &&
- FormatTok->is(Keywords.kw_async))
+ FormatTok->is(Keywords.kw_await))
nextToken();
if (FormatTok->Tok.is(tok::l_paren))
parseParens();
@@ -2091,16 +2119,11 @@ bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {
FormatTok.NewlinesBefore > 0;
}
-static bool isLineComment(const FormatToken &FormatTok) {
- return FormatTok.is(tok::comment) &&
- FormatTok.TokenText.startswith("//");
-}
-
// Checks if \p FormatTok is a line comment that continues the line comment
// section on \p Line.
-static bool continuesLineComment(const FormatToken &FormatTok,
- const UnwrappedLine &Line,
- llvm::Regex &CommentPragmasRegex) {
+static bool continuesLineCommentSection(const FormatToken &FormatTok,
+ const UnwrappedLine &Line,
+ llvm::Regex &CommentPragmasRegex) {
if (Line.Tokens.empty())
return false;
@@ -2199,12 +2222,8 @@ static bool continuesLineComment(const FormatToken &FormatTok,
MinColumnToken = PreviousToken;
}
- unsigned MinContinueColumn =
- MinColumnToken->OriginalColumn +
- (isLineComment(*MinColumnToken) ? 0 : 1);
- return isLineComment(FormatTok) && FormatTok.NewlinesBefore == 1 &&
- isLineComment(*(Line.Tokens.back().Tok)) &&
- FormatTok.OriginalColumn >= MinContinueColumn;
+ return continuesLineComment(FormatTok, /*Previous=*/Line.Tokens.back().Tok,
+ MinColumnToken);
}
void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
@@ -2222,7 +2241,7 @@ void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
// FIXME: Consider putting separate line comment sections as children to the
// unwrapped line instead.
(*I)->ContinuesLineCommentSection =
- continuesLineComment(**I, *Line, CommentPragmasRegex);
+ continuesLineCommentSection(**I, *Line, CommentPragmasRegex);
if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection)
addUnwrappedLine();
pushToken(*I);
@@ -2255,7 +2274,7 @@ void UnwrappedLineParser::distributeComments(
const SmallVectorImpl<FormatToken *> &Comments,
const FormatToken *NextTok) {
// Whether or not a line comment token continues a line is controlled by
- // the method continuesLineComment, with the following caveat:
+ // the method continuesLineCommentSection, with the following caveat:
//
// Define a trail of Comments to be a nonempty proper postfix of Comments such
// that each comment line from the trail is aligned with the next token, if
@@ -2293,7 +2312,7 @@ void UnwrappedLineParser::distributeComments(
FormatTok->ContinuesLineCommentSection = false;
} else {
FormatTok->ContinuesLineCommentSection =
- continuesLineComment(*FormatTok, *Line, CommentPragmasRegex);
+ continuesLineCommentSection(*FormatTok, *Line, CommentPragmasRegex);
}
if (!FormatTok->ContinuesLineCommentSection &&
(isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index 08d233fb83e0..efa5ed85d60b 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -246,6 +246,9 @@ public:
}
bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+ if (E->isClassReceiver())
+ IndexCtx.handleReference(E->getClassReceiver(), E->getReceiverLocation(),
+ Parent, ParentDC);
if (E->isExplicitProperty()) {
SmallVector<SymbolRelation, 2> Relations;
SymbolRoleSet Roles = getRolesForRef(E, Relations);
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index 203862c46e98..870b4e4fe825 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -63,6 +63,17 @@ public:
case TemplateArgument::Type:
IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
break;
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
+ Parent, DC);
+ if (const TemplateDecl *TD = TALoc.getArgument()
+ .getAsTemplateOrTemplatePattern()
+ .getAsTemplateDecl()) {
+ if (const NamedDecl *TTD = TD->getTemplatedDecl())
+ IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
+ }
+ break;
default:
break;
}
@@ -98,6 +109,17 @@ public:
}
}
}
+ } else {
+ // Index the default parameter value for function definitions.
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->isThisDeclarationADefinition()) {
+ for (const auto *PV : FD->parameters()) {
+ if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
+ !PV->hasUnparsedDefaultArg())
+ IndexCtx.indexBody(PV->getDefaultArg(), D);
+ }
+ }
+ }
}
}
@@ -206,9 +228,6 @@ public:
}
bool VisitFunctionDecl(const FunctionDecl *D) {
- if (D->isDeleted())
- return true;
-
SymbolRoleSet Roles{};
SmallVector<SymbolRelation, 4> Relations;
if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
@@ -568,8 +587,12 @@ public:
const DeclContext *DC = D->getDeclContext()->getRedeclContext();
const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
- IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
- D->getLexicalDeclContext());
+ // NNS for the local 'using namespace' directives is visited by the body
+ // visitor.
+ if (!D->getParentFunctionOrMethod())
+ IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
+ D->getLexicalDeclContext());
+
return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
D->getLocation(), Parent,
D->getLexicalDeclContext(),
@@ -598,8 +621,43 @@ public:
return true;
}
+ static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
+ if (!D)
+ return false;
+ // We want to index the template parameters only once when indexing the
+ // canonical declaration.
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
+ return FD->getCanonicalDecl() == FD;
+ else if (const auto *TD = dyn_cast<TagDecl>(D))
+ return TD->getCanonicalDecl() == TD;
+ else if (const auto *VD = dyn_cast<VarDecl>(D))
+ return VD->getCanonicalDecl() == VD;
+ return true;
+ }
+
bool VisitTemplateDecl(const TemplateDecl *D) {
// FIXME: Template parameters.
+
+ // Index the default values for the template parameters.
+ const NamedDecl *Parent = D->getTemplatedDecl();
+ if (D->getTemplateParameters() &&
+ shouldIndexTemplateParameterDefaultValue(Parent)) {
+ const TemplateParameterList *Params = D->getTemplateParameters();
+ for (const NamedDecl *TP : *Params) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
+ if (TTP->hasDefaultArgument())
+ IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
+ } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
+ if (NTTP->hasDefaultArgument())
+ IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
+ } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
+ if (TTPD->hasDefaultArgument())
+ handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
+ /*DC=*/nullptr);
+ }
+ }
+ }
+
return Visit(D->getTemplatedDecl());
}
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index 0bfa19346b4e..0b20970acc3b 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -61,6 +61,8 @@ bool index::isFunctionLocalSymbol(const Decl *D) {
if (isa<ObjCTypeParamDecl>(D))
return true;
+ if (isa<UsingDirectiveDecl>(D))
+ return false;
if (!D->getParentFunctionOrMethod())
return false;
@@ -318,16 +320,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
if (Info.Properties & (unsigned)SymbolProperty::Generic)
Info.Lang = SymbolLanguage::CXX;
- auto getExternalSymAttr = [](const Decl *D) -> ExternalSourceSymbolAttr* {
- if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>())
- return attr;
- if (auto *dcd = dyn_cast<Decl>(D->getDeclContext())) {
- if (auto *attr = dcd->getAttr<ExternalSourceSymbolAttr>())
- return attr;
- }
- return nullptr;
- };
- if (auto *attr = getExternalSymAttr(D)) {
+ if (auto *attr = D->getExternalSourceSymbolAttr()) {
if (attr->getLanguage() == "Swift")
Info.Lang = SymbolLanguage::Swift;
}
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 044edf715fc2..21054b099a8e 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -49,7 +49,7 @@ static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
static StringRef GetExternalSourceContainer(const NamedDecl *D) {
if (!D)
return StringRef();
- if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>()) {
+ if (auto *attr = D->getExternalSourceSymbolAttr()) {
return attr->getDefinedIn();
}
return StringRef();
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 6f44dc757e85..1f7003a2a4a7 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -950,39 +950,6 @@ bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
return !Mod->UnresolvedConflicts.empty();
}
-Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
- if (Loc.isInvalid())
- return nullptr;
-
- if (UmbrellaDirs.empty() && Headers.empty())
- return nullptr;
-
- // Use the expansion location to determine which module we're in.
- FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
- if (!ExpansionLoc.isFileID())
- return nullptr;
-
- const SourceManager &SrcMgr = Loc.getManager();
- FileID ExpansionFileID = ExpansionLoc.getFileID();
-
- while (const FileEntry *ExpansionFile
- = SrcMgr.getFileEntryForID(ExpansionFileID)) {
- // Find the module that owns this header (if any).
- if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
- return Mod;
-
- // No module owns this header, so look up the inclusion chain to see if
- // any included header has an associated module.
- SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
- if (IncludeLoc.isInvalid())
- return nullptr;
-
- ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
- }
-
- return nullptr;
-}
-
//----------------------------------------------------------------------------//
// Module map file parser
//----------------------------------------------------------------------------//
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index faf8809e4eb4..0534aeb10ccb 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -667,24 +667,17 @@ Module *Preprocessor::getModuleForLocation(SourceLocation Loc) {
: HeaderInfo.lookupModule(getLangOpts().CurrentModule);
}
-Module *Preprocessor::getModuleContainingLocation(SourceLocation Loc) {
- return HeaderInfo.getModuleMap().inferModuleFromLocation(
- FullSourceLoc(Loc, SourceMgr));
-}
-
const FileEntry *
Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ Module *M,
SourceLocation Loc) {
+ assert(M && "no module to include");
+
// If we have a module import syntax, we shouldn't include a header to
// make a particular module visible.
if (getLangOpts().ObjC2)
return nullptr;
- // Figure out which module we'd want to import.
- Module *M = getModuleContainingLocation(Loc);
- if (!M)
- return nullptr;
-
Module *TopM = M->getTopLevelModule();
Module *IncM = getModuleForLocation(IncLoc);
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 1938328c904d..5a589d6a17b3 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -731,7 +731,7 @@ Module *Preprocessor::LeaveSubmodule(bool ForPragma) {
Module *LeavingMod = Info.M;
SourceLocation ImportLoc = Info.ImportLoc;
- if (!needModuleMacros() ||
+ if (!needModuleMacros() ||
(!getLangOpts().ModulesLocalVisibility &&
LeavingMod->getTopLevelModuleName() != getLangOpts().CurrentModule)) {
// If we don't need module macros, or this is not a module for which we
@@ -777,17 +777,6 @@ Module *Preprocessor::LeaveSubmodule(bool ForPragma) {
for (auto *MD = Macro.getLatest(); MD != OldMD; MD = MD->getPrevious()) {
assert(MD && "broken macro directive chain");
- // Stop on macros defined in other submodules of this module that we
- // #included along the way. There's no point doing this if we're
- // tracking local submodule visibility, since there can be no such
- // directives in our list.
- if (!getLangOpts().ModulesLocalVisibility) {
- Module *Mod = getModuleContainingLocation(MD->getLocation());
- if (Mod != LeavingMod &&
- Mod->getTopLevelModule() == LeavingMod->getTopLevelModule())
- break;
- }
-
if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
// The latest visibility directive for a name in a submodule affects
// all the directives that come before it.
@@ -809,6 +798,13 @@ Module *Preprocessor::LeaveSubmodule(bool ForPragma) {
if (Def || !Macro.getOverriddenMacros().empty())
addModuleMacro(LeavingMod, II, Def,
Macro.getOverriddenMacros(), IsNew);
+
+ if (!getLangOpts().ModulesLocalVisibility) {
+ // This macro is exposed to the rest of this compilation as a
+ // ModuleMacro; we don't need to track its MacroDirective any more.
+ Macro.setLatest(nullptr);
+ Macro.setOverriddenMacros(*this, {});
+ }
break;
}
}
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 172b0edce5e4..cc1e8850a523 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -731,19 +731,6 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
ConsumeBrace();
break;
- case tok::code_completion:
- Toks.push_back(Tok);
- ConsumeCodeCompletionToken();
- break;
-
- case tok::string_literal:
- case tok::wide_string_literal:
- case tok::utf8_string_literal:
- case tok::utf16_string_literal:
- case tok::utf32_string_literal:
- Toks.push_back(Tok);
- ConsumeStringToken();
- break;
case tok::semi:
if (StopAtSemi)
return false;
@@ -751,7 +738,7 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
default:
// consume this token.
Toks.push_back(Tok);
- ConsumeToken();
+ ConsumeAnyToken(/*ConsumeCodeCompletionTok*/true);
break;
}
isFirstTokenConsumed = false;
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 4ccee74eaa90..b785f5f7d2e6 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2989,7 +2989,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
}
DS.getTypeSpecScope() = SS;
- ConsumeToken(); // The C++ scope.
+ ConsumeAnnotationToken(); // The C++ scope.
assert(Tok.is(tok::annot_template_id) &&
"ParseOptionalCXXScopeSpecifier not working");
AnnotateTemplateIdTokenAsType();
@@ -2998,7 +2998,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (Next.is(tok::annot_typename)) {
DS.getTypeSpecScope() = SS;
- ConsumeToken(); // The C++ scope.
+ ConsumeAnnotationToken(); // The C++ scope.
if (Tok.getAnnotationValue()) {
ParsedType T = getTypeAnnotation(Tok);
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
@@ -3010,7 +3010,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
else
DS.SetTypeSpecError();
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
- ConsumeToken(); // The typename
+ ConsumeAnnotationToken(); // The typename
}
if (Next.isNot(tok::identifier))
@@ -3037,7 +3037,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
// typename.
if (!TypeRep) {
- ConsumeToken(); // Eat the scope spec so the identifier is current.
+ // Eat the scope spec so the identifier is current.
+ ConsumeAnnotationToken();
ParsedAttributesWithRange Attrs(AttrFactory);
if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
if (!Attrs.empty()) {
@@ -3050,7 +3051,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
}
DS.getTypeSpecScope() = SS;
- ConsumeToken(); // The C++ scope.
+ ConsumeAnnotationToken(); // The C++ scope.
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
DiagID, TypeRep, Policy);
@@ -3080,7 +3081,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
break;
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
- ConsumeToken(); // The typename
+ ConsumeAnnotationToken(); // The typename
continue;
}
@@ -4836,10 +4837,12 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) {
}
// Parse the constructor name.
- if (Tok.isOneOf(tok::identifier, tok::annot_template_id)) {
+ if (Tok.is(tok::identifier)) {
// We already know that we have a constructor name; just consume
// the token.
ConsumeToken();
+ } else if (Tok.is(tok::annot_template_id)) {
+ ConsumeAnnotationToken();
} else {
TPA.Revert();
return false;
@@ -4895,7 +4898,7 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) {
// be a constructor declaration with an invalid argument type. Keep
// looking.
if (Tok.is(tok::annot_cxxscope))
- ConsumeToken();
+ ConsumeAnnotationToken();
ConsumeToken();
// If this is not a constructor, we must be parsing a declarator,
@@ -5539,11 +5542,28 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
D.SetRangeEnd(Tok.getLocation());
ConsumeToken();
goto PastIdentifier;
- } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
- // A virt-specifier isn't treated as an identifier if it appears after a
- // trailing-return-type.
- if (D.getContext() != Declarator::TrailingReturnContext ||
- !isCXX11VirtSpecifier(Tok)) {
+ } else if (Tok.is(tok::identifier) && !D.mayHaveIdentifier()) {
+ // We're not allowed an identifier here, but we got one. Try to figure out
+ // if the user was trying to attach a name to the type, or whether the name
+ // is some unrelated trailing syntax.
+ bool DiagnoseIdentifier = false;
+ if (D.hasGroupingParens())
+ // An identifier within parens is unlikely to be intended to be anything
+ // other than a name being "declared".
+ DiagnoseIdentifier = true;
+ else if (D.getContext() == Declarator::TemplateTypeArgContext)
+ // T<int N> is an accidental identifier; T<int N indicates a missing '>'.
+ DiagnoseIdentifier =
+ NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater);
+ else if (D.getContext() == Declarator::AliasDeclContext ||
+ D.getContext() == Declarator::AliasTemplateContext)
+ // The most likely error is that the ';' was forgotten.
+ DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi);
+ else if (D.getContext() == Declarator::TrailingReturnContext &&
+ !isCXX11VirtSpecifier(Tok))
+ DiagnoseIdentifier = NextToken().isOneOf(
+ tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
+ if (DiagnoseIdentifier) {
Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
<< FixItHint::CreateRemoval(Tok.getLocation());
D.SetIdentifier(nullptr, Tok.getLocation());
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index e6cf65e36cfa..527d45b1e203 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -901,7 +901,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
if (Tok.is(tok::annot_decltype)) {
Result = getExprAnnotation(Tok);
EndLoc = Tok.getAnnotationEndLoc();
- ConsumeToken();
+ ConsumeAnnotationToken();
if (Result.isInvalid()) {
DS.SetTypeSpecError();
return EndLoc;
@@ -1105,7 +1105,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
ParsedType Type = getTypeAnnotation(Tok);
EndLocation = Tok.getAnnotationEndLoc();
- ConsumeToken();
+ ConsumeAnnotationToken();
if (Type)
return Type;
@@ -1162,7 +1162,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
// return.
EndLocation = Tok.getAnnotationEndLoc();
ParsedType Type = getTypeAnnotation(Tok);
- ConsumeToken();
+ ConsumeAnnotationToken();
return Type;
}
@@ -1565,7 +1565,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
}
} else if (Tok.is(tok::annot_template_id)) {
TemplateId = takeTemplateIdAnnotation(Tok);
- NameLoc = ConsumeToken();
+ NameLoc = ConsumeAnnotationToken();
if (TemplateId->Kind != TNK_Type_template &&
TemplateId->Kind != TNK_Dependent_template_name) {
@@ -3405,39 +3405,42 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
// parse '::'[opt] nested-name-specifier[opt]
CXXScopeSpec SS;
ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false);
- ParsedType TemplateTypeTy;
- if (Tok.is(tok::annot_template_id)) {
- TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
- if (TemplateId->Kind == TNK_Type_template ||
- TemplateId->Kind == TNK_Dependent_template_name) {
- AnnotateTemplateIdTokenAsType(/*IsClassName*/true);
- assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
- TemplateTypeTy = getTypeAnnotation(Tok);
- }
- }
- // Uses of decltype will already have been converted to annot_decltype by
- // ParseOptionalCXXScopeSpecifier at this point.
- if (!TemplateTypeTy && Tok.isNot(tok::identifier)
- && Tok.isNot(tok::annot_decltype)) {
- Diag(Tok, diag::err_expected_member_or_base_name);
- return true;
- }
+ // : identifier
IdentifierInfo *II = nullptr;
- DeclSpec DS(AttrFactory);
SourceLocation IdLoc = Tok.getLocation();
- if (Tok.is(tok::annot_decltype)) {
+ // : declype(...)
+ DeclSpec DS(AttrFactory);
+ // : template_name<...>
+ ParsedType TemplateTypeTy;
+
+ if (Tok.is(tok::identifier)) {
+ // Get the identifier. This may be a member name or a class name,
+ // but we'll let the semantic analysis determine which it is.
+ II = Tok.getIdentifierInfo();
+ ConsumeToken();
+ } else if (Tok.is(tok::annot_decltype)) {
// Get the decltype expression, if there is one.
+ // Uses of decltype will already have been converted to annot_decltype by
+ // ParseOptionalCXXScopeSpecifier at this point.
+ // FIXME: Can we get here with a scope specifier?
ParseDecltypeSpecifier(DS);
} else {
- if (Tok.is(tok::identifier))
- // Get the identifier. This may be a member name or a class name,
- // but we'll let the semantic analysis determine which it is.
- II = Tok.getIdentifierInfo();
- ConsumeToken();
+ TemplateIdAnnotation *TemplateId = Tok.is(tok::annot_template_id)
+ ? takeTemplateIdAnnotation(Tok)
+ : nullptr;
+ if (TemplateId && (TemplateId->Kind == TNK_Type_template ||
+ TemplateId->Kind == TNK_Dependent_template_name)) {
+ AnnotateTemplateIdTokenAsType(/*IsClassName*/true);
+ assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
+ TemplateTypeTy = getTypeAnnotation(Tok);
+ ConsumeAnnotationToken();
+ } else {
+ Diag(Tok, diag::err_expected_member_or_base_name);
+ return true;
+ }
}
-
// Parse the '('.
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 727fd3500991..c739a50f0b38 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -192,6 +192,16 @@ Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
return ParseRHSOfBinaryExpression(R, prec::Assignment);
}
+ExprResult
+Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) {
+ assert(Actions.ExprEvalContexts.back().Context ==
+ Sema::ExpressionEvaluationContext::ConstantEvaluated &&
+ "Call this function only if your ExpressionEvaluationContext is "
+ "already ConstantEvaluated");
+ ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
+ ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+ return Actions.ActOnConstantExpression(Res);
+}
ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
// C++03 [basic.def.odr]p2:
@@ -200,10 +210,7 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
// C++98 and C++11 have no such rule, but this is only a defect in C++98.
EnterExpressionEvaluationContext ConstantEvaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
-
- ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
- ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
- return Actions.ActOnConstantExpression(Res);
+ return ParseConstantExpressionInExprEvalContext(isTypeCast);
}
/// \brief Parse a constraint-expression.
@@ -804,7 +811,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::annot_primary_expr:
assert(Res.get() == nullptr && "Stray primary-expression annotation?");
Res = getExprAnnotation(Tok);
- ConsumeToken();
+ ConsumeAnnotationToken();
break;
case tok::kw___super:
@@ -1199,7 +1206,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
if (Ty.isInvalid())
break;
- ConsumeToken();
+ ConsumeAnnotationToken();
Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
Ty.get(), nullptr);
break;
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 56093f685617..0b210e0360a1 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -160,7 +160,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
Tok.getAnnotationRange(),
SS);
- ConsumeToken();
+ ConsumeAnnotationToken();
return false;
}
@@ -346,7 +346,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
*LastII = TemplateId->Name;
// Consume the template-id token.
- ConsumeToken();
+ ConsumeAnnotationToken();
assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
SourceLocation CCLoc = ConsumeToken();
@@ -920,7 +920,7 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
PP.AnnotateCachedTokens(Tok);
// Consume the annotated initializer.
- ConsumeToken();
+ ConsumeAnnotationToken();
}
}
} else
@@ -1528,7 +1528,7 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
// store it in the pseudo-dtor node (to be used when instantiating it).
FirstTypeName.setTemplateId(
(TemplateIdAnnotation *)Tok.getAnnotationValue());
- ConsumeToken();
+ ConsumeAnnotationToken();
assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
CCLoc = ConsumeToken();
} else {
@@ -1882,7 +1882,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
DS.SetTypeSpecError();
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
- ConsumeToken();
+ ConsumeAnnotationToken();
DS.Finish(Actions, Policy);
return;
@@ -1951,11 +1951,8 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
DS.Finish(Actions, Policy);
return;
}
- if (Tok.is(tok::annot_typename))
- DS.SetRangeEnd(Tok.getAnnotationEndLoc());
- else
- DS.SetRangeEnd(Tok.getLocation());
- ConsumeToken();
+ ConsumeAnyToken();
+ DS.SetRangeEnd(PrevTokLocation);
DS.Finish(Actions, Policy);
}
@@ -2529,12 +2526,12 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
/*NontrivialTypeSourceInfo=*/true);
Result.setConstructorName(Ty, TemplateId->TemplateNameLoc,
TemplateId->RAngleLoc);
- ConsumeToken();
+ ConsumeAnnotationToken();
return false;
}
Result.setConstructorTemplateId(TemplateId);
- ConsumeToken();
+ ConsumeAnnotationToken();
return false;
}
@@ -2542,7 +2539,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
// our unqualified-id.
Result.setTemplateId(TemplateId);
TemplateKWLoc = TemplateId->TemplateKWLoc;
- ConsumeToken();
+ ConsumeAnnotationToken();
return false;
}
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 86ac035f3c8c..b925dd7053dc 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -532,7 +532,7 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
ConsumeAnyToken();
}
// Skip the last annot_pragma_openmp_end.
- SourceLocation EndLoc = ConsumeToken();
+ SourceLocation EndLoc = ConsumeAnnotationToken();
if (!IsError) {
return Actions.ActOnOpenMPDeclareSimdDirective(
Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
@@ -562,7 +562,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
ParenBraceBracketBalancer BalancerRAIIObj(*this);
- SourceLocation Loc = ConsumeToken();
+ SourceLocation Loc = ConsumeAnnotationToken();
auto DKind = ParseOpenMPDirectiveKind(*this);
switch (DKind) {
@@ -578,7 +578,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
}
// Skip the last annot_pragma_openmp_end.
- ConsumeToken();
+ ConsumeAnnotationToken();
return Actions.ActOnOpenMPThreadprivateDirective(Loc,
Helper.getIdentifiers());
}
@@ -596,7 +596,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
ConsumeAnyToken();
}
// Skip the last annot_pragma_openmp_end.
- ConsumeToken();
+ ConsumeAnnotationToken();
return Res;
}
break;
@@ -686,7 +686,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
ParseExternalDeclaration(attrs);
if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
TentativeParsingAction TPA(*this);
- ConsumeToken();
+ ConsumeAnnotationToken();
DKind = ParseOpenMPDirectiveKind(*this);
if (DKind != OMPD_end_declare_target)
TPA.Revert();
@@ -814,7 +814,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
FirstClauses(OMPC_unknown + 1);
unsigned ScopeFlags =
Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
- SourceLocation Loc = ConsumeToken(), EndLoc;
+ SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
auto DKind = ParseOpenMPDirectiveKind(*this);
OpenMPDirectiveKind CancelRegion = OMPD_unknown;
// Name of critical directive.
@@ -973,7 +973,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
// End location of the directive.
EndLoc = Tok.getLocation();
// Consume final annot_pragma_openmp_end.
- ConsumeToken();
+ ConsumeAnnotationToken();
// OpenMP [2.13.8, ordered Construct, Syntax]
// If the depend clause is specified, the ordered construct is a stand-alone
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index c34cd09a6238..18aebe658073 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -382,7 +382,7 @@ void Parser::resetPragmaHandlers() {
/// annot_pragma_unused 'x' annot_pragma_unused 'y'
void Parser::HandlePragmaUnused() {
assert(Tok.is(tok::annot_pragma_unused));
- SourceLocation UnusedLoc = ConsumeToken();
+ SourceLocation UnusedLoc = ConsumeAnnotationToken();
Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
ConsumeToken(); // The argument token.
}
@@ -391,7 +391,7 @@ void Parser::HandlePragmaVisibility() {
assert(Tok.is(tok::annot_pragma_vis));
const IdentifierInfo *VisType =
static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
- SourceLocation VisLoc = ConsumeToken();
+ SourceLocation VisLoc = ConsumeAnnotationToken();
Actions.ActOnPragmaVisibility(VisType, VisLoc);
}
@@ -407,7 +407,7 @@ void Parser::HandlePragmaPack() {
assert(Tok.is(tok::annot_pragma_pack));
PragmaPackInfo *Info =
static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
- SourceLocation PragmaLoc = ConsumeToken();
+ SourceLocation PragmaLoc = ConsumeAnnotationToken();
ExprResult Alignment;
if (Info->Alignment.is(tok::numeric_constant)) {
Alignment = Actions.ActOnNumericConstant(Info->Alignment);
@@ -423,7 +423,7 @@ void Parser::HandlePragmaMSStruct() {
PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
Actions.ActOnPragmaMSStruct(Kind);
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
}
void Parser::HandlePragmaAlign() {
@@ -431,7 +431,7 @@ void Parser::HandlePragmaAlign() {
Sema::PragmaOptionsAlignKind Kind =
static_cast<Sema::PragmaOptionsAlignKind>(
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
- SourceLocation PragmaLoc = ConsumeToken();
+ SourceLocation PragmaLoc = ConsumeAnnotationToken();
Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
}
@@ -440,12 +440,12 @@ void Parser::HandlePragmaDump() {
IdentifierInfo *II =
reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
- ConsumeToken();
+ ConsumeAnnotationToken();
}
void Parser::HandlePragmaWeak() {
assert(Tok.is(tok::annot_pragma_weak));
- SourceLocation PragmaLoc = ConsumeToken();
+ SourceLocation PragmaLoc = ConsumeAnnotationToken();
Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
Tok.getLocation());
ConsumeToken(); // The weak name.
@@ -453,7 +453,7 @@ void Parser::HandlePragmaWeak() {
void Parser::HandlePragmaWeakAlias() {
assert(Tok.is(tok::annot_pragma_weakalias));
- SourceLocation PragmaLoc = ConsumeToken();
+ SourceLocation PragmaLoc = ConsumeAnnotationToken();
IdentifierInfo *WeakName = Tok.getIdentifierInfo();
SourceLocation WeakNameLoc = Tok.getLocation();
ConsumeToken();
@@ -467,7 +467,7 @@ void Parser::HandlePragmaWeakAlias() {
void Parser::HandlePragmaRedefineExtname() {
assert(Tok.is(tok::annot_pragma_redefine_extname));
- SourceLocation RedefLoc = ConsumeToken();
+ SourceLocation RedefLoc = ConsumeAnnotationToken();
IdentifierInfo *RedefName = Tok.getIdentifierInfo();
SourceLocation RedefNameLoc = Tok.getLocation();
ConsumeToken();
@@ -498,13 +498,13 @@ void Parser::HandlePragmaFPContract() {
}
Actions.ActOnPragmaFPContract(FPC);
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
}
StmtResult Parser::HandlePragmaCaptured()
{
assert(Tok.is(tok::annot_pragma_captured));
- ConsumeToken();
+ ConsumeAnnotationToken();
if (Tok.isNot(tok::l_brace)) {
PP.Diag(Tok, diag::err_expected) << tok::l_brace;
@@ -541,7 +541,7 @@ void Parser::HandlePragmaOpenCLExtension() {
auto State = Data->second;
auto Ident = Data->first;
SourceLocation NameLoc = Tok.getLocation();
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
auto &Opt = Actions.getOpenCLOptions();
auto Name = Ident->getName();
@@ -580,7 +580,7 @@ void Parser::HandlePragmaMSPointersToMembers() {
LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
static_cast<LangOptions::PragmaMSPointersToMembersKind>(
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
- SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
+ SourceLocation PragmaLoc = ConsumeAnnotationToken();
Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
}
@@ -590,7 +590,7 @@ void Parser::HandlePragmaMSVtorDisp() {
Sema::PragmaMsStackAction Action =
static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
- SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
+ SourceLocation PragmaLoc = ConsumeAnnotationToken();
Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
}
@@ -600,7 +600,7 @@ void Parser::HandlePragmaMSPragma() {
auto TheTokens =
(std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true);
- SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
+ SourceLocation PragmaLocation = ConsumeAnnotationToken();
assert(Tok.isAnyIdentifier());
StringRef PragmaName = Tok.getIdentifierInfo()->getName();
PP.Lex(Tok); // pragma kind
@@ -896,7 +896,7 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) {
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
Hint.Range = Info->PragmaName.getLocation();
return true;
}
@@ -923,7 +923,7 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute;
// Verify loop hint has an argument.
if (Toks[0].is(tok::eof)) {
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
<< /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll
<< /*AssumeSafetyKeyword=*/AssumeSafetyArg;
@@ -932,7 +932,7 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
// Validate the argument.
if (StateOption) {
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
SourceLocation StateLoc = Toks[0].getLocation();
IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
@@ -955,7 +955,7 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
} else {
// Enter constant expression including eof terminator into token stream.
PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false);
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
ExprResult R = ParseConstantExpression();
@@ -1241,7 +1241,7 @@ void Parser::HandlePragmaAttribute() {
SourceLocation PragmaLoc = Tok.getLocation();
auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
if (Info->Action == PragmaAttributeInfo::Pop) {
- ConsumeToken();
+ ConsumeAnnotationToken();
Actions.ActOnPragmaAttributePop(PragmaLoc);
return;
}
@@ -1249,7 +1249,7 @@ void Parser::HandlePragmaAttribute() {
assert(Info->Action == PragmaAttributeInfo::Push &&
"Unexpected #pragma attribute command");
PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false);
- ConsumeToken();
+ ConsumeAnnotationToken();
ParsedAttributes &Attrs = Info->Attributes;
Attrs.clearListOnly();
@@ -2526,7 +2526,7 @@ void Parser::HandlePragmaFP() {
}
Actions.ActOnPragmaFPContract(FPC);
- ConsumeToken(); // The annotation token.
+ ConsumeAnnotationToken();
}
/// \brief Parses loop or unroll pragma hint value and fills in Info.
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 7d78046d0684..d147ab0a5674 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -338,13 +338,13 @@ Retry:
case tok::annot_pragma_fp_contract:
ProhibitAttributes(Attrs);
Diag(Tok, diag::err_pragma_fp_contract_scope);
- ConsumeToken();
+ ConsumeAnnotationToken();
return StmtError();
case tok::annot_pragma_fp:
ProhibitAttributes(Attrs);
Diag(Tok, diag::err_pragma_fp_scope);
- ConsumeToken();
+ ConsumeAnnotationToken();
return StmtError();
case tok::annot_pragma_opencl_extension:
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 6a81e14ed496..a919d870810a 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -1186,7 +1186,13 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() {
// expression is resolved to a type-id, regardless of the form of
// the corresponding template-parameter.
//
- // Therefore, we initially try to parse a type-id.
+ // Therefore, we initially try to parse a type-id - and isCXXTypeId might look
+ // up and annotate an identifier as an id-expression during disambiguation,
+ // so enter the appropriate context for a constant expression template
+ // argument before trying to disambiguate.
+
+ EnterExpressionEvaluationContext EnterConstantEvaluated(
+ Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
if (isCXXTypeId(TypeIdAsTemplateArgument)) {
SourceLocation Loc = Tok.getLocation();
TypeResult TypeArg = ParseTypeName(/*Range=*/nullptr,
@@ -1216,7 +1222,7 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() {
// Parse a non-type template argument.
SourceLocation Loc = Tok.getLocation();
- ExprResult ExprArg = ParseConstantExpression(MaybeTypeCast);
+ ExprResult ExprArg = ParseConstantExpressionInExprEvalContext(MaybeTypeCast);
if (ExprArg.isInvalid() || !ExprArg.get())
return ParsedTemplateArgument();
@@ -1234,7 +1240,7 @@ bool Parser::IsTemplateArgumentList(unsigned Skip) {
} Tentative(*this);
while (Skip) {
- ConsumeToken();
+ ConsumeAnyToken();
--Skip;
}
@@ -1248,7 +1254,7 @@ bool Parser::IsTemplateArgumentList(unsigned Skip) {
// See whether we have declaration specifiers, which indicate a type.
while (isCXXDeclarationSpecifier() == TPResult::True)
- ConsumeToken();
+ ConsumeAnyToken();
// If we have a '>' or a ',' then this is a template argument list.
return Tok.isOneOf(tok::greater, tok::comma);
@@ -1262,9 +1268,7 @@ bool Parser::IsTemplateArgumentList(unsigned Skip) {
/// template-argument-list ',' template-argument
bool
Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
- // Template argument lists are constant-evaluation contexts.
- EnterExpressionEvaluationContext EvalContext(
- Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+
ColonProtectionRAIIObject ColonProtection(*this, false);
do {
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 0ea3f8d95179..0d783131dd6e 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -208,17 +208,20 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
TryAnnotateCXXScopeToken())
return TPResult::Error;
if (Tok.is(tok::annot_cxxscope))
+ ConsumeAnnotationToken();
+ if (Tok.is(tok::identifier))
ConsumeToken();
- if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
+ else if (Tok.is(tok::annot_template_id))
+ ConsumeAnnotationToken();
+ else
return TPResult::Error;
- ConsumeToken();
break;
case tok::annot_cxxscope:
- ConsumeToken();
+ ConsumeAnnotationToken();
// Fall through.
default:
- ConsumeToken();
+ ConsumeAnyToken();
if (getLangOpts().ObjC1 && Tok.is(tok::less))
return TryParseProtocolQualifiers();
@@ -478,10 +481,10 @@ Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement) {
/// the corresponding ')'. If the context is
/// TypeIdAsTemplateArgument, we've already parsed the '<' or ','
/// before this template argument, and will cease lookahead when we
- /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id
- /// and false for an expression. If during the disambiguation
- /// process a parsing error is encountered, the function returns
- /// true to let the declaration parsing code handle it.
+ /// hit a '>', '>>' (in C++0x), or ','; or, in C++0x, an ellipsis immediately
+ /// preceding such. Returns true for a type-id and false for an expression.
+ /// If during the disambiguation process a parsing error is encountered,
+ /// the function returns true to let the declaration parsing code handle it.
///
/// type-id:
/// type-specifier-seq abstract-declarator[opt]
@@ -530,10 +533,15 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
// We are supposed to be inside a template argument, so if after
// the abstract declarator we encounter a '>', '>>' (in C++0x), or
- // ',', this is a type-id. Otherwise, it's an expression.
+ // ','; or, in C++0x, an ellipsis immediately preceding such, this
+ // is a type-id. Otherwise, it's an expression.
} else if (Context == TypeIdAsTemplateArgument &&
(Tok.isOneOf(tok::greater, tok::comma) ||
- (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)))) {
+ (getLangOpts().CPlusPlus11 &&
+ (Tok.is(tok::greatergreater) ||
+ (Tok.is(tok::ellipsis) &&
+ NextToken().isOneOf(tok::greater, tok::greatergreater,
+ tok::comma)))))) {
TPR = TPResult::True;
isAmbiguous = true;
@@ -706,7 +714,7 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() {
if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
(Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
// ptr-operator
- ConsumeToken();
+ ConsumeAnyToken();
while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
tok::kw__Nonnull, tok::kw__Nullable,
tok::kw__Null_unspecified))
@@ -826,14 +834,14 @@ Parser::TPResult Parser::TryParseOperatorId() {
/// abstract-declarator:
/// ptr-operator abstract-declarator[opt]
/// direct-abstract-declarator
-/// ...
///
/// direct-abstract-declarator:
/// direct-abstract-declarator[opt]
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
/// exception-specification[opt]
/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
/// '(' abstract-declarator ')'
+/// [C++0x] ...
///
/// ptr-operator:
/// '*' cv-qualifier-seq[opt]
@@ -883,7 +891,7 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
mayHaveIdentifier) {
// declarator-id
if (Tok.is(tok::annot_cxxscope))
- ConsumeToken();
+ ConsumeAnnotationToken();
else if (Tok.is(tok::identifier))
TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
if (Tok.is(tok::kw_operator)) {
@@ -925,10 +933,6 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
while (1) {
TPResult TPR(TPResult::Ambiguous);
- // abstract-declarator: ...
- if (Tok.is(tok::ellipsis))
- ConsumeToken();
-
if (Tok.is(tok::l_paren)) {
// Check whether we have a function declarator or a possible ctor-style
// initializer that follows the declarator. Note that ctor-style
@@ -1399,7 +1403,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
SS);
if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {
RevertingTentativeParsingAction PA(*this);
- ConsumeToken();
+ ConsumeAnnotationToken();
ConsumeToken();
bool isIdentifier = Tok.is(tok::identifier);
TPResult TPR = TPResult::False;
@@ -1471,7 +1475,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
if (getLangOpts().ObjC1 && NextToken().is(tok::less)) {
// Tentatively parse the protocol qualifiers.
RevertingTentativeParsingAction PA(*this);
- ConsumeToken(); // The type token
+ ConsumeAnyToken(); // The type token
TPResult TPR = TryParseProtocolQualifiers();
bool isFollowedByParen = Tok.is(tok::l_paren);
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 38476ce7e15d..4fe038d271ad 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -337,21 +337,13 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
ConsumeBrace();
break;
- case tok::string_literal:
- case tok::wide_string_literal:
- case tok::utf8_string_literal:
- case tok::utf16_string_literal:
- case tok::utf32_string_literal:
- ConsumeStringToken();
- break;
-
case tok::semi:
if (HasFlagsSet(Flags, StopAtSemi))
return false;
// FALL THROUGH.
default:
// Skip this token.
- ConsumeToken();
+ ConsumeAnyToken();
break;
}
isFirstTokenSkipped = false;
@@ -578,19 +570,19 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
Actions.ActOnModuleInclude(Tok.getLocation(),
reinterpret_cast<Module *>(
Tok.getAnnotationValue()));
- ConsumeToken();
+ ConsumeAnnotationToken();
return false;
case tok::annot_module_begin:
Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>(
Tok.getAnnotationValue()));
- ConsumeToken();
+ ConsumeAnnotationToken();
return false;
case tok::annot_module_end:
Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>(
Tok.getAnnotationValue()));
- ConsumeToken();
+ ConsumeAnnotationToken();
return false;
case tok::annot_pragma_attribute:
@@ -2169,7 +2161,7 @@ bool Parser::parseMisplacedModuleImport() {
Actions.ActOnModuleEnd(Tok.getLocation(),
reinterpret_cast<Module *>(
Tok.getAnnotationValue()));
- ConsumeToken();
+ ConsumeAnnotationToken();
continue;
}
// Inform caller that recovery failed, the error must be handled at upper
@@ -2181,7 +2173,7 @@ bool Parser::parseMisplacedModuleImport() {
Actions.ActOnModuleBegin(Tok.getLocation(),
reinterpret_cast<Module *>(
Tok.getAnnotationValue()));
- ConsumeToken();
+ ConsumeAnnotationToken();
++MisplacedModuleBeginCount;
continue;
case tok::annot_module_include:
@@ -2190,7 +2182,7 @@ bool Parser::parseMisplacedModuleImport() {
Actions.ActOnModuleInclude(Tok.getLocation(),
reinterpret_cast<Module *>(
Tok.getAnnotationValue()));
- ConsumeToken();
+ ConsumeAnnotationToken();
// If there is another module import, process it.
continue;
default:
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index dca51b0e8c8e..5e937aa69963 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2021,7 +2021,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
Diag(New->getLocation(), diag::err_redefinition_variably_modified_typedef)
<< Kind << NewType;
if (Old->getLocation().isValid())
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
New->setInvalidDecl();
return true;
}
@@ -2034,7 +2034,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
Diag(New->getLocation(), diag::err_redefinition_different_typedef)
<< Kind << NewType << OldType;
if (Old->getLocation().isValid())
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
New->setInvalidDecl();
return true;
}
@@ -2101,7 +2101,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
NamedDecl *OldD = OldDecls.getRepresentativeDecl();
if (OldD->getLocation().isValid())
- notePreviousDefinition(OldD->getLocation(), New->getLocation());
+ notePreviousDefinition(OldD, New->getLocation());
return New->setInvalidDecl();
}
@@ -2193,7 +2193,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
Diag(New->getLocation(), diag::err_redefinition)
<< New->getDeclName();
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
return New->setInvalidDecl();
}
@@ -2214,7 +2214,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
Diag(New->getLocation(), diag::ext_redefinition_of_typedef)
<< New->getDeclName();
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
}
/// DeclhasAttr - returns true if decl Declaration already has the target
@@ -2448,7 +2448,7 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
return false;
}
-static const Decl *getDefinition(const Decl *D) {
+static const NamedDecl *getDefinition(const Decl *D) {
if (const TagDecl *TD = dyn_cast<TagDecl>(D))
return TD->getDefinition();
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -2475,7 +2475,7 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
if (!New->hasAttrs())
return;
- const Decl *Def = getDefinition(Old);
+ const NamedDecl *Def = getDefinition(Old);
if (!Def || Def == New)
return;
@@ -2502,7 +2502,7 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
: diag::err_redefinition;
S.Diag(VD->getLocation(), Diag) << VD->getDeclName();
if (Diag == diag::err_redefinition)
- S.notePreviousDefinition(Def->getLocation(), VD->getLocation());
+ S.notePreviousDefinition(Def, VD->getLocation());
else
S.Diag(Def->getLocation(), diag::note_previous_definition);
VD->setInvalidDecl();
@@ -2891,7 +2891,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
} else {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
- notePreviousDefinition(OldD->getLocation(), New->getLocation());
+ notePreviousDefinition(OldD, New->getLocation());
return true;
}
}
@@ -2928,7 +2928,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
!Old->hasAttr<InternalLinkageAttr>()) {
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
<< New->getDeclName();
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
New->dropAttr<InternalLinkageAttr>();
}
@@ -3657,7 +3657,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
- notePreviousDefinition(Previous.getRepresentativeDecl()->getLocation(),
+ notePreviousDefinition(Previous.getRepresentativeDecl(),
New->getLocation());
return New->setInvalidDecl();
}
@@ -3687,7 +3687,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
Old->getStorageClass() == SC_None &&
!Old->hasAttr<WeakImportAttr>()) {
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
// Remove weak_import attribute on new declaration.
New->dropAttr<WeakImportAttr>();
}
@@ -3696,7 +3696,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
!Old->hasAttr<InternalLinkageAttr>()) {
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
<< New->getDeclName();
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
New->dropAttr<InternalLinkageAttr>();
}
@@ -3853,29 +3853,22 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
New->setImplicitlyInline();
}
-void Sema::notePreviousDefinition(SourceLocation Old, SourceLocation New) {
+void Sema::notePreviousDefinition(const NamedDecl *Old, SourceLocation New) {
SourceManager &SrcMgr = getSourceManager();
auto FNewDecLoc = SrcMgr.getDecomposedLoc(New);
- auto FOldDecLoc = SrcMgr.getDecomposedLoc(Old);
+ auto FOldDecLoc = SrcMgr.getDecomposedLoc(Old->getLocation());
auto *FNew = SrcMgr.getFileEntryForID(FNewDecLoc.first);
auto *FOld = SrcMgr.getFileEntryForID(FOldDecLoc.first);
auto &HSI = PP.getHeaderSearchInfo();
- StringRef HdrFilename = SrcMgr.getFilename(SrcMgr.getSpellingLoc(Old));
+ StringRef HdrFilename =
+ SrcMgr.getFilename(SrcMgr.getSpellingLoc(Old->getLocation()));
- auto noteFromModuleOrInclude = [&](SourceLocation &Loc,
- SourceLocation &IncLoc) -> bool {
- Module *Mod = nullptr;
+ auto noteFromModuleOrInclude = [&](Module *Mod,
+ SourceLocation IncLoc) -> bool {
// Redefinition errors with modules are common with non modular mapped
// headers, example: a non-modular header H in module A that also gets
// included directly in a TU. Pointing twice to the same header/definition
// is confusing, try to get better diagnostics when modules is on.
- if (getLangOpts().Modules) {
- auto ModLoc = SrcMgr.getModuleImportLoc(Old);
- if (!ModLoc.first.isInvalid())
- Mod = HSI.getModuleMap().inferModuleFromLocation(
- FullSourceLoc(Loc, SrcMgr));
- }
-
if (IncLoc.isValid()) {
if (Mod) {
Diag(IncLoc, diag::note_redefinition_modules_same_file)
@@ -3899,19 +3892,19 @@ void Sema::notePreviousDefinition(SourceLocation Old, SourceLocation New) {
if (FNew == FOld && FNewDecLoc.second == FOldDecLoc.second) {
SourceLocation OldIncLoc = SrcMgr.getIncludeLoc(FOldDecLoc.first);
SourceLocation NewIncLoc = SrcMgr.getIncludeLoc(FNewDecLoc.first);
- EmittedDiag = noteFromModuleOrInclude(Old, OldIncLoc);
- EmittedDiag |= noteFromModuleOrInclude(New, NewIncLoc);
+ EmittedDiag = noteFromModuleOrInclude(Old->getOwningModule(), OldIncLoc);
+ EmittedDiag |= noteFromModuleOrInclude(getCurrentModule(), NewIncLoc);
// If the header has no guards, emit a note suggesting one.
if (FOld && !HSI.isFileMultipleIncludeGuarded(FOld))
- Diag(Old, diag::note_use_ifdef_guards);
+ Diag(Old->getLocation(), diag::note_use_ifdef_guards);
if (EmittedDiag)
return;
}
// Redefinition coming from different files or couldn't do better above.
- Diag(Old, diag::note_previous_definition);
+ Diag(Old->getLocation(), diag::note_previous_definition);
}
/// We've just determined that \p Old and \p New both appear to be definitions
@@ -3934,7 +3927,7 @@ bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
return false;
} else {
Diag(New->getLocation(), diag::err_redefinition) << New;
- notePreviousDefinition(Old->getLocation(), New->getLocation());
+ notePreviousDefinition(Old, New->getLocation());
New->setInvalidDecl();
return true;
}
@@ -6942,7 +6935,7 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl,
}
}
- DeclContext *OldDC = ShadowedDecl->getDeclContext();
+ DeclContext *OldDC = ShadowedDecl->getDeclContext()->getRedeclContext();
unsigned WarningDiag = diag::warn_decl_shadow;
SourceLocation CaptureLoc;
@@ -7198,7 +7191,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
// ISO/IEC TR 18037 S5.1.2
if (!getLangOpts().OpenCL
&& NewVD->hasLocalStorage() && T.getAddressSpace() != 0) {
- Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl);
+ Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 0;
NewVD->setInvalidDecl();
return;
}
@@ -7278,6 +7271,11 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
NewVD->setInvalidDecl();
return;
}
+ } else if (T.getAddressSpace() != LangAS::Default) {
+ // Do not allow other address spaces on automatic variable.
+ Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 1;
+ NewVD->setInvalidDecl();
+ return;
}
}
}
@@ -13503,9 +13501,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
} else if (TUK == TUK_Reference &&
(PrevTagDecl->getFriendObjectKind() ==
Decl::FOK_Undeclared ||
- PP.getModuleContainingLocation(
- PrevDecl->getLocation()) !=
- PP.getModuleContainingLocation(KWLoc)) &&
+ PrevDecl->getOwningModule() != getCurrentModule()) &&
SS.isEmpty()) {
// This declaration is a reference to an existing entity, but
// has different visibility from that entity: it either makes
@@ -13561,7 +13557,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name;
else
Diag(NameLoc, diag::err_redefinition) << Name;
- notePreviousDefinition(Def->getLocation(),
+ notePreviousDefinition(Def,
NameLoc.isValid() ? NameLoc : KWLoc);
// If this is a redefinition, recover by making this
// struct be anonymous, which will make any later
@@ -13652,7 +13648,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// The tag name clashes with something else in the target scope,
// issue an error and recover by making this tag be anonymous.
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
- notePreviousDefinition(PrevDecl->getLocation(), NameLoc);
+ notePreviousDefinition(PrevDecl, NameLoc);
Name = nullptr;
Invalid = true;
}
@@ -15356,7 +15352,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
Diag(IdLoc, diag::err_redefinition_of_enumerator) << Id;
else
Diag(IdLoc, diag::err_redefinition) << Id;
- notePreviousDefinition(PrevDecl->getLocation(), IdLoc);
+ notePreviousDefinition(PrevDecl, IdLoc);
return nullptr;
}
}
@@ -16052,8 +16048,10 @@ void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
// FIXME: Consider creating a child DeclContext to hold the entities
// lexically within the module.
if (getLangOpts().trackLocalOwningModule()) {
- cast<Decl>(CurContext)->setHidden(true);
- cast<Decl>(CurContext)->setLocalOwningModule(Mod);
+ for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
+ cast<Decl>(DC)->setHidden(true);
+ cast<Decl>(DC)->setLocalOwningModule(Mod);
+ }
}
}
@@ -16086,9 +16084,13 @@ void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) {
// Any further declarations are in whatever module we returned to.
if (getLangOpts().trackLocalOwningModule()) {
- cast<Decl>(CurContext)->setLocalOwningModule(getCurrentModule());
- if (!getCurrentModule())
- cast<Decl>(CurContext)->setHidden(false);
+ // The parser guarantees that this is the same context that we entered
+ // the module within.
+ for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
+ cast<Decl>(DC)->setLocalOwningModule(getCurrentModule());
+ if (!getCurrentModule())
+ cast<Decl>(DC)->setHidden(false);
+ }
}
}
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 3de792e4e406..32be26efa14f 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -5935,12 +5935,18 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleDLLAttr(S, D, Attr);
break;
case AttributeList::AT_Mips16:
- handleSimpleAttributeWithExclusions<Mips16Attr, MipsInterruptAttr>(S, D,
- Attr);
+ handleSimpleAttributeWithExclusions<Mips16Attr, MicroMipsAttr,
+ MipsInterruptAttr>(S, D, Attr);
break;
case AttributeList::AT_NoMips16:
handleSimpleAttribute<NoMips16Attr>(S, D, Attr);
break;
+ case AttributeList::AT_MicroMips:
+ handleSimpleAttributeWithExclusions<MicroMipsAttr, Mips16Attr>(S, D, Attr);
+ break;
+ case AttributeList::AT_NoMicroMips:
+ handleSimpleAttribute<NoMicroMipsAttr>(S, D, Attr);
+ break;
case AttributeList::AT_AMDGPUFlatWorkGroupSize:
handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr);
break;
@@ -7252,6 +7258,12 @@ public:
bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
+ bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
+ if (PRE->isClassReceiver())
+ DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation());
+ return true;
+ }
+
bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
if (ObjCMethodDecl *D = Msg->getMethodDecl())
DiagnoseDeclAvailability(
@@ -7381,6 +7393,9 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) {
const Type *TyPtr = Ty.getTypePtr();
SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()};
+ if (Range.isInvalid())
+ return true;
+
if (const TagType *TT = dyn_cast<TagType>(TyPtr)) {
TagDecl *TD = TT->getDecl();
DiagnoseDeclAvailability(TD, Range);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 04350831c681..678817f02996 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1420,11 +1420,46 @@ bool Sema::hasVisibleDefaultArgument(const NamedDecl *D,
Modules);
}
+template<typename Filter>
+static bool hasVisibleDeclarationImpl(Sema &S, const NamedDecl *D,
+ llvm::SmallVectorImpl<Module *> *Modules,
+ Filter F) {
+ for (auto *Redecl : D->redecls()) {
+ auto *R = cast<NamedDecl>(Redecl);
+ if (!F(R))
+ continue;
+
+ if (S.isVisible(R))
+ return true;
+
+ if (Modules) {
+ Modules->push_back(R->getOwningModule());
+ const auto &Merged = S.Context.getModulesWithMergedDefinition(R);
+ Modules->insert(Modules->end(), Merged.begin(), Merged.end());
+ }
+ }
+
+ return false;
+}
+
+bool Sema::hasVisibleExplicitSpecialization(
+ const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules) {
+ return hasVisibleDeclarationImpl(*this, D, Modules, [](const NamedDecl *D) {
+ if (auto *RD = dyn_cast<CXXRecordDecl>(D))
+ return RD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
+ if (auto *FD = dyn_cast<FunctionDecl>(D))
+ return FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ return VD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
+ llvm_unreachable("unknown explicit specialization kind");
+ });
+}
+
bool Sema::hasVisibleMemberSpecialization(
const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules) {
assert(isa<CXXRecordDecl>(D->getDeclContext()) &&
"not a member specialization");
- for (auto *Redecl : D->redecls()) {
+ return hasVisibleDeclarationImpl(*this, D, Modules, [](const NamedDecl *D) {
// If the specialization is declared at namespace scope, then it's a member
// specialization declaration. If it's lexically inside the class
// definition then it was instantiated.
@@ -1432,19 +1467,8 @@ bool Sema::hasVisibleMemberSpecialization(
// FIXME: This is a hack. There should be a better way to determine this.
// FIXME: What about MS-style explicit specializations declared within a
// class definition?
- if (Redecl->getLexicalDeclContext()->isFileContext()) {
- auto *NonConstR = const_cast<NamedDecl*>(cast<NamedDecl>(Redecl));
-
- if (isVisible(NonConstR))
- return true;
-
- if (Modules) {
- Modules->push_back(getOwningModule(NonConstR));
- const auto &Merged = Context.getModulesWithMergedDefinition(NonConstR);
- Modules->insert(Modules->end(), Merged.begin(), Merged.end());
- }
- }
- }
+ return D->getLexicalDeclContext()->isFileContext();
+ });
return false;
}
@@ -1459,23 +1483,19 @@ bool Sema::hasVisibleMemberSpecialization(
/// your module can see, including those later on in your module).
bool LookupResult::isVisibleSlow(Sema &SemaRef, NamedDecl *D) {
assert(D->isHidden() && "should not call this: not in slow case");
- Module *DeclModule = nullptr;
-
- if (SemaRef.getLangOpts().ModulesLocalVisibility) {
- DeclModule = SemaRef.getOwningModule(D);
- if (!DeclModule) {
- assert(!D->isHidden() && "hidden decl not from a module");
- return true;
- }
- // If the owning module is visible, and the decl is not module private,
- // then the decl is visible too. (Module private is ignored within the same
- // top-level module.)
- if ((!D->isFromASTFile() || !D->isModulePrivate()) &&
- (SemaRef.isModuleVisible(DeclModule) ||
- SemaRef.hasVisibleMergedDefinition(D)))
- return true;
- }
+ Module *DeclModule = SemaRef.getOwningModule(D);
+ assert(DeclModule && "hidden decl not from a module");
+
+ // If the owning module is visible, and the decl is not module private,
+ // then the decl is visible too. (Module private is ignored within the same
+ // top-level module.)
+ // FIXME: Check the owning module for module-private declarations rather than
+ // assuming "same AST file" is the same thing as "same module".
+ if ((!D->isFromASTFile() || !D->isModulePrivate()) &&
+ (SemaRef.isModuleVisible(DeclModule) ||
+ SemaRef.hasVisibleMergedDefinition(D)))
+ return true;
// If this declaration is not at namespace scope nor module-private,
// then it is visible if its lexical parent has a visible definition.
@@ -1571,20 +1591,8 @@ static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
bool Sema::hasVisibleDeclarationSlow(const NamedDecl *D,
llvm::SmallVectorImpl<Module *> *Modules) {
assert(!isVisible(D) && "not in slow case");
-
- for (auto *Redecl : D->redecls()) {
- auto *NonConstR = const_cast<NamedDecl*>(cast<NamedDecl>(Redecl));
- if (isVisible(NonConstR))
- return true;
-
- if (Modules) {
- Modules->push_back(getOwningModule(NonConstR));
- const auto &Merged = Context.getModulesWithMergedDefinition(NonConstR);
- Modules->insert(Modules->end(), Merged.begin(), Merged.end());
- }
- }
-
- return false;
+ return hasVisibleDeclarationImpl(*this, D, Modules,
+ [](const NamedDecl *) { return true; });
}
NamedDecl *LookupResult::getAcceptableDeclSlow(NamedDecl *D) const {
@@ -4957,6 +4965,14 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
MissingImportKind MIK, bool Recover) {
assert(!Modules.empty());
+ // Weed out duplicates from module list.
+ llvm::SmallVector<Module*, 8> UniqueModules;
+ llvm::SmallDenseSet<Module*, 8> UniqueModuleSet;
+ for (auto *M : Modules)
+ if (UniqueModuleSet.insert(M).second)
+ UniqueModules.push_back(M);
+ Modules = UniqueModules;
+
if (Modules.size() > 1) {
std::string ModuleList;
unsigned N = 0;
@@ -4971,8 +4987,8 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
Diag(UseLoc, diag::err_module_unimported_use_multiple)
<< (int)MIK << Decl << ModuleList;
- } else if (const FileEntry *E =
- PP.getModuleHeaderToIncludeForDiagnostics(UseLoc, DeclLoc)) {
+ } else if (const FileEntry *E = PP.getModuleHeaderToIncludeForDiagnostics(
+ UseLoc, Modules[0], DeclLoc)) {
// The right way to make the declaration visible is to include a header;
// suggest doing so.
//
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index a479d1027533..8cd7efbb1dba 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -7901,6 +7901,7 @@ bool Sema::CheckFunctionTemplateSpecialization(
TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind();
if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) {
Specialization->setLocation(FD->getLocation());
+ Specialization->setLexicalDeclContext(FD->getLexicalDeclContext());
// C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr
// function can differ from the template declaration with respect to
// the constexpr specifier.
@@ -7961,6 +7962,7 @@ bool Sema::CheckFunctionTemplateSpecialization(
// FIXME: We need an update record for this AST mutation.
Specialization->setDeletedAsWritten(false);
}
+ // FIXME: We need an update record for this AST mutation.
SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
MarkUnusedFileScopedDecl(Specialization);
}
@@ -9745,7 +9747,7 @@ private:
IsHiddenExplicitSpecialization =
Spec->getMemberSpecializationInfo()
? !S.hasVisibleMemberSpecialization(Spec, &Modules)
- : !S.hasVisibleDeclaration(Spec);
+ : !S.hasVisibleExplicitSpecialization(Spec, &Modules);
} else {
checkInstantiated(Spec);
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 03df6fde6c80..e7523ce2836d 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1540,8 +1540,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
// DR1484 clarifies that the members of a local class are instantiated as part
// of the instantiation of their enclosing entity.
if (D->isCompleteDefinition() && D->isLocalClass()) {
- Sema::SavePendingLocalImplicitInstantiationsRAII
- SavedPendingLocalImplicitInstantiations(SemaRef);
+ Sema::LocalEagerInstantiationScope LocalInstantiations(SemaRef);
SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs,
TSK_ImplicitInstantiation,
@@ -1555,7 +1554,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
// This class may have local implicit instantiations that need to be
// performed within this scope.
- SemaRef.PerformPendingInstantiations(/*LocalOnly=*/true);
+ LocalInstantiations.perform();
}
SemaRef.DiagnoseUnusedNestedTypedefs(Record);
@@ -3812,10 +3811,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// while we're still within our own instantiation context.
// This has to happen before LateTemplateParser below is called, so that
// it marks vtables used in late parsed templates as used.
- SavePendingLocalImplicitInstantiationsRAII
- SavedPendingLocalImplicitInstantiations(*this);
- SavePendingInstantiationsAndVTableUsesRAII
- SavePendingInstantiationsAndVTableUses(*this, /*Enabled=*/Recursive);
+ GlobalEagerInstantiationScope GlobalInstantiations(*this,
+ /*Enabled=*/Recursive);
+ LocalEagerInstantiationScope LocalInstantiations(*this);
// Call the LateTemplateParser callback if there is a need to late parse
// a templated function definition.
@@ -3942,20 +3940,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// This class may have local implicit instantiations that need to be
// instantiation within this scope.
- PerformPendingInstantiations(/*LocalOnly=*/true);
+ LocalInstantiations.perform();
Scope.Exit();
-
- if (Recursive) {
- // Define any pending vtables.
- DefineUsedVTables();
-
- // Instantiate any pending implicit instantiations found during the
- // instantiation of this template.
- PerformPendingInstantiations();
-
- // PendingInstantiations and VTableUses are restored through
- // SavePendingInstantiationsAndVTableUses's destructor.
- }
+ GlobalInstantiations.perform();
}
VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
@@ -4287,10 +4274,10 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate
// later, while we're still within our own instantiation context.
- SavePendingInstantiationsAndVTableUsesRAII
- SavePendingInstantiationsAndVTableUses(*this, /*Enabled=*/Recursive);
-
+ GlobalEagerInstantiationScope GlobalInstantiations(*this,
+ /*Enabled=*/Recursive);
LocalInstantiationScope Local(*this);
+ LocalEagerInstantiationScope LocalInstantiations(*this);
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
@@ -4303,21 +4290,9 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
// This variable may have local implicit instantiations that need to be
// instantiated within this scope.
- PerformPendingInstantiations(/*LocalOnly=*/true);
-
+ LocalInstantiations.perform();
Local.Exit();
-
- if (Recursive) {
- // Define any newly required vtables.
- DefineUsedVTables();
-
- // Instantiate any pending implicit instantiations found during the
- // instantiation of this template.
- PerformPendingInstantiations();
-
- // PendingInstantiations and VTableUses are restored through
- // SavePendingInstantiationsAndVTableUses's destructor.
- }
+ GlobalInstantiations.perform();
}
// Find actual definition
@@ -4408,16 +4383,16 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate later,
// while we're still within our own instantiation context.
- SavePendingLocalImplicitInstantiationsRAII
- SavedPendingLocalImplicitInstantiations(*this);
- SavePendingInstantiationsAndVTableUsesRAII
- SavePendingInstantiationsAndVTableUses(*this, /*Enabled=*/Recursive);
+ GlobalEagerInstantiationScope GlobalInstantiations(*this,
+ /*Enabled=*/Recursive);
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
ContextRAII PreviousContext(*this, Var->getDeclContext());
LocalInstantiationScope Local(*this);
+ LocalEagerInstantiationScope LocalInstantiations(*this);
+
VarDecl *OldVar = Var;
if (Def->isStaticDataMember() && !Def->isOutOfLine()) {
// We're instantiating an inline static data member whose definition was
@@ -4470,21 +4445,9 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
// This variable may have local implicit instantiations that need to be
// instantiated within this scope.
- PerformPendingInstantiations(/*LocalOnly=*/true);
-
+ LocalInstantiations.perform();
Local.Exit();
-
- if (Recursive) {
- // Define any newly required vtables.
- DefineUsedVTables();
-
- // Instantiate any pending implicit instantiations found during the
- // instantiation of this template.
- PerformPendingInstantiations();
-
- // PendingInstantiations and VTableUses are restored through
- // SavePendingInstantiationsAndVTableUses's destructor.
- }
+ GlobalInstantiations.perform();
}
void
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 3992179fabae..f8970744389b 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -3735,16 +3735,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// inner pointers.
complainAboutMissingNullability = CAMN_InnerPointers;
- auto isDependentNonPointerType = [](QualType T) -> bool {
- // Note: This is intended to be the same check as Type::canHaveNullability
- // except with all of the ambiguous cases being treated as 'false' rather
- // than 'true'.
- return T->isDependentType() && !T->isAnyPointerType() &&
- !T->isBlockPointerType() && !T->isMemberPointerType();
- };
-
- if (T->canHaveNullability() && !T->getNullability(S.Context) &&
- !isDependentNonPointerType(T)) {
+ if (T->canHaveNullability(/*ResultIfUnknown*/false) &&
+ !T->getNullability(S.Context)) {
// Note that we allow but don't require nullability on dependent types.
++NumPointersRemaining;
}
@@ -3962,7 +3954,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// If the type itself could have nullability but does not, infer pointer
// nullability and perform consistency checking.
if (S.CodeSynthesisContexts.empty()) {
- if (T->canHaveNullability() && !T->getNullability(S.Context)) {
+ if (T->canHaveNullability(/*ResultIfUnknown*/false) &&
+ !T->getNullability(S.Context)) {
if (isVaList(T)) {
// Record that we've seen a pointer, but do nothing else.
if (NumPointersRemaining > 0)
@@ -5531,14 +5524,15 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
addrSpace.setIsSigned(false);
}
llvm::APSInt max(addrSpace.getBitWidth());
- max = Qualifiers::MaxAddressSpace - LangAS::Count;
+ max = Qualifiers::MaxAddressSpace - LangAS::FirstTargetAddressSpace;
if (addrSpace > max) {
S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
<< (unsigned)max.getZExtValue() << ASArgExpr->getSourceRange();
Attr.setInvalid();
return;
}
- ASIdx = static_cast<unsigned>(addrSpace.getZExtValue()) + LangAS::Count;
+ ASIdx = static_cast<unsigned>(addrSpace.getZExtValue()) +
+ LangAS::FirstTargetAddressSpace;
} else {
// The keyword-based type attributes imply which address space to use.
switch (Attr.getKind()) {
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 5cabd0e6740d..55cb670f427e 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -2756,7 +2756,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// If we've already loaded the decl, perform the updates when we finish
// loading this block.
if (Decl *D = GetExistingDecl(ID))
- PendingUpdateRecords.push_back(std::make_pair(ID, D));
+ PendingUpdateRecords.push_back(
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
break;
}
@@ -3086,7 +3087,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// If we've already loaded the decl, perform the updates when we finish
// loading this block.
if (Decl *D = GetExistingDecl(ID))
- PendingUpdateRecords.push_back(std::make_pair(ID, D));
+ PendingUpdateRecords.push_back(
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
}
break;
}
@@ -8956,7 +8958,7 @@ void ASTReader::finishPendingActions() {
while (!PendingUpdateRecords.empty()) {
auto Update = PendingUpdateRecords.pop_back_val();
ReadingKindTracker ReadingKind(Read_Decl, *this);
- loadDeclUpdateRecords(Update.first, Update.second);
+ loadDeclUpdateRecords(Update);
}
}
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index e0304d22fe50..f3ee9078298e 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -3612,7 +3612,8 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
assert(Record.getIdx() == Record.size());
// Load any relevant update records.
- PendingUpdateRecords.push_back(std::make_pair(ID, D));
+ PendingUpdateRecords.push_back(
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/true));
// Load the categories after recursive loading is finished.
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
@@ -3657,20 +3658,24 @@ void ASTReader::PassInterestingDeclsToConsumer() {
}
}
-void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
+void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
// The declaration may have been modified by files later in the chain.
// If this is the case, read the record containing the updates from each file
// and pass it to ASTDeclReader to make the modifications.
+ serialization::GlobalDeclID ID = Record.ID;
+ Decl *D = Record.D;
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
if (UpdI != DeclUpdateOffsets.end()) {
auto UpdateOffsets = std::move(UpdI->second);
DeclUpdateOffsets.erase(UpdI);
- // FIXME: This call to isConsumerInterestedIn is not safe because
- // we could be deserializing declarations at the moment. We should
- // delay calling this in the same way as done in D30793.
- bool WasInteresting = isConsumerInterestedIn(Context, D, false);
+ // Check if this decl was interesting to the consumer. If we just loaded
+ // the declaration, then we know it was interesting and we skip the call
+ // to isConsumerInterestedIn because it is unsafe to call in the
+ // current ASTReader state.
+ bool WasInteresting =
+ Record.JustLoaded || isConsumerInterestedIn(Context, D, false);
for (auto &FileAndOffset : UpdateOffsets) {
ModuleFile *F = FileAndOffset.first;
uint64_t Offset = FileAndOffset.second;
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index b6c0cb2815fb..b3556371c9b8 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2841,25 +2841,6 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
"non-imported submodule?");
}
-serialization::SubmoduleID
-ASTWriter::inferSubmoduleIDFromLocation(SourceLocation Loc) {
- if (Loc.isInvalid() || !WritingModule)
- return 0; // No submodule
-
- // Find the module that owns this location.
- ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
- Module *OwningMod
- = ModMap.inferModuleFromLocation(FullSourceLoc(Loc,PP->getSourceManager()));
- if (!OwningMod)
- return 0;
-
- // Check whether this submodule is part of our own module.
- if (WritingModule != OwningMod && !OwningMod->isSubModuleOf(WritingModule))
- return 0;
-
- return getSubmoduleID(OwningMod);
-}
-
void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
bool isModule) {
llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 812cd9e916d9..8fa64aa1b9d3 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -299,7 +299,7 @@ void ASTDeclWriter::VisitDecl(Decl *D) {
Record.push_back(D->isTopLevelDeclInObjCContainer());
Record.push_back(D->getAccess());
Record.push_back(D->isModulePrivate());
- Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
+ Record.push_back(Writer.getSubmoduleID(D->getOwningModule()));
// If this declaration injected a name into a context different from its
// lexical context, and that context is an imported namespace, we need to
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 2114033ba8b5..2c3169c0f8dd 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -3448,14 +3448,12 @@ void BugReporter::FlushReport(BugReport *exampleReport,
// the BugReporterVisitors may mark this bug as a false positive.
assert(!bugReports.empty());
- MaxBugClassSize =
- std::max(bugReports.size(), static_cast<size_t>(MaxBugClassSize));
+ MaxBugClassSize.updateMax(bugReports.size());
if (!generatePathDiagnostic(*D.get(), PD, bugReports))
return;
- MaxValidBugClassSize =
- std::max(bugReports.size(), static_cast<size_t>(MaxValidBugClassSize));
+ MaxValidBugClassSize.updateMax(bugReports.size());
// Examine the report and see if the last piece is in a header. Reset the
// report location to the last piece in the main source file.
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 0fe0f3a6ed58..c47edc7d2125 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -674,10 +674,8 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
DisplayFunction(D, Mode, IMode);
CFG *DeclCFG = Mgr->getCFG(D);
- if (DeclCFG) {
- unsigned CFGSize = DeclCFG->size();
- MaxCFGSize = MaxCFGSize < CFGSize ? CFGSize : MaxCFGSize;
- }
+ if (DeclCFG)
+ MaxCFGSize.updateMax(DeclCFG->size());
BugReporter BR(*Mgr);
diff --git a/test/CodeGen/address-space.c b/test/CodeGen/address-space.c
index 5d57d5b6ebe5..35e3dbdcfa73 100644
--- a/test/CodeGen/address-space.c
+++ b/test/CodeGen/address-space.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck -check-prefixes=CHECK,GIZ %s
// RUN: %clang_cc1 -triple amdgcn -emit-llvm < %s | FileCheck -check-prefixes=CHECK,PIZ %s
-// RUN: %clang_cc1 -triple amdgcn---amdgiz -emit-llvm < %s | FileCheck -check-prefixes=CHeCK,GIZ %s
+// RUN: %clang_cc1 -triple amdgcn---amdgiz -emit-llvm < %s | FileCheck -check-prefixes=CHECK,GIZ %s
// CHECK: @foo = common addrspace(1) global
int foo __attribute__((address_space(1)));
@@ -40,8 +40,10 @@ typedef struct {
} MyStruct;
// CHECK-LABEL: define void @test4(
-// CHECK: call void @llvm.memcpy.p0i8.p2i8
-// CHECK: call void @llvm.memcpy.p2i8.p0i8
+// GIZ: call void @llvm.memcpy.p0i8.p2i8
+// GIZ: call void @llvm.memcpy.p2i8.p0i8
+// PIZ: call void @llvm.memcpy.p4i8.p2i8
+// PIZ: call void @llvm.memcpy.p2i8.p4i8
void test4(MyStruct __attribute__((address_space(2))) *pPtr) {
MyStruct s = pPtr[0];
pPtr[0] = s;
diff --git a/test/CodeGen/micromips-attr.c b/test/CodeGen/micromips-attr.c
new file mode 100644
index 000000000000..96ba774afc0f
--- /dev/null
+++ b/test/CodeGen/micromips-attr.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((micromips)) foo (void) {}
+
+// CHECK: define void @foo() [[MICROMIPS:#[0-9]+]]
+
+void __attribute__((nomicromips)) nofoo (void) {}
+
+// CHECK: define void @nofoo() [[NOMICROMIPS:#[0-9]+]]
+
+// CHECK: attributes [[MICROMIPS]] = { noinline nounwind {{.*}} "micromips" {{.*}} }
+// CHECK: attributes [[NOMICROMIPS]] = { noinline nounwind {{.*}} "nomicromips" {{.*}} }
diff --git a/test/CodeGen/wchar-size.c b/test/CodeGen/wchar-size.c
new file mode 100644
index 000000000000..38da462d98cb
--- /dev/null
+++ b/test/CodeGen/wchar-size.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s -check-prefix=LONG-WCHAR
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix=SHORT-WCHAR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - -fshort-wchar %s | FileCheck %s -check-prefix=SHORT-WCHAR
+// Note: -fno-short-wchar implies the target default is used; so there is no
+// need to test this separately here.
+
+// LONG-WCHAR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"wchar_size", i32 4}
+// SHORT-WCHAR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"wchar_size", i32 2}
diff --git a/test/CodeGenCUDA/flush-denormals.cu b/test/CodeGenCUDA/flush-denormals.cu
index e528d7b102d4..94285f1f33ce 100644
--- a/test/CodeGenCUDA/flush-denormals.cu
+++ b/test/CodeGenCUDA/flush-denormals.cu
@@ -18,8 +18,8 @@ extern "C" __device__ void foo() {}
// FTZ: attributes #0 = {{.*}} "nvptx-f32ftz"="true"
// NOFTZ-NOT: attributes #0 = {{.*}} "nvptx-f32ftz"
-// FTZ:!llvm.module.flags = !{[[MODFLAG:![0-9]+]]}
+// FTZ:!llvm.module.flags = !{{{.*}}[[MODFLAG:![0-9]+]]}
// FTZ:[[MODFLAG]] = !{i32 4, !"nvvm-reflect-ftz", i32 1}
-// NOFTZ:!llvm.module.flags = !{[[MODFLAG:![0-9]+]]}
+// NOFTZ:!llvm.module.flags = !{{{.*}}[[MODFLAG:![0-9]+]]}
// NOFTZ:[[MODFLAG]] = !{i32 4, !"nvvm-reflect-ftz", i32 0}
diff --git a/test/CodeGenCXX/amdgcn-automatic-variable.cpp b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
new file mode 100644
index 000000000000..aab720770d12
--- /dev/null
+++ b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -O0 -triple amdgcn---amdgiz -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define void @_Z5func1Pi(i32* %x)
+void func1(int *x) {
+ // CHECK: %[[x_addr:.*]] = alloca i32*{{.*}}addrspace(5)
+ // CHECK: store i32* %x, i32* addrspace(5)* %[[x_addr]]
+ // CHECK: %[[r0:.*]] = load i32*, i32* addrspace(5)* %[[x_addr]]
+ // CHECK: store i32 1, i32* %[[r0]]
+ *x = 1;
+}
+
+// CHECK-LABEL: define void @_Z5func2v()
+void func2(void) {
+ // CHECK: %lv1 = alloca i32, align 4, addrspace(5)
+ // CHECK: %lv2 = alloca i32, align 4, addrspace(5)
+ // CHECK: %la = alloca [100 x i32], align 4, addrspace(5)
+ // CHECK: %lp1 = alloca i32*, align 4, addrspace(5)
+ // CHECK: %lp2 = alloca i32*, align 4, addrspace(5)
+ // CHECK: %lvc = alloca i32, align 4, addrspace(5)
+
+ // CHECK: %[[r0:.*]] = addrspacecast i32 addrspace(5)* %lv1 to i32*
+ // CHECK: store i32 1, i32* %[[r0]]
+ int lv1;
+ lv1 = 1;
+ // CHECK: %[[r1:.*]] = addrspacecast i32 addrspace(5)* %lv2 to i32*
+ // CHECK: store i32 2, i32* %[[r1]]
+ int lv2 = 2;
+
+ // CHECK: %[[r2:.*]] = addrspacecast [100 x i32] addrspace(5)* %la to [100 x i32]*
+ // CHECK: %[[arrayidx:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i64 0, i64 0
+ // CHECK: store i32 3, i32* %[[arrayidx]], align 4
+ int la[100];
+ la[0] = 3;
+
+ // CHECK: %[[r3:.*]] = addrspacecast i32* addrspace(5)* %lp1 to i32**
+ // CHECK: store i32* %[[r0]], i32** %[[r3]], align 4
+ int *lp1 = &lv1;
+
+ // CHECK: %[[r4:.*]] = addrspacecast i32* addrspace(5)* %lp2 to i32**
+ // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i32 0, i32 0
+ // CHECK: store i32* %[[arraydecay]], i32** %[[r4]], align 4
+ int *lp2 = la;
+
+ // CHECK: call void @_Z5func1Pi(i32* %[[r0]])
+ func1(&lv1);
+
+ // CHECK: %[[r5:.*]] = addrspacecast i32 addrspace(5)* %lvc to i32*
+ // CHECK: store i32 4, i32* %[[r5]]
+ // CHECK: store i32 4, i32* %[[r0]]
+ const int lvc = 4;
+ lv1 = lvc;
+}
+
+void destroy(int x);
+
+class A {
+int x;
+public:
+ A():x(0) {}
+ ~A() {
+ destroy(x);
+ }
+};
+
+// CHECK-LABEL: define void @_Z5func3v
+void func3() {
+ // CHECK: %[[a:.*]] = alloca %class.A, align 4, addrspace(5)
+ // CHECK: %[[r0:.*]] = addrspacecast %class.A addrspace(5)* %[[a]] to %class.A*
+ // CHECK: call void @_ZN1AC1Ev(%class.A* %[[r0]])
+ // CHECK: call void @_ZN1AD1Ev(%class.A* %[[r0]])
+ A a;
+}
diff --git a/test/CodeGenCXX/strict-vtable-pointers.cpp b/test/CodeGenCXX/strict-vtable-pointers.cpp
index 21f85b1c5772..928817bfb1f5 100644
--- a/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ b/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -211,7 +211,7 @@ struct DynamicFromStatic;
// CHECK-DTORS-LABEL: {{^}}}
-// CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:.*]], ![[SEC:.*]]{{.*}}}
+// CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:[0-9]+]], ![[SEC:[0-9]+]]{{.*}}}
// CHECK-LINK-REQ: ![[FIRST]] = !{i32 1, !"StrictVTablePointers", i32 1}
// CHECK-LINK-REQ: ![[SEC]] = !{i32 3, !"StrictVTablePointersRequirement", ![[META:.*]]}
diff --git a/test/CodeGenOpenCL/amdgcn-automatic-variable.cl b/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
new file mode 100644
index 000000000000..29309567ec71
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -O0 -cl-std=CL1.2 -triple amdgcn---amdgizcl -emit-llvm %s -o - | FileCheck -check-prefixes=CHECK,CL12 %s
+// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple amdgcn---amdgizcl -emit-llvm %s -o - | FileCheck -check-prefixes=CHECK,CL20 %s
+
+// CL12-LABEL: define void @func1(i32 addrspace(5)* %x)
+// CL20-LABEL: define void @func1(i32* %x)
+void func1(int *x) {
+ // CL12: %[[x_addr:.*]] = alloca i32 addrspace(5)*{{.*}}addrspace(5)
+ // CL12: store i32 addrspace(5)* %x, i32 addrspace(5)* addrspace(5)* %[[x_addr]]
+ // CL12: %[[r0:.*]] = load i32 addrspace(5)*, i32 addrspace(5)* addrspace(5)* %[[x_addr]]
+ // CL12: store i32 1, i32 addrspace(5)* %[[r0]]
+ // CL20: %[[x_addr:.*]] = alloca i32*{{.*}}addrspace(5)
+ // CL20: store i32* %x, i32* addrspace(5)* %[[x_addr]]
+ // CL20: %[[r0:.*]] = load i32*, i32* addrspace(5)* %[[x_addr]]
+ // CL20: store i32 1, i32* %[[r0]]
+ *x = 1;
+}
+
+// CHECK-LABEL: define void @func2()
+void func2(void) {
+ // CHECK: %lv1 = alloca i32, align 4, addrspace(5)
+ // CHECK: %lv2 = alloca i32, align 4, addrspace(5)
+ // CHECK: %la = alloca [100 x i32], align 4, addrspace(5)
+ // CL12: %lp1 = alloca i32 addrspace(5)*, align 4, addrspace(5)
+ // CL12: %lp2 = alloca i32 addrspace(5)*, align 4, addrspace(5)
+ // CL20: %lp1 = alloca i32*, align 4, addrspace(5)
+ // CL20: %lp2 = alloca i32*, align 4, addrspace(5)
+ // CHECK: %lvc = alloca i32, align 4, addrspace(5)
+
+ // CHECK: store i32 1, i32 addrspace(5)* %lv1
+ int lv1;
+ lv1 = 1;
+ // CHECK: store i32 2, i32 addrspace(5)* %lv2
+ int lv2 = 2;
+
+ // CHECK: %[[arrayidx:.*]] = getelementptr inbounds [100 x i32], [100 x i32] addrspace(5)* %la, i64 0, i64 0
+ // CHECK: store i32 3, i32 addrspace(5)* %[[arrayidx]], align 4
+ int la[100];
+ la[0] = 3;
+
+ // CL12: store i32 addrspace(5)* %lv1, i32 addrspace(5)* addrspace(5)* %lp1, align 4
+ // CL20: %[[r0:.*]] = addrspacecast i32 addrspace(5)* %lv1 to i32*
+ // CL20: store i32* %[[r0]], i32* addrspace(5)* %lp1, align 4
+ int *lp1 = &lv1;
+
+ // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32] addrspace(5)* %la, i32 0, i32 0
+ // CL12: store i32 addrspace(5)* %[[arraydecay]], i32 addrspace(5)* addrspace(5)* %lp2, align 4
+ // CL20: %[[r1:.*]] = addrspacecast i32 addrspace(5)* %[[arraydecay]] to i32*
+ // CL20: store i32* %[[r1]], i32* addrspace(5)* %lp2, align 4
+ int *lp2 = la;
+
+ // CL12: call void @func1(i32 addrspace(5)* %lv1)
+ // CL20: %[[r2:.*]] = addrspacecast i32 addrspace(5)* %lv1 to i32*
+ // CL20: call void @func1(i32* %[[r2]])
+ func1(&lv1);
+
+ // CHECK: store i32 4, i32 addrspace(5)* %lvc
+ // CHECK: store i32 4, i32 addrspace(5)* %lv1
+ const int lvc = 4;
+ lv1 = lvc;
+}
diff --git a/test/CodeGenOpenCL/amdgpu-alignment.cl b/test/CodeGenOpenCL/amdgpu-alignment.cl
index 35a8342eec01..714e7240f539 100644
--- a/test/CodeGenOpenCL/amdgpu-alignment.cl
+++ b/test/CodeGenOpenCL/amdgpu-alignment.cl
@@ -1,5 +1,5 @@
// REQUIRES: amdgpu-registered-target
-// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown-opencl -S -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
index 7baee5eee391..061ce2cca2fc 100644
--- a/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
@@ -1,4 +1,4 @@
-// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
+// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa-opencl -mcpu=fiji -o - %s | FileCheck %s
// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_NONE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}})
// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_LOCAL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 2)
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
index c0a4c21ce760..8cf086bf8dcc 100644
--- a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
@@ -1,4 +1,4 @@
-// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
+// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa-opencl -mcpu=fiji -o - %s | FileCheck %s
// CHECK-DAG: ![[LOCAL:[0-9]+]] = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
// CHECK-DAG: ![[PRIVATE:[0-9]+]] = !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)
diff --git a/test/CodeGenOpenCL/amdgpu-nullptr.cl b/test/CodeGenOpenCL/amdgpu-nullptr.cl
index 37c7469aa180..3e54cd5c34a0 100644
--- a/test/CodeGenOpenCL/amdgpu-nullptr.cl
+++ b/test/CodeGenOpenCL/amdgpu-nullptr.cl
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s -O0 -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck --check-prefix=NOOPT %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O0 -cl-std=CL2.0 -include opencl-c.h -triple amdgcn---opencl -emit-llvm -o - | FileCheck --check-prefix=NOOPT %s
typedef struct {
private char *p1;
diff --git a/test/CodeGenOpenCL/builtins-amdgcn.cl b/test/CodeGenOpenCL/builtins-amdgcn.cl
index a19ce2f1ed59..fdbae9b531c1 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn.cl
@@ -1,5 +1,5 @@
// REQUIRES: amdgpu-registered-target
-// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown-opencl -S -emit-llvm -o - %s | FileCheck %s
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
diff --git a/test/CodeGenOpenCL/byval.cl b/test/CodeGenOpenCL/byval.cl
index 1a8105c5207f..a7c5adfb79d6 100644
--- a/test/CodeGenOpenCL/byval.cl
+++ b/test/CodeGenOpenCL/byval.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---opencl %s | FileCheck %s
// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s -check-prefix=AMDGIZ
struct A {
diff --git a/test/CodeGenOpenCL/size_t.cl b/test/CodeGenOpenCL/size_t.cl
index ed941e01852d..20f29fe1cd41 100644
--- a/test/CodeGenOpenCL/size_t.cl
+++ b/test/CodeGenOpenCL/size_t.cl
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple spir-unknown-unknown -o - | FileCheck --check-prefix=SZ32 %s
// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple spir64-unknown-unknown -o - | FileCheck --check-prefix=SZ64 --check-prefix=SZ64ONLY %s
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple amdgcn-- -o - | FileCheck --check-prefix=SZ64 --check-prefix=AMDONLY %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple amdgcn---opencl -o - | FileCheck --check-prefix=SZ64 --check-prefix=AMDONLY %s
//SZ32: define{{.*}} i32 @test_ptrtoint_private(i8* %x)
//SZ32: ptrtoint i8* %{{.*}} to i32
diff --git a/test/Index/Core/external-source-symbol-attr.m b/test/Index/Core/external-source-symbol-attr.m
index 49a075fc74e0..cdc52966977d 100644
--- a/test/Index/Core/external-source-symbol-attr.m
+++ b/test/Index/Core/external-source-symbol-attr.m
@@ -4,6 +4,10 @@
#define GEN_DECL(mod_name) __attribute__((external_source_symbol(language="Swift", defined_in=mod_name, generated_declaration)))
#define PUSH_GEN_DECL(mod_name) push(GEN_DECL(mod_name), apply_to=any(enum, objc_interface, objc_category, objc_protocol))
+// Forward declarations should not affect module namespacing below
+@class I1;
+@class I2;
+
// This should not be indexed.
GEN_DECL("some_module")
@interface I1
diff --git a/test/Index/Core/index-dependent-source.cpp b/test/Index/Core/index-dependent-source.cpp
index 8c097b935a37..59c6286cd3dd 100644
--- a/test/Index/Core/index-dependent-source.cpp
+++ b/test/Index/Core/index-dependent-source.cpp
@@ -141,3 +141,20 @@ void undefinedTemplateLookup2(UserOfUndefinedTemplateClass<T> &x) {
x.lookup;
typename UserOfUndefinedTemplateClass<T>::Type y;
}
+
+template<typename T> struct Dropper;
+
+template<typename T> struct Trait;
+
+template<typename T>
+struct Recurse : Trait<typename Dropper<T>::Type> { };
+
+template<typename T>
+struct Trait : Recurse<T> {
+};
+
+template<typename T>
+void infiniteTraitRecursion(Trait<T> &t) {
+// Shouldn't crash!
+ t.lookup;
+}
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 9248e86ff697..8b049314ffbe 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -1,7 +1,7 @@
// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | <no-cgname> | Def | rel: 0
-class Cls {
+class Cls { public:
// CHECK: [[@LINE+3]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
// CHECK-NEXT: RelChild | Cls | c:@S@Cls
// CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
@@ -339,3 +339,97 @@ void ::ns::inner::func() {
// CHECK: [[@LINE-1]]:3 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
// CHECK: [[@LINE-2]]:7 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Ref,RelCont | rel: 1
}
+
+void innerUsingNamespace() {
+ using namespace ns;
+// CHECK: [[@LINE-1]]:19 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+ {
+ using namespace ns::innerAlias;
+// CHECK: [[@LINE-1]]:25 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:21 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-3]]:21
+ }
+}
+
+void indexDefaultValueInDefn(Cls cls = Cls(gvi), Record param = Record()) {
+// CHECK: [[@LINE-1]]:40 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:44 | variable/C | gvi | c:@gvi | _gvi | Ref,Read,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-3]]:44
+// CHECK: [[@LINE-4]]:65 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-5]]:65
+}
+
+template<template <typename> class T>
+struct IndexDefaultValue {
+ IndexDefaultValue(int k = Record::C) {
+// CHECK: [[@LINE-1]]:38 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:30 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+ }
+};
+
+struct DeletedMethods {
+ DeletedMethods(const DeletedMethods &) = delete;
+// CHECK: [[@LINE-1]]:3 | constructor/cxx-copy-ctor/C++ | DeletedMethods | c:@S@DeletedMethods@F@DeletedMethods#&1$@S@DeletedMethods# | __ZN14DeletedMethodsC1ERKS_ | Def,RelChild | rel: 1
+// CHECK: RelChild | DeletedMethods | c:@S@DeletedMethods
+// CHECK: [[@LINE-3]]:24 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
+};
+
+namespace ns2 {
+template<typename T> struct ACollectionDecl { };
+}
+
+template<typename T = Cls,
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+ int x = Record::C,
+// CHECK: [[@LINE-1]]:26 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+// CHECK: [[@LINE-3]]:18 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+ template <typename> class Collection = ns2::ACollectionDecl>
+// CHECK: [[@LINE-1]]:49 | namespace/C++ | ns2 | c:@N@ns2 | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+// CHECK: [[@LINE-3]]:54 | struct(Gen)/C++ | ACollectionDecl | c:@N@ns2@ST>1#T@ACollectionDecl | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+struct TemplateDefaultValues { };
+
+template<typename T = Record,
+// CHECK: [[@LINE-1]]:23 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+ int x = sizeof(Cls)>
+// CHECK: [[@LINE-1]]:25 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+void functionTemplateDefaultValues() { }
+
+namespace ensureDefaultTemplateParamsAreRecordedOnce {
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-2]]:23
+void functionDecl();
+
+template<typename T>
+void functionDecl() { }
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-2]]:23
+class TagDecl;
+
+template<typename T>
+class TagDecl;
+
+template<typename T>
+class TagDecl { };
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+using TypeAlias = TagDecl<T>;
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-2]]:23
+extern T varDecl;
+
+template<typename T>
+T varDecl = T();
+
+} // end namespace ensureDefaultTemplateParamsAreRecordedOnce
diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m
index 041753b95316..7c2f753e71db 100644
--- a/test/Index/Core/index-source.m
+++ b/test/Index/Core/index-source.m
@@ -385,3 +385,22 @@ Separate separateT;
// CHECK: [[@LINE-1]]:1 | type-alias/C | Separate | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
struct Separate separateE;
// CHECK: [[@LINE-1]]:8 | struct/C | Separate | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
+
+@interface ClassReceivers
+
+@property(class) int p1;
++ (int)implicit;
++ (void)setImplicit:(int)x;
+
+@end
+
+void classReceivers() {
+ ClassReceivers.p1 = 0;
+// CHECK: [[@LINE-1]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+ (void)ClassReceivers.p1;
+// CHECK: [[@LINE-1]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+ ClassReceivers.implicit = 0;
+// CHECK: [[@LINE-1]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+ (void)ClassReceivers.implicit;
+// CHECK: [[@LINE-1]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+}
diff --git a/test/Misc/pragma-attribute-supported-attributes-list.test b/test/Misc/pragma-attribute-supported-attributes-list.test
index 0db17bdf4026..d698276f7dc4 100644
--- a/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -2,7 +2,7 @@
// The number of supported attributes should never go down!
-// CHECK: #pragma clang attribute supports 60 attributes:
+// CHECK: #pragma clang attribute supports 62 attributes:
// CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@@ -30,8 +30,10 @@
// CHECK-NEXT: IFunc (SubjectMatchRule_function)
// CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
// CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record)
+// CHECK-NEXT: MicroMips (SubjectMatchRule_function)
// CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
// CHECK-NEXT: NoDuplicate (SubjectMatchRule_function)
+// CHECK-NEXT: NoMicroMips (SubjectMatchRule_function)
// CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSplitStack (SubjectMatchRule_function)
diff --git a/test/Modules/extern_cxx.cpp b/test/Modules/extern_cxx.cpp
new file mode 100644
index 000000000000..97ec726de234
--- /dev/null
+++ b/test/Modules/extern_cxx.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -x c++-module-map -fmodule-name=A -verify %s -fmodules-local-submodule-visibility
+module A { module B {} module C {} }
+
+#pragma clang module contents
+
+#pragma clang module begin A.B
+extern "C++" {
+ #pragma clang module begin A.C
+ template<typename T> void f(T t);
+ #pragma clang module end
+
+ void g() { f(0); } // ok
+}
+
+extern "C++" {
+ #pragma clang module begin A.C
+ } // expected-error {{extraneous closing brace}}
+ #pragma clang module end
+
+ #pragma clang module begin A.C
+ extern "C++" { // expected-note {{to match this '{'}}
+ #pragma clang module end // expected-error {{expected '}' at end of module}}
+}
+
+#pragma clang module end
diff --git a/test/Modules/macro-redefinition.cpp b/test/Modules/macro-redefinition.cpp
new file mode 100644
index 000000000000..7b1c7b658624
--- /dev/null
+++ b/test/Modules/macro-redefinition.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fmodules -x c++-module-map %s -fmodule-name=__usr_include -verify
+// RUN: %clang_cc1 -fmodules -x c++-module-map %s -fmodule-name=__usr_include -verify -DIMPORT
+
+module __usr_include {
+ module stddef {}
+ module stdlib {}
+}
+
+#pragma clang module contents
+
+// expected-no-diagnostics
+
+#pragma clang module begin __usr_include.stddef
+ #define NULL 0
+#pragma clang module end
+
+#pragma clang module begin __usr_include.stdlib
+ #ifdef IMPORT
+ #pragma clang module import __usr_include.stddef
+ #else
+ #pragma clang module begin __usr_include.stddef
+ #define NULL 0
+ #pragma clang module end
+ #endif
+
+ void *f() { return NULL; } // ok, NULL is visible here
+#pragma clang module end
diff --git a/test/Modules/preprocess-module.cpp b/test/Modules/preprocess-module.cpp
index 64af00c471df..eaab3136938f 100644
--- a/test/Modules/preprocess-module.cpp
+++ b/test/Modules/preprocess-module.cpp
@@ -25,8 +25,8 @@
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -fmodule-map-file=%S/Inputs/preprocess/module.modulemap -x c++-module-map-cpp-output %t/rewrite.ii -emit-module -o /dev/null
// Check the module we built works.
-// RUN: %clang_cc1 -fmodules -fmodule-file=%t/no-rewrite.pcm %s -verify
-// RUN: %clang_cc1 -fmodules -fmodule-file=%t/rewrite.pcm %s -verify
+// RUN: %clang_cc1 -fmodules -fmodule-file=%t/no-rewrite.pcm %s -I%t -verify -fno-modules-error-recovery
+// RUN: %clang_cc1 -fmodules -fmodule-file=%t/rewrite.pcm %s -I%t -verify -fno-modules-error-recovery -DREWRITE
// == module map
@@ -95,10 +95,12 @@
// NO-REWRITE: #pragma clang module end
-// expected-no-diagnostics
-
-// FIXME: This should be rejected: we have not imported the submodule defining it yet.
-__FILE *a;
+__FILE *a; // expected-error {{declaration of '__FILE' must be imported}}
+#ifdef REWRITE
+// expected-note@rewrite.ii:1 {{here}}
+#else
+// expected-note@no-rewrite.ii:1 {{here}}
+#endif
#pragma clang module import file
diff --git a/test/Parser/cxx-template-argument.cpp b/test/Parser/cxx-template-argument.cpp
index 9b8ca985ddd9..963356eaaba3 100644
--- a/test/Parser/cxx-template-argument.cpp
+++ b/test/Parser/cxx-template-argument.cpp
@@ -10,7 +10,7 @@ template<typename T> struct A {};
// Check for template argument lists followed by junk
// FIXME: The diagnostics here aren't great...
A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}}
-A<int x; // expected-error {{type-id cannot have a name}} expected-error {{expected '>'}}
+A<int x; // expected-error {{expected '>'}}
// PR8912
template <bool> struct S {};
diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp
index 4a1b4ad777a6..71d32b8f51d9 100644
--- a/test/Parser/cxx0x-ambig.cpp
+++ b/test/Parser/cxx0x-ambig.cpp
@@ -132,6 +132,32 @@ namespace ellipsis {
void l(int(*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}}
void l(int(S<int>::*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}}
};
+
+ struct CtorSink {
+ template <typename ...T> constexpr CtorSink(T &&...t) { }
+ constexpr operator int() const { return 42; }
+ };
+
+ template <unsigned ...N> struct UnsignedTmplArgSink;
+
+ template <typename ...T>
+ void foo(int x, T ...t) {
+ // Have a variety of cases where the syntax is technically unambiguous, but hinges on careful treatment of ellipses.
+ CtorSink(t ...), x; // ok, expression; expected-warning 2{{expression result unused}}
+
+ int x0(CtorSink(t ...)); // ok, declares object x0
+ int *p0 = &x0;
+ (void)p0;
+
+ CtorSink x1(int(t) ..., int(x)); // ok, declares object x1
+ CtorSink *p1 = &x1;
+ (void)p1;
+
+ UnsignedTmplArgSink<T(CtorSink(t ...)) ...> *t0; // ok
+ UnsignedTmplArgSink<((T *)0, 42u) ...> **t0p = &t0;
+ }
+
+ template void foo(int, int, int); // expected-note {{in instantiation of function template specialization 'ellipsis::foo<int, int>' requested here}}
}
namespace braced_init_list {
diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp
index d912e19287be..2b253c019c97 100644
--- a/test/Parser/cxx0x-decl.cpp
+++ b/test/Parser/cxx0x-decl.cpp
@@ -123,6 +123,25 @@ namespace ColonColonDecltype {
::decltype(S())::T invalid; // expected-error {{expected unqualified-id}}
}
+namespace AliasDeclEndLocation {
+ template<typename T> struct A {};
+ // Ensure that we correctly determine the end of this declaration to be the
+ // end of the annotation token, not the beginning.
+ using B = AliasDeclEndLocation::A<int
+ > // expected-error {{expected ';' after alias declaration}}
+ +;
+ // FIXME: After splitting this >> into two > tokens, we incorrectly determine
+ // the end of the template-id to be after the *second* '>'.
+ // Perhaps we could synthesize an expansion FileID containing '> >' to fix this?
+ using C = AliasDeclEndLocation::A<int
+ >\
+> // expected-error {{expected ';' after alias declaration}}
+ ;
+ using D = AliasDeclEndLocation::A<int
+ > // expected-error {{expected ';' after alias declaration}}
+ B something_else;
+}
+
struct Base { virtual void f() = 0; virtual void g() = 0; virtual void h() = 0; };
struct MemberComponentOrder : Base {
void f() override __asm__("foobar") __attribute__(( )) {}
diff --git a/test/Sema/attr-micromips.c b/test/Sema/attr-micromips.c
new file mode 100644
index 000000000000..fe587fa3db07
--- /dev/null
+++ b/test/Sema/attr-micromips.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s
+
+__attribute__((nomicromips(0))) void foo1(); // expected-error {{'nomicromips' attribute takes no arguments}}
+__attribute__((micromips(1))) void foo2(); // expected-error {{'micromips' attribute takes no arguments}}
+
+__attribute((nomicromips)) int a; // expected-error {{attribute only applies to functions}}
+__attribute((micromips)) int b; // expected-error {{attribute only applies to functions}}
+
+__attribute__((micromips,mips16)) void foo5(); // expected-error {{'micromips' and 'mips16' attributes are not compatible}} \
+ // expected-note {{conflicting attribute is here}}
+__attribute__((mips16,micromips)) void foo6(); // expected-error {{'mips16' and 'micromips' attributes are not compatible}} \
+ // expected-note {{conflicting attribute is here}}
+
+__attribute((micromips)) void foo7();
+__attribute((nomicromips)) void foo8();
+__attribute__((mips16)) void foo9(void) __attribute__((micromips)); // expected-error {{'micromips' and 'mips16' attributes are not compatible}} \
+ // expected-note {{conflicting attribute is here}}
diff --git a/test/Sema/block-args.c b/test/Sema/block-args.c
index c6beead3915b..69cf047a9ece 100644
--- a/test/Sema/block-args.c
+++ b/test/Sema/block-args.c
@@ -37,7 +37,7 @@ void f0() {
// rdar://problem/8962770
void test4() {
- int (^f)() = ^((x)) { }; // expected-error {{expected ')'}} expected-warning {{type specifier missing}} expected-note {{to match this}}
+ int (^f)() = ^((x)) { }; // expected-warning {{type specifier missing}} expected-error {{type-id cannot have a name}}
}
// rdar://problem/9170609
diff --git a/test/Sema/integer-overflow.c b/test/Sema/integer-overflow.c
index 62ee33e3d181..c2b6ba209b71 100644
--- a/test/Sema/integer-overflow.c
+++ b/test/Sema/integer-overflow.c
@@ -151,6 +151,14 @@ uint64_t check_integer_overflows(int i) {
uint64_t *b;
uint64_t b2 = b[4608 * 1024 * 1024] + 1;
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
+ f0(4608 * 1024 * 1024);
+ f0(4608ul * 1024 * 1024);
+// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
+ f1(4608 * 1024 * 1024, 4608 * 1024 * 1024);
+// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
+ f2(4608 * 1024 * 1024, 4608 * 1024 * 1024);
+
// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
diff --git a/test/Sema/sizeof-struct-non-zero-as-member.cl b/test/Sema/sizeof-struct-non-zero-as-member.cl
index 0e13c61503aa..cd959735fe81 100644
--- a/test/Sema/sizeof-struct-non-zero-as-member.cl
+++ b/test/Sema/sizeof-struct-non-zero-as-member.cl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -triple amdgcn -target-cpu verde -S -emit-llvm -o - %s
+// RUN: %clang_cc1 -verify -fsyntax-only -triple amdgcn--opencl -target-cpu verde -S -emit-llvm -o - %s
// expected-no-diagnostics
// Record lowering was crashing on SI and newer targets, because it
diff --git a/test/SemaCXX/Inputs/nullability-completeness.h b/test/SemaCXX/Inputs/nullability-completeness.h
new file mode 100644
index 000000000000..1b30e1b4d906
--- /dev/null
+++ b/test/SemaCXX/Inputs/nullability-completeness.h
@@ -0,0 +1,4 @@
+template<typename T> struct Template final {
+ int *_Nonnull x;
+ T y;
+};
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index e0ab15dc6327..efbb47681ade 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -525,9 +525,9 @@ template <int N>
class S {};
void foo() {
- const int num = 18; // expected-note {{'num' declared here}}
+ const int num = 18;
auto outer = []() {
- auto inner = [](S<num> &X) {}; // expected-error {{variable 'num' cannot be implicitly captured in a lambda with no capture-default specified}}
+ auto inner = [](S<num> &X) {};
};
}
}
@@ -573,3 +573,13 @@ void foo1() {
auto s1 = S1{[name=name]() {}}; // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
}
}
+
+namespace PR25627_dont_odr_use_local_consts {
+
+ template<int> struct X {};
+
+ void foo() {
+ const int N = 10;
+ (void) [] { X<N> x; };
+ }
+}
diff --git a/test/SemaCXX/local-classes.cpp b/test/SemaCXX/local-classes.cpp
index f4ca79159dc9..eb0b7e43ebe4 100644
--- a/test/SemaCXX/local-classes.cpp
+++ b/test/SemaCXX/local-classes.cpp
@@ -40,3 +40,15 @@ namespace Templates {
};
}
}
+
+namespace PR25627_dont_odr_use_local_consts {
+ template<int> struct X { X(); X(int); };
+
+ void foo() {
+ const int N = 10;
+
+ struct Local {
+ void f(X<N> = X<N>()) {} // OK
+ };
+ }
+}
diff --git a/test/SemaCXX/modules-ts.cppm b/test/SemaCXX/modules-ts.cppm
index d1d7aaa96e6c..29122ec7dab5 100644
--- a/test/SemaCXX/modules-ts.cppm
+++ b/test/SemaCXX/modules-ts.cppm
@@ -18,7 +18,8 @@ int n;
#if TEST >= 2
// expected-error@-2 {{redefinition of '}}
// expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}}
-// expected-note-re@modules-ts.cppm:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site here}}
+// FIXME: We should drop the "header from" in this diagnostic.
+// expected-note-re@modules-ts.cppm:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site in header from module 'foo'}}
#endif
#if TEST == 0
diff --git a/test/SemaCXX/nullability.cpp b/test/SemaCXX/nullability.cpp
index 160741b1409c..99375a9fdde3 100644
--- a/test/SemaCXX/nullability.cpp
+++ b/test/SemaCXX/nullability.cpp
@@ -1,10 +1,12 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-nullability-declspec %s -verify -Wnullable-to-nonnull-conversion -I%S/Inputs
#if __has_feature(nullability)
#else
# error nullability feature should be defined
#endif
+#include "nullability-completeness.h"
+
typedef decltype(nullptr) nullptr_t;
class X {
@@ -130,3 +132,7 @@ void arraysInLambdas() {
withTypedef(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
auto withTypedefBad = [](INTS _Nonnull[2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int [4]')}}
}
+
+void testNullabilityCompletenessWithTemplate() {
+ Template<int*> tip;
+}
diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp
index 0b84ef50caa1..d5f0623eb320 100644
--- a/test/SemaCXX/warn-shadow.cpp
+++ b/test/SemaCXX/warn-shadow.cpp
@@ -206,3 +206,10 @@ void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition
}
}
+
+extern "C" {
+typedef int externC; // expected-note {{previous declaration is here}}
+}
+void handleLinkageSpec() {
+ typedef void externC; // expected-warning {{declaration shadows a typedef in the global namespace}}
+}
diff --git a/test/SemaObjC/unguarded-availability.m b/test/SemaObjC/unguarded-availability.m
index 071a21ea1b3f..82823204ba61 100644
--- a/test/SemaObjC/unguarded-availability.m
+++ b/test/SemaObjC/unguarded-availability.m
@@ -135,6 +135,26 @@ void (^topLevelBlockDecl)() = ^ {
func_10_12();
};
+AVAILABLE_10_12
+__attribute__((objc_root_class))
+@interface InterWithProp // expected-note 2 {{marked partial here}}
+@property(class) int x;
++ (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+void test_property(void) {
+ int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+ InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+__attribute__((objc_root_class))
+@interface Subscriptable
+- (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+
+void test_at(Subscriptable *x) {
+ id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
#ifdef OBJCPP
int f(char) AVAILABLE_10_12;
diff --git a/test/SemaOpenCL/storageclass-cl20.cl b/test/SemaOpenCL/storageclass-cl20.cl
index 1eba64b44c8a..b12676fe7437 100644
--- a/test/SemaOpenCL/storageclass-cl20.cl
+++ b/test/SemaOpenCL/storageclass-cl20.cl
@@ -12,7 +12,9 @@ void kernel foo() {
constant int L1 = 0;
local int L2;
- global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
+ global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
+ generic int L4; // expected-error{{automatic variable qualified with an invalid address space}}
+ __attribute__((address_space(100))) int L5; // expected-error{{automatic variable qualified with an invalid address space}}
extern global int G5;
extern int G6; // expected-error{{extern variable must reside in global or constant address space}}
diff --git a/test/SemaOpenCL/storageclass.cl b/test/SemaOpenCL/storageclass.cl
index f457cfd1d3f6..e611313b4a70 100644
--- a/test/SemaOpenCL/storageclass.cl
+++ b/test/SemaOpenCL/storageclass.cl
@@ -13,29 +13,37 @@ void kernel foo(int x) {
constant int L1 = 0;
local int L2;
- auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}}
- global int L4; // expected-error{{function scope variable cannot be declared in global address space}}
-
- constant int L5 = x; // expected-error {{initializer element is not a compile-time constant}}
- global int *constant L6 = &G4;
- private int *constant L7 = &x; // expected-error {{initializer element is not a compile-time constant}}
- constant int *constant L8 = &L1;
- local int *constant L9 = &L2; // expected-error {{initializer element is not a compile-time constant}}
+ auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}}
+ global int L4; // expected-error{{function scope variable cannot be declared in global address space}}
+ __attribute__((address_space(100))) int L5; // expected-error{{automatic variable qualified with an invalid address space}}
+
+ constant int L6 = x; // expected-error {{initializer element is not a compile-time constant}}
+ global int *constant L7 = &G4;
+ private int *constant L8 = &x; // expected-error {{initializer element is not a compile-time constant}}
+ constant int *constant L9 = &L1;
+ local int *constant L10 = &L2; // expected-error {{initializer element is not a compile-time constant}}
}
static void kernel bar() { // expected-error{{kernel functions cannot be declared static}}
}
void f() {
- constant int L1 = 0; // expected-error{{non-kernel function variable cannot be declared in constant address space}}
- local int L2; // expected-error{{non-kernel function variable cannot be declared in local address space}}
+ constant int L1 = 0; // expected-error{{non-kernel function variable cannot be declared in constant address space}}
+ local int L2; // expected-error{{non-kernel function variable cannot be declared in local address space}}
+ global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
+ __attribute__((address_space(100))) int L4; // expected-error{{automatic variable qualified with an invalid address space}}
+
{
- constant int L1 = 0; // expected-error{{non-kernel function variable cannot be declared in constant address space}}
- local int L2; // expected-error{{non-kernel function variable cannot be declared in local address space}}
+ constant int L1 = 0; // expected-error{{non-kernel function variable cannot be declared in constant address space}}
+ local int L2; // expected-error{{non-kernel function variable cannot be declared in local address space}}
+ global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
+ __attribute__((address_space(100))) int L4; // expected-error{{automatic variable qualified with an invalid address space}}
}
- global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
- extern constant float L4;
- extern local float L5; // expected-error{{extern variable must reside in constant address space}}
- static int L6 = 0; // expected-error{{variables in function scope cannot be declared static}}
- static int L7; // expected-error{{variables in function scope cannot be declared static}}
+
+
+ extern constant float L5;
+ extern local float L6; // expected-error{{extern variable must reside in constant address space}}
+
+ static int L7 = 0; // expected-error{{variables in function scope cannot be declared static}}
+ static int L8; // expected-error{{variables in function scope cannot be declared static}}
}
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 9c795ae9c5b7..394ee0ec4390 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -7487,16 +7487,7 @@ unsigned clang_Cursor_isExternalSymbol(CXCursor C,
const Decl *D = getCursorDecl(C);
- auto getExternalSymAttr = [](const Decl *D) -> ExternalSourceSymbolAttr* {
- if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>())
- return attr;
- if (auto *dcd = dyn_cast<Decl>(D->getDeclContext())) {
- if (auto *attr = dcd->getAttr<ExternalSourceSymbolAttr>())
- return attr;
- }
- return nullptr;
- };
- if (auto *attr = getExternalSymAttr(D)) {
+ if (auto *attr = D->getExternalSourceSymbolAttr()) {
if (language)
*language = cxstring::createDup(attr->getLanguage());
if (definedIn)
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 076041406c87..0935c1bed204 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -3457,6 +3457,18 @@ TEST_F(FormatTest, BreaksAfterAssignments) {
" 1;");
}
+TEST_F(FormatTest, ConfigurableBreakAssignmentPenalty) {
+ FormatStyle Style = getLLVMStyle();
+ verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccccc;",
+ Style);
+
+ Style.PenaltyBreakAssignment = 20;
+ verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbb +\n"
+ " cccccccccccccccccccccccccc;",
+ Style);
+}
+
TEST_F(FormatTest, AlignsAfterAssignments) {
verifyFormat(
"int Result = aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n"
@@ -8802,6 +8814,8 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("ObjCBlockIndentWidth: 1234", ObjCBlockIndentWidth, 1234u);
CHECK_PARSE("ColumnLimit: 1234", ColumnLimit, 1234u);
CHECK_PARSE("MaxEmptyLinesToKeep: 1234", MaxEmptyLinesToKeep, 1234u);
+ CHECK_PARSE("PenaltyBreakAssignment: 1234",
+ PenaltyBreakAssignment, 1234u);
CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234",
PenaltyBreakBeforeFirstCallParameter, 1234u);
CHECK_PARSE("PenaltyExcessCharacter: 1234", PenaltyExcessCharacter, 1234u);
diff --git a/unittests/Format/FormatTestComments.cpp b/unittests/Format/FormatTestComments.cpp
index 4238efe54f06..a44a6845587d 100644
--- a/unittests/Format/FormatTestComments.cpp
+++ b/unittests/Format/FormatTestComments.cpp
@@ -1020,6 +1020,38 @@ TEST_F(FormatTestComments, SplitsLongLinesInCommentsInPreprocessor) {
getLLVMStyleWithColumns(20)));
}
+TEST_F(FormatTestComments, KeepsTrailingPPCommentsAndSectionCommentsSeparate) {
+ verifyFormat("#ifdef A // line about A\n"
+ "// section comment\n"
+ "#endif",
+ getLLVMStyleWithColumns(80));
+ verifyFormat("#ifdef A // line 1 about A\n"
+ " // line 2 about A\n"
+ "// section comment\n"
+ "#endif",
+ getLLVMStyleWithColumns(80));
+ EXPECT_EQ("#ifdef A // line 1 about A\n"
+ " // line 2 about A\n"
+ "// section comment\n"
+ "#endif",
+ format("#ifdef A // line 1 about A\n"
+ " // line 2 about A\n"
+ "// section comment\n"
+ "#endif",
+ getLLVMStyleWithColumns(80)));
+ verifyFormat("int f() {\n"
+ " int i;\n"
+ "#ifdef A // comment about A\n"
+ " // section comment 1\n"
+ " // section comment 2\n"
+ " i = 2;\n"
+ "#else // comment about #else\n"
+ " // section comment 3\n"
+ " i = 4;\n"
+ "#endif\n"
+ "}", getLLVMStyleWithColumns(80));
+}
+
TEST_F(FormatTestComments, CommentsInStaticInitializers) {
EXPECT_EQ(
"static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n"
@@ -1198,6 +1230,16 @@ TEST_F(FormatTestComments, ReflowsComments) {
format("/* long long long long\n"
" * long */",
getLLVMStyleWithColumns(20)));
+ EXPECT_EQ("///< long long long\n"
+ "///< long long\n",
+ format("///< long long long long\n"
+ "///< long\n",
+ getLLVMStyleWithColumns(20)));
+ EXPECT_EQ("//!< long long long\n"
+ "//!< long long\n",
+ format("//!< long long long long\n"
+ "//!< long\n",
+ getLLVMStyleWithColumns(20)));
// Don't bring leading whitespace up while reflowing.
EXPECT_EQ("/* long long long\n"
@@ -1535,7 +1577,7 @@ TEST_F(FormatTestComments, ReflowsComments) {
" *\n"
" * long */",
getLLVMStyleWithColumns(20)));
-
+
// Don't reflow lines having content that is a single character.
EXPECT_EQ("// long long long\n"
"// long\n"
@@ -1560,7 +1602,7 @@ TEST_F(FormatTestComments, ReflowsComments) {
format("// long long long long\n"
"// @param arg",
getLLVMStyleWithColumns(20)));
-
+
// Don't reflow lines starting with 'TODO'.
EXPECT_EQ("// long long long\n"
"// long\n"
@@ -1629,6 +1671,69 @@ TEST_F(FormatTestComments, ReflowsComments) {
"// long",
getLLVMStyleWithColumns(20)));
+ // Don't reflow separate bullets in list
+ EXPECT_EQ("// - long long long\n"
+ "// long\n"
+ "// - long",
+ format("// - long long long long\n"
+ "// - long",
+ getLLVMStyleWithColumns(20)));
+ EXPECT_EQ("// * long long long\n"
+ "// long\n"
+ "// * long",
+ format("// * long long long long\n"
+ "// * long",
+ getLLVMStyleWithColumns(20)));
+ EXPECT_EQ("// + long long long\n"
+ "// long\n"
+ "// + long",
+ format("// + long long long long\n"
+ "// + long",
+ getLLVMStyleWithColumns(20)));
+ EXPECT_EQ("// 1. long long long\n"
+ "// long\n"
+ "// 2. long",
+ format("// 1. long long long long\n"
+ "// 2. long",
+ getLLVMStyleWithColumns(20)));
+ EXPECT_EQ("// -# long long long\n"
+ "// long\n"
+ "// -# long",
+ format("// -# long long long long\n"
+ "// -# long",
+ getLLVMStyleWithColumns(20)));
+
+ EXPECT_EQ("// - long long long\n"
+ "// long long long\n"
+ "// - long",
+ format("// - long long long long\n"
+ "// long long\n"
+ "// - long",
+ getLLVMStyleWithColumns(20)));
+ EXPECT_EQ("// - long long long\n"
+ "// long long long\n"
+ "// long\n"
+ "// - long",
+ format("// - long long long long\n"
+ "// long long long\n"
+ "// - long",
+ getLLVMStyleWithColumns(20)));
+
+ // Large number (>2 digits) are not list items
+ EXPECT_EQ("// long long long\n"
+ "// long 1024. long.",
+ format("// long long long long\n"
+ "// 1024. long.",
+ getLLVMStyleWithColumns(20)));
+
+ // Do not break before number, to avoid introducing a non-reflowable doxygen
+ // list item.
+ EXPECT_EQ("// long long\n"
+ "// long 10. long.",
+ format("// long long long 10.\n"
+ "// long.",
+ getLLVMStyleWithColumns(20)));
+
// Don't break or reflow after implicit string literals.
verifyFormat("#include <t> // l l l\n"
" // l",
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index ff28f304be99..ba6ff0236085 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -548,15 +548,14 @@ TEST_F(FormatTestJS, AsyncFunctions) {
" // Comment.\n"
" return async.then();\n"
"}\n");
- verifyFormat("for async (const x of y) {\n"
+ verifyFormat("for await (const x of y) {\n"
" console.log(x);\n"
"}\n");
verifyFormat("function asyncLoop() {\n"
- " for async (const x of y) {\n"
+ " for await (const x of y) {\n"
" console.log(x);\n"
" }\n"
"}\n");
-
}
TEST_F(FormatTestJS, FunctionParametersTrailingComma) {
@@ -1824,6 +1823,11 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) {
verifyFormat("let x = !foo;\n");
verifyFormat("let x = foo[0]!;\n");
verifyFormat("let x = (foo)!;\n");
+ verifyFormat("let x = x(foo!);\n");
+ verifyFormat(
+ "a.aaaaaa(a.a!).then(\n"
+ " x => x(x));\n",
+ getGoogleJSStyleWithColumns(20));
verifyFormat("let x = foo! - 1;\n");
verifyFormat("let x = {foo: 1}!;\n");
verifyFormat(
diff --git a/unittests/Format/FormatTestSelective.cpp b/unittests/Format/FormatTestSelective.cpp
index 9ee87b34c217..182218fe96db 100644
--- a/unittests/Format/FormatTestSelective.cpp
+++ b/unittests/Format/FormatTestSelective.cpp
@@ -530,6 +530,14 @@ TEST_F(FormatTestSelective, SelectivelyRequoteJavaScript) {
20, 0));
}
+TEST_F(FormatTestSelective, KeepsIndentAfterCommentSectionImport) {
+ std::string Code = "#include <a> // line 1\n" // 23 chars long
+ " // line 2\n" // 23 chars long
+ "\n" // this newline is char 47
+ "int i;"; // this line is not indented
+ EXPECT_EQ(Code, format(Code, 47, 1));
+}
+
} // end namespace
} // end namespace format
} // end namespace clang