Update cling's patches to be relative to its LastKnownGood.
Simplify some of the patches by reverting some of the changed llvm / clang files to the original ones. git-svn-id: http://root.cern.ch/svn/root/trunk@49363 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
parent
896a4b3f76
commit
14c6595959
@ -45,6 +45,17 @@
|
||||
|
||||
using namespace clang;
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct less<llvm::sys::DynamicLibrary> {
|
||||
bool operator()(const llvm::sys::DynamicLibrary& lhs,
|
||||
const llvm::sys::DynamicLibrary& rhs ) const {
|
||||
return *reinterpret_cast<void* const*>(&lhs)
|
||||
< *reinterpret_cast<void* const*>(&rhs);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static cling::Interpreter::ExecutionResult
|
||||
@ -285,7 +296,6 @@ namespace cling {
|
||||
|
||||
CompilerInstance* CI = getCI();
|
||||
HeaderSearchOptions& headerOpts = CI->getHeaderSearchOpts();
|
||||
const bool IsUserSupplied = true;
|
||||
const bool IsFramework = false;
|
||||
const bool IsSysRootRelative = true;
|
||||
headerOpts.AddPath(incpath, frontend::Angled, IsFramework,
|
||||
|
11
patches/clang-ASTReaderDecl-friendDeclBug.diff
Normal file
11
patches/clang-ASTReaderDecl-friendDeclBug.diff
Normal file
@ -0,0 +1,11 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/Serialization/ASTReaderDecl.cpp 2013-04-11 09:34:53.573169052 +0200
|
||||
+++ ./tools/clang/lib/Serialization/ASTReaderDecl.cpp 2013-04-24 19:40:15.673487393 +0200
|
||||
@@ -1264,7 +1264,7 @@
|
||||
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->NextFriend = ReadDeclID(Record, Idx);
|
||||
D->UnsupportedFriend = (Record[Idx++] != 0);
|
||||
D->FriendLoc = ReadSourceLocation(Record, Idx);
|
||||
}
|
@ -1,18 +1,6 @@
|
||||
diff -u tools/clang/lib/CodeGen/CGExprScalar.cpp tools/clang/lib/CodeGen/CGExprScalar.cpp
|
||||
--- tools/clang/lib/CodeGen/CGExprScalar.cpp 2013-04-10 12:29:53.811425530 +0200
|
||||
+++ tools/clang/lib/CodeGen/CGExprScalar.cpp 2013-04-10 11:37:18.923238322 +0200
|
||||
@@ -1446,6 +1446,7 @@
|
||||
BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
|
||||
BinOp.Ty = E->getType();
|
||||
BinOp.Opcode = BO_Sub;
|
||||
+ BinOp.FPContractable = false;
|
||||
BinOp.E = E;
|
||||
return EmitSub(BinOp);
|
||||
}
|
||||
diff -u tools/clang/lib/CodeGen/CodeGenModule.cpp tools/clang/lib/CodeGen/CodeGenModule.cpp
|
||||
--- tools/clang/lib/CodeGen/CodeGenModule.cpp 2013-04-10 12:29:53.811425530 +0200
|
||||
+++ tools/clang/lib/CodeGen/CodeGenModule.cpp 2013-04-10 12:37:15.510983363 +0200
|
||||
@@ -443,7 +443,7 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/CodeGen/CodeGenModule.cpp 2013-04-11 09:34:53.217172752 +0200
|
||||
+++ ./tools/clang/lib/CodeGen/CodeGenModule.cpp 2013-04-24 19:40:15.333490079 +0200
|
||||
@@ -477,7 +477,7 @@
|
||||
GlobalDtors.push_back(std::make_pair(Dtor, Priority));
|
||||
}
|
||||
|
||||
@ -21,7 +9,7 @@ diff -u tools/clang/lib/CodeGen/CodeGenModule.cpp tools/clang/lib/CodeGen/CodeGe
|
||||
// Ctor function type is void()*.
|
||||
llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false);
|
||||
llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy);
|
||||
@@ -469,6 +469,7 @@
|
||||
@@ -503,6 +503,7 @@
|
||||
llvm::ConstantArray::get(AT, Ctors),
|
||||
GlobalName);
|
||||
}
|
||||
@ -29,10 +17,9 @@ diff -u tools/clang/lib/CodeGen/CodeGenModule.cpp tools/clang/lib/CodeGen/CodeGe
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes
|
||||
diff -u tools/clang/lib/CodeGen/CodeGenModule.h tools/clang/lib/CodeGen/CodeGenModule.h
|
||||
--- tools/clang/lib/CodeGen/CodeGenModule.h 2013-04-10 12:29:53.819425451 +0200
|
||||
+++ tools/clang/lib/CodeGen/CodeGenModule.h 2013-04-10 12:33:10.845445231 +0200
|
||||
@@ -960,8 +960,8 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/CodeGen/CodeGenModule.h 2013-04-11 09:34:53.233172585 +0200
|
||||
+++ ./tools/clang/lib/CodeGen/CodeGenModule.h 2013-04-24 19:40:15.325490142 +0200
|
||||
@@ -1035,8 +1035,8 @@
|
||||
|
||||
/// EmitCtorList - Generates a global array of functions and priorities using
|
||||
/// the given list and name. This array will have appending linkage and is
|
||||
@ -43,51 +30,3 @@ diff -u tools/clang/lib/CodeGen/CodeGenModule.h tools/clang/lib/CodeGen/CodeGenM
|
||||
|
||||
/// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the
|
||||
/// given type.
|
||||
diff -u tools/clang/lib/CodeGen/ModuleBuilder.cpp tools/clang/lib/CodeGen/ModuleBuilder.cpp
|
||||
--- tools/clang/lib/CodeGen/ModuleBuilder.cpp 2013-04-10 12:29:53.815425490 +0200
|
||||
+++ tools/clang/lib/CodeGen/ModuleBuilder.cpp 2013-04-10 11:45:35.970177539 +0200
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "clang/CodeGen/ModuleBuilder.h"
|
||||
#include "CodeGenModule.h"
|
||||
+#include "CodeGenTypes.h"
|
||||
#include "clang/Frontend/CodeGenOptions.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
@@ -49,6 +50,10 @@
|
||||
return M.take();
|
||||
}
|
||||
|
||||
+ virtual llvm::Type* ConvertType(QualType T) {
|
||||
+ return Builder->getTypes().ConvertType(T);
|
||||
+ }
|
||||
+
|
||||
virtual void Initialize(ASTContext &Context) {
|
||||
Ctx = &Context;
|
||||
|
||||
Index: tools/clang/include/clang/CodeGen/ModuleBuilder.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/CodeGen/ModuleBuilder.h (revision 165095)
|
||||
+++ tools/clang/include/clang/CodeGen/ModuleBuilder.h (working copy)
|
||||
@@ -20,18 +20,21 @@
|
||||
namespace llvm {
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
+ class Type;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
class DiagnosticsEngine;
|
||||
class LangOptions;
|
||||
class CodeGenOptions;
|
||||
+ class QualType;
|
||||
|
||||
class CodeGenerator : public ASTConsumer {
|
||||
virtual void anchor();
|
||||
public:
|
||||
virtual llvm::Module* GetModule() = 0;
|
||||
virtual llvm::Module* ReleaseModule() = 0;
|
||||
+ virtual llvm::Type* ConvertType(QualType T) = 0;
|
||||
};
|
||||
|
||||
/// CreateLLVMCodeGen - Create a CodeGenerator instance.
|
||||
|
73
patches/clang-Decl-clearLinkageCache.diff
Normal file
73
patches/clang-Decl-clearLinkageCache.diff
Normal file
@ -0,0 +1,73 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/include/clang/AST/Decl.h 2013-04-11 09:35:12.328974114 +0200
|
||||
+++ ./tools/clang/include/clang/AST/Decl.h 2013-04-24 19:40:12.605511633 +0200
|
||||
@@ -214,6 +214,9 @@
|
||||
/// \brief Determine what kind of linkage this entity has.
|
||||
Linkage getLinkage() const;
|
||||
|
||||
+ /// \brief Force a reevaluation of the kind of linkage this entity has.
|
||||
+ void ClearLinkageCache();
|
||||
+
|
||||
/// \brief True if this decl has external linkage.
|
||||
bool hasExternalLinkage() const {
|
||||
return getLinkage() == ExternalLinkage;
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/AST/Decl.cpp 2013-04-11 09:34:54.269161818 +0200
|
||||
+++ ./tools/clang/lib/AST/Decl.cpp 2013-04-24 19:40:14.517496526 +0200
|
||||
@@ -856,6 +856,15 @@
|
||||
return LV;
|
||||
}
|
||||
|
||||
+static void clearLinkageForClass(const CXXRecordDecl *record) {
|
||||
+ for (CXXRecordDecl::decl_iterator
|
||||
+ i = record->decls_begin(), e = record->decls_end(); i != e; ++i) {
|
||||
+ Decl *child = *i;
|
||||
+ if (isa<NamedDecl>(child))
|
||||
+ cast<NamedDecl>(child)->ClearLinkageCache();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void NamedDecl::anchor() { }
|
||||
|
||||
bool NamedDecl::isLinkageValid() const {
|
||||
@@ -870,6 +879,42 @@
|
||||
return getLVForDecl(this, LVForExplicitValue).getLinkage() == ExternalLinkage;
|
||||
}
|
||||
|
||||
+void NamedDecl::ClearLinkageCache() {
|
||||
+ // Note that we can't skip clearing the linkage of children just
|
||||
+ // because the parent doesn't have cached linkage: we don't cache
|
||||
+ // when computing linkage for parent contexts.
|
||||
+
|
||||
+ HasCachedLinkage = 0;
|
||||
+
|
||||
+ // If we're changing the linkage of a class, we need to reset the
|
||||
+ // linkage of child declarations, too.
|
||||
+ if (const CXXRecordDecl *record = dyn_cast<CXXRecordDecl>(this))
|
||||
+ clearLinkageForClass(record);
|
||||
+
|
||||
+ if (ClassTemplateDecl *temp =
|
||||
+ dyn_cast<ClassTemplateDecl>(const_cast<NamedDecl*>(this))) {
|
||||
+ // Clear linkage for the template pattern.
|
||||
+ CXXRecordDecl *record = temp->getTemplatedDecl();
|
||||
+ record->HasCachedLinkage = 0;
|
||||
+ clearLinkageForClass(record);
|
||||
+
|
||||
+ // We need to clear linkage for specializations, too.
|
||||
+ for (ClassTemplateDecl::spec_iterator
|
||||
+ i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
|
||||
+ i->ClearLinkageCache();
|
||||
+ }
|
||||
+
|
||||
+ // Clear cached linkage for function template decls, too.
|
||||
+ if (FunctionTemplateDecl *temp =
|
||||
+ dyn_cast<FunctionTemplateDecl>(const_cast<NamedDecl*>(this))) {
|
||||
+ temp->getTemplatedDecl()->ClearLinkageCache();
|
||||
+ for (FunctionTemplateDecl::spec_iterator
|
||||
+ i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
|
||||
+ i->ClearLinkageCache();
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
Linkage NamedDecl::getLinkage() const {
|
||||
if (HasCachedLinkage)
|
||||
return Linkage(CachedLinkage);
|
21
patches/clang-DyLib-SpeedUpGlobalSyms.diff
Normal file
21
patches/clang-DyLib-SpeedUpGlobalSyms.diff
Normal file
@ -0,0 +1,21 @@
|
||||
--- /home/axel/build/cling/src/./lib/Support/DynamicLibrary.cpp 2013-04-24 21:58:01.339752276 +0200
|
||||
+++ ./lib/Support/DynamicLibrary.cpp 2013-04-24 19:40:23.073428922 +0200
|
||||
@@ -137,6 +137,10 @@
|
||||
}
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
+ void* ptr = dlsym(RTLD_DEFAULT, symbolName);
|
||||
+ if (ptr)
|
||||
+ return ptr;
|
||||
+#ifdef R__TOO_SLOW
|
||||
// Now search the libraries.
|
||||
if (OpenedHandles) {
|
||||
for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
|
||||
@@ -148,6 +152,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+#endif // R__TOO_SLOW
|
||||
#endif
|
||||
|
||||
if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
|
12
patches/clang-HeaderSearch-cygwin.diff
Normal file
12
patches/clang-HeaderSearch-cygwin.diff
Normal file
@ -0,0 +1,12 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/Frontend/InitHeaderSearch.cpp 2013-04-11 09:34:53.657168179 +0200
|
||||
+++ ./tools/clang/lib/Frontend/InitHeaderSearch.cpp 2013-04-24 19:40:13.977500793 +0200
|
||||
@@ -307,7 +307,8 @@
|
||||
case llvm::Triple::RTEMS:
|
||||
break;
|
||||
case llvm::Triple::Cygwin:
|
||||
- AddPath("/usr/include/w32api", System, false);
|
||||
+ // The headers in w32api/ are not cygwin-compatible (but native)
|
||||
+ //AddPath("/usr/include/w32api", System, false);
|
||||
break;
|
||||
case llvm::Triple::MinGW32: {
|
||||
// mingw-w64 crt include paths
|
46
patches/clang-ModuleBuilder-ConvertType.diff
Normal file
46
patches/clang-ModuleBuilder-ConvertType.diff
Normal file
@ -0,0 +1,46 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/include/clang/CodeGen/ModuleBuilder.h 2013-04-11 09:35:12.484972492 +0200
|
||||
+++ ./tools/clang/include/clang/CodeGen/ModuleBuilder.h 2013-04-24 19:40:12.817509958 +0200
|
||||
@@ -20,12 +20,14 @@
|
||||
namespace llvm {
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
+ class Type;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
class DiagnosticsEngine;
|
||||
class LangOptions;
|
||||
class CodeGenOptions;
|
||||
+ class QualType;
|
||||
class TargetOptions;
|
||||
|
||||
class CodeGenerator : public ASTConsumer {
|
||||
@@ -33,6 +35,7 @@
|
||||
public:
|
||||
virtual llvm::Module* GetModule() = 0;
|
||||
virtual llvm::Module* ReleaseModule() = 0;
|
||||
+ virtual llvm::Type* ConvertType(QualType T) = 0;
|
||||
};
|
||||
|
||||
/// CreateLLVMCodeGen - Create a CodeGenerator instance.
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/CodeGen/ModuleBuilder.cpp 2013-04-11 09:34:53.225172669 +0200
|
||||
+++ ./tools/clang/lib/CodeGen/ModuleBuilder.cpp 2013-04-24 19:40:15.341490016 +0200
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "clang/CodeGen/ModuleBuilder.h"
|
||||
#include "CodeGenModule.h"
|
||||
+#include "CodeGenTypes.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
@@ -52,6 +53,10 @@
|
||||
return M.take();
|
||||
}
|
||||
|
||||
+ virtual llvm::Type* ConvertType(QualType T) {
|
||||
+ return Builder->getTypes().ConvertType(T);
|
||||
+ }
|
||||
+
|
||||
virtual void Initialize(ASTContext &Context) {
|
||||
Ctx = &Context;
|
||||
|
307
patches/clang-Parser-Multiple-AndActOnEndOfTU.diff
Normal file
307
patches/clang-Parser-Multiple-AndActOnEndOfTU.diff
Normal file
@ -0,0 +1,307 @@
|
||||
--- /home/axel/build/cling/src/./tools/clang/lib/Parse/Parser.cpp 2013-04-24 22:04:39.536536803 +0200
|
||||
+++ ./tools/clang/lib/Parse/Parser.cpp 2013-04-25 14:34:00.138269622 +0200
|
||||
@@ -48,15 +48,17 @@
|
||||
return Ident__except;
|
||||
}
|
||||
|
||||
-Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
|
||||
+Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies,
|
||||
+ bool isTemporary /*=false*/)
|
||||
: PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
|
||||
GreaterThanIsOperator(true), ColonIsSacred(false),
|
||||
InMessageExpression(false), TemplateParameterDepth(0),
|
||||
- ParsingInObjCContainer(false) {
|
||||
+ ParsingInObjCContainer(false), IsTemporary(isTemporary) {
|
||||
SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
|
||||
Tok.startToken();
|
||||
Tok.setKind(tok::eof);
|
||||
- Actions.CurScope = 0;
|
||||
+ if (!IsTemporary)
|
||||
+ Actions.CurScope = 0;
|
||||
NumCachedScopes = 0;
|
||||
ParenCount = BracketCount = BraceCount = 0;
|
||||
CurParsedObjCImpl = 0;
|
||||
@@ -64,37 +66,48 @@
|
||||
// Add #pragma handlers. These are removed and destroyed in the
|
||||
// destructor.
|
||||
AlignHandler.reset(new PragmaAlignHandler());
|
||||
- PP.AddPragmaHandler(AlignHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(AlignHandler.get());
|
||||
|
||||
GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
|
||||
- PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
|
||||
OptionsHandler.reset(new PragmaOptionsHandler());
|
||||
- PP.AddPragmaHandler(OptionsHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(OptionsHandler.get());
|
||||
|
||||
PackHandler.reset(new PragmaPackHandler());
|
||||
- PP.AddPragmaHandler(PackHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(PackHandler.get());
|
||||
|
||||
MSStructHandler.reset(new PragmaMSStructHandler());
|
||||
- PP.AddPragmaHandler(MSStructHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(MSStructHandler.get());
|
||||
|
||||
UnusedHandler.reset(new PragmaUnusedHandler());
|
||||
- PP.AddPragmaHandler(UnusedHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(UnusedHandler.get());
|
||||
|
||||
WeakHandler.reset(new PragmaWeakHandler());
|
||||
- PP.AddPragmaHandler(WeakHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(WeakHandler.get());
|
||||
|
||||
RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
|
||||
- PP.AddPragmaHandler(RedefineExtnameHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(RedefineExtnameHandler.get());
|
||||
|
||||
FPContractHandler.reset(new PragmaFPContractHandler());
|
||||
- PP.AddPragmaHandler("STDC", FPContractHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("STDC", FPContractHandler.get());
|
||||
|
||||
if (getLangOpts().OpenCL) {
|
||||
OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
|
||||
- PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
-
|
||||
- PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
+
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
|
||||
}
|
||||
if (getLangOpts().OpenMP)
|
||||
OpenMPHandler.reset(new PragmaOpenMPHandler());
|
||||
@@ -103,9 +116,11 @@
|
||||
PP.AddPragmaHandler(OpenMPHandler.get());
|
||||
|
||||
CommentSemaHandler.reset(new ActionCommentHandler(actions));
|
||||
- PP.addCommentHandler(CommentSemaHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.addCommentHandler(CommentSemaHandler.get());
|
||||
|
||||
- PP.setCodeCompletionHandler(*this);
|
||||
+ if (!IsTemporary)
|
||||
+ PP.setCodeCompletionHandler(*this);
|
||||
}
|
||||
|
||||
DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
|
||||
@@ -398,9 +413,11 @@
|
||||
|
||||
Parser::~Parser() {
|
||||
// If we still have scopes active, delete the scope tree.
|
||||
- delete getCurScope();
|
||||
- Actions.CurScope = 0;
|
||||
-
|
||||
+ if (!IsTemporary) {
|
||||
+ delete getCurScope();
|
||||
+ Actions.CurScope = 0;
|
||||
+ }
|
||||
+
|
||||
// Free the scope cache.
|
||||
for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
|
||||
delete ScopeCache[i];
|
||||
@@ -410,38 +427,40 @@
|
||||
it != LateParsedTemplateMap.end(); ++it)
|
||||
delete it->second;
|
||||
|
||||
- // Remove the pragma handlers we installed.
|
||||
- PP.RemovePragmaHandler(AlignHandler.get());
|
||||
- AlignHandler.reset();
|
||||
- PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
- GCCVisibilityHandler.reset();
|
||||
- PP.RemovePragmaHandler(OptionsHandler.get());
|
||||
- OptionsHandler.reset();
|
||||
- PP.RemovePragmaHandler(PackHandler.get());
|
||||
- PackHandler.reset();
|
||||
- PP.RemovePragmaHandler(MSStructHandler.get());
|
||||
- MSStructHandler.reset();
|
||||
- PP.RemovePragmaHandler(UnusedHandler.get());
|
||||
- UnusedHandler.reset();
|
||||
- PP.RemovePragmaHandler(WeakHandler.get());
|
||||
- WeakHandler.reset();
|
||||
- PP.RemovePragmaHandler(RedefineExtnameHandler.get());
|
||||
- RedefineExtnameHandler.reset();
|
||||
-
|
||||
- if (getLangOpts().OpenCL) {
|
||||
- PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
- OpenCLExtensionHandler.reset();
|
||||
- PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
|
||||
- }
|
||||
+ if (!IsTemporary) {
|
||||
+ // Remove the pragma handlers we installed.
|
||||
+ PP.RemovePragmaHandler(AlignHandler.get());
|
||||
+ AlignHandler.reset();
|
||||
+ PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
+ GCCVisibilityHandler.reset();
|
||||
+ PP.RemovePragmaHandler(OptionsHandler.get());
|
||||
+ OptionsHandler.reset();
|
||||
+ PP.RemovePragmaHandler(PackHandler.get());
|
||||
+ PackHandler.reset();
|
||||
+ PP.RemovePragmaHandler(MSStructHandler.get());
|
||||
+ MSStructHandler.reset();
|
||||
+ PP.RemovePragmaHandler(UnusedHandler.get());
|
||||
+ UnusedHandler.reset();
|
||||
+ PP.RemovePragmaHandler(WeakHandler.get());
|
||||
+ WeakHandler.reset();
|
||||
+ PP.RemovePragmaHandler(RedefineExtnameHandler.get());
|
||||
+ RedefineExtnameHandler.reset();
|
||||
+
|
||||
+ if (getLangOpts().OpenCL) {
|
||||
+ PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
+ OpenCLExtensionHandler.reset();
|
||||
+ PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
|
||||
+ }
|
||||
PP.RemovePragmaHandler(OpenMPHandler.get());
|
||||
OpenMPHandler.reset();
|
||||
|
||||
- PP.RemovePragmaHandler("STDC", FPContractHandler.get());
|
||||
- FPContractHandler.reset();
|
||||
+ PP.RemovePragmaHandler("STDC", FPContractHandler.get());
|
||||
+ FPContractHandler.reset();
|
||||
|
||||
- PP.removeCommentHandler(CommentSemaHandler.get());
|
||||
+ PP.removeCommentHandler(CommentSemaHandler.get());
|
||||
|
||||
- PP.clearCodeCompletionHandler();
|
||||
+ PP.clearCodeCompletionHandler();
|
||||
+ }
|
||||
|
||||
assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?");
|
||||
}
|
||||
@@ -515,30 +534,10 @@
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
-namespace {
|
||||
- /// \brief RAIIObject to destroy the contents of a SmallVector of
|
||||
- /// TemplateIdAnnotation pointers and clear the vector.
|
||||
- class DestroyTemplateIdAnnotationsRAIIObj {
|
||||
- SmallVectorImpl<TemplateIdAnnotation *> &Container;
|
||||
- public:
|
||||
- DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl<TemplateIdAnnotation *>
|
||||
- &Container)
|
||||
- : Container(Container) {}
|
||||
-
|
||||
- ~DestroyTemplateIdAnnotationsRAIIObj() {
|
||||
- for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I =
|
||||
- Container.begin(), E = Container.end();
|
||||
- I != E; ++I)
|
||||
- (*I)->Destroy();
|
||||
- Container.clear();
|
||||
- }
|
||||
- };
|
||||
-}
|
||||
-
|
||||
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
|
||||
/// action tells us to. This returns true if the EOF was encountered.
|
||||
bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
|
||||
- DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
|
||||
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
|
||||
|
||||
// Skip over the EOF token, flagging end of previous input for incremental
|
||||
// processing
|
||||
@@ -553,9 +552,7 @@
|
||||
// Late template parsing can begin.
|
||||
if (getLangOpts().DelayedTemplateParsing)
|
||||
Actions.SetLateTemplateParser(LateTemplateParserCallback, this);
|
||||
- if (!PP.isIncrementalProcessingEnabled())
|
||||
- Actions.ActOnEndOfTranslationUnit();
|
||||
- //else don't tell Sema that we ended parsing: more input might come.
|
||||
+ Actions.ActOnEndOfTranslationUnit();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -594,7 +591,7 @@
|
||||
Parser::DeclGroupPtrTy
|
||||
Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
||||
ParsingDeclSpec *DS) {
|
||||
- DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
|
||||
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
|
||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||
|
||||
if (PP.isCodeCompletionReached()) {
|
||||
--- /home/axel/build/cling/src/./tools/clang/include/clang/Parse/Parser.h 2013-04-24 22:05:47.695986522 +0200
|
||||
+++ ./tools/clang/include/clang/Parse/Parser.h 2013-04-24 19:40:12.825509895 +0200
|
||||
@@ -45,6 +45,7 @@
|
||||
class InMessageExpressionRAIIObject;
|
||||
class PoisonSEHIdentifiersRAIIObject;
|
||||
class VersionTuple;
|
||||
+ class DestroyTemplateIdAnnotationsRAIIObj;
|
||||
|
||||
/// Parser - This implements a parser for the C family of languages. After
|
||||
/// parsing units of the grammar, productions are invoked to handle whatever has
|
||||
@@ -58,6 +59,7 @@
|
||||
friend class ObjCDeclContextSwitch;
|
||||
friend class ParenBraceBracketBalancer;
|
||||
friend class BalancedDelimiterTracker;
|
||||
+ friend class DestroyTemplateIdAnnotationsRAIIObj;
|
||||
|
||||
Preprocessor &PP;
|
||||
|
||||
@@ -193,8 +195,10 @@
|
||||
|
||||
bool SkipFunctionBodies;
|
||||
|
||||
+ bool IsTemporary;
|
||||
public:
|
||||
- Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
|
||||
+ Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies,
|
||||
+ bool isTemp = false);
|
||||
~Parser();
|
||||
|
||||
const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
|
||||
@@ -204,6 +208,34 @@
|
||||
AttributeFactory &getAttrFactory() { return AttrFactory; }
|
||||
|
||||
const Token &getCurToken() const { return Tok; }
|
||||
+
|
||||
+ /// A RAII object to temporarily reset PP's state and restore it.
|
||||
+ class ParserCurTokRestoreRAII {
|
||||
+ private:
|
||||
+ Parser &P;
|
||||
+ Token SavedTok;
|
||||
+
|
||||
+ public:
|
||||
+ ParserCurTokRestoreRAII(Parser &P)
|
||||
+ : P(P), SavedTok(P.Tok)
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ void pop() {
|
||||
+ if (SavedTok.is(tok::unknown))
|
||||
+ return;
|
||||
+
|
||||
+ P.Tok = SavedTok;
|
||||
+
|
||||
+ SavedTok.startToken();
|
||||
+ }
|
||||
+
|
||||
+ ~ParserCurTokRestoreRAII() {
|
||||
+ pop();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+
|
||||
Scope *getCurScope() const { return Actions.getCurScope(); }
|
||||
|
||||
Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
|
||||
@@ -701,7 +733,7 @@
|
||||
return Diag(Tok, DiagID);
|
||||
}
|
||||
|
||||
-private:
|
||||
+protected:
|
||||
void SuggestParentheses(SourceLocation Loc, unsigned DK,
|
||||
SourceRange ParenRange);
|
||||
void CheckNestedObjCContexts(SourceLocation AtLoc);
|
22
patches/clang-Sema-enable_ActOnEndOfTU_cling.diff
Normal file
22
patches/clang-Sema-enable_ActOnEndOfTU_cling.diff
Normal file
@ -0,0 +1,22 @@
|
||||
--- /home/axel/build/cling/src/./tools/clang/lib/Sema/Sema.cpp 2013-04-24 22:04:42.288514584 +0200
|
||||
+++ ./tools/clang/lib/Sema/Sema.cpp 2013-04-24 19:40:14.329498012 +0200
|
||||
@@ -599,7 +599,8 @@
|
||||
|
||||
if (TUKind == TU_Prefix) {
|
||||
// Translation unit prefixes don't need any of the checking below.
|
||||
- TUScope = 0;
|
||||
+ if (!PP.isIncrementalProcessingEnabled())
|
||||
+ TUScope = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -790,7 +791,8 @@
|
||||
assert(ParsingInitForAutoVars.empty() &&
|
||||
"Didn't unmark var as having its initializer parsed");
|
||||
|
||||
- TUScope = 0;
|
||||
+ if (!PP.isIncrementalProcessingEnabled())
|
||||
+ TUScope = 0;
|
||||
}
|
||||
|
||||
|
18
patches/clang-ToolChains-Mageia.diff
Normal file
18
patches/clang-ToolChains-Mageia.diff
Normal file
@ -0,0 +1,18 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/Driver/ToolChains.cpp 2013-04-11 09:34:54.425160197 +0200
|
||||
+++ ./tools/clang/lib/Driver/ToolChains.cpp 2013-04-24 19:40:14.813494188 +0200
|
||||
@@ -1098,6 +1098,7 @@
|
||||
"x86_64-suse-linux",
|
||||
"x86_64-manbo-linux-gnu",
|
||||
"x86_64-linux-gnu",
|
||||
+ "x86_64-mageia-linux-gnu",
|
||||
"x86_64-slackware-linux"
|
||||
};
|
||||
static const char *const X86LibDirs[] = { "/lib32", "/lib" };
|
||||
@@ -1112,6 +1113,7 @@
|
||||
"i386-redhat-linux",
|
||||
"i586-suse-linux",
|
||||
"i486-slackware-linux",
|
||||
+ "i586-mageia-linux-gnu",
|
||||
"i686-montavista-linux"
|
||||
};
|
||||
|
24
patches/clang-dso_handle.diff
Normal file
24
patches/clang-dso_handle.diff
Normal file
@ -0,0 +1,24 @@
|
||||
--- /home/axel/build/llvm-orig/src/./cmake/config-ix.cmake 2013-04-11 09:34:27.245442672 +0200
|
||||
+++ ./cmake/config-ix.cmake 2013-04-24 19:40:08.149546838 +0200
|
||||
@@ -221,6 +221,8 @@
|
||||
add_llvm_definitions( -D_GNU_SOURCE )
|
||||
endif()
|
||||
|
||||
+check_function_exists(__dso_handle HAVE___DSO_HANDLE)
|
||||
+
|
||||
set(headers "")
|
||||
if (HAVE_SYS_TYPES_H)
|
||||
set(headers ${headers} "sys/types.h")
|
||||
--- /home/axel/build/llvm-orig/src/./include/llvm/Config/config.h.cmake 2013-04-11 09:34:30.121412783 +0200
|
||||
+++ ./include/llvm/Config/config.h.cmake 2013-04-24 19:40:08.477544247 +0200
|
||||
@@ -519,8 +519,8 @@
|
||||
/* Have host's __divdi3 */
|
||||
#cmakedefine HAVE___DIVDI3 ${HAVE___DIVDI3}
|
||||
|
||||
-/* Define to 1 if you have the `__dso_handle' function. */
|
||||
-#undef HAVE___DSO_HANDLE
|
||||
+/* Have host's `__dso_handle' */
|
||||
+#cmakedefine HAVE___DSO_HANDLE ${HAVE___DSO_HANDLE}
|
||||
|
||||
/* Have host's __fixdfdi */
|
||||
#cmakedefine HAVE___FIXDFDI ${HAVE___FIXDFDI}
|
47
patches/clang_SourceManager_invalidPCHSourceFiles.diff
Normal file
47
patches/clang_SourceManager_invalidPCHSourceFiles.diff
Normal file
@ -0,0 +1,47 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/include/clang/Basic/SourceManager.h 2013-04-11 09:35:12.700970247 +0200
|
||||
+++ ./tools/clang/include/clang/Basic/SourceManager.h 2013-04-24 19:40:12.173515046 +0200
|
||||
@@ -1456,7 +1456,7 @@
|
||||
if (Invalid) *Invalid = true;
|
||||
return LocalSLocEntryTable[0];
|
||||
}
|
||||
- return getSLocEntryByID(FID.ID);
|
||||
+ return getSLocEntryByID(FID.ID, Invalid);
|
||||
}
|
||||
|
||||
unsigned getNextLocalOffset() const { return NextLocalOffset; }
|
||||
@@ -1520,11 +1520,11 @@
|
||||
const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
|
||||
|
||||
/// \brief Get the entry with the given unwrapped FileID.
|
||||
- const SrcMgr::SLocEntry &getSLocEntryByID(int ID) const {
|
||||
+ const SrcMgr::SLocEntry &getSLocEntryByID(int ID, bool* Invalid = 0) const {
|
||||
assert(ID != -1 && "Using FileID sentinel value");
|
||||
if (ID < 0)
|
||||
- return getLoadedSLocEntryByID(ID);
|
||||
- return getLocalSLocEntry(static_cast<unsigned>(ID));
|
||||
+ return getLoadedSLocEntryByID(ID, Invalid);
|
||||
+ return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid);
|
||||
}
|
||||
|
||||
const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID,
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/Serialization/ASTReader.cpp 2013-04-11 09:34:53.569169094 +0200
|
||||
+++ ./tools/clang/lib/Serialization/ASTReader.cpp 2013-04-24 19:40:15.673487393 +0200
|
||||
@@ -932,7 +932,7 @@
|
||||
// We will detect whether a file changed and return 'Failure' for it, but
|
||||
// we will also try to fail gracefully by setting up the SLocEntry.
|
||||
unsigned InputID = Record[4];
|
||||
- InputFile IF = getInputFile(*F, InputID);
|
||||
+ InputFile IF = getInputFile(*F, InputID, /*Complain=*/false);
|
||||
const FileEntry *File = IF.getFile();
|
||||
bool OverriddenBuffer = IF.isOverridden();
|
||||
|
||||
@@ -1683,7 +1683,8 @@
|
||||
ErrorStr += "' referenced by AST file";
|
||||
Error(ErrorStr.c_str());
|
||||
}
|
||||
- return InputFile();
|
||||
+ File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
|
||||
+ //return InputFile();
|
||||
}
|
||||
|
||||
// Check if there was a request to override the contents of the file
|
@ -1,33 +1,6 @@
|
||||
Index: tools/clang/include/clang/Parse/Parser.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Parse/Parser.h (revision 47284)
|
||||
+++ tools/clang/include/clang/Parse/Parser.h (working copy)
|
||||
@@ -223,8 +223,10 @@
|
||||
|
||||
bool SkipFunctionBodies;
|
||||
|
||||
+ bool IsTemporary;
|
||||
public:
|
||||
- Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
|
||||
+ Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies,
|
||||
+ bool isTemp = false);
|
||||
~Parser();
|
||||
|
||||
const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
|
||||
@@ -720,7 +722,7 @@
|
||||
return Diag(Tok, DiagID);
|
||||
}
|
||||
|
||||
-private:
|
||||
+protected:
|
||||
void SuggestParentheses(SourceLocation Loc, unsigned DK,
|
||||
SourceRange ParenRange);
|
||||
void CheckNestedObjCContexts(SourceLocation AtLoc);
|
||||
Index: tools/clang/lib/Lex/Pragma.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Lex/Pragma.cpp (revision 47284)
|
||||
+++ tools/clang/lib/Lex/Pragma.cpp (working copy)
|
||||
@@ -890,9 +890,11 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/Lex/Pragma.cpp 2013-04-11 09:34:54.365160820 +0200
|
||||
+++ ./tools/clang/lib/Lex/Pragma.cpp 2013-04-24 19:40:14.677495262 +0200
|
||||
@@ -858,9 +858,11 @@
|
||||
}
|
||||
|
||||
// Check to make sure we don't already have a pragma for this identifier.
|
||||
@ -42,178 +15,3 @@ Index: tools/clang/lib/Lex/Pragma.cpp
|
||||
}
|
||||
|
||||
/// RemovePragmaHandler - Remove the specific pragma handler from the
|
||||
Index: tools/clang/lib/Parse/Parser.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/Parser.cpp (revision 47284)
|
||||
+++ tools/clang/lib/Parse/Parser.cpp (working copy)
|
||||
@@ -47,13 +47,16 @@
|
||||
return Ident__except;
|
||||
}
|
||||
|
||||
-Parser::Parser(Preprocessor &pp, Sema &actions, bool SkipFunctionBodies)
|
||||
+Parser::Parser(Preprocessor &pp, Sema &actions, bool SkipFunctionBodies,
|
||||
+ bool isTemporary /*=false*/)
|
||||
: PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
|
||||
GreaterThanIsOperator(true), ColonIsSacred(false),
|
||||
InMessageExpression(false), TemplateParameterDepth(0),
|
||||
- ParsingInObjCContainer(false), SkipFunctionBodies(SkipFunctionBodies) {
|
||||
+ ParsingInObjCContainer(false), SkipFunctionBodies(SkipFunctionBodies),
|
||||
+ IsTemporary(isTemporary) {
|
||||
Tok.setKind(tok::eof);
|
||||
- Actions.CurScope = 0;
|
||||
+ if (!IsTemporary)
|
||||
+ Actions.CurScope = 0;
|
||||
NumCachedScopes = 0;
|
||||
ParenCount = BracketCount = BraceCount = 0;
|
||||
CurParsedObjCImpl = 0;
|
||||
@@ -61,43 +64,56 @@
|
||||
// Add #pragma handlers. These are removed and destroyed in the
|
||||
// destructor.
|
||||
AlignHandler.reset(new PragmaAlignHandler(actions));
|
||||
- PP.AddPragmaHandler(AlignHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(AlignHandler.get());
|
||||
|
||||
GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler(actions));
|
||||
- PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
|
||||
OptionsHandler.reset(new PragmaOptionsHandler(actions));
|
||||
- PP.AddPragmaHandler(OptionsHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(OptionsHandler.get());
|
||||
|
||||
PackHandler.reset(new PragmaPackHandler(actions));
|
||||
- PP.AddPragmaHandler(PackHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(PackHandler.get());
|
||||
|
||||
MSStructHandler.reset(new PragmaMSStructHandler(actions));
|
||||
- PP.AddPragmaHandler(MSStructHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(MSStructHandler.get());
|
||||
|
||||
UnusedHandler.reset(new PragmaUnusedHandler(actions));
|
||||
- PP.AddPragmaHandler(UnusedHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(UnusedHandler.get());
|
||||
|
||||
WeakHandler.reset(new PragmaWeakHandler(actions));
|
||||
- PP.AddPragmaHandler(WeakHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(WeakHandler.get());
|
||||
|
||||
RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler(actions));
|
||||
- PP.AddPragmaHandler(RedefineExtnameHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler(RedefineExtnameHandler.get());
|
||||
|
||||
FPContractHandler.reset(new PragmaFPContractHandler(actions));
|
||||
- PP.AddPragmaHandler("STDC", FPContractHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("STDC", FPContractHandler.get());
|
||||
|
||||
if (getLangOpts().OpenCL) {
|
||||
OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler(actions));
|
||||
- PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
-
|
||||
- PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
+
|
||||
+ if (!IsTemporary)
|
||||
+ PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
|
||||
}
|
||||
|
||||
CommentSemaHandler.reset(new ActionCommentHandler(actions));
|
||||
- PP.addCommentHandler(CommentSemaHandler.get());
|
||||
+ if (!IsTemporary)
|
||||
+ PP.addCommentHandler(CommentSemaHandler.get());
|
||||
|
||||
- PP.setCodeCompletionHandler(*this);
|
||||
+ if (!IsTemporary)
|
||||
+ PP.setCodeCompletionHandler(*this);
|
||||
}
|
||||
|
||||
/// If a crash happens while the parser is active, print out a line indicating
|
||||
@@ -413,9 +429,11 @@
|
||||
|
||||
Parser::~Parser() {
|
||||
// If we still have scopes active, delete the scope tree.
|
||||
- delete getCurScope();
|
||||
- Actions.CurScope = 0;
|
||||
-
|
||||
+ if (!IsTemporary) {
|
||||
+ delete getCurScope();
|
||||
+ Actions.CurScope = 0;
|
||||
+ }
|
||||
+
|
||||
// Free the scope cache.
|
||||
for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
|
||||
delete ScopeCache[i];
|
||||
@@ -425,36 +443,38 @@
|
||||
it != LateParsedTemplateMap.end(); ++it)
|
||||
delete it->second;
|
||||
|
||||
- // Remove the pragma handlers we installed.
|
||||
- PP.RemovePragmaHandler(AlignHandler.get());
|
||||
- AlignHandler.reset();
|
||||
- PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
- GCCVisibilityHandler.reset();
|
||||
- PP.RemovePragmaHandler(OptionsHandler.get());
|
||||
- OptionsHandler.reset();
|
||||
- PP.RemovePragmaHandler(PackHandler.get());
|
||||
- PackHandler.reset();
|
||||
- PP.RemovePragmaHandler(MSStructHandler.get());
|
||||
- MSStructHandler.reset();
|
||||
- PP.RemovePragmaHandler(UnusedHandler.get());
|
||||
- UnusedHandler.reset();
|
||||
- PP.RemovePragmaHandler(WeakHandler.get());
|
||||
- WeakHandler.reset();
|
||||
- PP.RemovePragmaHandler(RedefineExtnameHandler.get());
|
||||
- RedefineExtnameHandler.reset();
|
||||
+ if (!IsTemporary) {
|
||||
+ // Remove the pragma handlers we installed.
|
||||
+ PP.RemovePragmaHandler(AlignHandler.get());
|
||||
+ AlignHandler.reset();
|
||||
+ PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
+ GCCVisibilityHandler.reset();
|
||||
+ PP.RemovePragmaHandler(OptionsHandler.get());
|
||||
+ OptionsHandler.reset();
|
||||
+ PP.RemovePragmaHandler(PackHandler.get());
|
||||
+ PackHandler.reset();
|
||||
+ PP.RemovePragmaHandler(MSStructHandler.get());
|
||||
+ MSStructHandler.reset();
|
||||
+ PP.RemovePragmaHandler(UnusedHandler.get());
|
||||
+ UnusedHandler.reset();
|
||||
+ PP.RemovePragmaHandler(WeakHandler.get());
|
||||
+ WeakHandler.reset();
|
||||
+ PP.RemovePragmaHandler(RedefineExtnameHandler.get());
|
||||
+ RedefineExtnameHandler.reset();
|
||||
|
||||
- if (getLangOpts().OpenCL) {
|
||||
- PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
- OpenCLExtensionHandler.reset();
|
||||
- PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
|
||||
- }
|
||||
+ if (getLangOpts().OpenCL) {
|
||||
+ PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
+ OpenCLExtensionHandler.reset();
|
||||
+ PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
|
||||
+ }
|
||||
|
||||
- PP.RemovePragmaHandler("STDC", FPContractHandler.get());
|
||||
- FPContractHandler.reset();
|
||||
+ PP.RemovePragmaHandler("STDC", FPContractHandler.get());
|
||||
+ FPContractHandler.reset();
|
||||
|
||||
- PP.removeCommentHandler(CommentSemaHandler.get());
|
||||
+ PP.removeCommentHandler(CommentSemaHandler.get());
|
||||
|
||||
- PP.clearCodeCompletionHandler();
|
||||
+ PP.clearCodeCompletionHandler();
|
||||
+ }
|
||||
|
||||
assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?");
|
||||
}
|
||||
|
@ -1,162 +0,0 @@
|
||||
Index: tools/clang/include/clang/Sema/Sema.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Sema/Sema.h (revision 47284)
|
||||
+++ tools/clang/include/clang/Sema/Sema.h (working copy)
|
||||
@@ -466,6 +466,41 @@
|
||||
}
|
||||
};
|
||||
|
||||
+ /// A RAII object to temporarily push a decl context and scope.
|
||||
+ class ContextAndScopeRAII {
|
||||
+ private:
|
||||
+ Sema &S;
|
||||
+ DeclContext *SavedContext;
|
||||
+ Scope *SavedScope;
|
||||
+ ProcessingContextState SavedContextState;
|
||||
+ QualType SavedCXXThisTypeOverride;
|
||||
+
|
||||
+ public:
|
||||
+ ContextAndScopeRAII(Sema &S, DeclContext *ContextToPush, Scope *ScopeToPush)
|
||||
+ : S(S), SavedContext(S.CurContext), SavedScope(S.CurScope),
|
||||
+ SavedContextState(S.DelayedDiagnostics.pushUndelayed()),
|
||||
+ SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
|
||||
+ {
|
||||
+ assert(ContextToPush && "pushing null context");
|
||||
+ S.CurContext = ContextToPush;
|
||||
+ S.CurScope = ScopeToPush;
|
||||
+ }
|
||||
+
|
||||
+ void pop() {
|
||||
+ if (!SavedContext) return;
|
||||
+ S.CurContext = SavedContext;
|
||||
+ S.CurScope = SavedScope;
|
||||
+ S.DelayedDiagnostics.popUndelayed(SavedContextState);
|
||||
+ S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
|
||||
+ SavedContext = 0;
|
||||
+ SavedScope = 0;
|
||||
+ }
|
||||
+
|
||||
+ ~ContextAndScopeRAII() {
|
||||
+ pop();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
/// WeakUndeclaredIdentifiers - Identifiers contained in
|
||||
/// \#pragma weak before declared. rare. may alias another
|
||||
/// identifier, declared or undeclared
|
||||
Index: tools/clang/include/clang/Lex/Preprocessor.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Lex/Preprocessor.h (revision 47284)
|
||||
+++ tools/clang/include/clang/Lex/Preprocessor.h (working copy)
|
||||
@@ -623,6 +623,72 @@
|
||||
void EnterTokenStream(const Token *Toks, unsigned NumToks,
|
||||
bool DisableMacroExpansion, bool OwnsTokens);
|
||||
|
||||
+ /// A RAII object to temporarily reset PP's state and restore it.
|
||||
+ class CleanupAndRestoreCacheRAII {
|
||||
+ private:
|
||||
+ Preprocessor &PP;
|
||||
+ CachedTokensTy::size_type SavedCachedLexPos;
|
||||
+ CachedTokensTy SavedCachedTokens;
|
||||
+ std::vector<IncludeStackInfo> SavedStack;
|
||||
+ Lexer *SavedCurLexer;
|
||||
+ PTHLexer *SavedCurPTHLexer;
|
||||
+ PreprocessorLexer *SavedCurPPLexer;
|
||||
+ TokenLexer* SavedCurTokenLexer;
|
||||
+ const DirectoryLookup *SavedCurDirLookup;
|
||||
+ enum CurLexerKind SavedCurLexerKind;
|
||||
+
|
||||
+ public:
|
||||
+ CleanupAndRestoreCacheRAII(Preprocessor &PP)
|
||||
+ : PP(PP), SavedCachedLexPos(PP.CachedLexPos),
|
||||
+ SavedCachedTokens(PP.CachedTokens), SavedStack(PP.IncludeMacroStack),
|
||||
+ SavedCurLexer(PP.CurLexer.take()),
|
||||
+ SavedCurPTHLexer(PP.CurPTHLexer.take()),
|
||||
+ SavedCurPPLexer(PP.CurPPLexer),
|
||||
+ SavedCurTokenLexer(PP.CurTokenLexer.take()),
|
||||
+ SavedCurDirLookup(PP.CurDirLookup),
|
||||
+ SavedCurLexerKind(PP.CurLexerKind)
|
||||
+ {
|
||||
+ PP.CachedLexPos = 0;
|
||||
+ PP.CachedTokens.clear();
|
||||
+ PP.IncludeMacroStack.clear();
|
||||
+ PP.CurLexer.reset(0);
|
||||
+ PP.CurPTHLexer.reset(0);
|
||||
+ PP.CurPPLexer = 0;
|
||||
+ PP.CurTokenLexer.reset(0);
|
||||
+ PP.CurDirLookup = 0;
|
||||
+ PP.CurLexerKind = CLK_CachingLexer;
|
||||
+ }
|
||||
+
|
||||
+ void pop() {
|
||||
+ if (SavedCurLexerKind == (enum CurLexerKind)~0U)
|
||||
+ return;
|
||||
+
|
||||
+ PP.CachedLexPos = SavedCachedLexPos;
|
||||
+ PP.CachedTokens = SavedCachedTokens;
|
||||
+ PP.IncludeMacroStack = SavedStack;
|
||||
+ PP.CurLexer.reset(SavedCurLexer);
|
||||
+ PP.CurPTHLexer.reset(SavedCurPTHLexer);
|
||||
+ PP.CurPPLexer = SavedCurPPLexer;
|
||||
+ PP.CurTokenLexer.reset(SavedCurTokenLexer);
|
||||
+ PP.CurDirLookup = SavedCurDirLookup;
|
||||
+ PP.CurLexerKind = SavedCurLexerKind;
|
||||
+
|
||||
+ SavedCachedLexPos = 0;
|
||||
+ SavedCachedTokens.clear();
|
||||
+ SavedStack.clear();
|
||||
+ SavedCurLexer = 0;
|
||||
+ SavedCurPTHLexer = 0;
|
||||
+ SavedCurPPLexer = 0;
|
||||
+ SavedCurTokenLexer = 0;
|
||||
+ SavedCurDirLookup = 0;
|
||||
+ SavedCurLexerKind = (enum CurLexerKind)~0U;
|
||||
+ }
|
||||
+
|
||||
+ ~CleanupAndRestoreCacheRAII() {
|
||||
+ pop();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
/// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
|
||||
/// lexer stack. This should only be used in situations where the current
|
||||
/// state of the top-of-stack lexer is known.
|
||||
Index: tools/clang/include/clang/Parse/Parser.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Parse/Parser.h (revision 47327)
|
||||
+++ tools/clang/include/clang/Parse/Parser.h (working copy)
|
||||
@@ -236,6 +236,34 @@
|
||||
AttributeFactory &getAttrFactory() { return AttrFactory; }
|
||||
|
||||
const Token &getCurToken() const { return Tok; }
|
||||
+
|
||||
+ /// A RAII object to temporarily reset PP's state and restore it.
|
||||
+ class ParserCurTokRestoreRAII {
|
||||
+ private:
|
||||
+ Parser &P;
|
||||
+ Token SavedTok;
|
||||
+
|
||||
+ public:
|
||||
+ ParserCurTokRestoreRAII(Parser &P)
|
||||
+ : P(P), SavedTok(P.Tok)
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ void pop() {
|
||||
+ if (SavedTok.is(tok::unknown))
|
||||
+ return;
|
||||
+
|
||||
+ P.Tok = SavedTok;
|
||||
+
|
||||
+ SavedTok.startToken();
|
||||
+ }
|
||||
+
|
||||
+ ~ParserCurTokRestoreRAII() {
|
||||
+ pop();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+
|
||||
Scope *getCurScope() const { return Actions.getCurScope(); }
|
||||
|
||||
Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
|
@ -1,8 +1,6 @@
|
||||
Index: tools/clang/lib/Sema/SemaLookup.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/SemaLookup.cpp (revision 47284)
|
||||
+++ tools/clang/lib/Sema/SemaLookup.cpp (working copy)
|
||||
@@ -1207,8 +1207,14 @@
|
||||
--- /home/axel/build/llvm-orig/src/./tools/clang/lib/Sema/SemaLookup.cpp 2013-04-11 09:34:54.101163564 +0200
|
||||
+++ ./tools/clang/lib/Sema/SemaLookup.cpp 2013-04-24 19:40:14.317498106 +0200
|
||||
@@ -1250,8 +1250,14 @@
|
||||
}
|
||||
} else {
|
||||
// Perform C++ unqualified name lookup.
|
||||
|
@ -1,27 +1,18 @@
|
||||
Index: tools/clang/include/clang/Parse/Parser.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Parse/Parser.h (revision 47334)
|
||||
+++ tools/clang/include/clang/Parse/Parser.h (working copy)
|
||||
@@ -43,6 +43,7 @@
|
||||
class InMessageExpressionRAIIObject;
|
||||
class PoisonSEHIdentifiersRAIIObject;
|
||||
class VersionTuple;
|
||||
+ class DestroyTemplateIdAnnotationsRAIIObj;
|
||||
--- ./tools/clang/lib/Parse/Makefile 2012-03-16 10:46:07.000000000 +0100
|
||||
+++ ./tools/clang/lib/Parse/Makefile 2013-04-25 14:31:22.431552232 +0200
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
/// PrettyStackTraceParserEntry - If a crash happens while the parser is active,
|
||||
/// an entry is printed for it.
|
||||
@@ -89,6 +90,7 @@
|
||||
friend class ObjCDeclContextSwitch;
|
||||
friend class ParenBraceBracketBalancer;
|
||||
friend class BalancedDelimiterTracker;
|
||||
+ friend class DestroyTemplateIdAnnotationsRAIIObj;
|
||||
|
||||
Preprocessor &PP;
|
||||
CLANG_LEVEL := ../..
|
||||
LIBRARYNAME := clangParse
|
||||
-
|
||||
+# To find moved RAIIObjectsForParser.h
|
||||
+CPP.Flags += -I$(PROJ_SRC_DIR)/$(CLANG_LEVEL)/include/clang/Sema
|
||||
include $(CLANG_LEVEL)/Makefile
|
||||
|
||||
Index: tools/clang/include/clang/Parse/RAIIObjectsForParser.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Parse/RAIIObjectsForParser.h (revision 0)
|
||||
+++ tools/clang/include/clang/Parse/RAIIObjectsForParser.h (working copy)
|
||||
+++ tools/clang/include/clang/Parse/RAIIObjectsForParser.h (revision 0)
|
||||
@@ -0,0 +1,452 @@
|
||||
+//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===//
|
||||
+//
|
||||
@ -433,7 +424,7 @@ Index: tools/clang/include/clang/Parse/RAIIObjectsForParser.h
|
||||
+ if (!P.Tok.is(Kind))
|
||||
+ return true;
|
||||
+
|
||||
+ if (getDepth() < MaxDepth) {
|
||||
+ if (getDepth() < P.getLangOpts().BracketDepth) {
|
||||
+ LOpen = (P.*Consumer)();
|
||||
+ return false;
|
||||
+ }
|
||||
@ -475,236 +466,442 @@ Index: tools/clang/include/clang/Parse/RAIIObjectsForParser.h
|
||||
+} // end namespace clang
|
||||
+
|
||||
+#endif
|
||||
Index: tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseCXXInlineMethods.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseCXXInlineMethods.cpp (working copy)
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
using namespace clang;
|
||||
|
||||
/// ParseCXXInlineMethodDef - We parsed and verified that the specified
|
||||
Index: tools/clang/lib/Parse/ParseDecl.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseDecl.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseDecl.cpp (working copy)
|
||||
@@ -13,12 +13,12 @@
|
||||
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Basic/OpenCL.h"
|
||||
#include "clang/Sema/Lookup.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
#include "clang/Sema/ParsedTemplate.h"
|
||||
#include "clang/Sema/PrettyDeclStackTrace.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
Index: tools/clang/lib/Parse/ParseDeclCXX.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseDeclCXX.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseDeclCXX.cpp (working copy)
|
||||
@@ -14,13 +14,13 @@
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
#include "clang/Sema/ParsedTemplate.h"
|
||||
#include "clang/Sema/PrettyDeclStackTrace.h"
|
||||
#include "clang/Sema/SemaDiagnostic.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
using namespace clang;
|
||||
|
||||
/// ParseNamespace - We know that the current token is a namespace keyword. This
|
||||
Index: tools/clang/lib/Parse/ParseExpr.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseExpr.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseExpr.cpp (working copy)
|
||||
@@ -22,12 +22,12 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Parse/Parser.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
#include "clang/Sema/ParsedTemplate.h"
|
||||
#include "clang/Sema/TypoCorrection.h"
|
||||
#include "clang/Basic/PrettyStackTrace.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
using namespace clang;
|
||||
Index: tools/clang/lib/Parse/ParseExprCXX.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseExprCXX.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseExprCXX.cpp (working copy)
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Basic/PrettyStackTrace.h"
|
||||
#include "clang/Lex/LiteralSupport.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
Index: tools/clang/lib/Parse/ParseInit.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseInit.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseInit.cpp (working copy)
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/Designator.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
Index: tools/clang/lib/Parse/ParseObjc.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseObjc.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseObjc.cpp (working copy)
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/PrettyDeclStackTrace.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
Index: tools/clang/lib/Parse/ParseStmt.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseStmt.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseStmt.cpp (working copy)
|
||||
@@ -13,7 +13,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Parse/Parser.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/PrettyDeclStackTrace.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
Index: tools/clang/lib/Parse/ParseTemplate.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/ParseTemplate.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/ParseTemplate.cpp (working copy)
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/ParsedTemplate.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
using namespace clang;
|
||||
Index: tools/clang/lib/Parse/Parser.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/Parser.cpp (revision 47334)
|
||||
+++ tools/clang/lib/Parse/Parser.cpp (working copy)
|
||||
@@ -13,11 +13,11 @@
|
||||
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
+#include "clang/Parse/RAIIObjectsForParser.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
#include "clang/Sema/ParsedTemplate.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
-#include "RAIIObjectsForParser.h"
|
||||
#include "ParsePragma.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
@@ -546,30 +546,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
-namespace {
|
||||
- /// \brief RAIIObject to destroy the contents of a SmallVector of
|
||||
- /// TemplateIdAnnotation pointers and clear the vector.
|
||||
- class DestroyTemplateIdAnnotationsRAIIObj {
|
||||
- SmallVectorImpl<TemplateIdAnnotation *> &Container;
|
||||
- public:
|
||||
- DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl<TemplateIdAnnotation *>
|
||||
- &Container)
|
||||
- : Container(Container) {}
|
||||
-
|
||||
- ~DestroyTemplateIdAnnotationsRAIIObj() {
|
||||
- for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I =
|
||||
- Container.begin(), E = Container.end();
|
||||
- I != E; ++I)
|
||||
- (*I)->Destroy();
|
||||
- Container.clear();
|
||||
- }
|
||||
- };
|
||||
-}
|
||||
-
|
||||
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
|
||||
/// action tells us to. This returns true if the EOF was encountered.
|
||||
bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
|
||||
- DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
|
||||
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
|
||||
|
||||
// Skip over the EOF token, flagging end of previous input for incremental
|
||||
// processing
|
||||
@@ -639,7 +619,7 @@
|
||||
Parser::DeclGroupPtrTy
|
||||
Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
||||
ParsingDeclSpec *DS) {
|
||||
- DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
|
||||
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
|
||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||
|
||||
if (PP.isCodeCompletionReached()) {
|
||||
Index: tools/clang/lib/Parse/RAIIObjectsForParser.h
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/RAIIObjectsForParser.h (revision 47334)
|
||||
--- tools/clang/lib/Parse/RAIIObjectsForParser.h (revision 179269)
|
||||
+++ tools/clang/lib/Parse/RAIIObjectsForParser.h (working copy)
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Sema/DelayedDiagnostic.h"
|
||||
+#include "clang/Sema/ParsedTemplate.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
|
||||
namespace clang {
|
||||
@@ -429,6 +430,23 @@
|
||||
void skipToEnd();
|
||||
};
|
||||
|
||||
+ /// \brief RAIIObject to destroy the contents of a SmallVector of
|
||||
+ /// TemplateIdAnnotation pointers and clear the vector.
|
||||
+ class DestroyTemplateIdAnnotationsRAIIObj {
|
||||
+ Parser &P;
|
||||
+ public:
|
||||
+ DestroyTemplateIdAnnotationsRAIIObj(Parser &p)
|
||||
+ : P(p) {}
|
||||
+
|
||||
+ ~DestroyTemplateIdAnnotationsRAIIObj() {
|
||||
+ for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I =
|
||||
+ P.TemplateIds.begin(), E = P.TemplateIds.end();
|
||||
+ I != E; ++I)
|
||||
+ (*I)->Destroy();
|
||||
+ P.TemplateIds.clear();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
@@ -1,434 +0,0 @@
|
||||
-//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- 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 and implements the some simple RAII objects that are used
|
||||
-// by the parser to manage bits in recursion.
|
||||
-//
|
||||
-//===----------------------------------------------------------------------===//
|
||||
-
|
||||
-#ifndef LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
|
||||
-#define LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
|
||||
-
|
||||
-#include "clang/Parse/ParseDiagnostic.h"
|
||||
-#include "clang/Parse/Parser.h"
|
||||
-#include "clang/Sema/DelayedDiagnostic.h"
|
||||
-#include "clang/Sema/Sema.h"
|
||||
-
|
||||
-namespace clang {
|
||||
- // TODO: move ParsingClassDefinition here.
|
||||
- // TODO: move TentativeParsingAction here.
|
||||
-
|
||||
- /// \brief A RAII object used to temporarily suppress access-like
|
||||
- /// checking. Access-like checks are those associated with
|
||||
- /// controlling the use of a declaration, like C++ access control
|
||||
- /// errors and deprecation warnings. They are contextually
|
||||
- /// dependent, in that they can only be resolved with full
|
||||
- /// information about what's being declared. They are also
|
||||
- /// suppressed in certain contexts, like the template arguments of
|
||||
- /// an explicit instantiation. However, those suppression contexts
|
||||
- /// cannot necessarily be fully determined in advance; for
|
||||
- /// example, something starting like this:
|
||||
- /// template <> class std::vector<A::PrivateType>
|
||||
- /// might be the entirety of an explicit instantiation:
|
||||
- /// template <> class std::vector<A::PrivateType>;
|
||||
- /// or just an elaborated type specifier:
|
||||
- /// template <> class std::vector<A::PrivateType> make_vector<>();
|
||||
- /// Therefore this class collects all the diagnostics and permits
|
||||
- /// them to be re-delayed in a new context.
|
||||
- class SuppressAccessChecks {
|
||||
- Sema &S;
|
||||
- sema::DelayedDiagnosticPool DiagnosticPool;
|
||||
- Sema::ParsingDeclState State;
|
||||
- bool Active;
|
||||
-
|
||||
- public:
|
||||
- /// Begin suppressing access-like checks
|
||||
- SuppressAccessChecks(Parser &P, bool activate = true)
|
||||
- : S(P.getActions()), DiagnosticPool(NULL) {
|
||||
- if (activate) {
|
||||
- State = S.PushParsingDeclaration(DiagnosticPool);
|
||||
- Active = true;
|
||||
- } else {
|
||||
- Active = false;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- void done() {
|
||||
- assert(Active && "trying to end an inactive suppression");
|
||||
- S.PopParsingDeclaration(State, NULL);
|
||||
- Active = false;
|
||||
- }
|
||||
-
|
||||
- void redelay() {
|
||||
- assert(!Active && "redelaying without having ended first");
|
||||
- if (!DiagnosticPool.pool_empty())
|
||||
- S.redelayDiagnostics(DiagnosticPool);
|
||||
- assert(DiagnosticPool.pool_empty());
|
||||
- }
|
||||
-
|
||||
- ~SuppressAccessChecks() {
|
||||
- if (Active) done();
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// \brief RAII object used to inform the actions that we're
|
||||
- /// currently parsing a declaration. This is active when parsing a
|
||||
- /// variable's initializer, but not when parsing the body of a
|
||||
- /// class or function definition.
|
||||
- class ParsingDeclRAIIObject {
|
||||
- Sema &Actions;
|
||||
- sema::DelayedDiagnosticPool DiagnosticPool;
|
||||
- Sema::ParsingDeclState State;
|
||||
- bool Popped;
|
||||
-
|
||||
- ParsingDeclRAIIObject(const ParsingDeclRAIIObject &) LLVM_DELETED_FUNCTION;
|
||||
- void operator=(const ParsingDeclRAIIObject &) LLVM_DELETED_FUNCTION;
|
||||
-
|
||||
- public:
|
||||
- enum NoParent_t { NoParent };
|
||||
- ParsingDeclRAIIObject(Parser &P, NoParent_t _)
|
||||
- : Actions(P.getActions()), DiagnosticPool(NULL) {
|
||||
- push();
|
||||
- }
|
||||
-
|
||||
- /// Creates a RAII object whose pool is optionally parented by another.
|
||||
- ParsingDeclRAIIObject(Parser &P,
|
||||
- const sema::DelayedDiagnosticPool *parentPool)
|
||||
- : Actions(P.getActions()), DiagnosticPool(parentPool) {
|
||||
- push();
|
||||
- }
|
||||
-
|
||||
- /// Creates a RAII object and, optionally, initialize its
|
||||
- /// diagnostics pool by stealing the diagnostics from another
|
||||
- /// RAII object (which is assumed to be the current top pool).
|
||||
- ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *other)
|
||||
- : Actions(P.getActions()),
|
||||
- DiagnosticPool(other ? other->DiagnosticPool.getParent() : NULL) {
|
||||
- if (other) {
|
||||
- DiagnosticPool.steal(other->DiagnosticPool);
|
||||
- other->abort();
|
||||
- }
|
||||
- push();
|
||||
- }
|
||||
-
|
||||
- ~ParsingDeclRAIIObject() {
|
||||
- abort();
|
||||
- }
|
||||
-
|
||||
- sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() {
|
||||
- return DiagnosticPool;
|
||||
- }
|
||||
- const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const {
|
||||
- return DiagnosticPool;
|
||||
- }
|
||||
-
|
||||
- /// Resets the RAII object for a new declaration.
|
||||
- void reset() {
|
||||
- abort();
|
||||
- push();
|
||||
- }
|
||||
-
|
||||
- /// Signals that the context was completed without an appropriate
|
||||
- /// declaration being parsed.
|
||||
- void abort() {
|
||||
- pop(0);
|
||||
- }
|
||||
-
|
||||
- void complete(Decl *D) {
|
||||
- assert(!Popped && "ParsingDeclaration has already been popped!");
|
||||
- pop(D);
|
||||
- }
|
||||
-
|
||||
- /// Unregister this object from Sema, but remember all the
|
||||
- /// diagnostics that were emitted into it.
|
||||
- void abortAndRemember() {
|
||||
- pop(0);
|
||||
- }
|
||||
-
|
||||
- private:
|
||||
- void push() {
|
||||
- State = Actions.PushParsingDeclaration(DiagnosticPool);
|
||||
- Popped = false;
|
||||
- }
|
||||
-
|
||||
- void pop(Decl *D) {
|
||||
- if (!Popped) {
|
||||
- Actions.PopParsingDeclaration(State, D);
|
||||
- Popped = true;
|
||||
- }
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// A class for parsing a DeclSpec.
|
||||
- class ParsingDeclSpec : public DeclSpec {
|
||||
- ParsingDeclRAIIObject ParsingRAII;
|
||||
-
|
||||
- public:
|
||||
- ParsingDeclSpec(Parser &P)
|
||||
- : DeclSpec(P.getAttrFactory()),
|
||||
- ParsingRAII(P, ParsingDeclRAIIObject::NoParent) {}
|
||||
- ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
|
||||
- : DeclSpec(P.getAttrFactory()),
|
||||
- ParsingRAII(P, RAII) {}
|
||||
-
|
||||
- const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const {
|
||||
- return ParsingRAII.getDelayedDiagnosticPool();
|
||||
- }
|
||||
-
|
||||
- void complete(Decl *D) {
|
||||
- ParsingRAII.complete(D);
|
||||
- }
|
||||
-
|
||||
- void abort() {
|
||||
- ParsingRAII.abort();
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// A class for parsing a declarator.
|
||||
- class ParsingDeclarator : public Declarator {
|
||||
- ParsingDeclRAIIObject ParsingRAII;
|
||||
-
|
||||
- public:
|
||||
- ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C)
|
||||
- : Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
|
||||
- }
|
||||
-
|
||||
- const ParsingDeclSpec &getDeclSpec() const {
|
||||
- return static_cast<const ParsingDeclSpec&>(Declarator::getDeclSpec());
|
||||
- }
|
||||
-
|
||||
- ParsingDeclSpec &getMutableDeclSpec() const {
|
||||
- return const_cast<ParsingDeclSpec&>(getDeclSpec());
|
||||
- }
|
||||
-
|
||||
- void clear() {
|
||||
- Declarator::clear();
|
||||
- ParsingRAII.reset();
|
||||
- }
|
||||
-
|
||||
- void complete(Decl *D) {
|
||||
- ParsingRAII.complete(D);
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// A class for parsing a field declarator.
|
||||
- class ParsingFieldDeclarator : public FieldDeclarator {
|
||||
- ParsingDeclRAIIObject ParsingRAII;
|
||||
-
|
||||
- public:
|
||||
- ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS)
|
||||
- : FieldDeclarator(DS), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
|
||||
- }
|
||||
-
|
||||
- const ParsingDeclSpec &getDeclSpec() const {
|
||||
- return static_cast<const ParsingDeclSpec&>(D.getDeclSpec());
|
||||
- }
|
||||
-
|
||||
- ParsingDeclSpec &getMutableDeclSpec() const {
|
||||
- return const_cast<ParsingDeclSpec&>(getDeclSpec());
|
||||
- }
|
||||
-
|
||||
- void complete(Decl *D) {
|
||||
- ParsingRAII.complete(D);
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// ExtensionRAIIObject - This saves the state of extension warnings when
|
||||
- /// constructed and disables them. When destructed, it restores them back to
|
||||
- /// the way they used to be. This is used to handle __extension__ in the
|
||||
- /// parser.
|
||||
- class ExtensionRAIIObject {
|
||||
- ExtensionRAIIObject(const ExtensionRAIIObject &) LLVM_DELETED_FUNCTION;
|
||||
- void operator=(const ExtensionRAIIObject &) LLVM_DELETED_FUNCTION;
|
||||
-
|
||||
- DiagnosticsEngine &Diags;
|
||||
- public:
|
||||
- ExtensionRAIIObject(DiagnosticsEngine &diags) : Diags(diags) {
|
||||
- Diags.IncrementAllExtensionsSilenced();
|
||||
- }
|
||||
-
|
||||
- ~ExtensionRAIIObject() {
|
||||
- Diags.DecrementAllExtensionsSilenced();
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and
|
||||
- /// restores it when destroyed. This says that "foo:" should not be
|
||||
- /// considered a possible typo for "foo::" for error recovery purposes.
|
||||
- class ColonProtectionRAIIObject {
|
||||
- Parser &P;
|
||||
- bool OldVal;
|
||||
- public:
|
||||
- ColonProtectionRAIIObject(Parser &p, bool Value = true)
|
||||
- : P(p), OldVal(P.ColonIsSacred) {
|
||||
- P.ColonIsSacred = Value;
|
||||
- }
|
||||
-
|
||||
- /// restore - This can be used to restore the state early, before the dtor
|
||||
- /// is run.
|
||||
- void restore() {
|
||||
- P.ColonIsSacred = OldVal;
|
||||
- }
|
||||
-
|
||||
- ~ColonProtectionRAIIObject() {
|
||||
- restore();
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// \brief RAII object that makes '>' behave either as an operator
|
||||
- /// or as the closing angle bracket for a template argument list.
|
||||
- class GreaterThanIsOperatorScope {
|
||||
- bool &GreaterThanIsOperator;
|
||||
- bool OldGreaterThanIsOperator;
|
||||
- public:
|
||||
- GreaterThanIsOperatorScope(bool >IO, bool Val)
|
||||
- : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
|
||||
- GreaterThanIsOperator = Val;
|
||||
- }
|
||||
-
|
||||
- ~GreaterThanIsOperatorScope() {
|
||||
- GreaterThanIsOperator = OldGreaterThanIsOperator;
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- class InMessageExpressionRAIIObject {
|
||||
- bool &InMessageExpression;
|
||||
- bool OldValue;
|
||||
-
|
||||
- public:
|
||||
- InMessageExpressionRAIIObject(Parser &P, bool Value)
|
||||
- : InMessageExpression(P.InMessageExpression),
|
||||
- OldValue(P.InMessageExpression) {
|
||||
- InMessageExpression = Value;
|
||||
- }
|
||||
-
|
||||
- ~InMessageExpressionRAIIObject() {
|
||||
- InMessageExpression = OldValue;
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// \brief RAII object that makes sure paren/bracket/brace count is correct
|
||||
- /// after declaration/statement parsing, even when there's a parsing error.
|
||||
- class ParenBraceBracketBalancer {
|
||||
- Parser &P;
|
||||
- unsigned short ParenCount, BracketCount, BraceCount;
|
||||
- public:
|
||||
- ParenBraceBracketBalancer(Parser &p)
|
||||
- : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount),
|
||||
- BraceCount(p.BraceCount) { }
|
||||
-
|
||||
- ~ParenBraceBracketBalancer() {
|
||||
- P.ParenCount = ParenCount;
|
||||
- P.BracketCount = BracketCount;
|
||||
- P.BraceCount = BraceCount;
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- class PoisonSEHIdentifiersRAIIObject {
|
||||
- PoisonIdentifierRAIIObject Ident_AbnormalTermination;
|
||||
- PoisonIdentifierRAIIObject Ident_GetExceptionCode;
|
||||
- PoisonIdentifierRAIIObject Ident_GetExceptionInfo;
|
||||
- PoisonIdentifierRAIIObject Ident__abnormal_termination;
|
||||
- PoisonIdentifierRAIIObject Ident__exception_code;
|
||||
- PoisonIdentifierRAIIObject Ident__exception_info;
|
||||
- PoisonIdentifierRAIIObject Ident___abnormal_termination;
|
||||
- PoisonIdentifierRAIIObject Ident___exception_code;
|
||||
- PoisonIdentifierRAIIObject Ident___exception_info;
|
||||
- public:
|
||||
- PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue)
|
||||
- : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue),
|
||||
- Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue),
|
||||
- Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue),
|
||||
- Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue),
|
||||
- Ident__exception_code(Self.Ident__exception_code, NewValue),
|
||||
- Ident__exception_info(Self.Ident__exception_info, NewValue),
|
||||
- Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue),
|
||||
- Ident___exception_code(Self.Ident___exception_code, NewValue),
|
||||
- Ident___exception_info(Self.Ident___exception_info, NewValue) {
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- /// \brief RAII class that helps handle the parsing of an open/close delimiter
|
||||
- /// pair, such as braces { ... } or parentheses ( ... ).
|
||||
- class BalancedDelimiterTracker : public GreaterThanIsOperatorScope {
|
||||
- Parser& P;
|
||||
- tok::TokenKind Kind, Close;
|
||||
- SourceLocation (Parser::*Consumer)();
|
||||
- SourceLocation LOpen, LClose;
|
||||
-
|
||||
- unsigned short &getDepth() {
|
||||
- switch (Kind) {
|
||||
- case tok::l_brace: return P.BraceCount;
|
||||
- case tok::l_square: return P.BracketCount;
|
||||
- case tok::l_paren: return P.ParenCount;
|
||||
- default: llvm_unreachable("Wrong token kind");
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- enum { MaxDepth = 256 };
|
||||
-
|
||||
- bool diagnoseOverflow();
|
||||
- bool diagnoseMissingClose();
|
||||
-
|
||||
- public:
|
||||
- BalancedDelimiterTracker(Parser& p, tok::TokenKind k)
|
||||
- : GreaterThanIsOperatorScope(p.GreaterThanIsOperator, true),
|
||||
- P(p), Kind(k)
|
||||
- {
|
||||
- switch (Kind) {
|
||||
- default: llvm_unreachable("Unexpected balanced token");
|
||||
- case tok::l_brace:
|
||||
- Close = tok::r_brace;
|
||||
- Consumer = &Parser::ConsumeBrace;
|
||||
- break;
|
||||
- case tok::l_paren:
|
||||
- Close = tok::r_paren;
|
||||
- Consumer = &Parser::ConsumeParen;
|
||||
- break;
|
||||
-
|
||||
- case tok::l_square:
|
||||
- Close = tok::r_square;
|
||||
- Consumer = &Parser::ConsumeBracket;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- SourceLocation getOpenLocation() const { return LOpen; }
|
||||
- SourceLocation getCloseLocation() const { return LClose; }
|
||||
- SourceRange getRange() const { return SourceRange(LOpen, LClose); }
|
||||
-
|
||||
- bool consumeOpen() {
|
||||
- if (!P.Tok.is(Kind))
|
||||
- return true;
|
||||
-
|
||||
- if (getDepth() < P.getLangOpts().BracketDepth) {
|
||||
- LOpen = (P.*Consumer)();
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- return diagnoseOverflow();
|
||||
- }
|
||||
-
|
||||
- bool expectAndConsume(unsigned DiagID,
|
||||
- const char *Msg = "",
|
||||
- tok::TokenKind SkipToTok = tok::unknown);
|
||||
- bool consumeClose() {
|
||||
- if (P.Tok.is(Close)) {
|
||||
- LClose = (P.*Consumer)();
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- return diagnoseMissingClose();
|
||||
- }
|
||||
- void skipToEnd();
|
||||
- };
|
||||
-
|
||||
-} // end namespace clang
|
||||
-
|
||||
-#endif
|
||||
|
@ -1,38 +0,0 @@
|
||||
Index: tools/clang/lib/Sema/Sema.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/Sema.cpp (revision 47812)
|
||||
+++ tools/clang/lib/Sema/Sema.cpp (working copy)
|
||||
@@ -572,7 +572,8 @@
|
||||
|
||||
if (TUKind == TU_Prefix) {
|
||||
// Translation unit prefixes don't need any of the checking below.
|
||||
- TUScope = 0;
|
||||
+ if (!PP.isIncrementalProcessingEnabled())
|
||||
+ TUScope = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -754,7 +755,8 @@
|
||||
assert(ParsingInitForAutoVars.empty() &&
|
||||
"Didn't unmark var as having its initializer parsed");
|
||||
|
||||
- TUScope = 0;
|
||||
+ if (!PP.isIncrementalProcessingEnabled())
|
||||
+ TUScope = 0;
|
||||
}
|
||||
|
||||
|
||||
Index: tools/clang/lib/Parse/Parser.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Parse/Parser.cpp (revision 47812)
|
||||
+++ tools/clang/lib/Parse/Parser.cpp (working copy)
|
||||
@@ -564,8 +564,7 @@
|
||||
// Late template parsing can begin.
|
||||
if (getLangOpts().DelayedTemplateParsing)
|
||||
Actions.SetLateTemplateParser(LateTemplateParserCallback, this);
|
||||
- if (!PP.isIncrementalProcessingEnabled())
|
||||
- Actions.ActOnEndOfTranslationUnit();
|
||||
+ Actions.ActOnEndOfTranslationUnit();
|
||||
//else don't tell Sema that we ended parsing: more input might come.
|
||||
|
||||
return true;
|
11
patches/llvm-PathMagicDLL.diff
Normal file
11
patches/llvm-PathMagicDLL.diff
Normal file
@ -0,0 +1,11 @@
|
||||
--- /home/axel/build/cling/src/./lib/Support/PathV2.cpp 2013-04-24 21:58:01.343752243 +0200
|
||||
+++ ./lib/Support/PathV2.cpp 2013-04-24 19:40:23.077428890 +0200
|
||||
@@ -884,7 +884,7 @@
|
||||
}
|
||||
|
||||
error_code identify_magic(const Twine &path, file_magic &result) {
|
||||
- SmallString<32> Magic;
|
||||
+ SmallString<512> Magic;
|
||||
error_code ec = get_magic(path, Magic.capacity(), Magic);
|
||||
if (ec && ec != errc::value_too_large)
|
||||
return ec;
|
@ -1,13 +0,0 @@
|
||||
Index: configure
|
||||
===================================================================
|
||||
--- configure (revision 47359)
|
||||
+++ configure (working copy)
|
||||
@@ -21042,7 +21042,7 @@
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
- llvm_cv_cxx_visibility_inlines_hidden=yes
|
||||
+ llvm_cv_cxx_visibility_inlines_hidden=no
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
@ -1,14 +0,0 @@
|
||||
Index: include/llvm/Support/DynamicLibrary.h
|
||||
===================================================================
|
||||
--- include/llvm/Support/DynamicLibrary.h (revision 47319)
|
||||
+++ include/llvm/Support/DynamicLibrary.h (working copy)
|
||||
@@ -96,6 +96,9 @@ namespace sys {
|
||||
/// libraries.
|
||||
/// @brief Add searchable symbol/value pair.
|
||||
static void AddSymbol(StringRef symbolName, void *symbolValue);
|
||||
+
|
||||
+ bool operator<(const DynamicLibrary& Other) const { return Data < Other.Data; }
|
||||
+ bool operator==(const DynamicLibrary& Other) const { return Data == Other.Data; }
|
||||
};
|
||||
|
||||
} // End sys namespace
|
@ -1,827 +0,0 @@
|
||||
Index: tools/clang/include/clang/Sema/Sema.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Sema/Sema.h (revision 165095)
|
||||
+++ tools/clang/include/clang/Sema/Sema.h (working copy)
|
||||
@@ -190,6 +190,13 @@
|
||||
Sema(const Sema &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const Sema &) LLVM_DELETED_FUNCTION;
|
||||
mutable const TargetAttributesSema* TheTargetAttributesSema;
|
||||
+
|
||||
+ ///\brief Source of additional semantic information.
|
||||
+ ExternalSemaSource *ExternalSource;
|
||||
+
|
||||
+ ///\brief Whether Sema has generated a multiplexer and has to delete it.
|
||||
+ bool isMultiplexExternalSource;
|
||||
+
|
||||
public:
|
||||
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
|
||||
typedef OpaquePtr<TemplateName> TemplateTy;
|
||||
@@ -208,9 +215,6 @@
|
||||
/// \brief Flag indicating whether or not to collect detailed statistics.
|
||||
bool CollectStats;
|
||||
|
||||
- /// \brief Source of additional semantic information.
|
||||
- ExternalSemaSource *ExternalSource;
|
||||
-
|
||||
/// \brief Code-completion consumer.
|
||||
CodeCompleteConsumer *CodeCompleter;
|
||||
|
||||
@@ -770,7 +774,15 @@
|
||||
ASTContext &getASTContext() const { return Context; }
|
||||
ASTConsumer &getASTConsumer() const { return Consumer; }
|
||||
ASTMutationListener *getASTMutationListener() const;
|
||||
+ ExternalSemaSource* getExternalSource() const { return ExternalSource; }
|
||||
|
||||
+ ///\brief Registers an external source. If an external source already exists,
|
||||
+ /// creates a multiplex external source and appends to it.
|
||||
+ ///
|
||||
+ ///\param[in] E - A non-null external sema source.
|
||||
+ ///
|
||||
+ void addExternalSource(ExternalSemaSource *E);
|
||||
+
|
||||
void PrintStats() const;
|
||||
|
||||
/// \brief Helper class that creates diagnostics with optional
|
||||
Index: tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h
|
||||
===================================================================
|
||||
--- tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h (revision 0)
|
||||
+++ tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h (revision 0)
|
||||
@@ -0,0 +1,367 @@
|
||||
+//===--- MultiplexExternalSemaSource.h - External Sema Interface-*- 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 ExternalSemaSource interface, dispatching to all clients
|
||||
+//
|
||||
+//===----------------------------------------------------------------------===//
|
||||
+#ifndef LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
+#define LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
+
|
||||
+#include "clang/Sema/ExternalSemaSource.h"
|
||||
+#include "clang/Sema/Weak.h"
|
||||
+
|
||||
+#include "llvm/ADT/SmallVector.h"
|
||||
+
|
||||
+#include <utility>
|
||||
+
|
||||
+namespace clang {
|
||||
+
|
||||
+ class CXXConstructorDecl;
|
||||
+ class CXXRecordDecl;
|
||||
+ class DeclaratorDecl;
|
||||
+ struct ExternalVTableUse;
|
||||
+ class LookupResult;
|
||||
+ class NamespaceDecl;
|
||||
+ class Scope;
|
||||
+ class Sema;
|
||||
+ class TypedefNameDecl;
|
||||
+ class ValueDecl;
|
||||
+ class VarDecl;
|
||||
+
|
||||
+
|
||||
+/// \brief An abstract interface that should be implemented by
|
||||
+/// external AST sources that also provide information for semantic
|
||||
+/// analysis.
|
||||
+class MultiplexExternalSemaSource : public ExternalSemaSource {
|
||||
+
|
||||
+private:
|
||||
+ llvm::SmallVector<ExternalSemaSource*, 2> Sources; // doesn't own them.
|
||||
+
|
||||
+public:
|
||||
+
|
||||
+ ///\brief Constructs a new multiplexing external sema source and appends the
|
||||
+ /// given element to it.
|
||||
+ ///
|
||||
+ ///\param[in] s1 - A non-null (old) ExternalSemaSource.
|
||||
+ ///\param[in] s2 - A non-null (new) ExternalSemaSource.
|
||||
+ ///
|
||||
+ MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2);
|
||||
+
|
||||
+ ~MultiplexExternalSemaSource();
|
||||
+
|
||||
+ ///\brief Appends new source to the source list.
|
||||
+ ///
|
||||
+ ///\param[in] source - An ExternalSemaSource.
|
||||
+ ///
|
||||
+ void addSource(ExternalSemaSource &source);
|
||||
+
|
||||
+ //===--------------------------------------------------------------------===//
|
||||
+ // ExternalASTSource.
|
||||
+ //===--------------------------------------------------------------------===//
|
||||
+
|
||||
+ /// \brief Resolve a declaration ID into a declaration, potentially
|
||||
+ /// building a new declaration.
|
||||
+ ///
|
||||
+ /// This method only needs to be implemented if the AST source ever
|
||||
+ /// passes back decl sets as VisibleDeclaration objects.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual Decl *GetExternalDecl(uint32_t ID);
|
||||
+
|
||||
+ /// \brief Resolve a selector ID into a selector.
|
||||
+ ///
|
||||
+ /// This operation only needs to be implemented if the AST source
|
||||
+ /// returns non-zero for GetNumKnownSelectors().
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual Selector GetExternalSelector(uint32_t ID);
|
||||
+
|
||||
+ /// \brief Returns the number of selectors known to the external AST
|
||||
+ /// source.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual uint32_t GetNumExternalSelectors();
|
||||
+
|
||||
+ /// \brief Resolve the offset of a statement in the decl stream into
|
||||
+ /// a statement.
|
||||
+ ///
|
||||
+ /// This operation is meant to be used via a LazyOffsetPtr. It only
|
||||
+ /// needs to be implemented if the AST source uses methods like
|
||||
+ /// FunctionDecl::setLazyBody when building decls.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
|
||||
+
|
||||
+ /// \brief Resolve the offset of a set of C++ base specifiers in the decl
|
||||
+ /// stream into an array of specifiers.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
|
||||
+
|
||||
+ /// \brief Finds all declarations with the given name in the
|
||||
+ /// given context.
|
||||
+ ///
|
||||
+ /// Generally the final step of this method is either to call
|
||||
+ /// SetExternalVisibleDeclsForName or to recursively call lookup on
|
||||
+ /// the DeclContext after calling SetExternalVisibleDecls.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual DeclContextLookupResult
|
||||
+ FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
|
||||
+
|
||||
+ /// \brief Ensures that the table of all visible declarations inside this
|
||||
+ /// context is up to date.
|
||||
+ ///
|
||||
+ /// The default implementation of this functino is a no-op.
|
||||
+ virtual void completeVisibleDeclsMap(const DeclContext *DC);
|
||||
+
|
||||
+ /// \brief Finds all declarations lexically contained within the given
|
||||
+ /// DeclContext, after applying an optional filter predicate.
|
||||
+ ///
|
||||
+ /// \param isKindWeWant a predicate function that returns true if the passed
|
||||
+ /// declaration kind is one we are looking for. If NULL, all declarations
|
||||
+ /// are returned.
|
||||
+ ///
|
||||
+ /// \return an indication of whether the load succeeded or failed.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
+ bool (*isKindWeWant)(Decl::Kind),
|
||||
+ SmallVectorImpl<Decl*> &Result);
|
||||
+
|
||||
+ /// \brief Finds all declarations lexically contained within the given
|
||||
+ /// DeclContext.
|
||||
+ ///
|
||||
+ /// \return true if an error occurred
|
||||
+ ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
+ SmallVectorImpl<Decl*> &Result) {
|
||||
+ return FindExternalLexicalDecls(DC, 0, Result);
|
||||
+ }
|
||||
+
|
||||
+ template <typename DeclTy>
|
||||
+ ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
|
||||
+ SmallVectorImpl<Decl*> &Result) {
|
||||
+ return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
|
||||
+ }
|
||||
+
|
||||
+ /// \brief Get the decls that are contained in a file in the Offset/Length
|
||||
+ /// range. \p Length can be 0 to indicate a point at \p Offset instead of
|
||||
+ /// a range.
|
||||
+ virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
|
||||
+ SmallVectorImpl<Decl *> &Decls);
|
||||
+
|
||||
+ /// \brief Gives the external AST source an opportunity to complete
|
||||
+ /// an incomplete type.
|
||||
+ virtual void CompleteType(TagDecl *Tag);
|
||||
+
|
||||
+ /// \brief Gives the external AST source an opportunity to complete an
|
||||
+ /// incomplete Objective-C class.
|
||||
+ ///
|
||||
+ /// This routine will only be invoked if the "externally completed" bit is
|
||||
+ /// set on the ObjCInterfaceDecl via the function
|
||||
+ /// \c ObjCInterfaceDecl::setExternallyCompleted().
|
||||
+ virtual void CompleteType(ObjCInterfaceDecl *Class);
|
||||
+
|
||||
+ /// \brief Loads comment ranges.
|
||||
+ virtual void ReadComments();
|
||||
+
|
||||
+ /// \brief Notify ExternalASTSource that we started deserialization of
|
||||
+ /// a decl or type so until FinishedDeserializing is called there may be
|
||||
+ /// decls that are initializing. Must be paired with FinishedDeserializing.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual void StartedDeserializing();
|
||||
+
|
||||
+ /// \brief Notify ExternalASTSource that we finished the deserialization of
|
||||
+ /// a decl or type. Must be paired with StartedDeserializing.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual void FinishedDeserializing();
|
||||
+
|
||||
+ /// \brief Function that will be invoked when we begin parsing a new
|
||||
+ /// translation unit involving this external AST source.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual void StartTranslationUnit(ASTConsumer *Consumer);
|
||||
+
|
||||
+ /// \brief Print any statistics that have been gathered regarding
|
||||
+ /// the external AST source.
|
||||
+ ///
|
||||
+ /// The default implementation of this method is a no-op.
|
||||
+ virtual void PrintStats();
|
||||
+
|
||||
+
|
||||
+ /// \brief Perform layout on the given record.
|
||||
+ ///
|
||||
+ /// This routine allows the external AST source to provide an specific
|
||||
+ /// layout for a record, overriding the layout that would normally be
|
||||
+ /// constructed. It is intended for clients who receive specific layout
|
||||
+ /// details rather than source code (such as LLDB). The client is expected
|
||||
+ /// to fill in the field offsets, base offsets, virtual base offsets, and
|
||||
+ /// complete object size.
|
||||
+ ///
|
||||
+ /// \param Record The record whose layout is being requested.
|
||||
+ ///
|
||||
+ /// \param Size The final size of the record, in bits.
|
||||
+ ///
|
||||
+ /// \param Alignment The final alignment of the record, in bits.
|
||||
+ ///
|
||||
+ /// \param FieldOffsets The offset of each of the fields within the record,
|
||||
+ /// expressed in bits. All of the fields must be provided with offsets.
|
||||
+ ///
|
||||
+ /// \param BaseOffsets The offset of each of the direct, non-virtual base
|
||||
+ /// classes. If any bases are not given offsets, the bases will be laid
|
||||
+ /// out according to the ABI.
|
||||
+ ///
|
||||
+ /// \param VirtualBaseOffsets The offset of each of the virtual base classes
|
||||
+ /// (either direct or not). If any bases are not given offsets, the bases will
|
||||
+ /// be laid out according to the ABI.
|
||||
+ ///
|
||||
+ /// \returns true if the record layout was provided, false otherwise.
|
||||
+ virtual bool
|
||||
+ 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);
|
||||
+
|
||||
+ /// Return the amount of memory used by memory buffers, breaking down
|
||||
+ /// by heap-backed versus mmap'ed memory.
|
||||
+ virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
|
||||
+
|
||||
+ //===--------------------------------------------------------------------===//
|
||||
+ // ExternalSemaSource.
|
||||
+ //===--------------------------------------------------------------------===//
|
||||
+
|
||||
+ /// \brief Initialize the semantic source with the Sema instance
|
||||
+ /// being used to perform semantic analysis on the abstract syntax
|
||||
+ /// tree.
|
||||
+ virtual void InitializeSema(Sema &S);
|
||||
+
|
||||
+ /// \brief Inform the semantic consumer that Sema is no longer available.
|
||||
+ virtual void ForgetSema();
|
||||
+
|
||||
+ /// \brief Load the contents of the global method pool for a given
|
||||
+ /// selector.
|
||||
+ virtual void ReadMethodPool(Selector Sel);
|
||||
+
|
||||
+ /// \brief Load the set of namespaces that are known to the external source,
|
||||
+ /// which will be used during typo correction.
|
||||
+ virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
|
||||
+
|
||||
+ /// \brief Do last resort, unqualified lookup on a LookupResult that
|
||||
+ /// Sema cannot find.
|
||||
+ ///
|
||||
+ /// \param R a LookupResult that is being recovered.
|
||||
+ ///
|
||||
+ /// \param S the Scope of the identifier occurrence.
|
||||
+ ///
|
||||
+ /// \return true to tell Sema to recover using the LookupResult.
|
||||
+ virtual bool LookupUnqualified(LookupResult &R, Scope *S);
|
||||
+
|
||||
+ /// \brief Read the set of tentative definitions known to the external Sema
|
||||
+ /// source.
|
||||
+ ///
|
||||
+ /// The external source should append its own tentative definitions to the
|
||||
+ /// given vector of tentative definitions. Note that this routine may be
|
||||
+ /// invoked multiple times; the external source should take care not to
|
||||
+ /// introduce the same declarations repeatedly.
|
||||
+ virtual void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs);
|
||||
+
|
||||
+ /// \brief Read the set of unused file-scope declarations known to the
|
||||
+ /// external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own unused, filed-scope to the
|
||||
+ /// given vector of declarations. Note that this routine may be
|
||||
+ /// invoked multiple times; the external source should take care not to
|
||||
+ /// introduce the same declarations repeatedly.
|
||||
+ virtual void ReadUnusedFileScopedDecls(
|
||||
+ SmallVectorImpl<const DeclaratorDecl*> &Decls);
|
||||
+
|
||||
+ /// \brief Read the set of delegating constructors known to the
|
||||
+ /// external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own delegating constructors to the
|
||||
+ /// given vector of declarations. Note that this routine may be
|
||||
+ /// invoked multiple times; the external source should take care not to
|
||||
+ /// introduce the same declarations repeatedly.
|
||||
+ virtual void ReadDelegatingConstructors(
|
||||
+ SmallVectorImpl<CXXConstructorDecl*> &Decls);
|
||||
+
|
||||
+ /// \brief Read the set of ext_vector type declarations known to the
|
||||
+ /// external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own ext_vector type declarations to
|
||||
+ /// the given vector of declarations. Note that this routine may be
|
||||
+ /// invoked multiple times; the external source should take care not to
|
||||
+ /// introduce the same declarations repeatedly.
|
||||
+ virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls);
|
||||
+
|
||||
+ /// \brief Read the set of dynamic classes known to the external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own dynamic classes to
|
||||
+ /// the given vector of declarations. Note that this routine may be
|
||||
+ /// invoked multiple times; the external source should take care not to
|
||||
+ /// introduce the same declarations repeatedly.
|
||||
+ virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls);
|
||||
+
|
||||
+ /// \brief Read the set of locally-scoped external declarations known to the
|
||||
+ /// external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own locally-scoped external
|
||||
+ /// declarations to the given vector of declarations. Note that this routine
|
||||
+ /// may be invoked multiple times; the external source should take care not
|
||||
+ /// to introduce the same declarations repeatedly.
|
||||
+ virtual void ReadLocallyScopedExternalDecls(SmallVectorImpl<NamedDecl*>&Decls);
|
||||
+
|
||||
+ /// \brief Read the set of referenced selectors known to the
|
||||
+ /// external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own referenced selectors to the
|
||||
+ /// given vector of selectors. Note that this routine
|
||||
+ /// may be invoked multiple times; the external source should take care not
|
||||
+ /// to introduce the same selectors repeatedly.
|
||||
+ virtual void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
|
||||
+ SourceLocation> > &Sels);
|
||||
+
|
||||
+ /// \brief Read the set of weak, undeclared identifiers known to the
|
||||
+ /// external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own weak, undeclared identifiers to
|
||||
+ /// the given vector. Note that this routine may be invoked multiple times;
|
||||
+ /// the external source should take care not to introduce the same identifiers
|
||||
+ /// repeatedly.
|
||||
+ virtual void ReadWeakUndeclaredIdentifiers(
|
||||
+ SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI);
|
||||
+
|
||||
+ /// \brief Read the set of used vtables known to the external Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own used vtables to the given
|
||||
+ /// vector. Note that this routine may be invoked multiple times; the external
|
||||
+ /// source should take care not to introduce the same vtables repeatedly.
|
||||
+ virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables);
|
||||
+
|
||||
+ /// \brief Read the set of pending instantiations known to the external
|
||||
+ /// Sema source.
|
||||
+ ///
|
||||
+ /// The external source should append its own pending instantiations to the
|
||||
+ /// given vector. Note that this routine may be invoked multiple times; the
|
||||
+ /// external source should take care not to introduce the same instantiations
|
||||
+ /// repeatedly.
|
||||
+ virtual void ReadPendingInstantiations(
|
||||
+ SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending);
|
||||
+
|
||||
+ // isa/cast/dyn_cast support
|
||||
+ static bool classof(const MultiplexExternalSemaSource*) { return true; }
|
||||
+ //static bool classof(const ExternalSemaSource*) { return true; }
|
||||
+};
|
||||
+
|
||||
+} // end namespace clang
|
||||
+
|
||||
+#endif // LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
|
||||
Index: tools/clang/lib/Sema/SemaCodeComplete.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/SemaCodeComplete.cpp (revision 165095)
|
||||
+++ tools/clang/lib/Sema/SemaCodeComplete.cpp (working copy)
|
||||
@@ -5339,11 +5339,11 @@
|
||||
|
||||
// If we have an external source, load the entire class method
|
||||
// pool from the AST file.
|
||||
- if (SemaRef.ExternalSource) {
|
||||
+ if (SemaRef.getExternalSource()) {
|
||||
for (uint32_t I = 0,
|
||||
- N = SemaRef.ExternalSource->GetNumExternalSelectors();
|
||||
+ N = SemaRef.getExternalSource()->GetNumExternalSelectors();
|
||||
I != N; ++I) {
|
||||
- Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
|
||||
+ Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I);
|
||||
if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
|
||||
continue;
|
||||
|
||||
Index: tools/clang/lib/Sema/SemaDeclObjC.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/SemaDeclObjC.cpp (revision 165095)
|
||||
+++ tools/clang/lib/Sema/SemaDeclObjC.cpp (working copy)
|
||||
@@ -2582,7 +2582,7 @@
|
||||
// with this selector before.
|
||||
Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector);
|
||||
if (it == S.MethodPool.end()) {
|
||||
- if (!S.ExternalSource) return;
|
||||
+ if (!S.getExternalSource()) return;
|
||||
S.ReadMethodPool(selector);
|
||||
|
||||
it = S.MethodPool.find(selector);
|
||||
Index: tools/clang/lib/Sema/MultiplexExternalSemaSource.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/MultiplexExternalSemaSource.cpp (revision 0)
|
||||
+++ tools/clang/lib/Sema/MultiplexExternalSemaSource.cpp (revision 0)
|
||||
@@ -0,0 +1,271 @@
|
||||
+//===--- 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.
|
||||
+///
|
||||
+///\param[in] source - An ExternalSemaSource.
|
||||
+///
|
||||
+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 0;
|
||||
+}
|
||||
+
|
||||
+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 0;
|
||||
+}
|
||||
+
|
||||
+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 0;
|
||||
+}
|
||||
+
|
||||
+DeclContextLookupResult MultiplexExternalSemaSource::
|
||||
+FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
|
||||
+ StoredDeclsList DeclsFound;
|
||||
+ DeclContextLookupResult lookup;
|
||||
+ for(size_t i = 0; i < Sources.size(); ++i) {
|
||||
+ lookup = Sources[i]->FindExternalVisibleDeclsByName(DC, Name);
|
||||
+ while(lookup.first != lookup.second) {
|
||||
+ if (!DeclsFound.HandleRedeclaration(*lookup.first))
|
||||
+ DeclsFound.AddSubsequentDecl(*lookup.first);
|
||||
+ lookup.first++;
|
||||
+ }
|
||||
+ }
|
||||
+ return DeclsFound.getLookupResult();
|
||||
+}
|
||||
+
|
||||
+void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
|
||||
+ for(size_t i = 0; i < Sources.size(); ++i)
|
||||
+ Sources[i]->completeVisibleDeclsMap(DC);
|
||||
+}
|
||||
+
|
||||
+ExternalLoadResult MultiplexExternalSemaSource::
|
||||
+FindExternalLexicalDecls(const DeclContext *DC,
|
||||
+ bool (*isKindWeWant)(Decl::Kind),
|
||||
+ SmallVectorImpl<Decl*> &Result) {
|
||||
+ for(size_t i = 0; i < Sources.size(); ++i)
|
||||
+ // FIXME: The semantics of the return result is unclear to me...
|
||||
+ Sources[i]->FindExternalLexicalDecls(DC, isKindWeWant, Result);
|
||||
+
|
||||
+ return ELR_Success;
|
||||
+}
|
||||
+
|
||||
+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::ReadKnownNamespaces(
|
||||
+ SmallVectorImpl<NamespaceDecl*> &Namespaces){
|
||||
+ for(size_t i = 0; i < Sources.size(); ++i)
|
||||
+ Sources[i]->ReadKnownNamespaces(Namespaces);
|
||||
+}
|
||||
+
|
||||
+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::ReadDynamicClasses(
|
||||
+ SmallVectorImpl<CXXRecordDecl*> &Decls) {
|
||||
+ for(size_t i = 0; i < Sources.size(); ++i)
|
||||
+ Sources[i]->ReadDynamicClasses(Decls);
|
||||
+}
|
||||
+
|
||||
+void MultiplexExternalSemaSource::ReadLocallyScopedExternalDecls(
|
||||
+ SmallVectorImpl<NamedDecl*> &Decls) {
|
||||
+ for(size_t i = 0; i < Sources.size(); ++i)
|
||||
+ Sources[i]->ReadLocallyScopedExternalDecls(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);
|
||||
+}
|
||||
Index: tools/clang/lib/Sema/CMakeLists.txt
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/CMakeLists.txt (revision 165095)
|
||||
+++ tools/clang/lib/Sema/CMakeLists.txt (working copy)
|
||||
@@ -13,6 +13,7 @@
|
||||
DelayedDiagnostic.cpp
|
||||
IdentifierResolver.cpp
|
||||
JumpDiagnostics.cpp
|
||||
+ MultiplexExternalSemaSource.cpp
|
||||
Scope.cpp
|
||||
ScopeInfo.cpp
|
||||
Sema.cpp
|
||||
Index: tools/clang/lib/Sema/SemaExprMember.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/SemaExprMember.cpp (revision 165095)
|
||||
+++ tools/clang/lib/Sema/SemaExprMember.cpp (working copy)
|
||||
@@ -354,7 +354,7 @@
|
||||
// Now look up the TypeDefDecl from the vector type. Without this,
|
||||
// diagostics look bad. We want extended vector types to appear built-in.
|
||||
for (Sema::ExtVectorDeclsType::iterator
|
||||
- I = S.ExtVectorDecls.begin(S.ExternalSource),
|
||||
+ I = S.ExtVectorDecls.begin(S.getExternalSource()),
|
||||
E = S.ExtVectorDecls.end();
|
||||
I != E; ++I) {
|
||||
if ((*I)->getUnderlyingType() == VT)
|
||||
Index: tools/clang/lib/Sema/Sema.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Sema/Sema.cpp (revision 165095)
|
||||
+++ tools/clang/lib/Sema/Sema.cpp (working copy)
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "clang/Sema/CXXFieldCollector.h"
|
||||
#include "clang/Sema/TemplateDeduction.h"
|
||||
#include "clang/Sema/ExternalSemaSource.h"
|
||||
+#include "clang/Sema/MultiplexExternalSemaSource.h"
|
||||
#include "clang/Sema/ObjCMethodList.h"
|
||||
#include "clang/Sema/PrettyDeclStackTrace.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
@@ -68,10 +69,11 @@
|
||||
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
||||
TranslationUnitKind TUKind,
|
||||
CodeCompleteConsumer *CodeCompleter)
|
||||
- : TheTargetAttributesSema(0), FPFeatures(pp.getLangOpts()),
|
||||
+ : TheTargetAttributesSema(0), ExternalSource(0),
|
||||
+ isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
|
||||
LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
|
||||
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
|
||||
- CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter),
|
||||
+ CollectStats(false), CodeCompleter(CodeCompleter),
|
||||
CurContext(0), OriginalLexicalContext(0),
|
||||
PackContext(0), MSStructPragmaOn(false), VisContext(0),
|
||||
IsBuildingRecoveryCallExpr(false),
|
||||
@@ -188,6 +190,10 @@
|
||||
if (ExternalSemaSource *ExternalSema
|
||||
= dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
|
||||
ExternalSema->ForgetSema();
|
||||
+
|
||||
+ // If Sema's ExternalSource is the multiplexer - we own it.
|
||||
+ if (isMultiplexExternalSource)
|
||||
+ delete ExternalSource;
|
||||
}
|
||||
|
||||
/// makeUnavailableInSystemHeader - There is an error in the current
|
||||
@@ -219,6 +225,27 @@
|
||||
return getASTConsumer().GetASTMutationListener();
|
||||
}
|
||||
|
||||
+///\brief Registers an external source. If an external source already exists,
|
||||
+/// creates a multiplex external source and appends to it.
|
||||
+///
|
||||
+///\param[in] E - A non-null external sema source.
|
||||
+///
|
||||
+void Sema::addExternalSource(ExternalSemaSource *E) {
|
||||
+ assert(E && "Cannot use with NULL ptr");
|
||||
+
|
||||
+ if (!ExternalSource) {
|
||||
+ ExternalSource = E;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (isMultiplexExternalSource)
|
||||
+ static_cast<MultiplexExternalSemaSource*>(ExternalSource)->addSource(*E);
|
||||
+ else {
|
||||
+ ExternalSource = new MultiplexExternalSemaSource(*ExternalSource, *E);
|
||||
+ isMultiplexExternalSource = true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/// \brief Print out statistics about the semantic analysis.
|
||||
void Sema::PrintStats() const {
|
||||
llvm::errs() << "\n*** Semantic Analysis Stats:\n";
|
||||
Index: tools/clang/lib/Serialization/ASTReader.cpp
|
||||
===================================================================
|
||||
--- tools/clang/lib/Serialization/ASTReader.cpp (revision 165095)
|
||||
+++ tools/clang/lib/Serialization/ASTReader.cpp (working copy)
|
||||
@@ -5289,7 +5289,7 @@
|
||||
|
||||
void ASTReader::InitializeSema(Sema &S) {
|
||||
SemaObj = &S;
|
||||
- S.ExternalSource = this;
|
||||
+ S.addExternalSource(this);
|
||||
|
||||
// Makes sure any declarations that were deserialized "too early"
|
||||
// still get added to the identifier's declaration chains.
|
@ -1,645 +0,0 @@
|
||||
Index: include/llvm/Support/DynamicLibrary.h
|
||||
===================================================================
|
||||
--- include/llvm/Support/DynamicLibrary.h (revision 167609)
|
||||
+++ include/llvm/Support/DynamicLibrary.h (working copy)
|
||||
@@ -91,6 +91,13 @@ namespace sys {
|
||||
return SearchForAddressOfSymbol(symbolName.c_str());
|
||||
}
|
||||
|
||||
+ /// This function will search through all previously loaded dynamic
|
||||
+ /// libraries for the symbol \p symbolName, but not through explicitly
|
||||
+ /// provided symbols (AddSymbol()). If it is found, the address of
|
||||
+ /// that symbol is returned. If not, null is returned.
|
||||
+ /// @brief Search through libraries for address of a symbol
|
||||
+ static void *SearchForLibrarySymbol(const char *SymbolName);
|
||||
+
|
||||
/// This functions permanently adds the symbol \p symbolName with the
|
||||
/// value \p symbolValue. These symbols are searched before any
|
||||
/// libraries.
|
||||
Index: lib/Support/Unix/DynamicLibrary.inc
|
||||
===================================================================
|
||||
--- lib/Support/Unix/DynamicLibrary.inc (revision 0)
|
||||
+++ lib/Support/Unix/DynamicLibrary.inc (revision 0)
|
||||
@@ -0,0 +1,118 @@
|
||||
+//===--- Unix/DynamicLibrary.cpp - Unix DL Implementation -------*- C++ -*-===//
|
||||
+//
|
||||
+// The LLVM Compiler Infrastructure
|
||||
+//
|
||||
+// This file is distributed under the University of Illinois Open Source
|
||||
+// License. See LICENSE.TXT for details.
|
||||
+//
|
||||
+//===----------------------------------------------------------------------===//
|
||||
+//
|
||||
+// This file provides the dlsym specific implementation of DynamicLibrary.
|
||||
+//
|
||||
+//===----------------------------------------------------------------------===//
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+
|
||||
+static void MakeDlErrMsg(std::string *ErrMsg) {
|
||||
+ if (ErrMsg) {
|
||||
+ *ErrMsg = dlerror();
|
||||
+ } else {
|
||||
+ // Flush error state whether or not ErrMsg is provided.
|
||||
+ dlerror();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void *OpenLibraryImpl(const char *Filename, std::string *ErrMsg) {
|
||||
+ void *Handle = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL);
|
||||
+ if (Handle == 0) {
|
||||
+ MakeDlErrMsg(ErrMsg);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+#ifdef __CYGWIN__
|
||||
+ // Cygwin searches symbols only in the main
|
||||
+ // with the handle of dlopen(NULL, RTLD_GLOBAL).
|
||||
+ if (Filename == NULL)
|
||||
+ Handle = RTLD_DEFAULT;
|
||||
+#endif
|
||||
+ return Handle;
|
||||
+}
|
||||
+
|
||||
+bool CloseLibraryImpl(void *DlHandle, std::string *ErrMsg) {
|
||||
+ if (dlclose(DlHandle)) {
|
||||
+ MakeDlErrMsg(ErrMsg);
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+void *GetAddressOfSymbolImpl(void *DlHandle, const char *SymbolName,
|
||||
+ bool /*Global*/) {
|
||||
+ return dlsym(DlHandle, SymbolName);
|
||||
+}
|
||||
+
|
||||
+#include <string.h>
|
||||
+
|
||||
+// Must declare the symbols in the global namespace.
|
||||
+void PopulateSpecialSymbolsImpl(StringMap<void *>& SymMap) {
|
||||
+// This macro returns the address of a well-known, explicit symbol
|
||||
+#define EXPLICIT_SYMBOL(SYM) \
|
||||
+ SymMap[#SYM] = &SYM
|
||||
+
|
||||
+// On linux we have a weird situation. The stderr/out/in symbols are both
|
||||
+// macros and global variables because of standards requirements. So, we
|
||||
+// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
|
||||
+#if defined(__linux__) and !defined(__ANDROID__)
|
||||
+ {
|
||||
+ EXPLICIT_SYMBOL(stderr);
|
||||
+ EXPLICIT_SYMBOL(stdout);
|
||||
+ EXPLICIT_SYMBOL(stdin);
|
||||
+ }
|
||||
+#else
|
||||
+ // For everything else, we want to check to make sure the symbol isn't defined
|
||||
+ // as a macro before using EXPLICIT_SYMBOL.
|
||||
+ {
|
||||
+#ifndef stdin
|
||||
+ EXPLICIT_SYMBOL(stdin);
|
||||
+#endif
|
||||
+#ifndef stdout
|
||||
+ EXPLICIT_SYMBOL(stdout);
|
||||
+#endif
|
||||
+#ifndef stderr
|
||||
+ EXPLICIT_SYMBOL(stderr);
|
||||
+#endif
|
||||
+ }
|
||||
+#endif
|
||||
+#undef EXPLICIT_SYMBOL
|
||||
+
|
||||
+#define EXPLICIT_SYMBOL(SYM) \
|
||||
+ extern "C" void *SYM; symMap[#SYM] = &SYM
|
||||
+
|
||||
+ // If this is darwin, it has some funky issues, try to solve them here. Some
|
||||
+ // important symbols are marked 'private external' which doesn't allow
|
||||
+ // SearchForAddressOfSymbol to find them. As such, we special case them here,
|
||||
+ // there is only a small handful of them.
|
||||
+
|
||||
+#ifdef __APPLE__
|
||||
+ {
|
||||
+ // __eprintf is sometimes used for assert() handling on x86.
|
||||
+ //
|
||||
+ // FIXME: Currently disabled when using Clang, as we don't always have our
|
||||
+ // runtime support libraries available.
|
||||
+#ifndef __clang__
|
||||
+#ifdef __i386__
|
||||
+ EXPLICIT_SYMBOL(__eprintf);
|
||||
+#endif
|
||||
+#endif
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+#ifdef __CYGWIN__
|
||||
+ {
|
||||
+ EXPLICIT_SYMBOL(_alloca);
|
||||
+ EXPLICIT_SYMBOL(__main);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+#undef EXPLICIT_SYMBOL
|
||||
+}
|
||||
Index: lib/Support/DynamicLibrary.cpp
|
||||
===================================================================
|
||||
--- lib/Support/DynamicLibrary.cpp (revision 167609)
|
||||
+++ lib/Support/DynamicLibrary.cpp (working copy)
|
||||
@@ -9,7 +9,7 @@
|
||||
//
|
||||
// This header file implements the operating system DynamicLibrary concept.
|
||||
//
|
||||
-// FIXME: This file leaks ExplicitSymbols and OpenedHandles!
|
||||
+// FIXME: This file leaks OpenedHandles!
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -21,11 +21,45 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
-// Collection of symbol name/value pairs to be searched prior to any libraries.
|
||||
-static llvm::StringMap<void *> *ExplicitSymbols = 0;
|
||||
+using namespace llvm;
|
||||
+using namespace llvm::sys;
|
||||
+
|
||||
+// Platform-specific implementations are required to define these function.
|
||||
+// They do not need to be reentrant; locking is done by the caller.
|
||||
|
||||
+// Open the shared library called filename and return its handle. If filename
|
||||
+// is NULL, return a handle for searching symbols in the whole process.
|
||||
+static void *OpenLibraryImpl(const char *Filename, std::string *ErrMsg);
|
||||
+// Close the shared library.
|
||||
+static bool CloseLibraryImpl(void *DlHandle, std::string *ErrMsg);
|
||||
+// Get the address of the symbol named symname from the library with dlhandle.
|
||||
+// Global is true if this is part of a search spanning all OpenedHandles.
|
||||
+static void *GetAddressOfSymbolImpl(void *DlHandle, const char *SymbolName,
|
||||
+ bool Global);
|
||||
+// Inject special platform symbols into the map of explicitly defined symbols.
|
||||
+static void PopulateSpecialSymbolsImpl(StringMap<void *>& SymMap);
|
||||
+
|
||||
namespace {
|
||||
|
||||
+struct SpecialSymbolHolder {
|
||||
+ SpecialSymbolHolder() {
|
||||
+ PopulateSpecialSymbolsImpl(Map);
|
||||
+ }
|
||||
+
|
||||
+ // Symbol name/value pairs to be searched prior to any libraries.
|
||||
+ StringMap<void *> Map;
|
||||
+};
|
||||
+
|
||||
+}
|
||||
+
|
||||
+// Platform specific symbols, searched after libraries
|
||||
+static SpecialSymbolHolder *SpecialSymbols = 0;
|
||||
+
|
||||
+// User provided symbols, searched before libraries
|
||||
+static StringMap<void *> *ExplicitSymbols = 0;
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
struct ExplicitSymbolsDeleter {
|
||||
~ExplicitSymbolsDeleter() {
|
||||
delete ExplicitSymbols;
|
||||
@@ -42,148 +76,98 @@ static llvm::sys::SmartMutex<true>& getMutex() {
|
||||
return HandlesMutex;
|
||||
}
|
||||
|
||||
-void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName,
|
||||
- void *symbolValue) {
|
||||
- SmartScopedLock<true> lock(getMutex());
|
||||
- if (ExplicitSymbols == 0)
|
||||
- ExplicitSymbols = new llvm::StringMap<void*>();
|
||||
- (*ExplicitSymbols)[symbolName] = symbolValue;
|
||||
-}
|
||||
-
|
||||
char llvm::sys::DynamicLibrary::Invalid = 0;
|
||||
|
||||
-#ifdef LLVM_ON_WIN32
|
||||
+static DenseSet<void *> *OpenedHandles;
|
||||
|
||||
-#include "Windows/DynamicLibrary.inc"
|
||||
-
|
||||
-#else
|
||||
-
|
||||
-#if HAVE_DLFCN_H
|
||||
-#include <dlfcn.h>
|
||||
-using namespace llvm;
|
||||
-using namespace llvm::sys;
|
||||
-
|
||||
-//===----------------------------------------------------------------------===//
|
||||
-//=== WARNING: Implementation here must contain only TRULY operating system
|
||||
-//=== independent code.
|
||||
-//===----------------------------------------------------------------------===//
|
||||
-
|
||||
-static DenseSet<void *> *OpenedHandles = 0;
|
||||
-
|
||||
-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
|
||||
- std::string *errMsg) {
|
||||
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *Filename,
|
||||
+ std::string *ErrMsg) {
|
||||
SmartScopedLock<true> lock(getMutex());
|
||||
|
||||
- void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
|
||||
- if (handle == 0) {
|
||||
- if (errMsg) *errMsg = dlerror();
|
||||
+ void *Handle = OpenLibraryImpl(Filename, ErrMsg);
|
||||
+ if (Handle == 0) {
|
||||
return DynamicLibrary();
|
||||
}
|
||||
-
|
||||
-#ifdef __CYGWIN__
|
||||
- // Cygwin searches symbols only in the main
|
||||
- // with the handle of dlopen(NULL, RTLD_GLOBAL).
|
||||
- if (filename == NULL)
|
||||
- handle = RTLD_DEFAULT;
|
||||
-#endif
|
||||
-
|
||||
if (OpenedHandles == 0)
|
||||
OpenedHandles = new DenseSet<void *>();
|
||||
|
||||
// If we've already loaded this library, dlclose() the handle in order to
|
||||
// keep the internal refcount at +1.
|
||||
- if (!OpenedHandles->insert(handle).second)
|
||||
- dlclose(handle);
|
||||
+ if (!OpenedHandles->insert(Handle).second)
|
||||
+ CloseLibraryImpl(Handle, 0);
|
||||
|
||||
- return DynamicLibrary(handle);
|
||||
-}
|
||||
+ return DynamicLibrary(Handle);
|
||||
+}
|
||||
|
||||
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
|
||||
- if (!isValid())
|
||||
- return NULL;
|
||||
- return dlsym(Data, symbolName);
|
||||
+void llvm::sys::DynamicLibrary::AddSymbol(StringRef SymbolName,
|
||||
+ void *SymbolValue) {
|
||||
+ SmartScopedLock<true> lock(getMutex());
|
||||
+ if (ExplicitSymbols == 0)
|
||||
+ ExplicitSymbols = new StringMap<void *>();
|
||||
+ (*ExplicitSymbols)[SymbolName] = SymbolValue;
|
||||
}
|
||||
|
||||
-#else
|
||||
-
|
||||
-using namespace llvm;
|
||||
-using namespace llvm::sys;
|
||||
-
|
||||
-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
|
||||
- std::string *errMsg) {
|
||||
- if (errMsg) *errMsg = "dlopen() not supported on this platform";
|
||||
- return DynamicLibrary();
|
||||
+void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) {
|
||||
+ return GetAddressOfSymbolImpl(Data, SymbolName, false /*Global*/);
|
||||
}
|
||||
|
||||
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
|
||||
+void *DynamicLibrary::SearchForLibrarySymbol(const char *SymbolName) {
|
||||
+ if (OpenedHandles) {
|
||||
+ for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
|
||||
+ E = OpenedHandles->end(); I != E; ++I) {
|
||||
+ void *ptr = GetAddressOfSymbolImpl(*I, SymbolName, true /*Global*/);
|
||||
+ if (ptr) {
|
||||
+ return ptr;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-#endif
|
||||
-
|
||||
-namespace llvm {
|
||||
-void *SearchForAddressOfSpecialSymbol(const char* symbolName);
|
||||
-}
|
||||
-
|
||||
-void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
|
||||
+void* DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
|
||||
SmartScopedLock<true> Lock(getMutex());
|
||||
|
||||
// First check symbols added via AddSymbol().
|
||||
if (ExplicitSymbols) {
|
||||
- StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
|
||||
+ StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName);
|
||||
|
||||
if (i != ExplicitSymbols->end())
|
||||
return i->second;
|
||||
}
|
||||
|
||||
-#if HAVE_DLFCN_H
|
||||
// Now search the libraries.
|
||||
- if (OpenedHandles) {
|
||||
- for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
|
||||
- E = OpenedHandles->end(); I != E; ++I) {
|
||||
- //lt_ptr ptr = lt_dlsym(*I, symbolName);
|
||||
- void *ptr = dlsym(*I, symbolName);
|
||||
- if (ptr) {
|
||||
- return ptr;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
+ if (void *ptr = SearchForLibrarySymbol(SymbolName))
|
||||
+ return ptr;
|
||||
|
||||
- if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
|
||||
- return Result;
|
||||
+ // Finally check platform specific symbols.
|
||||
+ if (SpecialSymbols) {
|
||||
+ StringMap<void *>::iterator i = SpecialSymbols->Map.find(SymbolName);
|
||||
|
||||
-// This macro returns the address of a well-known, explicit symbol
|
||||
-#define EXPLICIT_SYMBOL(SYM) \
|
||||
- if (!strcmp(symbolName, #SYM)) return &SYM
|
||||
-
|
||||
-// On linux we have a weird situation. The stderr/out/in symbols are both
|
||||
-// macros and global variables because of standards requirements. So, we
|
||||
-// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
|
||||
-#if defined(__linux__) and !defined(__ANDROID__)
|
||||
- {
|
||||
- EXPLICIT_SYMBOL(stderr);
|
||||
- EXPLICIT_SYMBOL(stdout);
|
||||
- EXPLICIT_SYMBOL(stdin);
|
||||
+ if (i != SpecialSymbols->Map.end())
|
||||
+ return i->second;
|
||||
}
|
||||
-#else
|
||||
- // For everything else, we want to check to make sure the symbol isn't defined
|
||||
- // as a macro before using EXPLICIT_SYMBOL.
|
||||
- {
|
||||
-#ifndef stdin
|
||||
- EXPLICIT_SYMBOL(stdin);
|
||||
-#endif
|
||||
-#ifndef stdout
|
||||
- EXPLICIT_SYMBOL(stdout);
|
||||
-#endif
|
||||
-#ifndef stderr
|
||||
- EXPLICIT_SYMBOL(stderr);
|
||||
-#endif
|
||||
- }
|
||||
-#endif
|
||||
-#undef EXPLICIT_SYMBOL
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef LLVM_ON_WIN32
|
||||
+#include "Windows/DynamicLibrary.inc"
|
||||
+#elif HAVE_DLFCN_H
|
||||
+#include "Unix/DynamicLibrary.inc"
|
||||
+#else
|
||||
+
|
||||
+void *OpenLibraryImpl(const char *, std::string *errMsg) {
|
||||
+ if (errMsg) *errMsg = "dlopen() not supported on this platform";
|
||||
+ return NULL;
|
||||
+ }
|
||||
+bool CloseLibraryImpl(void *, std::string *ErrMsg) {
|
||||
+ if (errMsg) *errMsg = "dlclose() not supported on this platform";
|
||||
+ retun false;
|
||||
+}
|
||||
+void *GetAddressOfSymbolImpl(void *, const char *, bool) {
|
||||
+ return NULL;
|
||||
+}
|
||||
+void PopulateSpecialSymbolsImpl(StringMap<void *>&) {
|
||||
+}
|
||||
+
|
||||
#endif // LLVM_ON_WIN32
|
||||
Index: lib/Support/Windows/DynamicLibrary.inc
|
||||
===================================================================
|
||||
--- lib/Support/Windows/DynamicLibrary.inc (revision 167609)
|
||||
+++ lib/Support/Windows/DynamicLibrary.inc (working copy)
|
||||
@@ -31,16 +31,8 @@
|
||||
#pragma comment(lib, "dbghelp.lib")
|
||||
#endif
|
||||
|
||||
-namespace llvm {
|
||||
-using namespace sys;
|
||||
+using namespace llvm;
|
||||
|
||||
-//===----------------------------------------------------------------------===//
|
||||
-//=== WARNING: Implementation here must contain only Win32 specific code
|
||||
-//=== and must not be UNIX code.
|
||||
-//===----------------------------------------------------------------------===//
|
||||
-
|
||||
-static DenseSet<HMODULE> *OpenedHandles;
|
||||
-
|
||||
extern "C" {
|
||||
|
||||
static BOOL CALLBACK ELM_Callback(WIN32_ELMCB_PCSTR ModuleName,
|
||||
@@ -63,49 +55,61 @@ extern "C" {
|
||||
#endif
|
||||
stricmp(ModuleName, "msvcrt20") != 0 &&
|
||||
stricmp(ModuleName, "msvcrt40") != 0) {
|
||||
- OpenedHandles->insert((HMODULE)ModuleBase);
|
||||
+ OpenedHandles->insert((HMODULE)ModuleBase);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
-}
|
||||
+} // extern "C"
|
||||
|
||||
-DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
|
||||
- std::string *errMsg) {
|
||||
- SmartScopedLock<true> lock(getMutex());
|
||||
-
|
||||
- if (!filename) {
|
||||
+void *OpenLibraryImpl(const char *Filename, std::string *ErrMsg) {
|
||||
+ if (!Filename) {
|
||||
// When no file is specified, enumerate all DLLs and EXEs in the process.
|
||||
if (OpenedHandles == 0)
|
||||
- OpenedHandles = new DenseSet<HMODULE>();
|
||||
+ OpenedHandles = new DenseSet<void *>();
|
||||
|
||||
EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
|
||||
// Dummy library that represents "search all handles".
|
||||
// This is mostly to ensure that the return value still shows up as "valid".
|
||||
- return DynamicLibrary(&OpenedHandles);
|
||||
+ return &OpenedHandles;
|
||||
}
|
||||
|
||||
- HMODULE a_handle = LoadLibrary(filename);
|
||||
+ HMODULE a_handle = LoadLibrary(Filename);
|
||||
|
||||
if (a_handle == 0) {
|
||||
- MakeErrMsg(errMsg, std::string(filename) + ": Can't open : ");
|
||||
- return DynamicLibrary();
|
||||
+ MakeErrMsg(ErrMsg, std::string(Filename) + ": Can't open : ");
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
- if (OpenedHandles == 0)
|
||||
- OpenedHandles = new DenseSet<HMODULE>();
|
||||
+ return (void *)a_handle;
|
||||
+}
|
||||
|
||||
- // If we've already loaded this library, FreeLibrary() the handle in order to
|
||||
- // keep the internal refcount at +1.
|
||||
- if (!OpenedHandles->insert(a_handle).second)
|
||||
- FreeLibrary(a_handle);
|
||||
+bool CloseLibraryImpl(void *DlHandle, std::string *ErrMsg) {
|
||||
+ if (!FreeLibrary((HMODULE)DlHandle)) {
|
||||
+ MakeErrMsg(ErrMsg, "Cannot free DLL: ");
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
|
||||
- return DynamicLibrary(a_handle);
|
||||
+void *GetAddressOfSymbolImpl(void *DlHandle, const char *SymbolName,
|
||||
+ bool Global) {
|
||||
+ if (DlHandle == &OpenedHandles) {
|
||||
+ // Dummy library that represents "search all handles".
|
||||
+ if (Global) {
|
||||
+ // All libraries are already being searched, do not recurse.
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ // Perform a global symbol search through all libraries.
|
||||
+ DynamicLibrary::SearchForLibrarySymbol(SymbolName);
|
||||
+ }
|
||||
+ }
|
||||
+ return (void *)(intptr_t) GetProcAddress((HMODULE)DlHandle, SymbolName);
|
||||
}
|
||||
|
||||
// Stack probing routines are in the support library (e.g. libgcc), but we don't
|
||||
// have dynamic linking on windows. Provide a hook.
|
||||
#define EXPLICIT_SYMBOL(SYM) \
|
||||
- extern "C" { extern void *SYM; }
|
||||
+ extern "C" void *SYM;
|
||||
#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO)
|
||||
|
||||
#include "explicit_symbols.inc"
|
||||
@@ -113,51 +117,13 @@ extern "C" {
|
||||
#undef EXPLICIT_SYMBOL
|
||||
#undef EXPLICIT_SYMBOL2
|
||||
|
||||
-void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
|
||||
- SmartScopedLock<true> Lock(getMutex());
|
||||
+void PopulateSpecialSymbolsImpl(StringMap<void *>& SymMap) {
|
||||
+#define EXPLICIT_SYMBOL(SYM) \
|
||||
+ SymMap[#SYM] = &SYM;
|
||||
+#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO)
|
||||
|
||||
- // First check symbols added via AddSymbol().
|
||||
- if (ExplicitSymbols) {
|
||||
- StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
|
||||
+#include "explicit_symbols.inc"
|
||||
|
||||
- if (i != ExplicitSymbols->end())
|
||||
- return i->second;
|
||||
- }
|
||||
-
|
||||
- // Now search the libraries.
|
||||
- if (OpenedHandles) {
|
||||
- for (DenseSet<HMODULE>::iterator I = OpenedHandles->begin(),
|
||||
- E = OpenedHandles->end(); I != E; ++I) {
|
||||
- FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
|
||||
- if (ptr) {
|
||||
- return (void *)(intptr_t)ptr;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- #define EXPLICIT_SYMBOL(SYM) \
|
||||
- if (!strcmp(symbolName, #SYM)) return (void*)&SYM;
|
||||
- #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
|
||||
- if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO;
|
||||
-
|
||||
- {
|
||||
- #include "explicit_symbols.inc"
|
||||
- }
|
||||
-
|
||||
- #undef EXPLICIT_SYMBOL
|
||||
- #undef EXPLICIT_SYMBOL2
|
||||
-
|
||||
- return 0;
|
||||
+#undef EXPLICIT_SYMBOL
|
||||
+#undef EXPLICIT_SYMBOL2
|
||||
}
|
||||
-
|
||||
-
|
||||
-void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
|
||||
- if (!isValid())
|
||||
- return NULL;
|
||||
- if (Data == &OpenedHandles)
|
||||
- return SearchForAddressOfSymbol(symbolName);
|
||||
- return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-}
|
||||
Index: lib/Support/CMakeLists.txt
|
||||
===================================================================
|
||||
--- lib/Support/CMakeLists.txt (revision 167609)
|
||||
+++ lib/Support/CMakeLists.txt (working copy)
|
||||
@@ -80,6 +80,7 @@ add_llvm_library(LLVMSupport
|
||||
Threading.cpp
|
||||
TimeValue.cpp
|
||||
Valgrind.cpp
|
||||
+ Unix/DynamicLibrary.inc
|
||||
Unix/Host.inc
|
||||
Unix/Memory.inc
|
||||
Unix/Mutex.inc
|
||||
Index: lib/Support/SearchForAddressOfSpecialSymbol.cpp
|
||||
===================================================================
|
||||
--- lib/Support/SearchForAddressOfSpecialSymbol.cpp (revision 167609)
|
||||
+++ lib/Support/SearchForAddressOfSpecialSymbol.cpp (working copy)
|
||||
@@ -1,58 +0,0 @@
|
||||
-//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
|
||||
-//
|
||||
-// The LLVM Compiler Infrastructure
|
||||
-//
|
||||
-// This file is distributed under the University of Illinois Open Source
|
||||
-// License. See LICENSE.TXT for details.
|
||||
-//
|
||||
-//===----------------------------------------------------------------------===//
|
||||
-//
|
||||
-// This file pulls the addresses of certain symbols out of the linker. It must
|
||||
-// include as few header files as possible because it declares the symbols as
|
||||
-// void*, which would conflict with the actual symbol type if any header
|
||||
-// declared it.
|
||||
-//
|
||||
-//===----------------------------------------------------------------------===//
|
||||
-
|
||||
-#include <string.h>
|
||||
-
|
||||
-// Must declare the symbols in the global namespace.
|
||||
-static void *DoSearch(const char* symbolName) {
|
||||
-#define EXPLICIT_SYMBOL(SYM) \
|
||||
- extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
|
||||
-
|
||||
- // If this is darwin, it has some funky issues, try to solve them here. Some
|
||||
- // important symbols are marked 'private external' which doesn't allow
|
||||
- // SearchForAddressOfSymbol to find them. As such, we special case them here,
|
||||
- // there is only a small handful of them.
|
||||
-
|
||||
-#ifdef __APPLE__
|
||||
- {
|
||||
- // __eprintf is sometimes used for assert() handling on x86.
|
||||
- //
|
||||
- // FIXME: Currently disabled when using Clang, as we don't always have our
|
||||
- // runtime support libraries available.
|
||||
-#ifndef __clang__
|
||||
-#ifdef __i386__
|
||||
- EXPLICIT_SYMBOL(__eprintf);
|
||||
-#endif
|
||||
-#endif
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
-#ifdef __CYGWIN__
|
||||
- {
|
||||
- EXPLICIT_SYMBOL(_alloca);
|
||||
- EXPLICIT_SYMBOL(__main);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
-#undef EXPLICIT_SYMBOL
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-namespace llvm {
|
||||
-void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
|
||||
- return DoSearch(symbolName);
|
||||
-}
|
||||
-} // namespace llvm
|
Loading…
x
Reference in New Issue
Block a user