diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 79 | ||||
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 19 |
8 files changed, 146 insertions, 3 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 5c7c0694a04..2f167eedd15 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -24,6 +24,7 @@ #include "clang/AST/ASTMutationListener.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/Module.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetInfo.h" #include "llvm/Support/ErrorHandling.h" @@ -2609,3 +2610,81 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation RParenLoc) { return new (C) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc); } + +//===----------------------------------------------------------------------===// +// ImportDecl Implementation +//===----------------------------------------------------------------------===// + +/// \brief Retrieve the number of module identifiers needed to name the given +/// module. +static unsigned getNumModuleIdentifiers(Module *Mod) { + unsigned Result = 1; + while (Mod->Parent) { + Mod = Mod->Parent; + ++Result; + } + return Result; +} + +ImportDecl::ImportDecl(DeclContext *DC, SourceLocation ImportLoc, + Module *Imported, + ArrayRef<SourceLocation> IdentifierLocs) + : Decl(Import, DC, ImportLoc), ImportedAndComplete(Imported, true) +{ + assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size()); + SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(this + 1); + memcpy(StoredLocs, IdentifierLocs.data(), + IdentifierLocs.size() * sizeof(SourceLocation)); +} + +ImportDecl::ImportDecl(DeclContext *DC, SourceLocation ImportLoc, + Module *Imported, SourceLocation EndLoc) + : Decl(Import, DC, ImportLoc), ImportedAndComplete(Imported, false) +{ + *reinterpret_cast<SourceLocation *>(this + 1) = EndLoc; +} + +ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation ImportLoc, Module *Imported, + ArrayRef<SourceLocation> IdentifierLocs) { + void *Mem = C.Allocate(sizeof(ImportDecl) + + IdentifierLocs.size() * sizeof(SourceLocation)); + return new (Mem) ImportDecl(DC, ImportLoc, Imported, IdentifierLocs); +} + +ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, + SourceLocation ImportLoc, + Module *Imported, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(ImportDecl) + sizeof(SourceLocation)); + ImportDecl *Import + = new (Mem) ImportDecl(DC, ImportLoc, Imported, + ArrayRef<SourceLocation>(&EndLoc, 1)); + Import->setImplicit(); + return Import; +} + +ImportDecl *ImportDecl::CreateEmpty(ASTContext &C, unsigned NumLocations) { + void *Mem = C.Allocate(sizeof(ImportDecl) + + NumLocations * sizeof(SourceLocation)); + return new (Mem) ImportDecl(EmptyShell()); +} + +ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const { + if (!ImportedAndComplete.getInt()) + return ArrayRef<SourceLocation>(); + + const SourceLocation *StoredLocs + = reinterpret_cast<const SourceLocation *>(this + 1); + return ArrayRef<SourceLocation>(StoredLocs, + getNumModuleIdentifiers(getImportedModule())); +} + +SourceRange ImportDecl::getSourceRange() const { + if (!ImportedAndComplete.getInt()) + return SourceRange(getLocation(), + *reinterpret_cast<const SourceLocation *>(this + 1)); + + return SourceRange(getLocation(), getIdentifierLocs().back()); +} + diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index d892c56f712..f4507e36039 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -501,6 +501,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCImplementation: case ObjCCategory: case ObjCCategoryImpl: + case Import: // Never looked up by name. return 0; } diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index e5b4b0431b1..91b011fbda6 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -19,6 +19,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/PrettyPrinter.h" +#include "clang/Basic/Module.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -58,6 +59,7 @@ namespace { void VisitLabelDecl(LabelDecl *D); void VisitParmVarDecl(ParmVarDecl *D); void VisitFileScopeAsmDecl(FileScopeAsmDecl *D); + void VisitImportDecl(ImportDecl *D); void VisitStaticAssertDecl(StaticAssertDecl *D); void VisitNamespaceDecl(NamespaceDecl *D); void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); @@ -646,6 +648,11 @@ void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { Out << ")"; } +void DeclPrinter::VisitImportDecl(ImportDecl *D) { + Out << "__import_module__ " << D->getImportedModule()->getFullModuleName() + << ";\n"; +} + void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) { Out << "static_assert("; D->getAssertExpr()->printPretty(Out, Context, 0, Policy, Indentation); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 59efea0dae1..c7bc87ba1ef 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -84,6 +84,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::NamespaceAlias: case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label: // __label__ x; + case Decl::Import: // None of these decls require codegen support. return; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0905c4b283d..0e8468f31d5 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2335,6 +2335,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::TypeAliasTemplate: case Decl::NamespaceAlias: case Decl::Block: + case Decl::Import: break; case Decl::CXXConstructor: // Skip function templates diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1e57a00f1f1..01c7906e800 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9897,9 +9897,24 @@ DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, ModuleIdPath Path) if (!Mod) return true; - // FIXME: Actually create a declaration to describe the module import. - (void)Mod; - return DeclResult((Decl *)0); + llvm::SmallVector<SourceLocation, 2> IdentifierLocs; + Module *ModCheck = Mod; + for (unsigned I = 0, N = Path.size(); I != N; ++I) { + // If we've run out of module parents, just drop the remaining identifiers. + // We need the length to be consistent. + if (!ModCheck) + break; + ModCheck = ModCheck->Parent; + + IdentifierLocs.push_back(Path[I].second); + } + + ImportDecl *Import = ImportDecl::Create(Context, + Context.getTranslationUnitDecl(), + ImportLoc, Mod, + IdentifierLocs); + Context.getTranslationUnitDecl()->addDecl(Import); + return Import; } void diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 85cd72840af..e9833c394c9 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -94,6 +94,10 @@ namespace clang { return Reader.getGlobalSubmoduleID(F, R[I++]); } + Module *readModule(const RecordData &R, unsigned &I) { + return Reader.getSubmodule(readSubmoduleID(R, I)); + } + void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data, const RecordData &R, unsigned &I); @@ -168,6 +172,7 @@ namespace clang { void VisitUsingShadowDecl(UsingShadowDecl *D); void VisitLinkageSpecDecl(LinkageSpecDecl *D); void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD); + void VisitImportDecl(ImportDecl *D); void VisitAccessSpecDecl(AccessSpecDecl *D); void VisitFriendDecl(FriendDecl *D); void VisitFriendTemplateDecl(FriendTemplateDecl *D); @@ -1054,6 +1059,16 @@ void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { D->IsExplicitSpecified = Record[Idx++]; } +void ASTDeclReader::VisitImportDecl(ImportDecl *D) { + VisitDecl(D); + D->ImportedAndComplete.setPointer(readModule(Record, Idx)); + D->ImportedAndComplete.setInt(Record[Idx++]); + SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(D + 1); + for (unsigned I = 0, N = Record.back(); I != N; ++I) + StoredLocs[I] = ReadSourceLocation(Record, Idx); + ++Idx; +} + void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) { VisitDecl(D); D->setColonLoc(ReadSourceLocation(Record, Idx)); @@ -1760,6 +1775,11 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_CXX_BASE_SPECIFIERS: Error("attempt to read a C++ base-specifier record as a declaration"); return 0; + case DECL_IMPORT: + // Note: last entry of the ImportDecl record is the number of stored source + // locations. + D = ImportDecl::CreateEmpty(Context, Record.back()); + break; } assert(D && "Unknown declaration reading AST file"); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 4075db8d26f..afb7ca9f9f0 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -94,6 +94,7 @@ namespace clang { void VisitUsingShadowDecl(UsingShadowDecl *D); void VisitLinkageSpecDecl(LinkageSpecDecl *D); void VisitFileScopeAsmDecl(FileScopeAsmDecl *D); + void VisitImportDecl(ImportDecl *D); void VisitAccessSpecDecl(AccessSpecDecl *D); void VisitFriendDecl(FriendDecl *D); void VisitFriendTemplateDecl(FriendTemplateDecl *D); @@ -972,6 +973,24 @@ void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) { Code = serialization::DECL_CXX_CONVERSION; } +void ASTDeclWriter::VisitImportDecl(ImportDecl *D) { + VisitDecl(D); + Writer.SubmoduleIDs[D->getImportedModule()]; + ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs(); + Record.push_back(!IdentifierLocs.empty()); + if (IdentifierLocs.empty()) { + Writer.AddSourceLocation(D->getLocEnd(), Record); + Record.push_back(1); + } else { + for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I) + Writer.AddSourceLocation(IdentifierLocs[I], Record); + Record.push_back(IdentifierLocs.size()); + } + // Note: the number of source locations must always be the last element in + // the record. + Code = serialization::DECL_IMPORT; +} + void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) { VisitDecl(D); Writer.AddSourceLocation(D->getColonLoc(), Record); |