Update aosp/master Clang for rebase to r222490.
Change-Id: Ic557ac55e97fbf6ee08771c7b7c3594777b0aefd
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index a02a959..b9be775 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -51,6 +51,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/OnDiskHashTable.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
#include <algorithm>
#include <cstdio>
#include <string.h>
@@ -83,6 +84,8 @@
public:
/// \brief Type code that corresponds to the record generated.
TypeCode Code;
+ /// \brief Abbreviation to use for the record, if any.
+ unsigned AbbrevToUse;
ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
: Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { }
@@ -190,6 +193,9 @@
// FIXME: need to stabilize encoding of calling convention...
Record.push_back(C.getCC());
Record.push_back(C.getProducesResult());
+
+ if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult())
+ AbbrevToUse = 0;
}
void ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
@@ -216,14 +222,21 @@
void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
VisitFunctionType(T);
- Record.push_back(T->getNumParams());
- for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
- Writer.AddTypeRef(T->getParamType(I), Record);
+
Record.push_back(T->isVariadic());
Record.push_back(T->hasTrailingReturn());
Record.push_back(T->getTypeQuals());
Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
addExceptionSpec(Writer, T, Record);
+
+ Record.push_back(T->getNumParams());
+ for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
+ Writer.AddTypeRef(T->getParamType(I), Record);
+
+ if (T->isVariadic() || T->hasTrailingReturn() || T->getTypeQuals() ||
+ T->getRefQualifier() || T->getExceptionSpecType() != EST_None)
+ AbbrevToUse = 0;
+
Code = TYPE_FUNCTION_PROTO;
}
@@ -649,6 +662,40 @@
Writer.AddSourceLocation(TL.getRParenLoc(), Record);
}
+void ASTWriter::WriteTypeAbbrevs() {
+ using namespace llvm;
+
+ BitCodeAbbrev *Abv;
+
+ // Abbreviation for TYPE_EXT_QUAL
+ Abv = new BitCodeAbbrev();
+ Abv->Add(BitCodeAbbrevOp(serialization::TYPE_EXT_QUAL));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3)); // Quals
+ TypeExtQualAbbrev = Stream.EmitAbbrev(Abv);
+
+ // Abbreviation for TYPE_FUNCTION_PROTO
+ Abv = new BitCodeAbbrev();
+ Abv->Add(BitCodeAbbrevOp(serialization::TYPE_FUNCTION_PROTO));
+ // FunctionType
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ReturnType
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // NoReturn
+ Abv->Add(BitCodeAbbrevOp(0)); // HasRegParm
+ Abv->Add(BitCodeAbbrevOp(0)); // RegParm
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC
+ Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult
+ // FunctionProtoType
+ Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic
+ Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn
+ Abv->Add(BitCodeAbbrevOp(0)); // TypeQuals
+ Abv->Add(BitCodeAbbrevOp(0)); // RefQualifier
+ Abv->Add(BitCodeAbbrevOp(EST_None)); // ExceptionSpec
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumParams
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Params
+ TypeFunctionProtoAbbrev = Stream.EmitAbbrev(Abv);
+}
+
//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
@@ -684,6 +731,7 @@
#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
RECORD(STMT_STOP);
RECORD(STMT_NULL_PTR);
+ RECORD(STMT_REF_PTR);
RECORD(STMT_NULL);
RECORD(STMT_COMPOUND);
RECORD(STMT_CASE);
@@ -711,6 +759,7 @@
RECORD(EXPR_STRING_LITERAL);
RECORD(EXPR_CHARACTER_LITERAL);
RECORD(EXPR_PAREN);
+ RECORD(EXPR_PAREN_LIST);
RECORD(EXPR_UNARY_OPERATOR);
RECORD(EXPR_SIZEOF_ALIGN_OF);
RECORD(EXPR_ARRAY_SUBSCRIPT);
@@ -752,8 +801,13 @@
RECORD(STMT_OBJC_AT_SYNCHRONIZED);
RECORD(STMT_OBJC_AT_THROW);
RECORD(EXPR_OBJC_BOOL_LITERAL);
+ RECORD(STMT_CXX_CATCH);
+ RECORD(STMT_CXX_TRY);
+ RECORD(STMT_CXX_FOR_RANGE);
RECORD(EXPR_CXX_OPERATOR_CALL);
+ RECORD(EXPR_CXX_MEMBER_CALL);
RECORD(EXPR_CXX_CONSTRUCT);
+ RECORD(EXPR_CXX_TEMPORARY_OBJECT);
RECORD(EXPR_CXX_STATIC_CAST);
RECORD(EXPR_CXX_DYNAMIC_CAST);
RECORD(EXPR_CXX_REINTERPRET_CAST);
@@ -765,11 +819,10 @@
RECORD(EXPR_CXX_NULL_PTR_LITERAL);
RECORD(EXPR_CXX_TYPEID_EXPR);
RECORD(EXPR_CXX_TYPEID_TYPE);
- RECORD(EXPR_CXX_UUIDOF_EXPR);
- RECORD(EXPR_CXX_UUIDOF_TYPE);
RECORD(EXPR_CXX_THIS);
RECORD(EXPR_CXX_THROW);
RECORD(EXPR_CXX_DEFAULT_ARG);
+ RECORD(EXPR_CXX_DEFAULT_INIT);
RECORD(EXPR_CXX_BIND_TEMPORARY);
RECORD(EXPR_CXX_SCALAR_VALUE_INIT);
RECORD(EXPR_CXX_NEW);
@@ -781,12 +834,22 @@
RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT);
RECORD(EXPR_CXX_UNRESOLVED_MEMBER);
RECORD(EXPR_CXX_UNRESOLVED_LOOKUP);
+ RECORD(EXPR_CXX_EXPRESSION_TRAIT);
RECORD(EXPR_CXX_NOEXCEPT);
RECORD(EXPR_OPAQUE_VALUE);
+ RECORD(EXPR_BINARY_CONDITIONAL_OPERATOR);
+ RECORD(EXPR_TYPE_TRAIT);
+ RECORD(EXPR_ARRAY_TYPE_TRAIT);
RECORD(EXPR_PACK_EXPANSION);
RECORD(EXPR_SIZEOF_PACK);
+ RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM);
RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
+ RECORD(EXPR_FUNCTION_PARM_PACK);
+ RECORD(EXPR_MATERIALIZE_TEMPORARY);
RECORD(EXPR_CUDA_KERNEL_CALL);
+ RECORD(EXPR_CXX_UUIDOF_EXPR);
+ RECORD(EXPR_CXX_UUIDOF_TYPE);
+ RECORD(EXPR_LAMBDA);
#undef RECORD
}
@@ -800,6 +863,7 @@
// Control Block.
BLOCK(CONTROL_BLOCK);
RECORD(METADATA);
+ RECORD(SIGNATURE);
RECORD(MODULE_NAME);
RECORD(MODULE_MAP_FILE);
RECORD(IMPORTS);
@@ -895,15 +959,14 @@
RECORD(TYPE_VARIABLE_ARRAY);
RECORD(TYPE_VECTOR);
RECORD(TYPE_EXT_VECTOR);
- RECORD(TYPE_FUNCTION_PROTO);
RECORD(TYPE_FUNCTION_NO_PROTO);
+ RECORD(TYPE_FUNCTION_PROTO);
RECORD(TYPE_TYPEDEF);
RECORD(TYPE_TYPEOF_EXPR);
RECORD(TYPE_TYPEOF);
RECORD(TYPE_RECORD);
RECORD(TYPE_ENUM);
RECORD(TYPE_OBJC_INTERFACE);
- RECORD(TYPE_OBJC_OBJECT);
RECORD(TYPE_OBJC_OBJECT_POINTER);
RECORD(TYPE_DECLTYPE);
RECORD(TYPE_ELABORATED);
@@ -920,8 +983,13 @@
RECORD(TYPE_PACK_EXPANSION);
RECORD(TYPE_ATTRIBUTED);
RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
+ RECORD(TYPE_AUTO);
+ RECORD(TYPE_UNARY_TRANSFORM);
RECORD(TYPE_ATOMIC);
+ RECORD(TYPE_DECAYED);
+ RECORD(TYPE_ADJUSTED);
RECORD(DECL_TYPEDEF);
+ RECORD(DECL_TYPEALIAS);
RECORD(DECL_ENUM);
RECORD(DECL_RECORD);
RECORD(DECL_ENUM_CONSTANT);
@@ -1026,6 +1094,14 @@
return Filename + Pos;
}
+static ASTFileSignature getSignature() {
+ while (1) {
+ if (ASTFileSignature S = llvm::sys::Process::GetRandomNumber())
+ return S;
+ // Rely on GetRandomNumber to eventually return non-zero...
+ }
+}
+
/// \brief Write the control block.
void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot,
@@ -1055,6 +1131,11 @@
Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
getClangFullRepositoryVersion());
+ // Signature
+ Record.clear();
+ Record.push_back(getSignature());
+ Stream.EmitRecord(SIGNATURE, Record);
+
// Module name
if (WritingModule) {
BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
@@ -1068,17 +1149,28 @@
// Module map file
if (WritingModule) {
- BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
- Abbrev->Add(BitCodeAbbrevOp(MODULE_MAP_FILE));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename
- unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+ Record.clear();
+ auto addModMap = [&](const FileEntry *F) {
+ SmallString<128> ModuleMap(F->getName());
+ llvm::sys::fs::make_absolute(ModuleMap);
+ AddString(ModuleMap.str(), Record);
+ };
- assert(WritingModule->ModuleMap && "missing module map");
- SmallString<128> ModuleMap(WritingModule->ModuleMap->getName());
- llvm::sys::fs::make_absolute(ModuleMap);
- RecordData Record;
- Record.push_back(MODULE_MAP_FILE);
- Stream.EmitRecordWithBlob(AbbrevCode, Record, ModuleMap.str());
+ auto &Map = PP.getHeaderSearchInfo().getModuleMap();
+
+ // Primary module map file.
+ addModMap(Map.getModuleMapFileForUniquing(WritingModule));
+
+ // Additional module map files.
+ if (auto *AdditionalModMaps = Map.getAdditionalModuleMapFiles(WritingModule)) {
+ Record.push_back(AdditionalModMaps->size());
+ for (const FileEntry *F : *AdditionalModMaps)
+ addModMap(F);
+ } else {
+ Record.push_back(0);
+ }
+
+ Stream.EmitRecord(MODULE_MAP_FILE, Record);
}
// Imports
@@ -1096,6 +1188,7 @@
AddSourceLocation((*M)->ImportLoc, Record);
Record.push_back((*M)->File->getSize());
Record.push_back((*M)->File->getModificationTime());
+ Record.push_back((*M)->Signature);
const std::string &FileName = (*M)->FileName;
Record.push_back(FileName.size());
Record.append(FileName.begin(), FileName.end());
@@ -1110,8 +1203,9 @@
Record.push_back(LangOpts.Name);
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
-#include "clang/Basic/LangOptions.def"
-#define SANITIZER(NAME, ID) Record.push_back(LangOpts.Sanitize.ID);
+#include "clang/Basic/LangOptions.def"
+#define SANITIZER(NAME, ID) \
+ Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));
#include "clang/Basic/Sanitizers.def"
Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind());
@@ -1160,6 +1254,9 @@
Record.push_back(DiagOpts.Warnings.size());
for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
AddString(DiagOpts.Warnings[I], Record);
+ Record.push_back(DiagOpts.Remarks.size());
+ for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
+ AddString(DiagOpts.Remarks[I], Record);
// Note: we don't serialize the log or serialization file names, because they
// are generally transient files and will almost always be overridden.
Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
@@ -1900,6 +1997,10 @@
return true;
if (IsModule) {
+ // Re-export any imported directives.
+ if (MD->isImported())
+ return false;
+
SourceLocation Loc = MD->getLocation();
if (Loc.isInvalid())
return true;
@@ -1977,16 +2078,24 @@
AddSourceLocation(MD->getLocation(), Record);
Record.push_back(MD->getKind());
- if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+ if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
MacroID InfoID = getMacroRef(DefMD->getInfo(), Name);
Record.push_back(InfoID);
- Record.push_back(DefMD->isImported());
+ Record.push_back(DefMD->getOwningModuleID());
Record.push_back(DefMD->isAmbiguous());
-
- } else if (VisibilityMacroDirective *
- VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
+ } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
+ Record.push_back(UndefMD->getOwningModuleID());
+ } else {
+ auto *VisMD = cast<VisibilityMacroDirective>(MD);
Record.push_back(VisMD->isPublic());
}
+
+ if (MD->isImported()) {
+ auto Overrides = MD->getOverriddenModules();
+ Record.push_back(Overrides.size());
+ for (auto Override : Overrides)
+ Record.push_back(Override);
+ }
}
if (Record.empty())
continue;
@@ -2262,7 +2371,7 @@
}
// Enter the submodule description block.
- Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
+ Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5);
// Write the abbreviations needed for the submodules block.
using namespace llvm;
@@ -2313,11 +2422,21 @@
unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TEXTUAL_HEADER));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
+ unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+
+ Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_HEADER));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
+ unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
+
+ Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
@@ -2389,35 +2508,27 @@
Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,
UmbrellaDir->getName());
}
-
+
// Emit the headers.
- for (unsigned I = 0, N = Mod->NormalHeaders.size(); I != N; ++I) {
+ struct {
+ unsigned Kind;
+ unsigned Abbrev;
+ ArrayRef<const FileEntry*> Headers;
+ } HeaderLists[] = {
+ {SUBMODULE_HEADER, HeaderAbbrev, Mod->NormalHeaders},
+ {SUBMODULE_TEXTUAL_HEADER, TextualHeaderAbbrev, Mod->TextualHeaders},
+ {SUBMODULE_PRIVATE_HEADER, PrivateHeaderAbbrev, Mod->PrivateHeaders},
+ {SUBMODULE_PRIVATE_TEXTUAL_HEADER, PrivateTextualHeaderAbbrev,
+ Mod->PrivateTextualHeaders},
+ {SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Mod->ExcludedHeaders},
+ {SUBMODULE_TOPHEADER, TopHeaderAbbrev,
+ Mod->getTopHeaders(PP->getFileManager())}
+ };
+ for (auto &HL : HeaderLists) {
Record.clear();
- Record.push_back(SUBMODULE_HEADER);
- Stream.EmitRecordWithBlob(HeaderAbbrev, Record,
- Mod->NormalHeaders[I]->getName());
- }
- // Emit the excluded headers.
- for (unsigned I = 0, N = Mod->ExcludedHeaders.size(); I != N; ++I) {
- Record.clear();
- Record.push_back(SUBMODULE_EXCLUDED_HEADER);
- Stream.EmitRecordWithBlob(ExcludedHeaderAbbrev, Record,
- Mod->ExcludedHeaders[I]->getName());
- }
- // Emit the private headers.
- for (unsigned I = 0, N = Mod->PrivateHeaders.size(); I != N; ++I) {
- Record.clear();
- Record.push_back(SUBMODULE_PRIVATE_HEADER);
- Stream.EmitRecordWithBlob(PrivateHeaderAbbrev, Record,
- Mod->PrivateHeaders[I]->getName());
- }
- ArrayRef<const FileEntry *>
- TopHeaders = Mod->getTopHeaders(PP->getFileManager());
- for (unsigned I = 0, N = TopHeaders.size(); I != N; ++I) {
- Record.clear();
- Record.push_back(SUBMODULE_TOPHEADER);
- Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record,
- TopHeaders[I]->getName());
+ Record.push_back(HL.Kind);
+ for (auto *H : HL.Headers)
+ Stream.EmitRecordWithBlob(HL.Abbrev, Record, H->getName());
}
// Emit the imports.
@@ -2602,12 +2713,14 @@
// Emit the type's representation.
ASTTypeWriter W(*this, Record);
+ W.AbbrevToUse = 0;
if (T.hasLocalNonFastQualifiers()) {
Qualifiers Qs = T.getLocalQualifiers();
AddTypeRef(T.getLocalUnqualifiedType(), Record);
Record.push_back(Qs.getAsOpaqueValue());
W.Code = TYPE_EXT_QUAL;
+ W.AbbrevToUse = TypeExtQualAbbrev;
} else {
switch (T->getTypeClass()) {
// For all of the concrete, non-dependent types, call the
@@ -2620,7 +2733,7 @@
}
// Emit the serialized record.
- Stream.EmitRecord(W.Code, Record);
+ Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
// Flush any expressions that were written as part of this type.
FlushStmts();
@@ -2986,101 +3099,77 @@
if (Macro || (Macro = PP.getMacroDirectiveHistory(II))) {
if (!IsModule)
return !shouldIgnoreMacro(Macro, IsModule, PP);
- SubmoduleID ModID;
- if (getFirstPublicSubmoduleMacro(Macro, ModID))
+
+ MacroState State;
+ if (getFirstPublicSubmoduleMacro(Macro, State))
return true;
}
return false;
}
- typedef llvm::SmallVectorImpl<SubmoduleID> OverriddenList;
+ enum class SubmoduleMacroState {
+ /// We've seen nothing about this macro.
+ None,
+ /// We've seen a public visibility directive.
+ Public,
+ /// We've either exported a macro for this module or found that the
+ /// module's definition of this macro is private.
+ Done
+ };
+ typedef llvm::DenseMap<SubmoduleID, SubmoduleMacroState> MacroState;
MacroDirective *
- getFirstPublicSubmoduleMacro(MacroDirective *MD, SubmoduleID &ModID) {
- ModID = 0;
- llvm::SmallVector<SubmoduleID, 1> Overridden;
- if (MacroDirective *NextMD = getPublicSubmoduleMacro(MD, ModID, Overridden))
- if (!shouldIgnoreMacro(NextMD, IsModule, PP))
- return NextMD;
+ getFirstPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) {
+ if (MacroDirective *NextMD = getPublicSubmoduleMacro(MD, State))
+ return NextMD;
return nullptr;
}
MacroDirective *
- getNextPublicSubmoduleMacro(MacroDirective *MD, SubmoduleID &ModID,
- OverriddenList &Overridden) {
+ getNextPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) {
if (MacroDirective *NextMD =
- getPublicSubmoduleMacro(MD->getPrevious(), ModID, Overridden))
- if (!shouldIgnoreMacro(NextMD, IsModule, PP))
- return NextMD;
+ getPublicSubmoduleMacro(MD->getPrevious(), State))
+ return NextMD;
return nullptr;
}
- /// \brief Traverses the macro directives history and returns the latest
- /// public macro definition or undefinition that is not in ModID.
+ /// \brief Traverses the macro directives history and returns the next
+ /// public macro definition or undefinition that has not been found so far.
+ ///
/// A macro that is defined in submodule A and undefined in submodule B
/// will still be considered as defined/exported from submodule A.
- /// ModID is updated to the module containing the returned directive.
- ///
- /// FIXME: This process breaks down if a module defines a macro, imports
- /// another submodule that changes the macro, then changes the
- /// macro again itself.
MacroDirective *getPublicSubmoduleMacro(MacroDirective *MD,
- SubmoduleID &ModID,
- OverriddenList &Overridden) {
+ MacroState &State) {
if (!MD)
return nullptr;
- Overridden.clear();
- SubmoduleID OrigModID = ModID;
Optional<bool> IsPublic;
for (; MD; MD = MD->getPrevious()) {
- SubmoduleID ThisModID = getSubmoduleID(MD);
- if (ThisModID == 0) {
- IsPublic = Optional<bool>();
- continue;
- }
- if (ThisModID != ModID) {
- ModID = ThisModID;
- IsPublic = Optional<bool>();
- }
+ // Once we hit an ignored macro, we're done: the rest of the chain
+ // will all be ignored macros.
+ if (shouldIgnoreMacro(MD, IsModule, PP))
+ break;
- // If this is a definition from a submodule import, that submodule's
- // definition is overridden by the definition or undefinition that we
- // started with.
- // FIXME: This should only apply to macros defined in OrigModID.
- // We can't do that currently, because a #include of a different submodule
- // of the same module just leaks through macros instead of providing new
- // DefMacroDirectives for them.
- if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
- // Figure out which submodule the macro was originally defined within.
- SubmoduleID SourceID = DefMD->getInfo()->getOwningModuleID();
- if (!SourceID) {
- SourceLocation DefLoc = DefMD->getInfo()->getDefinitionLoc();
- if (DefLoc == MD->getLocation())
- SourceID = ThisModID;
- else
- SourceID = Writer.inferSubmoduleIDFromLocation(DefLoc);
- }
- if (SourceID != OrigModID)
- Overridden.push_back(SourceID);
- }
+ // If this macro was imported, re-export it.
+ if (MD->isImported())
+ return MD;
- // We are looking for a definition in a different submodule than the one
- // that we started with. If a submodule has re-definitions of the same
- // macro, only the last definition will be used as the "exported" one.
- if (ModID == OrigModID)
+ SubmoduleID ModID = getSubmoduleID(MD);
+ auto &S = State[ModID];
+ assert(ModID && "found macro in no submodule");
+
+ if (S == SubmoduleMacroState::Done)
continue;
- // The latest visibility directive for a name in a submodule affects all
- // the directives that come before it.
- if (VisibilityMacroDirective *VisMD =
- dyn_cast<VisibilityMacroDirective>(MD)) {
- if (!IsPublic.hasValue())
- IsPublic = VisMD->isPublic();
- } else if (!IsPublic.hasValue() || IsPublic.getValue()) {
- // FIXME: If we find an imported macro, we should include its list of
- // overrides in our export.
+ 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.
+ if (S == SubmoduleMacroState::None)
+ S = VisMD->isPublic() ? SubmoduleMacroState::Public
+ : SubmoduleMacroState::Done;
+ } else {
+ S = SubmoduleMacroState::Done;
return MD;
}
}
@@ -3088,6 +3177,64 @@
return nullptr;
}
+ ArrayRef<SubmoduleID>
+ getOverriddenSubmodules(MacroDirective *MD,
+ SmallVectorImpl<SubmoduleID> &ScratchSpace) {
+ assert(!isa<VisibilityMacroDirective>(MD) &&
+ "only #define and #undef can override");
+ if (MD->isImported())
+ return MD->getOverriddenModules();
+
+ ScratchSpace.clear();
+ SubmoduleID ModID = getSubmoduleID(MD);
+ for (MD = MD->getPrevious(); MD; MD = MD->getPrevious()) {
+ if (shouldIgnoreMacro(MD, IsModule, PP))
+ break;
+
+ // If this is a definition from a submodule import, that submodule's
+ // definition is overridden by the definition or undefinition that we
+ // started with.
+ if (MD->isImported()) {
+ if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+ SubmoduleID DefModuleID = DefMD->getInfo()->getOwningModuleID();
+ assert(DefModuleID && "imported macro has no owning module");
+ ScratchSpace.push_back(DefModuleID);
+ } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
+ // If we override a #undef, we override anything that #undef overrides.
+ // We don't need to override it, since an active #undef doesn't affect
+ // the meaning of a macro.
+ auto Overrides = UndefMD->getOverriddenModules();
+ ScratchSpace.insert(ScratchSpace.end(),
+ Overrides.begin(), Overrides.end());
+ }
+ }
+
+ // Stop once we leave the original macro's submodule.
+ //
+ // Either this submodule #included another submodule of the same
+ // module or it just happened to be built after the other module.
+ // In the former case, we override the submodule's macro.
+ //
+ // FIXME: In the latter case, we shouldn't do so, but we can't tell
+ // these cases apart.
+ //
+ // FIXME: We can leave this submodule and re-enter it if it #includes a
+ // header within a different submodule of the same module. In such cases
+ // the overrides list will be incomplete.
+ SubmoduleID DirectiveModuleID = getSubmoduleID(MD);
+ if (DirectiveModuleID != ModID) {
+ if (DirectiveModuleID && !MD->isImported())
+ ScratchSpace.push_back(DirectiveModuleID);
+ break;
+ }
+ }
+
+ std::sort(ScratchSpace.begin(), ScratchSpace.end());
+ ScratchSpace.erase(std::unique(ScratchSpace.begin(), ScratchSpace.end()),
+ ScratchSpace.end());
+ return ScratchSpace;
+ }
+
SubmoduleID getSubmoduleID(MacroDirective *MD) {
return Writer.inferSubmoduleIDFromLocation(MD->getLocation());
}
@@ -3121,27 +3268,23 @@
if (hadMacroDefinition(II, Macro)) {
DataLen += 4; // MacroDirectives offset.
if (IsModule) {
- SubmoduleID ModID;
- llvm::SmallVector<SubmoduleID, 4> Overridden;
- for (MacroDirective *
- MD = getFirstPublicSubmoduleMacro(Macro, ModID);
- MD; MD = getNextPublicSubmoduleMacro(MD, ModID, Overridden)) {
- // Previous macro's overrides.
- if (!Overridden.empty())
- DataLen += 4 * (1 + Overridden.size());
+ MacroState State;
+ SmallVector<SubmoduleID, 16> Scratch;
+ for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, State);
+ MD; MD = getNextPublicSubmoduleMacro(MD, State)) {
DataLen += 4; // MacroInfo ID or ModuleID.
+ if (unsigned NumOverrides =
+ getOverriddenSubmodules(MD, Scratch).size())
+ DataLen += 4 * (1 + NumOverrides);
}
- // Previous macro's overrides.
- if (!Overridden.empty())
- DataLen += 4 * (1 + Overridden.size());
- DataLen += 4;
+ DataLen += 4; // 0 terminator.
}
}
for (IdentifierResolver::iterator D = IdResolver.begin(II),
DEnd = IdResolver.end();
D != DEnd; ++D)
- DataLen += sizeof(DeclID);
+ DataLen += 4;
}
using namespace llvm::support;
endian::Writer<little> LE(Out);
@@ -3168,8 +3311,10 @@
using namespace llvm::support;
endian::Writer<little> LE(Out);
LE.write<uint32_t>(Overridden.size() | 0x80000000U);
- for (unsigned I = 0, N = Overridden.size(); I != N; ++I)
+ for (unsigned I = 0, N = Overridden.size(); I != N; ++I) {
+ assert(Overridden[I] && "zero module ID for override");
LE.write<uint32_t>(Overridden[I]);
+ }
}
}
@@ -3201,24 +3346,28 @@
LE.write<uint32_t>(Writer.getMacroDirectivesOffset(II));
if (IsModule) {
// Write the IDs of macros coming from different submodules.
- SubmoduleID ModID;
- llvm::SmallVector<SubmoduleID, 4> Overridden;
- for (MacroDirective *
- MD = getFirstPublicSubmoduleMacro(Macro, ModID);
- MD; MD = getNextPublicSubmoduleMacro(MD, ModID, Overridden)) {
- MacroID InfoID = 0;
- emitMacroOverrides(Out, Overridden);
+ MacroState State;
+ SmallVector<SubmoduleID, 16> Scratch;
+ for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, State);
+ MD; MD = getNextPublicSubmoduleMacro(MD, State)) {
if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
- InfoID = Writer.getMacroID(DefMD->getInfo());
+ // FIXME: If this macro directive was created by #pragma pop_macros,
+ // or if it was created implicitly by resolving conflicting macros,
+ // it may be for a different submodule from the one in the MacroInfo
+ // object. If so, we should write out its owning ModuleID.
+ MacroID InfoID = Writer.getMacroID(DefMD->getInfo());
assert(InfoID);
LE.write<uint32_t>(InfoID << 1);
} else {
- assert(isa<UndefMacroDirective>(MD));
- LE.write<uint32_t>((ModID << 1) | 1);
+ auto *UndefMD = cast<UndefMacroDirective>(MD);
+ SubmoduleID Mod = UndefMD->isImported()
+ ? UndefMD->getOwningModuleID()
+ : getSubmoduleID(UndefMD);
+ LE.write<uint32_t>((Mod << 1) | 1);
}
+ emitMacroOverrides(Out, getOverriddenSubmodules(MD, Scratch));
}
- emitMacroOverrides(Out, Overridden);
- LE.write<uint32_t>(0);
+ LE.write<uint32_t>(0xdeadbeef);
}
}
@@ -3349,6 +3498,31 @@
// DeclContext's Name Lookup Table Serialization
//===----------------------------------------------------------------------===//
+/// Determine the declaration that should be put into the name lookup table to
+/// represent the given declaration in this module. This is usually D itself,
+/// but if D was imported and merged into a local declaration, we want the most
+/// recent local declaration instead. The chosen declaration will be the most
+/// recent declaration in any module that imports this one.
+static NamedDecl *getDeclForLocalLookup(NamedDecl *D) {
+ if (!D->isFromASTFile())
+ return D;
+
+ if (Decl *Redecl = D->getPreviousDecl()) {
+ // For Redeclarable decls, a prior declaration might be local.
+ for (; Redecl; Redecl = Redecl->getPreviousDecl())
+ if (!Redecl->isFromASTFile())
+ return cast<NamedDecl>(Redecl);
+ } else if (Decl *First = D->getCanonicalDecl()) {
+ // For Mergeable decls, the first decl might be local.
+ if (!First->isFromASTFile())
+ return cast<NamedDecl>(First);
+ }
+
+ // All declarations are imported. Our most recent declaration will also be
+ // the most recent one in anyone who imports us.
+ return D;
+}
+
namespace {
// Trait used for the on-disk hash table used in the method pool.
class ASTDeclContextNameLookupTrait {
@@ -3466,7 +3640,7 @@
LE.write<uint16_t>(Lookup.size());
for (DeclContext::lookup_iterator I = Lookup.begin(), E = Lookup.end();
I != E; ++I)
- LE.write<uint32_t>(Writer.GetDeclRef(*I));
+ LE.write<uint32_t>(Writer.GetDeclRef(getDeclForLocalLookup(*I)));
assert(Out.tell() - Start == DataLen && "Data length is wrong");
}
@@ -3506,13 +3680,13 @@
}
void ASTWriter::AddUpdatedDeclContext(const DeclContext *DC) {
- if (UpdatedDeclContexts.insert(DC) && WritingAST) {
+ if (UpdatedDeclContexts.insert(DC).second && WritingAST) {
// Ensure we emit all the visible declarations.
visitLocalLookupResults(DC, DC->NeedToReconcileExternalVisibleStorage,
[&](DeclarationName Name,
DeclContext::lookup_const_result Result) {
for (auto *Decl : Result)
- GetDeclRef(Decl);
+ GetDeclRef(getDeclForLocalLookup(Decl));
});
}
}
@@ -3628,8 +3802,6 @@
Record.push_back(BucketOffset);
Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
LookupTable.str());
-
- Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
++NumVisibleDeclContexts;
return Offset;
}
@@ -3711,6 +3883,8 @@
FirstFromAST = Prev;
}
+ // FIXME: Do we need to do this for the first declaration from each
+ // redeclaration chain that was merged into this one?
Chain->MergedDecls[FirstFromAST].push_back(getDeclID(First));
}
@@ -3932,29 +4106,26 @@
}
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
- : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr),
- WritingModule(nullptr), WritingAST(false), DoneWritingDeclsAndTypes(false),
- ASTHasCompilerErrors(false),
- FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
- FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
- FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
- FirstMacroID(NUM_PREDEF_MACRO_IDS), NextMacroID(FirstMacroID),
- FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),
- NextSubmoduleID(FirstSubmoduleID),
- FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
- CollectedStmts(&StmtsToEmit),
- NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
- NumVisibleDeclContexts(0),
- NextCXXBaseSpecifiersID(1),
- DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0),
- DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0),
- DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0),
- DeclRecordAbbrev(0), IntegerLiteralAbbrev(0),
- DeclTypedefAbbrev(0),
- DeclVarAbbrev(0), DeclFieldAbbrev(0),
- DeclEnumAbbrev(0), DeclObjCIvarAbbrev(0)
-{
-}
+ : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr),
+ WritingModule(nullptr), WritingAST(false),
+ DoneWritingDeclsAndTypes(false), ASTHasCompilerErrors(false),
+ FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
+ FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
+ FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
+ FirstMacroID(NUM_PREDEF_MACRO_IDS), NextMacroID(FirstMacroID),
+ FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),
+ NextSubmoduleID(FirstSubmoduleID),
+ FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
+ CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0),
+ NumLexicalDeclContexts(0), NumVisibleDeclContexts(0),
+ NextCXXBaseSpecifiersID(1), TypeExtQualAbbrev(0),
+ TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0),
+ DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0),
+ UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0),
+ DeclVarAbbrev(0), DeclFieldAbbrev(0), DeclEnumAbbrev(0),
+ DeclObjCIvarAbbrev(0), DeclCXXMethodAbbrev(0), DeclRefExprAbbrev(0),
+ CharacterLiteralAbbrev(0), IntegerLiteralAbbrev(0),
+ ExprImplicitCastAbbrev(0) {}
ASTWriter::~ASTWriter() {
llvm::DeleteContainerSeconds(FileDeclIDs);
@@ -4132,6 +4303,11 @@
}
}
+ // Build a record containing all of the UnusedLocalTypedefNameCandidates.
+ RecordData UnusedLocalTypedefNameCandidates;
+ for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
+ AddDeclRef(TD, UnusedLocalTypedefNameCandidates);
+
// Build a record containing all of dynamic classes declarations.
RecordData DynamicClasses;
AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses);
@@ -4298,22 +4474,36 @@
SmallString<2048> Buffer;
{
llvm::raw_svector_ostream Out(Buffer);
- for (ModuleManager::ModuleConstIterator M = Chain->ModuleMgr.begin(),
- MEnd = Chain->ModuleMgr.end();
- M != MEnd; ++M) {
+ for (ModuleFile *M : Chain->ModuleMgr) {
using namespace llvm::support;
endian::Writer<little> LE(Out);
- StringRef FileName = (*M)->FileName;
+ StringRef FileName = M->FileName;
LE.write<uint16_t>(FileName.size());
Out.write(FileName.data(), FileName.size());
- LE.write<uint32_t>((*M)->SLocEntryBaseOffset);
- LE.write<uint32_t>((*M)->BaseIdentifierID);
- LE.write<uint32_t>((*M)->BaseMacroID);
- LE.write<uint32_t>((*M)->BasePreprocessedEntityID);
- LE.write<uint32_t>((*M)->BaseSubmoduleID);
- LE.write<uint32_t>((*M)->BaseSelectorID);
- LE.write<uint32_t>((*M)->BaseDeclID);
- LE.write<uint32_t>((*M)->BaseTypeIndex);
+
+ // Note: if a base ID was uint max, it would not be possible to load
+ // another module after it or have more than one entity inside it.
+ uint32_t None = std::numeric_limits<uint32_t>::max();
+
+ auto writeBaseIDOrNone = [&](uint32_t BaseID, bool ShouldWrite) {
+ assert(BaseID < std::numeric_limits<uint32_t>::max() && "base id too high");
+ if (ShouldWrite)
+ LE.write<uint32_t>(BaseID);
+ else
+ LE.write<uint32_t>(None);
+ };
+
+ // These values should be unique within a chain, since they will be read
+ // as keys into ContinuousRangeMaps.
+ writeBaseIDOrNone(M->SLocEntryBaseOffset, M->LocalNumSLocEntries);
+ writeBaseIDOrNone(M->BaseIdentifierID, M->LocalNumIdentifiers);
+ writeBaseIDOrNone(M->BaseMacroID, M->LocalNumMacros);
+ writeBaseIDOrNone(M->BasePreprocessedEntityID,
+ M->NumPreprocessedEntities);
+ writeBaseIDOrNone(M->BaseSubmoduleID, M->LocalNumSubmodules);
+ writeBaseIDOrNone(M->BaseSelectorID, M->LocalNumSelectors);
+ writeBaseIDOrNone(M->BaseDeclID, M->LocalNumDecls);
+ writeBaseIDOrNone(M->BaseTypeIndex, M->LocalNumTypes);
}
}
Record.clear();
@@ -4326,8 +4516,9 @@
// Keep writing types, declarations, and declaration update records
// until we've emitted all of them.
- Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
- WriteDeclsBlockAbbrevs();
+ Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5);
+ WriteTypeAbbrevs();
+ WriteDeclAbbrevs();
for (DeclsToRewriteTy::iterator I = DeclsToRewrite.begin(),
E = DeclsToRewrite.end();
I != E; ++I)
@@ -4405,6 +4596,11 @@
if (!DynamicClasses.empty())
Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses);
+ // Write the record containing potentially unused local typedefs.
+ if (!UnusedLocalTypedefNameCandidates.empty())
+ Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
+ UnusedLocalTypedefNameCandidates);
+
// Write the record containing pending implicit instantiations.
if (!PendingInstantiations.empty())
Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
@@ -4451,10 +4647,13 @@
auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {
return A.ID < B.ID;
};
+ auto Eq = [](const ModuleInfo &A, const ModuleInfo &B) {
+ return A.ID == B.ID;
+ };
// Sort and deduplicate module IDs.
std::sort(Imports.begin(), Imports.end(), Cmp);
- Imports.erase(std::unique(Imports.begin(), Imports.end(), Cmp),
+ Imports.erase(std::unique(Imports.begin(), Imports.end(), Eq),
Imports.end());
RecordData ImportedModules;
@@ -4514,17 +4713,17 @@
Record.push_back(GetDeclRef(Update.getDecl()));
break;
- case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
- AddSourceLocation(Update.getLoc(), Record);
- break;
-
- case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION:
+ case UPD_CXX_ADDED_FUNCTION_DEFINITION:
// An updated body is emitted last, so that the reader doesn't need
// to skip over the lazy body to reach statements for other records.
Record.pop_back();
HasUpdatedBody = true;
break;
+ case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
+ AddSourceLocation(Update.getLoc(), Record);
+ break;
+
case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
auto *RD = cast<CXXRecordDecl>(D);
AddUpdatedDeclContext(RD->getPrimaryContext());
@@ -4564,8 +4763,8 @@
// Instantiation may change attributes; write them all out afresh.
Record.push_back(D->hasAttrs());
if (Record.back())
- WriteAttributes(ArrayRef<const Attr*>(D->getAttrs().begin(),
- D->getAttrs().size()), Record);
+ WriteAttributes(llvm::makeArrayRef(D->getAttrs().begin(),
+ D->getAttrs().size()), Record);
// FIXME: Ensure we don't get here for explicit instantiations.
break;
@@ -4589,15 +4788,21 @@
case UPD_STATIC_LOCAL_NUMBER:
Record.push_back(Update.getNumber());
break;
+ case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:
+ AddSourceRange(D->getAttr<OMPThreadPrivateDeclAttr>()->getRange(),
+ Record);
+ break;
}
}
if (HasUpdatedBody) {
const FunctionDecl *Def = cast<FunctionDecl>(D);
- Record.push_back(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION);
+ Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);
Record.push_back(Def->isInlined());
AddSourceLocation(Def->getInnerLocStart(), Record);
AddFunctionDefinition(Def, Record);
+ if (auto *DD = dyn_cast<CXXDestructorDecl>(Def))
+ Record.push_back(GetDeclRef(DD->getOperatorDelete()));
}
OffsetsRecord.push_back(GetDeclRef(D));
@@ -4963,6 +5168,30 @@
}
}
+unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) {
+ assert(needsAnonymousDeclarationNumber(D) &&
+ "expected an anonymous declaration");
+
+ // Number the anonymous declarations within this context, if we've not
+ // already done so.
+ auto It = AnonymousDeclarationNumbers.find(D);
+ if (It == AnonymousDeclarationNumbers.end()) {
+ unsigned Index = 0;
+ for (Decl *LexicalD : D->getLexicalDeclContext()->decls()) {
+ auto *ND = dyn_cast<NamedDecl>(LexicalD);
+ if (!ND || !needsAnonymousDeclarationNumber(ND))
+ continue;
+ AnonymousDeclarationNumbers[ND] = Index++;
+ }
+
+ It = AnonymousDeclarationNumbers.find(D);
+ assert(It != AnonymousDeclarationNumbers.end() &&
+ "declaration not found within its lexical context");
+ }
+
+ return It->second;
+}
+
void ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
DeclarationName Name, RecordDataImpl &Record) {
switch (Name.getNameKind()) {
@@ -5050,6 +5279,10 @@
case NestedNameSpecifier::Global:
// Don't need to write an associated value.
break;
+
+ case NestedNameSpecifier::Super:
+ AddDeclRef(NNS->getAsRecordDecl(), Record);
+ break;
}
}
}
@@ -5099,6 +5332,11 @@
case NestedNameSpecifier::Global:
AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
break;
+
+ case NestedNameSpecifier::Super:
+ AddDeclRef(NNS.getNestedNameSpecifier()->getAsRecordDecl(), Record);
+ AddSourceRange(NNS.getLocalSourceRange(), Record);
+ break;
}
}
}
@@ -5168,7 +5406,7 @@
break;
case TemplateArgument::Declaration:
AddDeclRef(Arg.getAsDecl(), Record);
- Record.push_back(Arg.isDeclForReferenceParam());
+ AddTypeRef(Arg.getParamTypeForDecl(), Record);
break;
case TemplateArgument::NullPtr:
AddTypeRef(Arg.getNullPtrType(), Record);
@@ -5192,9 +5430,8 @@
break;
case TemplateArgument::Pack:
Record.push_back(Arg.pack_size());
- for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end();
- I != E; ++I)
- AddTemplateArgument(*I, Record);
+ for (const auto &P : Arg.pack_elements())
+ AddTemplateArgument(P, Record);
break;
}
}
@@ -5401,6 +5638,7 @@
Record.push_back(Capture.getCaptureKind());
switch (Capture.getCaptureKind()) {
case LCK_This:
+ case LCK_VLAType:
break;
case LCK_ByCopy:
case LCK_ByRef:
@@ -5504,8 +5742,6 @@
}
void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
- assert(!WritingAST && "Already writing the AST!");
-
// TU and namespaces are handled elsewhere.
if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC))
return;
@@ -5514,12 +5750,12 @@
return; // Not a source decl added to a DeclContext from PCH.
assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
+ assert(!WritingAST && "Already writing the AST!");
AddUpdatedDeclContext(DC);
UpdatingVisibleDecls.push_back(D);
}
void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
- assert(!WritingAST && "Already writing the AST!");
assert(D->isImplicit());
if (!(!D->isFromASTFile() && RD->isFromASTFile()))
return; // Not a source member added to a class from PCH.
@@ -5528,17 +5764,18 @@
// A decl coming from PCH was modified.
assert(RD->isCompleteDefinition());
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[RD].push_back(DeclUpdate(UPD_CXX_ADDED_IMPLICIT_MEMBER, D));
}
void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
const ClassTemplateSpecializationDecl *D) {
// The specializations set is kept in the canonical template.
- assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
if (!(!D->isFromASTFile() && TD->isFromASTFile()))
return; // Not a source specialization added to a template from PCH.
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
D));
}
@@ -5546,11 +5783,11 @@
void ASTWriter::AddedCXXTemplateSpecialization(
const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
// The specializations set is kept in the canonical template.
- assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
if (!(!D->isFromASTFile() && TD->isFromASTFile()))
return; // Not a source specialization added to a template from PCH.
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
D));
}
@@ -5558,11 +5795,11 @@
void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {
// The specializations set is kept in the canonical template.
- assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
if (!(!D->isFromASTFile() && TD->isFromASTFile()))
return; // Not a source specialization added to a template from PCH.
+ assert(!WritingAST && "Already writing the AST!");
DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
D));
}
@@ -5590,9 +5827,8 @@
if (!D->isFromASTFile())
return; // Declaration not imported from PCH.
- // Implicit decl from a PCH was defined.
- // FIXME: Should implicit definition be a separate FunctionDecl?
- RewriteDecl(D);
+ // Implicit function decl from a PCH was defined.
+ DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
}
void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
@@ -5600,10 +5836,8 @@
if (!D->isFromASTFile())
return;
- // Since the actual instantiation is delayed, this really means that we need
- // to update the instantiation location.
DeclUpdates[D].push_back(
- DeclUpdate(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION));
+ DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
}
void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
@@ -5651,3 +5885,11 @@
DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_USED));
}
+
+void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
+ assert(!WritingAST && "Already writing the AST!");
+ if (!D->isFromASTFile())
+ return;
+
+ DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE));
+}