Skip to content

Commit 670df13

Browse files
committed
Improve codegen, Start on constification.
There are also various experiements that need cleaning up, specifically around builtins and source location.
1 parent 4b91b34 commit 670df13

33 files changed

+760
-144
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
360360
/// __builtin_va_list type.
361361
mutable TypedefDecl *BuiltinVaListDecl = nullptr;
362362

363+
/// The typedef for the predefined __builtin_source_loc_impl_type
364+
/// type.
365+
mutable TypedefDecl *BuiltinSourceLocImplDecl = nullptr;
366+
363367
/// The typedef for the predefined \c __builtin_ms_va_list type.
364368
mutable TypedefDecl *BuiltinMSVaListDecl = nullptr;
365369

@@ -1173,6 +1177,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
11731177
// The decl is built when constructing 'BuiltinVaListDecl'.
11741178
mutable Decl *VaListTagDecl = nullptr;
11751179

1180+
// The implicit record decl __builtin_source_loc_impl_type
1181+
mutable Decl *BuiltinSourceLocImplRecordDecl = nullptr;
1182+
11761183
// Implicitly-declared type 'struct _GUID'.
11771184
mutable TagDecl *MSGuidTagDecl = nullptr;
11781185

@@ -2181,6 +2188,20 @@ class ASTContext : public RefCountedBase<ASTContext> {
21812188
return getTagDeclType(MSGuidTagDecl);
21822189
}
21832190

2191+
/// Retrieve the C type declaration corresponding to the predefined
2192+
/// \c __builtin_source_loc_impl_t type.
2193+
TypedefDecl *getBuiltinSourceLocImplDecl() const;
2194+
2195+
/// Retrieve the type of the \c __builtin_source_loc_impl_t type.
2196+
QualType getBuiltinSourceLocImplType() const {
2197+
return getTypeDeclType(getBuiltinSourceLocImplDecl());
2198+
}
2199+
2200+
/// Retrieve the C type declaration corresponding to the predefined
2201+
/// \c __builtin_source_loc_t type.
2202+
// FIXME(ERICWF): Is this needed
2203+
Decl *getBuiltinSourceLocImplRecord() const;
2204+
21842205
/// Return whether a declaration to a builtin is allowed to be
21852206
/// overloaded/redeclared.
21862207
bool canBuiltinBeRedeclared(const FunctionDecl *) const;

clang/include/clang/AST/DeclCXX.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4399,12 +4399,15 @@ const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
43994399
AccessSpecifier AS);
44004400

44014401

4402+
class MaterializedResultNameDecl;
4403+
44024404
/// A result name introduces in a post condition. For instance, given:
44034405
///
44044406
/// int foo() post(r : r > 0);
44054407
///
44064408
/// Where `r` refers to the value returned by the function
44074409
class ResultNameDecl : public ValueDecl {
4410+
MaterializedResultNameDecl *MaterializedDecl = nullptr;
44084411

44094412
ResultNameDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
44104413
: ValueDecl(Decl::ResultName, DC, IdLoc, Id, T) {}
@@ -4422,10 +4425,59 @@ class ResultNameDecl : public ValueDecl {
44224425
using ValueDecl::getDeclName;
44234426
using ValueDecl::setType;
44244427

4428+
void setMaterializedResultNameDecl(MaterializedResultNameDecl *D) {
4429+
4430+
}
4431+
44254432
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
44264433
static bool classofKind(Kind K) { return K == Decl::ResultName; }
44274434
};
44284435

4436+
/*
4437+
class MaterializedResultNameDecl final
4438+
: public VarDecl,
4439+
private llvm::TrailingObjects<MaterializedResultNameDecl, ResultNameDecl *> {
4440+
/// The number of BindingDecl*s following this object.
4441+
unsigned NumBindings;
4442+
4443+
MaterializedResultNameDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
4444+
SourceLocation LSquareLoc, QualType T,
4445+
TypeSourceInfo *TInfo, StorageClass SC,
4446+
ArrayRef<ResultNameDecl *> Bindings)
4447+
: VarDecl(Decomposition, C, DC, StartLoc, LSquareLoc, nullptr, T, TInfo,
4448+
SC),
4449+
NumBindings(Bindings.size()) {
4450+
std::uninitialized_copy(Bindings.begin(), Bindings.end(),
4451+
getTrailingObjects<ResultNameDecl *>());
4452+
for (auto *B : Bindings)
4453+
B->setDecomposedDecl(this);
4454+
}
4455+
4456+
void anchor() override;
4457+
4458+
public:
4459+
friend class ASTDeclReader;
4460+
friend TrailingObjects;
4461+
4462+
static MaterializedResultNameDecl *Create(ASTContext &C, DeclContext *DC,
4463+
SourceLocation StartLoc,
4464+
SourceLocation LSquareLoc,
4465+
QualType T, TypeSourceInfo *TInfo,
4466+
StorageClass S,
4467+
ArrayRef<BindingDecl *> Bindings);
4468+
static MaterializedResultNameDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
4469+
unsigned NumBindings);
4470+
4471+
ArrayRef<BindingDecl *> bindings() const {
4472+
return llvm::ArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
4473+
}
4474+
4475+
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
4476+
4477+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
4478+
static bool classofKind(Kind K) { return K == Decomposition; }
4479+
};
4480+
*/
44294481
} // namespace clang
44304482

44314483
#endif // LLVM_CLANG_AST_DECLCXX_H

clang/include/clang/AST/DeclID.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,16 @@ enum PredefinedDeclIDs {
8484

8585
/// The internal '__type_pack_element' template.
8686
PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17,
87+
88+
/// The internal '__builtin_source_location_impl_type' typedef.
89+
PREDEF_DECL_BUILTIN_SOURCE_LOCATION_IMPL_T_ID = 18,
8790
};
8891

8992
/// The number of declaration IDs that are predefined.
9093
///
9194
/// For more information about predefined declarations, see the
9295
/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
93-
const unsigned int NUM_PREDEF_DECL_IDS = 18;
96+
const unsigned int NUM_PREDEF_DECL_IDS = 19;
9497

9598
/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means
9699
/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the

clang/include/clang/AST/Expr.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4723,12 +4723,13 @@ enum class SourceLocIdentKind {
47234723
FileName,
47244724
Line,
47254725
Column,
4726-
SourceLocStruct
4726+
SourceLocStruct,
4727+
BuiltinSourceLocStruct
47274728
};
47284729

47294730
/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
47304731
/// __builtin_FUNCTION(), __builtin_FUNCSIG(), __builtin_FILE(),
4731-
/// __builtin_FILE_NAME() or __builtin_source_location().
4732+
/// __builtin_FILE_NAME(), __builtin_source_location(), or __builtin_source_location()2.
47324733
class SourceLocExpr final : public Expr {
47334734
SourceLocation BuiltinLoc, RParenLoc;
47344735
DeclContext *ParentContext;
@@ -4760,6 +4761,7 @@ class SourceLocExpr final : public Expr {
47604761
case SourceLocIdentKind::Function:
47614762
case SourceLocIdentKind::FuncSig:
47624763
case SourceLocIdentKind::SourceLocStruct:
4764+
case SourceLocIdentKind::BuiltinSourceLocStruct:
47634765
return false;
47644766
case SourceLocIdentKind::Line:
47654767
case SourceLocIdentKind::Column:
@@ -4794,6 +4796,7 @@ class SourceLocExpr final : public Expr {
47944796
case SourceLocIdentKind::Function:
47954797
case SourceLocIdentKind::FuncSig:
47964798
case SourceLocIdentKind::SourceLocStruct:
4799+
case SourceLocIdentKind::BuiltinSourceLocStruct:
47974800
return true;
47984801
default:
47994802
return false;

clang/include/clang/AST/Stmt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ class alignas(void *) Stmt {
709709
/// The kind of source location builtin represented by the SourceLocExpr.
710710
/// Ex. __builtin_LINE, __builtin_FUNCTION, etc.
711711
LLVM_PREFERRED_TYPE(SourceLocIdentKind)
712-
unsigned Kind : 3;
712+
unsigned Kind : 4;
713713
};
714714

715715
class StmtExprBitfields {

clang/include/clang/Basic/Builtins.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2624,6 +2624,17 @@ def ContractViolation : Builtin {
26242624
let Attributes = [NoThrow, NoReturn, Constexpr];
26252625
}
26262626

2627+
def UnnamedConstant : Builtin {
2628+
let Spellings = ["__builtin_unnamed_constant"];
2629+
let Prototype = "void(...)";
2630+
let Attributes = [NoThrow, CustomTypeChecking, Constexpr];
2631+
}
2632+
2633+
def CurrentContractEvaluationSemantic : Builtin {
2634+
let Spellings = ["__builtin_contract_evaluation_semantic"];
2635+
let Prototype = "int()";
2636+
let Attributes = [NoThrow, Constexpr];
2637+
}
26272638

26282639
// C99 library functions
26292640
// C99 stdarg.h

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11879,6 +11879,9 @@ def err_coroutine_return_type : Error<
1187911879
>;
1188011880
} // end of coroutines issue category
1188111881

11882+
def select_contract_kind : TextSubstitution<
11883+
"%select{pre|post|contract_assert}0">;
11884+
1188211885
let CategoryName = "Contract Issue" in {
1188311886
def err_ericwf_unimplemented : Error<
1188411887
"contract feature %0 is not yet implemented (complain to [email protected])"
@@ -11899,6 +11902,8 @@ def err_void_result_name : Error<
1189911902
"result name %0 cannot be used with a void return type">;
1190011903
def err_deduced_auto_result_name_without_body : Error<
1190111904
"result name on function with deduced return type requires a body">;
11905+
def err_result_name_not_allowed : Error<
11906+
"result name %0 not allowed outside of post condition specifier">;
1190211907

1190311908
} // end of contracts issues
1190411909
let CategoryName = "Documentation Issue" in {

clang/include/clang/Basic/LangOptions.h

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -443,35 +443,29 @@ class LangOptionsBase {
443443

444444
/// Contract evaluation mode. Determines whether to check contracts, and
445445
// whether contract failures cause compile errors.
446-
enum class ContractEvalMode {
446+
enum class ContractEvaluationSemantic {
447447
// Contracts are parsed, syntax checked and type checked, but never evaluated.
448+
// FIXME(EricWF): This doesn't yet map to an actual enumerator in
449+
// std::contracts::evaluation_semantic
448450
Ignore = 0,
449451

450-
// Contracts are run, and failures are reported, but contract failures do not
451-
// logically stop execution of the program, nor can the compiler assume
452-
// contracts are true for optimizing.
453-
Observe = 1,
454-
455452
// Contracts are run, failures are reported, and when a contract fails the
456453
// program is terminated. The compiler can assume after contracts statements
457454
// that the contracts hold.
458-
Enforce = 2,
459-
};
455+
Enforce = 1,
460456

461-
/// Determines the strategy to implement contract evaluation
462-
enum class ContractImplStrategy {
463-
// Contracts are checked after entering and before exiting a function.
464-
Callee = 0,
465-
466-
// Precontracts are checked before making a function call and after entering the function
467-
// Postcontracts are checked before returning from a function, and after returning from a function call.
468-
Both = 1,
469-
470-
// Precontracts are checked before making a function call, postcontracts
471-
// are checked before returning from a function call.
472-
Split = 2,
457+
// Contracts are run, and failures are reported, but contract failures do not
458+
// logically stop execution of the program, nor can the compiler assume
459+
// contracts are true for optimizing.
460+
Observe = 2,
461+
462+
// Contracts are run, failures cause an immediate trap
463+
// FIXME(EricWF): This doesn't yet map to an actual enumerator in
464+
// std::contracts::evaluation_semantic
465+
QuickEnforce = 3,
473466
};
474467

468+
475469
// Define simple language options (with no accessors).
476470
#define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
477471
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
@@ -587,10 +581,11 @@ class LangOptions : public LangOptionsBase {
587581
GPUDefaultStreamKind GPUDefaultStream;
588582

589583
/// C++ contracts evaluation mode
590-
ContractEvalMode ContractEvaluation;
584+
ContractEvaluationSemantic ContractEvalSemantic;
591585

592-
/// C++ contracts implementation strategy
593-
ContractImplStrategy ContractStrategy;
586+
/// A List of + or - prefixed contract groups to enable or disable
587+
/// FIXME(EricWF): Implement this
588+
std::vector<std::string> ClangContractGroups;
594589

595590
/// The seed used by the randomize structure layout feature.
596591
std::string RandstructSeed;

clang/include/clang/Basic/TokenKinds.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ KEYWORD(__builtin_FUNCSIG , KEYMS)
458458
KEYWORD(__builtin_LINE , KEYALL)
459459
KEYWORD(__builtin_COLUMN , KEYALL)
460460
KEYWORD(__builtin_source_location , KEYCXX)
461+
KEYWORD(__builtin_source_location2 , KEYCXX)
462+
461463

462464
// __builtin_types_compatible_p is a GNU C extension that we handle like a C++
463465
// type trait.

clang/include/clang/Driver/Options.td

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,27 +1668,27 @@ def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>,
16681668
HelpText<"Specify comma-separated list of offloading target triples (CUDA and HIP only)">;
16691669

16701670
// C++ Contracts
1671-
defm fcontracts : BoolFOption<"contracts",
1671+
defm contracts : BoolFOption<"contracts",
16721672
LangOpts<"Contracts">, DefaultFalse,
1673-
PosFlag<SetTrue, [], [ClangOption, CC1Option],
1673+
PosFlag<SetTrue, [], [ClangOption, CC1Option, CLOption],
16741674
"Enable support for C++ Contracts">,
16751675
NegFlag<SetFalse>>;
16761676

1677-
def fcontracts_eval_mode : Joined<["-"], "fcontracts_evaluation=">,
1678-
HelpText<"Specify contract evaluation mode. The default value is 'ignore'.">,
1679-
Values<"0,1,2">,
1677+
1678+
def fcontract_evaluation_semantic_EQ : Joined<["-"], "fcontract-evaluation-semantic=">,
1679+
HelpText<"Specify contract evaluation semantic. The default value is 'enforce'.">,
1680+
Values<"ignore,enforce,observe,quick_enforce">,
16801681
Visibility<[ClangOption, CC1Option]>,
1681-
NormalizedValuesScope<"LangOptions::ContractEvalMode">,
1682-
NormalizedValues<["Ignore", "Observe", "Enforce"]>,
1683-
MarshallingInfoEnum<LangOpts<"ContractEvaluation">, "Ignore">;
1682+
NormalizedValuesScope<"LangOptions::ContractEvaluationSemantic">,
1683+
NormalizedValues<["Ignore", "Enforce", "Observe", "QuickEnforce"]>,
1684+
MarshallingInfoEnum<LangOpts<"ContractEvalSemantic">, "Enforce">;
16841685

1685-
def fcontracts_impl_strategy : Joined<["-"], "fcontracts_strategy=">,
1686-
HelpText<"Specify contract implementation strategy. The default value is 'callee'.">,
1687-
Values<"0,1,2">,
1686+
def fclang_contract_groups_EQ : CommaJoined<["-"], "fcontract-groups=">,
16881687
Visibility<[ClangOption, CC1Option]>,
1689-
NormalizedValuesScope<"LangOptions::ContractImplStrategy">,
1690-
NormalizedValues<["Callee", "Both", "Split"]>,
1691-
MarshallingInfoEnum<LangOpts<"ContractStrategy">, "Callee">;
1688+
HelpText<"Clang extension. Enable or disable contracts by group. The argument is a comma-separated "
1689+
"sequence of one or more group names, each prefixed by '+' or '-'.">,
1690+
MarshallingInfoStringVector<LangOpts<"ClangContractGroups">>;
1691+
16921692

16931693
// C++ Coroutines
16941694
defm coroutines : BoolFOption<"coroutines",

0 commit comments

Comments
 (0)