summaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp200
1 files changed, 123 insertions, 77 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index c42944df6344..0fbdd7e5daeb 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -12,19 +12,19 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Serialization/ASTReader.h"
#include "ASTCommon.h"
#include "ASTReaderInternals.h"
-#include "clang/Serialization/ASTReader.h"
-#include "clang/Sema/IdentifierResolver.h"
-#include "clang/Sema/Sema.h"
-#include "clang/Sema/SemaDiagnostic.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/Support/SaveAndRestore.h"
using namespace clang;
using namespace clang::serialization;
@@ -44,9 +44,6 @@ namespace clang {
unsigned &Idx;
TypeID TypeIDForTypeDecl;
- DeclID DeclContextIDForTemplateParmDecl;
- DeclID LexicalDeclContextIDForTemplateParmDecl;
-
bool HasPendingBody;
uint64_t GetCurrentCursorOffset();
@@ -116,29 +113,25 @@ namespace clang {
ASTReader &Reader;
GlobalDeclID FirstID;
mutable bool Owning;
+ Decl::Kind DeclKind;
void operator=(RedeclarableResult &) LLVM_DELETED_FUNCTION;
public:
- RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID)
- : Reader(Reader), FirstID(FirstID), Owning(true) { }
+ RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID,
+ Decl::Kind DeclKind)
+ : Reader(Reader), FirstID(FirstID), Owning(true), DeclKind(DeclKind) { }
RedeclarableResult(const RedeclarableResult &Other)
- : Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning)
+ : Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning) ,
+ DeclKind(Other.DeclKind)
{
Other.Owning = false;
}
~RedeclarableResult() {
- // FIXME: We want to suppress this when the declaration is local to
- // a function, since there's no reason to search other AST files
- // for redeclarations (they can't exist). However, this is hard to
- // do locally because the declaration hasn't necessarily loaded its
- // declaration context yet. Also, local externs still have the function
- // as their (semantic) declaration context, which is wrong and would
- // break this optimize.
-
- if (FirstID && Owning && Reader.PendingDeclChainsKnown.insert(FirstID))
+ if (FirstID && Owning && isRedeclarableDeclKind(DeclKind) &&
+ Reader.PendingDeclChainsKnown.insert(FirstID))
Reader.PendingDeclChains.push_back(FirstID);
}
@@ -151,7 +144,7 @@ namespace clang {
Owning = false;
}
};
-
+
/// \brief Class used to capture the result of searching for an existing
/// declaration of a specific kind and name, along with the ability
/// to update the place where this result was found (the declaration
@@ -272,6 +265,7 @@ namespace clang {
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
void VisitStaticAssertDecl(StaticAssertDecl *D);
void VisitBlockDecl(BlockDecl *BD);
+ void VisitEmptyDecl(EmptyDecl *D);
std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
@@ -295,6 +289,7 @@ namespace clang {
void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+ void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
};
}
@@ -333,14 +328,6 @@ void ASTDeclReader::Visit(Decl *D) {
Reader.PendingBodies[FD] = GetCurrentCursorOffset();
HasPendingBody = true;
}
- } else if (D->isTemplateParameter()) {
- // If we have a fully initialized template parameter, we can now
- // set its DeclContext.
- DeclContext *SemaDC = cast<DeclContext>(
- Reader.GetDecl(DeclContextIDForTemplateParmDecl));
- DeclContext *LexicalDC = cast<DeclContext>(
- Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl));
- D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext());
}
}
@@ -350,8 +337,11 @@ void ASTDeclReader::VisitDecl(Decl *D) {
// parameter immediately, because the template parameter might be
// used in the formulation of its DeclContext. Use the translation
// unit DeclContext as a placeholder.
- DeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
- LexicalDeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ Reader.addPendingDeclContextInfo(D,
+ SemaDCIDForTemplateParmDecl,
+ LexicalDCIDForTemplateParmDecl);
D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
} else {
DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx);
@@ -479,6 +469,7 @@ void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
RD->setHasFlexibleArrayMember(Record[Idx++]);
RD->setAnonymousStructOrUnion(Record[Idx++]);
RD->setHasObjectMember(Record[Idx++]);
+ RD->setHasVolatileMember(Record[Idx++]);
}
void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
@@ -513,9 +504,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
// FunctionDecl's body is handled last at ASTDeclReader::Visit,
// after everything else is read.
-
+
FD->SClass = (StorageClass)Record[Idx++];
- FD->SClassAsWritten = (StorageClass)Record[Idx++];
FD->IsInline = Record[Idx++];
FD->IsInlineSpecified = Record[Idx++];
FD->IsVirtualAsWritten = Record[Idx++];
@@ -528,6 +518,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->IsExplicitlyDefaulted = Record[Idx++];
FD->HasImplicitReturnZero = Record[Idx++];
FD->IsConstexpr = Record[Idx++];
+ FD->HasSkippedBody = Record[Idx++];
+ FD->HasCachedLinkage = true;
+ FD->CachedLinkage = Record[Idx++];
FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
@@ -652,6 +645,7 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
MD->setPropertyAccessor(Record[Idx++]);
MD->setDefined(Record[Idx++]);
MD->IsOverriding = Record[Idx++];
+ MD->HasSkippedBody = Record[Idx++];
MD->IsRedeclaration = Record[Idx++];
MD->HasRedeclaration = Record[Idx++];
@@ -899,9 +893,8 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
RedeclarableResult Redecl = VisitRedeclarable(VD);
VisitDeclaratorDecl(VD);
-
+
VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
- VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++];
VD->VarDeclBits.ThreadSpecified = Record[Idx++];
VD->VarDeclBits.InitStyle = Record[Idx++];
VD->VarDeclBits.ExceptionVar = Record[Idx++];
@@ -909,6 +902,8 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
VD->VarDeclBits.CXXForRangeDecl = Record[Idx++];
VD->VarDeclBits.ARCPseudoStrong = Record[Idx++];
VD->VarDeclBits.IsConstexpr = Record[Idx++];
+ VD->HasCachedLinkage = true;
+ VD->CachedLinkage = Record[Idx++];
// Only true variables (not parameters or implicit parameters) can be merged.
if (VD->getKind() == Decl::Var)
@@ -1083,11 +1078,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
const RecordData &Record, unsigned &Idx) {
// Note: the caller has deserialized the IsLambda bit already.
Data.UserDeclaredConstructor = Record[Idx++];
- Data.UserDeclaredCopyConstructor = Record[Idx++];
- Data.UserDeclaredMoveConstructor = Record[Idx++];
- Data.UserDeclaredCopyAssignment = Record[Idx++];
- Data.UserDeclaredMoveAssignment = Record[Idx++];
- Data.UserDeclaredDestructor = Record[Idx++];
+ Data.UserDeclaredSpecialMembers = Record[Idx++];
Data.Aggregate = Record[Idx++];
Data.PlainOldData = Record[Idx++];
Data.Empty = Record[Idx++];
@@ -1101,25 +1092,26 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasMutableFields = Record[Idx++];
Data.HasOnlyCMembers = Record[Idx++];
Data.HasInClassInitializer = Record[Idx++];
- Data.HasTrivialDefaultConstructor = Record[Idx++];
+ Data.HasUninitializedReferenceMember = Record[Idx++];
+ Data.NeedOverloadResolutionForMoveConstructor = Record[Idx++];
+ Data.NeedOverloadResolutionForMoveAssignment = Record[Idx++];
+ Data.NeedOverloadResolutionForDestructor = Record[Idx++];
+ Data.DefaultedMoveConstructorIsDeleted = Record[Idx++];
+ Data.DefaultedMoveAssignmentIsDeleted = Record[Idx++];
+ Data.DefaultedDestructorIsDeleted = Record[Idx++];
+ Data.HasTrivialSpecialMembers = Record[Idx++];
+ Data.HasIrrelevantDestructor = Record[Idx++];
Data.HasConstexprNonCopyMoveConstructor = Record[Idx++];
Data.DefaultedDefaultConstructorIsConstexpr = Record[Idx++];
Data.HasConstexprDefaultConstructor = Record[Idx++];
- Data.HasTrivialCopyConstructor = Record[Idx++];
- Data.HasTrivialMoveConstructor = Record[Idx++];
- Data.HasTrivialCopyAssignment = Record[Idx++];
- Data.HasTrivialMoveAssignment = Record[Idx++];
- Data.HasTrivialDestructor = Record[Idx++];
- Data.HasIrrelevantDestructor = Record[Idx++];
Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++];
Data.ComputedVisibleConversions = Record[Idx++];
Data.UserProvidedDefaultConstructor = Record[Idx++];
- Data.DeclaredDefaultConstructor = Record[Idx++];
- Data.DeclaredCopyConstructor = Record[Idx++];
- Data.DeclaredMoveConstructor = Record[Idx++];
- Data.DeclaredCopyAssignment = Record[Idx++];
- Data.DeclaredMoveAssignment = Record[Idx++];
- Data.DeclaredDestructor = Record[Idx++];
+ Data.DeclaredSpecialMembers = Record[Idx++];
+ Data.ImplicitCopyConstructorHasConstParam = Record[Idx++];
+ Data.ImplicitCopyAssignmentHasConstParam = Record[Idx++];
+ Data.HasDeclaredCopyConstructorWithConstParam = Record[Idx++];
+ Data.HasDeclaredCopyAssignmentWithConstParam = Record[Idx++];
Data.FailedImplicitMoveConstructor = Record[Idx++];
Data.FailedImplicitMoveAssignment = Record[Idx++];
@@ -1266,10 +1258,12 @@ void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
VisitDecl(D);
- if (Record[Idx++])
- D->Friend = GetTypeSourceInfo(Record, Idx);
- else
+ if (Record[Idx++]) // hasFriendDecl
D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
+ else
+ D->Friend = GetTypeSourceInfo(Record, Idx);
+ for (unsigned i = 0; i != D->NumTPLists; ++i)
+ D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
D->NextFriend = Record[Idx++];
D->UnsupportedFriend = (Record[Idx++] != 0);
D->FriendLoc = ReadSourceLocation(Record, Idx);
@@ -1532,6 +1526,10 @@ void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
D->RParenLoc = ReadSourceLocation(Record, Idx);
}
+void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) {
+ VisitDecl(D);
+}
+
std::pair<uint64_t, uint64_t>
ASTDeclReader::VisitDeclContext(DeclContext *DC) {
uint64_t LexicalOffset = Record[Idx++];
@@ -1563,7 +1561,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
// The result structure takes care to note that we need to load the
// other declaration chains for this ID.
- return RedeclarableResult(Reader, FirstDeclID);
+ return RedeclarableResult(Reader, FirstDeclID,
+ static_cast<T *>(D)->getKind());
}
/// \brief Attempts to merge the given declaration (D) with another declaration
@@ -1626,6 +1625,17 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D,
}
}
+void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
+ VisitDecl(D);
+ unsigned NumVars = D->varlist_size();
+ SmallVector<DeclRefExpr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned i = 0; i != NumVars; ++i) {
+ Vars.push_back(cast<DeclRefExpr>(Reader.ReadExpr(F)));
+ }
+ D->setVars(Vars);
+}
+
//===----------------------------------------------------------------------===//
// Attribute Reading
//===----------------------------------------------------------------------===//
@@ -1811,6 +1821,30 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
if (DC->isTranslationUnit() && Reader.SemaObj) {
IdentifierResolver &IdResolver = Reader.SemaObj->IdResolver;
+
+ // Temporarily consider the identifier to be up-to-date. We don't want to
+ // cause additional lookups here.
+ class UpToDateIdentifierRAII {
+ IdentifierInfo *II;
+ bool WasOutToDate;
+
+ public:
+ explicit UpToDateIdentifierRAII(IdentifierInfo *II)
+ : II(II), WasOutToDate(false)
+ {
+ if (II) {
+ WasOutToDate = II->isOutOfDate();
+ if (WasOutToDate)
+ II->setOutOfDate(false);
+ }
+ }
+
+ ~UpToDateIdentifierRAII() {
+ if (WasOutToDate)
+ II->setOutOfDate(true);
+ }
+ } UpToDate(Name.getAsIdentifierInfo());
+
for (IdentifierResolver::iterator I = IdResolver.begin(Name),
IEnd = IdResolver.end();
I != IEnd; ++I) {
@@ -1820,10 +1854,11 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
}
if (DC->isNamespace()) {
- for (DeclContext::lookup_result R = DC->lookup(Name);
- R.first != R.second; ++R.first) {
- if (isSameEntity(*R.first, D))
- return FindExistingResult(Reader, D, *R.first);
+ DeclContext::lookup_result R = DC->lookup(Name);
+ for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
+ ++I) {
+ if (isSameEntity(*I, D))
+ return FindExistingResult(Reader, D, *I);
}
}
@@ -1937,7 +1972,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
ASTDeclReader Reader(*this, *Loc.F, ID, RawLocation, Record,Idx);
Decl *D = 0;
- switch ((DeclCode)DeclsCursor.ReadRecord(Code, Record)) {
+ switch ((DeclCode)DeclsCursor.readRecord(Code, Record)) {
case DECL_CONTEXT_LEXICAL:
case DECL_CONTEXT_VISIBLE:
llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord");
@@ -2005,7 +2040,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
D = AccessSpecDecl::CreateDeserialized(Context, ID);
break;
case DECL_FRIEND:
- D = FriendDecl::CreateDeserialized(Context, ID);
+ D = FriendDecl::CreateDeserialized(Context, ID, Record[Idx++]);
break;
case DECL_FRIEND_TEMPLATE:
D = FriendTemplateDecl::CreateDeserialized(Context, ID);
@@ -2109,6 +2144,12 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
// locations.
D = ImportDecl::CreateDeserialized(Context, ID, Record.back());
break;
+ case DECL_OMP_THREADPRIVATE:
+ D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record[Idx++]);
+ break;
+ case DECL_EMPTY:
+ D = EmptyDecl::CreateDeserialized(Context, ID);
+ break;
}
assert(D && "Unknown declaration reading AST file");
@@ -2122,12 +2163,18 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
// If this declaration is also a declaration context, get the
// offsets for its tables of lexical and visible declarations.
if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
+ // FIXME: This should really be
+ // DeclContext *LookupDC = DC->getPrimaryContext();
+ // but that can walk the redeclaration chain, which might not work yet.
+ DeclContext *LookupDC = DC;
+ if (isa<NamespaceDecl>(DC))
+ LookupDC = DC->getPrimaryContext();
std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
if (Offsets.first || Offsets.second) {
if (Offsets.first != 0)
DC->setHasExternalLexicalStorage(true);
if (Offsets.second != 0)
- DC->setHasExternalVisibleStorage(true);
+ LookupDC->setHasExternalVisibleStorage(true);
if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets,
Loc.F->DeclContextInfos[DC]))
return 0;
@@ -2139,7 +2186,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
if (I != PendingVisibleUpdates.end()) {
// There are updates. This means the context has external visible
// storage, even if the original stored version didn't.
- DC->setHasExternalVisibleStorage(true);
+ LookupDC->setHasExternalVisibleStorage(true);
DeclContextVisibleUpdates &U = I->second;
for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
UI != UE; ++UI) {
@@ -2149,9 +2196,6 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
}
PendingVisibleUpdates.erase(I);
}
-
- if (!DC->hasExternalVisibleStorage() && DC->hasExternalLexicalStorage())
- DC->setMustBuildLookupTable();
}
assert(Idx == Record.size());
@@ -2189,7 +2233,7 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
Cursor.JumpToBit(Offset);
RecordData Record;
unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.ReadRecord(Code, Record);
+ unsigned RecCode = Cursor.readRecord(Code, Record);
(void)RecCode;
assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
@@ -2226,7 +2270,7 @@ namespace {
SmallVectorImpl<DeclID> &SearchDecls;
llvm::SmallPtrSet<Decl *, 16> &Deserialized;
GlobalDeclID CanonID;
- llvm::SmallVector<Decl *, 4> Chain;
+ SmallVector<Decl *, 4> Chain;
public:
RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls,
@@ -2307,7 +2351,7 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
Decl *CanonDecl = D->getCanonicalDecl();
// Determine the set of declaration IDs we'll be searching for.
- llvm::SmallVector<DeclID, 1> SearchDecls;
+ SmallVector<DeclID, 1> SearchDecls;
GlobalDeclID CanonID = 0;
if (D == CanonDecl) {
SearchDecls.push_back(ID); // Always first.
@@ -2404,7 +2448,7 @@ namespace {
if (Tail)
ASTDeclReader::setNextObjCCategory(Tail, Cat);
else
- Interface->setCategoryList(Cat);
+ Interface->setCategoryListRaw(Cat);
Tail = Cat;
}
@@ -2419,13 +2463,15 @@ namespace {
Tail(0)
{
// Populate the name -> category map with the set of known categories.
- for (ObjCCategoryDecl *Cat = Interface->getCategoryList(); Cat;
- Cat = Cat->getNextClassCategory()) {
+ for (ObjCInterfaceDecl::known_categories_iterator
+ Cat = Interface->known_categories_begin(),
+ CatEnd = Interface->known_categories_end();
+ Cat != CatEnd; ++Cat) {
if (Cat->getDeclName())
- NameCategoryMap[Cat->getDeclName()] = Cat;
+ NameCategoryMap[Cat->getDeclName()] = *Cat;
// Keep track of the tail of the category list.
- Tail = Cat;
+ Tail = *Cat;
}
}