summaryrefslogtreecommitdiffstats
path: root/include/clang/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Sema')
-rw-r--r--include/clang/Sema/AttributeList.h12
-rw-r--r--include/clang/Sema/DeclSpec.h65
-rw-r--r--include/clang/Sema/Lookup.h8
-rw-r--r--include/clang/Sema/Sema.h148
4 files changed, 205 insertions, 28 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 58b1b9e..4d18633 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -81,6 +81,8 @@ public:
AS_Declspec,
/// __ptr16, alignas(...), etc.
AS_Keyword,
+ /// Context-sensitive version of a keyword attribute.
+ AS_ContextSensitiveKeyword,
/// #pragma ...
AS_Pragma
};
@@ -343,14 +345,20 @@ public:
bool isAlignasAttribute() const {
// FIXME: Use a better mechanism to determine this.
- return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
+ return getKind() == AT_Aligned && isKeywordAttribute();
}
bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
bool isCXX11Attribute() const {
return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
}
- bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
+ bool isKeywordAttribute() const {
+ return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
+ }
+
+ bool isContextSensitiveKeywordAttribute() const {
+ return SyntaxUsed == AS_ContextSensitiveKeyword;
+ }
bool isInvalid() const { return Invalid; }
void setInvalid(bool b = true) const { Invalid = b; }
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index de39d83..2ec3286 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -31,6 +31,7 @@
#include "clang/Lex/Token.h"
#include "clang/Sema/AttributeList.h"
#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -785,7 +786,8 @@ public:
DQ_Out = 0x4,
DQ_Bycopy = 0x8,
DQ_Byref = 0x10,
- DQ_Oneway = 0x20
+ DQ_Oneway = 0x20,
+ DQ_CSNullability = 0x40
};
/// PropertyAttributeKind - list of property attributes.
@@ -802,17 +804,22 @@ public:
DQ_PR_atomic = 0x100,
DQ_PR_weak = 0x200,
DQ_PR_strong = 0x400,
- DQ_PR_unsafe_unretained = 0x800
+ DQ_PR_unsafe_unretained = 0x800,
+ DQ_PR_nullability = 0x1000,
+ DQ_PR_null_resettable = 0x2000
};
-
ObjCDeclSpec()
: objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
- GetterName(nullptr), SetterName(nullptr) { }
+ Nullability(0), GetterName(nullptr), SetterName(nullptr) { }
+
ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
}
+ void clearObjCDeclQualifier(ObjCDeclQualifier DQVal) {
+ objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier & ~DQVal);
+ }
ObjCPropertyAttributeKind getPropertyAttributes() const {
return ObjCPropertyAttributeKind(PropertyAttributes);
@@ -822,6 +829,28 @@ public:
(ObjCPropertyAttributeKind)(PropertyAttributes | PRVal);
}
+ NullabilityKind getNullability() const {
+ assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
+ (getPropertyAttributes() & DQ_PR_nullability)) &&
+ "Objective-C declspec doesn't have nullability");
+ return static_cast<NullabilityKind>(Nullability);
+ }
+
+ SourceLocation getNullabilityLoc() const {
+ assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
+ (getPropertyAttributes() & DQ_PR_nullability)) &&
+ "Objective-C declspec doesn't have nullability");
+ return NullabilityLoc;
+ }
+
+ void setNullability(SourceLocation loc, NullabilityKind kind) {
+ assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
+ (getPropertyAttributes() & DQ_PR_nullability)) &&
+ "Set the nullability declspec or property attribute first");
+ Nullability = static_cast<unsigned>(kind);
+ NullabilityLoc = loc;
+ }
+
const IdentifierInfo *getGetterName() const { return GetterName; }
IdentifierInfo *getGetterName() { return GetterName; }
void setGetterName(IdentifierInfo *name) { GetterName = name; }
@@ -834,10 +863,15 @@ private:
// FIXME: These two are unrelated and mutually exclusive. So perhaps
// we can put them in a union to reflect their mutual exclusivity
// (space saving is negligible).
- ObjCDeclQualifier objcDeclQualifier : 6;
+ ObjCDeclQualifier objcDeclQualifier : 7;
// NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
- unsigned PropertyAttributes : 12;
+ unsigned PropertyAttributes : 14;
+
+ unsigned Nullability : 2;
+
+ SourceLocation NullabilityLoc;
+
IdentifierInfo *GetterName; // getter name or NULL if no getter
IdentifierInfo *SetterName; // setter name or NULL if no setter
};
@@ -1616,7 +1650,13 @@ private:
bool InlineParamsUsed;
/// \brief true if the declaration is preceded by \c __extension__.
- bool Extension : 1;
+ unsigned Extension : 1;
+
+ /// Indicates whether this is an Objective-C instance variable.
+ unsigned ObjCIvar : 1;
+
+ /// Indicates whether this is an Objective-C 'weak' property.
+ unsigned ObjCWeakProperty : 1;
/// \brief If this is the second or subsequent declarator in this declaration,
/// the location of the comma before this declarator.
@@ -1635,7 +1675,8 @@ public:
GroupingParens(false), FunctionDefinition(FDK_Declaration),
Redeclaration(false),
Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
- InlineParamsUsed(false), Extension(false) {
+ InlineParamsUsed(false), Extension(false), ObjCIvar(false),
+ ObjCWeakProperty(false) {
}
~Declarator() {
@@ -1713,6 +1754,8 @@ public:
Attrs.clear();
AsmLabel = nullptr;
InlineParamsUsed = false;
+ ObjCIvar = false;
+ ObjCWeakProperty = false;
CommaLoc = SourceLocation();
EllipsisLoc = SourceLocation();
}
@@ -2121,6 +2164,12 @@ public:
void setExtension(bool Val = true) { Extension = Val; }
bool getExtension() const { return Extension; }
+ void setObjCIvar(bool Val = true) { ObjCIvar = Val; }
+ bool isObjCIvar() const { return ObjCIvar; }
+
+ void setObjCWeakProperty(bool Val = true) { ObjCWeakProperty = Val; }
+ bool isObjCWeakProperty() const { return ObjCWeakProperty; }
+
void setInvalidType(bool Val = true) { InvalidType = Val; }
bool isInvalidType() const {
return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error;
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index 97192b5..5bfee8b 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -302,14 +302,10 @@ public:
if (!D->isInIdentifierNamespace(IDNS))
return nullptr;
- if (isVisible(getSema(), D))
+ if (isHiddenDeclarationVisible() || isVisible(getSema(), D))
return D;
- if (auto *Visible = getAcceptableDeclSlow(D))
- return Visible;
-
- // Even if hidden declarations are visible, prefer a visible declaration.
- return isHiddenDeclarationVisible() ? D : nullptr;
+ return getAcceptableDeclSlow(D);
}
private:
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 60664c5..cb75b96 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -210,6 +210,50 @@ namespace threadSafety {
typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>,
SourceLocation> UnexpandedParameterPack;
+/// Describes whether we've seen any nullability information for the given
+/// file.
+struct FileNullability {
+ /// The first pointer declarator (of any pointer kind) in the file that does
+ /// not have a corresponding nullability annotation.
+ SourceLocation PointerLoc;
+
+ /// Which kind of pointer declarator we saw.
+ uint8_t PointerKind;
+
+ /// Whether we saw any type nullability annotations in the given file.
+ bool SawTypeNullability = false;
+};
+
+/// A mapping from file IDs to a record of whether we've seen nullability
+/// information in that file.
+class FileNullabilityMap {
+ /// A mapping from file IDs to the nullability information for each file ID.
+ llvm::DenseMap<FileID, FileNullability> Map;
+
+ /// A single-element cache based on the file ID.
+ struct {
+ FileID File;
+ FileNullability Nullability;
+ } Cache;
+
+public:
+ FileNullability &operator[](FileID file) {
+ // Check the single-element cache.
+ if (file == Cache.File)
+ return Cache.Nullability;
+
+ // It's not in the single-element cache; flush the cache if we have one.
+ if (!Cache.File.isInvalid()) {
+ Map[Cache.File] = Cache.Nullability;
+ }
+
+ // Pull this entry into the cache.
+ Cache.File = file;
+ Cache.Nullability = Map[file];
+ return Cache.Nullability;
+ }
+};
+
/// Sema - This implements semantic analysis and AST building for C.
class Sema {
Sema(const Sema &) = delete;
@@ -341,6 +385,9 @@ public:
PragmaStack<StringLiteral *> ConstSegStack;
PragmaStack<StringLiteral *> CodeSegStack;
+ /// A mapping that describes the nullability we've seen in each header file.
+ FileNullabilityMap NullabilityMap;
+
/// Last section used with #pragma init_seg.
StringLiteral *CurInitSeg;
SourceLocation CurInitSegLoc;
@@ -1157,6 +1204,16 @@ public:
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
+ unsigned deduceWeakPropertyFromType(QualType T) {
+ if ((getLangOpts().getGC() != LangOptions::NonGC &&
+ T.isObjCGCWeak()) ||
+ (getLangOpts().ObjCAutoRefCount &&
+ T.getObjCLifetime() == Qualifiers::OCL_Weak))
+ return ObjCDeclSpec::DQ_PR_weak;
+ return 0;
+ }
+
+
/// \brief Build a function type.
///
/// This routine checks the function type according to C++ rules and
@@ -1325,6 +1382,11 @@ public:
return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden);
}
+ /// Determine if the template parameter \p D has a visible default argument.
+ bool
+ hasVisibleDefaultArgument(const NamedDecl *D,
+ llvm::SmallVectorImpl<Module *> *Modules = nullptr);
+
bool RequireCompleteType(SourceLocation Loc, QualType T,
TypeDiagnoser &Diagnoser);
bool RequireCompleteType(SourceLocation Loc, QualType T,
@@ -1727,6 +1789,22 @@ public:
void createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
Module *Mod);
+ /// Kinds of missing import. Note, the values of these enumerators correspond
+ /// to %select values in diagnostics.
+ enum class MissingImportKind {
+ Declaration,
+ Definition,
+ DefaultArgument
+ };
+
+ /// \brief Diagnose that the specified declaration needs to be visible but
+ /// isn't, and suggest a module import that would resolve the problem.
+ void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
+ bool NeedDefinition, bool Recover = true);
+ void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
+ SourceLocation DeclLoc, ArrayRef<Module *> Modules,
+ MissingImportKind MIK, bool Recover);
+
/// \brief Retrieve a suitable printing policy.
PrintingPolicy getPrintingPolicy() const {
return getPrintingPolicy(Context, PP);
@@ -1847,10 +1925,10 @@ public:
/// struct, or union).
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
+ typedef void *SkippedDefinitionContext;
+
/// \brief Invoked when we enter a tag definition that we're skipping.
- void ActOnTagStartSkippedDefinition(Scope *S, Decl *TD) {
- PushDeclContext(S, cast<DeclContext>(TD));
- }
+ SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD);
Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
@@ -1867,9 +1945,7 @@ public:
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl,
SourceLocation RBraceLoc);
- void ActOnTagFinishSkippedDefinition() {
- PopDeclContext();
- }
+ void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context);
void ActOnObjCContainerFinishDefinition();
@@ -2819,6 +2895,7 @@ public:
unsigned ArgNum, StringRef &Str,
SourceLocation *ArgLocation = nullptr);
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str);
+ void checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
bool checkMSInheritanceAttrOnDefinition(
CXXRecordDecl *RD, SourceRange Range, bool BestCase,
MSInheritanceAttr::Spelling SemanticSpelling);
@@ -2839,6 +2916,26 @@ public:
/// Valid types should not have multiple attributes with different CCs.
const AttributedType *getCallingConvAttributedType(QualType T) const;
+ /// Check whether a nullability type specifier can be added to the given
+ /// type.
+ ///
+ /// \param type The type to which the nullability specifier will be
+ /// added. On success, this type will be updated appropriately.
+ ///
+ /// \param nullability The nullability specifier to add.
+ ///
+ /// \param nullabilityLoc The location of the nullability specifier.
+ ///
+ /// \param isContextSensitive Whether this nullability specifier was
+ /// written as a context-sensitive keyword (in an Objective-C
+ /// method) or an Objective-C property attribute, rather than as an
+ /// underscored type specifier.
+ ///
+ /// \returns true if nullability cannot be applied, false otherwise.
+ bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability,
+ SourceLocation nullabilityLoc,
+ bool isContextSensitive);
+
/// \brief Stmt attributes - this routine is the top level dispatcher.
StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
SourceRange Range);
@@ -2878,6 +2975,9 @@ public:
ObjCContainerDecl *CDecl,
bool SynthesizeProperties);
+ /// Diagnose any null-resettable synthesized setters.
+ void diagnoseNullResettableSynthesizedSetters(ObjCImplDecl *impDecl);
+
/// DefaultSynthesizeProperties - This routine default synthesizes all
/// properties which must be synthesized in the class's \@implementation.
void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
@@ -2914,7 +3014,8 @@ public:
const unsigned Attributes,
const unsigned AttributesAsWritten,
bool *isOverridingProperty,
- TypeSourceInfo *T,
+ QualType T,
+ TypeSourceInfo *TSI,
tok::ObjCKeywordKind MethodImplKind);
/// Called by ActOnProperty and HandlePropertyInClassExtension to
@@ -2930,7 +3031,8 @@ public:
const bool isReadWrite,
const unsigned Attributes,
const unsigned AttributesAsWritten,
- TypeSourceInfo *T,
+ QualType T,
+ TypeSourceInfo *TSI,
tok::ObjCKeywordKind MethodImplKind,
DeclContext *lexicalDC = nullptr);
@@ -7629,6 +7731,9 @@ public:
/// \brief Called on well-formed '\#pragma omp taskwait'.
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp taskgroup'.
+ StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// \brief Called on well-formed '\#pragma omp flush'.
StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
@@ -8557,9 +8662,10 @@ private:
const FunctionProtoType *Proto,
SourceLocation Loc);
- void checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
- unsigned NumParams, bool IsMemberFunction, SourceLocation Loc,
- SourceRange Range, VariadicCallType CallType);
+ void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
+ ArrayRef<const Expr *> Args, bool IsMemberFunction,
+ SourceLocation Loc, SourceRange Range,
+ VariadicCallType CallType);
bool CheckObjCString(Expr *Arg);
@@ -8602,7 +8708,9 @@ private:
llvm::APSInt &Result);
bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
int Low, int High);
-
+ bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,
+ int ArgNum, unsigned ExpectedFieldNum,
+ bool AllowName);
public:
enum FormatStringType {
FST_Scanf,
@@ -8731,6 +8839,13 @@ private:
mutable IdentifierInfo *Ident_super;
mutable IdentifierInfo *Ident___float128;
+ /// Nullability type specifiers.
+ IdentifierInfo *Ident___nonnull = nullptr;
+ IdentifierInfo *Ident___nullable = nullptr;
+ IdentifierInfo *Ident___null_unspecified = nullptr;
+
+ IdentifierInfo *Ident_NSError = nullptr;
+
protected:
friend class Parser;
friend class InitializationSequence;
@@ -8739,6 +8854,15 @@ protected:
friend class ASTWriter;
public:
+ /// Retrieve the keyword associated
+ IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability);
+
+ /// The struct behind the CFErrorRef pointer.
+ RecordDecl *CFError = nullptr;
+
+ /// Retrieve the identifier "NSError".
+ IdentifierInfo *getNSErrorIdent();
+
/// \brief Retrieve the parser's current scope.
///
/// This routine must only be used when it is certain that semantic analysis
OpenPOWER on IntegriCloud