Index: src/IceGlobalInits.h |
diff --git a/src/IceGlobalInits.h b/src/IceGlobalInits.h |
index 8f51db243f02d229ee057634a1d9b3e6e60a5246..82e5cde7131d7d02db78db5be63234a5121920fa 100644 |
--- a/src/IceGlobalInits.h |
+++ b/src/IceGlobalInits.h |
@@ -87,11 +87,29 @@ public: |
return getSuppressMangling() ? Name : Ctx->mangleName(Name); |
} |
+ /// Returns textual name of linkage. |
+ const char *getLinkageName() const { |
+ return isInternal() ? "internal" : "external"; |
+ } |
+ |
protected: |
GlobalDeclaration(GlobalDeclarationKind Kind, |
llvm::GlobalValue::LinkageTypes Linkage) |
: Kind(Kind), Linkage(Linkage) {} |
+ /// Returns true if linkage is defined correctly for the global declaration, |
+ /// based on default rules. |
+ bool verifyLinkageDefault(const GlobalContext *Ctx) const { |
+ switch (Linkage) { |
+ default: |
+ return false; |
+ case llvm::GlobalValue::InternalLinkage: |
+ return true; |
+ case llvm::GlobalValue::ExternalLinkage: |
+ return Ctx->getFlags().getAllowExternDefinedSymbols(); |
+ } |
+ } |
+ |
const GlobalDeclarationKind Kind; |
IceString Name; |
llvm::GlobalValue::LinkageTypes Linkage; |
@@ -124,6 +142,13 @@ public: |
void dump(GlobalContext *Ctx, Ostream &Stream) const final; |
bool getSuppressMangling() const final { return isExternal() && IsProto; } |
+ /// Returns true if linkage is correct for the function declaration. |
+ bool verifyLinkageCorrect(const GlobalContext *Ctx) const { |
+ if (isPNaClABIExternalName() || isIntrinsicName(Ctx)) |
+ return Linkage == llvm::GlobalValue::ExternalLinkage; |
+ return verifyLinkageDefault(Ctx); |
+ } |
+ |
private: |
const Ice::FuncSigType Signature; |
llvm::CallingConv::ID CallingConv; |
@@ -134,6 +159,19 @@ private: |
llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) |
: GlobalDeclaration(FunctionDeclarationKind, Linkage), |
Signature(Signature), CallingConv(CallingConv), IsProto(IsProto) {} |
+ |
+ bool isPNaClABIExternalName() const { |
+ const char *Name = getName().c_str(); |
+ return strcmp(Name, "_start") == 0 || strcmp(Name, "__pnacl_pso_root") == 0; |
+ } |
+ |
+ bool isIntrinsicName(const GlobalContext *Ctx) const { |
+ if (!hasName()) |
+ return false; |
+ bool BadIntrinsic; |
+ return Ctx->getIntrinsicsInfo().find(getName(), BadIntrinsic) && |
+ !BadIntrinsic; |
+ } |
}; |
/// Models a global variable declaration, and its initializers. |
@@ -309,6 +347,11 @@ public: |
/// initialization). |
void dump(GlobalContext *Ctx, Ostream &Stream) const final; |
+ /// Returns true if linkage is correct for the variable declaration. |
+ bool verifyLinkageCorrect(const GlobalContext *Ctx) const { |
+ return verifyLinkageDefault(Ctx); |
+ } |
+ |
static bool classof(const GlobalDeclaration *Addr) { |
return Addr->getKind() == VariableDeclarationKind; |
} |