#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SanitizerBlacklist.h"
+#include "clang/Basic/XRayLists.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
class CoverageMappingModuleGen;
class TargetCodeGenInfo;
+enum ForDefinition_t : bool {
+ NotForDefinition = false,
+ ForDefinition = true
+};
+
struct OrderGlobalInits {
unsigned int priority;
unsigned int lex_order;
/// void objc_release(id);
llvm::Constant *objc_release;
- /// id objc_storeStrong(id*, id);
+ /// void objc_storeStrong(id*, id);
llvm::Constant *objc_storeStrong;
/// id objc_storeWeak(id*, id);
/// List of global values which are required to be present in the object file;
/// bitcast to i8*. This is used for forcing visibility of symbols which may
/// otherwise be optimized out.
- std::vector<llvm::WeakVH> LLVMUsed;
- std::vector<llvm::WeakVH> LLVMCompilerUsed;
+ std::vector<llvm::WeakTrackingVH> LLVMUsed;
+ std::vector<llvm::WeakTrackingVH> LLVMCompilerUsed;
/// Store the list of global constructors and their respective priorities to
/// be emitted when the translation unit is complete.
SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits;
/// Global destructor functions and arguments that need to run on termination.
- std::vector<std::pair<llvm::WeakVH,llvm::Constant*> > CXXGlobalDtors;
+ std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>> CXXGlobalDtors;
/// \brief The complete set of modules that has been imported.
llvm::SetVector<clang::Module *> ImportedModules;
+ /// \brief The set of modules for which the module initializers
+ /// have been emitted.
+ llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers;
+
/// \brief A vector of metadata strings.
SmallVector<llvm::Metadata *, 16> LinkerOptionsMetadata;
/// Cached reference to the class for constant strings. This value has type
/// int * but is actually an Obj-C class pointer.
- llvm::WeakVH CFConstantStringClassRef;
-
- /// Cached reference to the class for constant strings. This value has type
- /// int * but is actually an Obj-C class pointer.
- llvm::WeakVH ConstantStringClassRef;
-
- /// \brief The LLVM type corresponding to NSConstantString.
- llvm::StructType *NSConstantStringType = nullptr;
+ llvm::WeakTrackingVH CFConstantStringClassRef;
/// \brief The type used to describe the state of a fast enumeration in
/// Objective-C's for..in loop.
bool isTriviallyRecursive(const FunctionDecl *F);
bool shouldEmitFunction(GlobalDecl GD);
+ /// Map used to be sure we don't emit the same CompoundLiteral twice.
+ llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *>
+ EmittedCompoundLiterals;
+
+ /// Map of the global blocks we've emitted, so that we don't have to re-emit
+ /// them if the constexpr evaluator gets aggressive.
+ llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks;
+
/// @name Cache for Blocks Runtime Globals
/// @{
return *ObjCData;
}
+ // Version checking function, used to implement ObjC's @available:
+ // i32 @__isOSVersionAtLeast(i32, i32, i32)
+ llvm::Constant *IsOSVersionAtLeastFn = nullptr;
+
InstrProfStats &getPGOStats() { return PGOStats; }
llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
return TheModule.getDataLayout();
}
const TargetInfo &getTarget() const { return Target; }
- const llvm::Triple &getTriple() const;
+ const llvm::Triple &getTriple() const { return Target.getTriple(); }
bool supportsCOMDAT() const;
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO);
llvm_unreachable("unknown visibility!");
}
- llvm::Constant *GetAddrOfGlobal(GlobalDecl GD, bool IsForDefinition = false);
+ llvm::Constant *GetAddrOfGlobal(GlobalDecl GD,
+ ForDefinition_t IsForDefinition
+ = NotForDefinition);
/// Will return a global variable of the given type. If a variable with a
/// different type already exists then a new variable with the right type
/// the same mangled name but some other type.
llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D,
llvm::Type *Ty = nullptr,
- bool IsForDefinition = false);
+ ForDefinition_t IsForDefinition
+ = NotForDefinition);
/// Return the address of the given function. If Ty is non-null, then this
/// function will use the specified type if it has to create it.
llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr,
bool ForVTable = false,
bool DontDefer = false,
- bool IsForDefinition = false);
+ ForDefinition_t IsForDefinition
+ = NotForDefinition);
/// Get the address of the RTTI descriptor for the given type.
llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false);
llvm::Type *getGenericBlockLiteralType();
/// Gets the address of a block which requires no captures.
- llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
+ llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name);
+
+ /// Returns the address of a block which requires no caputres, or null if
+ /// we've yet to emit the block for BE.
+ llvm::Constant *getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE) {
+ return EmittedGlobalBlocks.lookup(BE);
+ }
+
+ /// Notes that BE's global block is available via Addr. Asserts that BE
+ /// isn't already emitted.
+ void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr);
/// Return a pointer to a constant CFString object for the given string.
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal);
/// compound literal expression.
ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E);
+ /// If it's been emitted already, returns the GlobalVariable corresponding to
+ /// a compound literal. Otherwise, returns null.
+ llvm::GlobalVariable *
+ getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E);
+
+ /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already
+ /// emitted.
+ void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE,
+ llvm::GlobalVariable *GV);
+
/// \brief Returns a pointer to a global variable representing a temporary
/// with static or thread storage duration.
ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E,
getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type,
const CGFunctionInfo *FnInfo = nullptr,
llvm::FunctionType *FnType = nullptr,
- bool DontDefer = false, bool IsForDefinition = false);
+ bool DontDefer = false,
+ ForDefinition_t IsForDefinition = NotForDefinition);
/// Given a builtin id for a function like "__builtin_fabsf", return a
/// Function* for "fabsf".
- llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,
- unsigned BuiltinID);
+ llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD,
+ unsigned BuiltinID);
llvm::Function *getIntrinsic(unsigned IID, ArrayRef<llvm::Type*> Tys = None);
}
/// Create a new runtime function with the specified type and name.
- llvm::Constant *CreateRuntimeFunction(llvm::FunctionType *Ty,
- StringRef Name,
- llvm::AttributeSet ExtraAttrs =
- llvm::AttributeSet());
+ llvm::Constant *
+ CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
+ llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
+ bool Local = false);
+
/// Create a new compiler builtin function with the specified type and name.
- llvm::Constant *CreateBuiltinFunction(llvm::FunctionType *Ty,
- StringRef Name,
- llvm::AttributeSet ExtraAttrs =
- llvm::AttributeSet());
+ llvm::Constant *
+ CreateBuiltinFunction(llvm::FunctionType *Ty, StringRef Name,
+ llvm::AttributeList ExtraAttrs = llvm::AttributeList());
/// Create a new runtime global variable with the specified type and name.
llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,
StringRef Name);
/// \param CalleeInfo - The callee information these attributes are being
/// constructed for. If valid, the attributes applied to this decl may
/// contribute to the function attributes and calling convention.
- /// \param PAL [out] - On return, the attribute list to use.
+ /// \param Attrs [out] - On return, the attribute list to use.
/// \param CallingConv [out] - On return, the LLVM calling convention to use.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info,
- CGCalleeInfo CalleeInfo, AttributeListType &PAL,
- unsigned &CallingConv, bool AttrOnCallSite);
+ CGCalleeInfo CalleeInfo,
+ llvm::AttributeList &Attrs, unsigned &CallingConv,
+ bool AttrOnCallSite);
+
+ /// Adds attributes to F according to our CodeGenOptions and LangOptions, as
+ /// though we had emitted it ourselves. We remove any attributes on F that
+ /// conflict with the attributes we add here.
+ ///
+ /// This is useful for adding attrs to bitcode modules that you want to link
+ /// with but don't control, such as CUDA's libdevice. When linking with such
+ /// a bitcode library, you might want to set e.g. its functions'
+ /// "unsafe-fp-math" attribute to match the attr of the functions you're
+ /// codegen'ing. Otherwise, LLVM will interpret the bitcode module's lack of
+ /// unsafe-fp-math attrs as tantamount to unsafe-fp-math=false, and then LLVM
+ /// will propagate unsafe-fp-math=false up to every transitive caller of a
+ /// function in the bitcode library!
+ ///
+ /// With the exception of fast-math attrs, this will only make the attributes
+ /// on the function more conservative. But it's unsafe to call this on a
+ /// function which relies on particular fast-math attributes for correctness.
+ /// It's up to you to ensure that this is safe.
+ void AddDefaultFnAttrs(llvm::Function &F);
// Fills in the supplied string map with the set of target features for the
// passed in function.
QualType Ty,
StringRef Category = StringRef()) const;
+ /// Imbue XRay attributes to a function, applying the always/never attribute
+ /// lists in the process. Returns true if we did imbue attributes this way,
+ /// false otherwise.
+ bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
+ StringRef Category = StringRef()) const;
+
SanitizerMetadata *getSanitizerMetadata() {
return SanitizerMD.get();
}
void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset,
const CXXRecordDecl *RD);
- /// \breif Get the declaration of std::terminate for the platform.
+ /// \brief Get the declaration of std::terminate for the platform.
llvm::Constant *getTerminateFn();
llvm::SanitizerStatReport &getSanStats();
llvm::Value *
createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF);
+ /// Get target specific null pointer.
+ /// \param T is the LLVM type of the null pointer.
+ /// \param QT is the clang QualType of the null pointer.
+ llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT);
+
private:
- llvm::Constant *
- GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D,
- bool ForVTable, bool DontDefer = false,
- bool IsThunk = false,
- llvm::AttributeSet ExtraAttrs = llvm::AttributeSet(),
- bool IsForDefinition = false);
+ llvm::Constant *GetOrCreateLLVMFunction(
+ StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable,
+ bool DontDefer = false, bool IsThunk = false,
+ llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
+ ForDefinition_t IsForDefinition = NotForDefinition);
llvm::Constant *GetOrCreateLLVMGlobal(StringRef MangledName,
llvm::PointerType *PTy,
const VarDecl *D,
- bool IsForDefinition = false);
+ ForDefinition_t IsForDefinition
+ = NotForDefinition);
void setNonAliasAttributes(const Decl *D, llvm::GlobalObject *GO);
// C++ related functions.
- void EmitNamespace(const NamespaceDecl *D);
+ void EmitDeclContext(const DeclContext *DC);
void EmitLinkageSpec(const LinkageSpecDecl *D);
- void CompleteDIClassType(const CXXMethodDecl* D);
/// \brief Emit the function that initializes C++ thread_local variables.
void EmitCXXThreadLocalInitFunc();
llvm::Constant *AssociatedData = nullptr);
void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535);
- /// Generates a global array of functions and priorities using the given list
- /// and name. This array will have appending linkage and is suitable for use
- /// as a LLVM constructor or destructor array.
- void EmitCtorList(const CtorList &Fns, const char *GlobalName);
+ /// EmitCtorList - Generates a global array of functions and priorities using
+ /// the given list and name. This array will have appending linkage and is
+ /// suitable for use as a LLVM constructor or destructor array. Clears Fns.
+ void EmitCtorList(CtorList &Fns, const char *GlobalName);
/// Emit any needed decls for which code generation was deferred.
void EmitDeferred();
/// Emit any vtables which we deferred and still have a use for.
void EmitDeferredVTables();
+ /// Emit a dummy function that reference a CoreFoundation symbol when
+ /// @available is used on Darwin.
+ void emitAtAvailableLinkGuard();
+
/// Emit the llvm.used and llvm.compiler.used metadata.
void emitLLVMUsed();
/// Check whether we can use a "simpler", more core exceptions personality
/// function.
void SimplifyPersonality();
+
+ /// Helper function for ConstructAttributeList and AddDefaultFnAttrs.
+ /// Constructs an AttrList for a function with the given properties.
+ void ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
+ bool AttrOnCallSite,
+ llvm::AttrBuilder &FuncAttrs);
};
} // end namespace CodeGen
} // end namespace clang