Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,251 @@
//===--- AttributeList.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the AttributeList class implementation
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/AttributeList.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "llvm/ADT/SmallString.h"
using namespace clang;
IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc,
IdentifierInfo *Ident) {
IdentifierLoc *Result = new (Ctx) IdentifierLoc;
Result->Loc = Loc;
Result->Ident = Ident;
return Result;
}
size_t AttributeList::allocated_size() const {
if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
else if (IsTypeTagForDatatype)
return AttributeFactory::TypeTagForDatatypeAllocSize;
else if (IsProperty)
return AttributeFactory::PropertyAllocSize;
return (sizeof(AttributeList) + NumArgs * sizeof(ArgsUnion));
}
AttributeFactory::AttributeFactory() {
// Go ahead and configure all the inline capacity. This is just a memset.
FreeLists.resize(InlineFreeListsCapacity);
}
AttributeFactory::~AttributeFactory() {}
static size_t getFreeListIndexForSize(size_t size) {
assert(size >= sizeof(AttributeList));
assert((size % sizeof(void*)) == 0);
return ((size - sizeof(AttributeList)) / sizeof(void*));
}
void *AttributeFactory::allocate(size_t size) {
// Check for a previously reclaimed attribute.
size_t index = getFreeListIndexForSize(size);
if (index < FreeLists.size()) {
if (AttributeList *attr = FreeLists[index]) {
FreeLists[index] = attr->NextInPool;
return attr;
}
}
// Otherwise, allocate something new.
return Alloc.Allocate(size, alignof(AttributeFactory));
}
void AttributeFactory::reclaimPool(AttributeList *cur) {
assert(cur && "reclaiming empty pool!");
do {
// Read this here, because we're going to overwrite NextInPool
// when we toss 'cur' into the appropriate queue.
AttributeList *next = cur->NextInPool;
size_t size = cur->allocated_size();
size_t freeListIndex = getFreeListIndexForSize(size);
// Expand FreeLists to the appropriate size, if required.
if (freeListIndex >= FreeLists.size())
FreeLists.resize(freeListIndex+1);
// Add 'cur' to the appropriate free-list.
cur->NextInPool = FreeLists[freeListIndex];
FreeLists[freeListIndex] = cur;
cur = next;
} while (cur);
}
void AttributePool::takePool(AttributeList *pool) {
assert(pool);
// Fast path: this pool is empty.
if (!Head) {
Head = pool;
return;
}
// Reverse the pool onto the current head. This optimizes for the
// pattern of pulling a lot of pools into a single pool.
do {
AttributeList *next = pool->NextInPool;
pool->NextInPool = Head;
Head = pool;
pool = next;
} while (pool);
}
#include "clang/Sema/AttrParsedAttrKinds.inc"
static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
AttributeList::Syntax SyntaxUsed) {
// Normalize the attribute name, __foo__ becomes foo. This is only allowable
// for GNU attributes.
bool IsGNU = SyntaxUsed == AttributeList::AS_GNU ||
((SyntaxUsed == AttributeList::AS_CXX11 ||
SyntaxUsed == AttributeList::AS_C2x) && ScopeName == "gnu");
if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
AttrName.endswith("__"))
AttrName = AttrName.slice(2, AttrName.size() - 2);
return AttrName;
}
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
const IdentifierInfo *ScopeName,
Syntax SyntaxUsed) {
StringRef AttrName = Name->getName();
SmallString<64> FullName;
if (ScopeName)
FullName += ScopeName->getName();
AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
// Ensure that in the case of C++11 attributes, we look for '::foo' if it is
// unscoped.
if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
FullName += "::";
FullName += AttrName;
return ::getAttrKind(FullName, SyntaxUsed);
}
unsigned AttributeList::getAttributeSpellingListIndex() const {
// Both variables will be used in tablegen generated
// attribute spell list index matching code.
StringRef Scope = ScopeName ? ScopeName->getName() : "";
StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
(AttributeList::Syntax)SyntaxUsed);
#include "clang/Sema/AttrSpellingListIndex.inc"
}
struct ParsedAttrInfo {
unsigned NumArgs : 4;
unsigned OptArgs : 4;
unsigned HasCustomParsing : 1;
unsigned IsTargetSpecific : 1;
unsigned IsType : 1;
unsigned IsStmt : 1;
unsigned IsKnownToGCC : 1;
unsigned IsSupportedByPragmaAttribute : 1;
bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
const Decl *);
bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
bool (*ExistsInTarget)(const TargetInfo &Target);
unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
void (*GetPragmaAttributeMatchRules)(
llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
const LangOptions &LangOpts);
};
namespace {
#include "clang/Sema/AttrParsedAttrImpl.inc"
}
static const ParsedAttrInfo &getInfo(const AttributeList &A) {
return AttrInfoMap[A.getKind()];
}
unsigned AttributeList::getMinArgs() const {
return getInfo(*this).NumArgs;
}
unsigned AttributeList::getMaxArgs() const {
return getMinArgs() + getInfo(*this).OptArgs;
}
bool AttributeList::hasCustomParsing() const {
return getInfo(*this).HasCustomParsing;
}
bool AttributeList::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
}
bool AttributeList::appliesToDecl(const Decl *D,
attr::SubjectMatchRule MatchRule) const {
return checkAttributeMatchRuleAppliesTo(D, MatchRule);
}
void AttributeList::getMatchRules(
const LangOptions &LangOpts,
SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
const {
return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
}
bool AttributeList::diagnoseLangOpts(Sema &S) const {
return getInfo(*this).DiagLangOpts(S, *this);
}
bool AttributeList::isTargetSpecificAttr() const {
return getInfo(*this).IsTargetSpecific;
}
bool AttributeList::isTypeAttr() const {
return getInfo(*this).IsType;
}
bool AttributeList::isStmtAttr() const {
return getInfo(*this).IsStmt;
}
bool AttributeList::existsInTarget(const TargetInfo &Target) const {
return getInfo(*this).ExistsInTarget(Target);
}
bool AttributeList::isKnownToGCC() const {
return getInfo(*this).IsKnownToGCC;
}
bool AttributeList::isSupportedByPragmaAttribute() const {
return getInfo(*this).IsSupportedByPragmaAttribute;
}
unsigned AttributeList::getSemanticSpelling() const {
return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
}
bool AttributeList::hasVariadicArg() const {
// If the attribute has the maximum number of optional arguments, we will
// claim that as being variadic. If we someday get an attribute that
// legitimately bumps up against that maximum, we can use another bit to track
// whether it's truly variadic or not.
return getInfo(*this).OptArgs == 15;
}

View File

@ -0,0 +1,65 @@
set(LLVM_LINK_COMPONENTS
Support
)
if (MSVC)
set_source_files_properties(SemaDeclAttr.cpp PROPERTIES COMPILE_FLAGS /bigobj)
set_source_files_properties(SemaExpr.cpp PROPERTIES COMPILE_FLAGS /bigobj)
endif()
add_clang_library(clangSema
AnalysisBasedWarnings.cpp
AttributeList.cpp
CodeCompleteConsumer.cpp
DeclSpec.cpp
DelayedDiagnostic.cpp
IdentifierResolver.cpp
JumpDiagnostics.cpp
MultiplexExternalSemaSource.cpp
Scope.cpp
ScopeInfo.cpp
Sema.cpp
SemaAccess.cpp
SemaAttr.cpp
SemaCXXScopeSpec.cpp
SemaCast.cpp
SemaChecking.cpp
SemaCodeComplete.cpp
SemaConsumer.cpp
SemaCoroutine.cpp
SemaCUDA.cpp
SemaDecl.cpp
SemaDeclAttr.cpp
SemaDeclCXX.cpp
SemaDeclObjC.cpp
SemaExceptionSpec.cpp
SemaExpr.cpp
SemaExprCXX.cpp
SemaExprMember.cpp
SemaExprObjC.cpp
SemaFixItUtils.cpp
SemaInit.cpp
SemaLambda.cpp
SemaLookup.cpp
SemaObjCProperty.cpp
SemaOpenMP.cpp
SemaOverload.cpp
SemaPseudoObject.cpp
SemaStmt.cpp
SemaStmtAsm.cpp
SemaStmtAttr.cpp
SemaTemplate.cpp
SemaTemplateDeduction.cpp
SemaTemplateInstantiate.cpp
SemaTemplateInstantiateDecl.cpp
SemaTemplateVariadic.cpp
SemaType.cpp
TypeLocBuilder.cpp
LINK_LIBS
clangAST
clangAnalysis
clangBasic
clangEdit
clangLex
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
//===- CoroutineStmtBuilder.h - Implicit coroutine stmt builder -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
//
// This file defines CoroutineStmtBuilder, a class for building the implicit
// statements required for building a coroutine body.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_SEMA_COROUTINESTMTBUILDER_H
#define LLVM_CLANG_LIB_SEMA_COROUTINESTMTBUILDER_H
#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/SemaInternal.h"
namespace clang {
class CoroutineStmtBuilder : public CoroutineBodyStmt::CtorArgs {
Sema &S;
FunctionDecl &FD;
sema::FunctionScopeInfo &Fn;
bool IsValid = true;
SourceLocation Loc;
SmallVector<Stmt *, 4> ParamMovesVector;
const bool IsPromiseDependentType;
CXXRecordDecl *PromiseRecordDecl = nullptr;
public:
/// \brief Construct a CoroutineStmtBuilder and initialize the promise
/// statement and initial/final suspends from the FunctionScopeInfo.
CoroutineStmtBuilder(Sema &S, FunctionDecl &FD, sema::FunctionScopeInfo &Fn,
Stmt *Body);
/// \brief Build the coroutine body statements, including the
/// "promise dependent" statements when the promise type is not dependent.
bool buildStatements();
/// \brief Build the coroutine body statements that require a non-dependent
/// promise type in order to construct.
///
/// For example different new/delete overloads are selected depending on
/// if the promise type provides `unhandled_exception()`, and therefore they
/// cannot be built until the promise type is complete so that we can perform
/// name lookup.
bool buildDependentStatements();
/// \brief Build just parameter moves. To use for rebuilding in TreeTransform.
bool buildParameterMoves();
bool isInvalid() const { return !this->IsValid; }
private:
bool makePromiseStmt();
bool makeInitialAndFinalSuspend();
bool makeNewAndDeleteExpr();
bool makeOnFallthrough();
bool makeOnException();
bool makeReturnObject();
bool makeGroDeclAndReturnStmt();
bool makeReturnOnAllocFailure();
bool makeParamMoves();
};
} // end namespace clang
#endif // LLVM_CLANG_LIB_SEMA_COROUTINESTMTBUILDER_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
//===--- DelayedDiagnostic.cpp - Delayed declarator diagnostics -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DelayedDiagnostic class implementation, which
// is used to record diagnostics that are being conditionally produced
// during declarator parsing.
//
// This file also defines AccessedEntity.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/DelayedDiagnostic.h"
#include <string.h>
using namespace clang;
using namespace sema;
DelayedDiagnostic
DelayedDiagnostic::makeAvailability(AvailabilityResult AR,
SourceLocation Loc,
const NamedDecl *ReferringDecl,
const NamedDecl *OffendingDecl,
const ObjCInterfaceDecl *UnknownObjCClass,
const ObjCPropertyDecl *ObjCProperty,
StringRef Msg,
bool ObjCPropertyAccess) {
DelayedDiagnostic DD;
DD.Kind = Availability;
DD.Triggered = false;
DD.Loc = Loc;
DD.AvailabilityData.ReferringDecl = ReferringDecl;
DD.AvailabilityData.OffendingDecl = OffendingDecl;
DD.AvailabilityData.UnknownObjCClass = UnknownObjCClass;
DD.AvailabilityData.ObjCProperty = ObjCProperty;
char *MessageData = nullptr;
if (Msg.size()) {
MessageData = new char [Msg.size()];
memcpy(MessageData, Msg.data(), Msg.size());
}
DD.AvailabilityData.Message = MessageData;
DD.AvailabilityData.MessageLen = Msg.size();
DD.AvailabilityData.AR = AR;
DD.AvailabilityData.ObjCPropertyAccess = ObjCPropertyAccess;
return DD;
}
void DelayedDiagnostic::Destroy() {
switch (Kind) {
case Access:
getAccessData().~AccessedEntity();
break;
case Availability:
delete[] AvailabilityData.Message;
break;
case ForbiddenType:
break;
}
}

View File

@ -0,0 +1,422 @@
//===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the IdentifierResolver class, which is used for lexical
// scoped lookup, based on declaration names.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/IdentifierResolver.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Scope.h"
using namespace clang;
//===----------------------------------------------------------------------===//
// IdDeclInfoMap class
//===----------------------------------------------------------------------===//
/// IdDeclInfoMap - Associates IdDeclInfos with declaration names.
/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
/// individual IdDeclInfo to heap.
class IdentifierResolver::IdDeclInfoMap {
static const unsigned int POOL_SIZE = 512;
/// We use our own linked-list implementation because it is sadly
/// impossible to add something to a pre-C++0x STL container without
/// a completely unnecessary copy.
struct IdDeclInfoPool {
IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
IdDeclInfoPool *Next;
IdDeclInfo Pool[POOL_SIZE];
};
IdDeclInfoPool *CurPool;
unsigned int CurIndex;
public:
IdDeclInfoMap() : CurPool(nullptr), CurIndex(POOL_SIZE) {}
~IdDeclInfoMap() {
IdDeclInfoPool *Cur = CurPool;
while (IdDeclInfoPool *P = Cur) {
Cur = Cur->Next;
delete P;
}
}
/// Returns the IdDeclInfo associated to the DeclarationName.
/// It creates a new IdDeclInfo if one was not created before for this id.
IdDeclInfo &operator[](DeclarationName Name);
};
//===----------------------------------------------------------------------===//
// IdDeclInfo Implementation
//===----------------------------------------------------------------------===//
/// RemoveDecl - Remove the decl from the scope chain.
/// The decl must already be part of the decl chain.
void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
if (D == *(I-1)) {
Decls.erase(I-1);
return;
}
}
llvm_unreachable("Didn't find this decl on its identifier's chain!");
}
//===----------------------------------------------------------------------===//
// IdentifierResolver Implementation
//===----------------------------------------------------------------------===//
IdentifierResolver::IdentifierResolver(Preprocessor &PP)
: LangOpt(PP.getLangOpts()), PP(PP),
IdDeclInfos(new IdDeclInfoMap) {
}
IdentifierResolver::~IdentifierResolver() {
delete IdDeclInfos;
}
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
/// true if 'D' belongs to the given declaration context.
bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,
bool AllowInlineNamespace) const {
Ctx = Ctx->getRedeclContext();
if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) {
// Ignore the scopes associated within transparent declaration contexts.
while (S->getEntity() && S->getEntity()->isTransparentContext())
S = S->getParent();
if (S->isDeclScope(D))
return true;
if (LangOpt.CPlusPlus) {
// C++ 3.3.2p3:
// The name declared in a catch exception-declaration is local to the
// handler and shall not be redeclared in the outermost block of the
// handler.
// C++ 3.3.2p4:
// Names declared in the for-init-statement, and in the condition of if,
// while, for, and switch statements are local to the if, while, for, or
// switch statement (including the controlled statement), and shall not be
// redeclared in a subsequent condition of that statement nor in the
// outermost block (or, for the if statement, any of the outermost blocks)
// of the controlled statement.
//
assert(S->getParent() && "No TUScope?");
if (S->getParent()->getFlags() & Scope::ControlScope) {
S = S->getParent();
if (S->isDeclScope(D))
return true;
}
if (S->getFlags() & Scope::FnTryCatchScope)
return S->getParent()->isDeclScope(D);
}
return false;
}
// FIXME: If D is a local extern declaration, this check doesn't make sense;
// we should be checking its lexical context instead in that case, because
// that is its scope.
DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)
: Ctx->Equals(DCtx);
}
/// AddDecl - Link the decl to its shadowed decl chain.
void IdentifierResolver::AddDecl(NamedDecl *D) {
DeclarationName Name = D->getDeclName();
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
updatingIdentifier(*II);
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) {
Name.setFETokenInfo(D);
return;
}
IdDeclInfo *IDI;
if (isDeclPtr(Ptr)) {
Name.setFETokenInfo(nullptr);
IDI = &(*IdDeclInfos)[Name];
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
IDI->AddDecl(PrevD);
} else
IDI = toIdDeclInfo(Ptr);
IDI->AddDecl(D);
}
void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) {
DeclarationName Name = D->getDeclName();
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
updatingIdentifier(*II);
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) {
AddDecl(D);
return;
}
if (isDeclPtr(Ptr)) {
// We only have a single declaration: insert before or after it,
// as appropriate.
if (Pos == iterator()) {
// Add the new declaration before the existing declaration.
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
RemoveDecl(PrevD);
AddDecl(D);
AddDecl(PrevD);
} else {
// Add new declaration after the existing declaration.
AddDecl(D);
}
return;
}
// General case: insert the declaration at the appropriate point in the
// list, which already has at least two elements.
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
if (Pos.isIterator()) {
IDI->InsertDecl(Pos.getIterator() + 1, D);
} else
IDI->InsertDecl(IDI->decls_begin(), D);
}
/// RemoveDecl - Unlink the decl from its shadowed decl chain.
/// The decl must already be part of the decl chain.
void IdentifierResolver::RemoveDecl(NamedDecl *D) {
assert(D && "null param passed");
DeclarationName Name = D->getDeclName();
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
updatingIdentifier(*II);
void *Ptr = Name.getFETokenInfo<void>();
assert(Ptr && "Didn't find this decl on its identifier's chain!");
if (isDeclPtr(Ptr)) {
assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
Name.setFETokenInfo(nullptr);
return;
}
return toIdDeclInfo(Ptr)->RemoveDecl(D);
}
/// begin - Returns an iterator for decls with name 'Name'.
IdentifierResolver::iterator
IdentifierResolver::begin(DeclarationName Name) {
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
readingIdentifier(*II);
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) return end();
if (isDeclPtr(Ptr))
return iterator(static_cast<NamedDecl*>(Ptr));
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
if (I != IDI->decls_begin())
return iterator(I-1);
// No decls found.
return end();
}
namespace {
enum DeclMatchKind {
DMK_Different,
DMK_Replace,
DMK_Ignore
};
}
/// \brief Compare two declarations to see whether they are different or,
/// if they are the same, whether the new declaration should replace the
/// existing declaration.
static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New) {
// If the declarations are identical, ignore the new one.
if (Existing == New)
return DMK_Ignore;
// If the declarations have different kinds, they're obviously different.
if (Existing->getKind() != New->getKind())
return DMK_Different;
// If the declarations are redeclarations of each other, keep the newest one.
if (Existing->getCanonicalDecl() == New->getCanonicalDecl()) {
// If we're adding an imported declaration, don't replace another imported
// declaration.
if (Existing->isFromASTFile() && New->isFromASTFile())
return DMK_Different;
// If either of these is the most recent declaration, use it.
Decl *MostRecent = Existing->getMostRecentDecl();
if (Existing == MostRecent)
return DMK_Ignore;
if (New == MostRecent)
return DMK_Replace;
// If the existing declaration is somewhere in the previous declaration
// chain of the new declaration, then prefer the new declaration.
for (auto RD : New->redecls()) {
if (RD == Existing)
return DMK_Replace;
if (RD->isCanonicalDecl())
break;
}
return DMK_Ignore;
}
return DMK_Different;
}
bool IdentifierResolver::tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name){
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
readingIdentifier(*II);
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) {
Name.setFETokenInfo(D);
return true;
}
IdDeclInfo *IDI;
if (isDeclPtr(Ptr)) {
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
switch (compareDeclarations(PrevD, D)) {
case DMK_Different:
break;
case DMK_Ignore:
return false;
case DMK_Replace:
Name.setFETokenInfo(D);
return true;
}
Name.setFETokenInfo(nullptr);
IDI = &(*IdDeclInfos)[Name];
// If the existing declaration is not visible in translation unit scope,
// then add the new top-level declaration first.
if (!PrevD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
IDI->AddDecl(D);
IDI->AddDecl(PrevD);
} else {
IDI->AddDecl(PrevD);
IDI->AddDecl(D);
}
return true;
}
IDI = toIdDeclInfo(Ptr);
// See whether this declaration is identical to any existing declarations.
// If not, find the right place to insert it.
for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(),
IEnd = IDI->decls_end();
I != IEnd; ++I) {
switch (compareDeclarations(*I, D)) {
case DMK_Different:
break;
case DMK_Ignore:
return false;
case DMK_Replace:
*I = D;
return true;
}
if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
// We've found a declaration that is not visible from the translation
// unit (it's in an inner scope). Insert our declaration here.
IDI->InsertDecl(I, D);
return true;
}
}
// Add the declaration to the end.
IDI->AddDecl(D);
return true;
}
void IdentifierResolver::readingIdentifier(IdentifierInfo &II) {
if (II.isOutOfDate())
PP.getExternalSource()->updateOutOfDateIdentifier(II);
}
void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) {
if (II.isOutOfDate())
PP.getExternalSource()->updateOutOfDateIdentifier(II);
if (II.isFromAST())
II.setFETokenInfoChangedSinceDeserialization();
}
//===----------------------------------------------------------------------===//
// IdDeclInfoMap Implementation
//===----------------------------------------------------------------------===//
/// Returns the IdDeclInfo associated to the DeclarationName.
/// It creates a new IdDeclInfo if one was not created before for this id.
IdentifierResolver::IdDeclInfo &
IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
void *Ptr = Name.getFETokenInfo<void>();
if (Ptr) return *toIdDeclInfo(Ptr);
if (CurIndex == POOL_SIZE) {
CurPool = new IdDeclInfoPool(CurPool);
CurIndex = 0;
}
IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
Name.setFETokenInfo(reinterpret_cast<void*>(
reinterpret_cast<uintptr_t>(IDI) | 0x1)
);
++CurIndex;
return *IDI;
}
void IdentifierResolver::iterator::incrementSlowCase() {
NamedDecl *D = **this;
void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
BaseIter I = getIterator();
if (I != Info->decls_begin())
*this = iterator(I-1);
else // No more decls.
*this = iterator();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,324 @@
//===--- MultiplexExternalSemaSource.cpp ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the event dispatching to the subscribed clients.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/MultiplexExternalSemaSource.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/Sema/Lookup.h"
using namespace clang;
///\brief Constructs a new multiplexing external sema source and appends the
/// given element to it.
///
MultiplexExternalSemaSource::MultiplexExternalSemaSource(ExternalSemaSource &s1,
ExternalSemaSource &s2){
Sources.push_back(&s1);
Sources.push_back(&s2);
}
// pin the vtable here.
MultiplexExternalSemaSource::~MultiplexExternalSemaSource() {}
///\brief Appends new source to the source list.
///
///\param[in] source - An ExternalSemaSource.
///
void MultiplexExternalSemaSource::addSource(ExternalSemaSource &source) {
Sources.push_back(&source);
}
//===----------------------------------------------------------------------===//
// ExternalASTSource.
//===----------------------------------------------------------------------===//
Decl *MultiplexExternalSemaSource::GetExternalDecl(uint32_t ID) {
for(size_t i = 0; i < Sources.size(); ++i)
if (Decl *Result = Sources[i]->GetExternalDecl(ID))
return Result;
return nullptr;
}
void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) {
for (size_t i = 0; i < Sources.size(); ++i)
Sources[i]->CompleteRedeclChain(D);
}
Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) {
Selector Sel;
for(size_t i = 0; i < Sources.size(); ++i) {
Sel = Sources[i]->GetExternalSelector(ID);
if (!Sel.isNull())
return Sel;
}
return Sel;
}
uint32_t MultiplexExternalSemaSource::GetNumExternalSelectors() {
uint32_t total = 0;
for(size_t i = 0; i < Sources.size(); ++i)
total += Sources[i]->GetNumExternalSelectors();
return total;
}
Stmt *MultiplexExternalSemaSource::GetExternalDeclStmt(uint64_t Offset) {
for(size_t i = 0; i < Sources.size(); ++i)
if (Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset))
return Result;
return nullptr;
}
CXXBaseSpecifier *MultiplexExternalSemaSource::GetExternalCXXBaseSpecifiers(
uint64_t Offset){
for(size_t i = 0; i < Sources.size(); ++i)
if (CXXBaseSpecifier *R = Sources[i]->GetExternalCXXBaseSpecifiers(Offset))
return R;
return nullptr;
}
CXXCtorInitializer **
MultiplexExternalSemaSource::GetExternalCXXCtorInitializers(uint64_t Offset) {
for (auto *S : Sources)
if (auto *R = S->GetExternalCXXCtorInitializers(Offset))
return R;
return nullptr;
}
ExternalASTSource::ExtKind
MultiplexExternalSemaSource::hasExternalDefinitions(const Decl *D) {
for (const auto &S : Sources)
if (auto EK = S->hasExternalDefinitions(D))
if (EK != EK_ReplyHazy)
return EK;
return EK_ReplyHazy;
}
bool MultiplexExternalSemaSource::
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
bool AnyDeclsFound = false;
for (size_t i = 0; i < Sources.size(); ++i)
AnyDeclsFound |= Sources[i]->FindExternalVisibleDeclsByName(DC, Name);
return AnyDeclsFound;
}
void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->completeVisibleDeclsMap(DC);
}
void MultiplexExternalSemaSource::FindExternalLexicalDecls(
const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->FindExternalLexicalDecls(DC, IsKindWeWant, Result);
}
void MultiplexExternalSemaSource::FindFileRegionDecls(FileID File,
unsigned Offset,
unsigned Length,
SmallVectorImpl<Decl *> &Decls){
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls);
}
void MultiplexExternalSemaSource::CompleteType(TagDecl *Tag) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->CompleteType(Tag);
}
void MultiplexExternalSemaSource::CompleteType(ObjCInterfaceDecl *Class) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->CompleteType(Class);
}
void MultiplexExternalSemaSource::ReadComments() {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadComments();
}
void MultiplexExternalSemaSource::StartedDeserializing() {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->StartedDeserializing();
}
void MultiplexExternalSemaSource::FinishedDeserializing() {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->FinishedDeserializing();
}
void MultiplexExternalSemaSource::StartTranslationUnit(ASTConsumer *Consumer) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->StartTranslationUnit(Consumer);
}
void MultiplexExternalSemaSource::PrintStats() {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->PrintStats();
}
bool MultiplexExternalSemaSource::layoutRecordType(const RecordDecl *Record,
uint64_t &Size,
uint64_t &Alignment,
llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets){
for(size_t i = 0; i < Sources.size(); ++i)
if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets,
BaseOffsets, VirtualBaseOffsets))
return true;
return false;
}
void MultiplexExternalSemaSource::
getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->getMemoryBufferSizes(sizes);
}
//===----------------------------------------------------------------------===//
// ExternalSemaSource.
//===----------------------------------------------------------------------===//
void MultiplexExternalSemaSource::InitializeSema(Sema &S) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->InitializeSema(S);
}
void MultiplexExternalSemaSource::ForgetSema() {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ForgetSema();
}
void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadMethodPool(Sel);
}
void MultiplexExternalSemaSource::updateOutOfDateSelector(Selector Sel) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->updateOutOfDateSelector(Sel);
}
void MultiplexExternalSemaSource::ReadKnownNamespaces(
SmallVectorImpl<NamespaceDecl*> &Namespaces){
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadKnownNamespaces(Namespaces);
}
void MultiplexExternalSemaSource::ReadUndefinedButUsed(
llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadUndefinedButUsed(Undefined);
}
void MultiplexExternalSemaSource::ReadMismatchingDeleteExpressions(
llvm::MapVector<FieldDecl *,
llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
Exprs) {
for (auto &Source : Sources)
Source->ReadMismatchingDeleteExpressions(Exprs);
}
bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->LookupUnqualified(R, S);
return !R.empty();
}
void MultiplexExternalSemaSource::ReadTentativeDefinitions(
SmallVectorImpl<VarDecl*> &TentativeDefs) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadTentativeDefinitions(TentativeDefs);
}
void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls(
SmallVectorImpl<const DeclaratorDecl*> &Decls) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadUnusedFileScopedDecls(Decls);
}
void MultiplexExternalSemaSource::ReadDelegatingConstructors(
SmallVectorImpl<CXXConstructorDecl*> &Decls) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadDelegatingConstructors(Decls);
}
void MultiplexExternalSemaSource::ReadExtVectorDecls(
SmallVectorImpl<TypedefNameDecl*> &Decls) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadExtVectorDecls(Decls);
}
void MultiplexExternalSemaSource::ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadUnusedLocalTypedefNameCandidates(Decls);
}
void MultiplexExternalSemaSource::ReadReferencedSelectors(
SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadReferencedSelectors(Sels);
}
void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers(
SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadWeakUndeclaredIdentifiers(WI);
}
void MultiplexExternalSemaSource::ReadUsedVTables(
SmallVectorImpl<ExternalVTableUse> &VTables) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadUsedVTables(VTables);
}
void MultiplexExternalSemaSource::ReadPendingInstantiations(
SmallVectorImpl<std::pair<ValueDecl*,
SourceLocation> > &Pending) {
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadPendingInstantiations(Pending);
}
void MultiplexExternalSemaSource::ReadLateParsedTemplates(
llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
&LPTMap) {
for (size_t i = 0; i < Sources.size(); ++i)
Sources[i]->ReadLateParsedTemplates(LPTMap);
}
TypoCorrection MultiplexExternalSemaSource::CorrectTypo(
const DeclarationNameInfo &Typo,
int LookupKind, Scope *S, CXXScopeSpec *SS,
CorrectionCandidateCallback &CCC,
DeclContext *MemberContext,
bool EnteringContext,
const ObjCObjectPointerType *OPT) {
for (size_t I = 0, E = Sources.size(); I < E; ++I) {
if (TypoCorrection C = Sources[I]->CorrectTypo(Typo, LookupKind, S, SS, CCC,
MemberContext,
EnteringContext, OPT))
return C;
}
return TypoCorrection();
}
bool MultiplexExternalSemaSource::MaybeDiagnoseMissingCompleteType(
SourceLocation Loc, QualType T) {
for (size_t I = 0, E = Sources.size(); I < E; ++I) {
if (Sources[I]->MaybeDiagnoseMissingCompleteType(Loc, T))
return true;
}
return false;
}

View File

@ -0,0 +1,199 @@
//===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Scope class, which is used for recording
// information about a lexical scope.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/Scope.h"
#include "clang/AST/Decl.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
void Scope::setFlags(Scope *parent, unsigned flags) {
AnyParent = parent;
Flags = flags;
if (parent && !(flags & FnScope)) {
BreakParent = parent->BreakParent;
ContinueParent = parent->ContinueParent;
} else {
// Control scopes do not contain the contents of nested function scopes for
// control flow purposes.
BreakParent = ContinueParent = nullptr;
}
if (parent) {
Depth = parent->Depth + 1;
PrototypeDepth = parent->PrototypeDepth;
PrototypeIndex = 0;
FnParent = parent->FnParent;
BlockParent = parent->BlockParent;
TemplateParamParent = parent->TemplateParamParent;
MSLastManglingParent = parent->MSLastManglingParent;
MSCurManglingNumber = getMSLastManglingNumber();
if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
0)
Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
} else {
Depth = 0;
PrototypeDepth = 0;
PrototypeIndex = 0;
MSLastManglingParent = FnParent = BlockParent = nullptr;
TemplateParamParent = nullptr;
MSLastManglingNumber = 1;
MSCurManglingNumber = 1;
}
// If this scope is a function or contains breaks/continues, remember it.
if (flags & FnScope) FnParent = this;
// The MS mangler uses the number of scopes that can hold declarations as
// part of an external name.
if (Flags & (ClassScope | FnScope)) {
MSLastManglingNumber = getMSLastManglingNumber();
MSLastManglingParent = this;
MSCurManglingNumber = 1;
}
if (flags & BreakScope) BreakParent = this;
if (flags & ContinueScope) ContinueParent = this;
if (flags & BlockScope) BlockParent = this;
if (flags & TemplateParamScope) TemplateParamParent = this;
// If this is a prototype scope, record that.
if (flags & FunctionPrototypeScope) PrototypeDepth++;
if (flags & DeclScope) {
if (flags & FunctionPrototypeScope)
; // Prototype scopes are uninteresting.
else if ((flags & ClassScope) && getParent()->isClassScope())
; // Nested class scopes aren't ambiguous.
else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
; // Classes inside of namespaces aren't ambiguous.
else if ((flags & EnumScope))
; // Don't increment for enum scopes.
else
incrementMSManglingNumber();
}
}
void Scope::Init(Scope *parent, unsigned flags) {
setFlags(parent, flags);
DeclsInScope.clear();
UsingDirectives.clear();
Entity = nullptr;
ErrorTrap.reset();
NRVO.setPointerAndInt(nullptr, 0);
}
bool Scope::containedInPrototypeScope() const {
const Scope *S = this;
while (S) {
if (S->isFunctionPrototypeScope())
return true;
S = S->getParent();
}
return false;
}
void Scope::AddFlags(unsigned FlagsToSet) {
assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
"Unsupported scope flags");
if (FlagsToSet & BreakScope) {
assert((Flags & BreakScope) == 0 && "Already set");
BreakParent = this;
}
if (FlagsToSet & ContinueScope) {
assert((Flags & ContinueScope) == 0 && "Already set");
ContinueParent = this;
}
Flags |= FlagsToSet;
}
void Scope::mergeNRVOIntoParent() {
if (VarDecl *Candidate = NRVO.getPointer()) {
if (isDeclScope(Candidate))
Candidate->setNRVOVariable(true);
}
if (getEntity())
return;
if (NRVO.getInt())
getParent()->setNoNRVO();
else if (NRVO.getPointer())
getParent()->addNRVOCandidate(NRVO.getPointer());
}
LLVM_DUMP_METHOD void Scope::dump() const { dumpImpl(llvm::errs()); }
void Scope::dumpImpl(raw_ostream &OS) const {
unsigned Flags = getFlags();
bool HasFlags = Flags != 0;
if (HasFlags)
OS << "Flags: ";
std::pair<unsigned, const char *> FlagInfo[] = {
{FnScope, "FnScope"},
{BreakScope, "BreakScope"},
{ContinueScope, "ContinueScope"},
{DeclScope, "DeclScope"},
{ControlScope, "ControlScope"},
{ClassScope, "ClassScope"},
{BlockScope, "BlockScope"},
{TemplateParamScope, "TemplateParamScope"},
{FunctionPrototypeScope, "FunctionPrototypeScope"},
{FunctionDeclarationScope, "FunctionDeclarationScope"},
{AtCatchScope, "AtCatchScope"},
{ObjCMethodScope, "ObjCMethodScope"},
{SwitchScope, "SwitchScope"},
{TryScope, "TryScope"},
{FnTryCatchScope, "FnTryCatchScope"},
{OpenMPDirectiveScope, "OpenMPDirectiveScope"},
{OpenMPLoopDirectiveScope, "OpenMPLoopDirectiveScope"},
{OpenMPSimdDirectiveScope, "OpenMPSimdDirectiveScope"},
{EnumScope, "EnumScope"},
{SEHTryScope, "SEHTryScope"},
{SEHExceptScope, "SEHExceptScope"},
{SEHFilterScope, "SEHFilterScope"},
{CompoundStmtScope, "CompoundStmtScope"},
{ClassInheritanceScope, "ClassInheritanceScope"}};
for (auto Info : FlagInfo) {
if (Flags & Info.first) {
OS << Info.second;
Flags &= ~Info.first;
if (Flags)
OS << " | ";
}
}
assert(Flags == 0 && "Unknown scope flags");
if (HasFlags)
OS << '\n';
if (const Scope *Parent = getParent())
OS << "Parent: (clang::Scope*)" << Parent << '\n';
OS << "Depth: " << Depth << '\n';
OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n';
OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n';
if (const DeclContext *DC = getEntity())
OS << "Entity : (clang::DeclContext*)" << DC << '\n';
if (NRVO.getInt())
OS << "NRVO not allowed\n";
else if (NRVO.getPointer())
OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
}

View File

@ -0,0 +1,250 @@
//===--- ScopeInfo.cpp - Information about a semantic context -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements FunctionScopeInfo and its subclasses, which contain
// information about a single function, block, lambda, or method body.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/ScopeInfo.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
using namespace clang;
using namespace sema;
void FunctionScopeInfo::Clear() {
HasBranchProtectedScope = false;
HasBranchIntoScope = false;
HasIndirectGoto = false;
HasDroppedStmt = false;
HasOMPDeclareReductionCombiner = false;
HasFallthroughStmt = false;
HasPotentialAvailabilityViolations = false;
ObjCShouldCallSuper = false;
ObjCIsDesignatedInit = false;
ObjCWarnForNoDesignatedInitChain = false;
ObjCIsSecondaryInit = false;
ObjCWarnForNoInitDelegation = false;
FirstReturnLoc = SourceLocation();
FirstCXXTryLoc = SourceLocation();
FirstSEHTryLoc = SourceLocation();
// Coroutine state
FirstCoroutineStmtLoc = SourceLocation();
CoroutinePromise = nullptr;
NeedsCoroutineSuspends = true;
CoroutineSuspends.first = nullptr;
CoroutineSuspends.second = nullptr;
SwitchStack.clear();
Returns.clear();
ErrorTrap.reset();
PossiblyUnreachableDiags.clear();
WeakObjectUses.clear();
ModifiedNonNullParams.clear();
}
static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
if (PropE->isExplicitProperty())
return PropE->getExplicitProperty();
return PropE->getImplicitPropertyGetter();
}
FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
E = E->IgnoreParenCasts();
const NamedDecl *D = nullptr;
bool IsExact = false;
switch (E->getStmtClass()) {
case Stmt::DeclRefExprClass:
D = cast<DeclRefExpr>(E)->getDecl();
IsExact = isa<VarDecl>(D);
break;
case Stmt::MemberExprClass: {
const MemberExpr *ME = cast<MemberExpr>(E);
D = ME->getMemberDecl();
IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
break;
}
case Stmt::ObjCIvarRefExprClass: {
const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
D = IE->getDecl();
IsExact = IE->getBase()->isObjCSelfExpr();
break;
}
case Stmt::PseudoObjectExprClass: {
const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
const ObjCPropertyRefExpr *BaseProp =
dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
if (BaseProp) {
D = getBestPropertyDecl(BaseProp);
if (BaseProp->isObjectReceiver()) {
const Expr *DoubleBase = BaseProp->getBase();
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
DoubleBase = OVE->getSourceExpr();
IsExact = DoubleBase->isObjCSelfExpr();
}
}
break;
}
default:
break;
}
return BaseInfoTy(D, IsExact);
}
bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {
RecordDecl *RD = nullptr;
if (auto *LSI = dyn_cast<LambdaScopeInfo>(this))
RD = LSI->Lambda;
else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(this))
RD = CRSI->TheRecordDecl;
if (RD)
for (auto *FD : RD->fields()) {
if (FD->hasCapturedVLAType() && FD->getCapturedVLAType() == VAT)
return true;
}
return false;
}
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
const ObjCPropertyRefExpr *PropE)
: Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
if (PropE->isObjectReceiver()) {
const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
const Expr *E = OVE->getSourceExpr();
Base = getBaseInfo(E);
} else if (PropE->isClassReceiver()) {
Base.setPointer(PropE->getClassReceiver());
} else {
assert(PropE->isSuperReceiver());
}
}
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
const ObjCPropertyDecl *Prop)
: Base(nullptr, true), Property(Prop) {
if (BaseE)
Base = getBaseInfo(BaseE);
// else, this is a message accessing a property on super.
}
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
const DeclRefExpr *DRE)
: Base(nullptr, true), Property(DRE->getDecl()) {
assert(isa<VarDecl>(Property));
}
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
const ObjCIvarRefExpr *IvarE)
: Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
}
void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
const ObjCPropertyDecl *Prop) {
assert(Msg && Prop);
WeakUseVector &Uses =
WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
}
void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
E = E->IgnoreParenCasts();
if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
markSafeWeakUse(POE->getSyntacticForm());
return;
}
if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
markSafeWeakUse(Cond->getTrueExpr());
markSafeWeakUse(Cond->getFalseExpr());
return;
}
if (const BinaryConditionalOperator *Cond =
dyn_cast<BinaryConditionalOperator>(E)) {
markSafeWeakUse(Cond->getCommon());
markSafeWeakUse(Cond->getFalseExpr());
return;
}
// Has this weak object been seen before?
FunctionScopeInfo::WeakObjectUseMap::iterator Uses = WeakObjectUses.end();
if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
if (!RefExpr->isObjectReceiver())
return;
if (isa<OpaqueValueExpr>(RefExpr->getBase()))
Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
else {
markSafeWeakUse(RefExpr->getBase());
return;
}
}
else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
if (isa<VarDecl>(DRE->getDecl()))
Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
} else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
Uses =
WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
Prop));
}
}
}
else
return;
if (Uses == WeakObjectUses.end())
return;
// Has there been a read from the object using this Expr?
FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
llvm::find(llvm::reverse(Uses->second), WeakUseTy(E, true));
if (ThisUse == Uses->second.rend())
return;
ThisUse->markSafe();
}
void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD,
Expr *&E) const {
assert(Idx < getNumPotentialVariableCaptures() &&
"Index of potential capture must be within 0 to less than the "
"number of captures!");
E = PotentiallyCapturingExprs[Idx];
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
VD = dyn_cast<VarDecl>(DRE->getFoundDecl());
else if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
VD = dyn_cast<VarDecl>(ME->getMemberDecl());
else
llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for "
"potential captures");
assert(VD);
}
FunctionScopeInfo::~FunctionScopeInfo() { }
BlockScopeInfo::~BlockScopeInfo() { }
CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
ad6348685b64e6ac8a989cb0ddfa15c712d0080e

View File

@ -0,0 +1 @@
57af6b86bf8061e09525ffaa9b87a7345ccf526c

View File

@ -0,0 +1 @@
2acc896d53d71bd2d29997984b6706df66fd45a5

Some files were not shown because too many files have changed in this diff Show More